I would like to return structs keys from my contract to display on the frontend, ideally 10 at a time. I understand that if I make keyByOwner
public I can return a single key at a time with the getter that is created, but I need 10 keys and don't want to call the getter function 10 times.
I've tried to use the approach detailed here to return a tuple of arrays:
https://medium.com/coinmonks/solidity-tutorial-returning-structs-from-public-functions-e78e48efb378
I think this would be the way to proceed, except that it doesn't seem to work with the Key's data
field being of type bytes
(it works fine if I change type byes
to type bytes32
), giving me this error:
TypeError: This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature.
returns (uint[], bytes[])
^-----^
Is there any way to return multiple structs (or the fields from them) in Solidity when one of the struct fields is of type bytes
?
Here is my function:
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);
}