Deploy with Foundry
This guide explains how to build and deploy smart contracts to Mersennet using Foundry. Important: Mersennet uses a custom raw transaction format (not standard RLP), so forge create with eth_sendRawTransaction will not work. Use eth_sendTransaction or prime_sendTransaction instead.
Prerequisitesβ
Foundry Configurationβ
Create or update foundry.toml in your project root:
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.20"
optimizer = true
optimizer_runs = 200
evm_version = "shanghai"
[rpc_endpoints]
prime_testnet = "http://46.225.30.187:8545"
Build Your Contractsβ
forge build
Use the --legacy flag if your tooling expects legacy transaction format:
forge build --legacy
Deployment Limitationβ
Mersennet does not support standard RLP-encoded raw transactions via eth_sendRawTransaction. Tools that sign transactions locally and send them as raw hex (including forge create) will fail.
Supported deployment methods:
eth_sendTransactionβ Requires the RPC node to have the deployer account unlockedprime_sendTransactionβ Mersennetβspecific method for sending transactions
Node.js Deployment Helperβ
Use a Node.js script with ethers.js to deploy via eth_sendTransaction (with a wallet) or by having the node sign for an unlocked account.
1. Create a deploy scriptβ
Create scripts/deploy.js:
const { ethers } = require("ethers");
const RPC_URL = "http://46.225.30.187:8545";
const CHAIN_ID = 7919;
async function main() {
// Option A: Use private key (ethers signs, but we use eth_sendTransaction via a custom provider)
// Option B: Use a node with unlocked account
const provider = new ethers.JsonRpcProvider(RPC_URL, CHAIN_ID);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const factory = new ethers.ContractFactory(
require("./MyToken_abi.json"),
require("./MyToken_bytecode.json"),
wallet
);
const contract = await factory.deploy(1_000_000);
await contract.waitForDeployment();
console.log("Deployed to:", await contract.getAddress());
}
main().catch(console.error);
2. Compile and extract artifactsβ
forge build
Then create a script that reads Foundry artifacts:
// deploy-with-forge-artifacts.js
const { ethers } = require("ethers");
const fs = require("fs");
const path = require("path");
const RPC_URL = "http://46.225.30.187:8545";
const CHAIN_ID = 7919;
async function main() {
const provider = new ethers.JsonRpcProvider(RPC_URL, CHAIN_ID);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const artifactPath = path.join(__dirname, "../out/MyToken.sol/MyToken.json");
const artifact = JSON.parse(fs.readFileSync(artifactPath, "utf8"));
const factory = new ethers.ContractFactory(
artifact.abi,
artifact.bytecode.object,
wallet
);
const contract = await factory.deploy(1_000_000);
await contract.waitForDeployment();
console.log("MyToken deployed to:", await contract.getAddress());
}
main().catch(console.error);
3. Run the deploy scriptβ
npm install ethers
PRIVATE_KEY=0x_your_key node deploy-with-forge-artifacts.js
ethers.js v6 uses eth_sendTransaction under the hood when you call contract.deploy(). The library signs the transaction and sends it. However, if Mersennet expects a custom format for eth_sendRawTransaction, ethers may still use that. In that case, ensure your RPC supports eth_sendTransaction with a signed payload, or use a node with an unlocked account for deployment.
Alternative: Cast for Read-Only Operationsβ
For read-only operations, cast works normally:
# Get balance
cast balance 0xYourAddress --rpc-url http://46.225.30.187:8545
# Call a view function
cast call 0xContractAddress "totalSupply()(uint256)" --rpc-url http://46.225.30.187:8545
# Get chain ID
cast chain-id --rpc-url http://46.225.30.187:8545
Summaryβ
| Operation | Supported | Notes |
|---|---|---|
forge build | β | Use --legacy if needed |
forge test | β | Against local Anvil or Prime RPC |
forge create | β | Custom tx format; use Node.js helper |
cast call | β | Read-only |
cast send | β | Same limitation as forge create |
eth_sendTransaction | β | Use for deployment |
eth_feeHistory | β | Not supported on Mersennet |