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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值