调用合约方法并手动签名时出错。 SendTransaction 有效 SendRawTransaction 无效

Posted

技术标签:

【中文标题】调用合约方法并手动签名时出错。 SendTransaction 有效 SendRawTransaction 无效【英文标题】:Error when calling contract method and signing it manually. SendTransaction works SendRawTransaction doesn't 【发布时间】:2017-12-18 14:02:37 【问题描述】:

早安,

我正在编写一个节点 api 来公开我的区块链上的方法(使用 truffle 进行部署和测试)。我使用 web3.js、ethereumjs-tx、ethereum、truffle 和solidity 作为我的技术栈。

var txMethodData = masterKeyContract.myMethod.getData(myParams);

交易参数为:

 const txParams = 
    nonce: web3.toHex(web3.eth.getTransactionCount(web3.eth.coinbase)),
    gasPrice: web3.toHex(web3.eth.gasPrice),
    gasLimit: web3.toHex(2000000),
    from: mainAccount,
    value: '0x00',
    to: targetContract.address,
    data: txMethodData,
    chainId: 3
;

我正在使用 ethereumjs-tx

const EthereumTx = require('ethereumjs-tx');

使用链接到我的 mainAccount 的私钥签署交易

const tx = new EthereumTx(txParams);
tx.sign(privateKey);
const serializedTx = tx.serialize();
web3.eth.sendRawTransaction("0x" + serializedTx.toString('hex'), function (err1, resp1) 
    if (err1) 
        console.log(err1);
     else 
        console.log(resp1);
    
);

我得到了 gas * price + value 资金不足的错误。我从 mainAccount(来自 txParams 的 from: 字段)发送此交易。所以我在我的 mainAccount 上记录了余额

    web3.eth.getBalance(mainAccount, function (error, result) 
    if (!error) 
        console.log(web3.fromWei(result.toNumber(), "ether"));
     else 
        console.error(error);
    
);

结果是 252.12609391539726。所以不能没有资金。我什至估计了 web3.eth.estimateGas(txParams) 交易,它给了我 97899。当前 ropstein 区块的气体限制是 4,707,806。所以我应该有足够的。所以问题仍然是为什么我的资金不足。

我怀疑的唯一原因是我的 mainAccount 字段实际上不是交易的付款人。

更新: 问题可能出在签名上,因为我刚刚用

进行了测试
    web3.eth.sendTransaction(txParams, function (err1, resp1) 
    if (err1) 
        console.log(err1);
     else 
        console.log(resp1);
    
);

它起作用了,所以问题实际上是为什么 sendRawTransaction 不起作用。可能与我签署交易的方式有关吗?

我检查了

const privateKey = Buffer.from('[private_key_inserted_here]', 'hex');

其实和我的mainAccount有关。 private_key_inserted_here 取自“密文”字段中与我的主帐户相关的密钥库。我通过匹配密钥库的“地址”字段检查了这与我的 mainAccount 相关。

提前致谢。

【问题讨论】:

【参考方案1】:

我可以看到一些东西

gas 而不是gasLimit 不需要chainId 您应该真正自己管理nonce,而不是依靠节点向您发送正确的随机数。换句话说,不要从节点查询它,而是保留一个变量

如果你愿意,你可以看看我写的一个极简钱包签名者类 https://gist.github.com/gaiazov/e65a3e36c67eaf46fe81982cd193316d

【讨论】:

我会看看gas而不是gas limit确实是一个错误。谢谢你指点给我。

以上是关于调用合约方法并手动签名时出错。 SendTransaction 有效 SendRawTransaction 无效的主要内容,如果未能解决你的问题,请参考以下文章

将签名的交易发送到 Ropsten

[FAQ] MetaMask ALERT: 交易出错. 合约代码执行异常.

第94篇 合约间调用

关于web3.js中与交易发送交易签名智能合约函数调用相关api的理解

在 NodeJs 中调用我的合约方法时执行恢复

使用预授权签名加速 BSV 有状态合约更新