Skip to content
On this page

L1-4: Custom Stream(高级流支付)

1. 问题

在 ETH Streaming 基础上创建更高级的流支付系统,支持多接收者、多流管理、流取消等功能。

2. 原因

基本 ETH Streaming 只支持单一 ETH 流。实际应用中需要:

  • 管理多个并发流
  • 支持 ERC20 代币流(不仅是 ETH)
  • 流生命周期管理(创建、取消、资金回收)

3. 方案

架构设计

solidity
struct Stream {
    address token;              // ERC20 代币地址 (address(0) = ETH)
    uint256 cap;                // 单次最大可提取量
    uint256 unlockTime;         // 完整解锁周期
    uint256 timeOfLastWithdrawal;
    uint256 remainingBalance;   // 该流剩余总预算
}

多流管理

  • streamId 标识每个流
  • streamId → recipient → Stream 双层映射
  • 每个流独立追踪预算和解锁状态

流生命周期

  1. createStream(token, totalBudget) — 创建并注资
  2. addRecipient(streamId, recipient, cap, unlockTime) — 添加接收者
  3. withdraw(streamId, amount) — 接收者提取
  4. cancelStream(streamId) — 所有者取消流

4. 遇到的陷阱

4.1 remainingBalance 和 cap 的混淆

cap 是每次解锁周期的最大可提取量(会随时间恢复),remainingBalance 是该接收者的总预算(不会恢复)。

4.2 取消后未阻止提款

流取消后如果不清除 activeStreams 标记,接收者仍可能提款。

5. 陷阱的原因

5.1

cap 按时间解锁模型运作(同 L1-3),而 remainingBalance 是固定预算上限。两者需要分别处理:withdraw 中先检查 unlocked(时间维度),再检查 remainingBalance(预算维度)。

5.2

流取消修改内部状态后,需要在 withdraw 入口检查 activeStreams[streamId]

6. 如何解决陷阱

solidity
if (amount > unlocked) revert InsufficientUnlockedBalance();
if (amount > stream.remainingBalance) revert InsufficientStreamBalance();

7. 技术要点

要点说明
多流架构streamId + 双层映射
预算 vs 速率remainingBalance (总量) vs cap (速率)
流生命周期create → fund → addRecipient → withdraw → cancel
可扩展性每种流可配置独立的 unlockTime

Built with AiAda