如何在 Solidity 中 return 映射列表? (以太坊合约)

How to return mapping list in Solidity? (Ethereum contract)

我想做一个简单的智能合约,有列表,可以设置item,可以获取列表。

实体代码:

contract lister {
    mapping(int => string) list;
    int id = 0;
    
    function getList() returns ( /*HERE*/ ) {
        return list;
    }

    function setItemToList(string str) {
        list[id] = str;
        id++;
    }
}

我想将 getList() return 设为列表,但 return 类型不兼容。 我该怎么做?

批量访问 lists/arrays/etc 在 Solidity 中很痛苦。你很少在合同中看到它。在你的情况下,一个可能的解决方案是提供一个函数来访问 one 项目,使用它的索引,并让调用者从 0 循环到 id.

有了映射,键就不会被存储,值也无法迭代,所以它们真的只适用于单值查找。在您提供的示例中,使用数组可能是更好的选择。

另一方面,如果您使用数组并需要对其进行搜索(遍历所有项目),则需要小心,因为如果数组中的项目太多,最终可能会调用函数需要花费大量的 gas。

您可以更改变量 list 的可见性,插入 public 并且可以通过 getList 访问它.

mapping(int => string) public list;

映射不存储它们的键,只存储存储在状态内存地址的值。要获取数据列表,请使用数组。

address[] public addresses;

现在定义一个函数来获取这个数组的长度:

   function getAddressCount() public view returns(uint){
        return addresses.length;
    }

另外定义一个函数,通过索引获取元素:

function getAddressByIndex(uint index) public view returns(address){

   return addresses[index]
}

现在您需要编写代码来拉取 oen 的数组。这是在 javascript 中使用 web3 库完成的方式:

let addresses,addressCount;
try {
     addressesCount = await ContractName.methods.getCampaignCounts().call();
       
    addresses = await Promise.all(
      Array(parseInt(addressesCount))
        .fill()
        .map((element, index) => {
          return ContractName.methods.getAddressByIndex(index).call();
        })
    );
    
  } catch (e) {
    console.log("error in pulling array list", e);
  }