Solidity中的字符串数组

23

我遇到了一个很常见的问题,似乎在solidity中无法优雅且高效地解决它。

我需要将任意长度的字符串数组传递给一个solidity合约。

在我的想法中,应该是这样的:

function setStrings(string [] row)

但是看起来似乎无法做到。

我该如何解决这个问题?


我刚刚添加了一个更新的答案,截至2021年12月。 - Yulian
9个回答

37

这是Solidity的一个限制,原因是string基本上是任意长度的字节数组(即byte[]),所以string[]是一个二维字节数组(即byte[][])。根据Solidity参考文献,目前尚不支持将二维数组作为参数。

合约函数能否接受二维数组?

在外部调用和动态数组中,还未实现此功能-您只能使用一级动态数组。

您可以解决此问题的一种方法是,如果您预先知道所有字符串的最大长度(在大多数情况下可能会知道),则可以这样做:

function setStrings(byte[MAX_LENGTH][] row) {...}


那么转换会是怎样的呢? - Mago Nicolas Palacios

14

2021年12月更新

从Solidity 0.8.0版本开始,默认使用ABIEncoderV2,该版本原生支持动态字符串数组。

pragma solidity ^0.8.0;

contract Test {
    string[] public row;

    function getRow() public view returns (string[] memory) {
        return row;
    }

    function pushToRow(string memory newValue) public {
        row.push(newValue);
    }
}

2
你可以将数组元素转换为字节字符串,然后在函数内部将该字节字符串反序列化回数组。尽管这可能会非常昂贵,但如果没有选择,您可以尝试它。您可以参考此文来对任何Solitidy类型进行序列化/反序列化操作。

2

在Solidity中,目前不支持将字符串数组作为参数。


2

您需要的所有解决方案:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;

contract HelloWorld {
    string[] strings;

    // push one string to array
    function pushToStrings(string memory _data) public{
        strings.push(_data);
    }
    
    //get all the strings in array form
    function GetAllStrings() view public returns(string[] memory){
        return strings;
    }

    //get nth string of strings array
    function GetNthStrings(uint x) view public returns(string memory){
        return strings[x];
    }

    //push array of strings in strings
    function pushStringsArray(string[] memory someData) public{
        for (uint i=0; i < someData.length; i++) {
           strings.push(someData[i]);
        }
    }
    
    //change whole strings, take array of strings as input
    function changeWholeString(string[] memory someData) public{
       strings=someData;

    }
}

1

您可以通过在合约顶部使用pragma experimental ABIEncoderV2;来实现,然后您可以使用字符串的动态数组。例如: string[] memory myStrings;


1

在Solidity中,字符串数组不可用,因为字符串基本上是字符数组。嵌套动态数组未实现。


1
在Solidity中有两种类型的数组:静态数组和动态数组。 数组声明 静态数组: 其大小是固定的。
int[5] list_of_students;
list_of_students = ["Faisal","Asad","Naeem"];

我们使用索引号访问值。 动态数组: 这些数组的大小动态增加或减少。
int[] list_of_students;
list_of_students.push("Faisal");
list_of_students.push("Asad");
list_of_students.push("Smith");

我们可以使用索引号访问数组的值。 pushpop 函数用于插入和删除值。 length 函数用于测量数组的长度。

0

这是一个管理数组 pushgetgetAllremove 的示例合约。

pragma solidity ^0.8.4;

contract Array {
  string[] private fruits = ["banana", "apple", "avocado", "pineapple", "grapes"];

  function push(string memory item) public {
    fruits.push(item);
  }

  function get(uint256 index) public view returns (string memory) {
    return fruits[index];
  }

  function remove(uint256 index) public returns (bool) {
    if (index >= 0 && index < fruits.length) {
      fruits[index] = fruits[fruits.length - 1];
      fruits.pop();
      return true;
    }
    revert("index out of bounds");
  }

  function getAll() public view returns (string[] memory) {
    return fruits;
  }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接