Die Vertragsmethode funktioniert nur mit Vertragsadressen und nicht mit regulären Kontoadressen

Ich habe zu Testzwecken einen einfachen Token-Vertrag geschrieben:

pragma solidity ^0.4.18;

contract TestToken {
    uint public totalSupply;

    mapping(address => uint) public balanceOf;

    function transfer(address to, uint amount) public returns (bool) {
        require(balanceOf[msg.sender] >= amount);
        balanceOf[msg.sender] -= amount;
        balanceOf[to] += amount;
        return true;
    }

    function credit(address to, uint amount) public {
        balanceOf[to] += amount;
        totalSupply += amount;
    }

    function debit(address from, uint amount) public {
        balanceOf[from] -= amount;
        totalSupply -= amount;
    }
}

Immer wenn ich die creditMethode für den Vertrag aufrufe und die Adresse eines anderen Vertrags als Parameter übergebe, funktioniert alles wie erwartet:

token.methods.credit(wallet._address, 500000).send({from: accounts[0], gas: "0xB3E4", gasPrice: "0x4A817C800", value: "0x"})

Der Status der Transaktion ist 0x1.

Der Saldo wird aktualisiert:

token.methods.balanceOf(wallet._address).call()
'500000'

Aber wenn ich die Adresse eines regulären Ethereum-Kontos als Parameter übergebe, wird die Transaktion abgebaut, aber es passiert nichts.

token.methods.credit(accounts[0], 500000).send({from: accounts[0], gas: "0xB3E4", gasPrice: "0x4A817C800", value: "0x"})

Der Status der Transaktion ist 0x0.

Das Gleichgewicht ändert sich nicht:

token.methods.balanceOf(accounts[0]).call()
'0'

Beim Vergleich der resultierenden signierten Transaktionsobjekte besteht der einzige Unterschied außer dem dataFeld darin, dass der Signaturwert vimmer lautet, 0wenn die Transaktion fehlschlägt und 1wenn die Transaktion erfolgreich ist. Aber ich bin mir nicht sicher, was das bedeutet.


Aktualisieren:

Scheint nicht einmal Vertrag vs. Nichtvertrag zu sein, es ist nur so, dass einige Adressen nicht funktionieren.

Das funktioniert zum Beispiel:

token.methods.credit('0xd2d0aD819B2679FBDD5C75F93fa13242bfd7E2A5', 500000000000000000).send({from: accounts[0], gas: "0xB3E4", gasPrice: "0x4A817C800", value: "0x"})

Dies nicht:

token.methods.credit('0xc4beccd2ebdb32203800dfbc60ff0dd7c2762b48', 500000000000000000).send({from: accounts[0], gas: "0xB3E4", gasPrice: "0x4A817C800", value: "0x"})
Eine mögliche Ursache ist, dass Ihr Gas nicht ausreicht, um Ihre Transaktion zu decken. Eine Transaktion wird billiger, wenn der Empfänger ein Guthaben ungleich Null hat.
Genau das war das Problem. Ich habe nicht berücksichtigt, dass es mehr Gas kostet, die Kontostandszuordnung für dieses Konto zu erstellen, wenn ein Konto noch keinen Kontostand hat. Und so ging mir der Sprit aus, als ich die Methode mit neuen Adressen aufrief.

Antworten (2)

Das Problem liegt höchstwahrscheinlich am Gaslimit. Wie hast du es berechnet?

Wenn an die Transaktion einige Daten angehängt sind, z. B. Methodenselektor und Parameter des Vertrags, kosten null Bytes weniger als null. Eine Transaktion, die Token an sendet, 0x0011223344556677889900112233445566778899kostet also weniger als eine Transaktion, die die gleiche Anzahl von Token an sendet 0x112233445566778899aa112233445566778899aa. Außerdem kostet es mehr, den Wert im Speicher von Null auf Nicht-Null zu ändern, als ihn von Nicht-Null auf Nicht-Null zu ändern. Kostet also balanceOf[to] += amount;weniger, wenn todie Adresse bereits einige Token hat.

  1. Sie senden von Konto[0] an Konto[0], sodass das Guthaben gleich bleibt
  2. Wenn der Saldo von (Konten[0]) Null ist, wie Sie in Ihrem zweiten Aufruf zeigen, schlägt der Anruf wegen der Anforderung (balanceOf[msg.sender] >= Betrag) fehl.
Entschuldigung, ich habe den Fragentitel falsch eingegeben, ich habe über die creditFunktion gesprochen, die neue Token prägt.