问题
I am designing a solution for an ethereum smart contract that does bidding. The use-case includes reserving a name eg. "myName" and assigning to an address. And then, people can bid for that name (in this case myName). There can be multiple such biddings happening for multiple names.
struct Bid {
address bidOwner;
uint bidAmount;
bytes32 nameEntity;
}
mapping(bytes32 => Bid[]) highestBidder;
So, as you can see above, Bid struct holds data for one bidder, similarly, the key (eg. myName) in the mapping highestBidder points to an array of such bidders.
Now, I am facing a problem when I try to return something like highestBidder[myName].
Apparently, solidity does not support returning an array of structs (dynamic data). I either need to rearchitect my solution or find some workaround to make it work.
If you guys have any concerns regarding the question, please let me know, I will try to make it clear.
I am stuck here any help would be appreciated.
回答1:
As you mentioned, this is not yet supported in Solidity. The powers that be are planning on changing it so you can, but for now, you have to retrieve the number of elements and then retrieve the decomposed struct as a tuple.
function getBidCount(bytes32 name) public constant returns (uint) {
return highestBidder[name].length;
}
function getBid(bytes32 name, uint index) public constant returns (address, uint, bytes32) {
Bid storage bid = highestBidder[name][index];
return (bid.bidOwner, bid.bidAmount, bid.nameEntity);
}
Edit to address question in comment regarding storage
vs memory
in this case
Local storage variables are pointers to state variables (which are always in storage
). From the Solidity docs:
The type of the local variable x is uint[] storage, but since storage is not dynamically allocated, it has to be assigned from a state variable before it can be used. So no space in storage will be allocated for x, but instead it functions only as an alias for a pre-existing variable in storage.
This is referring to an example where the varable used is uint[] x
. Same applies to my code with Bid bid
. In other words, no new storage is being created.
In terms of cost:
getBid("foo", 0)
using Bid memory bid
:
getBid("foo", 0)
using Bid storage bid
:
In this case, storage
is cheaper.
回答2:
Return an array of struct in solidity?
In below function getBid returns array of bid structure.
contract BidHistory {
struct Bid {
address bidOwner;
uint bidAmount;
bytes32 nameEntity;
}
mapping (uint => Bid) public bids;
uint public bidCount;
constructor() public {
bidCount = 0;
storeBid("address0",0,0);
storeBid("address1",1,1);
}
function storeBid(address memory _bidOwner, uint memory _bidAmount, bytes32 memory _nameEntity) public {
bids[tripcount] = Bid(_bidOwner, _bidAmount,_nameEntity);
bidCount++;
}
//return Array of structure
function getBid() public view returns (Bid[] memory){
Bid[] memory lBids = new Bid[](tripcount);
for (uint i = 0; i < bidCount; i++) {
Bid storage lBid = bids[i];
lBids[i] = lBid;
}
return lBids;
}
}
回答3:
About "returning an array of structs"... just a small workaround in order to return an array of structs extracted from medium
pragma solidity ^0.4.13;
contract Project
{
struct Person {
address addr;
uint funds;
}
Person[] people;
function getPeople(uint[] indexes)
public
returns (address[], uint[]) {
address[] memory addrs = new address[](indexes.length);
uint[] memory funds = new uint[](indexes.length);
for (uint i = 0; i < indexes.length; i++) {
Person storage person = people[indexes[i]];
addrs[i] = person.addr;
funds[i] = person.funds;
}
return (addrs, funds);
}
}
The uint[] index parameters should contain the indexes that you want to access.
Best
来源:https://stackoverflow.com/questions/48877910/how-can-i-return-an-array-of-struct-in-solidity