Skip to content

Instantly share code, notes, and snippets.

@onimusya
Created October 6, 2018 01:38
Show Gist options
  • Save onimusya/c756f066798e84aef427f3b0a45f9168 to your computer and use it in GitHub Desktop.
Save onimusya/c756f066798e84aef427f3b0a45f9168 to your computer and use it in GitHub Desktop.
How to compile Solidity Smart Contract without Truffle
// Tutorial 1
// Command Line: node tutorial1.js --build example.sol
// The require packages
const path = require('path');
const fs = require('fs');
const solc = require('solc');
const md5File = require('md5-file');
// Retrieve the command line arguments
var argv = require('minimist')(process.argv.slice(2), { string: ['checkminter'] });
// Input parameters for solc
// Refer to https://solidity.readthedocs.io/en/develop/using-the-compiler.html#compiler-input-and-output-json-description
var solcInput = {
language: "Solidity",
sources: { },
settings: {
optimizer: {
enabled: true
},
evmVersion: "byzantium",
outputSelection: {
"*": {
"": [
"legacyAST",
"ast"
],
"*": [
"abi",
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",
"evm.deployedBytecode.sourceMap",
"evm.gasEstimates"
]
},
}
}
};
// Try to lookup imported sol files in "contracts" folder or "node_modules" folder
function findImports(importFile) {
console.log("Import File:" + importFile);
try {
// Find in contracts folder first
result = fs.readFileSync("contracts/" + importFile, 'utf8');
return { contents: result };
} catch (error) {
// Try to look into node_modules
try {
result = fs.readFileSync("node_modules/" + importFile, 'utf8');
return { contents: result };
} catch (error) {
console.log(error.message);
return { error: 'File not found' };
}
}
}
// Compile the sol file in "contracts" folder and output the built json file to "build/contracts"
function buildContract(contract) {
let contractFile = 'contracts/' + contract;
let jsonOutputName = path.parse(contract).name + '.json';
let jsonOutputFile = './build/contracts/' + jsonOutputName;
let result = false;
try {
result = fs.statSync(contractFile);
} catch (error) {
console.log(error.message);
return false;
}
let contractFileChecksum = md5File.sync(contractFile);
try {
fs.statSync(jsonOutputFile);
let jsonContent = fs.readFileSync(jsonOutputFile, 'utf8');
let jsonObject = JSON.parse(jsonContent);
let buildChecksum = '';
if (typeof jsonObject['contracts'][contract]['checksum'] != 'undefined') {
buildChecksum = jsonObject['contracts'][contract]['checksum'];
console.log('File Checksum: ' + contractFileChecksum);
console.log('Build Checksum: ' + buildChecksum);
if (contractFileChecksum === buildChecksum) {
console.log('No build is required due no change in file.');
console.log('==============================');
return true;
}
}
} catch (error) {
// Any file not found, will continue build
}
let contractContent = fs.readFileSync(contractFile, 'utf8');
console.log('Contract File: ' + contract);
solcInput.sources[contract] = {
"content": contractContent
};
let solcInputString = JSON.stringify(solcInput);
let output = solc.compileStandardWrapper(solcInputString, findImports);
let jsonOutput = JSON.parse(output);
let isError = false;
if (jsonOutput.errors) {
jsonOutput.errors.forEach(error => {
console.log(error.severity + ': ' + error.component + ': ' + error.formattedMessage);
if (error.severity == 'error') {
isError = true;
}
});
}
if (isError) {
// Compilation errors
console.log('Compile error!');
return false;
}
// Update the sol file checksum
jsonOutput['contracts'][contract]['checksum'] = contractFileChecksum;
let formattedJson = JSON.stringify(jsonOutput, null, 4);
// Write the output JSON
fs.writeFileSync('./build/contracts/' + jsonOutputName, formattedJson);
console.log('==============================');
return true;
}
if (typeof argv.build !== 'undefined') {
// Build contract
var contract = argv.build;
let result = buildContract(contract);
return;
}
console.log('End here.');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment