Solidity

如何從合約函式返回多個字元串?

  • March 3, 2018

在solidity 中,如何從函式返回單個字元串是顯而易見的。但是,我想讓智能合約返回多個字元串值。有沒有辦法做到這一點?

您可能指的是幾種類型的字元串值。

  • bytes1- bytes32:固定大小。
  • bytesstring:動態調整大小。

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

引用自:https://ethereum.stackexchange.com/questions/632