Solidity 实战【二】:手写一个「链上资金托管合约」

前言

如果说实战【一】解决的是:

"我终于会写合约了"

那这一篇解决的就是:

"原来合约还能这样用"

从这一篇开始,你会真正感受到:

👉 智能合约不是玩具,而是"可自动执行的资金规则"

一、什么是资金托管合约?为什么它非常重要?

先别急着写代码,我们先搞清楚 业务模型。

1️⃣ 现实世界的托管场景

现实中我们经常遇到:

买卖双方互不信任

需要一个"中间人"暂时保管钱

条件满足后,再放款

例如:

二手交易平台

自由职业接单

保证金 / 押金

传统模式是:

平台 / 银行 / 第三方 → 托管资金

2️⃣ 链上托管解决了什么?

链上托管的本质是:

代码即规则,资产由合约控制

特点:

无法私吞

规则透明

无需信任第三方

满足条件 → 自动放款

👉 这是 Solidity 最经典、最有价值的应用场景之一

二、实战目标(先定规则,再写代码)

这一点非常重要,也是新手最容易跳过的。

我们要实现一个最小可用的托管合约:

规则如下:

1️⃣ 合约由 托管人(owner) 部署

2️⃣ 任何人可以向合约 存入 ETH

3️⃣ 只有 owner 可以 释放资金

4️⃣ 释放后,钱打到指定地址

5️⃣ 合约余额可随时查询

👉 这是一个 可真实部署、可真实收钱的合约

三、合约整体结构设计(工程思维)

Escrow.sol

├── 状态变量

├── 构造函数

├── 收款逻辑

├── 放款逻辑

├── 查询逻辑

我们一步一步来。

四、合约骨架(从零开始)

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

contract Escrow {

}

老规矩:

SPDX:协议声明

pragma:版本锁定

合约名清晰表达业务语义

五、定义核心状态变量(资金 + 权限)

5.1 owner(托管人)

address public owner;

5.2 构造函数初始化

constructor() {

owner = msg.sender;

}

谁部署,谁就是规则制定者

六、让合约"能收钱"(关键一步)

这是新手第一次真正接触 payable。

6.1 最简单的存钱方式

function deposit() external payable {

// 只要转钱进来,就会记在合约余额里

}

解释:

payable:允许接收 ETH

msg.value:本次转入金额

钱不会进某个变量

👉 而是直接进合约账户

6.2 查看合约当前余额

function getBalance() external view returns (uint256) {

return address(this).balance;

}

这是 Solidity 非常重要的一行:

address(this).balance

含义是:

当前合约地址上的 ETH 余额

七、核心功能:释放资金(托管的本质)

7.1 权限校验(必须)

modifier onlyOwner() {

require(msg.sender == owner, "not owner");

_;

}

这是 modifier 的标准用法:

抽离权限逻辑

代码更干净

工程必备

7.2 放款函数(重点)

function release(address payable to, uint256 amount)

external

onlyOwner

{

require(amount <= address(this).balance, "insufficient balance");

复制代码
to.transfer(amount);

}

解释逐行拆解:

address payable:允许接收 ETH 的地址

校验余额,防止超额转账

transfer:最简单、安全的转账方式

👉 这是合约真正"动钱"的地方

八、完整合约代码(可直接部署)

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

contract Escrow {

复制代码
address public owner;

constructor() {
    owner = msg.sender;
}

modifier onlyOwner() {
    require(msg.sender == owner, "not owner");
    _;
}

// 存钱
function deposit() external payable {}

// 查看合约余额
function getBalance() external view returns (uint256) {
    return address(this).balance;
}

// 放款
function release(address payable to, uint256 amount)
    external
    onlyOwner
{
    require(amount <= address(this).balance, "insufficient balance");
    to.transfer(amount);
}

}

九、你已经掌握的 Solidity 核心能力(不知不觉)

这一篇你已经会了:

payable 的真实用法

合约如何持有 ETH

address(this).balance

modifier 权限抽象

ETH 转账完整流程

真实资金托管模型

👉 这已经不是"玩具合约"了

十、工程师一定要知道的 3 个关键安全点

❗1️⃣ transfer 不是万能的

在复杂场景中:

transfer 有 2300 gas 限制

新合约更推荐 call

但:

👉 新手阶段,transfer 是最安全的

❗2️⃣ 放款逻辑一定要简单

放款函数里:

❌ 不要 for 循环

❌ 不要复杂判断

❌ 不要调用不可信合约

❗3️⃣ 这是"半托管模型"

真正的业务托管还会涉及:

多方签名

状态机

仲裁机制

但 第一步走稳,比什么都重要

十一、正确的练习方式(非常重要)

强烈建议你做这 4 步:

1️⃣ 自己手敲一遍

2️⃣ 存 0.01 ETH 试试

3️⃣ 非 owner 调用 release

4️⃣ 把 transfer 改成 call(提前预习)

总结

如果说实战【一】是:

"我终于看懂 Solidity 了"

那实战【二】就是:

"原来智能合约真的能管钱"

你已经正式迈入 Web3 工程实战门槛。

下一篇预告(含金量更高)

👉 Solidity 实战【三】:重入攻击与防御(从 0 到 1 看懂 DAO 事件)

我们会:

写一个"有漏洞的合约"

亲手复现重入攻击

再一步步修复

这是 区块链工程师必会的一关。

相关推荐
傻小胖14 小时前
21.ETH-权益证明-北大肖臻老师客堂笔记
笔记·区块链
硅基流动18 小时前
硅基流动 × ValueCell:8K+Star,去中心化金融智能体加速投资决策
金融·去中心化·区块链
devmoon18 小时前
使用 Hardhat 在 Polkadot Hub 测试网部署基础 Solidity 合约(完整实战指南)
web3·区块链·智能合约·波卡·hardhat
威胁猎人19 小时前
【黑产大数据】2025年全球KYC攻击风险研究报告
大数据·区块链
焦点链创研究所19 小时前
去中心化实体基础设施网络的崛起:比较分析
网络·去中心化·区块链
MicroTech20251 天前
微算法科技(NASDAQ :MLGO)量子测量区块链共识机制:保障数字资产安全高效存储与交易
科技·安全·区块链
区块链蓝海1 天前
Ardor v2.6.0 正式发布:Nxt迁移完成,Ardor迈入多链协同新阶段
人工智能·区块链
MQLYES1 天前
02-UniswapV1-源码篇
去中心化·区块链
devmoon1 天前
快速了解兼容 Ethereum 的 JSON-RPC 接口
开发语言·网络·rpc·json·区块链·智能合约·polkadot
devmoon1 天前
用Remix IDE在Polkadot Hub部署一个最基础的Solidity 合约(新手友好)
web3·区块链·智能合约·编译·remix·polkadot