Я работал над концепцией создания игры типа 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();
}
}
Когда я вызываю функцию createWorld из nethereum — я вижу, как проходит транзакция, я жду завершения майнинга, но мое событие никогда не запускается?
То, что я делаю, сложно для Эфириума? Примечание. Затем контракт World создает экземпляр контракта Area, который затем создает экземпляр объекта Door.
Я оцениваю цену на газ с помощью netheriums var callResult = f.EstimateGasAsync(args).Result;
Где f — вызов функции.
Мой код .Net в nethereum выглядит так:
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 элементов, и даже с использованием кошелька Ethereum — я не вижу каких-либо событий контракта.
Предложения?
Я думаю, что разобрался - я думаю, что вызывал GetAllChanges для функции, а не для события.
В любом случае, я вижу, что события поднимаются сейчас. я добавил в
event RequestReceived(string s);
Таким образом, я мог отслеживать, как далеко в контрактных функциях зашло выполнение.
На случай, если это поможет, здесь есть шаблон: Существует ли шаблон простой контрактной фабрики?
Я думаю, вы найдете больше ясности, сосредоточившись сначала на структуре данных. Эта «фабрика» будет производить чемпионаты мира, поэтому все, что требуется, — это индекс для чемпионатов мира (и событий и т. д.).
address[] public worldList;
Вы можете построить индекс по ходу дела:
World newWorld = new World(name);
return worldList.push(newWorld);
Чтобы поддерживать вашу функцию удаления, вам нужно знать, в какой строке в 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
Надеюсь, это поможет.