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

add some scripts #76

Merged
merged 5 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions etc/EXAMPLE.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"network": {
"name": "testnet",
"url": "https://alpha4.starknet.io",
"name": "devnet",
"url": "http://127.0.0.1",
"accounts": {
"deployer": {
"address": "",
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
"starknet": "^5.19.5"
},
"scripts": {
"declare": "node scripts/deploy_zklink.js declareZklink",
"deploy": "node scripts/deploy_zklink.js deployZklink"
"build": "node scripts/build.js build",
"declareZklink": "node scripts/deploy_zklink.js declareZklink",
"deployZklink": "node scripts/deploy_zklink.js deployZklink",
"deployFaucetToken": "node scripts/deploy_faucet.js deployFaucetToken",
"addToken": "node scripts/interact.js addToken"
}
}
102 changes: 102 additions & 0 deletions scripts/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { program } from "commander";
import fs from "fs";
import { executeCommand } from "./utils.js";
import { command, contractPath } from "./constants.js";

program
.command("build")
.description("replace zklink contract constants and compile")
.action(async () => {
await build();
});

program.parse();

function parseBlockPeriod(blockPeriod) {
const regex = /^(\d+)\s+seconds?$/i;
const match = blockPeriod.match(regex);

if (match) {
return parseInt(match[1], 10);
} else {
throw new Error(`Invalid block period: ${blockPeriod}`);
}
}

function writeZklinkConstants(configs) {
fs.readFile(contractPath.ZKLINK_CONSTANTS_PATH, 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}

// BLOCK_PERIOD
let result = data.replace(/(const BLOCK_PERIOD: u64 = )(\d+)(;)/, `$1${configs.blockPeriod}$3`);
// PRIORITY_EXPIRATION
result = result.replace(/(const PRIORITY_EXPIRATION: u64 = )(\d+)(;)/, `$1${configs.priorityExpiration}$3`);
// UPGRADE_NOTICE_PERIOD
result = result.replace(/(const UPGRADE_NOTICE_PERIOD: u64 = )(\d+)(;)/, `$1${configs.upgradeNoticePeriod}$3`);
// CHAIN_ID
result = result.replace(/(const CHAIN_ID: u8 = )(\d+)(;)/, `$1${configs.chainId}$3`);
// MIN_CHAIN_ID
result = result.replace(/(const MIN_CHAIN_ID: u8 = )(\d+)(;)/, `$1${configs.minChainId}$3`);
// MAX_CHAIN_ID
result = result.replace(/(const MAX_CHAIN_ID: u8 = )(\d+)(;)/, `$1${configs.maxChainId}$3`);
// ALL_CHAAINS
result = result.replace(/(const ALL_CHAINS: u256 = )(\d+)(;)/, `$1${configs.allChains}$3`);
// CHAIN_INDEX
result = result.replace(/(const CHAIN_INDEX: u256 = )(\d+)(;)/, `$1${configs.chainIndex}$3`);
// ENABLE_COMMIT_COMPRESSED_BLOCK
result = result.replace(/(const ENABLE_COMMIT_COMPRESSED_BLOCK: felt252 = )(\d+)(;)/, `$1${configs.enableCommitCompressedBlock}$3`);

fs.writeFile(contractPath.ZKLINK_CONSTANTS_PATH, result, 'utf8', (err) => {
if (err) {
console.error(err);
return;
}
});
});
}

async function build() {
// read config json file
const netName = process.env.NET === undefined ? "EXAMPLE" : process.env.NET;
let netConfig = await fs.promises.readFile(`./etc/${netName}.json`, "utf-8");
netConfig = JSON.parse(netConfig);

const blockPeriod = parseBlockPeriod(netConfig.macro.BLOCK_PERIOD);
const upgradeNoticePeriod = netConfig.macro.UPGRADE_NOTICE_PERIOD;
const priorityExpiration = netConfig.macro.PRIORITY_EXPIRATION;
const chainId = netConfig.macro.CHAIN_ID;
const enableCommitCompressedBlock = netConfig.macro.ENABLE_COMMIT_COMPRESSED_BLOCK ? 1 : 0;
const minChainId = netConfig.macro.MIN_CHAIN_ID;
const maxChainId = netConfig.macro.MAX_CHAIN_ID;
const allChains = netConfig.macro.ALL_CHAINS;
const chainIndex = (1 << chainId) - 1;

const configs = {
blockPeriod,
upgradeNoticePeriod,
priorityExpiration,
chainId,
enableCommitCompressedBlock,
minChainId,
maxChainId,
allChains,
chainIndex
}

console.log("🔥 Reading and replace zklink constants...");
console.log("configs:", configs);
writeZklinkConstants(configs);
console.log("✅ Replace zklink constants success");

console.log("Building zklink contract...");
await executeCommand(command.COMMAND_BUILD)
.then((stdout) => {
console.log(stdout)
}).catch((error) => {
console.log(error)
});
console.log("✅ Build zklink contract success");
}
15 changes: 14 additions & 1 deletion scripts/deploy_log_name.js → scripts/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,27 @@ const VERIFIER_SIERRA_PATH = "./target/release/zklink_Verifier.sierra.json";
const VERIFIER_CASM_PATH = "./target/release/zklink_Verifier.casm.json";
const ZKLINK_SIERRA_PATH = "./target/release/zklink_Zklink.sierra.json";
const ZKLINK_CASM_PATH = "./target/release/zklink_Zklink.casm.json";
const FAUCET_TOKEN_SIERRA_PATH = "./target/release/zklink_FaucetToken.sierra.json";
const FAUCET_TOKEN_CASM_PATH = "./target/release/zklink_FaucetToken.casm.json";
const ZKLINK_CONSTANTS_PATH = "./src/utils/constants.cairo";

