关于实施ERC20 tokenswap合约的问题
Questions about implementing ERC20 tokenswap contract
我已经尝试自己实现 https://solidity-by-example.org/app/erc20/ 的代币交换合约。
我对此有一些疑问。
- 是否无法在构造函数中声明和分配变量?
我试过了,但是没有用。
- 我可以使用 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;
}
- 在示例中,它创建了新的私有函数
_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
类型的 call
或 delegatecall
方法来调用函数,则此方法可能很有用。这是因为此子调用中的异常不会冒泡到调用合约,因此您可以使用返回的布尔值来检查传输是否成功。有关这方面的更多详细信息,请参阅 https://docs.soliditylang.org/en/v0.8.11/control-structures.html 的错误处理:断言、要求、恢复和异常部分。
如果您有任何问题或我有任何错误,请告诉我:)
我已经尝试自己实现 https://solidity-by-example.org/app/erc20/ 的代币交换合约。 我对此有一些疑问。
- 是否无法在构造函数中声明和分配变量? 我试过了,但是没有用。
- 我可以使用 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;
}
- 在示例中,它创建了新的私有函数
_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
类型的 call
或 delegatecall
方法来调用函数,则此方法可能很有用。这是因为此子调用中的异常不会冒泡到调用合约,因此您可以使用返回的布尔值来检查传输是否成功。有关这方面的更多详细信息,请参阅 https://docs.soliditylang.org/en/v0.8.11/control-structures.html 的错误处理:断言、要求、恢复和异常部分。
如果您有任何问题或我有任何错误,请告诉我:)