Quiero dividir una fuente de 32 bytes: la primera mitad en Bytes16 mitad 1; segunda mitad en Bytes16 mitad2. Mi código funciona, sin embargo, solo para matriz dinámica, no con tamaño fijo 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);
}
}
Es posible hacer esto con ensamblaje:
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]);
}
}
Por ejemplo, convertir bytes de la cadena "¡Qué mundo tan maravilloso!" produce esto después de usar gas 2245:
trace[
"0x77686174206120776f6e64657266756c20776f726c6421000000000000000000",
"0x77686174206120776f6e64657266756c",
"0x20776f726c6421000000000000000000"
]
NB : el código se basa en la representación de datos internos que pueden estar sujetos a cambios en versiones posteriores de Solidity o interferir con el optimizador de Solidity de manera impredecible.
Encontré una solución usando ensamblaje en línea:
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)
significa?Ahora es posible usar conversiones de tipo para hacerlo en un par de líneas.
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)));
}
}
PD Lo siento si este código necesitará algo de pelusa, no puedo probarlo ahora, esto es solo una ilustración de la idea; así que cualquier corrección es bienvenida.
Intenta hacerlo con 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;
}
pero leer bytes de bytes32 devuelve valor cero (excepto el primero)
floyd