OCAP 的三代架构:从链访问协议到 AFS

OCAP 是 ArcBlock 最早提出的概念之一。它的全名是 Open Chain Access Protocol,开放链访问协议。如果你今天从早期白皮书、一本旧书,或者我们的区块链访问层专利认识它,再去看 ARC 的架构,可能会问:当年那个统一访问不同区块链的协议,后来去了哪里?
OCAP 的演变,是同一种访问抽象在三代产品中逐步找到更合适的位置。 最初,它是应用面前的一套链访问接口;后来,它成为 Blocklet 架构里的链访问部件;今天,在 ARC 中,这项职责进入了 AFS,也就是 Agentic File System。访问对象也从区块链扩展到了文件、数据与服务。
其中的变化很大。理解这段历史,需要把一个长期的设计意图和每一代具体采用的实现方式分开看。
一个比我预想中更受欢迎的想法
我们在 2017 年设计 ArcBlock、准备最早的白皮书时,已经把 OCAP 放在架构的基础位置。在它之上还有 Blocklet,以及围绕应用开发与运行的一整套设想。在我自己看来,OCAP 是其中相对简单、也很实用的一部分:应用需要一个比较稳定的访问方式,各条链的差异交给下面的驱动,也就是适配模块处理。
但开始向外介绍项目以后,我发现,听众往往对 OCAP 最感兴趣。我们讲了很多关于平台和应用的东西,交流时大家又会回到这个访问层。这个反馈确实让我有点惊讶,也让我们在后来的介绍中给了 OCAP 更多篇幅。
现在回头想,这件事很好理解。当时 Bitcoin、Ethereum 和各种许可链有各自的接口与概念,开发者很难在开始写应用之前,就确定自己以后只需要哪一条链。多接一条链,往往意味着又要理解一套数据结构、调用方式和开发工具。大家未必马上关心我们的整个平台,但都能理解这笔重复劳动。
OCAP 想减少的就是这部分工作。我的直接启发来自 ODBC。做过 Java 的人可能更熟悉 JDBC:应用面向一种共同的连接接口,不同数据库有各自的驱动。我们想把类似的分工带到区块链应用里。这个类比并非今天为了讲历史才补上去的,早期技术白皮书已经明确提到 ODBC、JDBC 和 Chain Adapter。
知识卡片:ODBC 与 JDBC 是什么?
ODBC 是 Open Database Connectivity。它为数据库访问定义一套共同的 API,具体数据库的 driver 负责将调用交给相应的数据源。应用不必为每一种数据库另写一整套底层连接代码。
JDBC 是 Java 的数据库访问 API。Java 程序通过连接、语句和结果集等接口使用数据库,厂商提供相应驱动。它和 ODBC 解决的是相近的连接问题,但 JDBC 不要求经过 ODBC;早期存在 JDBC-ODBC Bridge,也存在直接连接数据库的 JDBC 驱动。
两者统一的是访问约定,不是把数据库内部都变成一样。数据库支持什么 SQL、怎样处理事务,仍然可能不同。参见 Microsoft 的 ODBC 说明和 Oracle 的 JDBC 介绍。
从这个出发点看,OCAP 不需要先变成另一条链,也不需要在所有链上面再造一个虚拟的 Layer 2。这里的 Layer 2 指依托底层链提供另一层交易执行或扩展的系统。我们首先要解决的是应用怎样访问链,而不是让访问接口接管链的运行。
第一代:让开发者先把链用起来
最早的实现从 Bitcoin 入手。用一个接口或软件库隔开应用与链的具体接口,在概念上已经能够表达 OCAP。但到了真正交给开发者使用时,我们选择了 GraphQL。
GraphQL 的作用很具体:客户端描述自己需要哪些字段,服务按照已经定义的类型和字段关系返回数据。查询的写法、文档与工具可以形成一套共同的体验。各条链的实现仍然放在下面,不需要为了这种体验,再从头发明一门查询语言。
GraphQL 给了我们统一表达请求的工具;链适配器负责把请求真正做出来。 即使两条链都能通过 GraphQL 访问,schema,也就是它们公开的类型与字段定义,仍然需要设计。一个叫“交易”的对象包含什么、怎样找到账户关联的记录,这些不会由 GraphQL 自动替我们决定。
2018 年 6 月 30 日,OCAP Playground 发布。开发者可以打开浏览器,在一侧写查询,在另一侧看结果,不必先搭好一套链节点环境。当年的入门文章用 Bitcoin 的创世区块带读者完成第一次查询。内部实现先从 Bitcoin 开始,而公开发布时的介绍已经提到了 Bitcoin 和 Ethereum;这是两个不同的时间点。
在开发者看到的查询界面下面,我们也做了链数据的采集、整理和索引。节点有一份账本,并不意味着它已经按每个应用想问的问题整理好了数据。要方便地查一个账户关联的记录,往往需要把原始链数据变成适合查询的结构。因此,第一代既有眼前这个 GraphQL 入口,也有支撑它的数据服务。
这一代可以概括为:应用或 Playground 发出 GraphQL 请求,OCAP 服务交给相应的链适配与索引模块,再连接 Bitcoin、Ethereum 等底层网络。下面的图表示访问依赖,不表示两条链彼此交换资产。
2018 年讨论为何选择 GraphQL 的访谈保留了团队当时的思考。它适合和 Playground 的发布、教程一起读:一篇解释选择,一篇展示产品,一篇让人实际试用。这比单看一张架构图更接近当年的 OCAP。
第二代:访问层进入应用架构
后来,我们开始实现自己的区块链。此时,一个自然的问题是:既然统一访问已经是我们希望给应用的体验,为什么不从链和开发工具的设计开始,就把它考虑进去?
Forge 是我们当时用于构建区块链的框架。在这套框架中,GraphQL 从一开始就是面向应用设计的接口之一。我们也一度把自己的链称为 OCAP Chain:访问层的设计已经进入链本身,而不只是外接的一层包装。2019 年的 Forge 介绍同时记录了 GraphQL 和 gRPC 两种接口;后者让程序远程调用服务中的操作。重视 GraphQL,并不要求系统的每一层都采用它。
理解接下来的变化,先要知道 Blocklet 是什么。它是可以部署和运行的软件单元:一个完整应用可以是 Blocklet,一个供其他应用使用的服务也可以是 Blocklet。ABT Node 提供运行和组合这些单元的环境,后来更名为 Blocklet Server。
用一个需要读取链数据的应用来比较:在第一代中,它主要连接一套独立运营的 OCAP 服务;在第二代的架构中,链访问服务本身可以成为 Blocklet,与应用需要的其他部件一起部署和组合。应用仍然会调用接口,但谁提供链数据、接入部件放在哪里,不再必须与那套独立服务绑定。这一代改变的是软件的组织和交付方式。
我在 2023 年的架构回顾里记录过这个变化:第一代基于 AWS 索引体系的 OCAP 服务,后来由基于 Blocklet 的 OCAP 部件承接。2021 年的 OCAP-JS 更新记录也能让人看到,这个名字已经出现在我们自己的资产链与 SDK 的持续开发中。它所指向的具体软件,随着产品一起演进。
对于访问外部链,系统也不必坚持所有请求都经过我们自己运营的一套索引服务。应用可以利用适合的链服务,由相应部件承担接入。谁提供底层数据、采用什么接口,是这一层内部可以调整的实现选择。统一访问的职责仍然在,承担它的模块可以更贴近应用实际需要。
这一代的关系是:Blocklet 应用使用链访问部件,部件连接 ArcBlock 的链或所需的外部链服务。它表达的是职责划分,不要求这些服务共享一个物理端点。
数据库的发展提供了一个有用的参照。使用 ORM,也就是对象关系映射工具时,应用常常主要和对象、查询模型打交道,不再到处直接写连接和取结果的代码。但这并不表示 JDBC 消失了。Hibernate 的官方文档仍然有完整的 JDBC 连接与访问说明。更高一层的工具可以把连接接口放到内部,保留它的工作,让应用在更合适的层次表达需求。
我理解 OCAP 在这个阶段的变化,也是这样。架构中的访问职责,不必永远对应一个单独摆在最外面的产品。
第三代:ARC 用 AFS 承接统一访问
到了 ARC,这个问题又扩大了。应用需要接触区块链,也需要文件、数据库和各种服务;AI agent 同样需要找到这些资源,理解它们能做什么,并在获得授权后使用它们。如果每一种资源都让调用者重新学习一套发现和访问方式,原来促使我们设计 OCAP 的问题,就会在更大的范围里出现。
ARC 是 Agentic Realm Computer。它通过 AFS(Agentic File System)组织这些资源:资源出现在有路径的树状结构中,provider 是把某一类底层系统接入这棵树的适配模块。调用者可以使用共同的列目录、读取和查询等操作,provider 再把这些操作翻译成底层系统懂得的请求。具体资源支持哪些操作,仍由其能力和权限决定。
这使得 OCAP 的想法有了一个更广的承载位置。第一代面对的是“应用怎样访问不同的链”;在 ARC 里,我们要回答的是“人和 agent 怎样访问不同的资源”。区块链成为这套资源访问体系中的一种。
这已经有一个可以具体说明的实现。ARC 的 OCAP provider 把 ArcBlock 链的数据映射到 AFS 中。以主网挂载为例,调用者可以沿着下面的结构寻找账户、交易与代币记录;实际条目以对应网络返回的数据为准:
/dev/chain/main/
accounts/
transactions/
tokens/对不熟悉文件系统抽象的读者,可以这样理解:过去,你先找一个链 API,再阅读它的调用文档;这里,你可以先发现一棵“链资源树”,列出其中的集合,再读取某条记录。树中的交易并没有因此变成本地磁盘上的普通文件,它只是取得了一种共同的地址和访问方式。
有意思的是,当前这个 provider 内部仍然可以通过 GraphQL 访问 OCAP 服务。AFS 接过了面向应用的统一访问职责,GraphQL 则可以继续完成 provider 与链服务之间的通信。同一条请求,在外面表现为读取一个路径,在里面仍然可以是一条 GraphQL 查询。这两层并不冲突。
这一代的结构是:人和 agent 在 ARC 中使用 AFS,AFS 将请求路由到相应 provider,再由 provider 连接链服务或其他资源。图中的“其他资源”表示 AFS 的共同接入方式,不表示每一种资源具有相同的读写能力。
一个访问模型,也有面向人的界面
统一的路径不只方便程序。ARC 的区块链浏览器 Chain Explorer 使用链资源及其配套的界面描述,把账户、交易等对象呈现给人;agent 则可以通过 AFS 的访问操作读取这些资源。界面展示和程序访问可以围绕同一组资源组织,不需要先维护两份互相脱节的数据模型。
这里的 AUP 是 Agentic UI Protocol,用来描述面向人的交互界面。OCAP provider 附带的 AUP 资源,让链数据的结构和合适的呈现方式能够一起提供给应用。这比第一代在独立 Playground 里试查询更进一步:链访问已经进入计算环境本身,能够被不同应用复用。
这个方向也允许我们为 Ethereum、Solana 或其他链编写相应 provider,把它们接到 AFS 中。这里说的是同一套接入方法的扩展方向;本文介绍的现有实现是 ArcBlock 链的 OCAP provider,不能由它推断所有链都已有现成支持。对使用者来说,应该看具体 provider 能列出哪些资源、执行哪些操作,而不是仅凭一张架构图判断支持范围。
共同路径不会替代链的规则
把链接进 AFS,也不意味着可以通过普通文件写入随意改写账本。当前这个 OCAP provider 提供的是链数据的只读访问。读取交易记录和发起一笔需要授权、签名并等待网络处理的交易,是不同的操作。路径让对象更容易找到,并不替任何人批准交易。
同样,Bitcoin 与 Ethereum 的账户和交易语义仍然有差别。应用可以复用访问方式,但影响业务判断的网络、确认状态和数据时点,仍然需要保留。这种边界从 OCAP 延续到了 AFS。一个好的抽象减少的是重复接入工作,不是把应用必须知道的事实也省略掉。
我觉得,ARC 在这里真正往前推进的,是让这种分工成为通用的资源访问模型。应用可以把链上记录和自己有权使用的其他资料放进同一个工作过程;agent 不必把每一种资源都当成一种全新的工具世界。资源仍有自己的能力和授权边界,但发现和访问它们可以采用共同的方法。
专利记录的是这段设计中的哪一部分
在 Publications 中,《区块链适配器、协议与访问层》对应美国授权专利 US11676139B2。这件专利与 OCAP 直接相关,来自我们对统一链访问及适配流程的设计工作。
公开文本描述了共同请求、链适配器、结构化数据以及客户端签名等具体流程,GraphQL 出现在从属权利要求中。它帮助读者理解早期 OCAP 怎样工作,但专利的法律范围仍要按具体权利要求阅读。不能把整段软件演变都压成“任何统一接口都属于这件专利”,也不能从设计思想的延续,直接推出 AFS 的法律覆盖范围。
如果你想进一步了解这些机制,《一个接口访问多条链,哪些差异不能藏?》详细讨论了查询、适配和交易签名。本文关心的是另一条线:同一种访问职责,怎样随着应用架构的变化,找到新的实现位置。
把这些材料连起来读
《区块链实战》里的 OCAP,可以放回这段演变中理解。它记录了当时我们怎样解释区块链访问;后来的文章和实现,则继续展开了这件事。旧材料无需被改写成今天的样子,新的回顾负责把时间和关系接起来。
| 想了解什么 | 对应材料 |
|---|---|
| 最初怎样定义访问层和链适配器 | 早期技术白皮书 |
| 第一代产品让人实际做什么 | Playground 发布(2018)与入门教程 |
| 为什么选择 GraphQL | 2018 年技术访谈 |
| 自有链怎样面对应用开发 | Forge 与 SDK 介绍(2019) |
| 访问职责怎样进入 Blocklet | OCAP-JS 更新(2021)与架构回顾(2023) |
| 今天怎样理解 AFS 与 provider | AFS 概览与Provider 文档 |
| 先读一个短解释 | OCAP 学习节点 |
我最初没有预料到,这个自己觉得相对简单的访问层,会成为大家认识 ArcBlock 的一个重要入口。后来它经历的变化,也让我更清楚地区分了一件事:值得长期保留的是哪项职责,哪些只是当时承载它的软件形态。
在第一代 OCAP 中,我们把这项职责做成面向链的接口。在 Blocklet 体系中,它进入可以组合的应用部件。到了 ARC,我们用 AFS 把它扩展成面向不同资源的共同访问方式。每一代都需要新的工程工作,也延续了前一代承担的访问职责。
所以,今天再问 OCAP 在哪里,我会从 ARC 的资源树讲起。沿着链的路径往下看,你仍然能找到当年那项很朴素的工作:让应用把精力花在要做的事情上,把具体怎样接入一个系统的工作,交给适合承担它的那一层。