Guardar la dirección del contrato después de implementar con Truffle

Para automatizar mi ciclo de desarrollo, quiero guardar las direcciones de los contratos implementados para que mi DApp pueda leer esta información y saber dónde encontrar los contratos en mi cadena de bloques privada:

por ejemplo, así es como se ve mi secuencia de comandos de migración de trufas:

const fs  = require('fs');
var  FunnyToken = artifacts.require("FunnyToken");
var  TokenSale = artifacts.require("TokenSale");
var storage = {};
module.exports  = function(deployer, network, accounts) {
    deployer.deploy(FunnyToken, 1000000000000)
        .then(function(){
            storage.TOKEN_ADDRESS = FunnyToken.address;
            deployer.deploy(TokenSale, 1, accounts[0], FunnyToken.address).then(function () {
                storage.SALE_ADDRESS = TokenSale.address;
            });
        });

    console.log("adresses:")
    console.log(storage)
    fs.writeFileSync('.address.json',JSON.stringify(storage), 'utf-8');
};

Pero el .address.jsongenerado de esta manera contiene simplemente un objeto vacío: {}.

En el lado DApp, quiero conectarme a la dirección del Contrato

web3.eth.contract(address=contract_address, abi=contract_abi)

También debo mencionar que estoy usando Python y web3.py para escribir la DApp. De modo que, idealmente, la información de la dirección debería almacenarse en un archivo para ser leído por la aplicación Python.

¿Cuál es el patrón recomendado para esto?

El código para Python DApp (Incluyendo la solución propuesta)

¿Has echado un vistazo a Trufa? Ese es el tipo de cosas con las que puede ayudarte: truffleframework.com/docs/truffle/getting-started/…
@XavierLeprêtreB9lab Estoy usando trufa.

Respuestas (3)

Truffle crea archivos .json dentro del directorio build/. Hay un archivo para cada contrato, contienen la dirección del contrato implementado. Dentro hay build/contracts/MetaCoin.jsonuna sección "redes" que es un diccionario que asigna la identificación de la red a la dirección del contrato.

Puede utilizar el idioma de su elección para procesar estos archivos y generar un archivo de configuración con las direcciones que desee.

Otra opción es agregar un script de migración que se ejecutará después de todas las etapas anteriores. Este script escribirá las direcciones del contrato en un archivo de configuración de su elección.

Cree un archivo llamado 9_final_step.js en el directorio de migraciones

var ConvertLib = artifacts.require("./ConvertLib.sol");
var MetaCoin = artifacts.require("./MetaCoin.sol");

module.exports = function(deployer) {
  // Output to console or a configuration file
  console.log({
    MetaCoin: MetaCoin.address,
    ConvertLib: ConvertLib.address,
  });
};
Los archivos json dentro de la compilación/contratos son el resultado de la compilación del contrato sin implementación. por lo tanto, no contienen información sobre la dirección a la que se envía el contrato.
Actualizaré el ejemplo con una ilustración de por qué esto no funciona
Uso esa función todo el tiempo, durante las migraciones, los artefactos se actualizarán con la dirección de implementación. Al final de los artefactos hay una sección de "redes" que contiene la dirección de implementación.
@fccoelho Es posible que haya un error en sus scripts de migración que provoque que truffle no actualice los artefactos de los contratos.
tiene razón, hay un error en la implementación del contrato TokenSale que impide que truffle actualice los artefactos.
Me faltaba el retorno de los objetos del implementador.

Además del hecho de que Truffle actualiza los archivos JSON, .address.jsoncontiene solo un {}porque es fs.writeFileSyncdemasiado pronto.

Verá, la cosa del implementador que escribió es una cadena de promesas y la storageinformación está lista solo cuando todos los correos electrónicos se .thenhan disparado. Así que tienes que poner tu fs.writeFileSyncdespués de que todos hayan disparado. Observe los muchos returns:


return deployer.deploy(FunnyToken, 1000000000000)
    .then(() => {
        storage.TOKEN_ADDRESS = FunnyToken.address;
        return deployer.deploy(TokenSale, 1,...);
    })
    .then(() => {
        storage.SALE_ADDRESS = TokenSale.address;
        fs.writeFileSync('.address.json',JSON.stringify(storage), 'utf-8');
    });
Sí, me di cuenta de eso después de un tiempo. En cualquier caso, decidí usar los archivos JSON en lugar de generar un nuevo archivo. Gracias.

Hay una manera fácil de obtener la dirección del contrato: lea el JSON generado por truffle migratey obtenga la entrada del último networksevento, de la siguiente manera:

let contractAddress = await fetch('/build/contracts/ContractName.json')
        .then(response => response.json())
        .then(data => {
            let lastEvent = Object.keys(data.networks).pop();
            data.networks[lastEvent].address;
        });

¡Espero eso ayude!