Ich habe gerade angefangen, solidity zu schreiben, und ich habe einige Fragen, auf die ich keine Antwort finden konnte.
Wenn Sie eine Karte wie diese deklarieren:
struct UserAccount{
string name;
uint id;
}
mapping (address => UserAccount) public accounts;
Wie wird das initialisiert? oder womit?
Zugriff zum Beispiel
accounts[0x79d66c53ad6f1847288c0d06c01a2b38c38f15bc]
wird eine Instanz eines Benutzerkontos zurückgegeben? Wenn ja, bedeutet das, dass die Karte für jede mögliche Adresse eine Instanz von UserAccount erstellt? Verbraucht das nicht sehr viel Speicher? Wenn nicht, wie kommt es, dass Sie dies tun können:
accounts[_address].name = _name;
?
Und die zweite Frage:
Ich verweise in meinem Vertrag auf eine Adresse, die der Eigentümer ist, die Adresse, die den Vertrag erstellt hat:
address public owner;
constructor() public {
owner = msg.sender;
}
Nachdem ich diese Funktion aufgerufen habe:
uint userCount=0;
mapping (address => UserAccount) public accounts;
function createAccount(string _name, uint _id, address _address) onlyOwner() public {
UserAccount user;
user.name = _name;
user.id = _id;
accounts[_address] = user;
userCount += 1;
// accounts[_address].name = _name;
// accounts[_address].id = _id;
// userCount += 1;
emit UserCreated(_address, _id, _name);
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
die Besitzeradresse ändert sich. Die kommentierten Zeilen der createAccount-Funktion sind der Weg, es zu tun, ich weiß, aber ich möchte verstehen, warum es nicht funktioniert.
Um mein Problem zu klären, werde ich auch einen js-Test posten.
beforeEach(async () => {
voting = await Voting.new({from: owner});
});
it("Should delete poll, as owner", async () =>{
var name = "Sandu";
console.log("LOCAL OWNER= " + owner);
console.log("OWNER BEFORE CREATE ACCOUNT FROM SOL= " + await voting.owner());
await voting.createAccount(name, 1, firstUser,{from:owner});
console.log("OWNER AFTER CREATE ACCOUNT FROM SOL= " + await voting.owner());
var pollName = "First Poll";
var endDateS="2018-08-11T10:20:30Z";
var endDate=new Date(endDateS)
await voting.createPoll(pollName, 1, endDate.getTime()/1000,{from:firstUser});
try{
await voting.deletePollById(1,{from: owner});
}catch(err){
console.log(err.message);
}
assert.notEqual(pollName, await voting.getPollById(1));
});
Der obige Test gibt Folgendes aus:
LOCAL OWNER= 0x79d66c53ad6f1847288c0d06c01a2b38c38f15bc //Owner that o have in my js file local, first address from the ganache accounts.
OWNER BEFORE CREATE ACCOUNT FROM SOL= 0x79d66c53ad6f1847288c0d06c01a2b38c38f15bc //The owner account from my contract before calling the function
OWNER AFTER CREATE ACCOUNT FROM SOL= 0x000000000000000000000000000000000000000a //The owner account from my contract after calling the function
Ich kann nicht verstehen, warum sich der Wert des Eigentümers ändert, da ich das in meiner Funktion nicht anfasse.
Wenn jemand helfen kann, würde es sehr geschätzt werden. Auch hier kenne ich den richtigen Weg, aber ich poste dies aus dem Wunsch heraus zu verstehen, was ich tue, um die Arbeit nicht zu erledigen.
Ich würde vorschlagen, dass Sie die Solidity-Dokumentation überprüfen.
Hier sind relevante Standorte:
Kurz gesagt: Es findet keine Initialisierung des Datensatzes/Mappings statt. Nahezu alle Datensätze sind mit Nullen vorinitialisiert und bereits vorhanden.
Ein allgemeines Muster, wie es gemacht wird, ist hier skizziert:
function createAccount(string _name, uint _id, address _address) onlyOwner() public {
UserAccount storage user = accounts[_address];
require(user.id == 0);
user.name = _name;
user.id = _id;
userCount += 1;
emit UserCreated(_address, _id, _name);
}
UserAccount storage user = accounts[_address];
Sie können sich das als Hinweis auf den Speicher
vorstellen . Es ist nicht so, dass der gesamte Datensatz kopiert wird. Siehe Speichermodifikator in der Dokumentation.
Jaime
Alexandru Sandu
Jaime