-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwasabi-deploy
164 lines (142 loc) · 5.31 KB
/
wasabi-deploy
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
console.log("Starting deployment...");
var Web3 = require("web3");
var Solc = require("solc");
var Config = require("config");
var fs = require('fs');
var Tx = require('ethereumjs-tx');
var wallet = require('ethereumjs-wallet');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider(Config.get('host')));
// Set Gas price
var maxGas = Config.get('max_gas');
console.log("Max gas price set to:", maxGas);
// Set address
var fromAddress = (Config.has('from')) ? Config.get('from') : web3.eth.accounts[0];
if (fromAddress == null && Config.has())
throw new Error("Contract author address not set!");
// Read contracts and create inputs
var input = {};
var contracts = Config.get('contracts');
for (var i = 0; i < contracts.length; i++) {
// read file
console.log("Reading contract:", contracts[i]);
var data = fs.readFileSync(contracts[i], 'utf8');
input[contracts[i]] = data;
}
// Compile input
var output = Solc.compile({ sources: input }, 1);
// Estimate Gas for all contracts
var gasQuote = {};
for (var contract in output.contracts) {
var code = "0x" + output.contracts[contract].bytecode;
var gas = web3.eth.estimateGas({
from: fromAddress,
data: code
});
console.log("Contract ", contract, ": estimated gas ", gas);
if (gas > maxGas) {
throw new Error("Gas price estimate is higher than made maxGas.");
}
gasQuote[contract] = gas;
}
// Create contracts.json
fs.writeFileSync('app/contracts.json', '[]', 'utf8');
// Sign to RPC node
if (Config.has('private_key')) {
pushSignedContract(0);
}
else {
for (var contract in output.contracts) {
var code = "0x" + output.contracts[contract].bytecode;
var abi = JSON.parse(output.contracts[contract].interface);
var c = web3.eth.contract(abi);
pushContract(contract, c);
}
}
function getTransactionReceipt(name, hash, abi, index) {
console.log('waiting for contract', name,' to be mined ', hash);
const receipt = web3.eth.getTransactionReceipt(hash);
if (receipt == null) {
setTimeout(() => {
getTransactionReceipt(name, hash, abi, index);
}, 1000);
} else {
console.log("Contract (", name, ") mined! Address: ", receipt.contractAddress);
writeSolJSON(name, receipt.contractAddress, abi);
// Lookup next contract to deploy
if (Object.keys(output.contracts).length > ++index)
pushSignedContract(index);
}
}
var contractsJSON = [];
function pushSignedContract (index) {
console.log("Self signing contract ", Object.keys(output.contracts)[index]);
var name = Object.keys(output.contracts)[index];
var code = "0x" + output.contracts[name].bytecode;
var abi = JSON.parse(output.contracts[name].interface);
var c = web3.eth.contract(abi);
console.log("Preparing ", name);
const privateKey = new Buffer(Config.get('private_key'), 'hex');
const fromAddress = wallet.fromPrivateKey(privateKey).getAddressString();
const contractData = c.new.getData({
data: code
});
const nonce = web3.eth.getTransactionCount(fromAddress);
const nonceHex = web3.toHex(nonce);
const rawTx = {
nonce: nonceHex,
gasPrice: web3.toHex(web3.eth.gasPrice),
gasLimit: web3.toHex(gasQuote[name]),
data: contractData,
from: fromAddress
};
const tx = new Tx(rawTx);
tx.sign(privateKey);
const serializedTx = tx.serialize();
web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), (err, hash) => {
if (err) { console.log(err); return; }
// Log the tx, you can explore status manually with eth.getTransaction()
console.log("Contract transaction pushed: TransactionHash (", hash, ") waiting to be mined...");
// Wait for the transaction to be mined
getTransactionReceipt(name, hash, c.abi, index);
});
return;
}
function pushContract (name, c) {
var x = c.new({
from: fromAddress,
data: code,
gas: gasQuote[contract]
}, function (e, contract) {
if (!e) {
if (!contract.address) {
console.log("Contract transaction pushed: TransactionHash (", contract.transactionHash, ") waiting to be mined...");
}
else {
console.log("Contract mined! Address: ", contract.address);
writeSolJSON(name, contract.address, contract.abi);
}
}
else {
throw new Error(e);
}
});
}
function writeSolJSON(name, address, abi) {
source = name.split(":")[0];
name = name.split(":")[1];
var conf = { source: source, name: name, address: address, abi: abi };
var contracts = fs.readFileSync('app/contracts.json');
contracts = JSON.parse(contracts.toString());
contracts.push(conf);
// write object to wasabi.js
console.log("Building app/wasabi.js");
var wasabiJS = fs.readFileSync(__dirname + '/static/wasabi.js', 'utf8');
wasabiJS = wasabiJS.toString().replace("// ####", "var config = " + JSON.stringify(contracts) + ";");
fs.writeFileSync('app/wasabi.js', wasabiJS);
console.log("Built app/wasabi.js");
// write object to portable JSON
console.log("Writing app/contracts.json");
fs.writeFileSync('app/contracts.json', JSON.stringify(contracts, null, '\t'));
console.log("Wrote app/contracts.json");
}