remix-project mirror
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
remix-project/libs/remix-tests/src/deployer.ts

118 lines
4.7 KiB

import async from 'async'
import { execution } from '@remix-project/remix-lib'
import Web3 from 'web3'
import { compilationInterface } from './types'
/**
* @dev Deploy all contracts from compilation result
* @param compileResult compilation result
* @param web3 web3 object
* @param withDoubleGas If true, try deployment with gas double of estimation (used for Out-of-gas error only)
* @param callback Callback
*/
export function deployAll (compileResult: compilationInterface, web3: Web3, withDoubleGas: boolean, callback) {
const compiledObject = {}
const contracts = {}
let accounts: string[] = []
async.waterfall([
function getAccountList (next) {
web3.eth.getAccounts((_err, _accounts) => {
accounts = _accounts
next()
})
},
function getContractData (next) {
for (const contractFile in compileResult) {
for (const contractName in compileResult[contractFile]) {
const contract = compileResult[contractFile][contractName]
const className = contractName
const filename = contractFile
const abi = contract.abi
const code = contract.evm.bytecode.object
compiledObject[className] = {}
compiledObject[className].abi = abi
compiledObject[className].code = code
compiledObject[className].filename = filename
compiledObject[className].className = className
compiledObject[className].raw = contract
if (contractFile.endsWith('_test.sol')) {
compiledObject[className].isTest = true
}
}
}
next()
},
function determineContractsToDeploy (next) {
const contractsToDeploy: string[] = ['Assert']
const allContracts = Object.keys(compiledObject)
for (const contractName of allContracts) {
if (contractName === 'Assert') {
continue
}
if (compiledObject[contractName].isTest) {
contractsToDeploy.push(contractName)
}
}
next(null, contractsToDeploy)
},
function deployContracts (contractsToDeploy: string[], next) {
const deployRunner = (deployObject, contractObject, contractName, filename, callback) => {
deployObject.estimateGas().then((gasValue) => {
const gasBase = Math.ceil(gasValue * 1.2)
const gas = withDoubleGas ? gasBase * 2 : gasBase
deployObject.send({
from: accounts[0],
gas: gas
}).on('receipt', function (receipt) {
contractObject.options.address = receipt.contractAddress
contractObject.options.from = accounts[0]
contractObject.options.gas = 5000 * 1000
compiledObject[contractName].deployedAddress = receipt.contractAddress
contracts[contractName] = contractObject
contracts[contractName].filename = filename
callback(null, { receipt: { contractAddress: receipt.contractAddress } }) // TODO this will only work with JavaScriptV VM
}).on('error', function (err) {
console.error(err)
callback(err)
})
})
}
async.eachOfLimit(contractsToDeploy, 1, function (contractName, index, nextEach) {
const contract = compiledObject[contractName]
const encodeDataFinalCallback = (error, contractDeployData) => {
if (error) return nextEach(error)
const contractObject = new web3.eth.Contract(contract.abi)
const deployObject = contractObject.deploy({ arguments: [], data: '0x' + contractDeployData.dataHex })
deployRunner(deployObject, contractObject, contractName, contract.filename, (error) => { nextEach(error) })
}
const encodeDataStepCallback = (msg) => { console.dir(msg) }
const encodeDataDeployLibraryCallback = (libData, callback) => {
const abi = compiledObject[libData.data.contractName].abi
const code = compiledObject[libData.data.contractName].code
const libraryObject = new web3.eth.Contract(abi)
const deployObject = libraryObject.deploy({ arguments: [], data: '0x' + code })
deployRunner(deployObject, libraryObject, libData.data.contractName, contract.filename, callback)
}
const funAbi = null // no need to set the abi for encoding the constructor
const params = '' // we suppose that the test contract does not have any param in the constructor
execution.txFormat.encodeConstructorCallAndDeployLibraries(contractName, contract.raw, compileResult, params, funAbi, encodeDataFinalCallback, encodeDataStepCallback, encodeDataDeployLibraryCallback)
}, function (err) {
if (err) return next(err)
next(null, contracts)
})
}
], callback)
}