Wie übergebe ich Argumente an die benutzerdefinierte Strukturfunktion bei der Bereitstellung?

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?

Antworten (1)

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.

Vielen Dank für die ausführliche Erklärung. Da ich neu bei Blockchain und Verträgen bin, kann ich mich im Moment nicht entscheiden, was die beste Architektur für mein Projekt wäre. Können Sie mir bitte Ihre E-Mail-Adresse mitteilen, damit ich Sie um die Projektanleitung bitten kann? Ich werde Ihnen die Einzelheiten mitteilen.
Und sollte ich den Vertrag nur einmal bereitstellen und dann beim nächsten API-Aufruf die Funktion addUserDetail aufrufen? Wenn ja, wie würde dies über web3.js erfolgen?
Wenn ich mich für diese Architektur entscheide und meine Benutzerbasis sehr groß wird, wäre sie dann immer noch effizient, oder sollten wir jeden Block für jeden Benutzer verwenden?
Es kann so schnell wachsen, wie Benutzer oder Administratoren es sich leisten können , Erstellungstransaktionen an den Vertrag zu senden. Abgesehen von Ethereum selbst gibt es kein Limit pro Block.
Danke für Ihre Antwort. Können Sie mir bitte sagen, warum ich nicht für jede Benutzerarchitektur einen anderen Block verwenden sollte?
Dieser Satz address of a blockist schwer zu verstehen. Wenn Sie URI of an objectwoanders gespeichert meinen, dann ja, das ist ein guter Ansatz.
Mit Adresse eines Blocks meine ich, einen Vertrag für jeden Benutzer bereitzustellen, damit er eine eindeutige Blockadresse erhält und mit Hilfe dieser Blockadresse (Hash) können wir seine Daten in Zukunft überprüfen.