1 | import async from 'async'
|
2 | import { execution } from 'remix-lib'
|
3 | import Web3 from 'web3'
|
4 | import { compilationInterface } from 'types'
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | export function deployAll(compileResult: compilationInterface, web3: Web3, withDoubleGas: boolean, callback) {
|
15 | let compiledObject = {}
|
16 | let contracts = {}
|
17 | let accounts: string[] = []
|
18 |
|
19 | async.waterfall([
|
20 | function getAccountList(next: Function) {
|
21 | web3.eth.getAccounts((_err, _accounts) => {
|
22 | accounts = _accounts
|
23 | next()
|
24 | })
|
25 | },
|
26 | function getContractData(next: Function) {
|
27 | for (let contractFile in compileResult) {
|
28 | for (let contractName in compileResult[contractFile]) {
|
29 | let contract = compileResult[contractFile][contractName]
|
30 |
|
31 | const className = contractName
|
32 | const filename = contractFile
|
33 |
|
34 | let abi = contract.abi
|
35 | let code = contract.evm.bytecode.object
|
36 |
|
37 | compiledObject[className] = {}
|
38 | compiledObject[className].abi = abi
|
39 | compiledObject[className].code = code
|
40 | compiledObject[className].filename = filename
|
41 | compiledObject[className].className = className
|
42 | compiledObject[className].raw = contract
|
43 |
|
44 | if (contractFile.endsWith('_test.sol')) {
|
45 | compiledObject[className].isTest = true
|
46 | }
|
47 | }
|
48 | }
|
49 | next()
|
50 | },
|
51 | function determineContractsToDeploy(next: Function) {
|
52 | let contractsToDeploy: string[] = ['Assert']
|
53 | let allContracts = Object.keys(compiledObject)
|
54 |
|
55 | for (let contractName of allContracts) {
|
56 | if (contractName === 'Assert') {
|
57 | continue
|
58 | }
|
59 | if (compiledObject[contractName].isTest) {
|
60 | contractsToDeploy.push(contractName)
|
61 | }
|
62 | }
|
63 | next(null, contractsToDeploy)
|
64 | },
|
65 | function deployContracts(contractsToDeploy: string[], next: Function) {
|
66 | const deployRunner = (deployObject, contractObject, contractName, filename, callback) => {
|
67 | deployObject.estimateGas().then((gasValue) => {
|
68 | const gasBase = Math.ceil(gasValue * 1.2)
|
69 | const gas = withDoubleGas ? gasBase * 2 : gasBase
|
70 | deployObject.send({
|
71 | from: accounts[0],
|
72 | gas: gas
|
73 | }).on('receipt', function (receipt) {
|
74 | contractObject.options.address = receipt.contractAddress
|
75 | contractObject.options.from = accounts[0]
|
76 | contractObject.options.gas = 5000 * 1000
|
77 | compiledObject[contractName].deployedAddress = receipt.contractAddress
|
78 |
|
79 | contracts[contractName] = contractObject
|
80 | contracts[contractName].filename = filename
|
81 |
|
82 | callback(null, { result: { createdAddress: receipt.contractAddress } })
|
83 | }).on('error', function (err) {
|
84 | console.error(err)
|
85 | callback(err)
|
86 | })
|
87 | })
|
88 | }
|
89 |
|
90 | async.eachOfLimit(contractsToDeploy, 1, function (contractName, index, nextEach) {
|
91 | let contract = compiledObject[contractName]
|
92 | let encodeDataFinalCallback = (error, contractDeployData) => {
|
93 | if (error) return nextEach(error)
|
94 | try {
|
95 | let contractObject = new web3.eth.Contract(contract.abi)
|
96 | let deployObject = contractObject.deploy({arguments: [], data: '0x' + contractDeployData.dataHex})
|
97 | deployRunner(deployObject, contractObject, contractName, contract.filename, (error) => { nextEach(error) })
|
98 | } catch (e) {
|
99 | throw e
|
100 | }
|
101 | }
|
102 |
|
103 | let encodeDataStepCallback = (msg) => { console.dir(msg) }
|
104 |
|
105 | let encodeDataDeployLibraryCallback = (libData, callback) => {
|
106 | let abi = compiledObject[libData.data.contractName].abi
|
107 | let code = compiledObject[libData.data.contractName].code
|
108 | let libraryObject = new web3.eth.Contract(abi)
|
109 | let deployObject = libraryObject.deploy({arguments: [], data: '0x' + code})
|
110 | deployRunner(deployObject, libraryObject, libData.data.contractName, contract.filename, callback)
|
111 | }
|
112 |
|
113 | let funAbi = null
|
114 | let params = ''
|
115 | execution.txFormat.encodeConstructorCallAndDeployLibraries(contractName, contract.raw, compileResult, params, funAbi, encodeDataFinalCallback, encodeDataStepCallback, encodeDataDeployLibraryCallback)
|
116 | }, function (err) {
|
117 | if(err) next(err)
|
118 | next(null, contracts)
|
119 | })
|
120 | }
|
121 | ], callback)
|
122 | }
|