第 10 课:构建你的第一个去中心化应用
踏上构建生产级应用的旅程。
你已经构建了一个应用,并成功把它发布到互联网上了。现在你要把它发布到区块链上——一个无法关停、无法审查、除了代码本身之外没有任何人能控制的地方。
你已经构建过应用并把它们发布到了互联网上。但你的代码仍然运行在某个组织拥有的服务器上。Vercel 可能会宕机。GitHub 可能会封禁你的账号。公司可能会改变定价。
去中心化应用(dApp)的后端则不一样。一旦你把它部署到区块链上,它就永远存在。没有公司控制它。没有人能修改它。没有人能把它下架。它会按照写好的方式精确执行,每一次都一样,对所有人都一样。
你已经知道如何把应用发布到互联网上。现在你要把它发布到区块链上。
而且你要用 Vibecoding 完成这一切。
在开始之前:关于智能合约安全的提醒
本课程是入门级的。你要构建的合约是把一条消息存到区块链上。它不处理真实的资金,不涉及用户资产,也没有任何金融价值的东西。
这很重要,因为那些处理资金的智能合约(smart contract)完全是另一回事。
AI 智能体编写 UI 代码的能力,要远比编写智能合约代码的能力强得多。Solidity 的训练数据更少,逻辑更专业,错误也更难被发现。在网页应用里,一个 bug 顶多让某个按钮失效;但在一个处理资金的智能合约里,一个 bug 可能导致永久的、不可逆的资金损失。这里没有撤销键,没有客服。一旦部署,就再也无法回头了。
Monad 的安全团队已经明确指出:vibe-coding 智能合约是有风险的,对没有智能合约经验的人来说尤其如此。资深工程师的建议是:
- 保持合约小而简单。 逻辑越复杂,出错的面就越大。
- 使用经过审计的代码库。 不要重新发明已经存在的东西。OpenZeppelin 是行业标准。
- 绝不要在没有专业审计的情况下,vibe-code 一个处理真实资金的合约。
- 永远先在测试网上测试。 绝不要直接部署到主网。
对于本课程的内容来说这问题不大。MessageBoard 只是存储一个字符串的合约。它不涉及任何资金。这相当于智能合约里的「Hello World」,非常适合入门。
在 junior 阶段的课程里,我们会更深入地讲解智能合约的安全、测试和审计。现在:构建、学习,留在测试网上。
什么是去中心化应用后端?
去中心化应用后端是一段运行在区块链上、而不是运行在服务器上的程序。一旦它被部署,没有人能修改它,也没有人能把它下架。它会按照写好的方式精确执行,每一次都一样,对所有人都一样。
可以把它想成一台自动售货机。你投入硬币,按下按钮,机器就会给你一份零食。没有收银员。没有讨价还价。规则是内置的,并且会自动执行。去中心化应用后端的工作方式也是一样的。
一个去中心化应用后端在部署之后由谁来控制?
什么是 Solidity?
Monad 上的应用由一种叫 Solidity 的语言编写的代码驱动。它是目前最广泛使用的去中心化应用后端编程语言,运行在 EVM 上——这正是 Monad 所采用的标准。
要完成这节课,你不需要把 Solidity 学得多么精通——具体的代码是 AI 智能体来写的。但理解一些基础概念,能帮助你读懂智能体生成的内容,并发现其中的错误。如果你想更深入,Solidity by Example 是最好的入门起点。
要用 vibecode 来构建一个去中心化应用后端,你需要先学会 Solidity 吗?
准备工作
[沙箱 — 推荐]
你大概率还停留在上一节课的 Replit 中,列表应用还开着。给这个 dApp 新建一个项目:
- 点击预览顶部栏(Canvas 按钮旁边)的项目名下拉菜单。
- 点击 Create something new(下方写着「Build with Agent」)。

