OCAP Playground 入门指南

作者: 王仕军 (ArcBlock团队软件工程师)

如果你对区块链技术已经有基本的了解,甚至自己开发过简单的区块链应用,不知道你有没有被各种链的不同接口、不同数据格式给搞晕。更进一步,你可能会发问:有没有更开发者友好、更接近传统应用架构的区块链接入方式?

如果接入每条链都需要开发者自己运维全节点,会把很多人拒之门外,即使像互联网领域的老兵也需要耗费大量的时间和精力做重复的事情。ArcBlock 的工程师很早就开始琢磨这个问题,数月研发之后将交付支持多链数据接入的解决方案:开放链访问协议(Open Chain Access Protocol,后文简称 OCAP)。

如果你对 OCAP 服务感兴趣,或者希望用更熟悉的方式接入区块链,不妨来花 5 分钟读完本文,相信你会有所收获。本文会从开发者的视角介绍 OCAP 服务的前端界面 Playground 的基本用法。

什么是 OCAP Playground ?

使用任何技术之前,搞清楚它是什么非常有必要,那么 OCAP Playground 究竟是什么呢?可以从下面 3 个视角去定义。

1. 是 OCAP 服务的前端界面

几乎所有复杂的现代软件系统都是大后端小前端的模式,ArcBlock 的 OCAP 架构也不例外,站在用户视角所观察到的部分都只是冰山一角:

iceburg

OCAP Playground 是 OCAP 服务的小前端,是整个 OCAP 服务的可见部分。通过 Playground 开发者可以方便的探索 OCAP 服务的能力,通过交互和数据展示上的优化 Playground 能让开发者在探索过程中有所发现、有所启发,为开发者后续基于 OCAP 服务开发自己的 DApp 打好基础,称之为"试验台"再合适不过。

2. 是 OCAP 服务的实时文档

因为 OCAP 遵循 GraphQL 规范来提供所有接口,得益于 GraphQL 的单接口、强类型等特性,Playground 自然而然的成了 OCAP 服务的活的、实时的文档,开发者可以在 Playground 中浏览文档、搜索文档,并且享受查询编辑器的智能提示功能,就像是在自己熟悉的 IDE 里面编写代码。

3. 是 ArcBlock 生态中的 DApp

如果把 OCAP 服务看成是黑盒,那么整个 ArcBlock 生态中的 DApp 自然也有 Playground 的一席之地:

relationship

如何使用 OCAP Playground ?

正式使用之前,我们需要做点准备工作,在某些关键概念上达成共识,然后在上手。

开始前的准备工作

理解基本的区块链数据模型

从概念上理解某项技术能让我们更快的掌握它,几乎所有的区块链数据都会包含如下几个关键要素:

blockchain-mental-model.png

  • 账户:Account,是好比我们在在银行的户头 + 密码的组合,不论是比特币还是以太坊的账户都由地址、公钥、私钥 3 部分构成,其中地址相当于用户名,而公钥 + 私钥相当于密码;
  • 交易:Transaction,是区块链上任意两个账户之间的转账交易或者某个账户对智能合约的调用请求;
  • 区块:Block,是经由某种共识算法(如 POW、POS、DPOS)产生的包含多笔交易并且概率上不可逆转的数据块;

绝大多数把全部或部分数据存储到区块链上的 DApp 无外乎读写的就是 Account、Transaction、Block 这 3 种实体的数据,OCAP 服务的绝大部分接口也是围绕这 3 种实体提供的。

了解基本的 GraphQL 语法

OCAP 服务在做技术选型时用了 GraphQL 来作为查询语言,GraphQL 被 jQuery 之父 John Resig 誉为 The New REST ,相比传统的 REST 方式,GraphQL 在接口规范、错误定义、数据类型、参数校验、文档实时性和可交互性等方面都具有更大的优势,围绕期周围的社区也在飞速的发展,部分数字货币交易所已经开始采用 GraphQL 提供前端接口。

读到这里,可能你心里会嘀咕,如果要基于 OCAP 服务开发 DApp 岂不是要先学习下 GraphQL?事实虽如此,但你大可不必担心,GraphQL 的语法也比较简单,即使你完全没接触过,也能上手使用 Playground,在接下来的实例中你就能体会到它的直观和简洁。

