Convertir estructura a bytes en Solidity

¿Hay alguna forma conveniente de convertir (por ejemplo, convertir) un structtipo 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 Userestructura como _extraDataargumento, ¿cuál sería un uso adecuado?

Gracias por adelantado,

Solidity no tiene formato de serialización para estructuras. Debe eliminar los parámetros uno por uno y concatenarlos en una matriz de bytes uno por uno. (Aunque no sé detalles sobre cómo agregar a la matriz de bytes). Aquí hay algunos detalles más ethereum.stackexchange.com/questions/11016/…

Respuestas (2)

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