Agregar dirección a la matriz de direcciones de Struct no persiste

Tengo problemas para que la matriz de "observadores" persista después de que yo:

  1. Implementar el contrato
  2. Crear magia con el nombre "test1"
  3. Ejecutar watchMagic (con el id mágico de test1)
  4. Ejecute watchMagic (con la identificación mágica de test1 de una cuenta diferente)
  5. Llame a getMagicWatchers que devuelve una matriz vacía

¿Algunas ideas?

contract WTF {

        struct Magic {
            bytes32 id;
            string name;
            address[] watchers;
        }

        uint _nonce;

        mapping (bytes32 => Magic) public allMagic;

        uint private _numWatchersMax = 16;

        function countWatchers(Magic magic) internal returns(uint) {
            uint count;
            uint i;
            for (i = 0; i < magic.watchers.length; i++) {
                if (address(0) != magic.watchers[i]) {
                    count++;
                }
            }
            return count;
        }

        function registerMagicWatcher(Magic magic, address watcher) internal returns(bool success) {
            magic.watchers[countWatchers(magic)] = watcher;
            return true;
        }

        function createMagic(string name) public returns(bytes32 magicId) {
            Magic memory magic = Magic({
                id: keccak256(msg.sender, name, _nonce++),
                name: name,
                watchers: new address[](_numWatchersMax)
            });

            require(registerMagicWatcher(magic, msg.sender));

            return magic.id;
        }

        function getMagicWatchers(bytes32 magicId) returns(address[] watchers) {
            return allMagic[magicId].watchers;
        }

        function watchMagic(bytes32 magicId) returns(bool success) {
            require(allMagic[magicId].id == magicId); // ensure magic with this id exists
            require(countWatchers(allMagic[magicId]) < _numWatchersMax);

            bool alreadyWatcher = false;
            uint i;
            for (i = 0; i < allMagic[magicId].watchers.length; i++) {
                if (msg.sender == allMagic[magicId].watchers[i]) {
                    alreadyWatcher = true;
                    break;
                }
            }
            require(alreadyWatcher == false);

            require(registerMagicWatcher(allMagic[magicId], msg.sender));
            return true;
        }
}
¿Ha depurado 'require(registerMagicWatcher(magic, msg.sender));'? Este es potencialmente tu problema. Es posible que tenga una excepción de estilo requerido generada al devolver falso.
@Malone si devolviera falso, la transacción fallaría, ¿verdad? no falla en remix
Requerir es actualmente un código de operación NO VÁLIDO hasta el lanzamiento de Metropolis, si este es el caso, la transacción no reembolsará el gas, etc. ethereum.stackexchange.com/questions/13502/…
@Malone gracias por el aviso: encontré más información aquí en caso de que alguien se lo pregunte. Tengo entendido que incluso ahora se debe usar require(). ¿Estoy equivocado?
Ponga require(false) debajo para que podamos descartarlo si falla.

Respuestas (1)

Su función createMagic crea una instancia de Magic pero nunca almacena

    function createMagic(string name) public returns(bytes32 magicId) {

        // Allocates magic inmemory
        Magic memory magic = Magic({
            id: keccak256(msg.sender, name, _nonce++),
            name: name,
            watchers: new address[](_numWatchersMax)
        });

        // Add msg.sender as watcher
        require(registerMagicWatcher(magic, msg.sender));

        // Save magic in storage
        allMagic[magic.id] = magic;             // <------- Missing part

        // return id
        return magic.id;
    }