Solidity Assembly Frage - mstore

Ich habe gesucht, wie man in Solidity ein uint in Bytes umwandelt, und diese Antwort gefunden.

function toBytes(uint256 x) returns (bytes b) {
    b = new bytes(32);
    assembly { mstore(add(b, 32), x) }
}

Aus der Dokumentation ist mstore(p, v) mem[p..(p+32)] := v

Was bedeutet, dass mstore(add(b, 32), x) zu mem[(b+32)..(b+64)] := x übersetzt wird

Was habe ich hier falsch verstanden? Sicherlich ist b 32 Bytes und der Wert von x sollte in b kopiert werden, nicht direkt danach.

Danke

Antworten (1)

Die Erklärung ist ganz einfach:

  1. In Solidity ist Bytes ein Byte-Array mit dynamischer Größe:

Variablen vom Typ bytes und string sind spezielle Arrays. Ein bytes ist ähnlich wie byte[], aber es ist eng in calldata gepackt. string ist gleich Bytes, erlaubt aber (vorerst) keinen Längen- oder Indexzugriff.

  1. In Solidity Assembly sind Variablen Zeiger auf Speicheradressen.

  2. Arbeits- und Speicher werden in Blöcken von 32 Bytes verwaltet.

  3. Der erste Teil des Speichers eines Arrays speichert die Länge dieses Arrays.

Schauen wir uns nun Ihren Code an:

b = new bytes(32);

Dadurch wird eine Variable namens b vom Typ bytes erstellt .

Durch 1 wissen wir jetzt, dass b als Array behandelt wird.

Durch 2 wissen wir, dass b auf seine Speicheradresse zeigen wird.

Durch 3 und 4 wissen wir jetzt, dass b auf die Länge davon zeigt, und nur 32 Bytes danach ist die Speicheradresse, wo der Wert für b beginnt.

Wir wissen, dass add(b, 32)dies die um 32 addierte Speicheradresse von b zurückgibt (mit anderen Worten, die Speicheradresse, an der der Wert für b gespeichert werden soll ).

Endlich wissen wir also, warum mstore(add(b, 32), x)macht b = x.