從合約方法創建合約實例
我一直在研究使用區塊鏈作為數據儲存來建構 MUD 類型遊戲的概念。注意 - 這是一個專用網路 - 所以乙太成本對我來說並不是一個大問題。
給定一個看起來像這樣的契約:
contract EtherWorldStorage { /* Constructor */ address owner; mapping (bytes32 => World) Gameworlds; mapping (bytes32 => uint) NamesIndex; World[] worldContracts; function EtherWorldStorage(){ owner = msg.sender; } event WorldCreated(bytes32 indexed worldName, address indexed sender, address result ); function createWorld(bytes32 name) returns (address a){ if(NamesIndex[name] > 0x0){ return 0x0; } World w = new World(name); NamesIndex[name] = worldContracts.length - 1; Gameworlds[name] = w; WorldCreated(name,msg.sender,w); return w; } function getWorldCount() returns (uint i){ return worldContracts.length; } function destroyWorld(bytes32 world){ World w = Gameworlds[world]; w.destroy(owner); } function getItemPossessorsInventory(InventoryItem item) returns (address a){ return item.getOwningInventory(); } }
當我從 nethereum 呼叫 createWorld 函式時 - 我可以看到交易正在進行,我等待探勘完成,但我的事件從未被觸發?
我正在為乙太坊做複雜的事情嗎?注意 - World 合約然後實例化一個 Area 合約,然後實例化一個 Door 對象。
我正在通過 nethereums var callResult = f.EstimateGasAsync(args).Result;
其中 f 是函式呼叫。
我在 nethereum 中的 .Net 程式碼如下所示:
public static string CreateWorld(string world) { var web3 = new Web3(Resources.Server); var result = web3.Personal.UnlockAccount.SendRequestAsync("0x54a222aE3d59EF92D715409f31C6eCAf331D0782", Resources.Password, 30).Result; if (result != true) { throw new Exception("Unable to unlock account..."); } var d = Encoding.UTF8.GetBytes(world); string address = "0x30d578718e1da379f4B1B1ac5E9be9ba646E0bCF"; // Contract address var contract = web3.Eth.GetContract(Resources.ContractInterface2, address); var add = contract.GetFunction("createWorld"); // Add method var worldCreatedEvent= contract.GetEvent("WorldCreated"); var filterAll = worldCreatedEvent.CreateFilterAsync().Result; var totalGas = new HexBigInteger(GetGasPrice(add, d).Value*2); HexBigInteger gasPrice = new HexBigInteger(new BigInteger(0.144)); var callResult = add.SendTransactionAsync("0x54a222aE3d59EF92D715409f31C6eCAf331D0782", totalGas,new HexBigInteger(0), d); var theResult = GetReceiptAsync(web3, callResult.Result); var log = worldCreatedEvent.GetAllChanges<dynamic>(filterAll).Result; return log[0].Event; return callResult.Result; }
無論如何,我的日誌總是以 0 個元素結束,即使使用乙太坊錢包 - 我也沒有看到任何合約事件被引發。
建議?
我想我把它整理好了——我想我是在函式而不是事件上呼叫 GetAllChanges。
無論如何-我可以看到現在正在引發的事件。我添加了
event RequestReceived(string s);
因此,我可以跟踪執行在合約功能中的進展情況。
如果有幫助,這裡有一個模式:有簡單的契約工廠模式嗎?
我認為通過首先關注資料結構,您會發現更清晰。這個“工廠”將製作世界,所以所需要的只是世界(和事件等)的索引。
address[] public worldList;
您可以隨時建構索引:
World newWorld = new World(name); return worldList.push(newWorld);
為了支持您的刪除功能,您需要知道每個 World 地址位於 worldList 中的哪一行,因此稍微修改映射:
mapping(address => uint) worldPointer;
並稍微修改新世界程序:
worldPointer[newWorld] = worldList.push(newWorld) - 1; // because it returns the array length
這樣,當您摧毀一個世界時,
worldPointer[world]
將為您提供要刪除的行。worldList
這裡有一個從數組中的任意行正確刪除的更完整的解釋:https ://medium.com/@robhitchens/solidity-crud-part-2-ed8d8b4f74ec
希望能幫助到你。