Solidity Hooks函数的使用

Openzeppelin


Hooks

Hooks函数帮助合约在每次执行例如转账等操作时执行需要的逻辑,而避免重复在不同的函数中编写这段逻辑。hooks函数会在每次该动作执行前或执行后被触发,其中,_beforeTokenTransfer(address from, address to, uint256 amount) 是最常见的hook,会在transfer之前被调用,包括mint和burn的场景


一、_beforeTokenTransfer()应用示例

1.实现ERC20的SafeTransfer,即使用_beforeTokenTransfer在每次转账前检查to地址的合法性

pragma solidity ^0.8.0;

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

contract ERC20WithSafeTransfer is ERC20 {
    
    
    function _beforeTokenTransfer(address from, address to, uint256 amount)
        internal virtual override
    {
    
    
        super._beforeTokenTransfer(from, to, amount);

        require(_validRecipient(to), "ERC20WithSafeTransfer: invalid recipient");
    }

    function _validRecipient(address to) private view returns (bool) {
    
    
        ...
    }

    ...
}

2.ERC20Pausable实现

Override _beforeTokenTransfer函数并加上whenNotPause修饰器,以在每次转账前判断

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyToken is ERC20, Pausable, Ownable {
    
    
    constructor() ERC20("MyToken", "MTK") {
    
    }

    function pause() public onlyOwner {
    
    
        _pause();
    }

    function unpause() public onlyOwner {
    
    
        _unpause();
    }

    function _beforeTokenTransfer(address from, address to, uint256 amount)
        internal
        whenNotPaused
        override
    {
    
    
        super._beforeTokenTransfer(from, to, amount);
    }
}

二、注意事项

1.使用virtual

当希望合约可以被继承并实现_beforeTokenTransfer函数的更多功能时,对_beforeTokenTransfer函数使用virtual关键字

2.使用super

重写_beforeTokenTransfer函数时,使用super继承parent合约的hooks函数

contract MyToken is ERC20 {
    
    
    function _beforeTokenTransfer(address from, address to, uint256 amount)
        internal virtual override // Add virtual here!
    {
    
    
        super._beforeTokenTransfer(from, to, amount); // Call parent hook
        ...
    }
}

其他

  • 除了_beforeTokenTransfer,还有_afterTokenTransfer,即在transfer后被调用
  • ERC721的hooks参数有所不同:_beforeTokenTransfer(address from, address to, uint256 tokenId),第三个参数为tokenId而不是amount

猜你喜欢

转载自blog.csdn.net/hhhhhhhhhjx/article/details/127264565
今日推荐