开发者:从交换原语到个人市场
在 ArcBlock 上构建一个去中心化市场,不必先复制 Uniswap,也不必先复制一家 CEX 的订单簿。更小、也更能验证架构的起点,是让两个已经找到彼此的人,用各自控制的工具谈妥条件、授权并完成一笔交换,再把“找到彼此”逐步开放。
这篇面向准备动手的开发者。Exchange、交易签名和 DID 有公开文档;下面的个人市场 Blocklet、报价消息和代理流程是建议的应用设计,不是一个现成 SDK 的安装教程。它们需要实现、测试和审计,才能成为用户可运行的软件。
从双方已知的交换开始
假设 Alice 拥有一项可转让资产,Bob 愿意用某种 token 交换。第一版只需要支持明确的资产类型、一条结算链和已知的接收方。报价可以经双方认可的通信渠道送达,甚至先由人确认。此时不做公开订单簿,不是功能不完整,而是把最重要的授权和交割先做正确。
ArcBlock 的公开 SDK 文档给出 prepareExchange → finalizeExchange → exchange 流程:一方构造并签署,另一方检查内容后补签,提交到链上。具体结构和 API 示例见协议技术篇及 SDK 交易 API。钱包对象应留在对应持有人的信任边界内;示例里出现两个 wallet 变量,并不意味着市场服务要收集两个人的私钥。
这一版要验证的不只是成功路径。余额不足、资产已经转走、对手替换接收者、重复提交、用户取消、网络中断后恢复,都会决定应用是否真正可靠。链上确认前不能把界面显示的“签名成功”当作“成交成功”。如果交易可能已经提交,恢复时先查询结果,再决定下一步,不能盲目重发。
把市场会话做成用户能带走的状态
已知对手的交换成立之后,才值得加入发现与谈判。Blocklet 可以把界面、状态处理与协议适配封装为可部署软件;部署出来的节点不必全部连到开发者经营的唯一后台。DID 用于识别节点、用户与代理,并验证授权关系;DID 本身不证明交易信誉或法律资格。
一个可实现的分工如下。这里列的是模块职责,不是已有组件清单。
| 模块 | 放什么 | 不应默认拿到什么 |
|---|---|---|
| ArcSpace 中的私有状态 | 用户偏好、预算、会话、完整报价、收据 | 不向公开索引复制底价与资产清单 |
| 发布与发现服务 | 可公开的意图摘要、端点、有效时间 | 无权修改用户规则或替用户成交 |
| 个人 Agent | 搜索、询价、比较、提出交易组合 | 不持有无限制资金授权 |
| 确定性检查与钱包 | 资产标识、数量、费用、签名范围 | 不相信自然语言可以覆盖签名内容 |
| 结算适配器 | ArcBlock 交易或其他链的合约/程序调用 | 不把跨链原子性交给界面承诺 |
市场会话需要自己的标识与状态;它不等于链上交易。一个会话可以产生多次报价,最终没有成交;一份成交协议也可能经历提交失败和恢复。下面是供应用设计讨论的状态机,不是 ArcBlock 链的交易类型:
DRAFT → PUBLISHED → NEGOTIATING → AGREED → AUTHORIZED
↓
SUBMITTED → SETTLED
↓
RECONCILING
签名前:可撤回意图、拒绝报价、结束会话
签名后:撤销是否有效,取决于结算协议的 nonce / cancellation 机制
提交后:先确认链上结果,再更新会话和剩余数量持久化的价值,是用户换一个界面、代理重启或网络恢复后,仍能知道自己承诺过什么。私有谈判内容只向必要参与者开放;公开索引中的旧摘要即使仍可读,也不能成为执行一份已撤销协议的授权。
先定义消息,再接入 Agent
一种最小应用消息可以包含以下字段。它是拟议的市场协议草图,不是可直接发送到链的交易 JSON,也不是已经发布的 ARC API。
{
"version": "market-intent-example/1",
"intentId": "local-unique-id",
"publisherDid": "<publisher DID>",
"contactEndpoint": "<authenticated messaging endpoint>",
"give": [{"chain": "<chain ID>", "asset": "<asset ID>", "maxAmount": "<integer units>"}],
"receive": [{"asset": "<asset ID>", "minAmount": "<integer units>"}],
"validUntil": "<UTC timestamp>",
"credentialPolicy": "<policy reference>"
}设计实现时,还需规范字段编码、签名域、消息身份验证、重复消息处理和撤回规则。validUntil 是应用声明,不会凭空变成所有结算链都执行的约束。最终签名必须绑定选定链、资产、数量、对手、费用与可执行的有效期或撤销机制。不能把公开的“我大概想卖”直接升级为“任何人都能动我的钱”。
发现服务也不必只有一种。起步时可以用联系人、小型目录或专业报价源,逐步开放多个可替换的索引器。索引器需要新鲜度、反垃圾和访问控制;一个可替换的专业服务,比一个名为 P2P、实际永远依赖唯一网关的服务更容易说清楚。
Agent 收到的应该是可校验的报价,不只是聊天文字。它可以比较 direct P2P、AMM、做市商和 solver,也可以按用户要求考虑隐私与等待时间。但金额计算、最低接收量、允许的接收者和签名检查应由确定性代码执行。对手发来的提示词是消息数据,不具有修改代理规则的权限。
结算层可以更换,但不能隐藏差异。ArcBlock 的原生交易适合其支持的资产组合;Ethereum 可以使用通用结算合约与双方签名;Solana 可以通过程序组织原子转移。跨链选择篇讨论的是选择不同结算链,而不是承诺一次调用自动完成跨链交换。
软件边界也是经营边界
把应用做成可部署 Blocklet,可以让开发者发布软件,让用户保留自己的状态和授权。这种技术分工有助于明确谁控制什么,但不会自动免除开发者或部署者的法律责任。
| 实际行为 | 架构上应明确的事实 | 需要进一步判断的法律问题 |
|---|---|---|
| 发布通用软件供他人运行 | 谁持有密钥,是否依赖作者后台 | 持续维护、控制和商业安排是否改变角色 |
| 用户的代理仅代表用户本人 | 权限、利益归属、是否接受第三方订单 | 本人交易与经常性经营的边界 |
| 运营公共报价、路由或撮合服务 | 谁选择对手、协商条件、收取什么费用 | 经纪、交易设施、支付及其他适用规则 |
| 托管资金或管理可动用资金的权限 | 谁能转移资产、冻结、退款或升级 | 托管、资金传输、客户资产与 AML 义务 |
“自己部署”是一种部署方式,不是一种牌照。特别是替别人自动谈判、接单或路由时,不能仅因为界面非托管,就把所有行为放进美国 SEC 关于特定自托管界面的 staff statement 范围。不同司法辖区看的是具体活动;法律篇把这些区别展开。
合规可以进入交易条件:卖方要求认可发行者签发的资格凭证,代理先检查有效期和撤销状态,再决定是否继续谈判。DID/VC 可以减少重复交出完整证件的需要;选择性披露或零知识证明还需要合适的凭证格式与验证实现。它们不能保证来源资金干净,也不能替经营者决定自己的法定义务。
第一阶段做对手明确的交换,第二阶段开放可替换的发布与发现,再加入受约束的个人代理,是一条可以逐步验证的建造路线。更复杂的流动性池、自动报价或公共市场,应当在确有需求、资金风险和经营责任都被理解后增加。最终交给用户的价值,不是一个与交易所相似的界面,而是能够理解、迁移和撤回授权的市场参与能力。