Ich habe einen Vertrag definiert, den ich zum Speichern von Benutzerdaten verwenden möchte, dh ein Feld zum Speichern des Hash seines Dokuments und ein Feld zum Speichern der Adresse eines Blocks, der einige andere Benutzerinformationen enthält. Ich habe dafür die folgende Struktur verwendet:
pragma solidity ^0.4.17;
contract UserDetails {
struct User {
string fileHash;
address addr;
}
User[] userArr;
function addUserDetail(string hash,address blockAddress) public returns (bool) {
User memory usr;
usr = User({fileHash:hash, addr:blockAddress});
userArr.push(usr);
}
}
1) Ist dies die richtige Datenstruktur für diesen Zweck?
2) Wie werden die Argumente an die Funktion addUserDetail übergeben, während der Vertrag mit web3 bereitgestellt wird?
Ich würde es ein wenig anpassen.
Das erste, was auffällt, ist, dass Sie die Benutzeradresse in der Struktur haben. Das ist überflüssig, weil Sie die Schlüssel auf andere Weise im Auge behalten möchten. Sie möchten beispielsweise nach Schlüssel suchen. Damit kennen Sie bereits den Schlüssel, den Sie nachschlagen möchten, oder? Sie müssen es nicht erneut in jeder Struktur speichern.
Mir ist aufgefallen, dass Sie Hashes speichern, also gehe ich davon aus, dass es eine Offchain-Speicherung von Metadaten geben wird. Trotzdem könnten Sie (normalerweise) einige zusätzliche On-Chain-Felder haben. Wie erkennt man den Unterschied? Wenn der Vertrag Zugriff auf ein Feld benötigt, um eine vertragsinterne Logik auszuführen, gehört das Feld in die Struktur.
Ich habe die Schlüsselliste veröffentlicht, damit ein Client die Schlüssel aufzählen kann, und eine Funktion hinzugefügt, um eine schnelle Zählung zu erhalten, da das Auslösen eines Fehlers meiner Meinung nach eine unangenehme Methode ist, um die Listenlänge zu ermitteln .
pragma solidity ^0.4.17;
contract UserDetails {
struct UserStruct {
string fileHash;
uint userListPointer;
// you may continue with other non-key fields that are needed for contract logic
}
// unique identifiers
address[] public userList;
mapping(address=>UserStruct) public userStructs;
function isUser(address userAddress) public view returns(bool isIndeed) {
if(userList.length ==0) return false;
return userList[userStructs[userAddress].userListPointer] == userAddress;
}
function addUserDetail(string hash,address userAddress) public returns (bool) {
require(!isUser(userAddress));
UserStruct memory usr;
usr.fileHash = hash;
usr.userListPointer = userList.push(userAddress) - 1;
userStructs[userAddress] = usr;
}
function getUserCount() public view returns(uint count) {
return userList.length;
}
}
Einige verwandte Muster finden Sie hier: Gibt es gut gelöste und einfache Speichermuster für Solidity?
Und eine vollständige Erklärung, die zufällig Benutzer für das Beispiel hier drüben verwendet: https://medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a
Ich hoffe es hilft.
Anubhav Gupta
Anubhav Gupta
Anubhav Gupta
Rob Hitchens
Anubhav Gupta
Rob Hitchens
address of a block
ist schwer zu verstehen. Wenn SieURI of an object
woanders gespeichert meinen, dann ja, das ist ein guter Ansatz.Anubhav Gupta