在 Playground 中发起简单查询

Talk is cheap, show me the code,用浏览器打开 ocap.arcblock.io,Playground 默认界面如下,整体分左右两部分,左边是查询编辑区域,右边是结果预览区域,如果你是第 1 次访问 Playground,我们会自动填充默认的查询语句,并且在右侧展示查询结果:

playground default

怎么发起自己的查询呢?清空查询编辑区域的所有代码,输入如下查询,该查询返回的是 1 个比特币区块的数据,比特币区块的数据结构请猛击这里

{
  genesisBlock {
    hash
    size
    total
    numberTxs
  }
}

然后单击 "Run" 按钮,或者直接用快捷键 CTRL + Enter(Mac 下面请按 CMD + Enter),不出意外,右侧的结果区域会展示 JSON 格式的比特币创世区块数据:

{
  "data": {
    "genesisBlock": {
      "total": 0,
      "size": 285,
      "numberTxs": 1,
      "hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
    }
  }
}

可以看到创世区块的 hash 为 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f,里面仅包含 1 笔交易。

恭喜你,到这里,你已经在 OCAP Playground 成功发起第 1 个查询!

在 Playground 中发起复杂查询

好奇的你可能会问,比特币创世区块里面到底有没有交易数据?如果有,是发给谁的?发了多少?网传中本聪在创世区块给自己创造了 50 个比特币是真的么?

接下来我们就自己动手验证下。对于这样的查询场景,我们可以发起单个查询把需要的创世区块数据全部拿出来,而没有任何冗余,绝大部分现存区块链数据查询服务都会返回全量数据,在区块很大的情况下会拖慢应用的性能。

修改查询语句如下,你也可以尝试手动键盘输入如下查询,体验查询编辑器的字段智能提示:

{
  genesisBlock {
    hash
    size
    total
    numberTxs
    transactions {
      data {
        hash
        total
        inputs {
          data {
            account
            value
          }
        }
        outputs {
          data {
            account
            value
          }
        }
      }
    }
  }
}

该查询增加了交易及相关字段的查询(完整的比特币交易数据结构猛击这里),执行该查询,拿到如下结果:

{
  "data": {
    "genesisBlock": {
      "transactions": {
        "data": [
          {
            "total": 5000000000,
            "outputs": {
              "data": [
                {
                  "value": 5000000000,
                  "account": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
                }
              ]
            },
            "inputs": {
              "data": [
                {
                  "value": 0,
                  "account": null
                }
              ]
            },
            "hash": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
          }
        ]
      },
      "total": 0,
      "size": 285,
      "numberTxs": 1,
      "hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
    }
  }
}

不难看出,比特币的创世区块确实只有 1 笔交易,该笔交易产生了 50 个比特币(比特币的最小单位是聪,10^8聪 = 1BTC),而这 50 个比特币发送给了地址为 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa 的账户,那这个账户里的比特币到现在有没有被花掉呢?

可以使用 OCAP 提供的 transactionsByAddress 继续深挖!

使用 Playground 的表格视图(Table)

我们找到了中本聪的比特币账户,该账户跟哪些账户有过交易?转入了多少?转出了多少?这些都可以使用 OCAP 服务提供的接口搞定。

比如,可以使用如下查询去探究该账户究竟有没有花掉里面的比特币:

{
  transactionsByAddress(sender: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa") {
    data {
      hash
      total
    }
  }
}

得到的结果是:

{
  "data": {
    "transactionsByAddress": {
      "data": []
    }
  }
}

显然,创世区块产生的比特币没有任何转出,那创世区块之后,还有没有人往这个账户里面转账呢?可以使用如下查询去探究:

{
  transactionsByAddress(receiver: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa") {
    data {
      hash
      total
    }
    page {
      cursor
      total
      next
    }
  }
}

因为按账号查询交易可能会包含很多条数据,为保证性能,OCAP 内置了分页功能,每页默认是 10 条,开发者可以通过添加 page 字段可以拿到总条数,查询结果如下:

