Solidity (solc) compile challenge

857 Views Asked by At

I'm trying to leverage what I thought was pretty good code I found to another answer that allows me to compile a number of .sol files in a directory at once while producing the .json files in a /build directory.

I've spent several solid days on this...but can't break through. As you can see from the code below and from the console log statements, I know compile.js is:

  1. Reading all the contract.sol files in the /contracts folder...of which there are 7. (They're all short. Only one of which is coded. The rest merely have the pragam statement as well as the contract name delaration).

  2. It's deleting the /build folder and its' contents and recreating it before it does the compile.

  3. It's getting the following error on the solc.compile line and console logs that output as per the error below '/////// Output is - '.

    errors: [ 'Error parsing input JSON: * Line 1, Column 1\n' + ' Syntax error: value, object or array expected.\n' + '* Line 1, Column 1\n' + ' A valid JSON document must be either an array or an object value.\n' ]

  4. It enters the for loop...but doesn't seem to output anything other than the error in the /build directory in an errors.json file.

My programs are all pragma ^0.4.25 and so is the solc compiler version in my package.json file.

I'm DESPERATE for experienced eyes to see the problem and help me get through this compile step.

I know many will suggest using Truffle but this is a pre-existing React app and a) I don't want to start from scratch and b) I really do want to understand this critical solc.compile step and the following code in the for loop!

P.S. contract compiles, deploys and works cleanly in Remix.

But I need to get access to the interface and bytecode in React app so that I can initiate a number of different Ethereum transactions.

Thank you.

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

// Pointing path to build folder so that we can delete everything in it.
// Fetch path of build
const buildPath = path.resolve(__dirname, "build");

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

// Fetch all Contract files in Contracts folder
const contractsPath = path.resolve(__dirname, "contracts");
const fileNames = fs.readdirSync(contractsPath);

// console.log("buildPath - ", buildPath);
// console.log("contractsPath - ", contractsPath);
// console.log("fileNames is - ", fileNames);

// 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: {} }
);

console.log("input contains these SCs - ", input);

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

console.log("Recreated the directory...");

// Compile all contracts
// const output = solc.compile(input, 1).contract;
var output = solc.compile(JSON.stringify(input).sources);

console.log("//////// OUTPUT is - ", output);

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


// ----------------------------------------------
// const bytecode = output.contracts[0].bytecode;
// const abi = JSON.parse(output.contracts[0].interface);

// console.log('\nBytecode: ', bytecode, '\nABI: ', abi);
**strong text**
1

There are 1 best solutions below

0
On

Try:

var output = JSON.parse(solc.compile(JSON.stringify(input).sources)));