Wie verkettet man ein bytes32[]-Array mit einer Zeichenfolge?

Ich übergebe ein Array von bytes32 an meine Funktion. Dieses Array kann Zahlen oder Hashes usw. enthalten, um ein Objekt zu identifizieren. In einem neuen Anwendungsfall möchte ich eine URL an diese Funktion übergeben, indem ich die URL in Teile aufteile, die in Bytes32 konvertiert werden. Wie kann ich die einzelnen Bytes32 verketten, um die URL wiederherzustellen?

Ich weiß, dass ich ein Byte-Array erstellen und Bytes an Indizes setzen kann. Aber ich weiß nicht, wie ich auf eine bestimmte Position in einem bytes32 zugreifen kann.

function bytes2string(bytes32[] data) returns (string) {
    bytes memory r = new bytes(1);
    r[0] = bytes1(data[0]);
    return string(r);
}

Antworten (2)

Dank Piper und Chris habe ich eine funktionierende Lösung für Solidity <= 0.2.1 gefunden. Der Grund, warum die ersten beiden Protokollanweisungen unterschiedliche Ergebnisse zurückgeben, liegt darin, dass uintN rechtsbündig und bytesN linksbündig ist. Die Konvertierung zwischen uintN und bytesN verkürzt zuerst und ändert dann die Ausrichtung. Deshalb muss es vor der Konvertierung in zurückkonvertiert bytes32werden byte:

LogBytes1(byte(data)); // prints "s"
LogBytes1(byte(uint(data))); prints "\x00"
LogBytes1(byte(bytes32(uint(data)))); prints "s"

Eine getestete Lösung für meine Frage ist:

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);
}
I meet some problem when call this function outside the contract, I specify the bytes32[] string like this [7bb8b6ec123302e43ad88384158e2347efcfef19600b821431e8e09504046595,1f57c6ad7358ac73b73730eabb54b1bea7b785df2e4502291ed99b08af625def] but the compiler tell me it's wrong, why?

Festigkeit <= 0.2.1

Sie können das n- te Byte eines beliebigen bytesXXTyps mit dem folgenden Code abrufen .

bytes32 v = ...;
byte b = byte(bytes32(uint(v) * 2 ** (8 * n)));

Festigkeit > 0,2,1

Ab der nächsten Version von Solidity können Sie über Indizes darauf zugreifen .

bytes32 v = ...;
byte b = v[n];
Danke Piper für deinen Kommentar. Die Solidity <= 0.2.1-Lösung funktioniert bei mir aufgrund eines seltsamen Solidity-Verhaltens nicht. Angenommen, ich habe ein bytes32, das eine Byte-Darstellung der Zeichenfolge "string" enthält, nach einer Uint- und Byte-Konvertierung haben sich die Daten geändert: ` event LogBytes1 (bytes1); LogBytes1 (Byte (Daten)); // gibt "s" aus LogBytes1(byte(uint(data))); // druckt "\x00" `
Ich habe meinen Code aktualisiert, um die Neufassung in bytes32. Nicht sicher, ob Sie diese Antwort oder die von unten behalten möchten.