bytes32
Wie kann ich a in a umwandeln string
? Hat jemand eine magische Funktion oder Bibliothek, die es tut?
Basierend auf der neuesten Compiler-Version 0.4.24 verwende ich Folgendes.
function convertingToString()public returns(string){
bytes32 memory hw = "Hello World";
string memory converted = string(hw);
return converted;
}
Verwenden der expliziten Konvertierung, um dies auszuführen. Auch der umgekehrte Weg ist möglich.
Für die Versionen 0.5.0+ verwenden Sie bitte (getestet von 0.5 bis 0.7.2 - es ist wahrscheinlich, dass es nach 0.7.2 weiter funktioniert):
function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) {
uint8 i = 0;
while(i < 32 && _bytes32[i] != 0) {
i++;
}
bytes memory bytesArray = new bytes(i);
for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
bytesArray[i] = _bytes32[i];
}
return string(bytesArray);
}
0x5bda7162b84dff721bcb8f777278b488ded8d1475264d4361c6b0abfcc2a99a8
Ab Februar 2021 können Sie dies tun
bytes32 foo = "hello";
string memory bar = string(abi.encodePacked(foo));
Hier ist eine:
function bytes32ToString(bytes32 x) constant returns (string) {
bytes memory bytesString = new bytes(32);
uint charCount = 0;
for (uint j = 0; j < 32; j++) {
byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
if (char != 0) {
bytesString[charCount] = char;
charCount++;
}
}
bytes memory bytesStringTrimmed = new bytes(charCount);
for (j = 0; j < charCount; j++) {
bytesStringTrimmed[j] = bytesString[j];
}
return string(bytesStringTrimmed);
}
Zum Testen wird es hier kombiniert mit dem Verketten eines Arrays vonbytes32
. Fügen Sie Folgendes in Remix ein .
contract C {
function bytes32ToString(bytes32 x) constant returns (string) {
bytes memory bytesString = new bytes(32);
uint charCount = 0;
for (uint j = 0; j < 32; j++) {
byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
if (char != 0) {
bytesString[charCount] = char;
charCount++;
}
}
bytes memory bytesStringTrimmed = new bytes(charCount);
for (j = 0; j < charCount; j++) {
bytesStringTrimmed[j] = bytesString[j];
}
return string(bytesStringTrimmed);
}
function bytes32ArrayToString(bytes32[] data) returns (string) {
bytes memory bytesString = new bytes(data.length * 32);
uint urlLength;
for (uint i=0; i<data.length; i++) {
for (uint j=0; j<32; j++) {
byte char = byte(bytes32(uint(data[i]) * 2 ** (8 * j)));
if (char != 0) {
bytesString[urlLength] = char;
urlLength += 1;
}
}
}
bytes memory bytesStringTrimmed = new bytes(urlLength);
for (i=0; i<urlLength; i++) {
bytesStringTrimmed[i] = bytesString[i];
}
return string(bytesStringTrimmed);
}
}
Klicken Sie auf „Erstellen“. Geben Sie dann in bytes32ToString
das Feld ein "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
und klicken Sie auf bytes32ToString
.
Geben Sie im bytes32ArrayToString
Feld ein ["0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]
und klicken Sie auf bytes32ArrayToString
.
Beide zeigen dasselbe Ergebnis (ABI-Codierung): Ergebnis:"0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
Hier ist ein weiteres Beispiel. Geben Sie im bytes32ToString
Feld ein "0xc3b6"
und klicken Sie auf bytes32ToString
. Du wirst bekommen ö
.
bytes32ArrayToString
mit einem festen bytes32[10]
, aber es scheint, dass ich einen werfe, invalid opcode
wenn ich 8-10 volle Slots des Arrays verwende. Das heißt, ich habe einen Test für abcdefghijklmnopqrstuvwxyzabcdef
(32 Zeichen) 10 Mal in einem Array und übergebe das, aber es wirft. Wenn ich 7 oder weniger habe, funktioniert es. Irgendeine Idee warum?So konvertieren Sie ein bytes32 in einen String:
pragma solidity ^0.4.15;
contract Bytes32ToString {
function bytes32ToStr(bytes32 _bytes32) public pure returns (string) {
// string memory str = string(_bytes32);
// TypeError: Explicit type conversion not allowed from "bytes32" to "string storage pointer"
// thus we should fist convert bytes32 to bytes (to dynamically-sized byte array)
bytes memory bytesArray = new bytes(32);
for (uint256 i; i < 32; i++) {
bytesArray[i] = _bytes32[i];
}
return string(bytesArray);
}
}
Wie bei @e18r bereits erwähnt, ist der einfachste Weg, dies zu tun, ohne all diese verrückten Funktionen schreiben zu müssen, mit denen alle anderen antworten (und mehr Benzin kosten würden), einfach:
string(abi.encodePacked(bytes32));
Es wird empfohlen, mithilfe von Web3.js a bytes32
in a umzuwandeln, um Benzinkosten zu vermeiden. string
Um dies zu tun, würden Sie den Wert bytes32
von Solidity an das Frontend abrufen und dann Folgendes tun:
web3.utils.hexToString(bytes32);
Dadurch wird die bytes32
in eine konvertiert, die string
Sie dann in Ihrer Frontend-dApp sehen und verwenden können.
Für alle Fälle, wenn Sie bytes32 in ASCII-Strings konvertieren möchten, können Sie die OpenZeppelin Strings-Bibliothek verwenden.
https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2504
Strings.toHexString(uint256(tokenIdSeed), 32),
Die Ausgabe sollte wie sein
0xd8df8ecd5432b247d2fc2beb0619d637e9de0df7512bd36220582deda9a1df6e
(Dies ist nur ein verdeckter Hexadezimalwert der Bytes32 in den String)
In Version 0.5.0 und höher endete ich mit der Verwendung von Viktor answer How to convert a bytes32 to string , aber das Entfernen der Nullen, sonst werden Sie damit enden
'ERC20\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'
Anstatt von
'ERC20'
Dies ist der Code:
/* bytes32 (fixed-size array) to string (dynamically-sized array) */
function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) {
uint8 i = 0;
while(i < 32 && _bytes32[i] != 0) {
i++;
}
bytes memory bytesArray = new bytes(i);
for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
bytesArray[i] = _bytes32[i];
}
return string(bytesArray);
}
Eine gaseffizientere Methode basierend auf dieser Antwort (für Versionen 0.5.0+):
function toString(bytes32 source)
internal
pure
returns (string memory result)
{
uint8 length = 0;
while (source[length] != 0 && length < 32) {
length++;
}
assembly {
result := mload(0x40)
// new "memory end" including padding (the string isn't larger than 32 bytes)
mstore(0x40, add(result, 0x40))
// store length in memory
mstore(result, length)
// write actual data
mstore(add(result, 0x20), source)
}
}
Diese Lösung verwendet Assembly, um Daten in den Speicher zu kopieren, anstatt for
Schleifen zu verwenden.
So mache ich es:
function char(byte b) returns (byte c) {
if (b < 10) return byte(uint8(b) + 0x30);
else return byte(uint8(b) + 0x57);
}
function bytes32string(bytes32 b32) returns (string out) {
bytes memory s = new bytes(64);
for (var i = 0; i < 32; i++) {
byte b = byte(b32[i]);
byte hi = byte(uint8(b) / 16);
byte lo = byte(uint8(b) - 16 * uint8(hi));
s[i*2] = char(hi);
s[i*2+1] = char(lo);
}
out = string(s);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract stringtobytes{
function set(string memory _a)public pure returns(bytes memory){
return bytes(_a);
}
function set1(bytes memory _a)public pure returns(string memory){
return string(_a);
}
}
// Sie können Zeichenfolgen in Bytes (im Dezimalformat) und umgekehrt mit dem folgenden Code konvertieren
//1- Bytes1=8bit=2dezimal
//2 Bytes2=16bit=4dezimal
//3 Bytes3=24bit=6dezimal
//4 Bytes=dynamisches Array und Referenzwert
eur10
arodriguezdonaire
Paul S
arodriguezdonaire