Создание экземпляров контракта из методов контракта

Я работал над концепцией создания игры типа 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 — я не вижу каких-либо событий контракта.

Предложения?

Ответы (2)

Я думаю, что разобрался - я думаю, что вызывал 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

Надеюсь, это поможет.