简体   繁体   English

关于实现 ERC20 代币交换合约的问题

[英]Questions about implementing ERC20 tokenswap contract

I've tried myself to implement token swap contract from https://solidity-by-example.org/app/erc20/ .我已经尝试自己从https://solidity-by-example.org/app/erc20/实施令牌交换合约。 And I have some questions about it.我对此有一些疑问。

  1. Is it impossible to declare & assign variable inside constructor function?是否不可能在构造函数 function 中声明和分配变量? I've tried but, it didn't work.我试过了,但是没有用。
  2. Can I use ERC20 instance instead of IERC20 instance?我可以使用 ERC20 实例而不是 IERC20 实例吗? and what's the advantage of using IERC20 instance?使用 IERC20 实例有什么好处?
contract TokenSwap {
    IERC20 public token1;
    address public owner1;
    uint public amount1;
    IERC20 public token2;
    address public owner2;
    uint public amount2;

    constructor(
        address _token1,
        address _owner1,
        uint _amount1,
        address _token2,
        address _owner2,
        uint _amount2
    ) {
        token1 = IERC20(_token1);
        owner1 = _owner1;
        amount1 = _amount1;
        token2 = IERC20(_token2);
        owner2 = _owner2;
        amount2 = _amount2;
    }
  1. In example it made new private function _safeTransferFrom instead of using just transferFrom function inside the swap function.例如,它在swap function 中创建了新的私有 function _safeTransferFrom而不是仅使用transferFrom function。 What is the advantage of this?这样做有什么好处?
    function swap() public {
        require(msg.sender == owner1 || msg.sender == owner2, "Not authorized");
        require(
            token1.allowance(owner1, address(this)) >= amount1,
            "Token 1 allowance too low"
        );
        require(
            token2.allowance(owner2, address(this)) >= amount2,
            "Token 2 allowance too low"
        );

        _safeTransferFrom(token1, owner1, owner2, amount1);
        _safeTransferFrom(token2, owner2, owner1, amount2);
    }

    function _safeTransferFrom(
        IERC20 token,
        address sender,
        address recipient,
        uint amount
    ) private {
        bool sent = token.transferFrom(sender, recipient, amount);
        require(sent, "Token transfer failed");
    }

1 1

You can declare and assign variables inside the constructor, they will just be local and only accessible inside the constructor after they have been declared.您可以在构造函数内声明和分配变量,它们只是局部的,并且只有在声明后才能在构造函数内访问。 Please provide the exact attempt you made so I can see what was wrong.请提供您所做的确切尝试,以便我查看问题所在。

2 2

A contract's interface provides all the information needed to interact with that contract.合约的接口提供了与该合约交互所需的所有信息。 Specifically, what is needed is the function signatures of the contracts external/public functions.具体来说,需要的是合约外部/公共功能的 function 签名。 This is used to encode the calldata that is sent to the contract in order to call a specific function, and is completely obtainable from the contract's interface.这用于对发送到合约的调用数据进行编码,以便调用特定的 function,并且完全可以从合约的接口获得。 See https://docs.soliditylang.org/en/v0.8.11/abi-spec.html for more details.有关详细信息,请参阅https://docs.soliditylang.org/en/v0.8.11/abi-spec.html

3 3

I am not too sure about the purpose of this new function.我不太确定这个新 function 的用途。 transferFrom and its subsequent _transfer call (see source code at https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol ) contain require statements that check the validity of the transfer, ie whether the spenders allowance is large enough and whether the actual token owner (the one's whose tokens are being spent) has the required tokens. transferFrom及其后续的_transfer调用(参见https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol的源代码)包含检查传输有效性的require语句,即花费者津贴是否足够大以及实际的代币所有者(其代币被花费的人)是否具有所需的代币。 Unless I have missed something, these checks determine whether a transaction is valid or not.除非我错过了什么,否则这些检查会确定交易是否有效。 As such, either the overall transaction will revert, due to one of these require statements having a false condition, or it will suceed.因此,由于其中一个require语句具有错误条件,因此整个事务将恢复,或者它将成功。 This makes the additional require(sent, "Token transfer failed") redundant, as the only time it will be called is when the transfer is a sucess.这使得额外的require(sent, "Token transfer failed")变得多余,因为它只会在传输成功时被调用。

Note: This method could be useful if you are using the address type's call or delegatecall methods to call the function.注意:如果您使用address类型的calldelegatecall调用方法来调用 function,此方法可能很有用。 This is because execeptions in this subcalls do not bubble up to the calling contract, so you could use the returned boolean to check if transfer was successful.这是因为此子调用中的异常不会冒泡到调用合约,因此您可以使用返回的 boolean 来检查传输是否成功。 See Error handling: Assert, Require, Revert and Exceptions section of https://docs.soliditylang.org/en/v0.8.11/control-structures.html for more detail on this.有关更多详细信息,请参阅https://docs.soliditylang.org/en/v0.8.11/control-structures.html的错误处理:断言、要求、恢复和异常部分。

Let me know if you have any questions or if I have made any mistakes:)如果您有任何问题或我犯了任何错误,请告诉我:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM