使用场景
因为在以太坊私链上进行开发,以太坊1.9.3
建议不要使用personal.unlockAccount
方法进行解锁账号,这个确实很危险,有一些扫描的服务,会在你解锁的时候,瞬间转走余额,所以需要通过加载私钥来发送交易的方式,调用以太坊合约。但是在这个过程一直遇到invalid sender
,后来才发现是ethereumjs-tx
的版本问题,记录一下,以防大家踩坑。
解决方案
注意ethereumjs-tx
版本需要设为1.3.7
, 如果是2.0.0
会报错:
(node:15700) UnhandledPromiseRejectionWarning: Error: Returned error: invalid sender
我的版本:
"ethereumjs-tx": "1.3.7",
"web3": "^1.0.0-beta.34"
下面是跑通的代码:
let Web3 = require('web3')
const web3 = new Web3('http://192.168.11.22:8547')
const EthereumTx = require('ethereumjs-tx')
//智能合约地址
const registryAddress = "0xa45bEA07Ed18B6ddF82f9403c02192aBC4e13178"
//智能合约对应Abi文件
const DidRegistryContract = require('./build/contracts/ethr-registry.json')
//私钥转换为Buffer
const privateKey = Buffer.from('e096cbf3fd506f950dd323a459bd394b7bf1021607262d10bbde492d43a1f09f',"hex")
//私钥转换为账号
const account = web3.eth.accounts.privateKeyToAccount("0xe096cbf3fd506f950dd323a459bd394b7bf1021607262d10bbde492d43a1f09f");
//私钥对应的账号地地址
const address = account.address
console.log("address: ",address)
//获取合约实例
var myContract = new web3.eth.Contract(DidRegistryContract,registryAddress)
//获取nonce,使用本地私钥发送交易
web3.eth.getTransactionCount(address).then(
nonce => {
console.log("nonce: ",nonce)
const txParams = {
nonce: nonce,
gasLimit: '0x271000',
to: registryAddress,
data: myContract.methods.set(10).encodeABI(), //智能合约中set方法的abi
}
const tx = new EthereumTx(txParams)
tx.sign(privateKey)
const serializedTx = tx.serialize()
web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'))
.on('receipt', console.log);
},
e => console.log(e)
)
这是ethereumjs-tx 的官方文档 示例
web3.js Document 中的示例 ,const tx = new EthereumTx(txParams, { chain: 'mainnet', hardfork: 'petersburg' })
这里少了{ chain: 'mainnet', hardfork: 'petersburg' })
,这种调用方式ethereumjs-tx
版本需要是1.3.7
因为版本的问题卡了好久,如果采用2.0.0
,需要增加{ chain: 'mainnet', hardfork: 'petersburg' })
,而我因为使用的私链,没有增加这两个参数,而导致一直找不到原因,网上好多也都是提问,后来找到一个相同的问题sendSignedTransaction() error: invalid sender #2915
需要使用1.3.7
版本,至于如何使用2.0.0
,私链的情况下{ chain: 'mainnet', hardfork: 'petersburg' })
填什么参数,我尝试了一下填自己的chainId: '1114'
,结果还是报错的,暂时先采用了1.3.7
。