// command
const COMMAND_BUILD = "scarb --release build";

export var command = {
COMMAND_BUILD
}

export var contractPath = {
GATEKEEPER_SIERRA_PATH,
GATEKEEPER_CASM_PATH,
VERIFIER_SIERRA_PATH,
VERIFIER_CASM_PATH,
ZKLINK_SIERRA_PATH,
ZKLINK_CASM_PATH
ZKLINK_CASM_PATH,
ZKLINK_CONSTANTS_PATH,
FAUCET_TOKEN_SIERRA_PATH,
FAUCET_TOKEN_CASM_PATH
}

export var logName = {
Expand Down
65 changes: 65 additions & 0 deletions scripts/deploy_faucet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { program } from "commander";
import fs from "fs";
import { contractPath } from "./constants.js";
import { connectStarknet, buildFaucetTokenConstructorArgs, getClassHashFromError } from "./utils.js";
import { json } from "starknet";

program
.command("deployFaucetToken")
.description("deploy faucet token")
.requiredOption('--name <name>', 'The token name')
.requiredOption('--symbol <symbol>', 'The token symbol')
.option('--decimals <decimals>', 'The token decimals', 18)
.option('--from-transfer-fee-ratio', 'The fee ratio taken of from address when transfer', 0)
.option('--to-transfer-fee-ratio', 'The fee ratio taken of to address when transfer', 0)
.action(async function (options) {
await deploy_faucet_token(options);
});

program.parse();

async function deploy_faucet_token(options) {
const name = options.name;
const symbol = options.symbol;
const decimals = options.decimals;
const fromTransferFeeRatio = options.fromTransferFeeRatio;
const toTransferFeeRatio = options.toTransferFeeRatio;

console.log("name:", name);
console.log("symbol:", symbol);
console.log("decimals:", decimals);
console.log("fromTransferFeeRatio:", fromTransferFeeRatio);
console.log("toTransferFeeRatio:", toTransferFeeRatio);

let { provider, deployer, governor, netConfig} = await connectStarknet();

// declare faucet token
const ContractSierra = json.parse(fs.readFileSync(contractPath.FAUCET_TOKEN_SIERRA_PATH).toString("ascii"));
const contractCasm = json.parse(fs.readFileSync(contractPath.FAUCET_TOKEN_CASM_PATH).toString("ascii"));
let classHash;
try {
const declareResponse = await deployer.declare({ contract: ContractSierra, casm: contractCasm });
await provider.waitForTransaction(declareResponse.transaction_hash);
classHash = declareResponse.class_hash;
console.log('✅ Faucet Token Contract declared with classHash = ', classHash);
} catch (error) {
if (error.errorCode !== 'StarknetErrorCode.CLASS_ALREADY_DECLARED') {
throw error;
}

classHash = getClassHashFromError(error);
if (classHash === undefined) {
console.log('❌ Cannot declare gatekeeper contract class hash:', error);
return;
} else {
console.log('✅ Faucet Token Contract already declared with classHash =', classHash);
}
}

// deploy faucet token
const constructorArgs = buildFaucetTokenConstructorArgs(ContractSierra.abi, name, symbol, decimals, fromTransferFeeRatio, toTransferFeeRatio);
const deployResponse = await deployer.deployContract({ classHash: classHash, constructorCalldata: constructorArgs });
await provider.waitForTransaction(deployResponse.transaction_hash);

console.log('✅ Faucet Token Contract deployed at =', deployResponse.contract_address);
}
6 changes: 3 additions & 3 deletions scripts/deploy_zklink.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Contract, json, cairo } from "starknet";
import fs from "fs";
import { program } from "commander";
import { logName, contractPath } from "./deploy_log_name.js"
import { logName, contractPath } from "./constants.js"
import { connectStarknet, getDeployLog, buildVerifierConstructorArgs, buildZklinkConstructorArgs, buildGateKeeperConstructorArgs, getClassHashFromError } from "./utils.js";


