Есть ли удобный способ конвертировать (например, приводить) struct
тип в bytes
?
Я пытаюсь вызвать метод, подобный приведенному ниже (взято отсюда ), где вы можете передать некоторую (произвольную) контекстную информацию, которая будет возвращена вам позже в методе «обратного вызова».
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;
}
}
Предположим, я хочу вызвать этот метод, передав User
структуру в качестве _extraData
аргумента, что было бы правильным использованием?
Заранее спасибо,
Вы можете сделать что-то вроде этого. Обратите внимание: для каждой пользовательской структуры вам придется писать собственные методы сериализации и десериализации.
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);
}
}
Вы можете использовать библиотеку Seriality .
1- С помощью Seriality вы можете легко сериализовать и десериализовать свои переменные, структуры, массивы, кортежи... и передавать их через контракты и библиотеки.
2- Вы можете отделить свой контракт от библиотек, сериализовав параметры в массив байтов.
3- Его также можно использовать в качестве альтернативы протоколу RLP в Solidity.
Вот пример:
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);
}
}
выходной буфер:
00000000000000000000000000000000000000000000000000000000020d949d 436f7079206b6f6e206c61736869000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000e 42696120696e6a6120646168616e207365727669636500000000000000000000 0000000000000000000000000000000000000000000000000000000000000016 012b0157
"1": int256: n1 34444445
"2": int8: n2 87
"3": uint24: n3 76545
"4": строка: n4 Копировать кон лаши
"5": строка: n5 Служба Bia inja dahan
Микко Отамаа