19

我遇到了一个很常见的问题,似乎我无法优雅有效地解决问题。

我必须将任意长字符串的任意长数组传递给solidity合约。

在我看来,它应该是这样的

function setStrings(string [] row)

但似乎无法做到。

我怎么解决这个问题?

4

9 回答 9

32

这是 Solidity 的一个限制,原因是它string基本上是一个任意长度的字节数组(ie byte[]),string[]二维字节数组(ie byte[][])也是如此。根据Solidity 参考资料,尚不支持二维数组作为参数。

合约函数可以接受二维数组吗?

这尚未针对外部调用和动态数组实现 - 您只能使用一级动态数组。

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

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

于 2017-03-21T16:52:44.390 回答
5

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);
    }
}
于 2021-12-03T13:22:45.323 回答
2

Solidity 尚不支持将字符串数组作为参数。

于 2018-01-08T00:20:42.470 回答
2

您可以将数组元素转换为字节字符串,然后将该字节字符串反序列化回函数内的数组。虽然这可能会非常昂贵,但如果您别无选择,您可以尝试一下。您可以按照这篇简短的文章来序列化/反序列化任何数据类型。

于 2018-06-06T19:44:26.180 回答
1

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

于 2018-07-23T13:50:52.913 回答
1

这可以通过 pragma experimental ABIEncoderV2; 在合同顶部使用来完成,然后您可以使用动态字符串数组。前任。 string[] memory myStrings;

于 2019-11-28T04:32:59.863 回答
0

您需要的所有解决方案:-

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

    }
}
于 2022-01-09T07:24:45.373 回答
0

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 函数用于测量数组的长度。

于 2019-08-30T13:54:40.293 回答
0

这是管理数组pushgetgetAll和的示例合约remove

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

于 2022-02-04T07:53:42.560 回答