Versuchen Sie, ein Beispiel basierend auf Struct zu erstellen, und speichern Sie eine Liste von Structs als Zuordnung. Aber wenn ich ein Element hinzufüge und versuche, es abzurufen, kann ich dieses Element nicht in der Zuordnung finden
Unten ist mein Vertrag
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);
}
}
Ich habe versucht, Artikel mit den folgenden Anweisungen hinzuzufügen
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}})
nach dem aufruf des vertrages mit den oben genannten daten bekam ich [] als antwort
Nun habe ich versucht die gespeicherten Daten per abzufragen
listarratcontract.countitemlist.call()
0
bekam Antwort als 0.
als ich mit anrief
listarratcontract.getitem.call("i2")
["0xo",0]
Ich kann die gespeicherten Daten nicht abrufen oder weiß nicht einmal, ob die Daten gespeichert sind oder nicht?
kann jemand darauf hinweisen, was das Problem sein könnte?
Die Probleme sind:
addItem()
gibt die Gasmenge nicht an, daher wird von 90.000 ausgegangen. Die Ausführung dieser addItem()
Methode erforderte 226.554 Gas.getItem(...)
Methode sollte als konstant markiert werden, um die Werte korrekt zurückzugeben.countItemList()
Methode sollte auch als konstant markiert werden, um den Wert korrekt zurückzugeben.@Tjaden Hess
unten kommentiert, führt Ihre Anweisung listarratcontract.AddItem.call({data:{name:"item2",iid:2,code:"i2",val:2}})
die Methode nicht als Transaktion aus, die die Blockchain-Daten ändert. Siehe unten für die Anweisung, diese Methode als Transaktion auszuführen. Siehe Was ist der Unterschied zwischen einer Transaktion und einem Anruf? Für weitere Informationen.Ich habe einige kleinere Änderungen an Ihrem Quellcode vorgenommen:
countItemList()
und getItem(...)
als konstant.log0(itemnew)
dieser Anweisung verursacht einen Fehler in meinem Browser Solidity / geth
.Hier ist der Quellcode:
pragma solidity ^0.4.0;
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() constant returns (uint count) {
return itemCount;
}
function removeItem(bytes code) {
delete itemList[code];
itemCount--;
}
function getItem(bytes code) constant returns (bytes iname, uint val) {
return (itemList[code].iname, itemList[code].ivalue);
}
}
Der folgende Screenshot Ihres Codes, der mit Browser Solidity bereitgestellt und ausgeführt wird, zeigt, dass die addItem(...)
Methode 226.554 Gas verbraucht hat.
Beim Aufrufen getItem(...)
wurde der im Aufruf hinzugefügte Wert an zurückgegeben addItem(...)
. Und der Anruf countItemList()
gab 1 zurück.
Der folgende Abschnitt zeigt die Ausführung Ihrer Kontraktmethoden über die geth
Kommandozeile und die erhöhte Gasmenge:
> var itemListABI = [{"constant":false,"inputs":[{"name":"code","type":"bytes"}],"name":"removeItem","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"countItemList","outputs":[{"name":"count","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"code","type":"bytes"}],"name":"getItem","outputs":[{"name":"iname","type":"bytes"},{"name":"val","type":"uint256"}],"payable":false,"type":"function"},{"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"},{"inputs":[],"type":"constructor"}];
undefined
> var itemList = eth.contract(itemListABI).at("0xee7b790b638553cc95a4355d422536bad1566fd7");
undefined
> itemList.addItem("item3", 3, "i3", 3, {from: eth.accounts[0], gas: 500000});
"0xc70469c662c759627c217827845a6567ff1ac1dd2ebd5e0d52fe817aeeb7867a"
> itemList.countItemList()
3
> itemList.getItem("i3")
["0x6974656d33", 3]
addItem(...)
GaskostenunterschiedeIch habe addItem(...)
4 mal angerufen mit folgenden Parametern und den dazugehörigen Spritkosten:
Es folgt der Screenshot von Browser Solidity:
Ich habe eine debug.traceTransaction(...)
für die erste und zweite Operation durchgeführt, um die Unterschiede in den Benzinkosten zu finden.
Hier ist ein Screenshot, der den ersten Unterschied bei den Benzinkosten zeigt:
Und hier ist ein Screenshot, der den zweiten Unterschied bei den Benzinkosten zeigt:
Hier ist der Code für addItem(...)
:
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++;
}
Die Differenz der Gaskosten zwischen dem ersten und dem zweiten Vorgang beträgt (20.000 x 2) - (5.000 x 2) = 30.000 für den SSTORE
Vorgang bei Zuweisung itemnew
zu itemList[code]
und itemArray.push(...)
.
Aus der Gebührenordnung im Ethereum Yellow Paper können Sie ersehen, dass die erste SSTORE
Operation zum Speichern der neuen Daten itemList
und itemArray
Setzen des Speicherwerts von null auf ungleich null 20.000 Gas kostet (unten grün hervorgehoben).
Die zweite SSTORE
Operation zum Speichern der neuen Daten itemList
und itemArray
setzt den Speicherwert von ungleich null auf ungleich null und kostet 5.000 Benzin (unten rosa hervorgehoben).
removeItem(...)
GaskostenunterschiedeIch habe dann removeItem(...)
4 mal angerufen mit folgenden Parametern und den dazugehörigen Spritkosten:
Es folgt der Screenshot von Browser Solidity:
Sie können eine debug.traceTransaction(...)
für den dritten und vierten Vorgang ausführen, um die Unterschiede in den Benzinkosten zu ermitteln.
Tjaden Hess
.call
in web3 eine Transaktion simuliert wird. Sie wollten eine tatsächliche Transaktion verwendenMahesh Gupta
Datenschutz ist ein Menschenrecht.eth
addItem(...)
beim ersten und zweiten Mal aufgerufene Funktion zu zeigen. Sie können die gleiche Art von Analyse verwenden, um die Differenz der Gaskosten für dieremoveItem(...)
Funktion „Vorletztes Mal“ und „Letztes Mal“ zu ermitteln. Bitte stellen Sie eine neue Frage unter Bezugnahme auf diese Fragen und Antworten, wenn Sie weitere Fragen zu den Gaskosten haben.