关于实施ERC20 tokenswap合约的问题

Questions about implementing ERC20 tokenswap contract

我已经尝试自己实现 https://solidity-by-example.org/app/erc20/ 的代币交换合约。 我对此有一些疑问。

  1. 是否无法在构造函数中声明和分配变量? 我试过了,但是没有用。
  2. 我可以使用 ERC20 实例而不是 IERC20 实例吗?使用 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. 在示例中,它创建了新的私有函数 _safeTransferFrom 而不是仅在 swap 函数中使用 transferFrom 函数。这样做有什么好处?
    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

您可以在构造函数内声明和分配变量,它们将只是局部的,并且只能在声明后在构造函数内访问。请提供您所做的确切尝试,以便我找出问题所在。

2

合约的界面提供了与该合约交互所需的所有信息。具体来说,需要的是合约 external/public 函数的函数签名。这用于对发送到合约的调用数据进行编码以调用特定功能,并且完全可以从合约的接口中获取。有关详细信息,请参阅 https://docs.soliditylang.org/en/v0.8.11/abi-spec.html

3

我不太确定这个新功能的用途。 transferFrom 及其后续的 _transfer 调用(参见 https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol 处的源代码)包含 require 检查转账有效性的语句,即支出津贴是否足够大以及是否实际的代币所有者(其代币被花费的人)拥有所需的代币。除非我遗漏了什么,否则这些检查会确定交易是否有效。因此,由于这些 require 语句中的一个具有错误条件,整个交易将恢复,或者它将成功。这使得额外的 require(sent, "Token transfer failed") 变得多余,因为它只会在传输成功时被调用。

注意:如果您使用 address 类型的 calldelegatecall 方法来调用函数,则此方法可能很有用。这是因为此子调用中的异常不会冒泡到调用合约,因此您可以使用返回的布尔值来检查传输是否成功。有关这方面的更多详细信息,请参阅 https://docs.soliditylang.org/en/v0.8.11/control-structures.html 的错误处理:断言、要求、恢复和异常部分。

如果您有任何问题或我有任何错误,请告诉我:)