¿Cómo puedo acceder a la dirección de un contrato creado por otro contrato?

Tengo problemas para acceder a la dirección de un nuevo contrato generado dentro de otro contrato actuando como Fábrica. Mi código:

objeto del contrato {

    nombre de cadena;
    función Objeto (Cadena _nombre) {
        nombre = _nombre
    }
}

contrato ObjectFactory {
    función createObject(string nombre) devuelve (dirección objectAddress) {
        dirección de retorno (nuevo objeto (nombre));
    }
}

cuando compilo y ejecuto el método createObject(''), espero que me devuelvan la dirección del nuevo contrato. En cambio, recibo el hash de la transacción. Yo uso Web3 para ejecutar la función:

var dirección = web3.eth.contract(objectFactoryAbi)
                  .at(contratoFábricaDirección)
                  .createObject("objeto", { gasolina: precio, de: dirección de cuenta });

También intenté modificar la función para almacenar la dirección en una matriz, devolver la longitud de la matriz y luego recuperarla en un momento posterior, con los mismos resultados: siempre se devuelve el hash de la transacción.

Cualquier luz sobre esto es bienvenida.

Si almacenó la dirección en una matriz en Solidity, no es el hash de la transacción. Muestra el código de la matriz.
buena pregunta. Todos los patrones de diseño normales (por ejemplo, fábricas) deben estar bien documentados para Solidity

Respuestas (2)

A menudo, el contrato en sí necesitará almacenar la dirección para uso futuro. Así que simplemente almacene la dirección en el contrato como un atributo y recupérela desde fuera del contrato utilizando los métodos habituales (por ejemplo, llame a la ABI de obtención predeterminada si declara que es de alcance público), después de que se haya completado la transacción: (nota, no probado pseudocódigo, pero he hecho cosas similares varias veces)

contract ObjectFactory {
    Object public theObj;

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

Debe hacer un callantes de realizar una transacción:

var dirección = web3.eth.contract(objectFactoryAbi)
                  .at(contratoFábricaDirección)
                  .createObject.call("objeto");

Ahora que tienes la dirección, sí, haces la transacción:

var txHash = web3.eth.contrato(objectFactoryAbi)
                  .at(contratoFábricaDirección)
                  .createObject("objeto", { gasolina: precio, de: dirección de cuenta });

De lo contrario, puede calcular la dirección del futuro contrato así (código no verificado):

var ethJsUtil = require('ethereumjs-util');
var direcciónFuturo = ethJsUtil.bufferToHex(ethJsUtil.generateAddress(
      dirección de fábrica del contrato,
      await web3.eth.getTransactionCount(contratoFactoryAddress)));
muchas gracias. Hice algunos intentos y, de hecho, descubrí que funciona al revés: web3.eth.contract(objectFactoryAbi).at(contractFactoryAddress).createObject("object", { gas: price, from: accountAddress });devuelve la identificación de la transacción, mientras web3.eth.contract(objectFactoryAbi).at(contractFactoryAddress).createObject.call("object")que devolverá el resultado real de la última transacción.
Actualicé la respuesta para reflejar el hecho de que la segunda línea recibe el txHash. Mi descuido.