{
  "data": {
    "transactionsByAddress": {
      "page": {
        "total": 1252,
        "next": true,
        "cursor": "pU7180SPAj6PCYTB1r%2BCHg%3D%3D"
      },
      "data": [
        {
          "total": 2267721,
          "hash": "256add784c8975fb357010b1b21539a5e55c25af231870616675ff757c5a64f5"
        },
        ...
      ]
    }
  }
}

可以看到中本聪的账号总共有 1252 笔转入操作,如果你愿意,请自行查询每笔转入操作的数量和转入方。

为方便开发者快速预览数据,Playground 会智能的探测列表型的查询结果,并将其渲染成表格形式:

playground table

同时,为了方便开发者从表格视图中得到更多有价值的信息,对表格中的字段展示也做了大量的优化:

  • 比如转账金额会转换为人类可读的格式;
  • 区块 HASH、账户地址、交易 HASH 都会会转换成链接,单击后会跳转到区块浏览器;
  • 提供略缩图和完整视图两种模式,单击表格右上角的按钮能展开;

如果查询的结果中包含嵌套的多层数据,比如 transaction 下面包含 input 和 output,或者 block 下面包含多个 transaction,且每个 transaction 里面有自己的 input 和 output,同样也能在表格视图下很好的展示出来,不信?你可以在表格视图尝试执行下节中的查询。

使用 Playground 的图形视图(Chart)

有句话叫做,文不如表,表不如图,ArcBlock 工程师在开发 Playground 的数据可视化时也下了非常多的功夫,比如下面这个查询会返回所有包含了转入到中本聪比特币账户的交易列表:

{
  transactionsByAddress(receiver: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa") {
    data {
      hash
      total
      inputs {
        data {
          account
          value
        }
      }
      outputs {
        data {
          account
          value
        }
      }
    }
    page {
      cursor
      total
      next
    }
  }
}

区块链是天然的分布式网络,网络中的数据流动使用 Sankey Diagram 来可视化再合适不过了,网络节点就是账户,而交易金额的大小和流向就是网络中的流,在查询结果区域切换到 Chart 模式,在图表类型种选择 Sankey 得到下图:

playground sankey

不难看出,给中本聪账户(上图右下角红框里面那个)转账的交易全部都是小额交易,大概率是社区的人在向他捐赠。

如果你在 Playground 使用过程中发现了比较有趣的 Sankey Diagram,欢迎截图发给我!

Playground 还支持哪些查询?

读到这里可能有同学会问,上面的例子从头到尾都在说比特币,说好的多链支持呢?如果你实际动手去用了 OCAP Playground,相信你已经发现了如何切换不同的链:Playground 支持以选项卡的形式创建多个查询,每个查询都可以选择不同的链,切换连的按钮在每个选项卡的左上角。

不同链支持的查询几乎是相同的,比如下列查询类型对以太坊和比特币都是支持的,只不过字段可能会稍有不同。

  • blockByHeight,按块高查询区块数据
  • blockByHash,按 HASH 查询区块数据
  • blocksByHeight,按块高范围查询区块列表
  • transactionByIndex,查询特定块里面的特定交易
  • transactionsByIndex,查询特定块里面的所有交易
  • transactionByHash,按交易 HASH 查询交易数据
  • transactionsByAddress,按账户查询交易列表
  • accountByAddress,按地址查询账户详情

各种 TOKEN 代币是以太坊生态的重要组成部分,也在以太坊区块链上产生了大量的数据,根据 TOKEN 名称去查询相关的转账记录也是支持的:transactionsByToken,是不是很方便?

如果你在查询过程中发现了问题该怎么办?不用担心,OCAP 服务在后端记录了日志,所有失败的查询我们都会集中时间去排查原因,并尽快修复。

结语

Playground 可以做的更好用?对我们的服务有建议?使用时发现了问题?欢迎在开发者社群中反馈,或者直接微信联系我:feweekly。

区块链时代的大幕已经开启,相信读到这里的你也会成为推动区块链技术落地、普及的重要力量,与其冷眼旁观,不如深度参与其中。