Documentation Index
Fetch the complete documentation index at: https://docs.stablenet.network/llms.txt
Use this file to discover all available pages before exploring further.
Deploy a Solidity contract to StableNet Testnet using Hardhat and verify it on the Explorer.
What you’ll learn
By the end of this tutorial, you’ll be able to:
- Configure Hardhat and
hardhat.config.js for StableNet Testnet
- Deploy a WKRC payment contract using a Hardhat deploy script
- Verify the deployment on the StableNet Explorer
Prerequisites
- Node.js ≥ 18 — run
node --version to check
- Testnet WKRC from the Faucet
Create a Hardhat project
mkdir stablenet-hardhat && cd stablenet-hardhat
npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox dotenv
npx hardhat init
When prompted, select “Create a JavaScript project”.
Store your private key in a .env file and add it to .gitignore. Never commit it to version control.
echo "PRIVATE_KEY=0xYourPrivateKey" > .env
echo ".env" >> .gitignore
Replace the contents of hardhat.config.js:
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
module.exports = {
solidity: {
version: "0.8.20",
settings: {
// StableNet does not support blob opcodes — do not use cancun
evmVersion: "shanghai",
},
},
networks: {
stablenet_testnet: {
url: "https://api.test.stablenet.network",
chainId: 8283,
accounts: [process.env.PRIVATE_KEY],
},
},
};
Do not set evmVersion to cancun. StableNet does not support blob opcodes (BLOBHASH, BLOBBASEFEE). Use paris or shanghai.
Write WKRCPayment.sol
Delete the placeholder and create contracts/WKRCPayment.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC20 {
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
}
/// @title WKRCPayment
/// @notice Accepts WKRC payments from an approved sender.
contract WKRCPayment {
/// @dev NativeCoinAdapter (WKRC) — fixed system contract address on StableNet.
IERC20 public constant WKRC =
IERC20(0x0000000000000000000000000000000000001000);
event Payment(address indexed from, address indexed to, uint256 amount);
/// @notice Pull `amount` of WKRC from msg.sender and forward it to `to`.
/// Requires prior WKRC.approve(address(this), amount).
function pay(address to, uint256 amount) external {
require(WKRC.transferFrom(msg.sender, to, amount), "WKRC transfer failed");
emit Payment(msg.sender, to, amount);
}
function allowanceOf(address owner) external view returns (uint256) {
return WKRC.allowance(owner, address(this));
}
}
Compiled 1 Solidity file successfully (evm target: shanghai).
Write the deploy script
Create scripts/deploy.js:
const { ethers } = require("hardhat");
async function main() {
const [deployer] = await ethers.getSigners();
console.log("Deploying with:", deployer.address);
const WKRCPayment = await ethers.getContractFactory("WKRCPayment");
// StableNet requires maxPriorityFeePerGas on every transaction
const contract = await WKRCPayment.deploy({
maxPriorityFeePerGas: ethers.parseUnits("27600", "gwei"),
maxFeePerGas: ethers.parseUnits("80000", "gwei"),
});
await contract.waitForDeployment();
console.log("WKRCPayment deployed to:", await contract.getAddress());
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
You must pass maxPriorityFeePerGas and maxFeePerGas on every deploy and send call. Hardhat does not pick up the network-enforced minimum automatically — omitting them causes the transaction to be rejected.
Deploy to Testnet
npx hardhat run scripts/deploy.js --network stablenet_testnet
Deploying with: 0xYourWalletAddress
WKRCPayment deployed to: 0xABC...
Block inclusion can take up to 1–2 minutes. If waitForDeployment() appears to hang, the transaction is already in the mempool. Do not cancel and retry — that may cause a nonce conflict.
Verify on Explorer
Open explorer.stablenet.network and search for your contract address. You should see a Contract Creation transaction with status Success.
Next steps
Deploy with Foundry
Deploy the same contract using Foundry’s forge and cast.
Listen to Events
Subscribe to on-chain events with WebSocket.
RPC API Reference
Full list of supported JSON-RPC methods.
Fee Delegation
Let a separate account pay gas for your users.