web3.js 提交事务 Error: Returned error: invalid sender

2023-05-16

初学使用web3.js提交事务到以太坊时,会遇到:Error: Returned error: invalid sender

以太坊返回提示:发送者无效。

产生此问题的根本原因是事务提交操作的链信息没有指定,或者指定的不对。看下面例子

    const Web3 = require('web3')
    const web3 = new Web3("http://localhost:8545")
    // 智能合约地址部署地址
    let contractAddr = '0x......'
    // 操作智能合约的账户,也就是要发送事务的账户
    const accountAddress = '0x.....'
    // 交易接收账户
    const accountReceiveAddr = '0x....'
    // 事务要执行的方法,取自abi中
    const fs = require('fs')
    // 通过remix编译得到的metadata文件
    const meta = JSON.parse(fs.readFileSync('artifacts/MyToken_metadata.json').toString())
    const abi = meta.output.abi;
    // 根据智能合约接口定义文件abi和部署地址,实例化智能合约
    const contract = new web3.eth.Contract(abi, contractAddr)
    // 构造要执行的智能合约方法
    let transferFn = contract.methods.transfer(accountReceiveAddr, 11)
    // 将要执行的方法编码为16进制数据,该数据包含方法签名16进制值+参数16进制编码值
    let transHexData = transferFn.encodeABI()
    console.log('transHexData =>', transHexData)
    // gas预估消耗
    let estimateGasValue = await web3.eth.estimateGas({
        from: accountAddress, // 必须加上from,否则抛出:Error: Returned error: execution reverted   at Object.ErrorResponse (...
        to: contractAddr, // 必传参数,通过事务消息要发送到的地址和data数据来估算gas值(每次调用不一定相同,gas值还和当前链上的任务数有关)
        data: transHexData
    }, (err, egas) => {
        console.log(err, 'estimateGas =>', egas)
    })
   
    // 引入事务对象 需要先安装模块 cnpm install -g @ethereumjs/tx
    // 文档:https://ethereumjs.readthedocs.io/en/latest/
    const Tx = require('@ethereumjs/tx').Transaction
    let rawTx = {
        // nonce值为当前要提交事务的账户已提交的事务数量
        nonce: web3.utils.toHex(await web3.eth.getTransactionCount(accountAddress)),
        // 1gwei  web3.eth.getGasPrice() 可以获取最近几个区块的价格中位数, 默认不设置gasPrice使用该值
        gasPrice: '0x3B9ACA00', 
        gasLimit: estimateGasValue,
        to: contractAddr, // 合约地址
        value: '0x00',
        data: transHexData
    }
    // web3.eth.defaultAccount = accountAddress
    // 账户密钥(创建时候保存的,或者从metamask导出密钥)
    const privateKey = Buffer.from('a7870a8da63dcf8fbb3d17e70de85846b9bbb54a957cb8d7ca454ae67fbcae7d', 'hex')
    // 私有链、自定义链必须指定链信息,默认mainnet,web3版本4.0后默认undefined,不指定导致 invalid sender
    // 安装common模块:cnpm install -g @ethereumjs/common
    // 配置自定义链信息,创建事务时需要指定,否则出现invalid sender问题
    const Common = require('@ethereumjs/common')
    let commOpt = Common.Common.custom({chainId: 1337802, networkId: 1337802})
    let tx = new Tx(rawTx, {common: commOpt})
    let signedTx = tx.sign(privateKey)
    let serializeTx = signedTx.serialize()
    console.log("serialize => ", serializeTx)
    web3.eth.sendSignedTransaction('0x' + serializeTx.toString('hex'))
        .on('receipt', console.log)

注意:invalid sender问题出现的原因就是在new Tx时候没有设置正确的txOptions参数:

const Common = require('@ethereumjs/common')
// 配置自定义链信息,链id和networkid为初始化链时的值,可以通过geth console获取eth.getChainId()
// 通常chainId和networkId一样,初始化创建创世区块时侯也可以设置的不一样
let commOpt = Common.Common.custom({chainId: 1337802, networkId: 1337802})
// 第二个参数为txOptions参数,用于配置链信息
let tx = new Tx(rawTx, {common: commOpt})

测试方式:

        通过geth启动一个自定义链,如果没有先初始化一个链,然后通过node demo.js测试即可。

本测试启动:geth console --kiln --rpc.gascap 0 --rpc.txfeecap 0 --http -http.api web3,eth,net,personal,debug --http.corsdomain '*'  --ws --ws.api web3,net,eth,personal,debug --allow-insecure-unlock --vmdebug 2>~/geth.log

参考

  1. web3js
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

web3.js 提交事务 Error: Returned error: invalid sender 的相关文章

随机推荐