Reputation: 429
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
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
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
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