Hardhat Template
The CrossFi Hardhat Template is a minimal starter project for developers who want to deploy smart contracts on the CrossFi Chain using the Hardhat framework.
It includes a simple "Hello World" contract and a pre-configured deployment script to help you get started quickly on CrossFi Testnet and Mainnet.
Prerequisites
- Node.js (v18 or higher)
- npm or yarn
- A CrossFi account with testnet tokens (get them from the faucet)
- A private key with testnet XFI tokens
Quick Start
Follow these steps to deploy your first contract to the CrossFi Testnet.
1. Clone the Repository
git clone https://github.com/crossfichain/hardhat-template.git
cd hardhat-template
2. Install Dependencies
npm install
3. Configure Environment
Create a .env file in the root directory by copying the example:
cp .env.example .env
Edit the .env file and add your private key:
PRIVATE_KEY=your_private_key_here
Never commit your .env file to version control. It contains sensitive information.
4. Compile Contracts
Compile the smart contracts to ensure everything is set up correctly:
npm run compile
5. Deploy to CrossFi Testnet
Run the deployment script targeting the crossfiTestnet network:
npx hardhat run scripts/deploy.ts --network crossfiTestnet
If successful, you will see the deployed contract address and transaction hash in the console output. You can then verify the transaction on the CrossFi Testnet Explorer.
Network Configuration
The template comes pre-configured with CrossFi network settings in hardhat.config.ts.
Testnet
- Chain ID: 4157
- RPC URL:
https://rpc.testnet.ms - Explorer:
https://test.xfiscan.com
Mainnet
- Chain ID: 4158
- RPC URL:
https://rpc.mainnet.ms - Explorer:
https://xfiscan.com
Gas Settings
CrossFi uses a fixed gas price strategy. The template is configured with a default gas price of 1 gwei, which is generally sufficient for transactions on the CrossFi network.
const DEFAULT_GAS_PRICE = 1_000_000_000n; // 1 gwei
1 gwei is the recommended starting point. You may need to adjust the gas price based on network conditions for high-priority transactions.
Contract Verification
CrossFi supports two methods for contract verification:
- Option A (CLI): Automated verification using Hardhat.
- Option B (Web UI): Manual verification via the XFI Scan website.
Option A: CLI Verification (Recommended)
Option A: CLI Verification (Recommended)
CrossFi uses custom verifier endpoints (xfiscan.com) that provide an Etherscan-style API. This requires configuring customChains in Hardhat, as XFI Scan does not use the default Etherscan endpoints. The template is pre-configured to support this.
Configuration
In your hardhat.config.ts, the etherscan configuration is set up with custom chains and API URLs. Match the apiKey values as shown below (placeholders required by the block explorer):
etherscan: {
apiKey: {
// Is not required by the block explorer, but cannot be empty
crossfiTestnet: "ABCDEFG",
crossfiMainnet: "no-key",
},
customChains: [
{
network: "crossfiTestnet",
chainId: 4157,
urls: {
apiURL: "https://test.xfiscan.com/api/1.0/verify-contract",
browserURL: "https://test.xfiscan.com",
},
},
{
network: "crossfiMainnet",
chainId: 4158,
urls: {
apiURL: "https://xfiscan.com/api/1.0/verify-contract",
browserURL: "https://xfiscan.com",
},
},
],
},
Verify Command
To verify your deployed contract, use the hardhat verify command. You need to provide the contract address and any constructor arguments.
For Testnet:
npx hardhat verify --network crossfiTestnet <DEPLOYED_CONTRACT_ADDRESS> "Hello, CrossFi!"
For Mainnet:
npx hardhat verify --network crossfiMainnet <DEPLOYED_CONTRACT_ADDRESS> "Hello, CrossFi!"
Ensure you use the correct network flag (--network crossfiTestnet or --network crossfiMainnet) matching where you deployed your contract.
Option B: Verify via XFI Scan Web UI
If you encounter issues with CLI verification, or prefer a graphical interface, you can verify your contract using the XFI Scan Web UI.
Links:
- Testnet: test.xfiscan.com/contract/verify
- Mainnet: xfiscan.com/contract/verify
Step-by-Step Guide
To successfully verify via UI, all parameters must match your compilation settings exactly. You can find these settings in your hardhat.config.ts or build artifacts.
-
Contract Address: Paste the address of your deployed contract.
-
Compiler Type:
- Single file: Use this if you have a flattened file (recommended for UI).
- Multi-Part files: Use this if you want to upload original source files. Warning: You must preserve the exact directory structure of your project.
-
Compiler Version:
- Must match the
solidityversion inhardhat.config.ts. - Example: If config says
0.8.27, selectv0.8.27+commit....
- Must match the
-
EVM Version:
- Must match the
settings.evmVersioninhardhat.config.ts. - Default: If not set in config, it defaults to the compiler's default (typically
parisorshanghaifor recent versions). Check your build artifacts keys if unsure.
- Must match the
-
Optimization:
- Yes/No: Check
settings.optimizer.enabledinhardhat.config.ts. - Runs: Check
settings.optimizer.runs. Must match exactly (e.g.200).
- Yes/No: Check
-
Enter Contract Code:
- For Single File: Run
npx hardhat flatten > Flat.sol, copy the content ofFlat.sol, and paste it into the code box. - For Multi-Part: Upload all
.solfiles, keeping them in their respective folders (e.g.contracts/Greeting.sol,contracts/libs/...).
- For Single File: Run
-
Click Verify.
Troubleshooting Web UI Verification
- "Bytecode does not match": This is the most common error. It means one of the settings (Optimizer runs, EVM version, or Compiler version) is different from what was used to deploy.
- Imports Error: If using "Multi-Part", ensure you uploaded all dependencies and the folder structure (e.g.
./utils/Math.sol) matches exactly what is in yourimportstatements. - Recommendation: Use Single file (Flattened) method as it eliminates file structure issues.