在 solidity 智能合约中管理 gas 费用

Managing gas fees in solidity smart contract

我有一个 ERC20 智能合约,其中编辑了 transfer 函数

function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        if(_transactionMaxValue > 0){
         require(_transactionMaxValue >= amount, "You can not transfer more than 1000000 tokens at once!");
        }
        transfer(recipient, amount);
    }

我在 transfer 函数中添加了 if 语句,以防用户在部署前指示每个事务的限制。我想知道这是否会影响转移代币时的汽油费,以便决定是否保留具有可起诉交易限制的“通用”ERC20 智能合约模板或编写新的,没有 if 声明,如果没有交易限制被指出。

I was wondering if this would affect gas fees when transferring tokens

加入(ifrequire)条件增加了总的gas使用量,但是在parent其他操作的gas使用量的背景下增加幅度较小transfer() 功能。这是因为在覆盖函数中,您正在执行“仅”一次存储读取和内存中的其他一些操作。

执行您的 transfer() 函数需要 54,620 gas(包括父函数;假设 require() 条件没有失败)。而仅执行父 transfer() 函数会花费 52,320 gas。


如果要调用父transfer()函数,则需要使用super.transfer(recipient, amount);。如果没有 super 关键字,您会将脚本锁定在无限递归中,始终调用自身。

此外,为了正确覆盖父函数,您需要在 public 可见性修饰符,以及 return 声明的值。

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    uint256 _transactionMaxValue = 1000000;

    constructor() ERC20("MyToken", "MyT") {
        _mint(msg.sender, 1000000);
    }

    // moved the `override virtual` before the `public` modifier
    function transfer(address recipient, uint256 amount) override virtual public returns (bool) {
        if(_transactionMaxValue > 0){
         require(_transactionMaxValue >= amount, "You can not transfer more than 1000000 tokens at once!");
        }
        // added `return super.`
        return super.transfer(recipient, amount);
    }
}

@Petr Hejda 建议的一切都是正确的。 这里的其他改进是使 require 语句失败原因字符串更小、更精确,因为它会导致字节码更小,因此部署成本更低。