monad-development

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Monad Development

Monad 开发指南

For questions not covered here, fetch https://docs.monad.xyz/llms.txt
如果遇到本文未涵盖的问题,请访问 https://docs.monad.xyz/llms.txt 获取相关信息

Quick Reference

快速参考

Defaults

默认配置

  • Network: Always use testnet (chain ID 10143) unless user says "mainnet"
  • Verification: Always verify contracts after deployment unless user says not to
  • Framework: Use Foundry (not Hardhat)
  • Wallet: If you generate a wallet, MUST persist it (see Wallet Persistence section)
  • 网络: 除非用户指定"mainnet",否则默认使用testnet(链ID 10143)
  • 验证: 除非用户明确说明不需要,否则部署合约后必须进行验证
  • 框架: 使用Foundry(而非Hardhat)
  • 钱包: 如果为用户生成钱包,必须持久化保存(请查看“钱包持久化”章节)

Networks

网络信息

网络链IDRPC地址
Testnet10143https://testnet-rpc.monad.xyz
Mainnet143https://rpc.monad.xyz
文档地址:https://docs.monad.xyz

Explorers

区块链浏览器

Agent APIs

Agent API

IMPORTANT: Do NOT use a browser. Use these APIs directly with curl.
Faucet (Testnet Funding):
bash
curl -X POST https://agents.devnads.com/v1/faucet \
  -H "Content-Type: application/json" \
  -d '{"chainId": 10143, "address": "0xYOUR_ADDRESS"}'
Returns:
{"txHash": "0x...", "amount": "1000000000000000000", "chain": "Monad Testnet"}
Fallback (official faucet): https://faucet.monad.xyz If the agent faucet fails, ask the user to fund via the official faucet (do not use a browser yourself).
Verification (All Explorers):
ALWAYS use the verification API first. It verifies on all 3 explorers (MonadVision, Socialscan, Monadscan) with one call. Do NOT use
forge verify-contract
as first choice.
bash
undefined
重要提示: 请勿使用浏览器。请直接使用curl调用以下API。
水龙头(测试网资金获取):
bash
curl -X POST https://agents.devnads.com/v1/faucet \
  -H "Content-Type: application/json" \
  -d '{"chainId": 10143, "address": "0xYOUR_ADDRESS"}'
返回结果:
{"txHash": "0x...", "amount": "1000000000000000000", "chain": "Monad Testnet"}
备用方案(官方水龙头): https://faucet.monad.xyz 如果Agent水龙头无法使用,请告知用户通过官方水龙头获取资金(请勿自行使用浏览器操作)。
合约验证(全浏览器支持):
请优先使用验证API。只需一次调用即可在三个浏览器(MonadVision、Socialscan、Monadscan)上完成验证。请勿将
forge verify-contract
作为首选方式。
bash
undefined

1. Get verification data

1. 获取验证数据

forge verify-contract <ADDR> <CONTRACT>
--chain 10143
--show-standard-json-input > /tmp/standard-input.json
cat out/<Contract>.sol/<Contract>.json | jq '.metadata' > /tmp/metadata.json COMPILER_VERSION=$(jq -r '.metadata | fromjson | .compiler.version' out/<Contract>.sol/<Contract>.json)
forge verify-contract <ADDR> <CONTRACT>
--chain 10143
--show-standard-json-input > /tmp/standard-input.json
cat out/<Contract>.sol/<Contract>.json | jq '.metadata' > /tmp/metadata.json COMPILER_VERSION=$(jq -r '.metadata | fromjson | .compiler.version' out/<Contract>.sol/<Contract>.json)

2. Call verification API

2. 调用验证API

STANDARD_INPUT=$(cat /tmp/standard-input.json) FOUNDRY_METADATA=$(cat /tmp/metadata.json)
cat > /tmp/verify.json << EOF { "chainId": 10143, "contractAddress": "0xYOUR_CONTRACT_ADDRESS", "contractName": "src/MyContract.sol:MyContract", "compilerVersion": "v${COMPILER_VERSION}", "standardJsonInput": $STANDARD_INPUT, "foundryMetadata": $FOUNDRY_METADATA } EOF
curl -X POST https://agents.devnads.com/v1/verify
-H "Content-Type: application/json"
-d @/tmp/verify.json

