Vertrag, der den Status eines anderen Vertrags ändert

In meinem System können Benutzer beantragen, durch einen vertrauenswürdigen Vertrag verifiziert zu werden. Wenn ein Benutzer ein Konto erstellt, stellt er diesen Vertrag bereit (wobei nicht verwandte Teile weggelassen werden).

pragma solidity ^0.4.11;

contract User {
    // State variables
    address owner = msg.sender;
    bool verified = false;
    uint creationTime = now;
    struct PersonalInfo {
        string firstName;
        string LastName;
        string email;
    }
    uint level = 0;

    function requestVerification(address trustEntity) {
        /*
            This function should send a verification request
            to a trust entity's contract
        */
    }
}

Es gibt eine bekannte vertrauenswürdige Entität, deren Vertragsadresse jedem bekannt sein wird, die die einzige Entität sein sollte, die in der Lage ist, die Benutzer zu verifizieren. Sein Vertrag (unter Auslassung nicht verwandter Teile) ist

pragma solidity ^0.4.11;

contract TrustEntity {
    address owner;
    address registry;
    address[] public pendingRequests;

    function verifyUsers(address user) {
        /*
            Whenever a user requests verification, his
            address should be pushed to the pendingRequests
            array, so it can then be fetched to verify or
            reject
        */
    }   
}

Jedes Beispiel, das ich sehe, dass ein Vertrag mit einem anderen Vertrag interagiert, befinden sich beide in derselben Datei ( docs , this question ), daher weiß ich nicht, ob es möglich ist, dass ein Vertrag einen anderen Vertrag aufruft (oder in diesem speziellen Fall , um eine Adresse in die Zustandsvariable eines anderen Vertrags zu verschieben / die Zustandsvariable eines anderen Vertrags zu ändern).

Antworten (2)

Ja.

Der Anrufvertrag benötigt zwei Dinge; die Adresse des anzurufenden Vertrages und eine Beschreibung der ABI. Die ABI ist zusammengefasst eine Beschreibung der Funktionsnamen und des Layouts der Argumente.

Sie sehen die Verträge oft in derselben Datei, weil sie dem Compiler die Informationen geben, die er über die ABI benötigt. In vielen Fällen werden ein oder mehrere Verträge nicht manuell bereitgestellt, sondern durch einen Prozess in einem oder mehreren anderen Verträgen.

Sie könnten so etwas sehen:

import "/Utility.sol"; // something already deployed. We want the code so the compiler can see the interface.

contract Factory { // something that deploys instances
  Utility utility; // Type is Utility (contract)
  function Factory(address _utility) {
    utility = Utility(_utility); // Utility at the supplied (known) address
  }
  function newInstance() returns(address contract) {
    Instance = new Instance(utility); // make a new instance and inform about another contract's address
    return instance;
}

contract Instance { // something that will copied/deployed many times
  Utility utility;
  function Instance(address _utility) { // utility address passed in
    utility = Utility(_utility); // get set to use the Utility
  }
}

Oben ist die Idee, dass Utility bereitgestellt wird und der Deployer die Adresse kennt, sodass er sie beim Deployment der Factory an den Contructor weitergibt (andernfalls, woher weiß er das?). Sie müssen keine Instanz bereitstellen, da dies von der Factory erledigt wird. Der Compiler muss weiterhin alle drei Quelldateien sehen, wenn Factory kompiliert wird. Factory benötigt eine Kopie des Bytecodes, mit dem es bereitgestellt werden soll, new Instance();und es benötigt die Schnittstelle zum Dienstprogramm, da die beiden anderen Verträge mit ihm kommunizieren.

Ein etwas praktischeres Beispiel hier drüben: Gibt es ein einfaches Vertragsfabrikmuster?

Ich hoffe es hilft.

Jedes Beispiel, das ich sehe, dass ein Vertrag mit einem anderen Vertrag interagiert, befinden sich beide in derselben Datei (Dokumente, diese Frage).

Sie können Verträge in mehreren Dateien haben. Zwei Verträge, die interagieren sollen, müssen sich nicht in derselben Datei befinden. Sie teilen den anderen Vertrag, mit dem Sie interagieren möchten, per Import-Anweisung mit.

In diesem Fall, wenn Benutzerverträge mit TrustEntity interagieren möchten, sollte es wie unten sein

pragma solidity ^0.4.11;
import "TrustEntity.sol"; -- Import statement

contract User {
....
...
}

Ich weiß nicht, ob es für einen Vertrag möglich ist, einen anderen Vertrag aufzurufen (oder in diesem speziellen Fall eine Adresse in die Zustandsvariable eines anderen Vertrags zu verschieben / die Zustandsvariable eines anderen Vertrags zu ändern).

Ja, es ist möglich. Sie übergeben die Instanz des anderen Vertrags im Konstruktor (idealerweise ist es die Adresse, an der der Vertrag bereitgestellt wird). In diesem Fall

 pragma solidity ^0.4.11;
    import "TrustEntity.sol"; -- Import statement
    Trustentity trustentity;
    contract User {
   function User(address _trustentity )
    {
  trustentity= Trustentity(_trustentity); // This will pick the address where your contract is deployed. 
    }

Um die Zustandsvariable eines anderen Vertrags zu ändern, greifen Sie über eine andere Vertragsinstanz darauf zu. dh trustentity.pendingRequests gibt Ihnen alle ausstehenden Anfragen von Benutzern im Benutzervertrag.

Danke für die Erklärung! Es scheint alles zu funktionieren, aber es gibt immer noch ein Problem. trustEntity.pendingRequestssollte das Array für ausstehende Anfragen zurückgeben. Warum erhalte ich also eine Fehlermeldung, wenn ich versuche, trustentity.pendingRequests.push(owner)aus dem Benutzervertrag zu schreiben? Ich dachte, es würde sich genauso verhalten. Der Fehler, den ich bekomme, istbrowser/User.sol:19:6: TypeError: Member "push" not found or not visible after argument-dependent lookup in function (uint256) constant external returns (address) trustEntity.pendingRequests.push(owner); ^------------------------------^
Ich habe hier tatsächlich eine neue Frage zu diesem Thema gestellt, weil es sich um ein etwas anderes Problem handelt.