Quiero convertir datos de tipo uint a tipo de bytes en solidez. He encontrado una respuesta sobre esto que es como a continuación.
function toBytes(uint256 x) public pure returns (bytes memory b) {
b = new bytes(32);
assembly { mstore(add(b, 32), x) }
}
Pero esto no funciona como pensaba. Por ejemplo, si pongo 0x0000000000000000000000000000000000000000000000000000000000000abc
el valor de entrada, esperaba tener un valor de retorno que se vea así 0xabc0000000000000000000000000000000000000000000000000000000000000
. Pero esta función devuelve lo mismo que el valor de entrada, que es 0x0000000000000000000000000000000000000000000000000000000000000abc
. ¿Cómo podría convertir 0x0000000000000000000000000000000000000000000000000000000000000abc
esto en 0xabc0000000000000000000000000000000000000000000000000000000000000
esto en solidez?
Lo que está buscando hacer se llama cambio de bits . Solidity permite el cambio de bit usando los operadores <<
y >>
.
Para su ejemplo, la parte distinta de cero 0x000000000000000000000000000000000000000000000000000000000000abcd
es abcd
la que ocupa 16 bits. Debido a que un bytes32 tiene una longitud de 256 bits, debe cambiar 240 bits para devolver el valor deseado:
function toBytes(uint256 x) public pure returns (bytes32) {
return bytes32(a) << 240;
}
Tenga en cuenta que el ejemplo anterior solo funciona cuando el valor inicial es de 2 bytes. Si no está seguro de la longitud de su valor inicial, puede determinarlo usando un ciclo for y alguna división:
function toBytes(uint256 a) public pure returns (bytes32) {
uint i;
for (i = 0; i < 33; i++) {
if (a / 256**i == 0) break;
}
return bytes32(a) << (32-i)*8;
}
bytes
no a bytes32
.¿Qué pasa con esto?
function toBytes(uint256 x) public pure returns (bytes memory b) {
uint l = 32;
if (x < 0x100000000000000000000000000000000) { x <<= 128; l -= 16; }
if (x < 0x1000000000000000000000000000000000000000000000000) { x <<= 64; l -= 8; }
if (x < 0x100000000000000000000000000000000000000000000000000000000) { x <<= 32; l -= 4; }
if (x < 0x1000000000000000000000000000000000000000000000000000000000000) { x <<= 16; l -= 2; }
if (x < 0x100000000000000000000000000000000000000000000000000000000000000) { x <<= 8; l -= 1; }
if (x < 0x100000000000000000000000000000000000000000000000000000000000000) { x <<= 8; l -= 1; }
b = new bytes (l);
assembly { mstore(add(b, 32), x) }
}
Para mí lo hace:
0x0 -> 0x (zero bytes)
0x1 -> 0x01 (1 byte)
0xFF -> 0xFF (1 byte)
0x100 -> 0x0100 (2 bytes)
0xFFFF -> 0xFFFF (2 bytes)
etc.
mijail vladimirov
uint
tiene bytes0a
ybc
, mientras que el resultantebytes
tieneab
yc0
.jung chun
0x0000000000000000000000000000000000000000000000000000000000000abc
en una función, quiero recibir0xabc
.mijail vladimirov
0xabc
no es unbytes
valor válido, ya que tiene una longitud de 12 bits, mientras que cada byte tiene 8 bits. Entonces es un número fraccionario de bytes.jung chun
0x000000000000000000000000000000000000000000000000000000000000abcd
. Quiero recibir0xabcd
cuando doy un valor de entrada0x000000000000000000000000000000000000000000000000000000000000abcd
. Pero esa función devuelve lo mismo que el valor de entrada.mijail vladimirov
ismael