Commit 2ff1117b authored by luxq's avatar luxq

update scripts

parent dbe81f33
node_modules
.env
# Hardhat files
/cache
/artifacts
# TypeChain files
/typechain
/typechain-types
# solidity-coverage files
/coverage
/coverage.json
# Hardhat Ignition default folder for deployments against a local node
ignition/deployments/chain-31337
.idea
# bridgecontract
## environment
- node v20.18.1
```shell
npm i
```
## config
- `.env` set correct values for `DEPLOY_PRIVATE_KEY`, `BRIDGE_VALIDATORS`, `TREASURY`, in test environemnt, also set `TREASURY_PRIVATE_KEY`.
- `hardhat.config.js` set correct chain config.
## deploy contract to chain A and B
```shell
npx hardhat run ./scripts/deploy.js --network <network-A>
npx hardhat run ./scripts/deploy.js --network <network-B>
```
All deployment will write to `deploy.json` file in the current directory.
## set necessary parameters
```shell
npx hardhat run ./scripts/setconfig.js --network <network-A>
npx hardhat run ./scripts/setconfig.js --network <network-B>
```
## do test
This diff is collapsed.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract TestToken is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
_mint(msg.sender, 100000000 * 10 ** decimals());
}
function mint(address to, uint256 amount) public {
_mint(to, amount);
}
function burn(uint256 amount) public {
_burn(msg.sender, amount);
}
}
\ No newline at end of file
require("@nomicfoundation/hardhat-toolbox");
require("@nomicfoundation/hardhat-ethers");
require("dotenv").config()
// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "List of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners()
for (const account of accounts) {
// dump account address and balance.
const balance = await hre.ethers.provider.getBalance(account.address);
console.log(`Address: ${account.address}, Balance: ${hre.ethers.formatEther(balance)} ETH`);
}
})
const privateKeys = [
process.env.DEPLOY_PRIVATE_KEY,
process.env.TREASURY_PRIVATE_KEY
];
module.exports = {
solidity: {
evmVersion: "istanbul",
compilers: [
{
version: "0.8.20",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
{
version: "0.8.10",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
],
},
etherscan: {
apiKey: {
'achain': 'empty',
'mova': 'empty',
'bsc':'AVZIFYCHUFHPG9FDKNMHEWJ1VAW1H5U66T'
},
customChains: [
{
network: "achain",
chainId: 100,
urls: {
apiURL: "https://scan.cmp20.bitheart.org/api",
browserURL: "https://scan.cmp20.bitheart.org"
}
},
{
network: "mova",
chainId: 10323,
urls: {
apiURL: "https://scan.mars.movachain.com/api",
browserURL: "https://scan.mars.movachain.com"
}
}
]
},
networks: {
hardhat: {
accounts: [
{ privateKey: privateKeys[0], balance: "10000000000000000000000" },
{ privateKey: privateKeys[1], balance: "10000000000000000000000" }
]
},
achain: {
url: "http://15.206.56.79:28545",
accounts: privateKeys
},
mova: {
url: "https://mars.rpc.movachain.com",
accounts: privateKeys
},
bit: {
url: "https://rpc.mova.bitheart.org",
accounts: privateKeys
},
hpb: {
url: "https://hpbnode.com",
accounts: privateKeys
}
}
};
console.log('Happy developing ✨')
This diff is collapsed.
{
"name": "testcontract",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"private": true,
"devDependencies": {
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"hardhat": "^2.24.0"
},
"dependencies": {
"@openzeppelin/contracts": "^5.3.0",
"dotenv": "^16.5.0",
"fp-ts": "^2.16.11"
}
}
const fs = require("fs");
const path = require("path");
const hre = require("hardhat");
const DEPLOY_FILE = path.join(__dirname, "deploy.json");
async function deploy() {
const token = await hre.ethers.getContractFactory(
"TestToken"
);
const tokenA = await token.deploy("Test Token Ali", "TTA");
await tokenA.waitForDeployment();
const tokenAAddr = await tokenA.getAddress();
const tokenB = await token.deploy("Test Token Bob", "TTB");
await tokenB.waitForDeployment();
const tokenBAddr = await tokenB.getAddress();
// Deploy the contract
const factory = await hre.ethers.getContractFactory(
"Bridge"
);
[owner] = await hre.ethers.getSigners();
const contract = await factory.deploy(owner.address);
await contract.waitForDeployment();
const bridgeAddr = await contract.getAddress();
const chainId = await hre.ethers.provider.getNetwork().then(network => network.chainId);
await saveDeployment(chainId, tokenAAddr, tokenBAddr, bridgeAddr);
}
function saveDeployment(chainId, tokenA, tokenB, bridge) {
let deployData = {};
if (fs.existsSync(DEPLOY_FILE)) {
deployData = JSON.parse(fs.readFileSync(DEPLOY_FILE, "utf8"));
}
deployData[chainId] = {
tokenA,
tokenB,
bridge,
};
fs.writeFileSync(DEPLOY_FILE, JSON.stringify(deployData, null, 2));
console.log("Deployment at chain ", chainId, " saved to deploy.json");
}
// Define the script
async function main() {
await deploy();
}
// Run the script
main().catch((error) => {
console.error("Error:", error);
});
\ No newline at end of file
{
"269": {
"tokenA": "0xF5c10392D841d55C41EBf696A4E437b2DC91f5D3",
"tokenB": "0x6A24C27cF83dAFf6227fa03852465aA65cF22527",
"bridge": "0x9a06d0CfAFc19a4bfe0ecd5f8bC20A26a88fA227"
},
"10323": {
"tokenA": "0xF5c10392D841d55C41EBf696A4E437b2DC91f5D3",
"tokenB": "0x6A24C27cF83dAFf6227fa03852465aA65cF22527",
"bridge": "0x9a06d0CfAFc19a4bfe0ecd5f8bC20A26a88fA227"
}
}
\ No newline at end of file
const fs = require("fs");
const path = require("path");
const hre = require("hardhat");
let INITIAL_VALIDATORS = process.env.BRIDGE_VALIDATORS
let TREASURY = process.env.TREASURY
const DEPLOY_FILE = path.join(__dirname, "deploy.json");
async function addValidators(contract, validators) {
let validatorList = validators.split(',')
for (let i = 0; i < validatorList.length; i++) {
var tx = await contract.addValidator(validatorList[i])
await tx.wait();
console.log("Added validator:", validatorList[i]);
}
}
async function setTreasury(contract, treasury) {
var tx = await contract.setTreasury(treasury);
await tx.wait();
console.log("Set treasury to:", treasury);
}
async function mintToken(tokenA, tokenB, user) {
var amount = hre.ethers.parseEther("1000000")
var tx = await tokenA.mint(user, amount);
await tx.wait();
console.log("Minted TTA to user:", user, " amount:", hre.ethers.formatEther(amount));
tx = await tokenB.mint(user, amount);
await tx.wait();
console.log("Minted TTB to user:", user, " amount:", hre.ethers.formatEther(amount));
}
async function treasuryApprove(tokenA, tokenB, bridgeAddr, treasury) {
var tx = await tokenA.connect(treasury).approve(bridgeAddr, hre.ethers.MaxUint256);
await tx.wait();
console.log("Approved TTA for bridge:", bridgeAddr);
tx = await tokenB.connect(treasury).approve(bridgeAddr, hre.ethers.MaxUint256);
await tx.wait();
console.log("Approved TTB for bridge:", bridgeAddr);
}
async function setConfig(tokenA, tokenB, bridge) {
if (!INITIAL_VALIDATORS || !TREASURY) {
throw new Error("Environment variables BRIDGE_VALIDATORS or TREASURY are not set.");
}
[owner, treasury] = await hre.ethers.getSigners();
await addValidators(bridge, INITIAL_VALIDATORS);
await setTreasury(bridge, TREASURY);
// if treasury is exist, do approve .
var bridgeAddr = await bridge.getAddress();
if (treasury.address) {
// test environment, mint token and approve.
await mintToken(tokenA, tokenB, TREASURY);
await treasuryApprove(tokenA, tokenB, bridgeAddr, treasury);
}
}
async function getDeploy(chainId) {
if (!fs.existsSync(DEPLOY_FILE)) {
throw new Error("deploy.json file not found");
}
const deployData = JSON.parse(fs.readFileSync(DEPLOY_FILE, "utf8"));
if (!deployData[chainId]) {
throw new Error(`No deployment data found for chainId ${chainId}`);
}
const addrs = deployData[chainId];
const tokenA = await hre.ethers.getContractAt("TestToken", addrs.tokenA);
const tokenB = await hre.ethers.getContractAt("TestToken", addrs.tokenB);
const bridge = await hre.ethers.getContractAt("Bridge", addrs.bridge);
return {tokenA, tokenB, bridge}
}
async function setOutConfig(curTokenMap, targetTokenMap, targetChainId, bridge) {
const outConfigA = {
receiveToken: await targetTokenMap.tokenA.getAddress(),
fee: hre.ethers.parseEther("0.05"),
limit: hre.ethers.parseEther("1000"),
isBurn: false,
enabled: true,
};
const outConfigB = {
receiveToken: await targetTokenMap.tokenB.getAddress(),
fee: hre.ethers.parseEther("0.04"),
limit: hre.ethers.parseEther("1000"),
isBurn: false,
enabled: true,
}
var tx = await bridge.changeOutConfig(
await curTokenMap.tokenA.getAddress(),
targetChainId, // Target chain ID
outConfigA
);
await tx.wait();
console.log("Set out config for tokenA to chain", targetChainId, "tx", tx.hash);
tx = await bridge.changeOutConfig(
await curTokenMap.tokenB.getAddress(),
targetChainId, // Target chain ID
outConfigB
);
await tx.wait();
console.log("Set out config for tokenB to chain", targetChainId, "tx", tx.hash);
}
// Define the script
async function main() {
const chainId = await hre.ethers.provider.getNetwork().then(network => network.chainId);
const targetChainId = chainId === 269n ? 10323 : 269;
console.log("Current chain ID:", chainId, "Target chain ID:", targetChainId);
const curChainDeploy = await getDeploy(chainId);
const targetChainDeploy = await getDeploy(targetChainId);
await setConfig(curChainDeploy.tokenA, curChainDeploy.tokenB, curChainDeploy.bridge);
await setOutConfig(curChainDeploy, targetChainDeploy, targetChainId, curChainDeploy.bridge);
console.log("Configuration set successfully for chain", chainId);
}
// Run the script
main().catch((error) => {
console.error("Error:", error);
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment