ERC20Interface 在智能合約中有什麼作用?
我發現這個用於生成智能合約的奇妙程式碼允許你將 ERC20 代幣發送到另一個地址。
其工作原理的簡單概述/解釋如下:
我們啟動智能合約接受的所有 erc20 代幣的映射。假設您只想接受 BNB,您的合約可以做到這一點,因為還有一個功能,允許智能合約所有者確定要接受哪個 ERC20。部分程式碼:
/** * @dev list of all supported tokens for transfer * @param string token symbol * @param address contract address of token */ mapping(bytes32 => address) public tokens; /** * @dev add address of token to list of supported tokens using * token symbol as identifier in mapping */ function addNewToken(bytes32 symbol_, address address_) public onlyOwner returns (bool) { tokens[symbol_] = address_; return true; } /** * @dev remove address of token we no more support */ function removeToken(bytes32 symbol_) public onlyOwner returns (bool) { require(tokens[symbol_] != 0x0); delete(tokens[symbol_]); return true; }
我沒有得到這個智能合約的兩個部分。首先,第 43 行的這段程式碼是做什麼的?
ERC20 public ERC20Interface;
根據我的發現,ERC20 是在開頭導入的openzepelin項目中聲明的。我認為契約只能與“is”一詞一起使用,例如(Contract myContract is ERC20)。
假設在這種情況下 ERC20 來自 openzepelin 項目,它會
public EERC20Interface
做什麼?我在這裡找到了 ERC20 介面,但我認為所有智能合約都會有這個標準的“介面”,那麼為什麼要專門聲明它呢?
我沒有得到的第二部分更複雜,所以我將添加 /** 評論
function transferTokens(bytes32 symbol_, address to_, uint256 amount_) public whenNotPaused { require(tokens[symbol_] != 0x0); require(amount_ > 0); address contract_ = tokens[symbol_]; address from_ = msg.sender; ERC20Interface = ERC20(contract_); /** what does this line do? Is it initiating a new instance of ERC20? **/ uint256 transactionId = transactions.push( Transfer({ contract_: contract_, to_: to_, amount_: amount_, failed_: true }) ); transactionIndexesToSender[from_].push(transactionId - 1); if(amount_ > ERC20Interface.allowance(from_, address(this))) { /** what does ERC20Interface.allowance indicate here? is this line checking that the ERC20 sender has enough balance? **/ emit TransferFailed(from_, to_, amount_); revert(); } ERC20Interface.transferFrom(from_, to_, amount_); transactions[transactionId - 1].failed_ = false; emit TransferSuccessful(from_, to_, amount_); }
在第 3 行:
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
在那裡:
contract ERC20 ...
ERC20
契約也是如此。在連結合約的第 43 行:
ERC20 public ERC20Interface;
ERC20
類型(在 中contract
定義)也是如此ERC20.sol
,可見性是public
並且實例被呼叫ERC20Interface
。稍後在第 93 行:
ERC20Interface = ERC20(contract_);
這是實例化一個實例,這次是使用已部署樣本的地址。這會將函式簽名(來自 ERC20)附加到地址。這意味著該函式可以在傳入函式的地址與 ERC20 合約進行互動。
在我看來,ERC20 合約的這種用法是次優的。它正在匯總所有程式碼,
ERC20.sol
即使TokenZendR
我們永遠不會使用它。它永遠不會使用將被編譯的函式實現,因為它所做的只是與其他(ERC20)合約進行通信。這可以通過使用介面更有效地完成。確實,
ERC20.sol
它本身指向了介面契約。在第 3 行:
import "./IERC20.sol";
這包含足夠的資訊
TokenZendR
來發送消息並且要小得多,因此它會降低複雜性、大小(和成本)。為相當於介面規範的內容保留和分配儲存空間也是一種浪費。
import "./IERC20.sol"; contract TokenZendR ... function transferTokens(address addr,... IERC20 i = IERC20(addr);
從這個合約的角度來看,知道有這樣的功能就足夠了(但知道實現並不重要)……
function transfer(address to, uint256 value) external returns (bool);
…因此您可以執行以下操作:
bool successfulTransfer = i.transfer(receiver, amount);
或者
require(i.transfer(receiver, amount);
希望能幫助到你。