Solidity
如何從合約函式返回多個字元串?
在solidity 中,如何從函式返回單個字元串是顯而易見的。但是,我想讓智能合約返回多個字元串值。有沒有辦法做到這一點?
您可能指的是幾種類型的字元串值。
bytes1
-bytes32
:固定大小。bytes
或string
:動態調整大小。Solidity 支持具有多個返回值的函式。
contract MultiReturner { function getData() constant returns (bytes32, bytes32) { bytes32 a = "abcd"; bytes32 b = "wxyz"; return (a, b); } function getDynamicData() constant returns (bytes, bytes) { bytes a; a.push('a'); a.push('b'); a.push('c'); bytes b; b.push('x'); b.push('y'); b.push('z'); return (a, b); } }
您可以使用
bytes
或使用相同的方法,string
但有以下限制:solidity 不支持將動態大小的值返回給其他函式。這意味著您將能夠getData
在另一個合約中使用該函式並檢索返回值,但您將無法從getDynamicData
合約中檢索返回值。contract UsesMultiReturner { function doIt() { mr = MultiReturner(0x1234); // this will work var (a, b) = mr.getData(); // this won't work var (a, b) = mr.getDynamicData(); } }
但是,您可以從兩者
getData
以及getDynamicData
何時call
從區塊鏈外部檢索返回值。
您可以使用序列庫。Seriality是一個用於以非常有效的方式對所有 Solidity 類型進行序列化和反序列化的庫,主要用 Solidity-Assembly 編寫
1- 通過 Seriality,您可以輕鬆地序列化和反序列化您的變數、結構、數組、元組……並將它們傳遞給合約和庫。
2-您可以通過將參數序列化為字節數組來將合約與庫分離。
3- 它也可以用作 Solidity 中 RLP 協議的替代方案。
這是一個範例:
pragma solidity ^0.4.16; import "./Seriality.sol"; contract StringsReturn is Seriality { function stringCaller() public returns( string memory out1, string memory out2, string memory out3, string memory out4, string memory out5) { bytes memory buffer = new bytes(320); uint offset = stringCallee(buffer); //deserializing out1 = new string (getStringSize(offset, buffer)); bytesToString(offset, buffer, bytes(out1)); offset -= sizeOfString(out1); out2 = new string (getStringSize(offset, buffer)); bytesToString(offset, buffer, bytes(out2)); offset -= sizeOfString(out2); out3 = new string (getStringSize(offset, buffer)); bytesToString(offset, buffer, bytes(out3)); offset -= sizeOfString(out3); out4 = new string (getStringSize(offset, buffer)); bytesToString(offset, buffer, bytes(out4)); offset -= sizeOfString(out4); out5 = new string (getStringSize(offset, buffer)); bytesToString(offset, buffer, bytes(out5)); } function stringCallee(bytes memory buffer) public returns (uint buffer_size) { string memory out1 = new string(32); string memory out2 = new string(32); string memory out3 = new string(32); string memory out4 = new string(32); string memory out5 = new string(32); out1 = "Come on baby lets dance!"; out2 = "May I buy you a drink?"; out3 = "I am an itinerant programmer"; out4 = "Inam javab lashi!"; out5 = "Bia inja dahan service"; // Serializing buffer_size = sizeOfString(out5) + sizeOfString(out4) + sizeOfString(out3) + sizeOfString(out2) + sizeOfString(out1); uint offset = buffer_size; stringToBytes(offset, bytes(out1), buffer); offset -= sizeOfString(out1); stringToBytes(offset, bytes(out2), buffer); offset -= sizeOfString(out2); stringToBytes(offset, bytes(out3), buffer); offset -= sizeOfString(out3); stringToBytes(offset, bytes(out4), buffer); offset -= sizeOfString(out4); stringToBytes(offset, bytes(out5), buffer); return buffer_size; } }
這是 stringCaller() 的輸出
"0": "string: out1 Come on baby lets dance!", "1": "string: out2 May I buy you a drink?", "2": "string: out3 I am an itinerant programmer", "3": "string: out4 Inam javab lashi!", "4": "string: out5 Bia inja dahan service"
這是緩衝區:
42696120696e6a6120646168616e207365727669636500000000000000000000 0000000000000000000000000000000000000000000000000000000000000016 496e616d206a61766162206c6173686921000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000011 4920616d20616e206974696e6572616e742070726f6772616d6d657200000000 000000000000000000000000000000000000000000000000000000000000001c 4d617920492062757920796f752061206472696e6b3f00000000000000000000 0000000000000000000000000000000000000000000000000000000000000016 436f6d65206f6e2062616279206c6574732064616e6365210000000000000000 0000000000000000000000000000000000000000000000000000000000000018