ERC677之技术性场景测试

简单模拟使用Erc677完成token的转移以及两种业务的处理;

IERC677Receiver.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IERC677Receiver {
    function onTokenTransfer(
        address sender,
        uint256 value,
        bytes memory data
    ) external;
}

Erc677.sol
合约内部方法transferAndCall实现token的转移,以及传递业务数据至to合约账户。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./IERC677Receiver.sol";
abstract contract Erc677 {
    event Transfer(
        address indexed from,
        address indexed to,
        uint256 value,
        bytes data
    );

    function transferAndCall(
        address to,
        uint256 value,
        bytes memory data
    ) public returns (bool success) {
        // 1. transfer
        emit Transfer(msg.sender, to, value, data);
        // 2. call
        IERC677Receiver(to).onTokenTransfer(msg.sender, value, data);
    }

    ///-----------------------测试--------------
    function getSubId() public pure returns (bytes32) {
        return keccak256("1");
    }

    function depositTest(
        address to,
        bytes32 subId,
        uint256 amount
    ) public {
        bytes4 sig = bytes4(keccak256("deposit(bytes32)"));
        bytes memory data = abi.encodeWithSelector(sig, subId, amount);
        transferAndCall(to, amount, data);
    }

    function oracleRequestTest(
        address to,
        uint256 amount,
        bytes32 subId,
        address callbackAddr,
        uint256 nonce,
        string calldata payload
    ) public {
        bytes memory data = abi.encodeWithSignature("oracleRequest(bytes32,address,uint256,string)", subId,callbackAddr, nonce, payload);
        transferAndCall(to, amount, data);
    }

}

Oracle.sol
合约内部通过方法onTokenTransfer接收业务数据,进行分类处理。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./IERC677Receiver.sol";
contract Oracle is IERC677Receiver {
     mapping(bytes32=>uint256) public balances;
     mapping(bytes32=>string) public jobs;
     
    event SubscriptionFunded(bytes32 indexed subId, address sender,uint256 oldBalance, uint256 newBalance);

    // 处理token合约发来的call信息
    function onTokenTransfer(
        address sender,
        uint256 value,
        bytes calldata data
    ) public {
        // call
        bytes4 sig = bytes4(data[:4]);
        if (sig == bytes4(keccak256("deposit(bytes32)"))) {
            bytes32 subId = abi.decode(data[4:], (bytes32));
            deposit(subId,value,sender);
        }else if(sig== this.oracleRequest.selector){
            (bytes32 jobId,address callbackAddress,uint256 nonce,string memory payload ) = abi.decode(data[4:], (bytes32,address,uint256,string));
            oracleRequest(jobId,callbackAddress,nonce,payload,sender);
        }else{
             revert("Unsupport action"); 
        }
    }

    function deposit(bytes32 subId, uint256 amount,address sender) public {
        require(subId != bytes32(0), "Invalid subId");
        require(amount != 0, "Invalid amount");
        uint256 oldBalance=balances[subId];
        uint256 newBalace = oldBalance + amount;
        balances[subId] = newBalace;
        emit SubscriptionFunded(subId,sender, oldBalance,newBalace);
    }

    event OracleRequest(
        bytes32 indexed jobId,
        address requester,
         uint256 nonce,
        address callbackAddr,
        string data
    );

     function oracleRequest(
        bytes32 jobId,
        address callbackAddress,
        uint256 nonce,
        string memory data,
        address sender
    ) public payable returns (bool) {
        jobs[jobId]=data;
        emit OracleRequest(jobId, sender,nonce, callbackAddress,data);
        return true;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容