这会打开一个全新的提示界面,你将在 Step 1 里描述你的新项目。
Step 1:构建前端
在写任何链上代码之前,先做一个供用户交互的前端。告诉你的智能体:
> Create a new React app with a clean, simple UI for a message board.
It should have:
- A header with the app title "Message Board"
- A section that displays a placeholder message (e.g. "Loading...")
- A text input and an "Update Message" button
- A "Connect Wallet" button in the top right corner
You can set up wagmi + RainbowKit so the Connect Wallet button
opens a real wallet-connection modal (configured for Monad testnet,
Chain ID: 10143, RPC: https://testnet-rpc.monad.xyz).
But the Update Message button must NOT be wired up to anything
yet — no local React state, no handlers that change the displayed
message, no fake updates. Keep it disabled or a no-op. We'll wire
it to an on-chain contract in a later step, and the displayed
message must only ever come from the contract.
智能体完成后,应用的实时预览会自动打开。你应该会看到一个基础页面,包含标题、消息区域、输入框和按钮。这些按钮目前还不会有任何反应。这是正常的。
你的钱包
你已经有了一个能跑起来的前端。下一步要部署合约,你需要一个连接到 Monad 测试网(testnet) 的钱包。整节课我们都使用测试网,而不是主网。测试网上的 MON 是免费的,没有真实价值。
重要: 使用你的开发钱包,不要用主钱包。你会把私钥放进智能体的环境变量里。永远不要用一个有真实资金的钱包做开发。
获取你的私钥
部署合约时需要钱包的私钥。在 MetaMask 中获取私钥的方法:
- 打开 MetaMask,确保当前是你的开发账户
- 点击账户名旁边的三个点
- 选择 Account Details
- 点击 Show private key
- 输入你的 MetaMask 密码
- 复制私钥
这是本节课最重要的安全步骤。继续之前请务必读完。
你的私钥能完全控制你的钱包。任何持有它的人都能拿走里面的一切。这其中也包括 AI 智能体。
把私钥存在你电脑上的
.env文件里,安全性是远远不够的。智能体运行在同一台机器上,可以读取那个文件——尤其是当它被提示注入(prompt injection)攻击时。如果一条恶意指令让智能体读取你的.env文件并把内容发到某个地方,它就会照办。规则很简单:绝不能让智能体看到你的私钥。 请按照下面对应路径的步骤操作。
Replit 内置了 Secrets 管理器。Secrets 会被加密存储,并在运行时作为环境变量注入。智能体无法从文件系统中读取它们。
- 在你的 Repl 里,点击左侧栏的 Secrets 标签(锁形图标)
- 点击 New Secret
- 把 key 设为
PRIVATE_KEY,value 粘贴你的私钥 - 点击 Add Secret
部署合约的代码可以通过 process.env.PRIVATE_KEY 访问它,但智能体在任何文件中都看不到它。
获取测试网 MON
部署合约会消耗少量 gas。没有 gas,部署会失败。
- 打开 Build Anything 水龙头
- 粘贴你的钱包地址
- 申请测试网 MON
你可以在 MetaMask 里查看余额,或者在 Monad 测试网区块浏览器 中搜索你的钱包地址来确认。
Step 2:用 Vibecode 写链上逻辑
现在来构建合约。我们要写一个把消息存在区块链上的去中心化应用后端。任何人都可以读取它。任何人都可以更新它。不涉及任何资金。
告诉你的智能体:
> Create a Solidity contract called MessageBoard. It should:
- Store a string message
- Let anyone read the current message
- Let any connected wallet update the message
- Emit an event every time the message is changed
Use Hardhat for the development setup. Configure it to deploy
to the Monad testnet (Chain ID: 10143, RPC: https://testnet-rpc.monad.xyz).
观察智能体的工作过程。它会搭建 Hardhat 项目、写 Solidity 合约、创建部署脚本,并把网络配置为 Monad 测试网。你不需要看懂每一行代码——但尽可能把它生成的内容通读一遍。这是个好习惯。
部署它
你的私钥已经设置为 secret。让智能体来部署:
> Deploy the MessageBoard contract to the Monad testnet using my
private key from the .env file. The key is available as the
PRIVATE_KEY environment variable.
再次提醒: 永远不要把私钥直接粘贴到给智能体的 prompt 里。也永远不要把它放进智能体能读取的文件里。
完成后,你会得到一个 合约地址(contract address)。把它保存下来。下一步会用到。
> What is the deployed contract address?
故障排查 — 部署失败或 gas 不足: 回到 Build Anything 水龙头,再申请一些测试网 MON,然后重试。
把前端连接到合约
现在把你在 Step 1 中构建的前端,与已经部署上链的合约连接起来。粘贴下面的内容(把 [your-contract-address] 替换成你刚才拿到的地址):
> The MessageBoard contract is deployed at [your-contract-address]
on Monad testnet (Chain ID: 10143). Wire my app up to it.
On page load, read the current message from the contract and
display it in the message section. Wire the "Update Message"
button to send a transaction that calls the contract's update
function.
Rules:
- Use wagmi for reads (useReadContract) and writes
(useWriteContract / useWaitForTransactionReceipt). Use the
ABI that was generated during deployment.
- The Update button must be disabled whenever no wallet is
connected. Never let the UI change the message without a wallet.
- Do not use local React state for the displayed message. Only
show the new message after the on-chain transaction is
confirmed and you've re-read the message from the contract.
- Any connected wallet can update (this is a simple shared
message board — no owner-only logic).
- Show a loading state during the transaction and a success
message when it's confirmed. If the transaction rejects or
reverts, show the error and leave the displayed message
unchanged.
- If the user is on the wrong chain, use wagmi's useSwitchChain
hook to switch them to Monad testnet. Do NOT call
wallet_switchEthereumChain through an ethers.BrowserProvider —
that throws "ethereum.request is not a function" in ethers v6.
If chain switching has to be manual, call .request() on
window.ethereum directly (the raw EIP-1193 provider).
把一个去中心化应用后端部署到 Monad 上,你需要什么?
Step 3:试用一下
点击预览按钮,在浏览器中打开你的应用。
连接你的钱包。你应该能看到来自区块链的当前消息以及更新表单。输入一条新消息,点击 Update,在钱包里确认交易,然后看着消息发生改变。
这条消息现在被永久存在了 Monad 区块链上。没有服务器。没有数据库。中间没有任何公司。
wagmi 是做什么的?
当你在合约上更新消息时,会发生什么?
刚刚发生了什么
你刚刚完成了:
- 构建了一个前端 UI
- 用普通中文(其实是英文)描述了你想要什么,并让 AI 智能体写出了链上代码
- 把它部署到了 Monad 测试网
- 通过钱包连接,把前端连到了合约
- 在你的应用里读写区块链上的数据
没有 Solidity 课程。没有花上几个月时间学习。你用 Vibecoding 做出了一个链上应用。
你已经把应用发布到了区块链上
想想你没有使用的东西。没有服务器。没有托管账号。没有需要维护的基础设施。没有月度账单。没有可能被封停的账号。
你的链上代码就是后端。它同时运行在世界各地成千上万台计算机上。没有单点故障,没有哪家公司能拔掉电源。你只把规则写下一次,部署上去,从此它就永远按照写好的方式运行——对任何能联网的人,全世界都一样。
用它你能构建什么?
一旦你意识到自己可以构建一个没有人控制的后端,一类全新的应用就变得可能了——它们在过去根本无法存在:
反虚假宣传的 AI 检测工具 —— 用来识别和标记 AI 生成的虚假信息,结果存储在链上,没有人能篡改或压制这些发现。记录是公开且永久的。
反审查平台 —— 内容存放在区块链上的发布与通信工具。没有平台能删除它,没有政府能下架它,也没有公司能在一夜之间改变规则。
可信投票 —— 每一票都被记录在链上,任何人都可以独立验证结果。没有黑箱。没有「请相信我们」。数学是公开且可审计的。
数据隐私 —— 用户真正拥有自己的数据、并由代码而非公司隐私政策来约束谁可以访问的应用。没有可以毫无预告就修改的服务条款。
它们的共同点是:这些应用的价值,恰恰来自「没有人能掌控它」这一事实。代码就是制度。这正是 Monad 在大规模上让其成为可能的事情。
接下来是什么
你已经用 Vibecoding 构建了一个去中心化应用后端,并把它和前端连接了起来。这只是开始。在 junior 课程里,你会更深入——智能合约的安全、测试、审计,以及如何构建能安全处理真实价值的合约。
0/5 正确
0% — 全部答对即可完成