[Ethereum] Geth and Web3js: invalid sender when sending signed transaction

go-ethereumtrezorweb3js

Im using https://trezor.io/ to send signed transactions

I have succesfully send transactions to:

  • Truffle development network
  • Ropsten

Right now im using a private local go-ethereum node, the invocation of the signed transaction is exactly the same code as for truffle and ropsten and i get Invalid sender when sending the transaction

When doing some research about this i found that this error is produced by not having the same chainId and networkId, i check my configuration and how i ran the geth node and the chainId is the same that networkId

I have specified in the genesis.json of my geth node the chain id 10

"config": {
    "chainId": 10,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "clique": {
      "period": 15,
      "epoch": 30000
    }
  }

and i ran the node with networkId 10:

 geth --datadir node1/ --syncmode 'full' --port 30311 --rpc --rpcport 8545 --rpcaddr '192.168.1.244' --rpccorsdomain="*" --ws --wsaddr "192.168.1.244" --wsorigins "http://192.168.1.182" --wsport 8546 --wsapi 'personal,db,eth,net,web3,txpool,miner' --rpcapi 'personal,db,eth,net,web3,txpool,miner' --bootnodes 'enode://8235e42bec82ad8944dcf65b57d25b7a970d6e94f35961a188b2dfd306c6964f2d00d078e3bf1d9ccc6664112669d7ea9c04aa45a8ab9113aa8fe8a04b088f80@127.0.0.1:30310' --networkid 10 --gasprice '1' -unlock 'd770217581e0ca1265c88c9faaff81f5038b129f' --password node1/password.txt --mine console 

Any ideas of why this could happen?

Im using geth 1.8 and web3 1.0-beta33

I think that it is something about the configuration of geth, because as i said, i have sent transactions to Truffle dev and Ropsten with the same code

Here is how i send the transactions (source code) https://github.com/ethereum/web3.js/issues/1669

Best Answer

Well,

apart from specifying the chain id in the geth configuration and when running the node it is also necessary to indicate it in the transaction to be signed

So, the right way to do it is:

1)

"config": {
    "chainId": 10,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "clique": {
      "period": 15,
      "epoch": 30000
    }
  }

2)

 geth --datadir node1/ --syncmode 'full' --port 30311 --rpc --rpcport 8545 --rpcaddr '192.168.1.244' --rpccorsdomain="*" --ws --wsaddr "192.168.1.244" --wsorigins "http://192.168.1.182" --wsport 8546 --wsapi 'personal,db,eth,net,web3,txpool,miner' --rpcapi 'personal,db,eth,net,web3,txpool,miner' --bootnodes 'enode://8235e42bec82ad8944dcf65b57d25b7a970d6e94f35961a188b2dfd306c6964f2d00d078e3bf1d9ccc6664112669d7ea9c04aa45a8ab9113aa8fe8a04b088f80@127.0.0.1:30310' --networkid 10 --gasprice '1' -unlock 'd770217581e0ca1265c88c9faaff81f5038b129f' --password node1/password.txt --mine console 

3) Create raw transaction (note chainId)

var tx = {
           nonce: count ,
           gasPrice: web3.toHex(gasPriceGwei*1e9),
           gasLimit: web3.toHex(gasLimit),
           to: CONTRACT_ADDRESS,
           value: '0x00',
           data: getData,
           chainId:10,
           from:"0xedff546ac229317df81ef9e6cb3b67c0e6425fa7"
       };
       let response = await this.trezorSignTx(tx);

4) then sign the transaction (note the chainId here too):

trezorSignTx= async(transaction)=> {
       let trezor=  await this.getTrezor();
       // spend one change output
       var address_n = "m/44'/1'/0'/0/0"
       // var address_n = [44 | 0x80000000,
       //                  60 | 0x80000000,
       //                  0  | 0x80000000 ,
       //                  0 ]; // same, in raw form
       var nonce = transaction.nonce.substring(2); // note - it is hex, not number!!!
       var gas_price = transaction.gasPrice.substring(2);
       var gas_limit = transaction.gasLimit.substring(2);
       var to = transaction.to.substring(2);
       // var value = '01'; // in hexadecimal, in wei - this is 1 wei
       var value = transaction.value.substring(2); // in hexadecimal, in wei - this is about 18 ETC
       var data = transaction.data.substring(2); // some contract data
       // var data = null  // for no data
       var chain_id = 10; // 1 for ETH, 61 for ETC
       console.log(transaction);
       return new Promise (function (resolve,reject) {
           trezor.ethereumSignTx(
               address_n,
               nonce,
               gas_price,
               gas_limit,
               to,
               value,
               data,
               chain_id,
               function (response) {
                   if (response.success) {

                       console.log('Signature V (recovery parameter):', response.v); // number
                       console.log('Signature R component:', response.r); // bytes
                       console.log('Signature S component:', response.s); // bytes
                       resolve(response);

                   } else {
                       console.error('Error:', response.error); // error message
                       resolve(null);
                   }

               });
       })
   }
Related Topic