monad-development
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMonad 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
网络信息
| Network | Chain ID | RPC |
|---|---|---|
| Testnet | 10143 | https://testnet-rpc.monad.xyz |
| Mainnet | 143 | https://rpc.monad.xyz |
Docs: https://docs.monad.xyz
| 网络 | 链ID | RPC地址 |
|---|---|---|
| Testnet | 10143 | https://testnet-rpc.monad.xyz |
| Mainnet | 143 | https://rpc.monad.xyz |
Explorers
区块链浏览器
| Explorer | Testnet | Mainnet |
|---|---|---|
| Socialscan | https://monad-testnet.socialscan.io | https://monad.socialscan.io |
| MonadVision | https://testnet.monadvision.com | https://monadvision.com |
| Monadscan | https://testnet.monadscan.com | https://monadscan.com |
| 浏览器 | Testnet地址 | Mainnet地址 |
|---|---|---|
| Socialscan | https://monad-testnet.socialscan.io | https://monad.socialscan.io |
| MonadVision | https://testnet.monadvision.com | https://monadvision.com |
| Monadscan | https://testnet.monadscan.com | https://monadscan.com |
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 as first choice.
forge verify-contractbash
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-contractbash
undefined1. Get verification data
1. 获取验证数据
forge verify-contract <ADDR> <CONTRACT>
--chain 10143
--show-standard-json-input > /tmp/standard-input.json
--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
--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
-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
-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:
- Create wallet:
cast wallet new - Immediately save the address and private key to a secure location
- Inform the user where the wallet details are stored
- Fund the wallet via faucet before deployment
Storage options:
- Write to with chmod 600
~/.monad-wallet - Store in a project-specific file (add to .gitignore)
.env - 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至关重要: 如果为用户生成钱包,必须持久化保存以便后续使用。
生成新钱包的步骤:
- 创建钱包:
cast wallet new - 立即保存钱包地址和私钥到安全位置
- 告知用户钱包详情的存储位置
- 在部署前通过水龙头为钱包充值
存储选项:
- 写入并设置权限chmod 600
~/.monad-wallet - 存储在项目专属的文件中(需添加到.gitignore)
.env - 将凭证返回给用户并要求其安全保存
重要性说明: 用户需要访问钱包以:
- 部署额外合约
- 与已部署合约交互
- 管理资金
- 验证所有权
Deployment Workflow
部署流程
Use for deployments:
forge scriptbash
forge script script/Deploy.s.sol:DeployScript \
--rpc-url https://testnet-rpc.monad.xyz \
--private-key $PRIVATE_KEY \
--broadcastDeploy 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 scriptbash
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 . Requires Solidity 0.8.27+.
evmVersion: "prague"Foundry ():
foundry.tomltoml
[profile.default]
evm_version = "prague"
solc_version = "0.8.28"必须设置。要求Solidity 0.8.27及以上版本。
evmVersion: "prague"Foundry配置():
foundry.tomltoml
[profile.default]
evmm_version = "prague"
solc_version = "0.8.28"Foundry Tips
Foundry使用技巧
Flags that don't exist (don't use):
- - not a valid flag for
--no-commitorforge initforge install
Deployment - use , NOT :
forge scriptforge createforge create --broadcastforge scriptbash
forge script script/Deploy.s.sol:DeployScript \
--rpc-url https://testnet-rpc.monad.xyz \
--private-key $PRIVATE_KEY \
--broadcastDeploy 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 scriptforge createforge create --broadcastforge scriptbash
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 . Do NOT define custom chain:
viem/chainsts
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/chainsts
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-token2. Configure :
foundry.tomltoml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
evm_version = "prague"
solc_version = "0.8.28"3. Create contract :
src/MyToken.solsolidity
// 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-commit5. Create deploy script :
script/Deploy.s.solsolidity
// 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 \
--broadcast7. Verify:
bash
undefined1. 创建项目:
bash
forge init my-token
cd my-token2. 配置:
foundry.tomltoml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
evmm_version = "prague"
solc_version = "0.8.28"3. 创建合约:
src/MyToken.solsolidity
// 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-commit5. 创建部署脚本:
script/Deploy.s.solsolidity
// 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 \
--broadcast7. 验证:
bash
undefinedUse 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//')" }"
-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//')" }"
undefinedSTANDARD_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//')" }"
-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