-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdeployL2-it.js
151 lines (132 loc) · 5.26 KB
/
deployL2-it.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
const fs = require('fs');
const hre = require("hardhat");
const dotenv = require("dotenv")
dotenv.config()
let ownerAddress = null;
let treasuryAddress = null;
const adminContractAddr = "";
const storageContractProxy = "";
const gasPrice = null;
const config = [
17, // maxKvSizeBits, 131072
30, // shardSizeBits ~ 1G
2, // randomChecks
7200, // cutoff = 2/3 * target internal (3 hours), 3 * 3600 * 2/3
32, // diffAdjDivisor
100, // treasuryShare, means 1%
];
const storageCost = 1500000000000000; // storageCost - 1,500,000Gwei forever per blob - https://ethresear.ch/t/ethstorage-scaling-ethereum-storage-via-l2-and-da/14223/6#incentivization-for-storing-m-physical-replicas-1
const dcfFactor = 340282366367469178095360967382638002176n; // dcfFactor, it mean 0.95 for yearly discount
async function verifyContract(contract, args) {
// if (!process.env.ETHERSCAN_API_KEY) {
// return;
// }
// await hre.run("verify:verify", {
// address: contract,
// constructorArguments: args,
// });
}
async function deployContract() {
const startTime = Math.floor(new Date().getTime() / 1000);
const [deployer] = await hre.ethers.getSigners();
ownerAddress = deployer.address;
treasuryAddress = deployer.address;
const StorageContract = await hre.ethers.getContractFactory("EthStorageContractL2");
// refer to https://docs.google.com/spreadsheets/d/11DHhSang1UZxIFAKYw6_Qxxb-V40Wh1lsYjY2dbIP5k/edit#gid=0
const implContract = await StorageContract.deploy(
config,
startTime, // startTime
storageCost,
dcfFactor,
{ gasPrice: gasPrice }
);
await implContract.deployed();
const impl = implContract.address;
console.log("storage impl address is ", impl);
const data = implContract.interface.encodeFunctionData("initialize", [
1572864, // minimumDiff 0.1 * 180 (3 minutes) * 1024 * 1024 / 12 = 1572864 for 0.1 replicas that can have 1M IOs in one epoch
6144000000000000000n, // prepaidAmount - 50% * 2^30 / 131072 * 1500000Gwei, it also means 3145 ETH for half of the shard
1048576, // nonceLimit 1024 * 1024 = 1M samples and finish sampling in 1.3s with IO rate 6144 MB/s: 4k * 2(random checks) / 6144 = 1.3s
treasuryAddress, // treasury
ownerAddress,
]);
console.log(impl, ownerAddress, data);
const EthStorageUpgradeableProxy = await hre.ethers.getContractFactory("EthStorageUpgradeableProxy");
const ethStorageProxy = await EthStorageUpgradeableProxy.deploy(impl, ownerAddress, data, { gasPrice: gasPrice });
await ethStorageProxy.deployed();
const admin = await ethStorageProxy.admin();
console.log("storage admin address is ", admin);
console.log("storage contract address is ", ethStorageProxy.address);
const receipt = await hre.ethers.provider.getTransactionReceipt(ethStorageProxy.deployTransaction.hash);
console.log(
"deployed in block number",
receipt.blockNumber,
"at",
new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" })
);
// fund 50 qkc into the storage contract to give reward for empty mining
const ethStorage = StorageContract.attach(ethStorageProxy.address);
const tx = await ethStorage.sendValue({ value: hre.ethers.utils.parseEther("50") });
await tx.wait();
console.log("balance of " + ethStorage.address, await hre.ethers.provider.getBalance(ethStorage.address));
// verify contract
await verifyContract(ethStorageProxy.address);
await verifyContract(impl, [config, startTime, storageCost, dcfFactor]);
// wait for contract finalized
var intervalId = setInterval(async function (){
try {
const block = await hre.ethers.provider.getBlock("finalized");
console.log(
"finalized block number is",
block.number,
"at",
new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" })
);
if (receipt.blockNumber < block.number) {
fs.writeFileSync(".caddr", ethStorageProxy.address);
clearInterval(intervalId);
}
} catch (e) {
console.error(`EthStorage: get finalized block failed!`, e.message);g
}
}, 60000);
}
async function updateContract() {
const StorageContract = await hre.ethers.getContractFactory("EthStorageContractL2");
// get start time
const ethStorage = StorageContract.attach(storageContractProxy);
const startTime = await ethStorage.startTime();
// deploy
const implContract = await StorageContract.deploy(
config,
startTime, // startTime
storageCost,
dcfFactor,
{ gasPrice: gasPrice }
);
await implContract.deployed();
const impl = implContract.address;
console.log("storage impl address is ", impl);
// set impl
const EthStorageAdmin = await hre.ethers.getContractAt("IProxyAdmin", adminContractAddr);
const tx = await EthStorageAdmin.upgradeAndCall(storageContractProxy, impl, "0x");
await tx.wait();
console.log("update contract success!");
// verify contract
await verifyContract(impl, [config, startTime, storageCost, dcfFactor]);
}
async function main() {
if (!storageContractProxy) {
// create
await deployContract();
} else {
// update
await updateContract();
}
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});