From b540bf6a0e6c6079fbe7d2a6881519ab6a22b97a Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 25 Jan 2018 13:51:55 +0100 Subject: [PATCH] ethapi: add personal.signTransaction --- internal/ethapi/api.go | 40 +++++++++++++++++++++++++++++++++++++ internal/web3ext/web3ext.go | 6 ++++++ 2 files changed, 46 insertions(+) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 55bd5aa1ba..34de5d0770 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -370,6 +370,46 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs return submitTransaction(ctx, s.b, signed) } +// SignTransaction will create a transaction from the given arguments and +// tries to sign it with the key associated with args.To. If the given passwd isn't +// able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast +// to other nodes +func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs, passwd string) (*SignTransactionResult, error) { + // Look up the wallet containing the requested signer + account := accounts.Account{Address: args.From} + + wallet, err := s.am.Find(account) + if err != nil { + return nil, err + } + if args.Nonce == nil { + // Hold the addresse's mutex around signing to prevent concurrent assignment of + // the same nonce to multiple accounts. + s.nonceLock.LockAddr(args.From) + defer s.nonceLock.UnlockAddr(args.From) + } + // Set some sanity defaults and terminate on failure + if err := args.setDefaults(ctx, s.b); err != nil { + return nil, err + } + // Assemble the transaction and sign with the wallet + tx := args.toTransaction() + + var chainID *big.Int + if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) { + chainID = config.ChainId + } + tx, err = wallet.SignTxWithPassphrase(account, passwd, tx, chainID) + if err != nil { + return nil, err + } + data, err := rlp.EncodeToBytes(tx) + if err != nil { + return nil, err + } + return &SignTransactionResult{data, tx}, nil +} + // signHash is a helper function that calculates a hash for the given message that can be // safely used to calculate a signature from. // diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index e11aa402f5..a6b81b4c2a 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -517,6 +517,12 @@ web3._extend({ call: 'personal_deriveAccount', params: 3 }), + new web3._extend.Method({ + name: 'signTransaction', + call: 'personal_signTransaction', + params: 2, + inputFormatter: [web3._extend.formatters.inputTransactionFormatter, null] + }), ], properties: [ new web3._extend.Property({