4

My compile.js file is below

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'];

I need help to export abi and bytecode for multiple contracts to write test scripts.

Above compile.js script works for single contract but how can I compile multiple contracts and export them?

2 Answers 2

1

You have two possibilities a) your own build script or b) just use truffle framework. The first option is strait forward but has some drawbacks. When you start with writing contracts it is a good idea to understand the way the sol compiler works, but later the truffle framework helps you to manage more complex scenarios (i.e. like migrations, testing, deployment and validation requests to etherscan).

To answer your question (building several contracts with a single script):

This code is an early script of a project I did last year. In this code you compile a main contract called CertificateManagement.sol and some dependency from the OpenZeppelin libraries for role management as well as the Migrations.sol code.

// 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();
0

I guess - --by adding the .sol file names in ballotPath for those contracts & --by changing the number 1 to the number of contracts you want to compile, like 2,3 etc --and removing the : blocktitans_ballot from .contracts in module exports so that all the contracts are covered.

apologies in advance if I am incorrect. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.