【发布时间】:2018-07-28 01:53:13
【问题描述】:
使用 web3js 调用不需要签名的函数(例如不更新合约状态的函数)很容易。但是,除了手动解锁我的 MetaMask 钱包并在Remix 环境中调用函数之外,还不清楚如何调用需要签名的函数。
第一次将我的 dapp 部署到 Ropsten 后,我需要调用 createItem(string name, uint price) 100 次以最初填充 items 数组。由于我不想在 Remix 中手动执行,我想编写一个自动执行此操作的脚本。
看起来除了web3js 之外,我还需要ethereumjs-tx 才能在没有MetaMask 的情况下以编程方式签署交易。我还需要有我的account 和privateKey。有了所有这些信息和官方 web3js 文档,我想出了以下内容:
// Call an external function programatically
const web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io"))
const account = "ACCOUNT_ADDRESS"
const privateKey = new Buffer('PRIVATE_KEY', 'hex')
const contract = new web3.eth.Contract(abi, CONTRACT_ADDRESS, {
from: account,
gas: 3000000,
})
const functionAbi = contract.methods.myFunctionName(myArgument).encodeABI()
let estimatedGas
contract.methods.myFunctionNAme(myArgument).estimateGas({
from: account,
}).then((gasAmount) => {
estimatedGas = gasAmount.toString(16)
})
const txParams = {
gasPrice: '0x' + estimatedGas,
to: CONTRACT_ADDRESS,
data: functionAbi,
from: account,
}
const tx = new Tx(txParams)
tx.sign(privateKey)
const serializedTx = tx.serialize()
web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).
on('receipt', console.log)
代码运行,但txParams 实际上缺少一个键:nonce。当你运行它时,你会得到以下错误:
Unhandled rejection Error: Returned error: nonce too low
这是我的问题:
- 这通常是我想做的事情的正确方法吗?
- 如果 1 为真,我如何获取已部署合约的
nonce参数?
参考文献:
- http://web3js.readthedocs.io/en/1.0/
- https://github.com/ethereumjs/ethereumjs-tx
- https://ethereum.stackexchange.com/questions/21402/web3-eth-call-how-can-i-set-data-param
- https://ethereum.stackexchange.com/questions/6368/using-web3-to-sign-a-transaction-without-connecting-to-geth
更新:
感谢 Adam,现在我学会了如何获取 nonce。所以我添加了以下代码:
let nonce
web3.eth.getTransactionCount(account).then(_nonce => {
nonce = _nonce.toString(16)
})
const txParams = {
gasPrice: '0x' + gasPrice,
to: CONTRACT_ADDRESS,
data: functionAbi,
from: account,
nonce: '0x' + nonce,
}
但现在我一直遇到这个异常:
未处理的拒绝错误:返回错误:rlp:输入字符串太长 对于 uint64,解码为 (types.Transaction)(types.txdata).AccountNonce
除了让我找到这个具有异常处理程序的文件 (https://github.com/ethereum/go-ethereum/blob/master/rlp/decode.go) 之外,Google 搜索没有任何帮助。有谁知道如何解决这个问题?
【问题讨论】:
-
在您的更新中,您已经在 TX 对象中使用了异步(承诺)代码更新
nonce。该对象只有在同一个then块内运行时才能看到更新后的 nonce 状态。