Search code examples
ethereumweb3jsgo-ethereumtrezor

Geth + web3js invalid sender when sending signed transaction


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


Solution

  • I have managed to resolve this,

    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);
                       }
    
                   });
           })
       }
    

    EDIT: Cross platform posts: Send signed transactions to Ropsten or Truffle develop network with Trezor (Hardware Wallet)