Deploy & Interact
Hardhat/Ethers
Learn about how to develop on Sophon using Hardhat
Was this page helpful?
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
Learn about how to develop on Sophon using Hardhat
import type { HardhatUserConfig } from "hardhat/config";
import "@matterlabs/hardhat-zksync";
import * as dotenv from "dotenv";
// Load environment variables from .env file
dotenv.config();
const config: HardhatUserConfig = {
defaultNetwork: "sophonTestnet",
networks: {
hardhat: {
zksync: true,
},
sophonMainnet: {
url: "https://rpc.sophon.xyz",
ethNetwork: "mainnet",
verifyURL: "https://verification-explorer.sophon.xyz/contract_verification",
browserVerifyURL: "https://explorer.sophon.xyz/",
enableVerifyURL: true,
zksync: true,
accounts: [process.env.WALLET_PRIVATE_KEY as string],
},
sophonTestnet: {
url: "https://rpc.testnet.sophon.xyz",
ethNetwork: "sepolia",
verifyURL: "https://api-explorer-verify.testnet.sophon.xyz/contract_verification",
browserVerifyURL: "https://explorer.testnet.sophon.xyz/",
enableVerifyURL: true,
zksync: true,
accounts: [process.env.WALLET_PRIVATE_KEY as string],
},
},
zksolc: {
version: "latest",
settings: {},
},
solidity: {
version: "0.8.27",
},
etherscan: {
enabled: true,
apiKey: {
sophonTestnet: process.env.ETHERSCAN_SOPHON_API_KEY as string,
sophonMainnet: process.env.ETHERSCAN_SOPHON_API_KEY as string,
},
customChains: [
{
network: "sophonTestnet",
chainId: 531050104,
urls: {
apiURL: "https://api-testnet.sophscan.xyz/api",
browserURL: "https://testnet.sophscan.xyz",
},
},
{
network: "sophonMainnet",
chainId: 50104,
urls: {
apiURL: "https://api.sophscan.xyz/api",
browserURL: "https://sophscan.xyz",
},
},
],
},
};
export default config;
WALLET_PRIVATE_KEY=your_private_key_here
ETHERSCAN_SOPHON_API_KEY=your_sophscan_api_key_here
import { utils } from "zksync-ethers";
const deployer = new Deployer(hre, wallet);
const artifact = await deployer.loadArtifact("Your_Contract");
const contract = await deployer.deploy(artifact, constructorArguments || []);
import { Provider, Wallet, utils } from "zksync-ethers";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
import { HardhatRuntimeEnvironment } from "hardhat/types";
export default async function (hre: HardhatRuntimeEnvironment) {
const provider = new Provider(hre.network.config.url);
const wallet = new Wallet(process.env.WALLET_PRIVATE_KEY!, provider);
const deployer = new Deployer(hre, wallet);
const artifact = await deployer.loadArtifact("your_contract");
const params = utils.getPaymasterParams(
"0x98546B226dbbA8230cf620635a1e4ab01F6A99B2", // Paymaster address
{
type: "General",
innerInput: new Uint8Array(),
}
);
const contract = await deployer.deploy(
artifact,
[], // Constructor arguments
undefined, // Deployment type (use undefined for regular contract deployment)
{
customData: {
paymasterParams: params,
gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
},
}
);
}
import { utils } from "zksync-ethers";
const deployer = new Deployer(hre, wallet);
const artifact = await deployer.loadArtifact("Your_Contract");
await hre.zkUpgrades.deployProxy(deployer.zkWallet, artifact, [initializerArgs], {
initializer: "initialize",
paymasterProxyParams: params,
paymasterImplParams: params,
});
import { utils } from "zksync-ethers";
const paymasterParams = utils.getPaymasterParams("0x98546B226dbbA8230cf620635a1e4ab01F6A99B2", {
type: "General",
innerInput: new Uint8Array(),
});
const tx = await contract.yourFunction(params, {
customData: {
gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
paymasterParams: paymasterParams,
},
});
npx hardhat verify --network sophonTestnet DEPLOYED_CONTRACT_ADDRESS constructor_arguments
const restrictionContractAddress = (hre.network.config as unknown as CustomNetworkConfig)
?.restrictionContract;
if (restrictionContractAddress && usePaymaster) {
const contractAddress = await contract.getAddress();
logger.info(
`Checking if ${contractName} (${contractAddress}) is whitelisted on restriction contract...`
);
// Create interface for the restriction contract
const restrictionContractABI = [
{
inputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
name: "contractWhitelist",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
];
const provider = hre.ethers.provider;
const restrictionContract = new hre.ethers.Contract(
restrictionContractAddress,
restrictionContractABI,
provider
);
let isWhitelisted = false;
let attempts = 0;
const maxAttempts = 5;
while (!isWhitelisted && attempts < maxAttempts) {
try {
isWhitelisted = await restrictionContract.contractWhitelist(contractAddress);
if (isWhitelisted) {
logger.info(`${contractName} is now whitelisted on restriction contract!`);
} else {
attempts++;
if (attempts < maxAttempts) {
logger.info(
`${contractName} is not yet whitelisted. Waiting ${
waitTime / 1000
} seconds before retry (attempt ${attempts}/${maxAttempts})...`
);
await new Promise((resolve) => setTimeout(resolve, waitTime));
} else {
logger.warn(
`${contractName} is still not whitelisted after ${maxAttempts} attempts. Proceeding anyway, but paymaster transactions might fail.`
);
}
}
} catch (error) {
logger.error(`Error checking whitelist status: ${error}`);
attempts++;
if (attempts < maxAttempts) {
await new Promise((resolve) => setTimeout(resolve, waitTime));
}
}
}
}
Was this page helpful?