¿Hay alguna forma conveniente de convertir (por ejemplo, convertir) un struct
tipo a bytes
?
Estoy tratando de llamar a un método como el que se muestra a continuación (tomado de aquí ) donde puede pasar información contextual (arbitraria) que se le devuelve más tarde en un método de "devolución de llamada".
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
}
Supongamos que quiero llamar a este método pasando una User
estructura como _extraData
argumento, ¿cuál sería un uso adecuado?
Gracias por adelantado,
Puedes hacer algo como esto. Tenga en cuenta que para cada estructura personalizada tendrá que escribir métodos personalizados de serialización y deserialización.
pragma solidity ^0.4.0;
contract StructSerialization
{
function StructSerialization()
{
}
event exactUserStructEvent(uint32 id, string name);
//Use only fixed size simple (uint,int) types!
struct ExactUserStruct
{
uint32 id;
string name;
}
function showStruct(ExactUserStruct u) private
{
exactUserStructEvent(u.id, u.name);
}
function exactUserStructToBytes(ExactUserStruct u) private
returns (bytes data)
{
// _size = "sizeof" u.id + "sizeof" u.name
uint _size = 4 + bytes(u.name).length;
bytes memory _data = new bytes(_size);
uint counter=0;
for (uint i=0;i<4;i++)
{
_data[counter]=byte(u.id>>(8*i)&uint32(255));
counter++;
}
for (i=0;i<bytes(u.name).length;i++)
{
_data[counter]=bytes(u.name)[i];
counter++;
}
return (_data);
}
function exactUserStructFromBytes(bytes data) private
returns (ExactUserStruct u)
{
for (uint i=0;i<4;i++)
{
uint32 temp = uint32(data[i]);
temp<<=8*i;
u.id^=temp;
}
bytes memory str = new bytes(data.length-4);
for (i=0;i<data.length-4;i++)
{
str[i]=data[i+4];
}
u.name=string(str);
}
function test()
{
//Create and show struct
ExactUserStruct memory struct_1=ExactUserStruct(1234567,"abcdef");
showStruct(struct_1);
//Serializing struct
bytes memory serialized_struct_1 = exactUserStructToBytes(struct_1);
//Deserializing struct
ExactUserStruct memory struct_2 = exactUserStructFromBytes(serialized_struct_1);
//Show deserealized struct
showStruct(struct_2);
}
}
Puede usar la biblioteca Seriality .
1- Mediante Seriality puedes serializar y deserializar fácilmente tus variables, structs, arrays, tuplas,... y pasarlas a través de los contratos y bibliotecas.
2- Puede desvincular su contrato de las bibliotecas serializando parámetros en una matriz de bytes.
3- También se puede utilizar como alternativa al protocolo RLP en Solidity.
Aquí hay una muestra:
pragma solidity ^0.4.16;
import "./Seriality.sol";
contract SerialitySample is Seriality {
function testSample1() public returns(int n1, int8 n2, uint24 n3, string n4,string n5) {
bytes memory buffer = new bytes(200);
string memory out4 = new string(32);
string memory out5 = new string(32);
n4 = new string(32);
n5 = new string(32);
int out1 = 34444445;
int8 out2 = 87;
uint24 out3 = 76545;
out4 = "Copy kon lashi";
out5 = "Bia inja dahan service";
// Serializing
uint offset = 200;
intToBytes(offset, out2, buffer);
offset -= sizeOfInt(8);
uintToBytes(offset, out3, buffer);
offset -= sizeOfUint(24);
stringToBytes(offset, bytes(out5), buffer);
offset -= sizeOfString(out5);
stringToBytes(offset, bytes(out4), buffer);
offset -= sizeOfString(out4);
intToBytes(offset, out1, buffer);
offset -= sizeOfInt(256);
// Deserializing
offset = 200;
n2 = bytesToInt8(offset, buffer);
offset -= sizeOfInt(8);
n3 = bytesToUint24(offset, buffer);
offset -= sizeOfUint(24);
bytesToString(offset, buffer, bytes(n5));
offset -= sizeOfString(out5);
bytesToString(offset, buffer, bytes(n4));
offset -= sizeOfString(out4);
n1 = bytesToInt256(offset, buffer);
}
}
búfer de salida:
00000000000000000000000000000000000000000000000000000000020d949d 436f7079206b6f6e206c61736869000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000e 42696120696e6a6120646168616e207365727669636500000000000000000000 0000000000000000000000000000000000000000000000000000000000000016 012b0157
"1": int256: n1 34444445
"2": int8: n2 87
"3": uint24: n3 76545
"4": cadena: n4 Copiar kon lashi
"5": cadena: servicio n5 Bia inja dahan
mikko ohtamaa