Konvertieren Sie Struct in Bytes in Solidity

Gibt es eine bequeme Möglichkeit, einen structTyp zu konvertieren (z. B. umzuwandeln) bytes?

Ich versuche, eine Methode wie die folgende (von here ) aufzurufen, in der Sie einige (willkürliche) Kontextinformationen übergeben können, die Ihnen später in einer "Callback" -Methode zurückgegeben werden.

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;
    }
}

Angenommen, ich möchte diese Methode aufrufen, indem ich eine UserStruktur als _extraDataArgument übergebe, was wäre eine ordnungsgemäße Verwendung?

Danke im Voraus,

Solidity hat kein Serialisierungsformat für Strukturen. Sie müssen die Parameter einzeln herausnehmen und sie einzeln mit einem Byte-Array verketten. (Obwohl ich keine Details zum Anhängen an ein Byte-Array kenne). Hier sind einige weitere Details ethereum.stackexchange.com/questions/11016/…

Antworten (2)

Sie können so etwas tun. Beachten Sie, dass Sie für jede benutzerdefinierte Struktur benutzerdefinierte Serialisierungs- und Deserialisierungsmethoden schreiben müssen.

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);
    }
}

Sie können die Serialitätsbibliothek verwenden.

1- Mittels Serialität können Sie Ihre Variablen, Strukturen, Arrays, Tupel usw. einfach serialisieren und deserialisieren und sie durch die Verträge und Bibliotheken leiten.

2- Sie können Ihren Vertrag von Bibliotheken entkoppeln, indem Sie Parameter in ein Byte-Array serialisieren.

3- Es kann auch als Alternative zum RLP-Protokoll in Solidity verwendet werden.

Hier ist ein Beispiel:

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);
}

}

Ausgangspuffer:

00000000000000000000000000000000000000000000000000000000020d949d 436f7079206b6f6e206c61736869000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000e 42696120696e6a6120646168616e207365727669636500000000000000000000 0000000000000000000000000000000000000000000000000000000000000016 012b0157

"1": int256: n1 34444445

"2": int8: n2 87

"3": uint24: n3 76545

"4": Zeichenfolge: n4 Kopieren Sie kon lashi

"5": Zeichenkette: n5 Bia inja dahan Dienst