Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create deployL2-it.js to deploy contract to l2 network for integration test and wait until it finalized #103

Merged
merged 13 commits into from
Aug 5, 2024
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
"prettier:fix": "prettier --write contracts/**/*.sol test/**/*.js scripts/**/*.js",
"deploy": "npx hardhat run scripts/deploy.js --network sepolia",
"deployL2Dev": "npx hardhat run scripts/deployL2.js --network qkc_devnet",
"deployL2Test": "npx hardhat run scripts/deployL2.js --network qkc_testnet"
"deployL2Test": "npx hardhat run scripts/deployL2.js --network qkc_testnet",
"deployL2ITDev": "npx hardhat run scripts/deployL2-it.js --network qkc_devnet",
"deployL2ITTest": "npx hardhat run scripts/deployL2-it.js --network qkc_testnet"
},
"workspaces": {
"packages": [
Expand Down
151 changes: 151 additions & 0 deletions scripts/deployL2-it.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,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
32, // shardSizeBits ~ 4G
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
24576000000000000000n, // prepaidAmount - 50% * 2^32 / 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;
});
Loading