在 ethers.js 中设置合同方法的气体限制

Set gas limit on contract method in ethers.js

问题

我正在尝试使用测试网络 (ropsten) 中的合同方法,但由于此错误而失败:

reason: 'cannot estimate gas; transaction may fail or may require manual gas limit', code: 'UNPREDICTABLE_GAS_LIMIT'

代码

我创建了一个智能合约实例并想调用它的注册方法:

const registrationContract = new ethers.Contract(ADDRESS, abi, signer);
const hashedDomain = utils.keccak256(utils.toUtf8Bytes(domain));

const register = await registrationContract.register(hashedDomain, walletAddress);

ethers.js是否提供设置合约限额的功能?还是可以这样做?我在 documentation.

中没有找到

你可以用一个对象作为最后一个参数来设置gas limit,对于一个简单的转账交易,你可以这样做:

const tx = {
  to: toAddress,
  value: ethers.utils.parseEther(value),
  gasLimit: 50000,
  nonce: nonce || undefined,
};
await signer.sendTransaction(tx);

如果您正在对智能合约进行交易,想法是相同的,但请确保您在其中一个 abi 方法中设置了最后一个参数,例如:

const tx = await contract.safeTransferFrom(from, to, tokenId, amount, [], {
  gasLimit: 100000,
  nonce: nonce || undefined,
});

这可以修复 UNPREDICTABLE_GAS_LIMIT 错误,因为手动通知它 ethers 会跳过对请求计算的 gas_limit.

的提供者的 rpc 方法调用

补充答案,当您手动定义 gasLimit 时,理解这一点很重要:

  1. 配置的值被保留并在合约调用时发送,因此调用者账户必须至少在他的钱包中有该值;

  2. 当然在交易完成后,剩余的Gas会返回到调用方钱包;

  3. 所以当对于同一个交易调用时会出现问题,例如取决于参数的数量,你有很大范围的 gas 值可能性,有时值集非常高并且与小额天然气交易不成比例。

因此,为了解决这个问题并动态设置 gasLimit,使用该函数来估算以太币的交易 gas (estimateGas),然后给出额外的保证金误差百分比。

可能是这样的,其中 gasMargin() 计算要传递给 tx 调用的最终气体(在这种情况下只增加 10%)。

const gasEstimated = await registrationContract.estimateGas.register(hashedDomain, walletAddress);

const register = await registrationContract.register(hashedDomain, walletAddress), {
      gasLimit: Math.ceil(gasMargin(gasEstimated, 1.1)) 
    });