forked from OpenZeppelin/ethernaut
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeploy_contracts.js
183 lines (154 loc) · 5.27 KB
/
deploy_contracts.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// These are required to enable ES6 on tests
// and it's dependencies.
require('babel-register')({
ignore: /node_modules\/(?!zeppelin-solidity)/
});
require('babel-polyfill');
// const Ethernaut = artifacts.require("./Ethernaut.sol");
const prompt = require('prompt')
const Web3 = require("web3")
const colors = require('colors')
const fs = require('fs')
const ethutil = require(`../src/utils/ethutil`)
const constants = require(`../src/constants`)
const EthernautABI = require('../build/contracts/Ethernaut.json')
const gamedata = require(`../gamedata/gamedata.json`)
let web3;
let ethernaut;
const PROMPT_ON_DEVELOP = true
const DEPLOY_DATA_PATH = `./gamedata/deploy.${constants.ACTIVE_NETWORK.name}.json`
async function exec() {
console.log(colors.cyan(`<< NETWORK: ${constants.ACTIVE_NETWORK.name} >>`).inverse)
await initWeb3()
// Retrieve deployment data for the active network.
const deployData = loadDeployData(DEPLOY_DATA_PATH)
// Determine which contracts need to be deployed.
let count = 0;
if(needsDeploy(deployData.ethernaut)) {
count++
console.log(colors.red(`(${count}) Will deploy Ethernaut.sol!`))
}
gamedata.levels.map(level => {
if(needsDeploy(deployData[level.deployId])) {
count++
console.log(colors.cyan(`(${count}) Will deploy ${level.levelContract} (${level.name})`))
}
})
if(count === 0) {
console.log(colors.gray(`No actions to perform, exiting.`));
return;
}
if(await confirmDeployment()) {
await deployContracts(deployData)
storeDeployData(DEPLOY_DATA_PATH, deployData)
}
}
exec()
async function deployContracts(deployData) {
const props = {
gasPrice: web3.eth.gasPrice * 10,
gas: 4500000
}
let from = constants.ADDRESSES[constants.ACTIVE_NETWORK.name];
if(!from) from = web3.eth.accounts[0];
console.log("FROM: ", from)
// Deploy/retrieve ethernaut contract
const Ethernaut = await ethutil.getTruffleContract(EthernautABI, {from})
if(needsDeploy(deployData.ethernaut)) {
console.log(deployData);
console.log(`Deploying Ethernaut.sol...`);
ethernaut = await Ethernaut.new(props)
console.log(colors.yellow(` Ethernaut: ${ethernaut.address}`));
deployData.ethernaut = ethernaut.address;
}
else {
console.log('Using deployed Ethernaut.sol:', deployData.ethernaut);
ethernaut = await Ethernaut.at(deployData.ethernaut)
// console.log('ethernaut: ', ethernaut);
}
// Sweep levels
const promises = gamedata.levels.map(async level => {
// console.log('level: ', level);
return new Promise(async resolve => {
if(needsDeploy(deployData[level.deployId])) {
console.log(`Deploying ${level.levelContract}, deployId: ${level.deployId}...`);
// Deploy contract
const LevelABI = require(`../build/contracts/${withoutExtension(level.levelContract)}.json`)
const Contract = await ethutil.getTruffleContract(LevelABI, {from})
const contract = await Contract.new(...level.deployParams, props)
console.log(colors.yellow(` ${level.name}: ${contract.address}`));
deployData[level.deployId] = contract.address
console.log(colors.gray(` storing deployed id: ${level.deployId} with address: ${contract.address}`));
// Register level in Ethernaut contract
console.log(` Registering level in Ethernaut.sol...`)
const tx = await ethernaut.registerLevel(contract.address, props);
// console.log(tx)
}
else {
console.log(`Using deployed ${level.levelContract}...`);
}
resolve(level)
})
})
return Promise.all(promises)
}
// ----------------------------------
// Utils
// ----------------------------------
function withoutExtension(str) {
return str.split('.')[0]
}
function needsDeploy(deployAddress) {
if(constants.ACTIVE_NETWORK === constants.NETWORKS.LOCAL) return true
return deployAddress === undefined || deployAddress === 'x'
}
function initWeb3() {
return new Promise(async (resolve, reject) => {
const providerUrl = `${constants.ACTIVE_NETWORK.url}:${constants.ACTIVE_NETWORK.port}`
console.log(colors.gray(`connecting web3 to '${providerUrl}'...`));
const provider = new Web3.providers.HttpProvider(providerUrl);
web3 = new Web3(provider)
web3.net.getListening((err, res) => {
if(err) {
console.log('error connecting web3:', err);
reject()
return
}
console.log(colors.gray(`web3 connected: ${res}\n`));
ethutil.setWeb3(web3)
resolve()
})
})
}
function loadDeployData(path) {
try {
return JSON.parse(fs.readFileSync(path, 'utf8'))
}
catch(err){
return {}
}
}
function storeDeployData(path, deployData) {
console.log(colors.green(`Writing updated deploy data: ${path}`))
fs.writeFileSync(path, JSON.stringify(deployData, null, 2), 'utf8')
}
function confirmDeployment() {
return new Promise((resolve, reject) => {
if(PROMPT_ON_DEVELOP || constants.ACTIVE_NETWORK !== constants.NETWORKS.LOCAL) {
const options = {
properties: {
confirmDeployment: {
description: `Confirm deployment? (y/n)`
}
}
}
prompt.start()
prompt.get(options, (err, res) => {
if (err) return reject(err)
resolve(res.confirmDeployment === 'y')
})
} else {
resolve(true)
}
})
}