Solidity - 从合约 B 检查合约 A 中是否存在索引

Solidity - Check if an index exists in contract A from Contract B

我有两个合约 A 和 B。我在合约 A 中定义了一个数组变量。我想检查合约 B 中是否存在索引。

A.sol

contract A {
    SomeStruct[] private myArray;
    /// @notice Check if an index exists
    function isIndexExists(uint256 index) public view returns (bool) {
      if (myArray[index].isExist) {
        return true;
      } else {
        return false;
      }
    }
}

B.sol

contract B is A {
  function todo(uint256 index) public view returns (bool) {
    if (isIndexExists(index)) {
      // ... logic
    } else {
      revert("Index in not exist")l
    }
  }
}

isIndexExists函数直接从合约A调用时运行良好,但在B中出现错误。

我在 Truffle 中的 JS 测试环境中进行了此调用。

错误: Error: Returned error: VM Exception while processing transaction: revert

错误是由两个原因之一引起的:

  1. 越界:您正在访问 myArray[index] 表达式中不存在的数组索引。

  2. 缺少 return:您没有 returning todo() 函数的 // ... logic 部分中承诺 return一个bool.

数组 myArray 是动态调整大小的。您不能安全地尝试使用 [] 运算符访问具有任意索引的元素,您首先需要检查索引是否超出范围。以下是如何更改合约 A 中的函数以实现此目的:

function isIndexExists(uint256 index) public view returns (bool) {
  // If the index is out of bounds, then there is no such element
  if (index >= myArray.length) {
    return false;
  }
  
  // We know that there is an object with that index, so check its 'isExist' property
  return myArray[index].isExist;
}

顺便说一句,请注意,当您检查某些 return 是布尔值的表达式时,您可以直接 return 该值。您不需要多余的 if-else,与这种只需要一行代码的方法相比,它需要 5 行。