2

I am trying to create a managed account and deploy a custom wallet contract through web3 on my own private network. The code I'm using is:

// Create account
let account = this.web3.eth.accounts.create();
let encryptedAccount = account.encrypt(password);

// Create and deploy contract
let walletCreationData = new this.web3.eth.Contract(walletContractAbi, null, {
    data: walletContractData
}).deploy().encodeABI();

// Sign contract creation with created account
this.web3.eth.accounts.signTransaction({
    data: walletCreationData,
    from: account.address,
    gasPrice: 0,
    gas: 200000
}, account.privateKey).then((signedTransaction) => {
    this.web3.eth.sendSignedTransaction(signedTransaction.rawTransaction).then(console.log);
});

Now this will give me an error with the message invalid sender at the sendSignedTransaction promise. I have tried many combinations, among which using an in-memory wallet and loading an account with an existing balance instead of freshly creating one, but they all ended up giving the same error. What crucial part is missing that would allow me to create a smart contract?

This was tested using web3 1.0.0-beta.24 and geth 1.7.1-stable.

2 Answers 2

3

I launched the geth node using a different network id than the chain id configured in genesis.json. By default, web3 will look up the network id from the node and uses it in the transaction, but this would be an invalid transaction as the genesis block states a different chain id.

I had no idea chain id and network id were one and the same. I adjusted the network id on the node to match the configured chain id and there were no issues anymore. Alternatively specifying the correct chainId when signing the transaction will also work.

1
  • Thanks so much, that helped me a lot. For me, the solution was not to use geth --dev but to actually initialize an own chain with a custom genesis.
    – Ice09
    Feb 12, 2018 at 18:51
0

Change the below

      const Tx = require('ethereumjs-tx').Transaction;

      var rawTransaction = {
        "from": myAddress,
        "gasPrice": this.web3.utils.toHex(20 * 1e9),
        "gasLimit": this.web3.utils.toHex(210000),
        "to": contractAddress,
        "value": "0x0",
        "data": contract.methods.safeTransferFrom(myAddress, toAddress, tokenId).encodeABI(),
      }

        var privateKey = Buffer.from('abcde', 'hex')

        var transaction = new Tx(rawTransaction,{ chain: 'ropsten' , hardfork: 'petersburg' });

        transaction.sign(privateKey);

        this.web3.eth.sendSignedTransaction('0x' + transaction.serialize().toString('hex'))
            .on('transactionHash', console.log);

to the below

      const Tx = require('ethereumjs-tx').Transaction;

      var rawTransaction = {
        "from": myAddress,
        "gasPrice": this.web3.utils.toHex(20 * 1e9),
        "gasLimit": this.web3.utils.toHex(210000),
        "to": contractAddress,
        "value": "0x0",
        "data": contract.methods.safeTransferFrom(myAddress, toAddress, tokenId).encodeABI(),
      }

        var privateKey ='abcde'

        this.web3.eth.accounts.signTransaction(rawTransaction, privateKey)
        .then(function(value){
            this.web3.eth.sendSignedTransaction(value.rawTransaction)
            .then(function(response){
              console.log("response:" + JSON.stringify(response, null, ' '));
            })
          })

this.web3.eth.accounts.signTransaction will take the burden of including the correct chainId and nonce . Reference: https://github.com/ChainSafe/web3.js/issues/1040

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.