Contract-Development

如何使用建構子設置介面地址?

  • December 13, 2021

沒什麼問題,只需要了解一些事情:

使用這段程式碼,當呼叫“getEstimatedTokenForBNB”函式時,事務被還原。

// Initialize Parameters

constructor () {

   tokenAddress = 0xf63DB3cc676b71F8D38D27181d0AE9d7Aa4F1D48;
   wbnbAddress = 0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd;
   pairAddress = 0xD280a7D55faa4a982616e8d5C6b2D68B5Ce366aF;
   routerAddress = 0x9Ac64Cc6e4415144C455BD8E4837Fea55603e5c3;
   userManagementAddress = 0xa1eD4f05cE96241e75817765c78eFAA74a9c120C;
}

// Initialize Interfaces

IUserManagement USERMANAGEMENT = IUserManagement(tokenAddress);
IDEXRouter iROUTER = IDEXRouter(routerAddress);
IBEP20 TOKEN = IBEP20(tokenAddress);  
IBEP20 LPTOKEN = IBEP20(pairAddress);
IBEP20 WBNB = IBEP20(wbnbAddress);

// Modifiers 

modifier onlyToken() {
   require(msg.sender == tokenAddress); _;
}

// View Functions


function getEstimatedTokenForBNB(uint buyAmountInWei) public view  returns (uint[] memory) {

   uint[] memory bnbQuote;
   bnbQuote = iROUTER.getAmountsOut(buyAmountInWei, getPathForWBNBToToken());
   return bnbQuote;
}

// Utility Functions

receive() external payable {}

function getPathForWBNBToToken() public view returns (address[] memory) {
   address[] memory path = new address[](2);
   path[0] = wbnbAddress;
   path[1] = tokenAddress;
   
   return path;
}

function checkAmountValidity (uint buyAmountInWei) public view returns(bool checkResult) {
   try iROUTER.getAmountsOut(buyAmountInWei, getPathForWBNBToToken()) {
       checkResult = true;
       return checkResult;        
       }
   catch {
       checkResult = false;
       return checkResult;
       }
}

我發現如果我在 //initialize Interfaces 部分手動設置地址,一切都會按預期工作..所以我想我的建構子當時沒有設置參數。

任何人都可以向我解釋正確的方法嗎?

您可以使用以下範常式式碼重現您的問題:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IInterface1 {
}

interface IInterface2 {
}

contract YourContract {

 address public address1;
 address public address2;

 IInterface1 public interface1 = IInterface1(address1);
 IInterface2 public interface2 = IInterface2(address2);

 constructor() {
     address1 = 0xf63DB3cc676b71F8D38D27181d0AE9d7Aa4F1D48;
     address2 = 0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd;
 }
}

問題是所有狀態變數都在部署時初始化,甚至在執行建構子之前,這在技術上也是部署過程的一部分。無論您是否願意,它們要麼被隱式設置為 0,要麼被設置為顯式值(如果你提供了一個)。所以在部署:

address public address1; // equivalent to address1 = address(0x0);

其次是 :

IInterface1 public interface1 = IInterface1(address1);

由於 address1 被初始化為 0,它設置interface1為相同的值:0。從儲存變數到儲存變數的分配總是創建一個獨立的副本(文件)。因此,address1建構子中的更新對interface1. 堅持那個(容易出錯的)設計,你可以:

在部署時初始化所有內容:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IInterface1 {
}

interface IInterface2 {
}

contract YourContract {

 address public address1 = 0xf63DB3cc676b71F8D38D27181d0AE9d7Aa4F1D48;
 address public address2 = 0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd;

 IInterface1 public interface1 = IInterface1(address1);
 IInterface2 public interface2 = IInterface2(address2);

 constructor() {
 }
}

或者初始化建構子中的所有內容:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IInterface1 {
}

interface IInterface2 {
}

contract YourContract {

 address public address1;
 address public address2;

 IInterface1 public interface1;
 IInterface2 public interface2;

 constructor() {
   address1 = 0xf63DB3cc676b71F8D38D27181d0AE9d7Aa4F1D48;
   address2 = 0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd;
   interface1 = IInterface1(address1);
   interface2 = IInterface2(address2);
 }
}

這些不是唯一的可能性,但我認為如果你想適應你目前的契約設計,它們是最乾淨的。

老實說,您似乎不需要address變數的“版本”,因為如果需要,您可以即時從界面中恢復它。重寫我的例子:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IInterface1 {
}

interface IInterface2 {
}

contract YourContract {

 IInterface1 public interface1;
 IInterface2 public interface2;

 constructor() {
     interface1 = IInterface1(0xf63DB3cc676b71F8D38D27181d0AE9d7Aa4F1D48);
     interface2 = IInterface2(0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd);
 }
}

這樣(或在變數聲明中移動兩個初始化)您不會復製本質上相同的變數(目標地址),並且您可以直接使用介面類型來清除外部函式呼叫。

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