diff --git a/dapps/tests/app/app/contracts/another_storage.sol b/dapps/tests/app/app/contracts/another_storage.sol new file mode 100644 index 000000000..ba845f931 --- /dev/null +++ b/dapps/tests/app/app/contracts/another_storage.sol @@ -0,0 +1,10 @@ +pragma solidity ^0.4.18; +contract AnotherStorage { + address public simpleStorageAddress; + address simpleStorageAddress2; + + constructor(address addr) public { + simpleStorageAddress = addr; + } + +} diff --git a/dapps/tests/app/config/contracts.js b/dapps/tests/app/config/contracts.js index 6527ccbb5..f5b6f1315 100644 --- a/dapps/tests/app/config/contracts.js +++ b/dapps/tests/app/config/contracts.js @@ -16,11 +16,15 @@ module.exports = { deploy: { SimpleStorage: { fromIndex: 0, - args: [100], - onDeploy: [ - "SimpleStorage.methods.setRegistar(web3.eth.defaultAccount).send()" - ] + args: [100] + // onDeploy: [ + // "SimpleStorage.methods.setRegistar(web3.eth.defaultAccount).send()" + // ] }, + AnotherStorage: { + args: ["$SimpleStorage"] + //args: ["0x0000000000000000000000000000000000000000"] + } }, afterDeploy: async (dependencies) => { console.log("=========================="); @@ -36,7 +40,7 @@ module.exports = { console.log("=========================="); console.log("=========================="); console.log("=========================="); - console.dir(dependencies); + // console.dir(dependencies); // console.dir(dependencies.contracts.SimpleStorage.methods); // try { // let value = await dependencies.contracts.SimpleStorage.methods.get().call(); diff --git a/packages/embark-contracts-manager/src/index.js b/packages/embark-contracts-manager/src/index.js index 2d28006bc..51049ed0a 100644 --- a/packages/embark-contracts-manager/src/index.js +++ b/packages/embark-contracts-manager/src/index.js @@ -45,6 +45,10 @@ class ContractsManager { cb(this.compileError, this.contractsState()); }); + this.events.setCommandHandler("contracts:contract", (contractName, cb) => { + cb(null, this.getContract(contractName)); + }); + console.dir("---- contracts manager---- ") // this.registerCommands() // this.registerAPIs() @@ -72,10 +76,6 @@ class ContractsManager { cb(self.compileError, self.contractDependencies); }); - self.events.setCommandHandler("contracts:contract", (contractName, cb) => { - cb(self.getContract(contractName)); - }); - self.events.setCommandHandler("contracts:contract:byTxHash", (txHash, cb) => { self.getContractByTxHash(txHash, cb); }); diff --git a/packages/embark/src/lib/modules/ethereum-blockchain-client/index.js b/packages/embark/src/lib/modules/ethereum-blockchain-client/index.js index 96c70392d..993998967 100644 --- a/packages/embark/src/lib/modules/ethereum-blockchain-client/index.js +++ b/packages/embark/src/lib/modules/ethereum-blockchain-client/index.js @@ -1,3 +1,4 @@ +const async = require('async'); const Web3 = require('web3'); const embarkJsUtils = require('embarkjs').Utils; @@ -7,6 +8,7 @@ class EthereumBlockchainClient { this.embark = embark; this.events = embark.events; + this.embark.registerActionForEvent('deployment:contract:beforeDeploy', this.determineArguments.bind(this)); this.events.request("blockchain:client:register", "ethereum", this.getClient.bind(this)); this.events.request("deployment:deployer:register", "ethereum", this.deployer.bind(this)); } @@ -23,12 +25,8 @@ class EthereumBlockchainClient { let account = accounts[0]; // let contractObject = this.blockchain.ContractObject({abi: contract.abiDefinition}); console.dir("== ethereum contract deployer") - console.dir(contract) - console.dir("-------") - console.dir("------- new web3") let contractObj = new web3.eth.Contract(contract.abiDefinition, contract.address); // let deployObject = this.blockchain.deployContractObject(contractObject, {arguments: contractParams, data: dataCode}); - console.dir("------- deploy") let contractObject = contractObj.deploy({ arguments: (contract.args || []), data: ("0x" + contract.code) }); // this.blockchain.deployContractFromObject(deployObject, console.dir({ arguments: contract.args, data: ("0x" + contract.code) }); @@ -46,6 +44,84 @@ class EthereumBlockchainClient { }) } + // TODO we can separate this into 3 separate methods, which will make it easier to test + // determineArguments(suppliedArgs, contract, accounts, callback) { + async determineArguments(params, callback) { + let suppliedArgs = params.contract.args; + let contract = params.contract; + let provider = await this.events.request2("blockchain:client:provider", "ethereum"); + let web3 = new Web3(provider) + let accounts = await web3.eth.getAccounts(); + + const self = this; + + let args = suppliedArgs; + if (!Array.isArray(args)) { + args = []; + let abi = contract.abiDefinition.find((abi) => abi.type === 'constructor'); + + for (let input of abi.inputs) { + let inputValue = suppliedArgs[input.name]; + if (!inputValue) { + this.logger.error(__("{{inputName}} has not been defined for {{className}} constructor", {inputName: input.name, className: contract.className})); + } + args.push(inputValue || ""); + } + } + + function parseArg(arg, cb) { + const match = arg.match(/\$accounts\[([0-9]+)]/); + if (match) { + if (!accounts[match[1]]) { + return cb(__('No corresponding account at index %d', match[1])); + } + return cb(null, accounts[match[1]]); + } + let contractName = arg.substr(1); + self.events.request('contracts:contract', contractName, (err, referedContract) => { + // Because we're referring to a contract that is not being deployed (ie. an interface), + // we still need to provide a valid address so that the ABI checker won't fail. + cb(err, (referedContract.deployedAddress || ZERO_ADDRESS)); + }); + } + + function checkArgs(argus, cb) { + async.map(argus, (arg, nextEachCb) => { + if (arg[0] === "$") { + return parseArg(arg, nextEachCb); + } + + if (Array.isArray(arg)) { + return checkArgs(arg, nextEachCb); + } + + return nextEachCb(null, arg); + + // TODO: re-add after ENS is re-added OR better yet, move this to the ENS plugin + // self.events.request('ens:isENSName', arg, (isENSName) => { + // if (isENSName) { + // return self.events.request("ens:resolve", arg, (err, address) => { + // if (err) { + // return nextEachCb(err); + // } + // nextEachCb(err, address); + // }); + // } + + // nextEachCb(null, arg); + // }); + }, cb); + } + + checkArgs(args, (err, realArgs) => { + if (err) { + return callback(err); + } + params.contract.args = realArgs; + callback(null, params); + }); + } + } module.exports = EthereumBlockchainClient;