Solidity
將映射作為建構子參數傳遞
在根據網路呼叫智能合約建構子時,我想將 DAI 和 UNI 的合約地址保存到映射中。下面是一個工作正常的簡約範例:
contract TokenManager { mapping(string => address) public contractERC20; address private ZERO_ADDRESS = 0x0000000000000000000000000000000000000000; // Contract constructor constructor(string memory network) public { if (compareStrings(network, "ropsten")) { registerERC20("DAI", 0xaD6D458402F60fD3Bd25163575031ACDce07538D); registerERC20("UNI", 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984); } } // Compare two strings function compareStrings(string memory s1, string memory s2) private pure returns(bool){ return keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2)); } // Register a ERC20 contract address function registerERC20(string memory _tokenName, address _tokenContract) public { require(bytes(_tokenName).length != 0, "Token name can't be empty"); require(contractERC20[_tokenName] == ZERO_ADDRESS, "ERC20 contract address already registered"); contractERC20[_tokenName] = _tokenContract; } // ... }
但是,我認為這不是最好的方法,因為地址是在合約中硬編碼的,並且代幣的完整列表乘以網路數量可能會很大。此外,最好直接從 Truffle 中的遷移文件中選擇要創建的代幣(例如),而不是為每個部署更新合約。
我正在考慮將一個包含所有地址的對像數組傳遞給建構子,以便合約循環遍歷該數組並分配每個地址,但沒有找到將此類對象/映射數組從 Truffle 發送到建構子的方法。
因此,在合約部署期間是否有更好的方法來處理這種地址分配?
首先,我建議從 切換
string
到bytes32
,因為:
- 編譯器目前不支持將字元串數組作為輸入傳遞
- 您的要求(網路名稱和令牌符號)似乎少於 32 個字元
其次,我建議在僅所有者函式中而不是在建構子中實現它:
pragma solidity 0.6.12; contract TokenManager { address public owner; mapping(bytes32 => mapping(bytes32 => address)) public contractERC20; constructor() public { owner = msg.sender; } function register( bytes32 network, bytes32[] memory tokenNames, address[] memory tokenAddresses ) external { require(msg.sender == owner); uint256 length = tokenNames.length; require(length == tokenAddresses.length); for (uint256 i = 0; i < length; i++) contractERC20[network][tokenNames[i]] = tokenAddresses[i]; } }
然後,您可以一一註冊您的網路。