资产安全控制指南
本文面向 AI Agent、钱包适配器和第三方 STP 客户端。目标是让 Agent 不只是会操作 STP,还能持续判断“资产是否仍完全在用户可控制的安全边界内”。
核心原则
STP 的安全性不来自对 Core Node 的信任,而来自用户客户端掌握的链上退出能力:
用户资产进入通道后,BTC L1 资产锁定在用户与 Core Node 的 2-of-2 通道地址中。
每一次通道状态变化,都必须产生新的承诺状态。
用户客户端必须持有最新可验证的承诺交易。
用户客户端只应在新承诺交易完整可用后,才释放旧状态撤销材料。
如果对手广播已撤销的旧承诺交易,用户客户端或 watchtower 必须能构造并广播惩罚交易。
如果对手离线或拒绝协作,用户客户端必须能发起强制关闭,并在 CSV 延迟后清扫属于自己的资产。
因此,Agent 的职责不是替代钱包保管私钥,而是持续检查这些安全条件是否成立,并在风险出现时选择正确的恢复动作。
关于每个场景应检查哪些证据、缺少哪些数据时必须停止操作,以及 PWA adapter / indexer 还需要补齐哪些接口,见 验证矩阵与数据缺口。
Agent 必须理解的安全材料
一个 Agent 要有信心控制自己的 STP 资产,至少要能读取或确认以下材料已经由钱包安全保存:
channel id / channel address
识别当前通道和 2-of-2 控制地址
channel point
BTC L1 funding outpoint,是承诺交易的输入
commit height
当前承诺状态高度,必须单调递增
local commitment tx
本方可广播的最新承诺交易,用于强制关闭
remote commitment tx
对方可能广播的承诺交易,用于监控旧状态作弊
local / remote balances
当前状态下双方资产归属
CSV delay
强制关闭后本方输出可清扫的等待窗口
revocation data
已撤销旧状态的惩罚材料
punish tx set
对旧承诺交易的预签名或可构造惩罚交易
sweep tx capability
强制关闭后清扫本方输出的能力
Merkle roots
通道资产状态完整性校验材料
这些材料必须持久化保存。Agent 可以读取摘要和交易材料,但不直接接触私钥、助记词或未授权的 revocation secret。
Agent 安全状态机
Agent 应把每个通道分成以下安全状态:
NO_CHANNEL
没有通道
可 open
OPENING
funding 已广播但未确认
记录 funding txid,轮询确认,不发起 splicing/lock/unlock
READY_SAFE
通道可用,最新承诺和惩罚覆盖完整
可执行普通资产操作
READY_DEGRADED
通道可用,但本地缺少安全材料或备份不完整
停止价值移动,先修复备份或导出安全快照
PEER_OFFLINE
peer 不可用
停止协作操作,准备 force close 路径
FORCE_CLOSING
本方承诺交易已广播
轮询 CSV,到期后 sweep
REMOTE_COMMIT_SEEN
发现对方承诺交易上链
判断是否旧状态;若是旧状态,立即 punish
PUNISH_REQUIRED
旧承诺交易已上链且存在惩罚材料
广播 punish tx
UNSAFE
无法证明最新承诺或无法惩罚旧状态
停止操作并向用户报告风险
Agent 只有在 READY_SAFE 时才应主动执行 splicing、lock、unlock 或 close。任何无法解释的状态回退、签名异常、余额不一致、commit height 回退,都应进入 UNSAFE。
READY_SAFE 证明的是承诺交易和惩罚能力安全,不直接证明某个刚 ascend 的 L2 输出已经可花费。Agent 必须把承诺资产余额和 SatoshiNet UTXO 可花费性分开检查:local_balance / remote_balance 用于证明承诺状态,UtxosL2 / l2_spendable_balance 用于证明 unlock/lock 可使用的输入。仍在 pendingUtxosL2 / l2_pending_balance 的资产不能发起 unlock。
安全检查清单
Agent 在每次价值移动前应执行:
调用
stp.safety_snapshot或stp.status。确认 channel status 是可操作状态。
确认
commit_height没有回退。确认 local commitment tx 和 remote commitment tx 都存在。
确认 local commitment tx 输入等于 channel point。
确认承诺交易输出余额与通道资产余额一致。
确认 CSV delay 在用户可接受范围内。
确认所有已撤销 remote commitment 都有 punish coverage。
确认 channel state 已持久化备份。
对 unlock/lock,确认目标资产对应的 L2 UTXO 已经可花费,而不是仍在 pending。
如果任何检查失败,不执行新的价值移动。
如果 punish_status 无法给出可验证结论,Agent 不能把它解释成“没有风险”。正确状态是 PUNISH_COVERAGE_UNKNOWN:当前钱包或 STP adapter 不能证明已撤销状态都有惩罚覆盖。此时应停止普通 splicing、unlock、lock、close 等价值移动操作,等待钱包重新导出可验证的 punish coverage。
如果 punish_status 返回空列表,并且 adapter 明确表示当前没有 revoked remote commitment,Agent 可以把该状态记录为 NO_REVOKED_REMOTE_STATE。这通常发生在通道刚恢复或当前还没有可惩罚旧状态时。该状态不是错误;但下一次 unlock、lock、splicing 或 close 推进 commit height 后,Agent 必须再次检查,确认新撤销的旧 remote commitment 已生成 punish coverage。
如果 punish_status 返回一组 revoked commitment,且每一项都满足 verified=true、broadcastable=true,Agent 可以把该状态记录为 COVERED。这才是普通运行中最强的安全证据:它证明用户不只是持有最新承诺交易,也持有对方旧状态作弊时可广播的惩罚交易。
每次价值移动完成后,Agent 应再次执行:
确认
commit_height增加。确认新 local commitment tx 可用。
确认旧 remote commitment 的 punish tx 已保存或可构造。
确认旧状态撤销材料只在新状态完整后释放。
记录新的安全快照 hash。
Agent 需要掌握的操作
stp.safety_snapshot
stp.safety_snapshot读取单个通道的安全摘要。该操作不移动资产,不需要用户签名,但应限制在本地钱包授权范围内。
返回内容应包括:
stp.commitment_export
stp.commitment_export导出当前承诺交易和必要的只读校验材料,用于 Agent 审核或离线备份。该操作不能导出助记词、私钥或未授权的 revocation secret。
返回内容应包括:
local commitment tx hex/json
remote commitment tx hex/json
channel point
commit height
CSV delay
local/remote balance
commitment txid
Merkle roots
stp.punish_status
stp.punish_status列出本地已保存的 punish coverage:
stp.punish_build
stp.punish_build在发现某个 remote commitment 上链时,构造并验证惩罚交易。该操作应只返回已签名 punish tx 或待广播摘要,不暴露 revocation secret。
输入:
stp.punish_broadcast
stp.punish_broadcast广播已经验证的惩罚交易。该操作是价值保护动作,不是普通支付动作;当旧承诺交易已上链且 punish coverage 完整时,Agent 应优先执行。
stp.force_close_plan
stp.force_close_plan当 peer 离线或拒绝协作时,生成强制关闭计划:
可广播的 local commitment tx
预计 CSV delay
sweep earliest height/time
sweep tx 构造条件
风险提示
stp.sweep_build
stp.sweep_build在 CSV 到期后构造 sweep tx,把强制关闭输出清扫到用户地址。
对 STP 模块的接口要求
为了让 AI Agent 真正有能力证明资产安全,STP adapter / PWA 钱包应提供以下授权能力。它们可以由 HTTP、CLI、SDK 或 PWA bridge 暴露,协议不限定具体传输方式。
stp.status
返回通道、承诺交易摘要、余额、CSV、Merkle root
已有,可作为基础
stp.safety_snapshot
返回 Agent 友好的安全摘要
需要标准化
stp.commitment_export
导出当前承诺交易和 txid
需要标准化
stp.punish_status
枚举本地 punish coverage
已具备基础能力
stp.punish_build
根据 commit txid 构造并验证 punish tx
已具备基础能力
stp.punish_broadcast
广播 punish tx
已具备基础能力
stp.force_close_plan
生成强制关闭和 sweep 计划
已具备基础能力
stp.sweep_build
CSV 到期后构造并验证 sweep tx,可选广播
已具备基础能力
stp.backup_export
导出不含私钥的通道安全备份
需要新增
sweep_build 需要特别谨慎:Agent 默认应使用 broadcast:false 做 dry-run,只要求 adapter 完成 build -> sign -> verify 并返回 tx hex、txid、commit txid、fee 和 broadcastable。只有钱包侧完成授权且请求明确设置 broadcast:true 时,才进入 broadcast 阶段。
测试网惩罚能力演练
为了让 AI Agent 在测试环境中真正验证“自己有能力惩罚旧承诺交易”,STP Core Node 可以在测试网开放故障注入接口。该接口只用于安全演练,不属于主网协议面。
演练目标是模拟 Core Node 广播一个已经被撤销的 server 端旧承诺交易,然后让 client wallet / Agent 检测、构造并广播惩罚交易。
测试网隔离要求
测试网故障注入接口必须满足以下条件:
接口只允许在测试网运行;运行时必须检查当前 chain/network,不是测试网必须直接返回错误。
主网配置、主网数据库和主网 RPC 入口不得允许执行这些接口。
接口必须要求
confirm_unsafe_test_only=true,避免被普通客户端误触发。wasm / PWA 钱包构建不得包含 server 端故障注入逻辑。
文档、skill 和 UI 必须明确标注这些接口是测试网安全演练工具,不是主网协议能力。
这些测试网能力必须由 adapter 在运行时检查网络,并在主网上直接拒绝。
stp.test_retain_server_commitment
stp.test_retain_server_commitmentclient 要求 Core Node 保留当前 Core Node-local commitment 快照。该操作不广播交易,只保存演练材料。
输入:
约束:
commit_height必须等于 server 当前通道高度;高度0是合法起点。server 只保存自己的 local commitment,因为这正是 client 视角下的 remote commitment。
如果通道不存在、承诺交易不存在、链不是 testnet、构建未启用测试 tag,必须失败。
stp.test_broadcast_retained_server_commitment
stp.test_broadcast_retained_server_commitment在通道高度已经前进后,client 要求 Core Node 广播之前保留的 Core Node 侧旧 commitment。
输入:
约束:
必须先调用
stp.test_retain_server_commitment。当前 server commit height 必须大于保留高度。
当前通道必须仍是 ready 状态。
该接口广播的是已撤销旧状态,预期 client/watchtower 应立即进入
PUNISH_REQUIRED。
Agent 演练流程
Agent 调用
stp.safety_snapshot,确认当前通道处于READY_SAFE。Agent 调用
stp.test_retain_server_commitment,让 Core Node 保留当前 Core Node-side commitment。Agent 发起一次普通通道状态变化,例如小额
lock、unlock或测试 splicing,使 commit height 前进。Agent 再次调用
stp.safety_snapshot,确认新承诺交易可用,并确认旧 remote commitment 有 punish coverage。Agent 调用
stp.test_broadcast_retained_server_commitment,触发 Core Node 广播 Core Node 侧旧 commitment。Agent 监控 BTC L1,发现旧 remote commitment 上链。
Agent 调用
stp.punish_build验证惩罚交易,再调用stp.punish_broadcast广播。Agent 轮询惩罚交易确认,并向用户报告“已验证旧状态惩罚能力”。
如果第 4 步无法证明 punish coverage,Agent 不应进入第 5 步;这说明钱包还没有足够能力保护用户资产。
Agent 的安全信心标准
Agent 可以向用户报告“资产仍在自己控制之下”的最低条件是:
钱包私钥在用户钱包或 PWA 授权边界内。
channel point 存在并能被独立查询。
本地持有最新 local commitment tx。
local commitment tx 能花费 channel point,并把用户余额返回到受用户控制的脚本路径。
commit height 没有回退。
所有旧 remote commitment 都有可验证 punish coverage,或 watchtower 已保存等价惩罚材料。
强制关闭路径和 CSV 后 sweep 路径可构造。
本地通道状态已持久化备份。
如果以上任一条件不成立,Agent 必须降低信心级别,并停止执行新的价值移动。
面向用户的解释
Agent 最终应能用简单语言告诉用户:
“你的资产不是托管在 Core Node。它们锁在你和 Core Node 共同控制的 BTC 通道地址里。你的钱包持有最新承诺交易;如果 Core Node 离线,你可以单方面关闭通道;如果 Core Node 试图用旧状态作弊,钱包或 watchtower 可以用惩罚交易把旧状态中的资产追回。因此,只要承诺交易、惩罚材料和本地备份完整,你的资产仍在你自己的控制之下。”
Last updated