Ethers.js: Error: invalid transaction object when attempting to deploy contract

Created on 10 Sep 2018  路  16Comments  路  Source: ethers-io/ethers.js

here is my code:

var bytecode = contractjson.bytecode
var transaction = ethers.Contract.getDeployTransaction(bytecode, abi);
var signedTx = wallet.sign(transaction)
var deployTx = await wallet.sendTransaction(signedTx)
let tx = await provider.waitForTransaction(deployTx)

this causes the following unhandled promise rejection error:

Error: invalid transaction object
    at Wallet.sendTransaction

not sure what's going wrong here - perhaps the bytecode isn't formatted correctly? any help is much appeciated :)

investigate

Most helpful comment

I'm initializing the wallet with an encrypted JSON keystore:
var wallet = await Wallet.fromEncryptedWallet(walletJson, password)
walletJson is an imported UTC file generated with geth

here's the entire error message:

{ Error: invalid sender
    at getResult (/home/elizabeth/shyft_jsbridge/node_modules/ethers/providers/json-rpc-provider.js:34:21)
    at exports.XMLHttpRequest.request.onreadystatechange (/home/elizabeth/shyft_jsbridge/node_modules/ethers/providers/provider.js:621:30)
    at exports.XMLHttpRequest.dispatchEvent (/home/elizabeth/shyft_jsbridge/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:591:25)
    at setState (/home/elizabeth/shyft_jsbridge/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:610:14)
    at IncomingMessage.<anonymous> (/home/elizabeth/shyft_jsbridge/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:447:13)
    at IncomingMessage.emit (events.js:185:15)
    at endReadableNT (_stream_readable.js:1106:12)
    at process._tickCallback (internal/process/next_tick.js:114:19)

it seems to be the wallet.sendTransaction line that generates the error; all the code before that works ok.

also, I'm able to send transactions to interact with a contract, so I think the wallet is set up ok. only deployment isn't working

All 16 comments

Not sure where chain is coming from, but a Signer (like a Wallet) has a sendTransacrion method which takes in an unsigned transaction object, not a serialized transaction hex string. A Provider can take take a serialized transaction hex, if you want to use the sign manually, but I would recommend rather than calling sign, use wallet.sendTransaction, which will also automatically populate the nonce, gas price and limit, and chain ID.

Wallet.prototype.sign is meant more for low-level purposes, such as offline or deferred signing transaction, or for analysis tools.

I updated my code to remove the signing, but now I get Error: invalid sender.

var abi = contractjson.abi
var bytecode = contractjson.bytecode
var transaction = ethers.Contract.getDeployTransaction(bytecode, abi);
var deployTx = await wallet.sendTransaction(transaction)
let tx = await provider.waitForTransaction(deployTx)

Which line is generating that error? How are you initializing the wallet?

I'm initializing the wallet with an encrypted JSON keystore:
var wallet = await Wallet.fromEncryptedWallet(walletJson, password)
walletJson is an imported UTC file generated with geth

here's the entire error message:

{ Error: invalid sender
    at getResult (/home/elizabeth/shyft_jsbridge/node_modules/ethers/providers/json-rpc-provider.js:34:21)
    at exports.XMLHttpRequest.request.onreadystatechange (/home/elizabeth/shyft_jsbridge/node_modules/ethers/providers/provider.js:621:30)
    at exports.XMLHttpRequest.dispatchEvent (/home/elizabeth/shyft_jsbridge/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:591:25)
    at setState (/home/elizabeth/shyft_jsbridge/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:610:14)
    at IncomingMessage.<anonymous> (/home/elizabeth/shyft_jsbridge/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:447:13)
    at IncomingMessage.emit (events.js:185:15)
    at endReadableNT (_stream_readable.js:1106:12)
    at process._tickCallback (internal/process/next_tick.js:114:19)

it seems to be the wallet.sendTransaction line that generates the error; all the code before that works ok.

also, I'm able to send transactions to interact with a contract, so I think the wallet is set up ok. only deployment isn't working

@noot have you been able to make any progress on this? I'm having this exact same issue now.

@noot what provider are you using? If you are using JsonRpcProvider then make sure you set the network to unspecified if you are testing against a local dev chain

@ctverceles no I haven't looked at it since. let me know if you figure it out

@naddison36 I was using JsonRpcProvider along with a local geth testntet. I'll try that, thanks!

Have you tried using v4 instead?

@ricmoo @naddison36 using ethers 4.0.7 and setting chain to unspecified, deployment now works! thanks! here's my working code:

const ethers = require("ethers")
const Wallet = ethers.Wallet
const providers = ethers.providers
const path = require("path")
const fs = require("fs")

const deploy = async() => {
    let keystore = path.resolve("./keystore/my-json-keystore")
    let walletJson = fs.readFileSync(keystore, 'utf8')
    let wallet = await Wallet.fromEncryptedJson(walletJson, "mypassword")

    let provider = new providers.JsonRpcProvider("http://localhost:8545", "unspecified")

    wallet = wallet.connect(provider)

    let abifile = path.resolve("./build/RingVerify.abi")
    let abi = fs.readFileSync(abifile, 'utf8')

    let binfile = path.resolve("./build/RingVerify.bin")
    let bin = fs.readFileSync(binfile, 'utf8')

    let ringVerifyFactory = new ethers.ContractFactory( abi , bin , wallet )
    let ringVerify = await ringVerifyFactory.deploy()
    let receipt = await provider.getTransactionReceipt(ringVerify.deployTransaction.hash)
    console.log(receipt)
}

deploy()

In v4, you should not need to specify "unspecified" though. Can you try removing that and see if it still works? The v4 JsonRpcProvider should automatically detect and use the chain ID.

I'm going to close this now, but please, anyone feel free to re-open if you think there is more to address.

Thanks! :)

@ricmoo hey, just an update, if I don't put "unspecified" in the provider field I get "invalid sender" when attempting to deploy. works fine with "unspecified" though :)

Ah zut... Okay, I鈥檒l look into this next. :)

I was just doing some testing against a local geth node and tripped over the invalid sender error. Explicitly setting the network to unspecified gets around geth's invalid sender error.
Note the network does not need to be passed when connecting to a local Parity node.

let provider = new providers.JsonRpcProvider("http://localhost:8545", "unspecified")

This resolved my issue! Thanks!

So, I think this was an issue with how v4 handled "guessing" chain ID and signers enforcing chains ID matches. If so, it should certainly be fixed in v5 (and I think it was fixed for an unrelated thing in v4). I think this issue is stale, so I'm going to close it. but if there are still problems, please re-open.

Thanks! :)

Was this page helpful?
0 / 5 - 0 ratings