**With constructor arguments:** Add `constructorArgs` (ABI-encoded, WITHOUT 0x prefix):
```bash
ARGS=$(cast abi-encode "constructor(string,string,uint256)" "MyToken" "MTK" 1000000000000000000000000)
ARGS_NO_PREFIX=${ARGS#0x}
STANDARD_INPUT=$(cat /tmp/standard-input.json) FOUNDRY_METADATA=$(cat /tmp/metadata.json)
cat > /tmp/verify.json << EOF { "chainId": 10143, "contractAddress": "0xYOUR_CONTRACT_ADDRESS", "contractName": "src/MyContract.sol:MyContract", "compilerVersion": "v${COMPILER_VERSION}", "standardJsonInput": $STANDARD_INPUT, "foundryMetadata": $FOUNDRY_METADATA } EOF
curl -X POST https://agents.devnads.com/v1/verify
-H "Content-Type: application/json"
-d @/tmp/verify.json

**带构造函数参数的情况:** 添加`constructorArgs`(ABI编码,不带0x前缀):
```bash
ARGS=$(cast abi-encode "constructor(string,string,uint256)" "MyToken" "MTK" 1000000000000000000000000)
ARGS_NO_PREFIX=${ARGS#0x}

Add to request: "constructorArgs": "$ARGS_NO_PREFIX"

添加到请求中: "constructorArgs": "$ARGS_NO_PREFIX"


**Manual verification fallback (if API fails):**
```bash
forge verify-contract <ADDR> <CONTRACT> --chain 10143 \
  --verifier sourcify \
  --verifier-url "https://sourcify-api-monad.blockvision.org/"

**手动验证备用方案(如果API失败):**
```bash
forge verify-contract <ADDR> <CONTRACT> --chain 10143 \
  --verifier sourcify \
  --verifier-url "https://sourcify-api-monad.blockvision.org/"

Wallet Persistence

钱包持久化

CRITICAL for agents: If you generate a wallet for the user, you MUST persist it for future use.
When generating a new wallet:
  1. Create wallet:
    cast wallet new
  2. Immediately save the address and private key to a secure location
  3. Inform the user where the wallet details are stored
  4. Fund the wallet via faucet before deployment
Storage options:
  • Write to
    ~/.monad-wallet
    with chmod 600
  • Store in a project-specific
    .env
    file (add to .gitignore)
  • Return credentials to user and ask them to save securely
Why this matters: Users need access to their wallet to:
  • Deploy additional contracts
  • Interact with deployed contracts
  • Manage funds
  • Verify ownership
对Agent至关重要: 如果为用户生成钱包,必须持久化保存以便后续使用。
生成新钱包的步骤:
  1. 创建钱包:
    cast wallet new
  2. 立即保存钱包地址和私钥到安全位置
  3. 告知用户钱包详情的存储位置
  4. 在部署前通过水龙头为钱包充值
存储选项:
  • 写入
    ~/.monad-wallet
    并设置权限chmod 600
  • 存储在项目专属的
    .env
    文件中(需添加到.gitignore)
  • 将凭证返回给用户并要求其安全保存
重要性说明: 用户需要访问钱包以:
  • 部署额外合约
  • 与已部署合约交互
  • 管理资金
  • 验证所有权

Deployment Workflow

部署流程

Use
forge script
for deployments:
bash
forge script script/Deploy.s.sol:DeployScript \
  --rpc-url https://testnet-rpc.monad.xyz \
  --private-key $PRIVATE_KEY \
  --broadcast
Deploy script template:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;
import "forge-std/Script.sol";
import "../src/MyContract.sol";

contract DeployScript is Script {
    function run() external {
        vm.startBroadcast();
        MyContract contract = new MyContract();
        console.log("Contract deployed at:", address(contract));
        vm.stopBroadcast();
    }
}
使用
forge script
进行部署:
bash
forge script script/Deploy.s.sol:DeployScript \
  --rpc-url https://testnet-rpc.monad.xyz \
  --private-key $PRIVATE_KEY \
  --broadcast
部署脚本模板:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;
import "forge-std/Script.sol";
import "../src/MyContract.sol";

contract DeployScript is Script {
    function run() external {
        vm.startBroadcast();
        MyContract contract = new MyContract();
        console.log("Contract deployed at:", address(contract));
        vm.stopBroadcast();
    }
}

Technical Details

技术细节

EVM Version (Critical)

EVM版本(关键)

Always set
evmVersion: "prague"
. Requires Solidity 0.8.27+.
Foundry (
foundry.toml
):
toml
[profile.default]
evm_version = "prague"
solc_version = "0.8.28"
必须设置
evmVersion: "prague"
。要求Solidity 0.8.27及以上版本。
Foundry配置(
foundry.toml
):
toml
[profile.default]
evmm_version = "prague"
solc_version = "0.8.28"

Foundry Tips

Foundry使用技巧

Flags that don't exist (don't use):
  • --no-commit
    - not a valid flag for
    forge init
    or
    forge install
Deployment - use
forge script
, NOT
forge create
:
forge create --broadcast
is buggy and often ignored. Use
forge script
instead.
bash
forge script script/Deploy.s.sol:DeployScript \
  --rpc-url https://testnet-rpc.monad.xyz \
  --private-key $PRIVATE_KEY \
  --broadcast
Deploy script must NOT hardcode addresses:
solidity
// ✅ Correct - reads private key from --private-key flag
function run() external {
    vm.startBroadcast();
    new MyContract();
    vm.stopBroadcast();
}

// ❌ Wrong - hardcodes address, causes "No associated wallet" error
function run() external {
    vm.startBroadcast(0x1234...);
}
不存在的标志(请勿使用):
  • --no-commit
    - 不是
    forge init
    forge install
    的有效标志
