Zugriff auf Zustandsvariablen in einem anderen Vertrag

Ich habe versucht, Methoden in einen Vertrag aufzunehmen, aber es wurde so groß, dass ich es nicht mit Trüffel einsetzen konnte. Jetzt muss ich einen anderen Vertrag erstellen, der anstelle des ursprünglichen Vertrags aufgerufen wird, um die im ursprünglichen Vertrag als Zustandsvariable gespeicherten Daten zu verarbeiten.

Die Variable, die ich verarbeiten werde, ist eine Zuordnung.

Ich versuche so etwas zu tun:

contract Original {

mapping(bytes32 => Person) private Persons;

 /* many structs and methods here */
}

contract SecondContract {
   function processdata(){
     /* here i want to process the data stored in the mapping in the first contract */
   }
}

Wie erhalte ich die Verbindung zwischen den beiden Verträgen und kann ich diese Daten verarbeiten?

Antworten (2)

Wenn ich das richtig verstehe, möchten Sie nur auf die Daten zugreifen, die in gespeichert sind Original. Wenn dies der Fall ist, können Sie Folgendes tun:

contract Original {
  mapping(bytes32 => Person) public persons;
}

contract SecondContract {
  Original original;

  function SecondContract(address ofOriginalContract) {
    original = Original(ofOriginalContract);
  }

  function processData(bytes32 someBytes) {
    Person entry = original.persons[someBytes];
    // do something with entry
  }
}

Beachten Sie, dass ich personseine publicZuordnung erstellt habe, damit wir von einem anderen Vertrag aus darauf zugreifen können.

Das ist etwas, was ich bereits getan habe, aber das Problem, dass ich meinem Vertrag nichts mehr hinzufügen kann, weil es nicht auf dem Ganache-Cli bereitgestellt wird (aufgrund der Größe). Das Hinzufügen eines zweiten Vertrags neben dem ursprünglichen Vertrag unterscheidet sich also nicht vom Hinzufügen processDataeiner Funktion zum ursprünglichen Vertrag

Verstärkung der Antwort von @ Travis.

Diese Linie

Original original;

fügt beträchtliche Größe hinzu, SecondContractweil es enthält Original .

Das ist ein separates Problem, das mit einer Schnittstelle gelöst werden kann. SecondContracterfordert nicht den vollständigen Bytecode für Original. Das wiederholt sich und ist unnötig. Es benötigt nur die Funktionssignatur und die Adresse der Instanz, mit der es kommunizieren soll.

Es gibt einige knifflige Vererbungs- und Type-Casting-Probleme, die zu entwirren sind, damit SecondContractdie kleinstmögliche Darstellung Originalder Oberfläche von (aber nicht des Arbeitscodes) geerbt werden kann und beide Verträge in Bezug auf das Layout der Person. Ich habe beschlossen, es für Sie zu versuchen. Sie können daraus auf eine komplexere Situation extrapolieren.

SecondContractwird viel kleiner sein, weil das, interfaceswas es erbt, niemals sehr groß werden wird.

pragma solidity 0.8.1;

interface Types {
  struct Person {
    uint age;
    string name;
  }    
}

interface IOriginal is Types {
  function persons(bytes32) external view returns(uint, string memory);
}

contract Original is IOriginal {
  mapping(bytes32 => Person) public override persons;
}

contract SecondContract is Types {
  IOriginal original;

  constructor(address ofOriginalContract) {
    original = IOriginal(ofOriginalContract);
  }

  function processData(bytes32 someBytes) public {
    (uint age, string memory name) = original.persons(someBytes);
    // do something with entry
  }
}

Es wäre zufriedenstellender, wenn function persons()ein Personanstelle der Mitglieder in zurückgegeben würde struct, aber ich habe es nicht zum Laufen gebracht. Vielleicht meldet sich eine gute Seele mit einer Lösung dafür.

Ich hoffe es hilft.