Liv Stan
Liv Stan

Reputation: 429

Solidity: How to compile multiple smart contracts in compile.js file?

I would like to compile multiple contracts in one compile.js file but I'm not sure how to do it.

My compile.js file with a single contract looks like this:

const path = require('path');
const fs = require('fs');
const solc = require('solc');

const lotteryPath = path.resolve(__dirname, 'contracts', 'Lottery.sol');

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

module.exports = solc.compile(source, 1);

How can I add more contracts to the compile.js file? I understand that the 1 must be changed to the number of contracts, but not sure what else is required?

Upvotes: 5

Views: 4369

Answers (3)

shubham
shubham

Reputation: 11

compile.js:

const path= require('path');
const solc = require('solc');
const fs = require('fs-extra');

const builtPath = path.resolve(__dirname, 'build');
//remove file in build module
fs.removeSync(builtPath);
const healthPath = path.resolve(__dirname, 'contract','health.sol');
//read  content present in file
console.log(healthPath);
const source = fs.readFileSync(healthPath,'utf8');
//compile contract
const output = solc.compile(source,1).contracts;
//create build folder

fs.ensureDirSync(builtPath);
console.log(output);


for(let contract in output)
{
    fs.outputJsonSync(
      path.resolve(buildPath, contract.replace(':','')+ '.json'),
      output[contract]
  );
}

Upvotes: 1

Henry Palacios
Henry Palacios

Reputation: 311

The approved solution does not work for solidity >0.6.0 and <=0.8.1.

For the mentioned versions, I solved it as follows:

const path = require("path");
const fs = require("fs-extra");
const solc = require("solc");

const buildPath = path.resolve(__dirname, "build");
fs.removeSync(buildPath);

const contractPath = path.resolve(__dirname, "contracts");
const fileNames = fs.readdirSync(contractPath);

const compilerInput = {
  language: "Solidity",
  sources: fileNames.reduce((input, fileName) => {
    const filePath = path.resolve(contractPath, fileName);
    const source = fs.readFileSync(filePath, "utf8");
    return { ...input, [fileName]: { content: source } };
  }, {}),
  settings: {
    outputSelection: {
      "*": {
        "*": ["abi", "evm.bytecode.object"],
      },
    },
  },
};

// Compile All contracts
const compiled = JSON.parse(solc.compile(JSON.stringify(compilerInput)));

fs.ensureDirSync(buildPath);

fileNames.map((fileName) => {
  const contracts = Object.keys(compiled.contracts[fileName]);
  contracts.map((contract) => {
    fs.outputJsonSync(
      path.resolve(buildPath, contract + ".json"),
      compiled.contracts[fileName][contract]
    );
  });
});

be sure to check that your pragma solidity x.x.x matches with the version specified in your package.json. For example, if I'm using solidity 0.6.12 my solidity compiles would be:

  "dependencies": {
    ...
    "solc": "^0.6.12",
    ...
  }

Upvotes: 3

Jo&#227;o Quintanilha
Jo&#227;o Quintanilha

Reputation: 206

Here is an example I did. You can find it in my public repo. Briefly, I have a "build" folder where I write the output of each compiled contract to Json files.

const path = require("path"); //nodejs ’path’ module
    const solc = require("solc"); //solidity compiler module
    const fs = require("fs-extra"); //file system module

    // Feth path of build
    const buildPath = path.resolve(__dirname, "build");
    const contractspath = path.resolve(__dirname, "contracts");

    // Removes folder build and every file in it
    fs.removeSync(buildPath);

    // Fetch all Contract files in Contracts folder
    const fileNames = fs.readdirSync(contractspath);

    // Gets ABI of all contracts into variable input
    const input = fileNames.reduce(
      (input, fileName) => {
        const filePath = path.resolve(__dirname, "contracts", fileName);
        const source = fs.readFileSync(filePath, "utf8");
        return { sources: { ...input.sources, [fileName]: source } };
      },
      { sources: {} }
    );

    // Compile all contracts
    const output = solc.compile(input, 1).contracts;

    // Re-Create build folder for output files from each contract
    fs.ensureDirSync(buildPath);

    // Output contains all objects from all contracts
    // Write the contents of each to different files
    for (let contract in output) {
      fs.outputJsonSync(
        path.resolve(buildPath, contract.split(":")[1] + ".json"),
        output[contract]
      );
    }

Basically, if you do not change your path struct to mine, you have to change you this part of the above code:

// Feth path of build
        const buildPath = path.resolve(__dirname, "build");
        const contractspath = path.resolve(__dirname, "contracts");

Upvotes: 4

Related Questions