Contract-Development
如何使用建構子設置介面地址?
沒什麼問題,只需要了解一些事情:
使用這段程式碼,當呼叫“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); } }
這樣(或在變數聲明中移動兩個初始化)您不會復製本質上相同的變數(目標地址),並且您可以直接使用介面類型來清除外部函式呼叫。