Wie konvertiere ich eine Zeichenfolge in Bytes32?

stringWie kann ich a in a umwandeln bytes32? Hat jemand eine magische Funktion oder Bibliothek, die es tut?

Zum Beispiel: Dies funktioniert, da ich als Eingabe 32-Bit angegeben habe. Aber es funktioniert nicht mit "> 32-Bit" Zeichen.

set_txn_hash = a.transact().set("QmVoGzRDscx61k3RHHkLYaMFtxYZi3ps");#32-bit char

-

function get() returns (stringc value){  
    return list.get_head_data();   
}

Aber wenn ich mehr Zeichen angeben muss, zum Beispiel eine 48-Bit-Zeichenfolge enthält, funktioniert dies nicht. [F] Wie könnte ich das zum Laufen bringen?

Antworten (7)

Das hat bei mir bisher funktioniert. Nicht sicher, ob es der beste Weg ist.

function stringToBytes32(string memory source) public pure returns (bytes32 result) {
    bytes memory tempEmptyStringTest = bytes(source);
    if (tempEmptyStringTest.length == 0) {
        return 0x0;
    }

    assembly {
        result := mload(add(source, 32))
    }
}

Denken Sie auch daran, dass Zeichenfolgen in Solidity UTF8 sind, sodass nach der Konvertierung in Bytes nicht jedes Byte unbedingt ein Zeichen ist.

EDIT: kürzere Version, sollte gleich funktionieren.

erwarteter elementarer Inline-Montagevorgang. bytes32-Ergebnis := mload(add(source, 32)) ^ Contracts/Link.sol:77:22: Fehler: Erwartetes Token-Semikolon hat 'Doppelpunkt' bytes32-Ergebnis := mload(add(source, 32))
@Avatar Sie haben, bytes32 result :=während mein Code das Ergebnis deklariert, Typ in returns (bytes32 result), entfernen Sie einfach das bytes32von vorher result := ...und es sollte kompilieren.
tolle werke!! Danke mein Herr. Eine letzte Frage ist, wenn meine Zeichenfolge größer als 32 Bit ist, z. B. 48 Bit, werden die verbleibenden 12 Bit gekürzt. Gibt es eine zusätzliche Montagelinie, auf der ich Bits von 32 bis 48 erhalten kann? vielen Dank für Ihre wertvolle Zeit. als ich "result := mload(add(source, 64))" gemacht habe, hat es funktioniert!
Ich habe Ihren Code in remix.ethereum.org (unter Verwendung von JavaScript VM) ausprobiert und "EOS8WE79SonHGHc5DquV4fxty9bHfnLSugCyTVXj2n9t4Uw5HL2vU" als meine Zeichenfolge eingegeben, die 56 Zeichen lang ist. Es wurde zurückgegeben: "0x454f533857453739536f6e4847486335447175563466787479396248666e4c53" Wenn ich dies in ASCII umwandle, erhalte ich "EOS8WE79SonHGHc5DquV4fxty9bHfnLS", das sind 34 Zeichen. Wieso den? Wie bekomme ich die ursprünglichen 56 Zeichen zurück?
@Curt kannst du nicht, die Konvertierung von String in Bytes32 ist verlustbehaftet. bytes32 kann nur 32 8-Bit-Zeichen enthalten, aber Zeichenfolgen können länger als 32 Zeichen sein und während dieser Operation gehen alle Zeichen über 32 verloren. Die Zeichenfolge, die Sie eingefügt haben, hat 32 Zeichen, ich habe die Anführungszeichen nicht gezählt.
Außerdem sollte diese Funktion wohl als "intern" gekennzeichnet werden, um etwas Sprit zu sparen
Es hat eine Weile gedauert, bis ich es für Interessierte herausgefunden habe: AFAIK 'Quelle' innerhalb von Assembly bezieht sich in diesem Zusammenhang auf die Speicheradresse der Quelle, nicht auf die Zeichenfolge, auf die sie zeigt. Dann fügen wir 32 zu dieser Adresse hinzu, da die ersten 32 Bytes anscheinend reserviert sind, um die Anzahl der Zeichen in der Zeichenfolge (/Länge des Arrays) aufzunehmen.
Könnt ihr erklären, warum dieser Code funktioniert? Welche Bedeutung hat das Hinzufügen von 32 zum Speicheradressenzeiger der Zeichenfolge, und wie wird er dadurch in bytes32 konvertiert?

