Chain 3961 · developer quickstart

Deploy a contract on Ferminux

Foundry, Hardhat, viem and ethers all work on chain 3961 once three things are set: compile for the Paris target, tip at least 1 gwei, and use chain id 3961.

Get gas from the faucet

Network

Chain ID
3961 (0xF79)
Currency
FMX, 18 decimals. It pays for gas and settles every payment.
RPC
https://rpc.ferminux.net
WebSocket
wss://rpc.ferminux.net/ws
Explorer
explorer.ferminux.net · verification API https://explorer.ferminux.net/api/
Consensus
Clique proof-of-authority: a set of authorised signers confirms a block every 7 seconds. How blocks are confirmed
Block gas limit
100,000,000
EVM
The London rule set. Compile for the Paris target.
Fees
EIP-1559. Base fee —; the signers include a transaction only when its tip is at least 1 gwei.
Head
—

Before you deploy

Six things differ from a default setup. The first two stop a deploy outright.

  1. Compile for Paris. The chain runs the London rule set, so the opcodes added after it are missing: PUSH0, transient storage (TLOAD/TSTORE) and MCOPY. Solidity 0.8.20 and later target a newer EVM by default and emit PUSH0, and the deploy fails with invalid opcode: PUSH0. Set evm_version = "paris" in Foundry or evmVersion: "paris" in Hardhat. Contracts that rely on transient storage, such as OpenZeppelin's ReentrancyGuardTransient, cannot run here.
  2. Tip at least 1 gwei. A transaction with a smaller tip still gets a hash back, then stays pending for good. eth_maxPriorityFeePerGas answers 1 gwei, so ethers, Hardhat and viem pick it up. eth_feeHistory reports zero tips, so Foundry tips 1 wei unless you pass --gas-price 2gwei --priority-gas-price 1gwei.
  3. Use block numbers, not finalized or safe. Both tags return null here. No block can be reorganised more than 64 blocks deep, so a block 64 behind the head is final.
  4. Recent state only, and no tracing. The public RPC is a full node: reading state more than about 128 blocks back fails with missing trie node, and debug_trace* and eth_getBlockReceipts are not served. Index from eth_getLogs.
  5. No shared singleton contracts yet. Multicall3, the CREATE2 deployer at 0x4e59b44847b379578588920cA78FbF26c0B4956C, Permit2, Safe and the 4337 EntryPoint are not deployed on chain 3961. Deploy with plain CREATE, and leave multicall3 out of your chain definition.
  6. block.prevrandao is not random. It returns the Clique difficulty, 1 or 2. Never use it as a source of randomness.

Foundry

foundry.toml
[profile.default]
solc_version = "0.8.24"
evm_version = "paris"   # chain 3961 runs the London rule set: no PUSH0, TSTORE or MCOPY
optimizer = true
optimizer_runs = 200

[rpc_endpoints]
ferminux = "https://rpc.ferminux.net"

Deploy. Foundry needs both fee flags: without them it tips 1 wei and the transaction never lands. --account deployer is a keystore made once with cast wallet import deployer --interactive.

Deploy one contract
forge create src/Counter.sol:Counter \
  --rpc-url ferminux \
  --account deployer \
  --broadcast \
  --gas-price 2gwei --priority-gas-price 1gwei
Run a deploy script
forge script script/Deploy.s.sol \
  --rpc-url ferminux \
  --account deployer \
  --broadcast \
  --with-gas-price 2gwei --priority-gas-price 1gwei
Call it
cast send <address> "increment()" \
  --rpc-url ferminux --account deployer \
  --gas-price 2gwei --priority-gas-price 1gwei

cast call <address> "number()(uint256)" --rpc-url ferminux

Hardhat

Hardhat 2 with @nomicfoundation/hardhat-toolbox. It reads the 1 gwei tip from the RPC, so no fee settings are needed.

hardhat.config.js
require("@nomicfoundation/hardhat-toolbox");

module.exports = {
  solidity: {
    version: "0.8.24",
    settings: { evmVersion: "paris", optimizer: { enabled: true, runs: 200 } },
  },
  networks: {
    ferminux: {
      url: "https://rpc.ferminux.net",
      chainId: 3961,
      accounts: process.env.FERMINUX_PRIVATE_KEY ? [process.env.FERMINUX_PRIVATE_KEY] : [],
    },
  },
  etherscan: {
    apiKey: { ferminux: "blockscout" }, // any non-empty string
    customChains: [{
      network: "ferminux",
      chainId: 3961,
      urls: { apiURL: "https://explorer.ferminux.net/api", browserURL: "https://explorer.ferminux.net" },
    }],
  },
  sourcify: { enabled: false },
};
scripts/deploy.js
const { ethers } = require("hardhat");

