2018-05-26 12:31:46 -04:00
|
|
|
const async = require('async');
|
|
|
|
const shelljs = require('shelljs');
|
2018-07-23 12:37:27 -04:00
|
|
|
const fs = require('fs');
|
2018-07-23 15:14:03 -04:00
|
|
|
const path = require('path');
|
2018-05-26 12:31:46 -04:00
|
|
|
|
2018-07-24 11:56:35 -04:00
|
|
|
function compileSolcContract(logger, filename, allowedDirectories, callback) {
|
|
|
|
const command = `solc --optimize --combined-json abi,bin,bin-runtime,compact-format,hashes,interface,metadata --allow-paths ${allowedDirectories.join(',')} ${filename}`;
|
|
|
|
shelljs.exec(command,
|
2018-05-26 12:31:46 -04:00
|
|
|
{silent: true}, (code, stdout, stderr) => {
|
|
|
|
|
|
|
|
if (stderr) {
|
|
|
|
logger.warn(stderr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (code !== 0) {
|
|
|
|
return callback(`solc exited with error code ${code}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!stdout) {
|
|
|
|
return callback('Execution returned nothing');
|
|
|
|
}
|
|
|
|
|
|
|
|
callback(null, stdout.replace(/\n/g, ''));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-07-23 12:37:27 -04:00
|
|
|
function compileSolc(embark, contractFiles, cb) {
|
2018-05-26 12:31:46 -04:00
|
|
|
if (!contractFiles || !contractFiles.length) {
|
|
|
|
return cb();
|
|
|
|
}
|
2018-05-30 15:52:42 -04:00
|
|
|
|
2018-07-23 12:37:27 -04:00
|
|
|
const logger = embark.logger;
|
|
|
|
const outputBinary = embark.pluginConfig.outputBinary;
|
|
|
|
const outputDir = embark.config.buildDir + embark.config.contractDirectories[0];
|
|
|
|
|
2018-05-30 15:52:42 -04:00
|
|
|
const solc = shelljs.which('solc');
|
|
|
|
if (!solc) {
|
2018-09-12 09:38:03 -04:00
|
|
|
logger.error('solc is not installed on your machine');
|
2018-05-30 15:52:42 -04:00
|
|
|
logger.info('You can install it by following the instructions on: http://solidity.readthedocs.io/en/latest/installing-solidity.html');
|
2018-09-12 09:38:03 -04:00
|
|
|
return cb('Compiler not installed');
|
2018-05-30 15:52:42 -04:00
|
|
|
}
|
|
|
|
|
2018-05-26 12:31:46 -04:00
|
|
|
logger.info("compiling solidity contracts with command line solc...");
|
2018-07-24 11:56:35 -04:00
|
|
|
|
2018-07-24 12:05:42 -04:00
|
|
|
const allowedDirectories = contractFiles.map((contractFile) => path.dirname(path.join(process.cwd(), contractFile.path)))
|
|
|
|
.filter((x, i, a) => a.indexOf(x) == i);
|
2018-07-24 11:56:35 -04:00
|
|
|
|
2018-05-26 12:31:46 -04:00
|
|
|
let compiled_object = {};
|
|
|
|
async.each(contractFiles,
|
|
|
|
function (file, fileCb) {
|
2018-07-24 11:56:35 -04:00
|
|
|
compileSolcContract(logger, file.filename, allowedDirectories, (err, compileString) => {
|
2018-05-26 12:31:46 -04:00
|
|
|
if (err) {
|
|
|
|
return fileCb(err);
|
|
|
|
}
|
|
|
|
|
2018-05-30 15:52:42 -04:00
|
|
|
let jsonStart = compileString.indexOf("\"contracts\":{");
|
|
|
|
|
|
|
|
let json = JSON.parse(compileString.substr(jsonStart - 1));
|
2018-05-26 12:31:46 -04:00
|
|
|
|
|
|
|
for (let contractFile in json.contracts) {
|
|
|
|
let className = contractFile.substr( contractFile.indexOf(":") + 1);
|
2018-07-24 13:37:59 -04:00
|
|
|
let filename = contractFile.substr(0, contractFile.indexOf(":"));
|
2018-05-26 12:31:46 -04:00
|
|
|
|
|
|
|
let contract = json.contracts[contractFile];
|
2018-07-24 13:37:59 -04:00
|
|
|
if(compiled_object[className] && compiled_object[className].filename != filename){
|
|
|
|
logger.warn(`Duplicated contract '${className}' found. Using '${compiled_object[className].filename}' instead of '${file.filename}'`);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-26 12:31:46 -04:00
|
|
|
compiled_object[className] = {};
|
|
|
|
compiled_object[className].code = contract.bin
|
|
|
|
compiled_object[className].runtimeBytecode = contract["bin-runtime"];
|
|
|
|
compiled_object[className].functionHashes = contract.hashes;
|
|
|
|
compiled_object[className].abiDefinition = JSON.parse(contract.abi);
|
2018-07-24 13:37:59 -04:00
|
|
|
compiled_object[className].filename = filename;
|
2018-05-26 12:31:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
fileCb();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
function (err) {
|
2018-07-23 13:29:13 -04:00
|
|
|
cb(err, compiled_object);
|
2018-07-23 15:14:03 -04:00
|
|
|
if(outputBinary){
|
|
|
|
embark.events.on("outputDone", function() {
|
2018-07-23 13:29:13 -04:00
|
|
|
Object.keys(compiled_object).map(function(className, index) {
|
2018-09-21 15:41:22 -04:00
|
|
|
fs.writeFile(path.join(outputDir, className + ".bin"), compiled_object[className].code, (err) => {
|
2018-07-23 13:29:13 -04:00
|
|
|
if (err) {
|
|
|
|
logger.error("Error writing binary file: " + JSON.stringify(err));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2018-07-23 15:14:03 -04:00
|
|
|
});
|
|
|
|
}
|
2018-05-26 12:31:46 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
compileSolc,
|
|
|
|
compileSolcContract
|
|
|
|
};
|