String-Typ oder bytes32 verwenden?

Welche Vorteile bietet die Verwendung von stringDatentypen bytes32zur Darstellung von Textdaten ? Es scheint, dass mein Vertrag in eine Gasmangel-Ausnahme gerät, wenn ich die Datenstrukturen von bytes32auf ändere string.

Antworten (3)

Warum stringstatt bytes32?

Für Zeichenfolgendaten beliebiger Länge (UTF-8) verwenden string, die länger als 32 Byte sind. Frontends können eine lange Zeichenfolge einfacher mithilfe von Methoden wie web3.toAscii oder UTF-8 (wenn Probleme behoben sind) decodieren, anstatt die Logik von UTF-8 zu implementieren, die eine Reihe von bytes32.

Aus Solidity-Dokumenten:

Verwenden Sie als Faustregel bytesfür Rohbytedaten beliebiger Länge und stringfür Zeichenfolgendaten beliebiger Länge (UTF-8). Wenn Sie die Länge auf eine bestimmte Anzahl von Bytes begrenzen können, verwenden Sie immer eine von bytes1bis, bytes32da diese viel billiger sind.

Zeichenfolgenliterale können auch hilfreich oder praktisch sein:

Zeichenfolgenliterale werden entweder mit doppelten oder einfachen Anführungszeichen ("foo" oder "bar") geschrieben ...

Zeichenfolgenliterale unterstützen Escapezeichen wie \n, \xNN und \uNNNN. \xNN nimmt einen Hex-Wert und fügt das entsprechende Byte ein, während \uNNNN einen Unicode-Codepunkt nimmt und eine UTF-8-Sequenz einfügt.


Warum bytes32statt string?

Beantwortet in Warum verwenden Solidity-Beispiele den Typ bytes32 anstelle von Zeichenfolgen?

bytes32verbraucht weniger Gas, weil es in ein einzelnes Wort des EVM passt, und stringist ein Typ mit dynamischer Größe, der aktuelle Einschränkungen in Solidity hat (z. B. kann nicht von einer Funktion zu einem Vertrag zurückgegeben werden).

Ich bin mir nicht sicher, ob ich den letzten Satz verstanden habe - String-Rückgabetypen funktionieren im aktuellen Solidity-Compiler.
@MikkoOhtamaa Der Schwerpunkt liegt auf einem Vertrag : Ich glaube nicht, dass ethereum.stackexchange.com/a/3788/42 noch unterstützt wird.
Ok, wenn Sie einen kontrollierenden Vertrag haben und auf Daten aus einem anderen Vertrag zugreifen, der Text zurückgibt, der länger als 32 Byte ist, müssten Sie ihn in einem bytes32-Array zurückgeben?
@ethereal Klingt richtig, gib dem Array eine Größe wie bytes32[3]. Es kann Assembler-Methoden geben, um die Größe der zurückgegebenen Daten zu ermitteln und eine fest codierte Größe zu vermeiden, z. B. die Verträge in github.com/ownage-ltd/ether-router
Wenn ein Vertrag nicht auf die String-Variablen eines anderen Vertrags zugreifen kann, was dann? Kann web3? Was ist, wenn ich eine Liste oder ein Array mit 60 Zeichen langen Zeichenfolgen speichern möchte, aber von einem anderen Vertrag oder Programm darauf zugreifen muss, wie mache ich das?
Wenn ich weiß, dass ich sagen muss, dass eine 50 lange Zeichenfolge gespeichert werden muss, ist es billiger, zwei Bytes32 zu verwenden und sie aufzuteilen oder Bytes/String zu verwenden?
@ClementWalter Ja, ich denke, zwei Bytes32 billiger. Ihr Frontend/Ihre Benutzeroberfläche sollte das Split/Concat durchführen. Sie möchten wahrscheinlich beide testen, um zu sehen, was Sie insgesamt bevorzugen.

Wie der andere Beitrag sagte, möchten Sie nur Zeichenfolgen für dynamisch zugewiesene Daten verwenden, da Byte32 sonst eine bessere Leistung erbringt. Bytes32 wird auch beim Gas besser sein. Wenn Sie damit herumspielen möchten, habe ich eine kleine Geige daraus gebaut https://ethfiddle.com/70ipaEIFdk

Byte verwendet 21465 Gas

String verwendet 21897 Gas

pragma solidity ^0.4.18;

contract SampleOverflow {
  string constant statictext = "HelloStackOverFlow";
  bytes32 constant byteText = "HelloStackOverFlow";
  function  getString() payable public  returns(string){
    return statictext;
  }

  function  getByte() payable public returns(bytes32){
    return byteText;
  }
}

Bytes bekommenGeben Sie hier die Bildbeschreibung ein

Holen Sie sich die Zeichenfolge https://ethfiddle.com/70ipaEIFdkGeben Sie hier die Bildbeschreibung ein

diese Geige funktioniert nicht. Ich denke, es hat mit den doppelten Anführungszeichen zu tun. Ich habe versucht, Fluchtzeichen zu entfernen, aber eth fiddle hat das auch nicht getan. Hier ist Ihr Beispiel, in dem ethfiddle.com/SeXTGt-AWi funktioniert

bytes32 bedeutet Zeichenfolge mit maximaler Länge 32. Es benötigt weniger Speicher als Zeichenfolge für die gleiche Länge der Zeichenfolge.

Wenn Ihre Daten also nicht mehr als 32 Bytes (32 Wörter) umfassen, verwenden Sie bytes32.

Wenn die Länge der Zeichenfolge nicht definiert ist, verwenden Sie einfach bytes.

auch byte8, byte16, byte32 sind alle verfügbar. Sie können alle gemäß den Bedingungen verwenden.

Vielen Dank für die einfache Antwort, ich möchte nur die dritte Anweisung "Wenn die Länge der Zeichenfolge nicht definiert ist, verwenden Sie eine Zeichenfolge" klären. In diesem Fall können wir Bytes anstelle von String oder Bytes32 verwenden, richtig?
bytes32 kann bis zu 32 Buchstaben (ASCII) speichern, wenn Sie mehr Länge benötigen, verwenden Sie String.
Ja, ich verstehe dich, aber wir können Bytes verwenden, nicht Byte32 , um mehr Länge anstelle von String zu speichern?
o ja, du hast recht, entschuldigung, ich aktualisiere die antwort.
Wenn Sie nur bei 'Bytes' bleiben, ist es auf eine bestimmte Standardnummer eingestellt? Wenn ja, was ist das, ist es 'bytes32'?