Wie kann ich auf die Adresse eines Vertrags zugreifen, der von einem anderen Vertrag erstellt wurde?

Ich habe Probleme beim Zugriff auf die Adresse eines neuen Vertrags, der in einem anderen Vertrag erstellt wurde, der als Fabrik fungiert. Mein Code:

Vertragsgegenstand {

    Zeichenfolgenname;
    Funktion Objekt(String _name) {
        name = _name
    }
}

Vertrag ObjectFactory {
    Funktion createObject(string name) gibt zurück (Adresse objectAddress) {
        Rücksendeadresse (neues Objekt (Name));
    }
}

Wenn ich die Methode kompiliere und ausführe createObject(''), erwarte ich, dass die Adresse des neuen Vertrags zurückgegeben wird. Stattdessen erhalte ich den Hash der Transaktion. Ich verwende Web3, um die Funktion auszuführen:

var address = web3.eth.contract(objectFactoryAbi)
                  .at(VertragFabrikAdresse)
                  .createObject("object", { gas: price, from: accountAddress });

Ich habe auch versucht, die Funktion zu ändern, um die Adresse in einem Array zu speichern, die Länge des Arrays zurückzugeben und sie dann zu einem späteren Zeitpunkt abzurufen, mit den gleichen Ergebnissen: Es wird immer der Transaktions-Hash zurückgegeben.

Jedes Licht auf diesem ist willkommen.

Wenn Sie die Adresse in Solidity in einem Array gespeichert haben, ist dies nicht der Hash der Transaktion. Zeigen Sie den Code des Array-Dings.
gute Frage. Alle normalen Entwurfsmuster (z. B. Fabriken) müssen für Solidity gut dokumentiert werden

Antworten (2)

Oft muss der Vertrag selbst die Adresse für die zukünftige Verwendung speichern. Speichern Sie also einfach die Adresse im Vertrag als Attribut und rufen Sie sie von außerhalb des Vertrags mit den üblichen Methoden ab (z. B. Aufruf des Standard-Getters ABI, wenn Sie ihn als öffentlichen Bereich deklarieren), nachdem die Transaktion abgeschlossen wurde: Pseudo-Code, aber ich habe ähnliche Sachen ein paar Mal gemacht)

contract ObjectFactory {
    Object public theObj;

    function createObject(string name) returns (address objectAddress) {
        theObj = address(new Object(name));
        return theObj;
    }
}

Sie sollten Folgendes tun, callbevor Sie eine Transaktion durchführen:

var address = web3.eth.contract(objectFactoryAbi)
                  .at(VertragFabrikAdresse)
                  .createObject.call("Objekt");

Jetzt, da Sie die Adresse haben, ja, führen Sie die Transaktion durch:

var txHash = web3.eth.contract(objectFactoryAbi)
                  .at(VertragFabrikAdresse)
                  .createObject("object", { gas: price, from: accountAddress });

Andernfalls können Sie die Adresse des zukünftigen Vertrags wie folgt berechnen (Code nicht verifiziert):

var ethJsUtil = require('ethereumjs-util');
var futureAddress = ethJsUtil.bufferToHex(ethJsUtil.generateAddress(
      VertragFabrikAdresse,
      warte auf web3.eth.getTransactionCount(contractFactoryAddress)));
Vielen Dank. Ich habe einige Versuche unternommen und festgestellt, dass es umgekehrt funktioniert: web3.eth.contract(objectFactoryAbi).at(contractFactoryAddress).createObject("object", { gas: price, from: accountAddress });Gibt die Transaktions-ID zurück, während web3.eth.contract(objectFactoryAbi).at(contractFactoryAddress).createObject.call("object")das tatsächliche Ergebnis der letzten Transaktion zurückgegeben wird
Ich habe die Antwort aktualisiert, um die Tatsache widerzuspiegeln, dass die zweite Zeile den txHash erhält. Mein Versehen.