Warum kann ich über 32 Zeichen in bytes32 speichern?

Ich habe einen Solidity-Vertrag mit Funktionen wie diesen:

function SetMessage (bytes32 key, bytes32 message) returns (bool success) {
    publicStruct[key].message = message;
    return true;
    }

    function GetMessage (bytes32 key) public constant returns (bytes32) {
    var message = publicStruct[key].message;
    return message;
    }

Dann verwende ich web3 zum Ausführen SetMessageund rufe dann auf, GetMessagenachdem das erledigt ist:

var mystringmessage = 'some string over 32 characters in length that can seem to be up to 128 characters in length to be stored in bytes32'
var key = 'message key'

MyContract.deployed().then(function (instance) {
          contractInstance = instance
          return contractInstance.SetMessage(key, mystringmessage, { gas: 200000, from: web3.eth.accounts[0] })
        }).then(function () {
          return contractInstance.GetMessage.call(key)
        }).then(function (messages) {
          console.log('MSG: ' + messages[0])
        })

Es scheint, dass jede Zeichenfolge mit bis zu 128 Zeichen in einem bytes32-Objekt von diesem gespeichert werden kann. Ich konvertiere auch nicht die gewöhnliche Javascript-Zeichenfolge in bytes32, bevor ich sie ausführe SetMessage, oder verwende web3.toAscii, um die bytes32 wieder in eine für Menschen lesbare Zeichenfolge zu konvertieren (wie ich es immer für notwendig hielt). Warum sollte ein einzelnes bytes32-Objekt mehr als 32 Zeichen speichern können?

Antworten (2)

bytes-x(1~32) kann eine Zeichenfolge speichern, wenn die Länge der Zeichenfolge größer als x ist, wird der Teil außerhalb der Länge gelöscht . Es ist ein einfacher Testvertrag

pragma solidity ^0.4.13;

contract Bytes32Test {

    bytes32 msg;

    function add(bytes32 _msg){
        msg = _msg;
    }

    function show() constant returns (bytes32){
        return msg;
    }

}

und ich rufe die add-Funktion durch einen Parameter auf 'eine Zeichenfolge mit einer Länge von über 32 Zeichen, die bis zu 128 Zeichen lang sein kann, um in bytes32 gespeichert zu werden', und jetzt rufen wir die Funktion show auf, das Ergebnis ist

0x736f6d6520737472696e67206f76657220333220636861726163746572732069

Das Ergebnis ist "irgendein String mit mehr als 32 Zeichen i", wenn wir es von Hex in ASCII konvertieren.

> web3.toAscii("0x736f6d6520737472696e67206f76657220333220636861726163746572732069")
"some string over 32 characters i"

Hoffe es hilft~

Ich verstehe, dass es so funktioniert. Ich bin verwirrt, warum in meinem Beispiel der Aufruf von GetMessage, das bytes32 zurückgibt, irgendwie eine für Menschen lesbare Zeichenfolge zurückgibt, die auch länger als 32 Zeichen sein kann
Ich hatte die GetMessage-Funktion getestet, sie gibt ein hex-codiertes Ergebnis zurück, da der Rückgabetyp bytes32 und keine Zeichenfolge ist. Wenn Sie einen lesbaren Zeichenfolgentyp zurückgeben möchten, wie folgt: ' function GetMessage (bytes32-Schlüssel) öffentliche Konstante gibt (Zeichenfolge) zurück { var message = publicStruct[key].message; Rückgabe bytes32ToString (Nachricht); }'
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); }

Ich denke, es hängt davon ab, was Sie darin speichern. Angenommen, ein 64-Bit-Wort,

"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8"

Wenn Sie das als Zeichenfolge übergeben (bytes32 word = "0x1c8..."), ist es 64 Bytes lang und die 32 Zeichen danach können abgeschnitten werden, aber wenn Sie es als hex betrachten (bytes32 word = 0x1c8...), sehen Sie das Fehlen von Anführungszeichen, dann sind es genau 32 Bytes als Ziffer in hex bezeichnet ein Nibble, 2 Ziffern bezeichnen ein Byte.