Я хотел бы вернуть ключи структур из моего контракта для отображения во внешнем интерфейсе, в идеале по 10 за раз. Я понимаю, что если я сделаю keyByOwner
общедоступным, я могу вернуть один ключ за раз с помощью созданного геттера, но мне нужно 10 ключей, и я не хочу вызывать функцию геттера 10 раз.
Я попытался использовать описанный здесь подход для возврата кортежа массивов: https://medium.com/coinmonks/solidity-tutorial-returning-structs-from-public-functions-e78e48efb378 продолжайте, за исключением того, что он, похоже, не работает с data
полем ключа типа bytes
(он отлично работает, если я меняю type byes
на type bytes32
), что дает мне эту ошибку:
TypeError: This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature.
returns (uint[], bytes[])
^-----^
Есть ли способ вернуть несколько структур (или полей из них) в Solidity, когда одно из полей структуры имеет тип bytes
?
Вот моя функция:
struct Key {
uint expirationTimestamp;
bytes data;
}
mapping (address => Key) internal keyByOwner;
address[] public owners;
function getKeysByPage(uint _startIndex)
external
view
returns (uint[], bytes[])
{
require(outstandingKeys() > 0, "No keys to retrieve");
require(_startIndex >= 0 && _startIndex < outstandingKeys(), "Index must be in-bounds");
uint endOfPageIndex;
if (_startIndex + 9 > owners.length) {
endOfPageIndex = owners.length - 1;
} else {
endOfPageIndex = _startIndex + 9;
}
address[] memory ownersByPage = new address[](10);
uint[] memory timestampsArray = new uint[](10);
bytes[] memory keyDataArray = new bytes[](10);
Key memory tempKey;
uint pageIndex = 0;
// Build the specified set of owners into a new temporary array
for (uint256 i = _startIndex; i <= endOfPageIndex; i++) {
ownersByPage[pageIndex] = owners[i];
pageIndex++;
}
// Loop through ownersByPage & build the requested keys into 2 new temporary arrays
for (uint256 n = 0; n < ownersByPage.length; n++) {
tempKey = keyByOwner[ownersByPage[n]];
timestampsArray[n] = tempKey.expirationTimestamp;
keyDataArray[n] = tempKey.data;
}
return(timestampsArray, keyDataArray);
}
Возврат структур и кортежей структур невозможен с текущим ABI. Если вы добавите pragma experimental ABIEncoderV2
сразу после своей pragma solidity
строки, она будет скомпилирована просто отлично. К сожалению, не рекомендуется переходить в производство с экспериментальной функцией, поэтому единственная жизнеспособная альтернатива сейчас — возвращать примитивные типы каждой структуры в строке.
Конкретно для вашего сценария вам нужно временно использовать совместимый тип. Например, вы можете преобразовать свой динамический массив байтов в bytes32.
Ник Фурфаро
pragma experimental ABIEncoderV2
заголовком, но, как вы сказали, недостаточно хорош для производства. Я могу возвращать кортежи массивов, но, похоже, это не работает, если один из массивов в кортеже имеет типbytes
или типstring
, вероятно, потому, что они оба являются динамическими массивами. Можете ли вы уточнить, что «единственная жизнеспособная альтернатива сейчас — это возвращать примитивные типы каждой структуры в строке»?Пол Разван Берг
Пол Разван Берг
Ник Фурфаро