async function main() {
  const counter = await ethers.deployContract("Counter");
  await counter.waitForDeployment();
  console.log("Counter:", await counter.getAddress());
}
main().catch((e) => { console.error(e); process.exitCode = 1; });
Deploy and verify
npx hardhat run scripts/deploy.js --network ferminux
npx hardhat verify --network ferminux <address>

viem and ethers

viem: the chain definition
import { createPublicClient, defineChain, http } from "viem";

export const ferminux = defineChain({
  id: 3961,
  name: "Ferminux",
  nativeCurrency: { name: "Ferminux", symbol: "FMX", decimals: 18 },
  rpcUrls: {
    default: { http: ["https://rpc.ferminux.net"], webSocket: ["wss://rpc.ferminux.net/ws"] },
  },
  blockExplorers: {
    default: { name: "Ferminux Explorer", url: "https://explorer.ferminux.net", apiUrl: "https://explorer.ferminux.net/api" },
  },
  // the signers' floor; no contracts.multicall3: it is not deployed on chain 3961
  fees: { maxPriorityFeePerGas: 1_000_000_000n },
});

const client = createPublicClient({ chain: ferminux, transport: http() });
console.log(await client.getBlockNumber());
ethers v6
import { ContractFactory, JsonRpcProvider, Wallet } from "ethers";

const provider = new JsonRpcProvider("https://rpc.ferminux.net", 3961, { staticNetwork: true });
const wallet = new Wallet(process.env.FERMINUX_PRIVATE_KEY, provider);

// getFeeData() reads the 1 gwei tip from eth_maxPriorityFeePerGas
const factory = new ContractFactory(abi, bytecode, wallet);
const counter = await factory.deploy();
await counter.waitForDeployment();

Verify on the explorer

The explorer runs Blockscout, and Foundry's Blockscout verifier talks to it directly. No API key is needed.

Verify a deployed contract
forge verify-contract <address> src/Counter.sol:Counter \
  --rpc-url https://rpc.ferminux.net \
  --verifier blockscout \
  --verifier-url https://explorer.ferminux.net/api/

For a contract with constructor arguments, add --constructor-args $(cast abi-encode "constructor(uint256)" 42). To verify in the same step as the deploy, add --verify --verifier blockscout --verifier-url https://explorer.ferminux.net/api/ to forge create or forge script.

Addresses

Everything the project runs on chain 3961. The last column reads each address's bytecode from the RPC as you open the page.

ContractAddressCode
Agent network
AgentRegistry0xa94f27F18267d09349809f3e2AeF8e7767033e8F
ServiceEscrow0x99b331495951dB91857902de91EAe9Ff54d8a719
X402Vault0x8751Cf7e29Fe588c61FDc53323438247198eaa57
AgentAccountFactory0x82e7C593785f726A0A0BB4D37AbCaF2bA4a72dcb
StreamPay0x59404F738A90E5CF725F5837EF40461d1EA2EC35
ArbiterPool0x367312B28f78dE97462905519337841e4d4cB2df
IdentityRegistry80040xf3e8c83a0472602d04Cd774e3887cBAA76c62147
ReputationRegistry80040xd5984C5a187cD6EcF2698eb218988F73FBF08884
ValidationRegistry80040x37feB1B3Fb6505d4D584dB0a632F3C20d9eAab97
AgentTokenFactory0xf9fcCF337a7930D146227601C1da7Be85bB50188
Ferminux Agents (FRC-721, FMXA)0x84FE97C49Ffe4227d9ea139B5998C097D9C06ddd
Ferminux Citizens (FRC-721, FMXC)0x5672AF1a567a46BAaFeb66959b7A95666E7f4252
Ferminux DEX
FerminuxRouter0x018C0Efca293F7a74D2f53ce738BA5e2f412BA9f
FerminuxFactory0x2034a8366fCdbfFCf4517D297f702aDDdba37040
WFMX (wrapped FMX)0x8a9Ae4D652cEba09Db8Ebf48D28C943b41B377Ae
WFMX/AZNT pool0xbab12e7B817F0686e11949eC06697235DC146845
LiquidityLocker0xe588c594388B978E64B69E2Dd91CC7E302763951
Tokens and treasury
USDF (FRC-20)0xCd032A609e34121D1881E8DE7355b2c2c7092363
AZNT (FRC-20)0xFc81ad7c145B868ef0CEC8D7Ec881Ac93f724178
Launchpad TokenFactory0x62BC7d9671EfE1385413434aB8fdfE2fa4aE01D4
Faucet0xf4dE70068031DA17347cd19aCaa841013751B3c0
Governance multisig0x910BD467D8576277f8f96DF47428377FFD94fEfe
Treasury (an account, not a contract)0xc0A5Eb613f859f072554F29f1Ab7400265af15aB

ABIs: docs, section 4 and the explorer's verified sources. FMX on BNB Chain is wFMX 0x73e64635E2a7b393F2aa3924dcf91fE3cFF51BD0; see where FMX trades.

Machine-readable