Ich möchte eine 32-Byte-Quelle aufteilen: erste Hälfte in Bytes16 half1; zweite Hälfte in Bytes16 half2. Mein Code funktioniert jedoch nur für dynamische Arrays, nicht mit fester Größe 16.
pragma solidity ^0.4.8;
contract cut {
function cutSha(bytes32 source) constant returns (bytes, bytes) {
bytes memory half1 = new bytes(16);
bytes memory half2 = new bytes(16);
for (uint j = 0; j < 16; j++) {
half1[j] = source[j];
half2[j] = source[j+16];
}
return (half1, half2);
}
}
Dies ist mit der Montage möglich:
pragma solidity ^0.4.8;
contract c {
event trace(bytes32 x, bytes16 a, bytes16 b);
function foo(bytes32 source) {
bytes16[2] memory y = [bytes16(0), 0];
assembly {
mstore(y, source)
mstore(add(y, 16), source)
}
trace(source, y[0], y[1]);
}
}
Wenn Sie beispielsweise Bytes aus der Zeichenfolge „what a wonderful world!“ Konvertieren, wird dies nach dem Verbrauch von 2245-Gas erzeugt:
trace[
"0x77686174206120776f6e64657266756c20776f726c6421000000000000000000",
"0x77686174206120776f6e64657266756c",
"0x20776f726c6421000000000000000000"
]
NB : Der Code stützt sich auf die interne Datendarstellung, die in späteren Versionen von Solidity geändert werden kann oder den Solidity-Optimierer auf unvorhersehbare Weise stört.
Ich habe eine Lösung mit Inline-Assembly gefunden:
contract cutByte32 {
//"0xa9c40ddcb43ebbc83add97b8f9f361f12b19bceff2f76b68f66b5bb1812365a9"
//use this as remix command
function cut(bytes32 sha) constant returns (bytes16 half1, bytes16 half2) {
assembly {
let freemem_pointer := mload(0x40)
mstore(add(freemem_pointer,0x00), sha)
half1 := mload(add(freemem_pointer,0x00))
half2 := mload(add(freemem_pointer,0x10))
}
}
}
mload(0x40)
bedeutet?Es ist jetzt möglich, Typkonvertierungen zu verwenden, um dies in ein paar Zeilen zu tun.
pragma solidity 0.8.16;
contract cut {
function cutSha(bytes32 source)
public
returns (bytes16 half1, bytes16 half2)
{
half1 = bytes16(source);
half2 = bytes16(uint128(uint256(source)));
}
}
PS Tut mir leid, wenn dieser Code fusseln muss - ich kann ihn gerade nicht testen, dies ist nur eine Illustration für die Idee; Korrekturen sind also willkommen.
Versuchen Sie es mit uints
function bytesChunck(bytes32 source, uint start, uint numBytes) constant returns(uint _result){
uint counter = 0;
uint result;
for(uint i = 0; i < numBytes; i++) {
result += uint8(source[start + i]);
}
return result;
}
aber das Lesen von Bytes aus bytes32 gibt einen Nullwert zurück (außer dem ersten)
Floyd