Gibt es eine Möglichkeit, einen Smart Contract zu haben, der einen Wert und einen Namen speichert und dann von einem anderen Smart Contract aufgerufen werden kann? So etwas ... (aber das funktioniert)
Contract D {
struct Document{
string name;
uint value;
}
function StoreDocument(bytes32 key, string name, uint value) returns (bool success) {
var doc = Document(name, value);
documents[key].push(doc);
return true;
}
}
Und dann möchte ich, dass ein anderer Vertrag den Schlüssel, die Vertragsadresse und den Namen übernimmt und den Wert zurückgeben kann, um ihn in einem Vertrag zu verwenden. Jede Hilfe wäre großartig.
Contract E {
function RetrieveData(address ConDadd, bytes32 key, string name) {
//some funciton to get the data from Contract D
}
}
Ich habe mit Ihrem Beispiel begonnen und es angepasst, bis es funktioniert. Ein paar Hinweise, die mir dabei aufgefallen sind.
struct
definiert einen Typ. Sie müssen eine Variable mit diesem Typ in Speicherwerte umwandeln. mapping
ist das Werkzeug zum Organisieren von Instanzen nach eindeutigem Schlüssel.
Ich habe den Typ von name
auf geändert, bytes32
da es derzeit nicht möglich ist, Zeichenfolgen zwischen Kontrakten zu übergeben.
E benötigt Kenntnisse des ABI für D, damit es Anrufe tätigen kann. D befindet sich in derselben Quelldatei, sodass der Compiler es "sehen" kann, wenn er auf diese Zeile trifft, die eine Variable als Typ "D" umwandelt.
D d;
E muss auch die Adresse „der“ D-Instanz kennen, mit der es kommunizieren soll. Der Konstruktor für E erwartet eine übergebene Adresse, wenn er bereitgestellt wird.
Ich habe die Zuordnung öffentlich gemacht, also wird eine "freie" Getter-Funktion aufgerufen documentStructs()
, die nur die key
übergebenen Werte erwartet. Sie gibt die beiden gespeicherten Werte zurück.
pragma solidity ^0.4.6;
contract D {
// This is a Type
struct DocumentStruct{
// Not possible to pass strings between contracts at this time
bytes32 name;
uint value;
}
// This is a namespace where we will store docs of Type DocumentStruct
mapping(bytes32 => DocumentStruct) public documentStructs;
// Set values in storage
function StoreDocument(bytes32 key, bytes32 name, uint value) returns (bool success) {
documentStructs[key].name = name;
documentStructs[key].value = value;
return true;
}
}
contract E {
// "d" is of type "D" which is a contract ^
D d;
// Define the Type in this context
struct DocumentStruct{
bytes32 name;
uint value;
}
// For this to work, pass in D's address to E's constructor
function E(address DContractAddress) {
d = D(DContractAddress);
}
function RetrieveData(bytes32 key)
public
constant
returns(bytes32, uint)
{
// Declare a temporary "doc" to hold a DocumentStruct
DocumentStruct memory doc;
// Get it from the "public" mapping's free getter.
(doc.name, doc.value) = d.documentStructs(key);
// return values with a fixed sized layout
return(doc.name, doc.value);
}
}
Es gibt alle möglichen nicht offensichtlichen Überlegungen zur Datenorganisation, die in der Anfangsphase ein bisschen schwierig sein können. Es kann hilfreich sein, sich die Stärken und Schwächen verschiedener Muster anzusehen, die hier aufgezeigt werden: Gibt es gut gelöste und einfache Speichermuster für Solidity?
Hier ist das obige in Remix, um zu zeigen, dass es funktioniert.
Ich hoffe es hilft.
das Fett