Есть ли способ получить длину массива в другом контракте без геттера?
pragma solidity ^0.4.11;
contract MyContractA {
uint[] public myArray;
function MyContractA() {
myArray.length = 1;
}
}
contract MyContractB {
function test() returns (uint ret) {
address instanceAddress = new MyContractA();
MyContractA instance = MyContractA(instanceAddress);
// works:
return instance.myArray(0);
//
// doesn't work:
//
// TypeError: Member "length" not found or not visible after argument-dependent lookup in function (uint256) constant external returns (uint256)
// return instance.myArray.length;
// TypeError: Member "length" not found or not visible after argument-dependent lookup in function (uint256) constant external returns (uint256)
// return instance.myArray.length();
// TypeError: Wrong argument count for function call: 0 arguments given but expected 1.
//return instance.myArray().length;
}
}
Нет. Вам нужно представить функцию, которая вернет длину массива в виде uint
.
Что-то вроде
function getCount() public view returns(uint count) {
return array.length;
}
Это довольно распространенное требование. Эти шаблоны хранения могут сэкономить вам время, пытаясь понять, как действовать в рамках ограничений, с которыми мы имеем дело: Существуют ли хорошо решенные и простые шаблоны хранения для Solidity?
Надеюсь, это поможет.
Недавно у меня возникла эта проблема, и мне действительно нужно было получить длину массива в уже развернутом контракте. И, конечно же, я не развернул какую-то приятную getCount()
функцию.
Вот мое действительно ужасное , но рабочее решение:
interface IExternalContract {
function arrayToCount(uint idx) external view returns (address);
}
contract ArrayCounter {
function getOfferCount(IExternalContract factory, uint start) public view returns (uint) {
for (uint256 i = start; i < 10000; i++) {
try factory.arrayToCount(i) returns (uint v) {
start = i; // keep going
} catch Error(string memory /*reason*/) {
return i;
} catch (bytes memory /*lowLevelData*/) {
return i;
}
}
return start;
}
}
Чтобы это работало для вашего контракта, вам нужно будет изменить имя массива arrayToCount
и возвращаемый тип массива на то, что у вас есть в интерфейсе и в try
строке.
Вам нужно будет передать ему начальный индекс. Что касается меня, я знал, что мой массив имеет длину чуть более 14 КБ, поэтому я просто прошел 14 КБ. Вы должны быть в состоянии получить достаточно близкое число, разделив его пополам.
Исмаэль