Ether

ERC20Interface 在智能合約中有什麼作用?

  • January 10, 2019

我發現這個用於生成智能合約的奇妙程式碼允許你將 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);

希望能幫助到你。

引用自:https://ethereum.stackexchange.com/questions/65297