diff --git a/lib/contracts/compiler.js b/lib/contracts/compiler.js index eb82a9b3..054e6bf2 100644 --- a/lib/contracts/compiler.js +++ b/lib/contracts/compiler.js @@ -1,21 +1,14 @@ /*jshint esversion: 6, loopfunc: true */ let async = require('../utils/async_extend.js'); -let SolcW = require('./solcW.js'); class Compiler { constructor(options) { this.plugins = options.plugins; this.logger = options.logger; - this.solcVersion = options.solcVersion; - this.contractDirectories = options.contractDirectories; } compile_contracts(contractFiles, cb) { - - let available_compilers = { - //".se": this.compile_serpent - ".sol": this.compile_solidity.bind(this) - }; + let available_compilers = {}; if (this.plugins) { let compilerPlugins = this.plugins.getPluginsFor('compilers'); @@ -48,90 +41,6 @@ class Compiler { } ); } - - compile_solidity(contractFiles, cb) { - let self = this; - let input = {}; - let solcW; - async.waterfall([ - function prepareInput(callback) { - async.each(contractFiles, - function(file, fileCb) { - let filename = file.filename; - - for (let directory of self.contractDirectories) { - filename = filename.replace(directory, ''); - } - - file.content(function(fileContent) { - input[filename] = fileContent; - fileCb(); - }); - }, - function (err) { - callback(err); - } - ); - }, - function loadCompiler(callback) { - // TODO: there ino need to load this twice - solcW = new SolcW({logger: self.logger, solcVersion: self.solcVersion}); - if (solcW.isCompilerLoaded()) { - return callback(); - } - - self.logger.info("loading solc compiler.."); - solcW.load_compiler(function (err) { - callback(err); - }); - }, - function compileContracts(callback) { - self.logger.info("compiling contracts..."); - solcW.compile({sources: input}, 1, function (output) { - if (output.errors) { - for (let i=0; i= 0) { - return callback(new Error("Solidity errors: " + output.errors).message); - } - } - self.logger.warn(output.errors.join('\n')); - } - callback(null, output); - }); - }, - function createCompiledObject(output, callback) { - let json = output.contracts; - - let compiled_object = {}; - - for (let contractName in json) { - let contract = json[contractName]; - - // Pull out filename:classname - // [0] filename:classname - // [1] filename - // [2] classname - const regex = /(.*):(.*)/; - const className = contractName.match(regex)[2]; - const filename = contractName.match(regex)[1]; - - compiled_object[className] = {}; - compiled_object[className].code = contract.bytecode; - compiled_object[className].runtimeBytecode = contract.runtimeBytecode; - compiled_object[className].realRuntimeBytecode = contract.runtimeBytecode.slice(0, -68); - compiled_object[className].swarmHash = contract.runtimeBytecode.slice(-68).slice(0, 64); - compiled_object[className].gasEstimates = contract.gasEstimates; - compiled_object[className].functionHashes = contract.functionHashes; - compiled_object[className].abiDefinition = JSON.parse(contract.interface); - compiled_object[className].filename = filename; - } - - callback(null, compiled_object); - } - ], function (err, result) { - cb(err, result); - }); - } } module.exports = Compiler; diff --git a/lib/contracts/contracts.js b/lib/contracts/contracts.js index 8c7616f4..00a26059 100644 --- a/lib/contracts/contracts.js +++ b/lib/contracts/contracts.js @@ -8,17 +8,10 @@ let Compiler = require('./compiler.js'); class ContractsManager { constructor(options) { this.contractFiles = options.contractFiles; - this.contractDirectories = options.contractDirectories; this.contractsConfig = options.contractsConfig; this.contracts = {}; this.logger = options.logger; this.plugins = options.plugins; - if (!options.contractsConfig.versions) { - this.solcVersion = "0.4.17"; - } else { - this.solcVersion = options.contractsConfig.versions.solc; - } - this.contractDependencies = {}; } @@ -26,7 +19,7 @@ class ContractsManager { let self = this; async.waterfall([ function compileContracts(callback) { - let compiler = new Compiler({plugins: self.plugins, logger: self.logger, solcVersion: self.solcVersion, contractDirectories: self.contractDirectories}); + let compiler = new Compiler({plugins: self.plugins, logger: self.logger}); compiler.compile_contracts(self.contractFiles, function (err, compiledObject) { self.compiledContracts = compiledObject; callback(err); diff --git a/lib/contracts/deploy_manager.js b/lib/contracts/deploy_manager.js index 9614af1f..975abae0 100644 --- a/lib/contracts/deploy_manager.js +++ b/lib/contracts/deploy_manager.js @@ -26,7 +26,6 @@ class DeployManager { function buildContracts(callback) { let contractsManager = new ContractsManager({ contractFiles: self.config.contractsFiles, - contractDirectories: self.config.contractDirectories, contractsConfig: self.config.contractsConfig, logger: self.logger, plugins: self.plugins diff --git a/lib/core/engine.js b/lib/core/engine.js index 050c7528..d689f3fe 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -46,6 +46,10 @@ class Engine { this.servicesMonitor.startMonitor(); } + registerModule(moduleName, options) { + this.plugins.loadInternalPlugin(moduleName, options); + } + startService(serviceName, _options) { let options = _options || {}; @@ -124,6 +128,12 @@ class Engine { deploymentService(options) { let self = this; + + this.registerModule('solidity', { + solcVersion: self.config.contractsConfig.solcVersion, + contractDirectories: self.config.contractDirectories + }); + this.deployManager = new DeployManager({ web3: options.web3 || self.web3, trackContracts: options.trackContracts, diff --git a/lib/core/plugin.js b/lib/core/plugin.js index 45a498f0..59272374 100644 --- a/lib/core/plugin.js +++ b/lib/core/plugin.js @@ -5,6 +5,7 @@ var utils = require('../utils/utils.js'); // TODO: pass other params like blockchainConfig, contract files, etc.. var Plugin = function(options) { this.name = options.name; + this.isInternal = options.isInternal; this.pluginModule = options.pluginModule; this.pluginPath = options.pluginPath; this.pluginConfig = options.pluginConfig; @@ -31,6 +32,10 @@ Plugin.prototype.loadPlugin = function() { (this.pluginModule.call(this, this)); }; +Plugin.prototype.loadInternalPlugin = function() { + new this.pluginModule(this, this.pluginConfig); +}; + Plugin.prototype.loadPluginFile = function(filename) { return fs.readFileSync(this.pathToFile(filename)).toString(); }; diff --git a/lib/core/plugins.js b/lib/core/plugins.js index c3319183..d2ba61b8 100644 --- a/lib/core/plugins.js +++ b/lib/core/plugins.js @@ -27,11 +27,20 @@ Plugins.prototype.listPlugins = function() { return list; }; +Plugins.prototype.loadInternalPlugin = function(pluginName, pluginConfig) { + var pluginPath = utils.joinPath('../modules/', pluginName, 'index.js'); + var plugin = require(pluginPath); + + var pluginWrapper = new Plugin({name: pluginName, pluginModule: plugin, pluginConfig: pluginConfig, logger: this.logger, pluginPath: pluginPath, interceptLogs: this.interceptLogs, events: this.events, config: this.config, isInternal: true}); + pluginWrapper.loadInternalPlugin(); + this.plugins.push(pluginWrapper); +}; + Plugins.prototype.loadPlugin = function(pluginName, pluginConfig) { var pluginPath = utils.joinPath(process.env.PWD, 'node_modules', pluginName); var plugin = require(pluginPath); - var pluginWrapper = new Plugin({name: pluginName, pluginModule: plugin, pluginConfig: pluginConfig, logger: this.logger, pluginPath: pluginPath, interceptLogs: this.interceptLogs, events: this.events, config: this.config}); + var pluginWrapper = new Plugin({name: pluginName, pluginModule: plugin, pluginConfig: pluginConfig, logger: this.logger, pluginPath: pluginPath, interceptLogs: this.interceptLogs, events: this.events, config: this.config, isInternal: false}); pluginWrapper.loadPlugin(); this.plugins.push(pluginWrapper); }; diff --git a/lib/modules/solidity/index.js b/lib/modules/solidity/index.js new file mode 100644 index 00000000..2087268b --- /dev/null +++ b/lib/modules/solidity/index.js @@ -0,0 +1,100 @@ +let async = require('../../utils/async_extend.js'); +let SolcW = require('./solcW.js'); + +class Solidity { + + constructor(embark, options) { + this.logger = embark.logger; + this.solcVersion = options.solcVersion; + this.contractDirectories = options.contractDirectories; + + embark.registerCompiler(".sol", this.compile_solidity.bind(this)); + } + + compile_solidity(contractFiles, cb) { + let self = this; + let input = {}; + let solcW; + async.waterfall([ + function prepareInput(callback) { + async.each(contractFiles, + function(file, fileCb) { + let filename = file.filename; + + for (let directory of self.contractDirectories) { + filename = filename.replace(directory, ''); + } + + file.content(function(fileContent) { + input[filename] = fileContent; + fileCb(); + }); + }, + function (err) { + callback(err); + } + ); + }, + function loadCompiler(callback) { + // TODO: there ino need to load this twice + solcW = new SolcW({logger: self.logger, solcVersion: self.solcVersion}); + if (solcW.isCompilerLoaded()) { + return callback(); + } + + self.logger.info("loading solc compiler.."); + solcW.load_compiler(function (err) { + callback(err); + }); + }, + function compileContracts(callback) { + self.logger.info("compiling contracts..."); + solcW.compile({sources: input}, 1, function (output) { + if (output.errors) { + for (let i=0; i= 0) { + return callback(new Error("Solidity errors: " + output.errors).message); + } + } + self.logger.warn(output.errors.join('\n')); + } + callback(null, output); + }); + }, + function createCompiledObject(output, callback) { + let json = output.contracts; + + let compiled_object = {}; + + for (let contractName in json) { + let contract = json[contractName]; + + // Pull out filename:classname + // [0] filename:classname + // [1] filename + // [2] classname + const regex = /(.*):(.*)/; + const className = contractName.match(regex)[2]; + const filename = contractName.match(regex)[1]; + + compiled_object[className] = {}; + compiled_object[className].code = contract.bytecode; + compiled_object[className].runtimeBytecode = contract.runtimeBytecode; + compiled_object[className].realRuntimeBytecode = contract.runtimeBytecode.slice(0, -68); + compiled_object[className].swarmHash = contract.runtimeBytecode.slice(-68).slice(0, 64); + compiled_object[className].gasEstimates = contract.gasEstimates; + compiled_object[className].functionHashes = contract.functionHashes; + compiled_object[className].abiDefinition = JSON.parse(contract.interface); + compiled_object[className].filename = filename; + } + + callback(null, compiled_object); + } + ], function (err, result) { + cb(err, result); + }); + } + +} + +module.exports = Solidity; diff --git a/lib/contracts/solcP.js b/lib/modules/solidity/solcP.js similarity index 100% rename from lib/contracts/solcP.js rename to lib/modules/solidity/solcP.js diff --git a/lib/contracts/solcW.js b/lib/modules/solidity/solcW.js similarity index 89% rename from lib/contracts/solcW.js rename to lib/modules/solidity/solcW.js index a801d1ec..d557187a 100644 --- a/lib/contracts/solcW.js +++ b/lib/modules/solidity/solcW.js @@ -1,9 +1,9 @@ -let utils = require('../utils/utils.js'); +let utils = require('../../utils/utils.js'); let solcProcess; let compilerLoaded = false; -var Npm = require('../pipeline/npm.js'); +var Npm = require('../../pipeline/npm.js'); let path = require('path'); -let currentSolcVersion = require('../../package.json').dependencies.solc; +let currentSolcVersion = require('../../../package.json').dependencies.solc; class SolcW {