Solidity
映射到合約
Solidity 文件說可以使用任何東西作為映射值,我假設它包括一個合約:
_ValueType
實際上可以是任何類型,包括映射。但我找不到有關如何使用它的範例或文件。
如果我有以下映射,我怎麼知道映射中的合約是否存在,或者已經自殺?
pragma solidity ^0.4.0; contract MyContract { // ... } contract MappingExample { mapping(uint32 => MyContract) inner_contracts; function do_something(uint32 key) { MyContract c; if(/* inner_contracts[key] exists??? */) { c = inner_contracts[key]; } else { c = new MyContract; inner_contracts[key] = c; } // do stuff with c } }
這是一個例子。
pragma solidity ^0.4.19; contract InnerContract { uint public value; function setValue(uint new_value) { value = new_value; } } contract Contract { mapping(address => InnerContract) public contracts; function makeNew() { contracts[msg.sender] = new InnerContract(); } function initialize() { contracts[msg.sender].setValue(3); } function get() constant returns (uint) { return contracts[msg.sender].value(); } }
如果您使用此程式碼,您會注意到在 makeNew 之前呼叫 initialize 不起作用。原因是映射的預設值用零填充。在契約的情況下,這不是一個好主意。
我怎麼知道映射中的契約是否存在,或者已經自殺?
讓我們為標誌使用另一個映射!
mapping(address => InnerContract) public is_contract_initialized;
如果值為 false(預設情況下),那麼您應該初始化您的合約。
即使它有效,它也可能非常昂貴。幾個建議。
- 儲存已部署的合約地址(小),然後根據需要實例化合約:
MyContract c = MyContract(theAddress);
- 避免
suicide/selfdestruct
。它只會創建接收器和無效的操作碼。相反,如果您想確保契約被淘汰,請稍微翻轉一下並使用修飾符,例如onlyIfRunning
. 您可以將該變數公開,然後輕鬆檢查它:if(c.isRunning()) {}
- 您可能會修剪已部署的契約列表,但它是一個相當複雜的結構,只需保留一個僅附加列表並使用該
isRunning()
想法來確定哪些契約被“關閉”並拒絕狀態更改就足夠了.我在這裡做了一個例子:有一個簡單的契約工廠模式嗎?
希望能幫助到你。