Das Hinzufügen von Adressen zum Adressenarray von Struct bleibt nicht erhalten

Ich habe Probleme, das Array von "Beobachtern" dazu zu bringen, bestehen zu bleiben, nachdem ich:

  1. Stellen Sie den Vertrag bereit
  2. Erstelle Magic mit dem Namen "test1"
  3. watchMagic ausführen (mit der magischen ID von test1)
  4. Ausführen von watchMagic (mit der magischen ID von test1 von einem anderen Konto)
  5. Rufen Sie getMagicWatchers auf, das ein leeres Array zurückgibt

Irgendwelche Ideen?

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;
        }
}
Haben Sie 'require(registerMagicWatcher(magic, msg.sender));' debuggt? Dies ist möglicherweise Ihr Problem. Möglicherweise wird eine Ausnahme im Require-Stil generiert, die false zurückgibt.
@Malone, wenn es falsch zurückgeben würde, würde die Transaktion fehlschlagen, oder? es scheitert nicht im Remix
Require ist derzeit ein UNGÜLTIGER Opcode bis zur Veröffentlichung von Metropolis, wenn dies der Fall ist, wird die Transaktion kein Benzin usw. zurückerstatten. ethereum.stackexchange.com/questions/13502/…
@Malone danke für den Hinweis - weitere Informationen finden Sie hier, falls sich jemand wundert. Mein Verständnis ist, dass auch jetzt require() verwendet werden sollte. Irre ich mich?
Setzen Sie require(false) darunter, damit wir es ausschließen können, wenn es fehlschlägt.

Antworten (1)

Ihre createMagic-Funktion erstellt eine Magic-Instanz, speichert sie aber nie

    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;
    }