Deploy Smart Contract to Ronin Network with Hardhat
Contents
Initiate project
-
mkdir play-hardhat && cd play-hardhat mkdir contracts mkdir scripts npm init -y yarn add -D hardhat @openzeppelin/hardhat-upgrades @nomicfoundation/hardhat-verify @nomicfoundation/hardhat-ethers yarn hardhat init
Configuration
-
// hardhat.config.ts import type { HardhatUserConfig } from 'hardhat/config'; import { MNEMONIC, PRIVATE_KEY } from './secrets.json'; import '@openzeppelin/hardhat-upgrades'; import '@nomicfoundation/hardhat-verify'; import '@nomicfoundation/hardhat-ethers'; const config: HardhatUserConfig = { solidity: { version: '0.8.27', settings: { optimizer: { enabled: true, runs: 200, }, }, }, networks: { ronin: { chainId: 2020, url: 'https://api.roninchain.com/rpc', gasPrice: 20_000_000_000, accounts: [PRIVATE_KEY], }, saigon: { chainId: 2021, url: 'https://saigon-testnet.roninchain.com/rpc', gasPrice: 20_000_000_000, accounts: { MNEMONIC, }, }, }, sourcify: { enabled: true, apiUrl: 'https://sourcify.roninchain.com/server/', }, // etherscan enabled default value true, have to override it to false in order to use sourcify etherscan: { enabled: false, }, }; export default config;
Deploy
-
// scripts/deploy.ts // yarn hardhat run --network saigon scripts/deploy.ts import { ethers } from 'hardhat'; async function main() { const name = 'Box'; const Contract = await ethers.getContractFactory(name); console.log(`Deploying ${name}...`); const proxy = await upgrades.deployProxy(Contract, [66], { initializer: 'store', kind: 'uups', }); await proxy.waitForDeployment(); const proxyAddress = await proxy.getAddress(); const implAddress = await upgrades.erc1967.getImplementationAddress(proxyAddress); console.log(`${name} deployed to:`, implAddress); console.log(`Proxy deployed to:`, proxyAddress); // const box = await Box.deploy(); // await box.waitForDeployment(); // const proxy = await ERC1967Proxy.deploy(await box.getAddress(), Box.interface.encodeFunctionData('store', [66])); // await proxy.waitForDeployment(); // console.log('Box deployed to:', await box.getAddress()); // console.log('Proxy deployed to:', await proxy.getAddress()); } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
Import
- This process will create
.openzeppelinfolder in the root directory -
// scripts/import.ts // yarn hardhat run --network saigon scripts/import.ts import { ethers, upgrades } from 'hardhat'; async function main() { const Box = await ethers.getContractFactory('Box'); console.log('Importing Box...'); await upgrades.forceImport('<PROXY_ADDRESS>', Box, { kind: 'uups', }); console.log('Imported!'); } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
Upgrade
-
// scripts/upgrade.ts // yarn hardhat run --network saigon scripts/upgrade.ts import { ethers, upgrades } from 'hardhat'; async function main() { const BoxV2 = await ethers.getContractFactory('BoxV2'); console.log('Upgrading to BoxV2...'); await upgrades.upgradeProxy('<PROXY_ADDRESS>', BoxV2, { kind: 'uups', redeployImplementation: 'always', }); console.log('Upgraded!'); } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
Verify
- For Implementation Contract
yarn hardhat verify --network saigon <IMPL_ADDRESS> - For Proxy Contract
Use the following solc-input.json