stringist nicht gleich bytes32aber gleich bytes, weil seine Länge dynamisch ist.

Sie könnten also ein Casting gebrauchenbytes B=bytes(S); //S string

Z.B

contract string_test {

    function string_tobytes( string s) constant returns (bytes){
        bytes memory b3 = bytes(s);
        return b3;
    }
}

Die Konvertierung von stringnach bytes32ist nur über Assembler möglich

Fehler: Explizite Typkonvertierung nicht zulässig. Bytes b = Bytes ("a");
Probieren Sie den neuen Code oben mit der Speichervariable aus.
TypeError: Explizite Typumwandlung von „literal_string „mined““ in „bytes storage pointer“ nicht zulässig.bytes memory data = bytes("mined");

ethers.js hat dafür eine eingebaute Hilfsfunktion: https://docs.ethers.io/ethers.js/html/api-utils.html#bytes32-strings

const ethers = require('ethers')
const utils = ethers.utils

const inBytes = utils.formatBytes32String("test");
Das sollte die richtige Lösung sein, meine Herren
Ich glaube nicht, dass dies die Frage beantwortet, wie man das in einem Smart Contract macht, nicht wie man es mit Javascript macht.
@GGizmos vielleicht, aber danach habe ich auch gesucht und die Suche hat mich hierher gebracht

Die Assemblierung ist in Version 0.8.7 nicht erforderlich

string text = "whatever"; 
bytes32 stringInBytes32 = bytes32(bytes(text));
Ich habe das versucht, was ich tun möchte, ist eine Bytes32-Zeichenfolge an Solidity zu senden und in einer Bytes32-Variablen zu speichern. If I take the input string: '0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d' and follow your code (bytes32(bytes(inputstring) I get '0x3078343162316130363439373532616631623238623364633239613135353665' from console.logBytes32 inside the solidity function. Seems to be all integers, altho the right length. Any ideas why that ist:
@GGizmos, Text soll eine Zeichenfolge von UTF-8-Zeichen sein. Sie verwenden einen Hexadezimalwert, ich weiß nicht, wie das in diesem Fall geht.
Wenn ich dies versuche, erhalte ich die explizite Typkonvertierung von "Bytes Speicher" nach "Bytes32" nicht erlaubt. Verwenden einer Zeichenfolge aus einem Parameter.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract stringtobytes{
    function set(string memory  _a)public pure returns(bytes memory){
        return (bytes(_a));
    } 
}

Sie können Zeichenfolgen mit dem folgenden Code in Bytes (im Dezimalformat) konvertieren

1-Bytes1=8bit=2dezimal

2 Bytes2=16bit=4dezimal

3 Bytes3=24bit=6dezimal

4 Bytes=dynamisches Array und Referenzwert

Die Frage bezog sich auf die Konvertierung von String in Bytes32, Ihr Beispiel funktioniert nicht für Bytes32.
function get(string memory key) 
    public 
    view 
    returns (bytes32) {
        return bytes32(abi.encodePacked(key));
}
Ich bekomme - Explizite Typkonvertierung von "Bytes Speicher" nach "Bytes32" nicht erlaubt.
@NickJ Die Antwort ist richtig. Überprüfen Sie Ihren Code.

Bitte verweisen Sie darauf. Sie können eine Zeichenfolge in ein bytes32-Array konvertieren. Die Länge der Zeichenfolge kann länger als 32 sein.

https://ethereum.stackexchange.com/a/13388/6353