program
.command("declareZklink")
.description("Declare zklink and verifier contract")
.action(async () => {
declare_zklink();
await declare_zklink();
});

program
Expand All @@ -26,7 +26,7 @@ program
.option('--skip-verify', 'Skip verification', false)
.option('--force', 'Force redeploy', false)
.action(async (options) => {
deploy_zklink(options);
await deploy_zklink(options);
});

async function declare_zklink() {
Expand Down
47 changes: 47 additions & 0 deletions scripts/interact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { program } from "commander";
import fs from "fs";
import { Contract, json } from "starknet";
import { contractPath, logName } from "./constants.js";
import { connectStarknet, getDeployLog } from "./utils.js";

program
.command("addToken")
.description("Adds a new token with a given address for testnet")
.option('--zklink <zklink>', 'The zkLink contract address (default get from deploy log)', undefined)
.requiredOption('--token-id <tokenId>', 'The token id')
.requiredOption('--token-address <tokenAddress>', 'The token address')
.option('--token-decimals <tokenDecimals>', 'The token decimals', 18)
.option('--standard <standard>', 'The token is a standard ERC20 token', true)
.action(async (options) => {
await add_token(options);
});

program.parse();

async function add_token(options) {
let { provider, deployer, governor, netConfig} = await connectStarknet();
const { deployLogPath, deployLog } = getDeployLog(logName.DEPLOY_ZKLINK_LOG_PREFIX);

const zklinkAddress = options.zklink === undefined ? deployLog[logName.DEPLOY_LOG_ZKLINK] : options.zklink;
const tokenId = options.tokenId;
const tokenAddress = options.tokenAddress;
const tokenDecimals = options.tokenDecimals;
const standard = options.standard;

console.log("zklink:", zklinkAddress);
console.log("governor:", governor.address);
console.log("tokenId:", tokenId);
console.log("tokenAddress:", tokenAddress);
console.log("tokenDecimals:", tokenDecimals);
console.log("standard:", standard);
console.log("Adding new ERC20 token to zklink");

const zklinkContractSierra = json.parse(fs.readFileSync(contractPath.ZKLINK_SIERRA_PATH).toString("ascii"));
const zklink = new Contract(zklinkContractSierra.abi, zklinkAddress, provider);

zklink.connect(governor);
const call = zklink.populate("addToken", [tokenId, tokenAddress, tokenDecimals, standard]);
const tx = await zklink.addToken(call.calldata);
await provider.waitForTransaction(tx.transaction_hash);
console.log('✅ zklink add new ERC20 token success, tx:', tx.transaction_hash);
}
25 changes: 24 additions & 1 deletion scripts/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import fs from "fs";
import { Provider, CallData, Account, constants } from "starknet";
import { exec } from "child_process";
import { stdout } from "process";


function buildProvider(networkConfig) {
Expand All @@ -21,7 +23,7 @@ function buildProvider(networkConfig) {

export async function connectStarknet() {
// read config json file
const netName = process.env.NET === undefined ? "devnet" : process.env.NET;
const netName = process.env.NET === undefined ? "EXAMPLE" : process.env.NET;
let netConfig = await fs.promises.readFile(`./etc/${netName}.json`, "utf-8");
netConfig = JSON.parse(netConfig);

Expand All @@ -37,6 +39,12 @@ export async function connectStarknet() {
return { provider, deployer, governor, netConfig};
}

export function buildFaucetTokenConstructorArgs(abi, name, symbol, decimals, fromTransferFeeRatio, toTransferFeeRatio) {
const contractCallData = new CallData(abi);
const constructorArgs = contractCallData.compile("constructor", [name, symbol, decimals, fromTransferFeeRatio, toTransferFeeRatio])
return constructorArgs;
}

export function buildGateKeeperConstructorArgs(abi, master, mainContract) {
const contractCallData = new CallData(abi);
const constructorArgs = contractCallData.compile("constructor", [master, mainContract])
Expand Down Expand Up @@ -90,4 +98,19 @@ export function getClassHashFromError(error) {
} else {
return undefined;
}
}

export function executeCommand(command) {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(`Error executing command: ${error.message}`);
console.error(`Command error: ${stderr}`);
console.error(`Command output: ${stdout}`);
resolve('');
} else {
resolve(stdout);
}
});
});
}
2 changes: 0 additions & 2 deletions src/contracts/zklink.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,6 @@ mod Zklink {

#[external(v0)]
impl Zklink of super::IZklink<ContractState> {
// TODO: upgrade interface

// Deposit ERC20 token to Layer 2 - transfer ERC20 tokens from user into contract, validate it, register deposit
// it MUST be ok to call other external functions within from this function
// when the token(eg. erc777) is not a pure erc20 token
Expand Down
1 change: 1 addition & 0 deletions src/dev.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod faucet_token;
Loading