部署 - 使用
forge script
,而非
forge create
forge create --broadcast
存在bug,经常无法正常工作。请改用
forge script
bash
forge script script/Deploy.s.sol:DeployScript \
  --rpc-url https://testnet-rpc.monad.xyz \
  --private-key $PRIVATE_KEY \
  --broadcast
部署脚本不得硬编码地址:
solidity
// ✅ 正确 - 从--private-key标志读取私钥
function run() external {
    vm.startBroadcast();
    new MyContract();
    vm.stopBroadcast();
}

// ❌ 错误 - 硬编码地址会导致"No associated wallet"错误
function run() external {
    vm.startBroadcast(0x1234...);
}

Frontend

前端开发

Import from
viem/chains
. Do NOT define custom chain:
ts
import { monadTestnet } from "viem/chains";
Use with wagmi:
ts
import { createConfig, http } from 'wagmi'
import { monadTestnet } from 'viem/chains'

const config = createConfig({
  chains: [monadTestnet],
  transports: {
    [monadTestnet.id]: http()
  }
})
viem/chains
导入链信息。请勿自定义链:
ts
import { monadTestnet } from "viem/chains";
与wagmi配合使用:
ts
import { createConfig, http } from 'wagmi'
import { monadTestnet } from 'viem/chains'

const config = createConfig({
  chains: [monadTestnet],
  transports: {
    [monadTestnet.id]: http()
  }
})

Example: Deploy ERC20

示例:部署ERC20代币

1. Create project:
bash
forge init my-token
cd my-token
2. Configure
foundry.toml
:
toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
evm_version = "prague"
solc_version = "0.8.28"
3. Create contract
src/MyToken.sol
:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
        _mint(msg.sender, initialSupply);
    }
}
4. Install dependencies:
bash
forge install OpenZeppelin/openzeppelin-contracts --no-commit
5. Create deploy script
script/Deploy.s.sol
:
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;
import "forge-std/Script.sol";
import "../src/MyToken.sol";

contract DeployScript is Script {
    function run() external {
        vm.startBroadcast();
        MyToken token = new MyToken(1000000 * 10**18);
        console.log("Token deployed at:", address(token));
        vm.stopBroadcast();
    }
}
6. Deploy:
bash
forge script script/Deploy.s.sol:DeployScript \
  --rpc-url https://testnet-rpc.monad.xyz \
  --private-key $PRIVATE_KEY \
  --broadcast
7. Verify:
bash
undefined
1. 创建项目:
bash
forge init my-token
cd my-token
2. 配置
foundry.toml
toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
evmm_version = "prague"
solc_version = "0.8.28"
3. 创建合约
src/MyToken.sol
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
        _mint(msg.sender, initialSupply);
    }
}
4. 安装依赖:
bash
forge install OpenZeppelin/openzeppelin-contracts --no-commit
5. 创建部署脚本
script/Deploy.s.sol
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;
import "forge-std/Script.sol";
import "../src/MyToken.sol";

contract DeployScript is Script {
    function run() external {
        vm.startBroadcast();
        MyToken token = new MyToken(1000000 * 10**18);
        console.log("Token deployed at:", address(token));
        vm.stopBroadcast();
    }
}
6. 部署:
bash
forge script script/Deploy.s.sol:DeployScript \
  --rpc-url https://testnet-rpc.monad.xyz \
  --private-key $PRIVATE_KEY \
  --broadcast
7. 验证:
bash
undefined

Use verification API (verifies on all explorers)

使用验证API(在所有浏览器上完成验证)

STANDARD_INPUT=$(forge verify-contract <TOKEN_ADDRESS> src/MyToken.sol:MyToken --chain 10143 --show-standard-json-input) COMPILER_VERSION=$(jq -r '.metadata | fromjson | .compiler.version' out/MyToken.sol/MyToken.json)
curl -X POST https://agents.devnads.com/v1/verify
-H "Content-Type: application/json"
-d "{ "chainId": 10143, "contractAddress": "<TOKEN_ADDRESS>", "contractName": "src/MyToken.sol:MyToken", "compilerVersion": "v${COMPILER_VERSION}", "standardJsonInput": $STANDARD_INPUT, "constructorArgs": "$(cast abi-encode 'constructor(uint256)' 1000000000000000000000000 | sed 's/0x//')" }"
undefined
STANDARD_INPUT=$(forge verify-contract <TOKEN_ADDRESS> src/MyToken.sol:MyToken --chain 10143 --show-standard-json-input) COMPILER_VERSION=$(jq -r '.metadata | fromjson | .compiler.version' out/MyToken.sol/MyToken.json)
curl -X POST https://agents.devnads.com/v1/verify
-H "Content-Type: application/json"
-d "{ "chainId": 10143, "contractAddress": "<TOKEN_ADDRESS>", "contractName": "src/MyToken.sol:MyToken", "compilerVersion": "v${COMPILER_VERSION}", "standardJsonInput": $STANDARD_INPUT, "constructorArgs": "$(cast abi-encode 'constructor(uint256)' 1000000000000000000000000 | sed 's/0x//')" }"
undefined