abi.encodeVollgepackt mit vielen Nullen

Gemäß dieser Dokumentation

Typen, die kürzer als 32 Byte sind, werden weder mit Nullen aufgefüllt noch vorzeichenerweitert und

Wenn ich abi.encodePacked (Adresse, uint, uint, Adresse) verwende, erhalte ich ein Ergebnis mit vielen Nullen. Zum Beispiel:

address addr = "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C";
uint x = 123;

abi.encodePacked(addr , x , x , addr)
0x14723a09acff6d2a60dcdf7aa4aff308fddc160c000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007b14723a09acff6d2a60dcdf7aa4aff308fddc160c

Sollte es nicht ohne Nullen sein.

Ändern Sie uint in uint8 und versuchen Sie es erneut

Antworten (2)

uint ist 256 Bit, also ist alles richtig kodiert:

first parameter:  14723a09acff6d2a60dcdf7aa4aff308fddc160c
second parameter: 000000000000000000000000000000000000000000000000000000000000007b
third parameter:  000000000000000000000000000000000000000000000000000000000000007b
fourth parameter: 14723a09acff6d2a60dcdf7aa4aff308fddc160c

es sollte nicht ohne Nullen sein, es dauert die ganzen 32 Bytes.

Ich kenne Ihre Verwirrung, Sie könnten einige Missverständnisse über die Funktion "abi.encodePacked(...)" haben.

Wie das Dokument sagt, "Typen, die kürzer als 32 Bytes sind, werden nicht mit Nullen aufgefüllt", aber der Typ, den Sie verwenden, ist uint, was genau ein 32-Byte-Typ ist.

Probieren Sie einfach folgenden Code aus:

contract Test {

    function test() public pure returns (bytes memory, bytes memory) {
        int8 a = 1;
        uint16 b=2;
        return (abi.encode(a,b), abi.encodePacked(a,b));
    }
}

und das Ergebnis wird sein:

0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002

Und

0x010002

Beachten Sie, dass ich in diesem Vertrag int8 und uint16 verwende, der Unterschied besteht also darin, dass "abi.encode" jeden Parameter auf 32 Bytes auffüllt, während "abi.encodePacked" dies nicht tut.