批量转账erc777代币

该智能合约实现了ERC777代币的回调方法,用于接收并处理ERC777代币的批量转账。合约包含了管理信任合同状态、更改管理者以及接收和重新分配代币的功能。当接收到ERC777代币转账时,合约会将代币按指定比例分发到多个地址。
摘要由CSDN通过智能技术生成
// contracts/GLDToken.sol 用0.6.12版本 加载的openzeppelin 全改成0.6.12 版本
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC777/IERC777.sol";
import "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol";
import "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol";

contract TransferToken is IERC777Recipient {
    //如果是自己的链,就用自己的erc1820 合约
    IERC1820Registry internal constant _ERC1820_REGISTRY =
    IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);

    mapping(address => bool) internal _trustedContracts;
    address internal _manager;

    modifier onlyManager {
        require(msg.sender == _manager, "Sender is not manager");
        _;
    }

    constructor(address[] memory trusted_contracts) public {
        for (uint256 i = 0; i < trusted_contracts.length; i++) {
            _trustedContracts[trusted_contracts[i]] = true;
        }
        _manager = msg.sender;
        _ERC1820_REGISTRY.setInterfaceImplementer(
            address(this),
            keccak256(abi.encodePacked("ERC777TokensRecipient")),
            address(this)
        );
    }

    function changeManager(address newManager) public onlyManager {
        _manager = newManager;
    }

    function isTrustedContract(address c) public view returns (bool) {
        return _trustedContracts[c];
    }

    function setTrustedContractState(address c, bool state) public onlyManager {
        // require(msg.sender == _manager);
        _trustedContracts[c] = state;
    }

    function retrieveToken(address tokenContract, uint256 value)
    public
    onlyManager
    {
        // require balance > value
        // address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(msg.sender, keccak256("ERC777Token"));
        // require (implementer != address(0), "Token contract should be an erc777 contract");

        require(
            IERC20(tokenContract).balanceOf(address(this)) >= value,
            "Transfer value is greater than contract balance"
        );
        IERC20(tokenContract).transfer(_manager, value);
    }

    function distributeCfx(bytes memory userData) public payable {
        (address [] memory tos, uint256[] memory vals) =
        abi.decode(userData, (address[], uint256[]));

        uint256 length = tos.length;

        require(tos.length == vals.length, "tos and vals length not match");

        // 检查 amount 相同
        uint256 sum = 0;
        for (uint256 i = 0; i < length; ++i) {
            sum += vals[i];
        }
        require(sum == msg.value, "Amount should equal to the sum of transfer");

        for (uint256 i = 0; i < length; ++i) {
            address payable recipient = payable(address(uint160(tos[i])));
            recipient.transfer(vals[i]);
        }
    }

    // @notice called when someone attempts to transfer ERC-777 tokens to this address.  If this function were to throw or doesn't exist, then the token transfer would fail.
    function tokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata userData,
        bytes calldata operatorData
    ) external override {
        require(to == address(this), "should transfer to this contract");
        // 有可能是不必要的,但暂时保留
        require(
            _trustedContracts[msg.sender],
            "The ERC777 Token is not registered in routing contract"
        );

        (address[] memory tos, uint256[] memory vals) =
        abi.decode(userData, (address[], uint256[]));

        uint256 length = tos.length;

        require(tos.length == vals.length, "tos and vals length not match");

        // 检查 amount 相同
        uint256 sum = 0;
        for (uint256 i = 0; i < length; ++i) {
            sum += vals[i];
        }
        require(sum == amount, "Amount should equal to the sum of transfer");

        // 本合约中不会有 ERC777 Token
        // 这里合约只会调用 ERC777 合约的转账接口
        address implementer =
        _ERC1820_REGISTRY.getInterfaceImplementer(
            msg.sender,
            keccak256("ERC777Token")
        );
        require(
            implementer != address(0),
            "Message sender should be an erc777 contract"
        );
        for (uint256 i = 0; i < length; ++i) {
            IERC777(implementer).send(tos[i], vals[i], "");
        }
    }
}

本合约是erc777合约的回调方法。发布合约时需要填erc777合约地址。然后调用erc777合约的send方法,实现批量转账


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值