trying to do a sample based on struct, storing a list of struct as a mapping.
but when i add an item and trying to retrieve i cannot find that item in the mapping
below is my contract
contract ItemListContract {
struct item
{
bytes iname;
uint16 itemid;
bytes icode;
uint ivalue;
}
uint itemcount;
mapping(bytes => item) itemlist;
item[] itemarray;
function ItemListContract()
{
log0('hi');
}
function AddItem(bytes name, uint16 iid, bytes code, uint val)
{
var itemnew = item(name, iid ,code, val);
log0(itemnew);
itemlist[code] = itemnew;
itemarray.push(itemnew);
itemcount++;
}
function countitemlist() returns (uint count)
{
return itemcount;
}
function removeitem(bytes code)
{
delete itemlist[code];
itemcount--;
}
function getitem(bytes code) returns (bytes iname, uint val)
{
return (itemlist[code].iname,itemlist[code].ivalue);
}
}
I tried to add item by using the below statements
var listarrayinterface =[{"constant":false,"inputs":[{"name":"name","type":"bytes"},{"name":"iid","type":"uint16"},{"name":"code","type":"bytes"},{"name":"val","type":"uint256"}],"name":"AddItem","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"code","type":"bytes"}],"name":"getitem","outputs":[{"name":"iname","type":"bytes"},{"name":"val","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"countitemlist","outputs":[{"name":"count","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"code","type":"bytes"}],"name":"removeitem","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"countitemarray","outputs":[{"name":"count","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"code","type":"bytes"}],"name":"getitemfromarray","outputs":[{"name":"iname","type":"bytes"},{"name":"val","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"}];
var listarratcontract = eth.contract(listarrayinterface).at("0x62fxxx")
listarratcontract.AddItem.call({data:{name:"item2",iid:2,code:"i2",val:2}})
after calling the contract with the above data i got [] as resoponse
Now I tried to query the saved data by
listarratcontract.countitemlist.call()
0
got response as 0.
when i called using
listarratcontract.getitem.call("i2")
["0xo",0]
I cant get the saved data or dont even know if the data is saved or not?
can any one point out what the issue might be?
Best Answer
Summary
The issues are:
addItem()
does not specify the gas amount so 90,000 is assumed. The execution of thisaddItem()
method took 226,554 gas.getItem(...)
method should be marked constant to return the values correctly.countItemList()
method should also be marked constant to return the value correctly.@Tjaden Hess
commented below, your statementlistarratcontract.AddItem.call({data:{name:"item2",iid:2,code:"i2",val:2}})
does not execute the method as a transaction modifying the blockchain data. See below for the statement to execute this method as a transaction. See What is the difference between a transaction and a call? for further information.Details
I've made some minor changes to your source code:
countItemList()
andgetItem(...)
as constant.log0(itemnew)
as this statement causes an error in my Browser Solidity /geth
.Here is the source code:
The following screenshot of your code being deployed and executed using Browser Solidity shows that the
addItem(...)
method took 226,554 gas.Calling
getItem(...)
returned the value added in the call toaddItem(...)
. And callingcountItemList()
returned 1.The following section shows the execution of your contract methods using the
geth
command line and the increased gas amount:Gas Cost Differences - Responding To Question In Comments
addItem(...)
Gas Cost DifferencesI called
addItem(...)
4 times with the following parameters and the associated gas cost:Following is the Browser Solidity screenshot:![enter image description here](https://i.stack.imgur.com/3bYS6.png)
I ran a
debug.traceTransaction(...)
for the first and second operation to find the differences in the gas cost.Here is a screenshot showing the first difference in gas cost:![enter image description here](https://i.stack.imgur.com/55ouF.png)
And here is a screenshot showing the second difference in gas cost:![enter image description here](https://i.stack.imgur.com/wyMU0.png)
Here is the code for
addItem(...)
:The difference in gas cost between the first and second operation is (20,000 x 2) - (5,000 x 2) = 30,000 for the
SSTORE
operation when assigningitemnew
toitemList[code]
anditemArray.push(...)
.From the fee schedule in the Ethereum Yellow Paper, you can see that the first
SSTORE
operation to store the new data initemList
anditemArray
sets the storage value from zero to non-zero and costs 20,000 gas (highlighted in green below).The second
SSTORE
operation to store the new data initemList
anditemArray
sets the storage value from non-zero to non-zero and costs 5,000 gas (highlighted in pink below).removeItem(...)
Gas Cost DifferencesI then called
removeItem(...)
4 times with the following parameters and the associated gas cost:Following is the Browser Solidity screenshot:![enter image description here](https://i.stack.imgur.com/5GziA.png)
You can run a
debug.traceTransaction(...)
for the third and fourth operations to find the differences in the gas cost.