bytes32 Hex-Strings gleicher Länge kosten unterschiedliches Gas, warum?

Ich kann den Unterschied in Gas für das folgende Problem nicht verstehen. Ich habe einen sha256-Hashwert generiert und die Ausgabe habe ich als Hexadezimal-Kleinbuchstaben ausgewählt. Der Ausgabewert ist also eine hexadezimale Zeichenfolge mit 64 Zeichen. Dann habe ich diesen Wert in einer bytes32-Variablen in einem Smart Contract gespeichert. Der Code des Smart Contracts lautet:

pragma solidity ^0.4.23;

contract Project {
    bytes32 public value;

    function addValue(bytes32 val) public {
        value = val;
    }
}

Mit Remix habe ich festgestellt, dass die Operation zum Hinzufügen eines Werts 43629 für einige Werte und andere 43693 kostet. Die Differenz beträgt also 64 Gas. Kann mir jemand helfen zu verstehen, warum das passiert? Ich habe viele Werte getestet und der Unterschied war 64 Gas, war es Zufall? Ich habe auch getestet, um es als Zeichenfolge zu speichern. Dann waren die Kosten für alle Eingaben konstant, vielleicht weil die Werte die gleiche Länge haben, wie ich sagte, die Eingabewerte haben 64 Zeichen.

Nur eine Vermutung, aber ist der Unterschied, wie viele Bytes 0 in der Eingabe sind?
@smarx Ich habe es für zwei Eingänge getestet, die beide sieben Nullen haben. Der eine kostete 43629 und der andere 64 Benzin mehr, also 43693, also denke ich nicht, dass die Nullen wichtig sind. Aber nette Idee, ich habe nicht daran gedacht, es zu überprüfen, bevor Sie es bemerken.
Zur Verdeutlichung zählen Sie die Anzahl der vollständigen Bytes, die 0 sind, und nicht nur die Gesamtzahl der 0, die in der hexadezimalen Zeichenfolge vorkommen? (Zum Beispiel hat 0x102030 keine Nullbytes, aber 0x100020 hat ein Nullbyte.)
@smarx ok, also habe ich es falsch gemacht, ich habe die Anzahl der Nullen gezählt, dumm von mir. Du meinst also, ich sollte es in Binär umwandeln und dann sollte ich Teams aus aufeinanderfolgenden 8 Bits bilden und sehen, ob ein "Team" alle Bits 0 hat? Entschuldigung, wenn mein Englisch nicht gut ist
Nun, hexadezimal ist in Ordnung. Alle zwei hexadezimalen Zeichen sind ein einzelnes Byte. Wenn Sie nur die Werte teilen würden, die Sie hier testen, wäre dies viel einfacher.
@smarx for example a value that cost 43629 is "0x44c6a374366f345cec0fa7d98eddf8185a533d4f3922c9c9397c38e8a8f526e2" and the other with 64 less gas is "0xd5bf2cb491dd63f800373f16ab0fc486ffe040923587c00adcead3dc4a4544b6". Also sind die aufeinanderfolgenden Nullen in der zweiten Eingabe das Problem?
@smart Bravo! Du hattest Recht! Jetzt bekomme ich es, ich teile es in Teams von zwei aufeinanderfolgenden auf, damit ich ein Byte bekomme. Dann sehe ich, wie viele Teams nur Nullen sind. Ja, die zweite Saite hat ein Team aus Nullen, kostet also 64 weniger. Dann füge ich diesen einen "0x44c6a374366f345cec0fa7d98eddf8185a533d4f3922c9c9397c38e8a8f50000" ein, der die erste Zeichenfolge mit 4 Nullen am Ende ist. Also 2 Bytes Null und es kostet 120 weniger. Danke schön!!!
Es hätte 128 weniger kosten sollen als ein Wert ohne Nullen. Siehe meine Antwort für ein wenig mehr Details.
@smarx Ich weiß, es ist kein Thema, aber wissen Sie zufällig, wie viele Nullbytes in einer Ausgabe von sha256 vorkommen können? Ja richtig 128 !
Die Ausgabe von sha256 beträgt 256 Bit, also 32 Byte. Es können also bis zu 32 Nullen vorkommen.

Antworten (1)

Aus dem Gelben Papier :

Gtxdatazero 4 Bezahlt für jedes Nullbyte an Daten oder Code für eine Transaktion.

Gtxdatanonzero 68 Bezahlt für jedes Nicht-Null-Byte an Daten oder Code für eine Transaktion

Wenn Sie also in Ihren Transaktionsdaten eine Nicht-Null durch eine Null ersetzen, reduzieren Sie die Kosten um 64 (68-4).

Beachten Sie, dass aufeinanderfolgende Nullen nicht unbedingt wichtig sind, nur wenn sie ein vollständiges Byte darstellen. Es ist einfacher zu sehen, wenn Sie Bytes trennen: d5 bf 2c b4 91 dd 63 f8 00 37 3f 16 ab 0f c4 86 ff e0 40 92 35 87 c0 0a dc ea d3 dc 4a 45 44 b6. Der zweite Wert, den Sie in Ihrem Kommentar erwähnt haben, hat also genau ein Nullbyte.