【web3.js】使用私钥调用以太坊智能合约,踩坑记录

使用场景

因为在以太坊私链上进行开发,以太坊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】使用私钥调用以太坊智能合约,踩坑记录_第1张图片
web3.js Document 中的示例 ,const tx = new EthereumTx(txParams, { chain: 'mainnet', hardfork: 'petersburg' }) 这里少了{ chain: 'mainnet', hardfork: 'petersburg' }),这种调用方式ethereumjs-tx版本需要是1.3.7
【web3.js】使用私钥调用以太坊智能合约,踩坑记录_第2张图片
因为版本的问题卡了好久,如果采用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
【web3.js】使用私钥调用以太坊智能合约,踩坑记录_第3张图片

你可能感兴趣的:(以太坊)