¿Cómo podemos compilar múltiples contratos inteligentes mediante el archivo compile.js?

Mi archivo compile.js está debajo

const path = require('path');

const fs = require('fs');

const solc = require('solc');

const ballotPath = path.resolve(__dirname, 'contracts', 'blocktitans_ballot.sol');

const source = fs.readFileSync(ballotPath, 'utf8');

module.exports = solc.compile(source, 1).contracts[':blocktitans_ballot'];

Necesito ayuda para exportar abi y bytecode para múltiples contratos para escribir scripts de prueba.

El script compile.js anterior funciona para un solo contrato, pero ¿cómo puedo compilar varios contratos y exportarlos?

Respuestas (2)

Tiene dos posibilidades a) su propio script de compilación o b) simplemente use el marco de trufa. La primera opción es directa pero tiene algunos inconvenientes. Cuando comienza a escribir contratos, es una buena idea comprender la forma en que funciona el compilador sol, pero luego el marco truffle lo ayuda a administrar escenarios más complejos (es decir, como migraciones, pruebas, implementación y solicitudes de validación a etherscan).

Para responder a su pregunta (construir varios contratos con un solo script):

Este código es un guión inicial de un proyecto que hice el año pasado. En este código compila un contrato principal llamado CertificateManagement.sol y algunas dependencias de las bibliotecas de OpenZeppelin para la gestión de funciones, así como el código de Migraciones.sol.

// Dependencies
const solc = require("solc");
const fs = require("fs");

// Parameter default values
let BUILD_TARGET_PATH = './build/';

let contractBuild = async () => {

    // Creates target path in the case it doesn't exists
    fs.mkdir(BUILD_TARGET_PATH, {recursive: true}, (err) => {
        if (err) throw err;

        // loading the source code from a solidity file
        let input = {
            language: 'Solidity',
            sources: {
                //
                // CertificateManagement.sol
                'CertificateManagement.sol': {
                    content: fs.readFileSync('contracts/CertificateManagement.sol', 'utf8'),
                },
                //
                // Pausable.sol
                'openzeppelin/lifecycle/Pausable.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/lifecycle/Pausable.sol', 'utf8'),
                },
                './openzeppelin/lifecycle/Pausable.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/lifecycle/Pausable.sol', 'utf8'),
                },
                //
                // PauserRole.sol
                './openzeppelin/access/roles/PauserRole.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/roles/PauserRole.sol', 'utf8'),
                },
                '../access/roles/PauserRole.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/roles/PauserRole.sol', 'utf8'),
                },
                'openzeppelin/access/roles/PauserRole.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/roles/PauserRole.sol', 'utf8'),
                },
                //
                // Roles.sol
                'Roles.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/Roles.sol', 'utf8'),
                },
                '../Roles.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/Roles.sol', 'utf8'),
                },
                '../access/Roles.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/Roles.sol', 'utf8'),
                },
                './openzeppelin/access/Roles.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/Roles.sol', 'utf8'),
                },
                'openzeppelin/access/Roles.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/Roles.sol', 'utf8'),
                },
                //
                // WhitelistedRole.sol
                'openzeppelin/access/roles/WhitelistedRole.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/roles/WhitelistedRole.sol', 'utf8'),
                },
                //
                // WhitelistAdminRole.sol
                'WhitelistAdminRole.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/roles/WhitelistAdminRole.sol', 'utf8'),
                },
                './WhitelistAdminRole.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/roles/WhitelistAdminRole.sol', 'utf8'),
                },
                'openzeppelin/access/roles/WhitelistAdminRole.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/roles/WhitelistAdminRole.sol', 'utf8'),
                },
                //
                // WhitelistedRole.sol
                'WhitelistedRole.sol': {
                    content: fs.readFileSync('contracts/openzeppelin/access/roles/WhitelistedRole.sol', 'utf8'),
                },
                //
                // Migrations.sol
                'Migrations.sol': {
                    content: fs.readFileSync('contracts/Migrations.sol', 'utf8'),
                },
            },
            settings: {
                outputSelection: {'*': {'*': ['*']}}
            }
        };

        // compile the solidity code
        let compiled = solc.compile(JSON.stringify(input));
        console.log("Compiling    -> OK" );
        let output = JSON.parse(compiled);

        for (let contractJson in output.contracts) {
            if (contractJson.startsWith("CertificateManagement.")) {
                fs.writeFile(BUILD_TARGET_PATH + '/' + contractJson.replace(".sol", ".json"), JSON.stringify(output.contracts[contractJson][contractJson.replace(".sol", "")]), function (err) {
                    console.log("\nJSON saved   -> OK\n    "+ BUILD_TARGET_PATH + contractJson.replace(".sol", ".json"));
                    if (err) throw err;
                });
            }
        }

        // Save bytecode
        let bytecode = '0x' + output.contracts['CertificateManagement.sol']['CertificateManagement'].evm.bytecode.object;
        console.log('\nByte Code    -> OK');

        fs.writeFile(BUILD_TARGET_PATH + 'CertificateManagement.bytecode', bytecode, function (err) {
            console.log("\nCode saved   -> OK\n    "+ BUILD_TARGET_PATH + "CertificateManagement.bytecode");
            if (err) throw err;
        });

        // Logging of methods
        console.log('\nIndentifiers -> OK\n');
        let methodIdentifiers = output.contracts['CertificateManagement.sol']['CertificateManagement'].evm.methodIdentifiers;
        for (let indentifier in methodIdentifiers) {
            console.log("    " + indentifier);
        }

        // save public interface of contract
        let abi = output.contracts['CertificateManagement.sol']['CertificateManagement'].abi;
        fs.writeFile(BUILD_TARGET_PATH + 'CertificateManagement.abi', JSON.stringify(abi), function (err) {
            console.log("\nABI saved    -> OK\n    "+ BUILD_TARGET_PATH + "CertificateManagement.abi");
            console.log(" ");
            if (err) throw err;
        });
    });
};

contractBuild();

Supongo que --añadiendo los nombres de archivo .sol en ballotPath para esos contratos y --cambiando el número 1 por el número de contratos que desea compilar, como 2,3, etc. --y eliminando: blocktitans_ballot de .contracts en las exportaciones de módulos para que todos los contratos estén cubiertos.

disculpas de antemano si me equivoco. Gracias.