embark-solc
Advanced tools
Comparing version 1.0.0 to 4.0.0
30
index.js
/*global require, module*/ | ||
const Compiler = require("./lib/Compiler"); | ||
const semver = require('semver'); | ||
module.exports = (embark) => { | ||
embark.registerCompiler('.sol', compileSolc); | ||
function compileSolc(contractFiles, options, cb) { | ||
if(!contractFiles || !contractFiles.length) { | ||
return cb(); | ||
} | ||
Compiler.compileSolc(embark, contractFiles, cb); | ||
} | ||
if (embark.config.embarkConfig.versions.solc) { | ||
embark.registerCompiler('.sol', (contractFiles, options, cb) => { | ||
if (!contractFiles || !contractFiles.length) { | ||
return cb(); | ||
} | ||
Compiler.getSolcVersion(embark.logger, (err, version) => { | ||
if (err) { | ||
embark.logger.error(err); | ||
embark.logger.error("Error getting solc's version. Will default back to Embark's compiler"); | ||
return cb(null, false); | ||
} | ||
if (semver.lt(version, embark.config.embarkConfig.versions.solc)) { | ||
embark.logger.warn(`Current version of solc lower than version in embark.json`); | ||
embark.logger.warn(`Current: ${version} | Wanted: ${embark.config.embarkConfig.versions.solc}`); | ||
embark.logger.warn('Will default back to Embark\'s compiler'); | ||
return cb(null, false); | ||
} | ||
Compiler.compileSolc(embark, contractFiles, embark.config.contractDirectories, options, cb); | ||
}); | ||
}); | ||
} | ||
}; |
@@ -6,7 +6,6 @@ const async = require('async'); | ||
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, | ||
{silent: true}, (code, stdout, stderr) => { | ||
function compileSolcContract(logger, compileSettings, allowedDirectories, callback) { | ||
const command = `solc --standard-json --allow-paths ${allowedDirectories.join(',')}`; | ||
shelljs.ShellString(JSON.stringify(compileSettings)).exec(command, {silent: true}, (code, stdout, stderr) => { | ||
if (stderr) { | ||
@@ -21,3 +20,3 @@ logger.warn(stderr); | ||
if (!stdout) { | ||
return callback('Execution returned nothing'); | ||
return callback('solc execution returned nothing'); | ||
} | ||
@@ -29,5 +28,24 @@ | ||
function compileSolc(embark, contractFiles, cb) { | ||
function getSolcVersion(logger, callback) { | ||
shelljs.exec('solc --version', {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('solc execution returned nothing'); | ||
} | ||
const result = stdout.match(/(\d+.\d+.\d+)/); | ||
callback(null, result[1]); | ||
}); | ||
} | ||
function compileSolc(embark, contractFiles, contractDirectories, options, callback) { | ||
if (!contractFiles || !contractFiles.length) { | ||
return cb(); | ||
return callback(); | ||
} | ||
@@ -38,62 +56,155 @@ | ||
const outputDir = embark.config.buildDir + embark.config.contractDirectories[0]; | ||
const solcConfig = embark.config.embarkConfig.options.solc; | ||
const solc = shelljs.which('solc'); | ||
if (!solc) { | ||
logger.error('solc is not installed on your machine'); | ||
logger.info('You can install it by following the instructions on: http://solidity.readthedocs.io/en/latest/installing-solidity.html'); | ||
return cb('Compiler not installed'); | ||
} | ||
logger.info("compiling solidity contracts with command line solc..."); | ||
let allowedDirectories = []; | ||
const remappings = []; | ||
const compilationSettings = { | ||
language: 'Solidity', | ||
sources: {}, | ||
settings: { | ||
optimizer: { | ||
enabled: solcConfig['optimize'], | ||
runs: solcConfig['optimize-runs'] | ||
}, | ||
remappings, | ||
outputSelection: { | ||
'*': { | ||
'': ['ast'], | ||
'*': [ | ||
'abi', | ||
'devdoc', | ||
'evm.bytecode', | ||
'evm.deployedBytecode', | ||
'evm.gasEstimates', | ||
'evm.legacyAssembly', | ||
'evm.methodIdentifiers', | ||
'metadata', | ||
'userdoc' | ||
] | ||
} | ||
} | ||
} | ||
}; | ||
const allowedDirectories = contractFiles.map((contractFile) => path.dirname(path.join(process.cwd(), contractFile.path))) | ||
.filter((x, i, a) => a.indexOf(x) == i); | ||
async.waterfall([ | ||
function checkSolc(next) { | ||
const solc = shelljs.which('solc'); | ||
if (!solc) { | ||
logger.error('solc is not installed on your machine'); | ||
logger.info('You can install it by following the instructions on: http://solidity.readthedocs.io/en/latest/installing-solidity.html'); | ||
return next('Compiler not installed'); | ||
} | ||
logger.info("compiling solidity contracts with command line solc..."); | ||
next(); | ||
}, | ||
let compiled_object = {}; | ||
async.each(contractFiles, | ||
function (file, fileCb) { | ||
compileSolcContract(logger, file.filename, allowedDirectories, (err, compileString) => { | ||
function getContentAndRemappings(next) { | ||
async.each(contractFiles, (file, eachCb) => { | ||
file.prepareForCompilation(options.isCoverage).then((content) => { | ||
// add contract directory and all it's recusrive import direcotries to allowed directories | ||
let dir = path.dirname(file.path); | ||
if (!allowedDirectories.includes(dir)) allowedDirectories.push(dir); | ||
file.importRemappings.forEach((importRemapping) => { | ||
dir = path.dirname(importRemapping.target); | ||
if (!allowedDirectories.includes(dir)) allowedDirectories.push(dir); | ||
const remapping = `${importRemapping.prefix}=${importRemapping.target}`; | ||
if (!remappings.includes(remapping)) { | ||
remappings.push(remapping); | ||
} | ||
}); | ||
compilationSettings.sources[file.path] = { | ||
content: content.replace(/\r\n/g, '\n') | ||
}; | ||
eachCb(); | ||
}).catch(eachCb); | ||
}, next); | ||
}, | ||
function compile(next) { | ||
compileSolcContract(logger, compilationSettings, allowedDirectories, (err, compileString) => { | ||
if (err) { | ||
return fileCb(err); | ||
return next(err); | ||
} | ||
let json; | ||
try { | ||
json = JSON.parse(compileString); | ||
} catch (e) { | ||
logger.error(e.message || e); | ||
return callback(`Compiling returned an unreadable result`); | ||
} | ||
const contracts = json.contracts; | ||
let jsonStart = compileString.indexOf("\"contracts\":{"); | ||
// Check for errors | ||
if (json.errors) { | ||
let isError = false; | ||
json.errors.forEach(error => { | ||
if (error.severity === 'error') { | ||
isError = true; | ||
logger.error(error.formattedMessage); | ||
} else { | ||
logger.warn(error.formattedMessage); | ||
} | ||
}); | ||
if (isError) { | ||
return next(`Error while compiling`); | ||
} | ||
} | ||
next(null, contracts); | ||
}); | ||
}, | ||
let json = JSON.parse(compileString.substr(jsonStart - 1)); | ||
function populateCompiledObject(contracts, next) { | ||
const compiledObject = {}; | ||
for (let contractFile in contracts) { | ||
for (let contractName in contracts[contractFile]) { | ||
let contract = contracts[contractFile][contractName]; | ||
let filename = contractFile; | ||
const originalFilename = filename; | ||
for (let directory of contractDirectories) { | ||
let match = new RegExp("^" + directory); | ||
filename = filename.replace(match, ''); | ||
} | ||
for (let contractFile in json.contracts) { | ||
let className = contractFile.substr( contractFile.indexOf(":") + 1); | ||
let filename = contractFile.substr(0, contractFile.indexOf(":")); | ||
let contract = json.contracts[contractFile]; | ||
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; | ||
let className = contractName; | ||
const contractFileMatch = className.match(/.sol:(.*)/); | ||
if (contractFileMatch) { | ||
className = contractFileMatch[1]; | ||
} | ||
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); | ||
compiled_object[className].filename = filename; | ||
compiledObject[className] = {}; | ||
compiledObject[className].code = contract.evm.bytecode.object; | ||
compiledObject[className].linkReferences = contract.evm.bytecode.linkReferences; | ||
compiledObject[className].runtimeBytecode = contract.evm.deployedBytecode.object; | ||
compiledObject[className].realRuntimeBytecode = contract.evm.deployedBytecode.object.slice(0, -68); | ||
compiledObject[className].swarmHash = contract.evm.deployedBytecode.object.slice(-68).slice(0, 64); | ||
compiledObject[className].gasEstimates = contract.evm.gasEstimates; | ||
compiledObject[className].functionHashes = contract.evm.methodIdentifiers; | ||
compiledObject[className].abiDefinition = contract.abi; | ||
compiledObject[className].filename = filename; | ||
compiledObject[className].originalFilename = originalFilename; | ||
} | ||
} | ||
fileCb(); | ||
next(null, compiledObject); | ||
} | ||
], (err, compiledObject) => { | ||
callback(err, compiledObject); | ||
if (outputBinary) { | ||
embark.events.once("outputDone", () => { | ||
async.eachOf(compiledObject, (contract, className, eachCb) => { | ||
fs.writeFile(path.join(outputDir, className + ".bin"), compiledObject[className].code, eachCb); | ||
}, (err) => { | ||
if (err) { | ||
logger.error("Error writing binary file", err.message || err); | ||
} | ||
}); | ||
}); | ||
}, | ||
function (err) { | ||
cb(err, compiled_object); | ||
if(outputBinary){ | ||
embark.events.on("outputDone", function() { | ||
Object.keys(compiled_object).map(function(className, index) { | ||
fs.writeFile(path.join(outputDir, className + ".bin"), compiled_object[className].code, (err) => { | ||
if (err) { | ||
logger.error("Error writing binary file: " + JSON.stringify(err)); | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
@@ -103,3 +214,4 @@ | ||
compileSolc, | ||
compileSolcContract | ||
compileSolcContract, | ||
getSolcVersion | ||
}; |
{ | ||
"name": "embark-solc", | ||
"version": "1.0.0", | ||
"version": "4.0.0", | ||
"description": "Solc plugin for Embark (uses command line)", | ||
@@ -24,8 +24,9 @@ "main": "index.js", | ||
"devDependencies": { | ||
"eslint": "^4.19.1" | ||
"eslint": "^5.16.0" | ||
}, | ||
"dependencies": { | ||
"async": "^2.6.0", | ||
"semver": "^5.6.0", | ||
"shelljs": "^0.8.1" | ||
} | ||
} |
@@ -6,9 +6,10 @@ Embark-Solc | ||
Installation | ||
====== | ||
## Installation | ||
In your embark dapp directory: | ||
```npm install embark-solc --save``` | ||
then add embark-solc to the plugins section in ```embark.json```: | ||
then add embark-solc to the plugins section in `embark.json`: | ||
@@ -25,7 +26,6 @@ ```Json | ||
Requirements | ||
====== | ||
## Requirements | ||
- Embark 3.0.0 or higher | ||
- Solc installed and available globally on your machine | ||
- [Solc](https://github.com/ethereum/solidity/releases) installed and available globally on your machine (h) | ||
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
18478
5
493
3
2
+ Addedsemver@^5.6.0
+ Addedsemver@5.7.2(transitive)