From 7df3be14d6d7e7eb665571babb6ba86ec28e6a39 Mon Sep 17 00:00:00 2001 From: imuge Date: Mon, 2 Aug 2021 17:24:59 +0800 Subject: [PATCH] update docs --- README.md | 141 +- .../src/main/resources/docs/api_doc_cn_1.3.MD | 1716 ------------ .../src/main/resources/docs/api_doc_cn_1.3.html | 2665 ------------------ .../src/main/resources/docs/api_doc_cn_1.4.MD | 2619 ------------------ .../src/main/resources/docs/code_example.MD | 361 --- .../resources/docs/design_contract-dev-manual.md | 436 --- docs/api.md | 2924 ++++++++++++++++++++ docs/block.md | 80 + docs/cli/keys.md | 120 + docs/cli/participant.md | 219 ++ docs/cli/query.md | 914 ++++++ docs/cli/tx.md | 531 ++++ docs/contract.md | 549 ++++ docs/data_account.md | 63 + docs/event.md | 185 ++ docs/gateway.md | 53 + docs/images/deployment.jpg | Bin 131011 -> 0 bytes docs/images/deployment.png | Bin 298018 -> 0 bytes docs/indexer.md | 15 + docs/jdchain_cli.md | 30 + docs/kvdb.md | 365 +++ docs/log.md | 19 + docs/participant.md | 253 ++ docs/project.md | 56 + docs/quick_start.md | 52 + docs/samples.md | 45 + docs/scripts/testnet.sh | 278 ++ docs/sdk.md | 295 ++ docs/structure.md | 200 ++ docs/transaction.md | 478 ++++ docs/user.md | 129 + 31 files changed, 7893 insertions(+), 7898 deletions(-) delete mode 100644 deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.3.MD delete mode 100644 deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.3.html delete mode 100644 deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.4.MD delete mode 100644 deploy/deploy-gateway/src/main/resources/docs/code_example.MD delete mode 100644 deploy/deploy-gateway/src/main/resources/docs/design_contract-dev-manual.md create mode 100644 docs/api.md create mode 100644 docs/block.md create mode 100644 docs/cli/keys.md create mode 100644 docs/cli/participant.md create mode 100644 docs/cli/query.md create mode 100644 docs/cli/tx.md create mode 100644 docs/contract.md create mode 100644 docs/data_account.md create mode 100644 docs/event.md create mode 100644 docs/gateway.md delete mode 100644 docs/images/deployment.jpg delete mode 100644 docs/images/deployment.png create mode 100644 docs/indexer.md create mode 100644 docs/jdchain_cli.md create mode 100644 docs/kvdb.md create mode 100644 docs/log.md create mode 100644 docs/participant.md create mode 100644 docs/project.md create mode 100644 docs/quick_start.md create mode 100644 docs/samples.md create mode 100644 docs/scripts/testnet.sh create mode 100644 docs/sdk.md create mode 100644 docs/structure.md create mode 100644 docs/transaction.md create mode 100644 docs/user.md diff --git a/README.md b/README.md index e3d7ced6..9abdf8f5 100644 --- a/README.md +++ b/README.md @@ -1,128 +1,67 @@ -[TOC] -#JD区块链 +![logo](http://storage.jd.com/jd.block.chain/jdt-jdchain.png) +
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.jd.blockchain/sdk-pack/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.jd.blockchain/sdk-pack/) [![Build Status](https://travis-ci.com/blockchain-jd-com/jdchain.svg?branch=master)](https://travis-ci.org/blockchain-jd-com/jdchain) +
+一个面向企业应用场景的通用区块链框架系统,能够作为企业级基础设施,为业务创新提供高效、灵活和安全的解决方案。 +## 源码构建 ------------------------------------------------------------------------- +`JD Chain`源码通过`git`及`git submodule`进行管理,如下操作可快速构建: -## 一、项目介绍 -JD Chain 的目标是实现一个面向企业应用场景的通用区块链框架系统,能够作为企业级基础设施,为业务创新提供高效、灵活和安全的解决方案。 - - -## 二、部署模型 - -JD Chain 主要部署组件包括以下几种: - -- 共识节点 - - 共识节点即参与共识的节点,这是系统的核心组件,承担了运行共识协议、管理账本数据、运行智能合约的职责。 - - 一个区块链网络由多个共识节点组成,共识节点的数量范围由选择的共识协议决定。 - - 共识节点和账本是两个不同的概念,共识节点是个物理上的概念,账本是个逻辑上的概念。JD Chain 是一个多账本区块链系统,一个共识节点上可以装载运行多个账本。账本是数据维度的独立管理单元。共识节点和账本的关系,就像关系数据库系统中,数据库服务器和数据库实例的关系。 - - 共识节点通常都部署在参与方的内部网络中,通过由网络管理员指定的安全的网络出口与其它的共识节点建立通讯连接。 - - 共识节点在形态上是服务器中的一个处理进程,背后需要连接一个本地或者内网的NoSQL数据库系统作为账本的存储。当前版本,共识节点目前是单进程的,未来版本将实现多进程以及多服务器集群模式。 - -- 网关节点 - - 网关节点是负责终端接入的节点,负责终端连接、协议转换、交易准入、本地密码运算、密钥管理等职责。 - - 网关节点是一种轻量节点,需要绑定一个特定参与方的密钥对,连接到一个或多个共识节点。 - - 网关节点向共识节点的连接是需要通过认证的,绑定的参与方的密钥对必须事先已经注册到区块链账本中,且得到接入授权。 - -- 终端 - - 终端泛指可以提交交易的客户端,典型来说,包括人、自动化设备、链外的信息系统等。 - - 终端只能通过网关节点来提交交易。终端提交的交易需要用体现该终端身份的私钥来签署,产生一份电子签名。随后当交易提交给网关节点时,网关节点需要在把交易提交到共识节点之前,对交易请求以网关节点绑定的私钥追加一项“节点签名”。 - - -- 备份节点 - - 仅对账本数据提供备份,但不参与交易共识的节点。(注:目前版本中尚未实现,将在后续版本中提供) - - -![](docs/images/deployment.jpg) +```bash +$ git clone https://github.com/blockchain-jd-com/jdchain.git jdchain +$ cd jdchain -## 三、构建源代码 +# 此处仅以 master 分支为例,正常情况下 master 分支可无障碍构建成功 +# 不推荐使用 develop 分支,submodule 代码可能未对齐 +# 推荐切换到具体已发布的版本分支 +$ git checkout master -1. 安装 Maven 环境 +$ chmod +x build/*.sh - JD Chain 当前版本以 Java 语言开发,需要安装配置 JVM 和 Maven,JDK 版本不低于1.8 。(没有特殊要求,请按标准方法安装,此处不赘述) - -2. 安装 Git 工具 - - 为了能够执行 git clone 命令获取代码仓库。 (没有特殊要求,请按标准方法安装,此处不赘述) - -3. 项目库说明 +# 执行完整的构建,包括执行”集成测试“和”打包“两部分;提供两个参数: +# --skipTests :跳过集成测试部分; +# --update :从远程仓库更新子模块。注意,采用此参数会导致子模块本地仓库丢失尚未 commit 的代码。 +# 不附带此参数的情况下不会更新子模块仓库。 +$ build/build.sh --update -JD Chain 源代码包括 3 个代码仓库 +# 跳过子模块代码更新和集成测试,直接编译和打包; +$ build/build.sh --skipTests -- jdchain 项目库: - - URL:git@github.com:blockchain-jd-com/jdchain.git - - 说明:主项目库,包含说明文档、示例代码,用于集成构建和打包; - - #### `主项目库包含以下 6 个子模块仓库,通过执行脚本 <主项目库根目录>/build/build.sh 便可以一键完成子模块的下载和整体的编译、测试和打包操作.` +# 首次代码拉取,跳过继承测试编译打包可执行: +build/build.sh --update --skipTests +``` -- project 项目库: - - URL:git@github.com:blockchain-jd-com/jdchain-project.git - - 说明:公共的父项目,定义公共的依赖; -- framework 项目库: - - URL:git@github.com:blockchain-jd-com/jdchain-framework.git - - 说明:框架源码库,定义公共数据类型、框架、模块组件接口、SDK、SPI、工具; -- core 项目库: - - URL:git@github.com:blockchain-jd-com/jdchain-core.git - - 说明:模块组件实现的源码库; -- explorer 项目库: - - URL:git@github.com:blockchain-jd-com/explorer.git - - 说明:相关产品的前端模块的源码库; -- libs/bft-smart 项目库: - - URL:git@github.com:blockchain-jd-com/bftsmart.git - - 说明:BFT-SMaRT 共识算法的源码库; -- test 项目库: - - URL:git@github.com:blockchain-jd-com/jdchain-test.git - - 说明:集成测试用例的源码库; +构建完成后会在`deploy`模块,`deploy-gateway`和`deploy-peer`目录`target`中生成网关安装部署包(`jdchain-gateway-*.zip`)和共识节点安装部署包(`jdchain-peer-*.zip`)。 -4. 构建操作 +## 部署使用 +### 快速部署 -```sh -$ git clone git@github.com:blockchain-jd-com/jdchain.git jdchain +使用[源码构建](#源码构建)生成的部署安装包,或者下载[官方部署安装包](http://ledger.jd.com/downloadapps.html) 参照[快速部署文档](docs/quick_start.md)可快速部署运行`JD Chain`网络。 -$ cd jdchain +### 数据上链 -$ git checkout develop +1. 命令行工具 -$ chmod +x build/*.sh +`JD Chain` 命令行工具集,即[jdchain-cli](docs/jdchain_cli.md),提供密钥管理,实时交易,链上信息查询,离线交易,共识节点变更等操作。可快速执行数据上链和链上数据查询。 -# 执行完整的构建,包括执行”集成测试“和”打包“两部分;提供两个参数: -# --skipTests :跳过集成测试部分; -# --update :从远程仓库更新子模块。注意,采用此参数会导致子模块本地仓库丢失尚未 commit 的代码。 -# 不附带此参数的情况下不会更新子模块仓库。 -$ build/build.sh --update - -# 跳过集成测试,直接编译和打包; -$ build/build.sh --skipTests +2. SDK -# 只执行集成测试; -$ build/test.sh - -``` +`JD Chain`提供了`Java`和`Go`版本的`SDK`。实际项目开发中`Java`可参照[示例代码](https://github.com/blockchain-jd-com/jdchain/tree/master/samples),`Go`语言`SDK`参照[framework-go](https://github.com/blockchain-jd-com/framework-go)。 -5. jdchain 的安装包 +### 更多 -当编译完成后,安装包位于主项目库的 deploy 目录中: +`JD Chain`功能开发,使用问题等欢迎`issue`中探讨,也欢迎广大开发者积极参与`JD Chain`社区活动及代码开发~ -- 共识节点的安装包: - - <主项目库根目录>/deploy/deploy-peer/target/jdchain-peer-**.zip -- 网关节点的安装包: - - <主项目库根目录>/deploy/deploy-gateway/target/jdchain-gateway-**.zip \ No newline at end of file +- `JD Chain`官方网站:https://ledger.jd.com/ +- 文档:[wiki](https://github.com/blockchain-jd-com/jdchain/wiki),[docs](docs/) +- 京东智臻链官网:https://blockchain.jd.com/ +- 服务邮箱:jdchain-support@jd.com +- `FAQ`:https://github.com/blockchain-jd-com/jdchain/wiki/FAQ \ No newline at end of file diff --git a/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.3.MD b/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.3.MD deleted file mode 100644 index 6ef57c60..00000000 --- a/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.3.MD +++ /dev/null @@ -1,1716 +0,0 @@ -# 京东区块链浏览器API文档参考 V_1.3 - -## 1 API调用说明 - -该文档内的所有api的调用成功和失败均按照以下规则 - -### 1.1 成功 - -```json -{ - "data": ..., - "success": true -} -``` - -说明 - - - success 值为 true 表明api调用成功 - - data 为返回的数据,具体数据类型参考具体的api说明 - -### 1.2 失败 - -```json -{ - "error": { - "errorCode": 5000, - "errorMessage": "未预期的异常! --Unsupported access ledger[6Gw3cK4uazegy4HjoaM81ck9NgYLNoKyBMb7a1TK1jt3d] !" - }, - "success": false -} -``` - -说明 - - - success 值为 false 表明api调用成功 - - errorCode 为异常代码 - - errorMessage 为错误提示 - -## 2 账本 - -### 2.1 获取账本总数 - -```http -GET /ledgers/count -``` - -#### 参数 -无 - - -#### 请求实例 -```http -http://localhost/ledgers/count -``` - -#### 返回实例 - -```json -{ - "data": 2, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账本总数| - - -### 2.2 获取账本列表 - -```http -GET /ledgers?fromIndex={start_index}&count={count} -``` - -#### 参数 -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|query|start_index|否|查询账本的起始序号,默认为0|数字 -|query|count|否|查询返回账本的数量限制,默认最大限制为100,小于0或大于100均返回最大可返回结果集|数字 - - -#### 请求实例 -```http -http://localhost/ledgers?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data": [ - { - "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs" - } - ], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账本哈希列表| -|value|账户哈希| - -### 2.3 获取账本详细信息 - -```http -GET /ledgers/{ledger} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs -``` - -#### 返回实例 - -```json -{ - "data": { - "hash": { - "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs" - }, - "latestBlockHash": { - "value": "67XsKWgqZTBz1NsytKGpyNWHMbMRENWcBj8PEDYQnWiDL" - }, - "latestBlockHeight": 66 - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账本信息| -|hash.value|账本哈希| -|latestBlockHash.value|最新区块哈希 -|latestBlockHeight|账本高度 - - -### 2.4 获取账本成员总数 - -```http -GET /ledgers/{ledger}/participants/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/participants/count -``` - -#### 返回实例 - -```json -{ - "data": 4, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账本成员总数| - - -### 2.5 获取账本成员列表 - -```http -GET /ledgers/{ledger}/participants?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|query|start_index|否|查询成员起始序号,默认为0|数字 -|query|count|否|查询成员返回数量,默认最大返回100,小于0或大于100均返回最大可返回结果集|数字 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/participants?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data": [ - { - "address": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522", - "name": "jd.com", - "id": 0, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - } - }, - { - "address": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha", - "name": "at.com", - "id": 1, - "pubKey": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - }, - { - "address": "5SmMWsqV2kbgrRMjyQFtSq1wvYuPzeRVepHG", - "name": "bt.com", - "id": 2, - "pubKey": { - "value": "mb4AtiGAH7vtPufMDuap2oca2Ww9X6KTkp59Eh5nZjXA5H" - } - }, - { - "address": "5Sm5QFyvN1dVB4GHFxWhDCp8vsJbNkdx31Ds", - "name": "xt.com", - "id": 3, - "pubKey": { - "value": "mb7pGhmmjqYUhxrJJ57C1YxXr9h1AWXv8QVosETyuLhVvH" - } - } - ], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|id|成员唯一标识| -|name|成员名称| -|address|成员地址| -|pubKey.value|成员公钥| - -## 3 区块 - -### 3.1 获取最新区块 - -```http -GET /ledgers/{ledger}/blocks/latest -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/latest -``` - -#### 返回实例 - -```json -{ - "data": { - "ledgerHash": { - "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs" - }, - "previousHash": { - "value": "6EJZnMc9464DCSU2kgi96RyngEv8YeEfVoJNhH3yZ2v5T" - }, - "transactionSetHash": { - "value": "6LmZtDpMM7xE8FPChACEmLj1PLhfaoVM2rEHRsrV3ohPN" - }, - "userAccountSetHash": { - "value": "67jx7SctrwdSczxxuYjwBocA8fER7V8qcRZUzWamSav5p" - }, - "contractAccountSetHash": { - "value": "67ftaBhPDez24NEB9wiiTM3SNcn1XFz5rb7boYhpbbLXN" - }, - "adminAccountHash": { - "value": "69KEFp9m5iFyAiyGmJ2qPcVxuT79gMChMf9JkStBZe8aa" - }, - "dataAccountSetHash": { - "value": "6LB9gosVWEPG3uvWXkxTcWq22mcwMHVehbiXkavFtr5fZ" - }, - "hash": { - "value": "67XsKWgqZTBz1NsytKGpyNWHMbMRENWcBj8PEDYQnWiDL" - }, - "height": 66 - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|hash|区块哈希| -|ledgerHash|账本哈希| -|previousHash|前置区块哈希| -|transactionSetHash|交易集哈希| -|userAccountSetHash|用户集哈希| -|contractAccountSetHash|合约集哈希| -|adminAccountHash|管理员集哈希| -|dataAccountSetHash|数据账户集哈希| - -### 3.2 根据区块哈希获取区块详细信息 - -```http -GET /ledgers/{ledger}/blocks/hash/{block_hash} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|block_hash|是|区块哈希|字符串| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/67XsKWgqZTBz1NsytKGpyNWHMbMRENWcBj8PEDYQnWiDL -``` - -#### 返回实例 - -[参考](#block-detail) - - -### 3.3 根据区块高度获取区块详细信息 - -```http -GET /ledgers/{ledger}/blocks/height/{block_height} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|block_height|是|区块高度|数字| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/height/66 -``` - -#### 返回实例 - -[参考](#block-detail) - - -### 3.4 根据哈希查询区块总数 - -```http - GET /ledgers/{ledger}/blocks/count/search?keyword={keyword} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是| 区块哈希的全部或者一部分|string| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/count/search?keyword=6D5M -``` - -#### 返回实例 - -```json -{ - "data": 26, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|查询到的区块总数| - -### 3.5 根据哈希查询区块 - -```http - GET /ledgers/{ledger}/blocks/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是| 区块哈希的全部或者一部分|string| -|**query**|**start_index**|否| 查询区块结果起始序号,默认为0|string| -|**query**|**count**|否| 查询区块结果返回数量,默认最大值为100,小于0或大于100均返回最大可返回结果集|string| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/search?keyword=6D5M&fromIndex=0&count=-1 -``` - - -#### 返回实例 - -```json -{ - "data": { - "blocks": [ - { - "hash": "6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb" - } - ] - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|blocks|查询到的区块列表| -|hash|区块哈希值| -|height|区块高度| -|txCount|区块内交易数量| - -## 4 交易 - -### 4.1 获取账本交易总数 - -```http -GET /ledgers/{ledger}/txs/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/count -``` - -##### 返回实例 - -```json -{ - "data": 688, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|交易数量| - -### 4.2 根据区块高度查询区块内的交易数量 - -```http -GET /ledgers/{ledger}/blocks/height/{block_height}/txs/additional-count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|block_height|是|区块高度|数字| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/height/66/txs/additional-count - -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb/txs/additional-count -``` - -#### 返回实例 - -```json -{ - "data": 86, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|交易数量| - - -### 4.3 根据区块哈希查询区块内的交易数量 - -```http -GET /ledgers/{ledger}/blocks/hash/{block_hash}/txs/additional-count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|block_hash|是|区块哈希|字符串| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb/txs/additional-count -``` - -#### 返回实例 - -```json -{ - "data": 86, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|交易数量| - - -### 4.4 获取指定高度的区块交易列表 - -```http -GET /ledgers/{ledger}/blocks/height/{height}/txs?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|height|是|区块高度|数字| -|query|start_index|否|查询交易的起始序号,默认为0|数字| -|query|count|否|查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/height/66/txs?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data": [ - { - "blockHeight": 1, - "executionState": "SUCCESS", - "transactionContent": { - "ledgerHash": { - "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs" - }, - "operations": [ - { - "userID": { - "address": { - "value": "5SmBgzsrnY6u9Y7DgSSkXfTkCgp83hiFin3v" - }, - "pubKey": { - "value": "mb5kukaqjWtXyAerfHU1JDtVwabSeBU5c3khMZbNh7R8VJ" - } - } - }, - { - "accountID": { - "address": { - "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha" - }, - "pubKey": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - } - }, - { - "contractID": { - "address": { - "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha" - }, - "pubKey": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - }, - "chainCode": "----------" - }, - { - "contractAddress": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - }, - "event": "----------", - "args": "----------" - }, - { - "writeSet": [{ - "key": "jdchain", - "value": { - "type": "TEXT", - "value": { - "value": "----------" - } - }, - "expectedVersion": 0 - }], - "accountAddress": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - } - ], - "hash": { - "value": "6BLtM1agb7ERKoN5AJgZKiTjzdS7BpjgzQNYK8ZeDqotA" - } - }, - "endpointSignatures": [ - { - "digest": { - "value": "42pbfM5YKnf39Gitr4UsjTCzhhnJjwNyi8MnLFYgP4VKewTLzHitzArHEMrCt3hZYUe5ex9XvqtmiCoWpeAbdc31F" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - } - } - ], - "nodeSignatures": [ - { - "digest": { - "value": "66SQ95SbDaApAJhN2NsFx5sfAQTxsWhMW26D5iPqXc1jZU9rJEhRnqT1nzt62ZAcCvsfrjEsay3MxqXYA5tWPoA2U" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - } - } - ] - } - ], - "success": true -} -``` - - -说明 - -|名称|说明| -|---|---| -|executionState|交易执行结果| -|transactionContent.hash|交易的哈希| -|transactionContent.operations|交易的操作列表| -|endpointSignatures|终端签名列表| -|nodeSignatures|节点的签名列表| - -### 4.5 获取指定哈希的区块的交易列表 - -```http -GET /ledgers/{ledger}/blocks/hash/{block_hash}/txs?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|block_hash|是|区块哈希|字符串| -|query|start_index|否|查询交易的起始序号,默认为0|数字| -|query|count|否|查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb/txs?fromIndex=0&count=-1 -``` - -#### 返回实例 - -[参考](#tx-list) - - -### 4.6 获取交易详细信息 - -```http -GET /ledgers/{ledger}/txs/hash/{tx_hash} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|tx_hash|是|交易哈希|字符串| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/hash/6BLtM1agb7ERKoN5AJgZKiTjzdS7BpjgzQNYK8ZeDqotA -``` - -#### 返回实例 - -```json -{ - "data": { - "blockHeight": 1, - "executionState": "SUCCESS", - "transactionContent": { - "ledgerHash": { - "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs" - }, - "operations": [ - { - "userID": { - "address": { - "value": "5SmBgzsrnY6u9Y7DgSSkXfTkCgp83hiFin3v" - }, - "pubKey": { - "value": "mb5kukaqjWtXyAerfHU1JDtVwabSeBU5c3khMZbNh7R8VJ" - } - } - }, - { - "accountID": { - "address": { - "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha" - }, - "pubKey": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - } - }, - { - "contractID": { - "address": { - "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha" - }, - "pubKey": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - }, - "chainCode": "----------" - }, - { - "contractAddress": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - }, - "event": "----------", - "args": "----------" - }, - { - "writeSet": [{ - "key": "jdchain", - "value": { - "type": "TEXT", - "value": { - "value": "----------" - } - }, - "expectedVersion": 0 - }], - "accountAddress": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - } - ], - "hash": { - "value": "6BLtM1agb7ERKoN5AJgZKiTjzdS7BpjgzQNYK8ZeDqotA" - } - }, - "endpointSignatures": [ - { - "digest": { - "value": "42pbfM5YKnf39Gitr4UsjTCzhhnJjwNyi8MnLFYgP4VKewTLzHitzArHEMrCt3hZYUe5ex9XvqtmiCoWpeAbdc31F" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - } - } - ], - "nodeSignatures": [ - { - "digest": { - "value": "66SQ95SbDaApAJhN2NsFx5sfAQTxsWhMW26D5iPqXc1jZU9rJEhRnqT1nzt62ZAcCvsfrjEsay3MxqXYA5tWPoA2U" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - } - } - ] - }, - "success": true -} -``` - -说明 - -[参考](#tx-keyword) - - -### 4.7 根据哈希查询交易总数 - -```http - GET /ledgers/{ledgers}/txs/count/search?keyword={keyword} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledgers**|是|所要搜索的账本范围,需要完整的账本哈希|string| -|**query**|**keyword**|是|交易哈希,签名者公钥,或者节点公钥的全部或者部分的|string| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/search?keyword=6BLt -``` - -#### 返回实例 - -```json -{ - "data": 36, - "success": true -} -``` - - -说明 - -|名称|说明| -|---|---| -|data|指定交易数量| - - -### 4.8 根据哈希查询交易 - -```http - GET /ledgers/{ledgers}/txs/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledgers**|是|所要搜索的账本范围,需要完整的账本哈希|string| -|**query**|**keyword**|是|交易哈希,签名者公钥,或者节点公钥的全部或者部分的|string| -|**query**|**start_index**|否|查询交易的起始序号,默认为0|数字| -|**query**|**count**|否|查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/search?keyword=6BLt -``` - - -#### 返回 - -```json -{ - "data": { - "txs": [ - { - "hash": "6L3ehswCmC1jqBfvGJP9vaPx8qxkLsieu2aRgYepmkiw3" - } - ] - }, - "success": true -} -``` - -## 5 用户 - -### 5.1 获取用户总数 - -```http -GET /ledgers/{ledger}/users/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/count -``` - -#### 返回实例 - -```json -{ - "data": 4, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|用户总数| - - -### 5.2 获取用户列表 - -```http -GET /ledgers/{ledger}/users?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|query|start_index|否|查询用户的起始序号,默认为0|数字| -|query|count|否|查询返回用户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data":[{ - "address": { - "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - }, - "rootHash": { - "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522" - } - }], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|用户地址| -|pubKey.value|用户公钥| - - -### 5.3 获取用户详细信息 - -```http -GET /ledgers/{ledger}/users/address/{address} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|用户地址|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/address/55SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522 -``` - -#### 返回实例 - -```json -{ - "data": { - "address": { - "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - }, - "rootHash": { - "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522" - } - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|用户地址| -|pubKey.value|用户公钥| -|rootHash.value|用户根Hash| - - -### 5.4 用户查询数量 - -```http - GET /ledgers/{ledger}/users/count/search?keyword={keyword} -``` - -#### 说明 - -用户有公钥和地址两个属性,可以通过公钥或者地址查找特定用户数量,也可以返回全部用户的数量 - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是| 用户的公钥或者地址的全部或者部分|string| -|**query**|**start_index**|否|查询用户的起始序号,默认为0|数字| -|**query**|**count**|否|查询返回用户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/count/search?keyword=5Sm -``` - -#### 返回实例 - -```json -{ - "data": 4, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|用户数量| - -### 5.5 用户查询 - -```http - GET /ledgers/{ledger}/users/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 说明 - -用户有公钥和地址两个属性,可以通过公钥或者地址查找特定用户,也可以返回全部用户的列表 - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是| 用户的公钥或者地址的全部或者部分|string| -|**query**|**start_index**|否|查询用户的起始序号,默认为0|数字| -|**query**|**count**|否|查询返回用户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/search?keyword=5Sm&fromIndex=0&count=-1 -``` - - -#### 返回实例 - -```json -{ - "data": { - "users": [ - { - "address": { - "value": "5SmAGKgmXyj5VsVvJgHbYCJ67iTizwSkNpw1" - }, - "pubKey": { - "value": "mb97eG4bba2EjrgjXYiD9chAstjg4HaNuV5xgCtSHc5TeB" - } - } - ] - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|用户地址| -|pubKey.value|用户公钥| -|rootHash.value|用户根Hash| - -## 6 数据账户 - -### 6.1 获取账户列表 - -```http -GET /ledgers/{ledger}/accounts?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|query|start_index|否|查询数据账户的起始序号,默认为0|数字| -|query|count|否|查询返回数据账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data":[{ - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "rootHash": { - "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - }], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| -|rootHash.value|默克尔树根哈希| - - -### 6.2 获取账户详细信息 - -```http -GET /ledgers/{ledger}/accounts/address/{address} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|账户地址|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa -``` - -#### 返回实例 - -```json -{ - "data": { - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "rootHash": { - "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| -|rootHash.value|默克尔树根哈希| - - -### 6.3 获取账户总数 - -```http -GET /ledgers/{ledger}/accounts/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/count -``` - -#### 返回实例 - -```json -{ - "data": 18, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账户数量| - - -### 6.4 查询数据账户匹配的数量 - -```http -GET /ledgers/{ledger}/accounts/count/search?keyword={keyword} -``` - -#### 说明 - -通过账户的公钥和地址的全部或者部分查询特定账户的总数量,也可以通过KV值的Key来查询含有该Key的账户的总数量 - - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|字符串 -|**query**|**keyword**|是|数据账户的公钥或者地址的全部或者部分,或者是KV值的key|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/count/search?keyword=jd -``` - -#### 返回实例 - -```json -{ - "data": 2, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账户数量| - - -### 6.5 查询数据账户 - -```http - GET /ledgers/{ledger}/accounts/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 说明 - -通过账户的公钥和地址的全部或者部分查询特定账户,也可以通过KV值的Key来查询含有该Key的账户 - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是| 数据账户的公钥或者地址的全部或者部分,或者是KV值的key|string| -|**query**|**start_index**|否|查询数据账户的起始序号,默认为0|数字| -|**query**|**count**|否|查询返回数据账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/search?keyword=5Sm5V&fromIndex=0&count=-1 -``` - - -#### 返回实例 - -```json -{ - "data": { - "accounts": [ - { - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - } - ] - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| -|rootHash.value|数据账户根Hash| - - -### 6.6 获取某数据账户KV总数 - -```http - GET /ledgers/{ledger}/accounts/address/{address}/entries/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|账户地址|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/entries/count -``` - -#### 返回实例 - -```json -{ - "data": 66, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|KV总数| - - -### 6.7 获取某数据账户KV详情 - -```http - GET/POST /ledgers/{ledger}/accounts/address/{address}/entries?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|账户地址|字符串 -|form|keys|是|key详细内容列表|字符串 -|query|start_index|否|查询数据账户对应KV的起始序号,默认为0|数字| -|query|count|否|查询返回数据账户对应KV的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -> keys说明: - 1)keys使用表单方式提交,且keys为需要查询Key的列表,列表中每个Key都需要为完整Key - 2)Key提交方式使用GET或POST均可 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/entries -``` - -说明:表单提交参数为keys={"jd", "jdchain"} - - -#### 返回实例 - -```json -{ - "data": [ - { - "key": "jd", - "version": 0, - "type": "TEXT", - "value": "www.jd.com" - }, - { - "key": "jdchain", - "version": 0, - "type": "TEXT", - "value": "www.blockchain.com" - }], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|key|键| -|version|版本号| -|type|value类型| -|value|值| - - - -## 7 搜索 - -### 7.1 搜索区块链 - -```http - GET /ledgers/{ledger}/all/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 说明 - -通过关键字搜索区块数据,支持区块哈希,交易哈希,用户公钥和地址,合约公钥和地址,数据账户哈希和地址的搜索 - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是|关键字|string| -|**query**|**start_index**|否|查询匹配结果的起始序号,默认为0|数字| -|**query**|**count**|否|查询匹配结果的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/all/search?keyword=5Sm5V&fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "message": "OK", - "code": 0, - "data": { - "blocks": ..., - "txs": ..., - "users": ..., - "accounts": ..., - "contracts": ..., - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|blocks|[参考](#query-blocks-result)| -|txs|[参考](#query-txs-result)| -|users|[参考](#query-users-result)| -|accounts|[参考](#query-accounts-result)| -|contracts|[参考](#query-contracts-result)| - -## 8 合约 - -### 8.1 获取合约列表 - -```http -GET /ledgers/{ledger}/contracts?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|query|start_index|否|查询合约的起始序号,默认为0|数字| -|query|count|否|查询返回合约的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data": [{ - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "rootHash": { - "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - }], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| -|rootHash.value|默克尔树根哈希| - - -### 8.2 获取合约详细信息 - -```http -GET /ledgers/{ledger}/contracts/address/{address} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|合约地址|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa -``` - -#### 返回实例 - -```json -{ - "data": { - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "rootHash": { - "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| -|rootHash.value|默克尔树根哈希| - -### 8.3 获取合约总数 - -```http -GET /ledgers/{ledger}/contracts/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/count -``` - -#### 返回实例 - -```json -{ - "data": 27, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|合约数量| - - -### 8.4 查询指定合约数量 - -```http -GET /ledgers/{ledger}/contracts/count/search?keyword={keyword} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本范围,需要完整的账本哈希|string| -|**query**|**keyword**|是| 合约的公钥或者地址的全部或者一部分|string| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/count/search?keyword=5Sm2 -``` - -#### 返回实例 - -```json -{ - "data": 2, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|合约数量| - -### 8.5 合约查询 - -```http - GET /ledgers/{ledger}/contracts/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 说明 - -合约有公钥和地址两个属性,可以通过合约的这两个属性查询特定合约,也可以返回一个当前所有合约的列表 - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本范围,需要完整的账本哈希|string| -|**query**|**keyword**|是| 合约的公钥或者地址的全部或者一部分|string| -|**query**|**start_index**|否|查询合约的起始序号,默认为0|数字| -|**query**|**count**|否|查询返回合约的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/earch?keyword=5Sm2&fromIndex=0&count=-1 -``` - - -#### 返回 - -```json -{ - "data": { - "contracts": [ - { - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "rootHash": { - "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - } - ] - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|合约地址| -|pubKey.value|合约公钥| -|rootHash|合约根Hash| diff --git a/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.3.html b/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.3.html deleted file mode 100644 index 169ef8b7..00000000 --- a/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.3.html +++ /dev/null @@ -1,2665 +0,0 @@ - - - - - api_doc_cn_1.3 - - -

京东区块链浏览器API文档参考 V_1.3

-

1 API调用说明

-

该文档内的所有api的调用成功和失败均按照以下规则

-

1.1 成功

-
{
  "data": ...,
  "success": true
}
-

说明

-
- success 值为 true 表明api调用成功
- data 为返回的数据,具体数据类型参考具体的api说明

1.2 失败

-
{
  "error": {
    "errorCode": 5000,
    "errorMessage": "未预期的异常! --Unsupported access ledger[6Gw3cK4uazegy4HjoaM81ck9NgYLNoKyBMb7a1TK1jt3d] !"
  },
  "success": false
}
-

说明

-
- success 值为 false 表明api调用成功
- errorCode 为异常代码
- errorMessage 为错误提示

2 账本

-

2.1 获取账本总数

-
GET /ledgers/count
-

参数

-

-

请求实例

-
http://localhost/ledgers/count
-

返回实例

-
{
  "data": 2,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data账本总数
-

2.2 获取账本列表

-
GET /ledgers?fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
querystart_index查询账本的起始序号,默认为0数字
querycount查询返回账本的数量限制,默认最大限制为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers?fromIndex=0&count=-1
-

返回实例

-
{
  "data": [
    {
      "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs"
    }
  ],
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - -
名称说明
data账本哈希列表
value账户哈希
-

2.3 获取账本详细信息

-
GET /ledgers/{ledger}
-

参数

- - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs
-

返回实例

-
{
  "data": {
    "hash": {
      "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs"
    },
    "latestBlockHash": {
      "value": "67XsKWgqZTBz1NsytKGpyNWHMbMRENWcBj8PEDYQnWiDL"
    },
    "latestBlockHeight": 66
  },
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - - - - - -
名称说明
data账本信息
hash.value账本哈希
latestBlockHash.value最新区块哈希
latestBlockHeight账本高度
-

2.4 获取账本成员总数

-
GET /ledgers/{ledger}/participants/count
-

参数

- - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/participants/count
-

返回实例

-
{
  "data": 4,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data账本成员总数
-

2.5 获取账本成员列表

-
GET /ledgers/{ledger}/participants?fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
querystart_index查询成员起始序号,默认为0数字
querycount查询成员返回数量,默认最大返回100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/participants?fromIndex=0&count=-1
-

返回实例

-
{
  "data": [
    {
      "address": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522",
      "name": "jd.com",
      "id": 0,
      "pubKey": {
        "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS"
      }
    },
    {
      "address": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha",
      "name": "at.com",
      "id": 1,
      "pubKey": {
        "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR"
      }
    },
    {
      "address": "5SmMWsqV2kbgrRMjyQFtSq1wvYuPzeRVepHG",
      "name": "bt.com",
      "id": 2,
      "pubKey": {
        "value": "mb4AtiGAH7vtPufMDuap2oca2Ww9X6KTkp59Eh5nZjXA5H"
      }
    },
    {
      "address": "5Sm5QFyvN1dVB4GHFxWhDCp8vsJbNkdx31Ds",
      "name": "xt.com",
      "id": 3,
      "pubKey": {
        "value": "mb7pGhmmjqYUhxrJJ57C1YxXr9h1AWXv8QVosETyuLhVvH"
      }
    }
  ],
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - - - - - -
名称说明
id成员唯一标识
name成员名称
address成员地址
pubKey.value成员公钥
-

3 区块

-

3.1 获取最新区块

-
GET /ledgers/{ledger}/blocks/latest
-

参数

- - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/latest
-

返回实例

-
{
  "data": {
    "ledgerHash": {
      "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs"
    },
    "previousHash": {
      "value": "6EJZnMc9464DCSU2kgi96RyngEv8YeEfVoJNhH3yZ2v5T"
    },
    "transactionSetHash": {
      "value": "6LmZtDpMM7xE8FPChACEmLj1PLhfaoVM2rEHRsrV3ohPN"
    },
    "userAccountSetHash": {
      "value": "67jx7SctrwdSczxxuYjwBocA8fER7V8qcRZUzWamSav5p"
    },
    "contractAccountSetHash": {
      "value": "67ftaBhPDez24NEB9wiiTM3SNcn1XFz5rb7boYhpbbLXN"
    },
    "adminAccountHash": {
      "value": "69KEFp9m5iFyAiyGmJ2qPcVxuT79gMChMf9JkStBZe8aa"
    },
    "dataAccountSetHash": {
      "value": "6LB9gosVWEPG3uvWXkxTcWq22mcwMHVehbiXkavFtr5fZ"
    },
    "hash": {
      "value": "67XsKWgqZTBz1NsytKGpyNWHMbMRENWcBj8PEDYQnWiDL"
    },
    "height": 66
  },
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称说明
hash区块哈希
ledgerHash账本哈希
previousHash前置区块哈希
transactionSetHash交易集哈希
userAccountSetHash用户集哈希
contractAccountSetHash合约集哈希
adminAccountHash管理员集哈希
dataAccountSetHash数据账户集哈希
-

3.2 根据区块哈希获取区块详细信息

-
GET /ledgers/{ledger}/blocks/hash/{block_hash}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathblock_hash区块哈希字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/67XsKWgqZTBz1NsytKGpyNWHMbMRENWcBj8PEDYQnWiDL
-

返回实例

-

参考

-

3.3 根据区块高度获取区块详细信息

-
GET /ledgers/{ledger}/blocks/height/{block_height}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathblock_height区块高度数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/height/66
-

返回实例

-

参考

-

3.4 根据哈希查询区块总数

-
  GET /ledgers/{ledger}/blocks/count/search?keyword={keyword}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本,需要完整的账本哈希string
querykeyword区块哈希的全部或者一部分string
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/count/search?keyword=6D5M
-

返回实例

-
{
  "data": 26,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data查询到的区块总数
-

3.5 根据哈希查询区块

-
  GET /ledgers/{ledger}/blocks/search?keyword={keyword}&fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本,需要完整的账本哈希string
querykeyword区块哈希的全部或者一部分string
querystart_index查询区块结果起始序号,默认为0string
querycount查询区块结果返回数量,默认最大值为100,小于0或大于100均返回最大可返回结果集string
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/search?keyword=6D5M&fromIndex=0&count=-1
-

-

返回实例

-
{
  "data": {
    "blocks": [
      {
        "hash": "6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb"
      }
    ]
  },
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - - - - - -
名称说明
blocks查询到的区块列表
hash区块哈希值
height区块高度
txCount区块内交易数量
-

4 交易

-

4.1 获取账本交易总数

-
GET /ledgers/{ledger}/txs/count
-

参数

- - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/count
-
返回实例
-
{
  "data": 688,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data交易数量
-

4.2 根据区块高度查询区块内的交易数量

-
GET /ledgers/{ledger}/blocks/height/{block_height}/txs/additional-count
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathblock_height区块高度数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/height/66/txs/additional-count
 
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb/txs/additional-count
-

返回实例

-
{
  "data": 86,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data交易数量
-

4.3 根据区块哈希查询区块内的交易数量

-
GET /ledgers/{ledger}/blocks/hash/{block_hash}/txs/additional-count
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathblock_hash区块哈希字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb/txs/additional-count
-

返回实例

-
{
  "data": 86,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data交易数量
-

4.4 获取指定高度的区块交易列表

-
GET /ledgers/{ledger}/blocks/height/{height}/txs?fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathheight区块高度数字
querystart_index查询交易的起始序号,默认为0数字
querycount查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/height/66/txs?fromIndex=0&count=-1
-

返回实例

-
{
  "data": [
    {
      "blockHeight": 1,
      "executionState": "SUCCESS",
      "transactionContent": {
        "ledgerHash": {
          "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs"
        },
        "operations": [
          {
            "userID": {
              "address": {
                "value": "5SmBgzsrnY6u9Y7DgSSkXfTkCgp83hiFin3v"
              },
              "pubKey": {
                "value": "mb5kukaqjWtXyAerfHU1JDtVwabSeBU5c3khMZbNh7R8VJ"
              }
            }
          },
          {
            "accountID": {
              "address": {
                "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha"
              },
              "pubKey": {
                "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR"
              }
            }
          },
          {
            "contractID": {
              "address": {
                "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha"
              },
              "pubKey": {
                "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR"
              }
            },
            "chainCode": "----------"
          },
          {
            "contractAddress": {
              "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR"
            },
            "event": "----------",
            "args": "----------"
          },
          {
            "writeSet": [{
              "key": "jdchain",
              "value": {
                "type": "TEXT",
                "value": {
                  "value": "----------"
                }
              },
              "expectedVersion": 0
            }],
            "accountAddress": {
              "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR"
            }
          }
        ],
        "hash": {
          "value": "6BLtM1agb7ERKoN5AJgZKiTjzdS7BpjgzQNYK8ZeDqotA"
        }
      },
      "endpointSignatures": [
        {
          "digest": {
            "value": "42pbfM5YKnf39Gitr4UsjTCzhhnJjwNyi8MnLFYgP4VKewTLzHitzArHEMrCt3hZYUe5ex9XvqtmiCoWpeAbdc31F"
          },
          "pubKey": {
            "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS"
          }
        }
      ],
      "nodeSignatures": [
        {
          "digest": {
            "value": "66SQ95SbDaApAJhN2NsFx5sfAQTxsWhMW26D5iPqXc1jZU9rJEhRnqT1nzt62ZAcCvsfrjEsay3MxqXYA5tWPoA2U"
          },
          "pubKey": {
            "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS"
          }
        }
      ]
    }
  ],
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称说明
executionState交易执行结果
transactionContent.hash交易的哈希
transactionContent.operations交易的操作列表
endpointSignatures终端签名列表
nodeSignatures节点的签名列表
-

4.5 获取指定哈希的区块的交易列表

-
GET /ledgers/{ledger}/blocks/hash/{block_hash}/txs?fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathblock_hash区块哈希字符串
querystart_index查询交易的起始序号,默认为0数字
querycount查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb/txs?fromIndex=0&count=-1
-

返回实例

-

参考

-

4.6 获取交易详细信息

-
GET /ledgers/{ledger}/txs/hash/{tx_hash}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathtx_hash交易哈希字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/hash/6BLtM1agb7ERKoN5AJgZKiTjzdS7BpjgzQNYK8ZeDqotA
-

返回实例

-
{
  "data": {
    "blockHeight": 1,
    "executionState": "SUCCESS",
    "transactionContent": {
      "ledgerHash": {
        "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs"
      },
      "operations": [
        {
          "userID": {
            "address": {
              "value": "5SmBgzsrnY6u9Y7DgSSkXfTkCgp83hiFin3v"
            },
            "pubKey": {
              "value": "mb5kukaqjWtXyAerfHU1JDtVwabSeBU5c3khMZbNh7R8VJ"
            }
          }
        },
        {
          "accountID": {
            "address": {
              "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha"
            },
            "pubKey": {
              "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR"
            }
          }
        },
        {
          "contractID": {
            "address": {
              "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha"
            },
            "pubKey": {
              "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR"
            }
          },
          "chainCode": "----------"
        },
        {
          "contractAddress": {
            "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR"
          },
          "event": "----------",
          "args": "----------"
        },
        {
          "writeSet": [{
            "key": "jdchain",
            "value": {
              "type": "TEXT",
              "value": {
                "value": "----------"
              }
            },
            "expectedVersion": 0
          }],
          "accountAddress": {
            "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR"
          }
        }
      ],
      "hash": {
        "value": "6BLtM1agb7ERKoN5AJgZKiTjzdS7BpjgzQNYK8ZeDqotA"
      }
    },
    "endpointSignatures": [
      {
        "digest": {
          "value": "42pbfM5YKnf39Gitr4UsjTCzhhnJjwNyi8MnLFYgP4VKewTLzHitzArHEMrCt3hZYUe5ex9XvqtmiCoWpeAbdc31F"
        },
        "pubKey": {
          "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS"
        }
      }
    ],
    "nodeSignatures": [
      {
        "digest": {
          "value": "66SQ95SbDaApAJhN2NsFx5sfAQTxsWhMW26D5iPqXc1jZU9rJEhRnqT1nzt62ZAcCvsfrjEsay3MxqXYA5tWPoA2U"
        },
        "pubKey": {
          "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS"
        }
      }
    ]
  },
  "success": true
}
-

说明

-

参考

-

4.7 根据哈希查询交易总数

-
  GET /ledgers/{ledgers}/txs/count/search?keyword={keyword}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledgers所要搜索的账本范围,需要完整的账本哈希string
querykeyword交易哈希,签名者公钥,或者节点公钥的全部或者部分的string
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/search?keyword=6BLt
-

返回实例

-
{
  "data": 36,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data指定交易数量
-

4.8 根据哈希查询交易

-
  GET /ledgers/{ledgers}/txs/search?keyword={keyword}&fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledgers所要搜索的账本范围,需要完整的账本哈希string
querykeyword交易哈希,签名者公钥,或者节点公钥的全部或者部分的string
querystart_index查询交易的起始序号,默认为0数字
querycount查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/search?keyword=6BLt
-

-

返回

-
{
  "data": {
    "txs": [
      {
        "hash": "6L3ehswCmC1jqBfvGJP9vaPx8qxkLsieu2aRgYepmkiw3"
      }
    ]
  },
  "success": true
}
-

5 用户

-

5.1 获取用户总数

-
GET /ledgers/{ledger}/users/count
-

参数

- - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/count
-

返回实例

-
{
  "data": 4,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data用户总数
-

5.2 获取用户列表

-
GET /ledgers/{ledger}/users?fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
querystart_index查询用户的起始序号,默认为0数字
querycount查询返回用户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users?fromIndex=0&count=-1
-

返回实例

-
{
  "data":[{
    "address": {
      "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522"
    },
    "pubKey": {
      "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS"
    },
    "rootHash": {
      "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522"
    }
  }],
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - -
名称说明
address.value用户地址
pubKey.value用户公钥
-

5.3 获取用户详细信息

-
GET /ledgers/{ledger}/users/address/{address}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathaddress用户地址字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/address/55SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522
-

返回实例

-
{
  "data": {
    "address": {
      "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522"
    },
    "pubKey": {
      "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS"
    },
    "rootHash": {
      "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522"
    }
  },
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - -
名称说明
address.value用户地址
pubKey.value用户公钥
rootHash.value用户根Hash
-

5.4 用户查询数量

-
  GET /ledgers/{ledger}/users/count/search?keyword={keyword}
-

说明

-

用户有公钥和地址两个属性,可以通过公钥或者地址查找特定用户数量,也可以返回全部用户的数量

-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本,需要完整的账本哈希string
querykeyword用户的公钥或者地址的全部或者部分string
querystart_index查询用户的起始序号,默认为0数字
querycount查询返回用户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/count/search?keyword=5Sm
-

返回实例

-
{
  "data": 4,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data用户数量
-

5.5 用户查询

-
  GET /ledgers/{ledger}/users/search?keyword={keyword}&fromIndex={start_index}&count={count}
-

说明

-

用户有公钥和地址两个属性,可以通过公钥或者地址查找特定用户,也可以返回全部用户的列表

-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本,需要完整的账本哈希string
querykeyword用户的公钥或者地址的全部或者部分string
querystart_index查询用户的起始序号,默认为0数字
querycount查询返回用户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/search?keyword=5Sm&fromIndex=0&count=-1
-

-

返回实例

-
{
  "data": {
    "users": [
      {
        "address": {
          "value": "5SmAGKgmXyj5VsVvJgHbYCJ67iTizwSkNpw1"
        },
        "pubKey": {
          "value": "mb97eG4bba2EjrgjXYiD9chAstjg4HaNuV5xgCtSHc5TeB"
        },
        "rootHash": {
          "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522"
        }
      }
    ]
  },
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - -
名称说明
address.value用户地址
pubKey.value用户公钥
rootHash.value用户根Hash
-

6 数据账户

-

6.1 获取账户列表

-
GET /ledgers/{ledger}/accounts?fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
querystart_index查询数据账户的起始序号,默认为0数字
querycount查询返回数据账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts?fromIndex=0&count=-1
-

返回实例

-
{
  "data":[{
    "address": {
      "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa"
    },
    "rootHash": {
      "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM"
    },
    "pubKey": {
      "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs"
    }
  }],
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - -
名称说明
address.value账户地址
pubKey.value账户公钥
rootHash.value默克尔树根哈希
-

6.2 获取账户详细信息

-
GET /ledgers/{ledger}/accounts/address/{address}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathaddress账户地址字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa
-

返回实例

-
{
  "data": {
    "address": {
      "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa"
    },
    "rootHash": {
      "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM"
    },
    "pubKey": {
      "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs"
    }
  },
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - -
名称说明
address.value账户地址
pubKey.value账户公钥
rootHash.value默克尔树根哈希
-

6.3 获取账户总数

-
GET /ledgers/{ledger}/accounts/count
-

参数

- - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/count
-

返回实例

-
{
  "data": 18,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data账户数量
-

6.4 查询数据账户匹配的数量

-
GET /ledgers/{ledger}/accounts/count/search?keyword={keyword}
-

说明

-

通过账户的公钥和地址的全部或者部分查询特定账户的总数量,也可以通过KV值的Key来查询含有该Key的账户的总数量

-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本,需要完整的账本哈希字符串
querykeyword数据账户的公钥或者地址的全部或者部分,或者是KV值的key字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/count/search?keyword=jd
-

返回实例

-
{
  "data": 2,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data账户数量
-

6.5 查询数据账户

-
  GET /ledgers/{ledger}/accounts/search?keyword={keyword}&fromIndex={start_index}&count={count}
-

说明

-

通过账户的公钥和地址的全部或者部分查询特定账户,也可以通过KV值的Key来查询含有该Key的账户

-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本,需要完整的账本哈希string
querykeyword数据账户的公钥或者地址的全部或者部分,或者是KV值的keystring
querystart_index查询数据账户的起始序号,默认为0数字
querycount查询返回数据账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/search?keyword=5Sm5V&fromIndex=0&count=-1
-

-

返回实例

-
{
  "data": {
    "accounts": [
      {
        "address": {
          "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa"
        },
        "rootHash": {
          "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM"
        },
        "pubKey": {
          "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs"
        }
      }
    ]
  },
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - -
名称说明
address.value账户地址
pubKey.value账户公钥
rootHash.value数据账户根Hash
-

6.6 获取某数据账户KV总数

-
  GET /ledgers/{ledger}/accounts/address/{address}/entries/count
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathaddress账户地址字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/entries/count
-

返回实例

-
{
  "data": 66,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
dataKV总数
-

6.7 获取某数据账户KV详情

-
  GET/POST /ledgers/{ledger}/accounts/address/{address}/entries?fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathaddress账户地址字符串
formkeyskey详细内容列表字符串
querystart_index查询数据账户对应KV的起始序号,默认为0数字
querycount查询返回数据账户对应KV的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-
-

keys说明: - 1)keys使用表单方式提交,且keys为需要查询Key的列表,列表中每个Key都需要为完整Key - 2)Key提交方式使用GET或POST均可

-
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/entries
-

说明:表单提交参数为keys={"jd", "jdchain"}

-

返回实例

-
{
  "data": [
  {
    "key": "jd",
    "version": 0,
    "type": "TEXT",
    "value": "www.jd.com"
  },
  {
    "key": "jdchain",
    "version": 0,
    "type": "TEXT",
    "value": "www.blockchain.com"
  }],
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - - - - - -
名称说明
key
version版本号
typevalue类型
value
-

6.8 查询某数据账户键数量

-
  GET /ledgers/{ledger}/accounts/address/{address}/keys/count/search?keyword={keyword}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本,需要完整的账本哈希string
pathaddress所要搜索的数据账户地址,需要完整的数据账户地址string
querykeyword键的部分字符,空表示全部string
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/keys/count/search?keyword=j
-

返回实例

-
{
  "data": 66,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data条件查询键总数
-

6.9 查询某数据账户键

-
  GET /ledgers/{ledger}/accounts/address/{address}/keys/search?keyword={keyword}&fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本,需要完整的账本哈希string
pathaddress所要搜索的数据账户地址,需要完整的数据账户地址string
querykeyword键的部分字符,空表示全部string
querystart_index查询数据账户对应Key的起始序号,默认为0数字
querycount查询返回数据账户对应Key的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/keys/search?keyword=j&fromIndex=0&count=-1
-

返回实例

-
{
  "data": [
  {
    "key": "jd"
  },
  {
    "key": "jdchain"
  }],
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
key
-

7 搜索

-

7.1 搜索区块链

-
  GET /ledgers/{ledger}/all/search?keyword={keyword}&fromIndex={start_index}&count={count}
-

说明

-

通过关键字搜索区块数据,支持区块哈希,交易哈希,用户公钥和地址,合约公钥和地址,数据账户哈希和地址的搜索

-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本,需要完整的账本哈希string
querykeyword关键字string
querystart_index查询匹配结果的起始序号,默认为0数字
querycount查询匹配结果的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/all/search?keyword=5Sm5V&fromIndex=0&count=-1
-

返回实例

-
{
  "message": "OK",
  "code": 0,
  "data": {
    "blocks": ...,
    "txs": ...,
    "users": ...,
    "accounts": ...,
    "contracts": ...,
  },
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称说明
blocks参考
txs参考
users参考
accounts参考
contracts参考
-

8 合约

-

8.1 获取合约列表

-
GET /ledgers/{ledger}/contracts?fromIndex={start_index}&count={count}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
querystart_index查询合约的起始序号,默认为0数字
querycount查询返回合约的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts?fromIndex=0&count=-1
-

返回实例

-
{
  "data": [{
    "address": {
      "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa"
    },
    "rootHash": {
      "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM"
    },
    "pubKey": {
      "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs"
    }
  }],
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - -
名称说明
address.value账户地址
pubKey.value账户公钥
rootHash.value默克尔树根哈希
-

8.2 获取合约详细信息

-
GET /ledgers/{ledger}/contracts/address/{address}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
pathaddress合约地址字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa
-

返回实例

-
{
  "data": {
    "address": {
      "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa"
    },
    "rootHash": {
      "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM"
    },
    "pubKey": {
      "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs"
    }
  },
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - -
名称说明
address.value账户地址
pubKey.value账户公钥
rootHash.value默克尔树根哈希
-

8.3 获取合约总数

-
GET /ledgers/{ledger}/contracts/count
-

参数

- - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger账本哈希字符串
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/count
-

返回实例

-
{
  "data": 27,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data合约数量
-

8.4 查询指定合约数量

-
GET /ledgers/{ledger}/contracts/count/search?keyword={keyword}
-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本范围,需要完整的账本哈希string
querykeyword合约的公钥或者地址的全部或者一部分string
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/count/search?keyword=5Sm2
-

返回实例

-
{
  "data": 2,
  "success": true
}
-

说明

- - - - - - - - - - - - - -
名称说明
data合约数量
-

8.5 合约查询

-
  GET /ledgers/{ledger}/contracts/search?keyword={keyword}&fromIndex={start_index}&count={count}
-

说明

-

合约有公钥和地址两个属性,可以通过合约的这两个属性查询特定合约,也可以返回一个当前所有合约的列表

-

参数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
请求类型名称是否必需说明数据类型
pathledger所要搜索的账本范围,需要完整的账本哈希string
querykeyword合约的公钥或者地址的全部或者一部分string
querystart_index查询合约的起始序号,默认为0数字
querycount查询返回合约的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集数字
-

请求实例

-
http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/earch?keyword=5Sm2&fromIndex=0&count=-1
-

-

返回

-
{
  "data": {
    "contracts": [
      {
        "address": {
          "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa"
        },
        "rootHash": {
          "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM"
        },
        "pubKey": {
          "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs"
        }
      }
    ]
  },
  "success": true
}
-

说明

- - - - - - - - - - - - - - - - - - - - - -
名称说明
address.value合约地址
pubKey.value合约公钥
rootHash合约根Hash
- diff --git a/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.4.MD b/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.4.MD deleted file mode 100644 index 06fd228a..00000000 --- a/deploy/deploy-gateway/src/main/resources/docs/api_doc_cn_1.4.MD +++ /dev/null @@ -1,2619 +0,0 @@ -# 京东区块链浏览器API文档参考 V_1.4 - -## 1 API调用说明 - -该文档内的所有api的调用成功和失败均按照以下规则 - -### 1.1 成功 - -```json -{ - "data": ..., - "success": true -} -``` - -说明 - - - success 值为 true 表明api调用成功 - - data 为返回的数据,具体数据类型参考具体的api说明 - -### 1.2 失败 - -```json -{ - "error": { - "errorCode": 5000, - "errorMessage": "未预期的异常! --Unsupported access ledger[6Gw3cK4uazegy4HjoaM81ck9NgYLNoKyBMb7a1TK1jt3d] !" - }, - "success": false -} -``` - -说明 - - - success 值为 false 表明api调用成功 - - errorCode 为异常代码 - - errorMessage 为错误提示 - -## 2 账本 - -### 2.1 获取账本总数 - -```http -GET /ledgers/count -``` - -#### 参数 -无 - - -#### 请求实例 -```http -http://localhost/ledgers/count -``` - -#### 返回实例 - -```json -{ - "data": 2, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账本总数| - - -### 2.2 获取账本列表 - -```http -GET /ledgers?fromIndex={start_index}&count={count} -``` - -#### 参数 -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|query|start_index|否|查询账本的起始序号,默认为0|数字 -|query|count|否|查询返回账本的数量限制,默认最大限制为100,小于0或大于100均返回最大可返回结果集|数字 - - -#### 请求实例 -```http -http://localhost/ledgers?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data": [ - { - "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs" - } - ], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账本哈希列表| -|value|账户哈希| - -### 2.3 获取账本详细信息 - -```http -GET /ledgers/{ledger} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs -``` - -#### 返回实例 - -```json -{ - "data": { - "hash": { - "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs" - }, - "latestBlockHash": { - "value": "67XsKWgqZTBz1NsytKGpyNWHMbMRENWcBj8PEDYQnWiDL" - }, - "latestBlockHeight": 66 - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账本信息| -|hash.value|账本哈希| -|latestBlockHash.value|最新区块哈希 -|latestBlockHeight|账本高度 - - -### 2.4 获取账本成员总数 - -```http -GET /ledgers/{ledger}/participants/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/participants/count -``` - -#### 返回实例 - -```json -{ - "data": 4, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账本成员总数| - - -### 2.5 获取账本成员列表 - -```http -GET /ledgers/{ledger}/participants?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|query|start_index|否|查询成员起始序号,默认为0|数字 -|query|count|否|查询成员返回数量,默认最大返回100,小于0或大于100均返回最大可返回结果集|数字 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/participants?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data": [ - { - "address": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522", - "name": "jd.com", - "id": 0, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - } - }, - { - "address": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha", - "name": "at.com", - "id": 1, - "pubKey": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - }, - { - "address": "5SmMWsqV2kbgrRMjyQFtSq1wvYuPzeRVepHG", - "name": "bt.com", - "id": 2, - "pubKey": { - "value": "mb4AtiGAH7vtPufMDuap2oca2Ww9X6KTkp59Eh5nZjXA5H" - } - }, - { - "address": "5Sm5QFyvN1dVB4GHFxWhDCp8vsJbNkdx31Ds", - "name": "xt.com", - "id": 3, - "pubKey": { - "value": "mb7pGhmmjqYUhxrJJ57C1YxXr9h1AWXv8QVosETyuLhVvH" - } - } - ], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|id|成员唯一标识| -|name|成员名称| -|address|成员地址| -|pubKey.value|成员公钥| - - - -### 2.6 获取账本元数据信息 - -```http -GET /ledgers/{ledger}/metadata -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/metadata -``` - -#### 返回实例 - -```json -{ - "data": { - "participantsHash": { - "value": "j5hQErg4epzNh38FR3EABx8YJqPkLYZoY828giAyKpCXMd" - }, - "seed": "ky3+I/4jIy8oPzL63TKqdoMiyi9WI2zacTazIssyP/4=", - "setting": { - "consensusProvider": "com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider", - "cryptoSetting": { - "supportedProviders": [{ - "algorithms": [{}, {}, {}, {}, {}, {}, {}], - "name": "com.jd.blockchain.crypto.service.classic.ClassicCryptoService" - }, { - "algorithms": [{}, {}, {}], - "name": "com.jd.blockchain.crypto.service.sm.SMCryptoService" - }], - "autoVerifyHash": true, - "hashAlgorithm": 8216 - }, - "consensusSetting": { - "value": "112ky33NcTKBkV..." - } - } - }, - "success": true -} - -``` - -说明 - -|名称|说明| -|---|---| -|seed|账本生成种子| -|consensusSetting|共识配置,每种共识不同,需独立解析| - - - - -### 2.7 获取账本配置信息 - -```http -GET /ledgers/{ledger}/settings -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/settings -``` - -#### 返回实例 - -```json - -{ - "data": { - "consensusProtocol": "com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider", - "consensusSettings": { - "nodes": [{ - "address": "LdeNgXM4J1SybrdUn71KdPhwBYvJzZ6xUG5Rd", - "id": 0, - "networkAddress": { - "host": "127.0.0.1", - "port": 26000, - "secure": false - }, - "pubKey": { - "value": "7VeRMXAkf3zoqr4N2RgLZ83xAv7wurqu6Vxak1V1GHv4Kfe3" - } - }, { - "address": "LdeNwbLhiAHQCVxnXsyKLhgcmUi2fuwYd6jkh", - "id": 1, - "networkAddress": { - "host": "127.0.0.1", - "port": 26010, - "secure": false - }, - "pubKey": { - "value": "7VeRAt79WPnMQ7TsM5cfhy2ERwVLu8fXbDezfFb6bT9BgYaZ" - } - }, { - "address": "LdeNgVjFaUTzsSHySB3ZrBaLiEeZebLkkyWFP", - "id": 2, - "networkAddress": { - "host": "127.0.0.1", - "port": 26020, - "secure": false - }, - "pubKey": { - "value": "7VeR9rnFNzgECCYGF8V3G36xhF3X9rr6YzqfN8h6CojgLpEY" - } - }, { - "address": "LdeNgVAkBAAdKLD1z3Nb7n5vtGujfqWdhx8G7", - "id": 3, - "networkAddress": { - "host": "127.0.0.1", - "port": 26030, - "secure": false - }, - "pubKey": { - "value": "7VeRPkXMyHFvpPf2jayHjiLX8H7CAcTJpF9F1FARogiroSK2" - } - }], - "systemConfigs": [{ - "name": "system.bft", - "value": "true" - }, { - "name": "system.communication.defaultkeys", - "value": "true" - }, { - "name": "system.communication.inQueueSize", - "value": "500000" - }, { - "name": "system.communication.outQueueSize", - "value": "500000" - }, { - "name": "system.communication.useMACs", - "value": "1" - }, { - "name": "system.communication.useSenderThread", - "value": "true" - }, { - "name": "system.communication.useSignatures", - "value": "0" - }, { - "name": "system.debug", - "value": "0" - }, { - "name": "system.initial.view", - "value": "0,1,2,3" - }, { - "name": "system.servers.f", - "value": "1" - }, { - "name": "system.servers.num", - "value": "4" - }, { - "name": "system.shutdownhook", - "value": "true" - }, { - "name": "system.totalordermulticast.checkpoint_period", - "value": "1000" - }, { - "name": "system.totalordermulticast.checkpoint_to_disk", - "value": "false" - }, { - "name": "system.totalordermulticast.global_checkpoint_period", - "value": "120000" - }, { - "name": "system.totalordermulticast.highMark", - "value": "10000" - }, { - "name": "system.totalordermulticast.log", - "value": "true" - }, { - "name": "system.totalordermulticast.log_parallel", - "value": "false" - }, { - "name": "system.totalordermulticast.log_to_disk", - "value": "false" - }, { - "name": "system.totalordermulticast.maxbatchsize", - "value": "400" - }, { - "name": "system.totalordermulticast.nonces", - "value": "10" - }, { - "name": "system.totalordermulticast.revival_highMark", - "value": "10" - }, { - "name": "system.totalordermulticast.state_transfer", - "value": "true" - }, { - "name": "system.totalordermulticast.sync_ckp", - "value": "false" - }, { - "name": "system.totalordermulticast.sync_log", - "value": "false" - }, { - "name": "system.totalordermulticast.timeout", - "value": "2000" - }, { - "name": "system.totalordermulticast.timeout_highMark", - "value": "200" - }, { - "name": "system.totalordermulticast.verifyTimestamps", - "value": "false" - }, { - "name": "system.ttp.id", - "value": "7002" - }] - }, - "cryptoSetting": { - "autoVerifyHash": true, - "hashAlgorithm": 8216, - "supportedProviders": [{ - "algorithms": [{}, {}, {}, {}, {}, {}, {}], - "name": "com.jd.blockchain.crypto.service.classic.ClassicCryptoService" - }, { - "algorithms": [{}, {}, {}], - "name": "com.jd.blockchain.crypto.service.sm.SMCryptoService" - }] - }, - "participantNodes": [{ - "address": "LdeNgXM4J1SybrdUn71KdPhwBYvJzZ6xUG5Rd", - "id": 0, - "name": "a.com", - "pubKey": { - "value": "7VeRMXAkf3zoqr4N2RgLZ83xAv7wurqu6Vxak1V1GHv4Kfe3" - } - }, { - "address": "LdeNwbLhiAHQCVxnXsyKLhgcmUi2fuwYd6jkh", - "id": 1, - "name": "b.com", - "pubKey": { - "value": "7VeRAt79WPnMQ7TsM5cfhy2ERwVLu8fXbDezfFb6bT9BgYaZ" - } - }, { - "address": "LdeNgVjFaUTzsSHySB3ZrBaLiEeZebLkkyWFP", - "id": 2, - "name": "c.com", - "pubKey": { - "value": "7VeR9rnFNzgECCYGF8V3G36xhF3X9rr6YzqfN8h6CojgLpEY" - } - }, { - "address": "LdeNgVAkBAAdKLD1z3Nb7n5vtGujfqWdhx8G7", - "id": 3, - "name": "d.com", - "pubKey": { - "value": "7VeRPkXMyHFvpPf2jayHjiLX8H7CAcTJpF9F1FARogiroSK2" - } - }], - "participantsHash": { - "value": "j5hQErg4epzNh38FR3EABx8YJqPkLYZoY828giAyKpCXMd" - }, - "seed": "932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe" - }, - "success": true -} - - -``` - -说明 - -|名称|说明| -|---|---| -|seed|账本种子信息| -|consensusProtocol|共识协议,以字符串方式显示| -|consensusSettings|共识配置,不同共识协议内容不同,上述示例为BFTSmart相关配置| -|cryptoSetting|密码相关配置| -|cryptoSetting.hashAlgorithm|Hash算法Code(8216代表SHA256)| -|cryptoSetting.autoVerifyHash|是否自动校验Hash| -|cryptoSetting.supportedProviders|支持的算法库| -|participantNodes|参与方列表信息| -|participantNodes.id|参与方序号| -|participantNodes.address|参与方地址| -|participantNodes.name|参与方名称| -|participantNodes.pubKey.value|参与方公钥信息| -|participantsHash.value|参与方根Hash| - - - -## 3 区块 - -### 3.1 获取最新区块 - -```http -GET /ledgers/{ledger}/blocks/latest -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/latest -``` - -#### 返回实例 - -```json -{ - "data": { - "ledgerHash": { - "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs" - }, - "previousHash": { - "value": "6EJZnMc9464DCSU2kgi96RyngEv8YeEfVoJNhH3yZ2v5T" - }, - "transactionSetHash": { - "value": "6LmZtDpMM7xE8FPChACEmLj1PLhfaoVM2rEHRsrV3ohPN" - }, - "userAccountSetHash": { - "value": "67jx7SctrwdSczxxuYjwBocA8fER7V8qcRZUzWamSav5p" - }, - "contractAccountSetHash": { - "value": "67ftaBhPDez24NEB9wiiTM3SNcn1XFz5rb7boYhpbbLXN" - }, - "adminAccountHash": { - "value": "69KEFp9m5iFyAiyGmJ2qPcVxuT79gMChMf9JkStBZe8aa" - }, - "dataAccountSetHash": { - "value": "6LB9gosVWEPG3uvWXkxTcWq22mcwMHVehbiXkavFtr5fZ" - }, - "hash": { - "value": "67XsKWgqZTBz1NsytKGpyNWHMbMRENWcBj8PEDYQnWiDL" - }, - "height": 66 - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|hash|区块哈希| -|ledgerHash|账本哈希| -|previousHash|前置区块哈希| -|transactionSetHash|交易集哈希| -|userAccountSetHash|用户集哈希| -|contractAccountSetHash|合约集哈希| -|adminAccountHash|管理员集哈希| -|dataAccountSetHash|数据账户集哈希| - -### 3.2 根据区块哈希获取区块详细信息 - -```http -GET /ledgers/{ledger}/blocks/hash/{block_hash} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|block_hash|是|区块哈希|字符串| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/67XsKWgqZTBz1NsytKGpyNWHMbMRENWcBj8PEDYQnWiDL -``` - -#### 返回实例 - -[参考](#block-detail) - - -### 3.3 根据区块高度获取区块详细信息 - -```http -GET /ledgers/{ledger}/blocks/height/{block_height} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|block_height|是|区块高度|数字| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/height/66 -``` - -#### 返回实例 - -[参考](#block-detail) - - -### 3.4 根据哈希查询区块总数 - -```http - GET /ledgers/{ledger}/blocks/count/search?keyword={keyword} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是| 区块哈希的全部或者一部分|string| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/count/search?keyword=6D5M -``` - -#### 返回实例 - -```json -{ - "data": 26, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|查询到的区块总数| - -### 3.5 根据哈希查询区块 - -```http - GET /ledgers/{ledger}/blocks/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是| 区块哈希的全部或者一部分|string| -|**query**|**start_index**|否| 查询区块结果起始序号,默认为0|string| -|**query**|**count**|否| 查询区块结果返回数量,默认最大值为100,小于0或大于100均返回最大可返回结果集|string| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/search?keyword=6D5M&fromIndex=0&count=-1 -``` - - -#### 返回实例 - -```json -{ - "data": { - "blocks": [ - { - "hash": "6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb" - } - ] - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|blocks|查询到的区块列表| -|hash|区块哈希值| -|height|区块高度| -|txCount|区块内交易数量| - -## 4 交易 - -### 4.1 获取账本交易总数 - -```http -GET /ledgers/{ledger}/txs/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/count -``` - -##### 返回实例 - -```json -{ - "data": 688, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|交易数量| - -### 4.2 根据区块高度查询区块内的交易数量 - -```http -GET /ledgers/{ledger}/blocks/height/{block_height}/txs/additional-count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|block_height|是|区块高度|数字| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/height/66/txs/additional-count - -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb/txs/additional-count -``` - -#### 返回实例 - -```json -{ - "data": 86, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|交易数量| - - -### 4.3 根据区块哈希查询区块内的交易数量 - -```http -GET /ledgers/{ledger}/blocks/hash/{block_hash}/txs/additional-count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|block_hash|是|区块哈希|字符串| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb/txs/additional-count -``` - -#### 返回实例 - -```json -{ - "data": 86, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|交易数量| - - -### 4.4 获取指定高度的区块交易列表 - -```http -GET /ledgers/{ledger}/blocks/height/{height}/txs?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|height|是|区块高度|数字| -|query|start_index|否|查询交易的起始序号,默认为0|数字| -|query|count|否|查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/height/66/txs?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data": [ - { - "blockHeight": 1, - "executionState": "SUCCESS", - "transactionContent": { - "ledgerHash": { - "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs" - }, - "operations": [ - { - "userID": { - "address": { - "value": "5SmBgzsrnY6u9Y7DgSSkXfTkCgp83hiFin3v" - }, - "pubKey": { - "value": "mb5kukaqjWtXyAerfHU1JDtVwabSeBU5c3khMZbNh7R8VJ" - } - } - }, - { - "accountID": { - "address": { - "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha" - }, - "pubKey": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - } - }, - { - "contractID": { - "address": { - "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha" - }, - "pubKey": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - }, - "chainCode": "----------" - }, - { - "contractAddress": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - }, - "event": "----------", - "args": "----------" - }, - { - "writeSet": [{ - "key": "jdchain", - "value": { - "type": "TEXT", - "value": { - "value": "----------" - } - }, - "expectedVersion": 0 - }], - "accountAddress": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - } - ], - "hash": { - "value": "6BLtM1agb7ERKoN5AJgZKiTjzdS7BpjgzQNYK8ZeDqotA" - } - }, - "endpointSignatures": [ - { - "digest": { - "value": "42pbfM5YKnf39Gitr4UsjTCzhhnJjwNyi8MnLFYgP4VKewTLzHitzArHEMrCt3hZYUe5ex9XvqtmiCoWpeAbdc31F" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - } - } - ], - "nodeSignatures": [ - { - "digest": { - "value": "66SQ95SbDaApAJhN2NsFx5sfAQTxsWhMW26D5iPqXc1jZU9rJEhRnqT1nzt62ZAcCvsfrjEsay3MxqXYA5tWPoA2U" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - } - } - ] - } - ], - "success": true -} -``` - - -说明 - -|名称|说明| -|---|---| -|executionState|交易执行结果| -|transactionContent.hash|交易的哈希| -|transactionContent.operations|交易的操作列表| -|endpointSignatures|终端签名列表| -|nodeSignatures|节点的签名列表| - -### 4.5 获取指定哈希的区块的交易列表 - -```http -GET /ledgers/{ledger}/blocks/hash/{block_hash}/txs?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|block_hash|是|区块哈希|字符串| -|query|start_index|否|查询交易的起始序号,默认为0|数字| -|query|count|否|查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/blocks/hash/6D5MJZnybT69bXET5QdCZdLGT16rZBJEjxLkANmDuykcb/txs?fromIndex=0&count=-1 -``` - -#### 返回实例 - -[参考](#tx-list) - - -### 4.6 获取交易详细信息 - -```http -GET /ledgers/{ledger}/txs/hash/{tx_hash} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|tx_hash|是|交易哈希|字符串| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/hash/6BLtM1agb7ERKoN5AJgZKiTjzdS7BpjgzQNYK8ZeDqotA -``` - -#### 返回实例 - -```json -{ - "data": { - "blockHeight": 1, - "executionState": "SUCCESS", - "transactionContent": { - "ledgerHash": { - "value": "657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs" - }, - "operations": [ - { - "userID": { - "address": { - "value": "5SmBgzsrnY6u9Y7DgSSkXfTkCgp83hiFin3v" - }, - "pubKey": { - "value": "mb5kukaqjWtXyAerfHU1JDtVwabSeBU5c3khMZbNh7R8VJ" - } - } - }, - { - "accountID": { - "address": { - "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha" - }, - "pubKey": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - } - }, - { - "contractID": { - "address": { - "value": "5SmA98VknTbZ1Z7fmbNPHBuN2pbD89ogy8Ha" - }, - "pubKey": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - }, - "chainCode": "----------" - }, - { - "contractAddress": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - }, - "event": "----------", - "args": "----------" - }, - { - "writeSet": [{ - "key": "jdchain", - "value": { - "type": "TEXT", - "value": { - "value": "----------" - } - }, - "expectedVersion": 0 - }], - "accountAddress": { - "value": "mbC8hzmYBz2SsLLqwoBXAJiGeHrCnByBEvcaUZWscAiPqR" - } - } - ], - "hash": { - "value": "6BLtM1agb7ERKoN5AJgZKiTjzdS7BpjgzQNYK8ZeDqotA" - } - }, - "endpointSignatures": [ - { - "digest": { - "value": "42pbfM5YKnf39Gitr4UsjTCzhhnJjwNyi8MnLFYgP4VKewTLzHitzArHEMrCt3hZYUe5ex9XvqtmiCoWpeAbdc31F" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - } - } - ], - "nodeSignatures": [ - { - "digest": { - "value": "66SQ95SbDaApAJhN2NsFx5sfAQTxsWhMW26D5iPqXc1jZU9rJEhRnqT1nzt62ZAcCvsfrjEsay3MxqXYA5tWPoA2U" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - } - } - ] - }, - "success": true -} -``` - -说明 - -[参考](#tx-keyword) - - -### 4.7 根据哈希查询交易总数 - -```http - GET /ledgers/{ledgers}/txs/count/search?keyword={keyword} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledgers**|是|所要搜索的账本范围,需要完整的账本哈希|string| -|**query**|**keyword**|是|交易哈希,签名者公钥,或者节点公钥的全部或者部分的|string| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/search?keyword=6BLt -``` - -#### 返回实例 - -```json -{ - "data": 36, - "success": true -} -``` - - -说明 - -|名称|说明| -|---|---| -|data|指定交易数量| - - -### 4.8 根据哈希查询交易 - -```http - GET /ledgers/{ledgers}/txs/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledgers**|是|所要搜索的账本范围,需要完整的账本哈希|string| -|**query**|**keyword**|是|交易哈希,签名者公钥,或者节点公钥的全部或者部分的|string| -|**query**|**start_index**|否|查询交易的起始序号,默认为0|数字| -|**query**|**count**|否|查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/txs/search?keyword=6BLt -``` - - -#### 返回 - -```json -{ - "data": { - "txs": [ - { - "hash": "6L3ehswCmC1jqBfvGJP9vaPx8qxkLsieu2aRgYepmkiw3" - } - ] - }, - "success": true -} -``` - -## 5 用户 - -### 5.1 获取用户总数 - -```http -GET /ledgers/{ledger}/users/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/count -``` - -#### 返回实例 - -```json -{ - "data": 4, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|用户总数| - - -### 5.2 获取用户列表 - -```http -GET /ledgers/{ledger}/users?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|query|start_index|否|查询用户的起始序号,默认为0|数字| -|query|count|否|查询返回用户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data":[{ - "address": { - "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - }, - "rootHash": { - "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522" - } - }], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|用户地址| -|pubKey.value|用户公钥| - - -### 5.3 获取用户详细信息 - -```http -GET /ledgers/{ledger}/users/address/{address} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|用户地址|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/address/55SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522 -``` - -#### 返回实例 - -```json -{ - "data": { - "address": { - "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522" - }, - "pubKey": { - "value": "mb5kbwzACnhK9P1dVxgMPB2ySJLFyJKQbHpH7T9oRK3LpS" - }, - "rootHash": { - "value": "5SmFzgFtHtpbJwMCsmWTwjNGTk6SeMKU1522" - } - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|用户地址| -|pubKey.value|用户公钥| -|rootHash.value|用户根Hash| - - -### 5.4 用户查询数量 - -```http - GET /ledgers/{ledger}/users/count/search?keyword={keyword} -``` - -#### 说明 - -用户有公钥和地址两个属性,可以通过公钥或者地址查找特定用户数量,也可以返回全部用户的数量 - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是| 用户的公钥或者地址的全部或者部分|string| -|**query**|**start_index**|否|查询用户的起始序号,默认为0|数字| -|**query**|**count**|否|查询返回用户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/count/search?keyword=5Sm -``` - -#### 返回实例 - -```json -{ - "data": 4, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|用户数量| - -### 5.5 用户查询 - -```http - GET /ledgers/{ledger}/users/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 说明 - -用户有公钥和地址两个属性,可以通过公钥或者地址查找特定用户,也可以返回全部用户的列表 - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是| 用户的公钥或者地址的全部或者部分|string| -|**query**|**start_index**|否|查询用户的起始序号,默认为0|数字| -|**query**|**count**|否|查询返回用户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/users/search?keyword=5Sm&fromIndex=0&count=-1 -``` - - -#### 返回实例 - -```json -{ - "data": { - "users": [ - { - "address": { - "value": "5SmAGKgmXyj5VsVvJgHbYCJ67iTizwSkNpw1" - }, - "pubKey": { - "value": "mb97eG4bba2EjrgjXYiD9chAstjg4HaNuV5xgCtSHc5TeB" - } - } - ] - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|用户地址| -|pubKey.value|用户公钥| -|rootHash.value|用户根Hash| - -## 6 数据账户 - -### 6.1 获取账户列表 - -```http -GET /ledgers/{ledger}/accounts?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|query|start_index|否|查询数据账户的起始序号,默认为0|数字| -|query|count|否|查询返回数据账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data":[{ - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "rootHash": { - "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - }], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| -|rootHash.value|默克尔树根哈希| - - -### 6.2 获取账户详细信息 - -```http -GET /ledgers/{ledger}/accounts/address/{address} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|账户地址|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa -``` - -#### 返回实例 - -```json -{ - "data": { - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "rootHash": { - "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| -|rootHash.value|默克尔树根哈希| - - -### 6.3 获取账户总数 - -```http -GET /ledgers/{ledger}/accounts/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/count -``` - -#### 返回实例 - -```json -{ - "data": 18, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账户数量| - - -### 6.4 查询数据账户匹配的数量 - -```http -GET /ledgers/{ledger}/accounts/count/search?keyword={keyword} -``` - -#### 说明 - -通过账户的公钥和地址的全部或者部分查询特定账户的总数量,也可以通过KV值的Key来查询含有该Key的账户的总数量 - - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|字符串 -|**query**|**keyword**|是|数据账户的公钥或者地址的全部或者部分,或者是KV值的key|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/count/search?keyword=jd -``` - -#### 返回实例 - -```json -{ - "data": 2, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|账户数量| - - -### 6.5 查询数据账户 - -```http - GET /ledgers/{ledger}/accounts/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 说明 - -通过账户的公钥和地址的全部或者部分查询特定账户,也可以通过KV值的Key来查询含有该Key的账户 - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是| 数据账户的公钥或者地址的全部或者部分,或者是KV值的key|string| -|**query**|**start_index**|否|查询数据账户的起始序号,默认为0|数字| -|**query**|**count**|否|查询返回数据账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/search?keyword=5Sm5V&fromIndex=0&count=-1 -``` - - -#### 返回实例 - -```json -{ - "data": { - "accounts": [ - { - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - } - ] - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| -|rootHash.value|数据账户根Hash| - - -### 6.6 获取某数据账户KV总数 - -```http - GET /ledgers/{ledger}/accounts/address/{address}/entries/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|账户地址|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/entries/count -``` - -#### 返回实例 - -```json -{ - "data": 66, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|KV总数| - - -### 6.7 获取某数据账户KV详情 - -```http - GET/POST /ledgers/{ledger}/accounts/address/{address}/entries?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|账户地址|字符串 -|form|keys|是|key详细内容列表|字符串 -|query|start_index|否|查询数据账户对应KV的起始序号,默认为0|数字| -|query|count|否|查询返回数据账户对应KV的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -> keys说明: - 1)keys使用表单方式提交,且keys为需要查询Key的列表,列表中每个Key都需要为完整Key - 2)Key提交方式使用GET或POST均可 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/entries -``` - -说明:表单提交参数为keys={"jd", "jdchain"} - - -#### 返回实例 - -```json -{ - "data": [ - { - "key": "jd", - "version": 0, - "type": "TEXT", - "value": "www.jd.com" - }, - { - "key": "jdchain", - "version": 0, - "type": "TEXT", - "value": "www.blockchain.com" - }], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|key|键| -|version|版本号| -|type|value类型| -|value|值| - - - - -### 6.8 获取某数据账户KV整个历史详情 - -```http - GET/POST /ledgers/{ledger}/accounts/{address}/entries-version -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|账户地址|字符串 -|form|KVInfoVO|是|Key相关信息|对象 - -KVInfoVO对应格式如下: - -```json - -{ - "data": [{ - "key": "zhangsan", - "version": [0, 1, 2] - }, { - "key": "lisi", - "version": [0, 1] - }] -} - -``` - -KVInfoVO说明: - + 1)支持多个Key作为入参; - - + 2)每个Key支持多个version; - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/entries-version -``` - - -#### 返回实例 - -```json -{ - "data": [ - { - "key": "jd", - "version": 0, - "type": "TEXT", - "value": "www.jd.com" - }, - { - "key": "jdchain", - "version": 0, - "type": "TEXT", - "value": "www.blockchain.com" - }], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|key|键| -|version|版本号| -|type|value类型| -|value|值| - -### 6.9 查询某数据账户键数量 -``` -GET /ledgers/{ledger}/accounts/address/{address}/keys/count/search?keyword={keyword} -``` -#### 参数 -请求类型 | 名称 | 是否必需 | 说明 | 数据类型 ---- | --- | --- | --- | --- -path | ledger | 是 | 所要搜索的账本,需要完整的账本哈希 | string -path | address | 是 | 所要搜索的数据账户地址,需要完整的数据账户地址 | string -query | keyword | 否 | 键的部分字符,空表示全部 | string - -#### 请求实例 -``` -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/keys/count/search?keyword=j -``` -#### 返回实例 -``` -{ "data": 66, "success": true } -``` -说明 - -名称 | 说明 ---- | --- -data | 条件查询键总数 - -### 6.10 查询某数据账户键 -``` -GET /ledgers/{ledger}/accounts/address/{address}/keys/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` -#### 参数 -请求类型 | 名称 | 是否必需 | 说明 | 数据类型 ---- | --- | --- | --- | --- -path | ledger | 是 | 所要搜索的账本,需要完整的账本哈希 | string -path | address | 是 | 所要搜索的数据账户地址,需要完整的数据账户地址 | string -query | keyword | 否 | 键的部分字符,空表示全部 | string -query | start_index | 否 | 查询数据账户对应Key的起始序号,默认为0 | 数字 -query | count | 否 | 查询返回数据账户对应Key的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集 | 数字 - -#### 请求实例 -``` -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/accounts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa/keys/search?keyword=j&fromIndex=0&count=-1 -``` -#### 返回实例 -``` -{ "data": [ { "key": "jd" }, { "key": "jdchain" }], "success": true } -``` -说明 - -名称 | 说明 ---- | --- -key | 键 - -## 7 搜索 - -### 7.1 搜索区块链 - -```http - GET /ledgers/{ledger}/all/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 说明 - -通过关键字搜索区块数据,支持区块哈希,交易哈希,用户公钥和地址,合约公钥和地址,数据账户哈希和地址的搜索 - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本,需要完整的账本哈希|string| -|**query**|**keyword**|是|关键字|string| -|**query**|**start_index**|否|查询匹配结果的起始序号,默认为0|数字| -|**query**|**count**|否|查询匹配结果的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/all/search?keyword=5Sm5V&fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "message": "OK", - "code": 0, - "data": { - "blocks": ..., - "txs": ..., - "users": ..., - "accounts": ..., - "contracts": ..., - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|blocks|[参考](#query-blocks-result)| -|txs|[参考](#query-txs-result)| -|users|[参考](#query-users-result)| -|accounts|[参考](#query-accounts-result)| -|contracts|[参考](#query-contracts-result)| - -## 8 合约 - -### 8.1 获取合约列表 - -```http -GET /ledgers/{ledger}/contracts?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|query|start_index|否|查询合约的起始序号,默认为0|数字| -|query|count|否|查询返回合约的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data": [{ - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "rootHash": { - "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - }], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| -|rootHash.value|默克尔树根哈希| - - -### 8.2 获取合约详细信息 - -```http -GET /ledgers/{ledger}/contracts/address/{address} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 -|path|address|是|合约地址|字符串 - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/address/5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa -``` - -#### 返回实例 - -```json -{ - "data": { - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "rootHash": { - "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| -|rootHash.value|默克尔树根哈希| - -### 8.3 获取合约总数 - -```http -GET /ledgers/{ledger}/contracts/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串 - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/count -``` - -#### 返回实例 - -```json -{ - "data": 27, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|合约数量| - - -### 8.4 查询指定合约数量 - -```http -GET /ledgers/{ledger}/contracts/count/search?keyword={keyword} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本范围,需要完整的账本哈希|string| -|**query**|**keyword**|是| 合约的公钥或者地址的全部或者一部分|string| - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/count/search?keyword=5Sm2 -``` - -#### 返回实例 - -```json -{ - "data": 2, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|合约数量| - -### 8.5 合约查询 - -```http - GET /ledgers/{ledger}/contracts/search?keyword={keyword}&fromIndex={start_index}&count={count} -``` - -#### 说明 - -合约有公钥和地址两个属性,可以通过合约的这两个属性查询特定合约,也可以返回一个当前所有合约的列表 - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|**path**|**ledger**|是|所要搜索的账本范围,需要完整的账本哈希|string| -|**query**|**keyword**|是| 合约的公钥或者地址的全部或者一部分|string| -|**query**|**start_index**|否|查询合约的起始序号,默认为0|数字| -|**query**|**count**|否|查询返回合约的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/contracts/earch?keyword=5Sm2&fromIndex=0&count=-1 -``` - - -#### 返回 - -```json -{ - "data": { - "contracts": [ - { - "address": { - "value": "5Sm4gWXrNpDWW9Boi4xZCzZMHboRvEDm29Fa" - }, - "rootHash": { - "value": "6GiAH2PBRLnoE724ia83bKVijkKsNuNU5danA4AAi5qMM" - }, - "pubKey": { - "value": "mavweXqvKGUAJzSxE9S15pV7c7qe9bgUn5R1HwpqmXVTUs" - } - } - ] - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|合约地址| -|pubKey.value|合约公钥| -|rootHash|合约根Hash| - -## 9 用户自定义事件 - -### 9.1 获取事件账户列表 - -```http -GET /ledgers/{ledger}/events/user/accounts?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|query|start_index|否|查询的起始序号,默认为0|数字| -|query|count|否|查询返回事件账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts?fromIndex=0&count=-1 -``` - -#### 返回实例 - -```json -{ - "data":[ - { - "address":{ - "value":"LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1" - }, - "pubKey":{ - "value":"7VeRBi3xDfT1E11vFs9q5Q9gFo23RR7SoobPzivqxw9Uubzq" - } - } - ], - "success":true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| - -### 9.2 获取事件账户 - -```http -GET /ledgers/{ledger}/events/user/accounts/{address} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|address|账户地址|是|事件账户地址|字符串| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1 -``` - -#### 返回实例 - -```json -{ - "data":[ - { - "address":{ - "value":"LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1" - }, - "pubKey":{ - "value":"7VeRBi3xDfT1E11vFs9q5Q9gFo23RR7SoobPzivqxw9Uubzq" - } - } - ], - "success":true -} -``` - -说明 - -|名称|说明| -|---|---| -|address.value|账户地址| -|pubKey.value|账户公钥| - -### 9.3 获取事件账户总数 - -```http -GET /ledgers/{ledger}/events/user/accounts/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/count -``` - -#### 返回实例 - -```json -{ - "data": 1, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|事件账户数量| - -### 9.4 获取事件名数量 - -```http -GET /ledgers/{ledger}/events/user/accounts/{address}/names/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|address|是|事件账户地址|字符串| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names/count -``` - -#### 返回实例 - -```json -{ - "data": 2, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|事件名数量| - -### 9.5 获取事件名列表 - -```http -GET /ledgers/{ledger}/events/user/accounts/{address}/names?fromIndex={start_index}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|address|是|事件账户地址|字符串| -|query|start_index|否|查询的起始序号,默认为0|数字| -|query|count|否|查询返回事件账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names?fromIndex=0&count=100 -``` - -#### 返回实例 - -```json -{ - "data": ["test1", "test2"], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|事件名数量数组| - -### 9.6 获取最新事件 - -```http -GET /ledgers/{ledger}/events/user/accounts/{address}/names/{event_name}/latest -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|address|是|事件账户地址|字符串| -|path|event_name|是|事件名|字符串| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names/test1/latest -``` - -#### 返回实例 - -```json -{ - "data": { - "sequence": 0, - "transactionSource": { - "value": "j5rENX3rsdEgi5toeNUUv7ycUUivjNxAUb9Fme6oLCU851" - }, - "blockHeight": 10, - "contractSource": "", - "eventAccount": { - "value": "LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1" - }, - "name": "test1", - "content": { - "nil": false, - "bytes": { - "value": "Ctt6Eur" - }, - "type": "TEXT", - "value": "imuge" - } - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|sequence|事件序列| -|transactionSource.value|交易哈希| -|blockHeight|时间产生区块高度| -|contractSource|合约地址| -|eventAccount.value|事件账户地址| -|name|事件名| -|content.nil|事件内容是否为空| -|content.bytes.value|事件内容字节| -|content.type|事件内容类型| -|content.value|事件内容| - -### 9.7 获取事件数量 - -```http -GET /ledgers/{ledger}/events/user/accounts/{address}/names/{event_name}/count -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|address|是|事件账户地址|字符串| -|path|event_name|是|事件名|字符串| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names/test1/count -``` - -#### 返回实例 - -```json -{ - "data": 1, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|事件数量| - -### 9.8 获取事件列表 - -```http -GET /ledgers/{ledger}/events/user/accounts/{address}/names/{event_name}?fromSequence={from_sequence}&count={count} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型| -|---|---|---|---|---| -|path|ledger|是|账本哈希|字符串| -|path|address|是|事件账户地址|字符串| -|path|event_name|是|事件名|字符串| -|query|from_sequence|否|查询的起始序号,默认为0|数字| -|query|count|否|查询返回事件的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| - - -#### 请求实例 -```http -http://localhost/ledgers/657TQAw6ssVoeKniWGwbovk7njvCTvikPambM9eBv6ezs/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names/test1?fromSequenct=0&count=100 -``` - -#### 返回实例 - -```json -{ - "data": [{ - "sequence": 0, - "transactionSource": { - "value": "j5rENX3rsdEgi5toeNUUv7ycUUivjNxAUb9Fme6oLCU851" - }, - "blockHeight": 10, - "contractSource": "", - "eventAccount": { - "value": "LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1" - }, - "name": "test1", - "content": { - "nil": false, - "bytes": { - "value": "Ctt6Eur" - }, - "type": "TEXT", - "value": "imuge" - } - }], - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|data|事件列表| -|sequence|事件序列| -|transactionSource.value|交易哈希| -|blockHeight|时间产生区块高度| -|contractSource|合约地址| -|eventAccount.value|事件账户地址| -|name|事件名| -|content.nil|事件内容是否为空| -|content.bytes.value|事件内容字节| -|content.type|事件内容类型| -|content.value|事件内容| - -## 10.权限对外提供的API接口使用 -### 10.1根据角色获取权限信息 -```http -GET /ledgers/{ledgerHash}/authorization/role/{roleName} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|get|ledger|是|账本哈希|字符串 -|--|roleName|是|角色名|字符串 - - -#### 请求实例 -```http -http://localhost:11000/ledgers/j5pSJLyVpS8QG2wL95fiDWHHnweh2YdqNhgmnb64SBMjUh/authorization/role/DEFAULT -``` - -#### 返回实例 - -```json -{ - "data": { - "roleName": "DEFAULT", - "transactionPrivilege": { - "privilege": [ - "DIRECT_OPERATION", - "CONTRACT_OPERATION" - ], - "permissionCount": 2 - }, - "ledgerPrivilege": { - "privilege": [ - "CONFIGURE_ROLES", - "AUTHORIZE_USER_ROLES", - "SET_CONSENSUS", - "SET_CRYPTO", - "REGISTER_PARTICIPANT", - "REGISTER_USER", - "REGISTER_DATA_ACCOUNT", - "REGISTER_CONTRACT", - "UPGRADE_CONTRACT", - "SET_USER_ATTRIBUTES", - "WRITE_DATA_ACCOUNT", - "APPROVE_TX", - "CONSENSUS_TX", - "REGISTER_EVENT_ACCOUNT", - "WRITE_EVENT_ACCOUNT" - ], - "permissionCount": 15 - }, - "version": 0 - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|roleName|角色名称| -|transactionPrivilege|交易权限| -|transactionPrivilege -> privilege|交易权限->权限类别| -|transactionPrivilege -> permissionCount|交易权限->权限总数| -|ledgerPrivilege|账本权限| -|ledgerPrivilege -> privilege|账本权限->权限类别| -|ledgerPrivilege -> permissionCount|账本权限->权限总数| - -### 10.2根据用户获取权限信息 - -```http -GET /ledgers/{ledgerHash}/authorization/user/{userAddress} -``` - -#### 参数 - -|请求类型|名称|是否必需|说明|数据类型 -|---|---|---|---|---| -|get|ledger|是|账本哈希|字符串 -|--|userAddress|是|用户地址|字符串 - - -#### 请求实例 -```http -http://localhost:11000/ledgers/j5pSJLyVpS8QG2wL95fiDWHHnweh2YdqNhgmnb64SBMjUh/authorization/user/LdeNwH71wxtbf1UM8ExRG8qbPnu17MdnRSVva -``` - -#### 返回实例 - -```json -{ - "data": { - "userAddress": { - "value": "LdeNwH71wxtbf1UM8ExRG8qbPnu17MdnRSVva" - }, - "transactionPrivilegesBitset": { - "privilege": [ - "DIRECT_OPERATION" - ], - "permissionCount": 1 - }, - "userRole": [ - "MANAGER1", - "MANAGER0" - ], - "ledgerPrivilegesBitset": { - "privilege": [ - "CONFIGURE_ROLES", - "REGISTER_USER" - ], - "permissionCount": 2 - } - }, - "success": true -} -``` - -说明 - -|名称|说明| -|---|---| -|userRole|用户角色| -|transactionPrivilegesBitset|交易权限集| -|ledgerPrivilegesBitset|账本权限集| diff --git a/deploy/deploy-gateway/src/main/resources/docs/code_example.MD b/deploy/deploy-gateway/src/main/resources/docs/code_example.MD deleted file mode 100644 index 2f429d3f..00000000 --- a/deploy/deploy-gateway/src/main/resources/docs/code_example.MD +++ /dev/null @@ -1,361 +0,0 @@ -# 1. maven坐标 -```java - - com.jd.blockchain - sdk-client - 1.4.0.RELEASE - - - com.jd.blockchain - contract-starter - 1.4.0.RELEASE - - - com.jd.blockchain - crypto-classic - 1.4.0.RELEASE - - - - com.jd.blockchain - crypto-sm - 1.4.0.RELEASE - -``` -# 2. 数据快速上链 -## 2.1. 服务连接 - -```java - //使用已注册用户信息进行连接; - String GW_PUB_KEY = "3snxxx"; - String GW_PRIV_KEY = "177xxx"; - String GW_PASSWORD = "xxx"; - PrivKey gwPrivkey0 = KeyGenUtils.decodePrivKey(GW_PRIV_KEY, GW_PASSWORD); - PubKey gwPubKey0 = KeyGenUtils.decodePubKey(GW_PUB_KEY); - BlockchainKeypair adminKey = new BlockchainKeypair(gwPubKey0, gwPrivkey0); - //创建服务代理 - final String GATEWAY_IP = "127.0.0.1"; - final int GATEWAY_PORT = 80; - final boolean SECURE = false; - GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(GATEWAY_IP, GATEWAY_PORT, SECURE, - adminKey); - // 创建服务代理; - BlockchainService service = serviceFactory.getBlockchainService(); - HashDigest[] ledgerHashs = service.getLedgerHashs(); - // 获取当前账本Hash - HashDigest ledgerHash = ledgerHashs[0]; -``` -## 2.2. 用户注册 -```java - // 创建服务代理; - BlockchainService service = serviceFactory.getBlockchainService(); - // 在本地定义注册账号的 TX; - TransactionTemplate txTemp = service.newTransaction(ledgerHash); - BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate(); - - txTemp.users().register(user.getIdentity()); - - // TX 准备就绪; - PreparedTransaction prepTx = txTemp.prepare(); - // 使用私钥进行签名; - prepTx.sign(adminKey); - // 提交交易; - prepTx.commit(); -``` -## 2.3. 数据账户注册 -```java - // 创建服务代理; - BlockchainService service = serviceFactory.getBlockchainService(); - // 在本地定义注册账号的 TX; - TransactionTemplate txTemp = service.newTransaction(ledgerHash); - BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate(); - - txTemp.dataAccounts().register(dataAccount.getIdentity()); - - // TX 准备就绪; - PreparedTransaction prepTx = txTemp.prepare(); - // 使用私钥进行签名; - prepTx.sign(adminKey); - - // 提交交易; - prepTx.commit(); -``` -## 2.4. 写入数据 -```java - // 创建服务代理; - BlockchainService service = serviceFactory.getBlockchainService(); - - // 在本地定义注册账号的 TX; - TransactionTemplate txTemp = service.newTransaction(ledgerHash); - - // -------------------------------------- - // 将商品信息写入到指定的账户中; - // 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引; - String commodityDataAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; - txTemp.dataAccount(commodityDataAccount).setText("ASSET_CODE", "value1", -1); - - // TX 准备就绪; - PreparedTransaction prepTx = txTemp.prepare(); - - String txHash = Base64Utils.encodeToUrlSafeString(prepTx.getHash().toBytes()); - // 使用私钥进行签名; - prepTx.sign(adminKey); - - // 提交交易; - prepTx.commit(); -``` -## 2.5. 查询数据 - -> 注:详细的查询可参考模块sdk-samples中SDK_GateWay_Query_Test_相关测试用例 - -```java - // 创建服务代理; - BlockchainService service = serviceFactory.getBlockchainService(); - - // 查询区块信息; - // 区块高度; - long ledgerNumber = service.getLedger(ledgerHash).getLatestBlockHeight(); - // 最新区块; - LedgerBlock latestBlock = service.getBlock(ledgerHash, ledgerNumber); - // 区块中的交易的数量; - long txCount = service.getTransactionCount(ledgerHash, latestBlock.getHash()); - // 获取交易列表; - LedgerTransaction[] txList = service.getTransactions(ledgerHash, ledgerNumber, 0, 100); - // 遍历交易列表 - for (LedgerTransaction ledgerTransaction : txList) { - TransactionContent txContent = ledgerTransaction.getTransactionContent(); - Operation[] operations = txContent.getOperations(); - if (operations != null && operations.length > 0) { - for (Operation operation : operations) { - operation = ClientResolveUtil.read(operation); - // 操作类型:数据账户注册操作 - if (operation instanceof DataAccountRegisterOperation) { - DataAccountRegisterOperation daro = (DataAccountRegisterOperation) operation; - BlockchainIdentity blockchainIdentity = daro.getAccountID(); - } - // 操作类型:用户注册操作 - else if (operation instanceof UserRegisterOperation) { - UserRegisterOperation uro = (UserRegisterOperation) operation; - BlockchainIdentity blockchainIdentity = uro.getUserID(); - } - // 操作类型:账本注册操作 - else if (operation instanceof LedgerInitOperation) { - - LedgerInitOperation ledgerInitOperation = (LedgerInitOperation)operation; - LedgerInitSetting ledgerInitSetting = ledgerInitOperation.getInitSetting(); - - ParticipantNode[] participantNodes = ledgerInitSetting.getConsensusParticipants(); - } - // 操作类型:合约发布操作 - else if (operation instanceof ContractCodeDeployOperation) { - ContractCodeDeployOperation ccdo = (ContractCodeDeployOperation) operation; - BlockchainIdentity blockchainIdentity = ccdo.getContractID(); - } - // 操作类型:合约执行操作 - else if (operation instanceof ContractEventSendOperation) { - ContractEventSendOperation ceso = (ContractEventSendOperation) operation; - } - // 操作类型:KV存储操作 - else if (operation instanceof DataAccountKVSetOperation) { - DataAccountKVSetOperation.KVWriteEntry[] kvWriteEntries = - ((DataAccountKVSetOperation) operation).getWriteSet(); - if (kvWriteEntries != null && kvWriteEntries.length > 0) { - for (DataAccountKVSetOperation.KVWriteEntry kvWriteEntry : kvWriteEntries) { - BytesValue bytesValue = kvWriteEntry.getValue(); - DataType dataType = bytesValue.getType(); - Object showVal = ClientResolveUtil.readValueByBytesValue(bytesValue); - System.out.println("writeSet.key=" + kvWriteEntry.getKey()); - System.out.println("writeSet.value=" + showVal); - System.out.println("writeSet.type=" + dataType); - System.out.println("writeSet.version=" + kvWriteEntry.getExpectedVersion()); - } - } - } - } - } - } - - // 根据交易的 hash 获得交易;注:客户端生成 PrepareTransaction 时得到交易hash; - HashDigest txHash = txList[0].getTransactionContent().getHash(); - Transaction tx = service.getTransactionByContentHash(ledgerHash, txHash); - // 获取数据; - String commerceAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; - String[] objKeys = new String[] { "x001", "x002" }; - TypedKVEntry[] kvData = service.getDataEntries(ledgerHash, commerceAccount, objKeys); - - long payloadVersion = kvData[0].getVersion(); - - // 获取数据账户下所有的KV列表 - TypedKVEntry[] kvDatas = service.getDataEntries(ledgerHash, commerceAccount, 0, 100); - if (kvData != null && kvData.length > 0) { - for (TypedKVEntry kvDatum : kvDatas) { - System.out.println("kvData.key=" + kvDatum.getKey()); - System.out.println("kvData.version=" + kvDatum.getVersion()); - System.out.println("kvData.type=" + kvDatum.getType()); - System.out.println("kvData.value=" + kvDatum.getValue()); - } - } -``` - -## 2.6. 合约发布 - -```java - - // 创建服务代理; - BlockchainService service = serviceFactory.getBlockchainService(); - - // 在本地定义TX模板 - TransactionTemplate txTemp = service.newTransaction(ledgerHash); - - // 合约内容读取 - byte[] contractBytes = FileUtils.readBytes(new File("CONTRACT_FILE")); - - // 生成用户 - BlockchainKeypair contractKeyPair = BlockchainKeyGenerator.getInstance().generate(); - - // 发布合约 - txTemp.contracts().deploy(contractKeyPair.getIdentity(), contractBytes); - - // TX 准备就绪; - PreparedTransaction prepTx = txTemp.prepare(); - - // 使用私钥进行签名; - prepTx.sign(adminKey); - - // 提交交易; - TransactionResponse transactionResponse = prepTx.commit(); - - assertTrue(transactionResponse.isSuccess()); - - // 打印合约地址 - System.out.println(contractKeyPair.getIdentity().getAddress().toBase58()); -``` - -## 2.7. 合约执行 - -```java - - // 创建服务代理; - BlockchainService service = serviceFactory.getBlockchainService(); - - // 在本地定义TX模板 - TransactionTemplate txTemp = service.newTransaction(ledgerHash); - - // 合约地址 - String contractAddress = ""; - - // 使用接口方式调用合约 - TransferContract transferContract = txTemp.contract(contractAddress, TransferContract.class); - - // 使用decode方式调用合约内部方法(create方法) - // 返回GenericValueHolder可通过get方法获取结果,但get方法需要在commit调用后执行 - String address = "address"; - String account = "fill account"; - long money = 100000000L; - GenericValueHolder result = ContractReturnValue.decode(transferContract.create(address, account, money)); - - PreparedTransaction ptx = txTemp.prepare(); - - ptx.sign(adminKey); - - TransactionResponse transactionResponse = ptx.commit(); - - String cotractExecResult = result.get(); - - // TransactionResponse也提供了可供查询结果的接口 - OperationResult[] operationResults = transactionResponse.getOperationResults(); - - // 通过OperationResult获取结果 - for (int i = 0; i < operationResults.length; i++) { - OperationResult opResult = operationResults[i]; - System.out.printf("Operation[%s].result = %s \r\n", - opResult.getIndex(), BytesValueEncoding.decode(opResult.getResult())); - } -``` - -## 2.8. 事件账户注册 -```java - BlockchainService service = serviceFactory.getBlockchainService(); - TransactionTemplate txTemp = service.newTransaction(ledgerHash); - - BlockchainKeypair eventAccount = BlockchainKeyGenerator.getInstance().generate(); - txTemp.eventAccounts().register(eventAccount.getIdentity()); - - // TX 准备就绪; - PreparedTransaction prepTx = txTemp.prepare(); - // 使用私钥进行签名; - prepTx.sign(adminKey); - - // 提交交易; - prepTx.commit(); -``` -## 2.9. 事件发布 -```java - BlockchainService service = serviceFactory.getBlockchainService(); - TransactionTemplate txTemp = service.newTransaction(ledgerHash); - - // 发布事件到指定的账户中; - String eventAccount = "GGhhreGeasdfasfUUfehf9932lkae99ds66jf=="; - txTemp.eventAccount(eventAccount).publish("event_name", "string", -1) - .publish("event_name", 0, 0); - - // TX 准备就绪; - PreparedTransaction prepTx = txTemp.prepare(); - - // 使用私钥进行签名; - prepTx.sign(adminKey); - - // 提交交易; - prepTx.commit(); -``` - -## 2.10. 事件监听 - -- 系统事件 -> 目前仅支持新区块产生事件 -```java - EventListenerHandle handler = blockchainService.monitorSystemEvent(ledgerHash, - SystemEvent.NEW_BLOCK_CREATED, 0, new SystemEventListener() { - @Override - public void onEvents(Event[] eventMessages, EventContext eventContext) { - for (Event eventMessage : eventMessages) { - BytesValue content = eventMessage.getContent(); - // content中存放的是当前链上最新高度 - System.out.println(BytesUtils.toLong(content.getBytes().toBytes())); - } - - // 关闭监听的两种方式:1 - eventContext.getHandle().cancel(); - } - }); - - // 关闭监听的两种方式:2 - handler.cancel(); -``` - -- 用户自定义事件 -```java - EventListenerHandle handler = blockchainService.monitorUserEvent(ledgerHash, - eventAccount.getAddress().toBase58(), eventName, 0, new UserEventListener() { - @Override - public void onEvent(Event eventMessage, EventContext eventContext) { - BytesValue content = eventMessage.getContent(); - switch (content.getType()) { - case TEXT: - System.out.println(content.getBytes().toUTF8String()); - break; - case INT64: - System.out.println(BytesUtils.toLong(content.getBytes().toBytes())); - break; - default: - break; - } - - // 关闭监听的两种方式:1 - eventContext.getHandle().cancel(); - } - }); - - // 关闭监听的两种方式:2 - handler.cancel(); -``` \ No newline at end of file diff --git a/deploy/deploy-gateway/src/main/resources/docs/design_contract-dev-manual.md b/deploy/deploy-gateway/src/main/resources/docs/design_contract-dev-manual.md deleted file mode 100644 index 676e1e77..00000000 --- a/deploy/deploy-gateway/src/main/resources/docs/design_contract-dev-manual.md +++ /dev/null @@ -1,436 +0,0 @@ -# 智能合约开发手册 -版本|修改时间|修改人 ----|:--:|---: -V1.0|2020-04-17|huanghaiquan - ---- - - - -### 1. 简介 - - JD Chain 智能合约系统由5个部分组成:合约代码语言、合约引擎、合约账户、合约开发框架、合约开发插件。 - - 合约代码语言是用来编写智能合约的编程语言,合约引擎是解释和执行合约代码的虚拟机。 - - JD Chain 账本中以合约账户的方式对合约代码进行管理。一份部署上链的合约代码需要关联到一个唯一的公钥上,并生成与公钥对应的区块链账户地址,在账本中注册为一个合约账户。在执行之前,系统从账本中读出合约代码并将其加载到合约引擎,由交易执行器调用合约引擎触发合约执行。 - - JD Chain 账本定义了一组标准的账本操作指令,合约代码的执行过程实质上是向账本输出一串操作指令序列,这些指令对账本中的数据产生了变更,形成合约执行的最终结果。 - - 合约开发框架定义了进行合约代码开发中需要依赖的一组编程接口和类库。合约开发插件提供了更方便与IDE集成的合约编译、部署工具,可以简化操作,并与持续集成过程结合。 - - JD Chain 以 Java 语言作为合约代码语言,合约引擎是基于 JVM 构建的安全沙盒。为了实现与主流的应用开发方式无缝兼容, JD Chain 支持以 Maven 来管理合约代码的工程项目,并提供相应的 maven 插件来简化合约的编译和部署。 - - >智能合约是一种可以由计算机执行的合同/协议。不同于现实生活中的合同是由自然语言来编写并约定相关方的权利和义务,智能合约是用合约代码语言来编写,以合约代码的形式存在和被执行。通过账本中的数据状态来表示合同/协议相关条款信息,合约代码的运行过程体现了合同/协议条款的执行,并记录相应的结果。 - -### 2. 快速入门 - - #### 2.1. 准备开发环境 - - 按照正常的 Java 应用开发环境要求进行准备,以 Maven 作为代码工程的构建管理工具,无其它特殊要求。 - - >检查 JDK 版本不低于 1.8 ,Maven 版本不低于 3.0。 - - #### 2.2. 创建合约代码工程 - 创建一个普通的 Java Maven 工程,打开 pom.xml 把 packaging 设为 contract . - - ``` xml - - - 4.0.0 - your.group.id - your.project - 0.0.1-SNAPSHOT - - contract - - - - - - - - - - - - - ``` - - > 注:合约代码工程也是一个普通的 Java Maven 工程,因此尽管不同 IDE 创建 Maven 工程有不同的操作方式,由于对于合约开发而言并无特殊要求,故在此不做详述。 - - #### 2.3. 加入合约开发依赖 - - 在合约代码工程 pom.xml 加入对合约开发 SDK 的依赖: - - ``` xml - - com.jd.blockchain - contract-starter - ${jdchain.version} - - ``` - - #### 2.4. 加入合约插件 - - 在合约代码工程的 pom.xml 加入 contract-maven-plugin 插件: - ``` xml - - com.jd.blockchain - contract-maven-plugin - ${jdchain.version} - true - - ``` - - 完整的 pom.xml 如下: - - ``` xml - - - - 4.0.0 - your.group.id - your.project - 0.0.1-SNAPSHOT - - contract - - - 1.2.0.RELEASE - - - - - - com.jd.blockchain - contract-starter - ${jdchain.version} - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 1.8 - 1.8 - UTF-8 - false - true - false - false - - - - - - com.jd.blockchain - contract-maven-plugin - ${jdchain.version} - true - - - - - - ``` - - #### 2.5. 编写合约代码 - - 2.5.1. **注意事项** - ``` - 1、不允许合约(包括合约接口和合约实现类)使用com.jd.blockchain开头的package; - 2、必须有且只有一个接口使用@Contract注解,且其中的event必须大于等于一个; - 3、使用@Contract注解的接口有且只有一个实现类; - 4、黑名单调用限制(具体黑名单可查看配置文件),需要注意的是,黑名单分析策略会递归分析类实现的接口和父类,也就是说调用一个实现了指定黑名单接口的类也是不允许的; - 目前设置的黑名单如下: - java.io.File - java.io.InputStream - java.io.OutputStream - java.io.DataInput - java.io.DataOutput - java.io.Reader - java.io.Writer - java.io.Flushable - java.nio.channels.* - java.nio.file.* - java.net.* - java.sql.* - java.lang.reflect.* - java.lang.Class - java.lang.ClassLoader - java.util.Random - java.lang.System-currentTimeMillis - java.lang.System-nanoTime - com.jd.blockchain.ledger.BlockchainKeyGenerator - ``` - - 2.5.2. **声明合约** - - ``` java - /** - * 声明合约接口; - **/ - @Contract - public interface AssetContract { - - @ContractEvent(name = "transfer") - String transfer(String address, String from, String to, long amount); - - } - ``` - - 2.5.3. **实现合约** - - ``` java - /** - * 实现合约; - * - * 实现 EventProcessingAware 接口是可选的,目的获得 ContractEventContext 上下文对象, - * 通过该对象可以进行账本操作; - */ - public class AssetContractImpl implements AssetContract, EventProcessingAware { - - // 合约事件上下文; - private ContractEventContext eventContext; - - /** - * 执行交易请求中对 AssetContract 合约的 transfer 调用操作; - */ - public String transfer(String address, String from, String to, long amount) { - //当前账本的哈希; - HashDigest ledgerHash = eventContext.getCurrentLedgerHash(); - //当前账本上下文; - LedgerContext ledgerContext = eventContext.getLedger(); - - //做操作; - // ledgerContext. - - //返回合约操作的结果; - return "success"; - } - - /** - * 准备执行交易中的合约调用操作; - */ - @Override - public void beforeEvent(ContractEventContext eventContext) { - this.eventContext = eventContext; - } - - /** - * 完成执行交易中的合约调用操作; - */ - @Override - public void postEvent(ContractEventContext eventContext, Exception error) { - this.eventContext = null; - } - } - ``` - #### 2.6. 编译打包合约代码 - - 合约代码工程的编译打包操作与普通的 maven 工程是相同的,在工程的根目录下输入以下命令: - - ``` bash - mvn clean package - ``` - - 执行成功之后,在 target 目录中输出合约代码文件 \.\.car 。 - - 如果合约代码加入了除 com.jd.blockchain:contract-starter 之外的其它依赖,默认配置下,第三方依赖包将与 .car 文件一起打包一起部署。(也可以把第三方依赖包独立打包,具体参见以下 “3. 合约插件详细配置” - - > 注意:合约代码虽然利用了 Java 语言,遵照 Java 语法进行编写,但本质上是作为一种运行于受限环境(合约虚拟机)的语言来使用,因而一些 Java 语法和 SDK 的 API 是不被允许使用的,在编译过程中将对此进行检查。 - - #### 2.7. 部署合约代码 - - ##### 2.7.1. 在项目中部署合约代码 - - 如果希望在构建打包的同时将合约代码部署到指定的区块链网络,可以在合约代码工程 pom.xml 的 contract-maven-plugin 插件配置中加入合约部署相关的信息(具体更详细的配置可以参考“3. 合约插件详细配置”)。 - - ``` xml - - com.jd.blockchain - contract-maven-plugin - 1.2.0.RELEASE - true - - - - - j5rpuGWVxSuUbU3gK7MDREfui797AjfdHzvAMiSaSzydu7 - - - - 192.168.10.10 - 8081 - - - - - 3snPdw7i7Po4fYcXFxS4QztR8Dm4kLBdBpjsemuGPZRyZRBmtn5Z5u - - - - - 7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq - 177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x - DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY - - - - - ``` - - 加入部署配置信息之后,对工程执行编译打包操作,输出的合约代码(.car)将自动部署到指定的区块链网络。 - - ``` bash - mvn clean deploy - ``` - ##### 2.7.2. 发布已编译好的car - 如果已经通过插件的打包方式,编译打包完成一个合约文件(.car),可通过命令行的方式进行发布,命令行要求与开发环境一致的Maven环境(包括环境变量及Setting都已配置完成)。 - - ``` bash - mvn com.jd.blockchain:contract-maven-plugin:${version}:deploy - -DcarPath= - -Dledger= - -DgatewayHost= - -DgatewayPort= - -DcontractPubKey= - -DcontractAddress= - -DsignerPubKey= - -DsignerPrivKey= - -DsignerPrivKeyPwd= - ``` - - 各参数说明如下: - - | 参数名 | 含义 |是否必填| - | ---- | ---- | ---- | - | ${version} | 合约插件的版本号 | 否,系统会自动选择发布的最新的RELEASE版本,SNAPSHOT版本必须填写 | - | carPath | 合约文件所在路径 | 是 | - | ledger | 账本Hash(Base58编码) | 否,会自动选择线上第一个账本| - | gatewayHost | 可访问的网关节点地址,域名或IP地址 | 是| - | gatewayPort | 网关节点监听端口 | 是 | - | contractPubKey | 合约账户的公钥(Base58编码)| 否,会自动创建 | - | contractAddress | 合约账户的地址(Base58编码)|否,会根据contractPubKey生成| - | signerPubKey | 合约签名公钥信息(Base58编码)|是| - | signerPrivKey | 合约签名私钥信息(Base58编码)|是| - | signerPrivKeyPwd | 合约签名私钥解密密钥(Base58编码)|是| - - -下面是一个示例,供参考: - -``` bash - mvn com.jd.blockchain:contract-maven-plugin:1.2.0.RELEASE:deploy \ - -DcarPath=/root/jdchain/contracts/contract-test-1.0-SNAPSHOT.car \ - -Dledger=j5tW5HUvMjEtm2yB7E6MHoSByoH1DXvMwvF2HurEgMSaLW \ - -DgatewayHost=127.0.0.1 \ - -DgatewayPort=11000 \ - -DcontractPubKey= 7VeRBsHM2nsGwP8b2ufRxz36hhNtSqjKTquzoa4WVKWty5sD \ - -DcontractAddress= LdeNt7sEmTirh9PmE7axKvA2txTrbB9kxz6KB \ - -DsignerPubKey=7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq \ - -DsignerPrivKey=177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x \ - -DsignerPrivKeyPwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY - ``` - - - > 重点说明: - 命令行中输入参数的优先级高于配置文件,就是说通过2.7.1方式发布合约时也可以采用命令行的参数(指-D相关配置),其优先级高于配置文件。 - -### 3. 合约插件详细配置 - - ``` xml - - com.jd.blockchain - contract-maven-plugin - 1.2.0.RELEASE - true - - - - - - false - - - - - 1 - - - MB - - - - - - - - - - - - - - - - -
-
- - - - - - - - - - -
-
-
- ``` - -### 4. 最简化合约插件配置示例 - -在pom.xml中有部分配置是非必填项,下面是一份最简化的合约发布(deploy)配置示例,供参考: - - - ``` xml - - com.jd.blockchain - contract-maven-plugin - 1.2.0.RELEASE - true - - - - - - 127.0.0.1 - 8081 - - - - - 7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq - 177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x - DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY - - - - - ``` \ No newline at end of file diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 00000000..2c6822fe --- /dev/null +++ b/docs/api.md @@ -0,0 +1,2924 @@ +# 网关API + +[账本](#2-账本) +- [获取账本总数](#21-获取账本总数) +- [获取账本列表](#22-获取账本列表) +- [获取账本详细信息](#23-获取账本详细信息) +- [获取账本参与方总数](#24-获取账本参与方总数) +- [获取账本参与方列表](#25-获取账本参与方列表) +- [获取账本元数据信息](#26-获取账本元数据信息) +- [获取账本初始化配置信息](#27-获取账本初始化配置信息) +- [获取账本管理数据信息](#28-获取账本管理数据信息) + +[区块](#3-区块) +- [获取最新区块](#31-获取最新区块) +- [根据区块哈希获取区块详细信息](#32-根据区块哈希获取区块详细信息) +- [根据区块高度获取区块详细信息](#33-根据区块高度获取区块详细信息) + +[交易](#4-交易) +- [获取账本交易总数](#41-获取账本交易总数) +- [根据区块高度查询交易数量](#42-根据区块高度查询交易数量) +- [根据区块哈希查询交易数量](#43-根据区块哈希查询交易数量) +- [根据区块高度查询区块内的交易数量](#44-根据区块高度查询区块内的交易数量) +- [根据区块哈希查询区块内的交易数量](#45-根据区块哈希查询区块内的交易数量) +- [获取指定区块高度的交易列表](#46-获取指定区块高度的交易列表) +- [获取指定哈希的区块的交易列表](#47-获取指定哈希的区块的交易列表) +- [获取交易详细信息](#48-获取交易详细信息) + +[用户](#5-用户) +- [获取用户总数](#51-获取用户总数) +- [获取用户列表](#52-获取用户列表) +- [获取用户详细信息](#53-获取用户详细信息) +- [获取指定高度的区块的用户总数](#54-获取指定高度的区块的用户总数) +- [获取指定哈希的区块的用户总数](#55-获取指定哈希的区块的用户总数) +- [根据区块高度查询区块内的用户数量](#56-根据区块高度查询区块内的用户数量) +- [根据区块哈希查询区块内的用户数量](#57-根据区块哈希查询区块内的用户数量) +- [查询最新区块新增用户数量](#58-查询最新区块新增用户数量) + +[角色权限](#6-角色权限) +- [根据角色获取权限信息](#61-根据角色获取权限信息) +- [根据用户获取权限信息](#62-根据用户获取权限信息) + +[数据账户](#7-数据账户) +- [获取账户列表](#71-获取账户列表) +- [获取账户详细信息](#72-获取账户详细信息) +- [获取账户总数](#73-获取账户总数) +- [获取指定高度的区块的数据账户总数](#74-获取指定高度的区块的数据账户总数) +- [获取指定哈希的区块的数据账户总数](#75-获取指定哈希的区块的数据账户总数) +- [根据区块高度查询区块内的数据账户数量](#76-根据区块高度查询区块内的数据账户数量) +- [根据区块哈希查询区块内的数据账户数量](#77-根据区块哈希查询区块内的数据账户数量) +- [获取某数据账户KV总数](#78-获取某数据账户KV总数) +- [获取某数据账户KV详情](#79-获取某数据账户KV详情) +- [获取某数据账户KV详情](#710-获取某数据账户KV详情) +- [获取某数据账户KV整个历史详情](#711-获取某数据账户KV整个历史详情) + +[合约](#8-合约) +- [获取合约总数](#81-获取合约总数) +- [获取指定区块高度的合约总数](#82-获取指定区块高度的合约总数) +- [获取指定区块哈希的合约总数](#83-获取指定区块哈希的合约总数) +- [根据区块高度查询区块内的合约总数](#84-根据区块高度查询区块内的合约总数) +- [根据区块哈希查询区块内的合约总数](#85-根据区块哈希查询区块内的合约总数) +- [获取合约列表](#86-获取合约列表) +- [获取合约详细信息](#87-获取合约详细信息) + +[事件](#9-用户自定义事件) + +- [获取事件账户列表](#91-获取事件账户列表) +- [获取事件账户](#92-获取事件账户) +- [获取事件账户总数](#93-获取事件账户总数) +- [获取事件名数量](#94-获取事件名数量) +- [获取事件名列表](#95-获取事件名列表) +- [获取最新事件](#96-获取最新事件) +- [获取事件数量](#97-获取事件数量) +- [获取事件列表](#98-获取事件列表) + +## 1 API调用说明 + +该文档内的所有api的调用成功和失败均按照以下规则 + +### 1.1 成功 + +```json +{ + "data": ..., + "success": true +} +``` + +说明 + + - success 值为 true 表明api调用成功 + - data 为返回的数据,具体数据类型参考具体的api说明 + +### 1.2 失败 + +```json +{ + "error": { + "errorCode": 5000, + "errorMessage": "未预期的异常! --Unsupported access ledger[6Gw3cK4uazegy4HjoaM81ck9NgYLNoKyBMb7a1TK1jt3d] !" + }, + "success": false +} + +[comment]: <> (```) + +说明 + + - success 值为 false 表明api调用成功 + - errorCode 为异常代码 + - errorMessage 为错误提示 + +## 2 账本 + +### 2.1 获取账本总数 + +​```http +GET /ledgers/count +``` + +#### 参数 +无 + + +#### 请求实例 +```http +http://localhost:8080/ledgers/count +``` + +#### 返回实例 + +```json +{ + "data": 2, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|账本总数| + + +### 2.2 获取账本列表 + +```http +GET /ledgers +``` + +#### 参数 +无 + + +#### 请求实例 +```http +http://localhost:8080/ledgers +``` + +#### 返回实例 + +```json +{ + "data" : [ + "j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp" + ], + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|账本哈希列表| + +### 2.3 获取账本详细信息 + +```http +GET /ledgers/{ledger} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型 | +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串 | + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp +``` + +#### 返回实例 + +```json +{ + "success" : true, + "data" : { + "hash" : "j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp", + "latestBlockHeight" : 0, + "latestBlockHash" : "j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp" + } +} +``` + +说明 + +|名称|说明| +|---|---| +|data|账本信息| +|hash|账本哈希| +|latestBlockHash | 最新区块哈希 | +|latestBlockHeight| 最新账本高度 | + + +### 2.4 获取账本参与方总数 + +```http +GET /ledgers/{ledger}/participants/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型 | +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串 | + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/participants/count +``` + +#### 返回实例 + +```json +{ + "data": 4, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|账本参与方总数| + + +### 2.5 获取账本参与方列表 + +```http +GET /ledgers/{ledger}/participants +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型 | +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串 | + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/participants +``` + +#### 返回实例 + +```json +{ + "data" : [ + { + "pubKey" : "7VeRFF1ednwhrFoe5cngKwPUJ2N4iFKD9Jt53GxSCc1MmPQ6", + "participantNodeState" : "CONSENSUS", + "id" : 2, + "address" : { + "value" : "LdeNwsiuo7n6HULWhNKc87PBXJXAfGKFon9RE" + }, + "name" : "2" + }, + { + "participantNodeState" : "CONSENSUS", + "pubKey" : "7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW", + "id" : 1, + "name" : "1", + "address" : { + "value" : "LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY" + } + }, + { + "pubKey" : "7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn", + "participantNodeState" : "CONSENSUS", + "address" : { + "value" : "LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw" + }, + "name" : "0", + "id" : 0 + }, + { + "id" : 3, + "address" : { + "value" : "LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6" + }, + "name" : "3", + "pubKey" : "7VeRGE4V9MR7HgAqTrkxGvJvaaKRZ3fAjHUjYzpNBGcjfAvr", + "participantNodeState" : "CONSENSUS" + } + ], + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|id|参与方唯一标识| +|name|参与方名称| +|address.value|参与方地址| +|pubKey|参与方公钥| +|participantNodeState|参与方状态| + +`ParticipantNodeState` 参与方状态: + +- `READY` 就绪,在此状态下,参与方的账户可以作为网关节点接入终端的交易请求 +- `CONSENSUS` 共识,在此状态下,参与方的账户可以作为共识节点参与共识,也可以作为网关节点接入终端的交易请求 +- `DEACTIVATED` 停用,在此状态下,参与方的账户既不能作为共识节点参与共识,也不能作为网关节点接入终端的交易请求 + +### 2.6 获取账本元数据信息 + +```http +GET /ledgers/{ledger}/metadata +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型 | +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串 | + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/metadata +``` + +#### 返回实例 + +```json +{ + "success" : true, + "data" : { + "participantsHash" : "j5qzkZgpGMczBDNKXRGJdyPTndkxPvB7Gdrfiqy6LvG7P5", + "userRolesHash" : "j5rggjQQtcjMTSwxFyDedcxPSxVVfjAB3khJDvgdiGFhiB", + "seed" : "NiSpjQVYRMMEA+1bnyU2eA==", + "settingsHash" : "j5iNkXJptLJrJcFL1YJpuvbJCh6H3iioBNJG7QKPESUUif", + "rolePrivilegesHash" : "j5hBCfTVv77mTyM5WHoGnw1cezgzB3QDqojqjhg5qmuECn", + "ledgerStructureVersion" : 0 + } +} +``` + +说明 + +|名称|说明| +|---|---| +|seed|账本生成种子| +|participantsHash|成员数据集哈希| +|userRolesHash|用户角色集哈希| +|settingsHash|配置数据集哈希| +|rolePrivilegesHash|角色权限数据集哈希| +|ledgerStructureVersion|账本结构版本| + + +### 2.7 获取账本初始化配置信息 + +```http +GET /ledgers/{ledger}/settings +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/settings +``` + +#### 返回实例 + +```json +{ + "data": { + "ledgerStructureVersion": 0, + "participantsHash": "j5qzkZgpGMczBDNKXRGJdyPTndkxPvB7Gdrfiqy6LvG7P5", + "seed": "3624a98d-055844c3-0403ed5b-9f253678", + "consensusProtocol": "com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider", + "consensusSettings": { + "systemConfigs": [ + { + "name": "system.bft", + "value": "true" + }, + { + "value": "true", + "name": "system.communication.defaultkeys" + }, + { + "value": "500000", + "name": "system.communication.inQueueSize" + }, + { + "value": "500000", + "name": "system.communication.outQueueSize" + }, + { + "name": "system.communication.send.retryCount", + "value": "100" + }, + { + "name": "system.communication.send.retryInterval", + "value": "2000" + }, + { + "name": "system.communication.useMACs", + "value": "1" + }, + { + "name": "system.communication.useSenderThread", + "value": "true" + }, + { + "value": "0", + "name": "system.communication.useSignatures" + }, + { + "value": "0", + "name": "system.debug" + }, + { + "value": "0,1,2,3", + "name": "system.initial.view" + }, + { + "name": "system.servers.f", + "value": "1" + }, + { + "value": "4", + "name": "system.servers.num" + }, + { + "value": "true", + "name": "system.shutdownhook" + }, + { + "name": "system.totalordermulticast.checkpoint_period", + "value": "1000" + }, + { + "name": "system.totalordermulticast.checkpoint_to_disk", + "value": "false" + }, + { + "value": "120000", + "name": "system.totalordermulticast.global_checkpoint_period" + }, + { + "name": "system.totalordermulticast.highMark", + "value": "10000" + }, + { + "name": "system.totalordermulticast.log", + "value": "true" + }, + { + "value": "false", + "name": "system.totalordermulticast.log_parallel" + }, + { + "name": "system.totalordermulticast.log_to_disk", + "value": "true" + }, + { + "name": "system.totalordermulticast.maxbatchsize", + "value": "2000" + }, + { + "value": "10", + "name": "system.totalordermulticast.nonces" + }, + { + "value": "10", + "name": "system.totalordermulticast.revival_highMark" + }, + { + "name": "system.totalordermulticast.state_transfer", + "value": "true" + }, + { + "name": "system.totalordermulticast.sync_ckp", + "value": "false" + }, + { + "value": "false", + "name": "system.totalordermulticast.sync_log" + }, + { + "value": "3000000", + "name": "system.totalordermulticast.timeTolerance" + }, + { + "name": "system.totalordermulticast.timeout", + "value": "60000" + }, + { + "name": "system.totalordermulticast.timeout_highMark", + "value": "200" + }, + { + "value": "false", + "name": "system.totalordermulticast.verifyTimestamps" + }, + { + "name": "system.ttp.id", + "value": "2001" + } + ], + "viewId": 0, + "nodes": [ + { + "id": 0, + "networkAddress": { + "host": "127.0.0.1", + "port": 10080, + "secure": false + }, + "pubKey": "7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn", + "address": "LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw" + }, + { + "pubKey": "7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW", + "address": "LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY", + "id": 1, + "networkAddress": { + "host": "127.0.0.1", + "port": 10082, + "secure": false + } + }, + { + "id": 2, + "networkAddress": { + "host": "127.0.0.1", + "port": 10084, + "secure": false + }, + "address": "LdeNwsiuo7n6HULWhNKc87PBXJXAfGKFon9RE", + "pubKey": "7VeRFF1ednwhrFoe5cngKwPUJ2N4iFKD9Jt53GxSCc1MmPQ6" + }, + { + "networkAddress": { + "host": "127.0.0.1", + "port": 10086, + "secure": false + }, + "id": 3, + "pubKey": "7VeRGE4V9MR7HgAqTrkxGvJvaaKRZ3fAjHUjYzpNBGcjfAvr", + "address": "LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6" + } + ] + }, + "cryptoSetting": { + "supportedProviders": [ + { + "algorithms": [ + { + "name": "AES", + "code": -32230 + }, + { + "name": "ED25519", + "code": 16661 + }, + { + "code": 16662, + "name": "ECDSA" + }, + { + "name": "RSA", + "code": -16105 + }, + { + "name": "RIPEMD160", + "code": 8217 + }, + { + "name": "SHA256", + "code": 8216 + }, + { + "name": "JVM-SECURE-RANDOM", + "code": 4123 + } + ], + "name": "com.jd.blockchain.crypto.service.classic.ClassicCryptoService" + }, + { + "name": "com.jd.blockchain.crypto.service.sm.SMCryptoService", + "algorithms": [ + { + "code": -16126, + "name": "SM2" + }, + { + "name": "SM3", + "code": 8195 + }, + { + "name": "SM4", + "code": -32252 + } + ] + } + ], + "hashAlgorithm": 8216, + "autoVerifyHash": false + }, + "participantNodes": [ + { + "participantNodeState": "CONSENSUS", + "pubKey": "7VeRFF1ednwhrFoe5cngKwPUJ2N4iFKD9Jt53GxSCc1MmPQ6", + "address": { + "value": "LdeNwsiuo7n6HULWhNKc87PBXJXAfGKFon9RE" + }, + "name": "2", + "id": 2 + }, + { + "id": 1, + "participantNodeState": "CONSENSUS", + "pubKey": "7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW", + "address": { + "value": "LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY" + }, + "name": "1" + }, + { + "id": 0, + "address": { + "value": "LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw" + }, + "name": "0", + "participantNodeState": "CONSENSUS", + "pubKey": "7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn" + }, + { + "id": 3, + "participantNodeState": "CONSENSUS", + "pubKey": "7VeRGE4V9MR7HgAqTrkxGvJvaaKRZ3fAjHUjYzpNBGcjfAvr", + "address": { + "value": "LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6" + }, + "name": "3" + } + ] + }, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|ledgerStructureVersion|账本种子信息| +|participantsHash|参与方数据集哈希| +|seed|账本种子信息| +|consensusProtocol|共识协议,以字符串方式显示| +|consensusSettings|共识配置| +|cryptoSetting|加密算法配置| +|participantNodes|参与方节点信息| + +### 2.8 获取账本管理数据信息 + +```http +GET /ledgers/{ledger}/admininfo +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型 | +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串 | + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/admininfo +``` + +#### 返回实例 + +```json +{ + "data" : { + "participants" : [ + { + "id" : 2, + "pubKey" : "7VeRFF1ednwhrFoe5cngKwPUJ2N4iFKD9Jt53GxSCc1MmPQ6", + "name" : "2", + "participantNodeState" : "CONSENSUS", + "address" : { + "value" : "LdeNwsiuo7n6HULWhNKc87PBXJXAfGKFon9RE" + } + }, + { + "name" : "1", + "pubKey" : "7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW", + "id" : 1, + "participantNodeState" : "CONSENSUS", + "address" : { + "value" : "LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY" + } + }, + { + "id" : 0, + "name" : "0", + "pubKey" : "7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn", + "address" : { + "value" : "LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw" + }, + "participantNodeState" : "CONSENSUS" + }, + { + "participantNodeState" : "CONSENSUS", + "address" : { + "value" : "LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6" + }, + "name" : "3", + "pubKey" : "7VeRGE4V9MR7HgAqTrkxGvJvaaKRZ3fAjHUjYzpNBGcjfAvr", + "id" : 3 + } + ], + "participantCount" : 4, + "metadata" : { + "ledgerStructureVersion" : 0, + "seed" : "NiSpjQVYRMMEA+1bnyU2eA==", + "userRolesHash" : "j5rggjQQtcjMTSwxFyDedcxPSxVVfjAB3khJDvgdiGFhiB", + "settingsHash" : "j5iNkXJptLJrJcFL1YJpuvbJCh6H3iioBNJG7QKPESUUif", + "participantsHash" : "j5qzkZgpGMczBDNKXRGJdyPTndkxPvB7Gdrfiqy6LvG7P5", + "rolePrivilegesHash" : "j5hBCfTVv77mTyM5WHoGnw1cezgzB3QDqojqjhg5qmuECn" + }, + "settings" : { + "cryptoSetting" : { + "supportedProviders" : [ + { + "algorithms" : [ + { + "name" : "AES", + "code" : -32230 + }, + { + "name" : "ED25519", + "code" : 16661 + }, + { + "code" : 16662, + "name" : "ECDSA" + }, + { + "name" : "RSA", + "code" : -16105 + }, + { + "name" : "RIPEMD160", + "code" : 8217 + }, + { + "name" : "SHA256", + "code" : 8216 + }, + { + "name" : "JVM-SECURE-RANDOM", + "code" : 4123 + } + ], + "name" : "com.jd.blockchain.crypto.service.classic.ClassicCryptoService" + }, + { + "name" : "com.jd.blockchain.crypto.service.sm.SMCryptoService", + "algorithms" : [ + { + "code" : -16126, + "name" : "SM2" + }, + { + "name" : "SM3", + "code" : 8195 + }, + { + "name" : "SM4", + "code" : -32252 + } + ] + } + ], + "hashAlgorithm" : 8216, + "autoVerifyHash" : false + }, + "consensusProvider" : "com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider", + "consensusSetting" : { + "value" : "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" + } + } + }, + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|participants|参与方列表| +|participantCount|参与方数量| +|metadata|元数据| +|settings|配置信息| +|consensusProvider|共识协议| +|consensusSetting|共识配置| + + +## 3 区块 + +### 3.1 获取最新区块 + +```http +GET /ledgers/{ledger}/blocks/latest +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型 | +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串 | + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/latest +``` + +#### 返回实例 + +```json +{ + "data" : { + "timestamp" : 1615261725429, + "transactionSetHash" : "j5ssSG7LQC2CgU7fLbMCs2m2JtwN26j5kj2buE2u8F9miP", + "userAccountSetHash" : "j5hzkPPBJAqKs4rLWbEiFhbh1VW6Jc2xk878X5A6JywPnC", + "previousHash" : "j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp", + "hash" : "j5irFH5SJBaCSa6R3QYhbWYMUA2Wos3gvXYUyDYAHVhG23", + "adminAccountHash" : "j5maavFZShDorv36Sj5W8ijm1wkm2z9GtfdiVvUcfzvwv8", + "height" : 1, + "ledgerHash" : "j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp", + "dataAccountSetHash" : "j5poz1Ced486LxYbcotGvihT42CTiQym98Mg1By8DHZBxJ" + }, + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|hash|区块哈希| +|height|区块高度| +|timestamp|区块创建时间戳| +|ledgerHash|账本哈希| +|previousHash|前置区块哈希| +|transactionSetHash|交易集哈希| +|userAccountSetHash|用户集哈希| +|contractAccountSetHash|合约集哈希| +|adminAccountHash|管理员集哈希| +|dataAccountSetHash|数据账户集哈希| + +### 3.2 根据区块哈希获取区块详细信息 + +```http +GET /ledgers/{ledger}/blocks/hash/{block_hash} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型 | +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|block_hash|是|区块哈希|字符串| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/hash/j5irFH5SJBaCSa6R3QYhbWYMUA2Wos3gvXYUyDYAHVhG23 +``` + +#### 返回实例 + +同 [3.1](3.1-获取最新区块) + + +### 3.3 根据区块高度获取区块详细信息 + +```http +GET /ledgers/{ledger}/blocks/height/{block_height} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|block_height|是|区块高度|数字| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/height/1 +``` + +#### 返回实例 + +同 [3.1](3.1-获取最新区块) + +## 4 交易 + +### 4.1 获取账本交易总数 + +```http +GET /ledgers/{ledger}/txs/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/txs/count +``` + +##### 返回实例 + +```json +{ + "data": 2, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|交易数量| + +### 4.2 根据区块高度查询交易数量 + +**包含当前区块以及之前区块数据** + +```http +GET /ledgers/{ledgerHash}/blocks/height/{block_height}/txs/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|block_height|是|区块高度|数字| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/height/66/txs/count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|交易数量| + +### 4.3 根据区块哈希查询交易数量 + +**包含当前区块以及之前区块数据** + +```http +GET /ledgers/{ledger}/blocks/hash/{block_hash}/txs/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|block_hash|是|区块哈希|字符串| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/hash/j5irFH5SJBaCSa6R3QYhbWYMUA2Wos3gvXYUyDYAHVhG23/txs/additional-count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|交易数量| + +### 4.4 根据区块高度查询区块内的交易数量 + +**仅包含当前区块数据** + +```http +GET /ledgers/{ledger}/blocks/height/{block_height}/txs/additional-count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|block_height|是|区块高度|数字| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/height/66/txs/additional-count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|交易数量| + +### 4.5 根据区块哈希查询区块内的交易数量 + +**仅包含当前区块数据** + +```http +GET /ledgers/{ledger}/blocks/hash/{block_hash}/txs/additional-count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|block_hash|是|区块哈希|字符串| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/hash/j5irFH5SJBaCSa6R3QYhbWYMUA2Wos3gvXYUyDYAHVhG23/txs/additional-count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|交易数量| + +### 4.6 获取指定区块高度的交易列表 + +**包含当前区块以及之前区块数据** + +```http +GET /ledgers/{ledger}/blocks/height/{height}/txs?fromIndex={fromIndex}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|height|是|区块高度|数字| +|query|fromIndex|否|查询交易的起始序号,默认为0|数字| +|query|count|否|查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/height/66/txs?fromIndex=1&count=1 +``` + +#### 返回实例 + +```json +{ + "data" : [ + { + "request" : { + "transactionContent" : { + "timestamp" : 1615261725387, + "ledgerHash" : "j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp", + "operations" : [ + { + "@type" : "com.jd.blockchain.ledger.DataAccountRegisterOperation", + "accountID" : { + "pubKey" : "7VeRBZLMWAxcgL9DTjGWn9FHWny54bzDzrgeAH6pCFvEJ5eT", + "address" : { + "value" : "LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn" + } + } + }, + { + "writeSet" : [ + { + "value" : { + "type" : "TEXT", + "bytes" : { + "value" : "EMeAB7i" + } + }, + "expectedVersion" : -1, + "key" : "key" + } + ], + "@type" : "com.jd.blockchain.ledger.DataAccountKVSetOperation", + "accountAddress" : { + "value" : "LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn" + } + } + ] + }, + "nodeSignatures" : [ + { + "pubKey" : "7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn", + "digest" : "SMJHE64z77GSkBkC8Zw45r8zRhCq3KWgyGMxRo7KXZ1JWjnBBj1WkPGBdS3AUAX3UoWK5ymGxeqaskjTVgHxGtC768" + } + ], + "transactionHash" : "j5siSjjv7H6s61zsMajkGfyhASFnKpthveNDptCrM2gmui", + "endpointSignatures" : [ + { + "digest" : "SMJHE64z77GSkBkC8Zw45r8zRhCq3KWgyGMxRo7KXZ1JWjnBBj1WkPGBdS3AUAX3UoWK5ymGxeqaskjTVgHxGtC768", + "pubKey" : "7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn" + } + ] + }, + "result" : { + "executionState" : "SUCCESS", + "dataSnapshot" : { + "adminAccountHash" : "j5maavFZShDorv36Sj5W8ijm1wkm2z9GtfdiVvUcfzvwv8", + "userAccountSetHash" : "j5hzkPPBJAqKs4rLWbEiFhbh1VW6Jc2xk878X5A6JywPnC", + "dataAccountSetHash" : "j5poz1Ced486LxYbcotGvihT42CTiQym98Mg1By8DHZBxJ" + }, + "blockHeight" : 1, + "transactionHash" : "j5siSjjv7H6s61zsMajkGfyhASFnKpthveNDptCrM2gmui" + } + } + ], + "success" : true +} +``` + + +说明 + +|名称|说明| +|---|---| +|request|请求数据| +|request.transactionContent|交易内容| +|request.transactionContent.timestamp|交易时间戳,毫秒| +|request.transactionContent.ledgerHash|账本哈希| +|request.transactionContent.operations|操作列表| +|request.nodeSignatures|参与方签名列表| +|request.endpointSignatures|终端用户签名列表| +|request.transactionHash|交易哈希| +|result|交易结果| +|result.executionState|交易执行状态,SUCCESS(成功)| +|result.dataSnapshot|交易执行后数据快照| +|result.blockHeight|最新区块高度| +|result.transactionHash|交易哈希| + +### 4.7 获取指定哈希的区块的交易列表 + +```http +GET /ledgers/{ledger}/blocks/hash/{block_hash}/txs?fromIndex={fromIndex}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|block_hash|是|区块哈希|字符串| +|query|fromIndex|否|查询交易的起始序号,默认为0|数字| +|query|count|否|查询返回交易的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/hash/j5irFH5SJBaCSa6R3QYhbWYMUA2Wos3gvXYUyDYAHVhG23/txs?fromIndex=1&count=1 +``` + +#### 返回实例 + +[同 4.4](#4.4-获取指定区块高度的交易列表) + + +### 4.8 获取交易详细信息 + +```http +GET /ledgers/{ledger}/txs/hash/{tx_hash} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|tx_hash|是|交易哈希|字符串| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/txs/hash/j5siSjjv7H6s61zsMajkGfyhASFnKpthveNDptCrM2gmui +``` + +#### 返回实例 + +```json +{ + "success" : true, + "data" : { + "result" : { + "dataSnapshot" : { + "dataAccountSetHash" : "j5poz1Ced486LxYbcotGvihT42CTiQym98Mg1By8DHZBxJ", + "userAccountSetHash" : "j5hzkPPBJAqKs4rLWbEiFhbh1VW6Jc2xk878X5A6JywPnC", + "adminAccountHash" : "j5maavFZShDorv36Sj5W8ijm1wkm2z9GtfdiVvUcfzvwv8" + }, + "transactionHash" : "j5siSjjv7H6s61zsMajkGfyhASFnKpthveNDptCrM2gmui", + "blockHeight" : 1, + "executionState" : "SUCCESS" + }, + "request" : { + "nodeSignatures" : [ + { + "pubKey" : "7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn", + "digest" : "SMJHE64z77GSkBkC8Zw45r8zRhCq3KWgyGMxRo7KXZ1JWjnBBj1WkPGBdS3AUAX3UoWK5ymGxeqaskjTVgHxGtC768" + } + ], + "endpointSignatures" : [ + { + "pubKey" : "7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn", + "digest" : "SMJHE64z77GSkBkC8Zw45r8zRhCq3KWgyGMxRo7KXZ1JWjnBBj1WkPGBdS3AUAX3UoWK5ymGxeqaskjTVgHxGtC768" + } + ], + "transactionHash" : "j5siSjjv7H6s61zsMajkGfyhASFnKpthveNDptCrM2gmui", + "transactionContent" : { + "timestamp" : 1615261725387, + "operations" : [ + { + "@type" : "com.jd.blockchain.ledger.DataAccountRegisterOperation", + "accountID" : { + "address" : { + "value" : "LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn" + }, + "pubKey" : "7VeRBZLMWAxcgL9DTjGWn9FHWny54bzDzrgeAH6pCFvEJ5eT" + } + }, + { + "accountAddress" : { + "value" : "LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn" + }, + "@type" : "com.jd.blockchain.ledger.DataAccountKVSetOperation", + "writeSet" : [ + { + "value" : { + "bytes" : { + "value" : "EMeAB7i" + }, + "type" : "TEXT" + }, + "expectedVersion" : -1, + "key" : "key" + } + ] + } + ], + "ledgerHash" : "j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp" + } + } + } +} +``` + +说明 + +[同 4.4](#4.4-获取指定区块高度的交易列表) + +## 5 用户 + +### 5.1 获取用户总数 + +```http +GET /ledgers/{ledger}/users/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/users/count +``` + +#### 返回实例 + +```json +{ + "data": 4, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|用户总数| + + +### 5.2 获取用户列表 + +```http +GET /ledgers/{ledger}/users?fromIndex={fromIndex}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|query|fromIndex|否|查询用户的起始序号,默认为0|数字| +|query|count|否|查询返回用户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/users?fromIndex=0&count=2 +``` + +#### 返回实例 + +```json +{ + "success" : true, + "data" : [ + { + "pubKey" : "7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn", + "address" : { + "value" : "LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw" + } + }, + { + "pubKey" : "7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW", + "address" : { + "value" : "LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY" + } + } + ] +} +``` + +说明 + +|名称|说明| +|---|---| +|address.value|用户地址| +|pubKey|用户公钥| + + +### 5.3 获取用户详细信息 + +```http +GET /ledgers/{ledger}/users/address/{address} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|用户地址|字符串| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/users/address/LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY +``` + +#### 返回实例 + +```json +{ + "success" : true, + "data" : { + "pubKey" : "7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW", + "iD" : { + "pubKey" : "7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW", + "address" : { + "value" : "LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY" + } + }, + "dataRootHash" : "j5uJfAqLw1ptaZYJyKVZm37zZybboqxMPpS6Mv59rNd4xF", + "headerRootHash" : "j5oYeBmoBJ4jLpijwi6eoKAqh4BsQ3RWHzxdBnTvvTqSK6", + "dataset" : { + "dataCount" : 0, + "updated" : false, + "readonly" : false, + "rootHash" : "j5uJfAqLw1ptaZYJyKVZm37zZybboqxMPpS6Mv59rNd4xF" + }, + "address" : { + "value" : "LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY" + } + } +} +``` + +说明 + +|名称|说明| +|---|---| +|address.value|用户地址| +|pubKey|用户公钥| +|dataset.rootHash|用户根Hash| + +### 5.4 获取指定高度的区块的用户总数 + +**包含当前区块以及之前区块数据** + +```http +GET /ledgers/{ledger}/blocks/height/{block_height}/users/count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ------------ | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | block_height | 是 | 区块高度 | 数字 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/users/height/1/users/count +``` + +#### 返回实例 + +```json +{ + "data": 4, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | ------------ | +| data | 数据账户数量 | + +### 5.5 获取指定哈希的区块的用户总数 + +**包含当前区块以及之前区块数据** + +```http +GET /ledgers/{ledger}/blocks/hash/{block_hash}/users/count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ---------- | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | block_hash | 是 | 区块哈希 | 字符串 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/hash/j5opzRbH2fB6YmjvEdMLQ8VHVeZoUuKyVWzExCtJF1wecw/users/count +``` + +#### 返回实例 + +```json +{ + "data": 4, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | ------------ | +| data | 数据账户数量 | + +### 5.6 根据区块高度查询区块内的用户数量 + +**仅包含当前区块数据** + +```http +GET /ledgers/{ledger}/blocks/height/{block_height}/users/additional-count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ------------ | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | block_height | 是 | 区块高度 | 数字 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/height/2/users/additional-count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | -------- | +| data | 用户数量 | + +### 5.7 根据区块哈希查询区块内的用户数量 + +**仅包含当前区块数据** + +```http +GET /ledgers/{ledger}/blocks/hash/{block_hash}/users/additional-count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ---------- | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | block_hash | 是 | 区块哈希 | 字符串 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/hash/j5irFH5SJBaCSa6R3QYhbWYMUA2Wos3gvXYUyDYAHVhG23/users/additional-count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | -------- | +| data | 用户数量 | + +### 5.8 查询最新区块新增用户数量 + +**仅包含最新区块数据** + +```http +GET /ledgers/{ledger}/blocks/users/additional-count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ------ | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/users/additional-count +``` + +#### 返回实例 + +```json +{ + "data": 0, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | -------- | +| data | 用户数量 | + +## 6 角色权限 + +有关用户/角色/权限说明参照[用户文档](user.md) + +### 6.1 根据角色获取权限信息 +```http +GET /ledgers/{ledger}/authorization/role/{roleName} +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | -------- | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | roleName | 是 | 角色名 | 字符串 | + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5pSJLyVpS8QG2wL95fiDWHHnweh2YdqNhgmnb64SBMjUh/authorization/role/DEFAULT +``` + +#### 返回实例 + +```json +{ + "success" : true, + "data" : { + "roleName" : "DEFAULT", + "transactionPrivilege" : { + "privilege" : [ + "DIRECT_OPERATION", + "CONTRACT_OPERATION" + ], + "permissionCount" : 2 + }, + "version" : 0, + "ledgerPrivilege" : { + "privilege" : [ + "CONFIGURE_ROLES", + "AUTHORIZE_USER_ROLES", + "SET_CONSENSUS", + "SET_CRYPTO", + "REGISTER_PARTICIPANT", + "REGISTER_USER", + "REGISTER_DATA_ACCOUNT", + "REGISTER_CONTRACT", + "UPGRADE_CONTRACT", + "SET_USER_ATTRIBUTES", + "WRITE_DATA_ACCOUNT", + "APPROVE_TX", + "CONSENSUS_TX", + "REGISTER_EVENT_ACCOUNT", + "WRITE_EVENT_ACCOUNT" + ], + "permissionCount" : 15 + } + } +} +``` + +说明 + +| 名称 | 说明 | +| ------------------------------------ | ----------------- | +| roleName | 角色名称 | +| transactionPrivilege | 交易权限 | +| transactionPrivilege.privilege | 交易权限.权限类别 | +| transactionPrivilege.permissionCount | 交易权限.权限总数 | +| ledgerPrivilege | 账本权限 | +| ledgerPrivilege.privilege | 账本权限.权限类别 | +| ledgerPrivilege.permissionCount | 账本权限.权限总数 | + +### 6.2 根据用户获取权限信息 + +```http +GET /ledgers/{ledger}/authorization/user/{userAddress} +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ----------- | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | userAddress | 是 | 用户地址 | 字符串 | + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5pSJLyVpS8QG2wL95fiDWHHnweh2YdqNhgmnb64SBMjUh/authorization/user/LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6 +``` + +#### 返回实例 + +```json +{ + "data" : { + "userAddress" : { + "value" : "LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6" + }, + "userRole" : [ + "DEFAULT" + ], + "ledgerPrivilegesBitset" : { + "privilege" : [ + "CONFIGURE_ROLES", + "AUTHORIZE_USER_ROLES", + "SET_CONSENSUS", + "SET_CRYPTO", + "REGISTER_PARTICIPANT", + "REGISTER_USER", + "REGISTER_DATA_ACCOUNT", + "REGISTER_CONTRACT", + "UPGRADE_CONTRACT", + "SET_USER_ATTRIBUTES", + "WRITE_DATA_ACCOUNT", + "APPROVE_TX", + "CONSENSUS_TX", + "REGISTER_EVENT_ACCOUNT", + "WRITE_EVENT_ACCOUNT" + ], + "permissionCount" : 15 + }, + "transactionPrivilegesBitset" : { + "permissionCount" : 2, + "privilege" : [ + "DIRECT_OPERATION", + "CONTRACT_OPERATION" + ] + } + }, + "success" : true +} +``` + +说明 + +| 名称 | 说明 | +| --------------------------- | ---------- | +| userRole | 用户角色 | +| transactionPrivilegesBitset | 交易权限集 | +| ledgerPrivilegesBitset | 账本权限集 | + +> 请求链上不存在的用户地址,会返回DEFAULT角色权限列表 + +## 7 数据账户 + +### 7.1 获取账户列表 + +```http +GET /ledgers/{ledger}/accounts?fromIndex={fromIndex}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|query|fromIndex|否|查询数据账户的起始序号,默认为0|数字| +|query|count|否|查询返回数据账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/accounts?fromIndex=0&count=-1 +``` + +#### 返回实例 + +```json +{ + "data" : [ + { + "address" : { + "value" : "LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn" + }, + "pubKey" : "7VeRBZLMWAxcgL9DTjGWn9FHWny54bzDzrgeAH6pCFvEJ5eT" + } + ], + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|address.value|账户地址| +|pubKey|账户公钥| + + +### 7.2 获取账户详细信息 + +```http +GET /ledgers/{ledger}/accounts/address/{address} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|账户地址|字符串| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/accounts/address/LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn +``` + +#### 返回实例 + +```json +{ + "data" : { + "dataset" : { + "updated" : false, + "readonly" : false, + "dataCount" : 1, + "rootHash" : "j5vjKBpdFncVW9dYnjefiKgs858QKNc98XAvy5pFXmgLKp" + }, + "headerRootHash" : "j5jUf96A8678xdggUdAZUtADL43WFsFu76gWxT9KkknjLf", + "dataRootHash" : "j5vjKBpdFncVW9dYnjefiKgs858QKNc98XAvy5pFXmgLKp", + "pubKey" : "7VeRBZLMWAxcgL9DTjGWn9FHWny54bzDzrgeAH6pCFvEJ5eT", + "iD" : { + "pubKey" : "7VeRBZLMWAxcgL9DTjGWn9FHWny54bzDzrgeAH6pCFvEJ5eT", + "address" : { + "value" : "LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn" + } + }, + "address" : { + "value" : "LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn" + } + }, + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|address.value|账户地址| +|pubKey|账户公钥| + + +### 7.3 获取账户总数 + +```http +GET /ledgers/{ledger}/accounts/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/accounts/count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|账户数量| + +### 7.4 获取指定高度的区块的数据账户总数 + +**包含当前区块以及之前区块数据** + +```http +GET /ledgers/{ledger}/blocks/height/{block_height}/accounts/count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ------------ | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | block_height | 是 | 区块高度 | 数字 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/height/1/accounts/count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | ------------ | +| data | 数据账户数量 | + +### 7.5 获取指定哈希的区块的数据账户总数 + +**包含当前区块以及之前区块数据** + +```http +GET /ledgers/{ledger}/blocks/hash/{block_hash}/accounts/count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ---------- | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | block_hash | 是 | 区块哈希 | 字符串 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/hash/j5opzRbH2fB6YmjvEdMLQ8VHVeZoUuKyVWzExCtJF1wecw/accounts/count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | ------------ | +| data | 数据账户数量 | + +### 7.6 根据区块高度查询区块内的数据账户数量 + +**仅包含当前区块数据** + +```http +GET /ledgers/{ledger}/blocks/height/{block_height}/accounts/additional-count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ------------ | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | block_height | 是 | 区块高度 | 数字 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/height/1/accounts/additional-count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | ------------ | +| data | 数据账户数量 | + +### 7.7 根据区块哈希查询区块内的数据账户数量 + +**仅包含当前区块数据** + +```http +GET /ledgers/{ledger}/blocks/hash/{block_hash}/accounts/additional-count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ---------- | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | block_hash | 是 | 区块哈希 | 字符串 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/hash/j5irFH5SJBaCSa6R3QYhbWYMUA2Wos3gvXYUyDYAHVhG23/accounts/additional-count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | ------------ | +| data | 数据账户数量 | + +### 7.8 获取某数据账户KV总数 + +```http + GET /ledgers/{ledger}/accounts/address/{address}/entries/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|账户地址|字符串| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/accounts/address/LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn/entries/count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|KV总数| + + +### 7.9 获取某数据账户KV详情 + +```http +GET /ledgers/{ledger}/accounts/address/{address}/entries?fromIndex={fromIndex}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|账户地址|字符串| +|query|fromIndex|否|查询数据账户对应KV的起始序号,默认为0|数字| +|query|count|否|查询返回数据账户对应KV的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/accounts/address/LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn/entries?fromIndex=0&count=1 +``` + +#### 返回实例 + +```json +{ + "data" : [ + { + "type" : "TEXT", + "version" : 0, + "key" : "key", + "value" : "value" + } + ], + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|key|键| +|version|版本号| +|type|value类型| +|value|值| + +> 数据类型参照[数据账户](data_account.md)中描述。 + +### 7.10 获取某数据账户KV详情 + +```http +GET/POST /ledgers/{ledger}/accounts/{address}/entries?keys={keys} +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ------- | -------- | --------------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | address | 是 | 账户地址 | 字符串 | +| form | keys | 是 | key详细内容列表 | 字符串 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/accounts/LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn/entries?keys=key,key1 +``` + + +#### 返回实例 + +```json +{ + "success" : true, + "data" : [ + { + "key" : "key", + "value" : 1024, + "version" : 2, + "type" : "INT64" + }, + { + "type" : "NIL", + "version" : -1, + "key" : "key1" + } + ] +} +``` + +说明 + +| 名称 | 说明 | +| ------- | --------- | +| key | 键 | +| version | 版本号 | +| type | value类型 | +| value | 值 | + + +### 7.11 获取某数据账户KV整个历史详情 + +```http + GET/POST /ledgers/{ledger}/accounts/{address}/entries-version +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|账户地址|字符串| +|body|kvInfoVO|是|Key相关信息|对象| + +KVInfoVO对应格式如下: + +```json + +{ + "data": [{ + "key": "key", + "version": [0, 1] + } +} + +``` + +kvInfoVO说明: + - 支持多个Key作为入参; + - 每个Key支持多个version; + + +#### 请求实例 +```curl +curl -H 'Content-Type:application/json' --data '{"data":[{"key":"key","version":[0,1]}]}' 'http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/accounts/LdeNscE3MP9a1vgyVUg9LgxQx6yzkUEUS65Rn/entries-version' +``` + +#### 返回实例 + +```json +{ + "data" : [ + { + "type" : "TEXT", + "key" : "key", + "value" : "value", + "version" : 0 + }, + { + "type" : "BYTES", + "version" : 1, + "value" : "Ynl0ZXM=", + "key" : "key" + } + ], + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|key|键| +|version|版本号| +|type|value类型| +|value|值,BASE64编码| + +## 8 合约 + +### 8.1 获取合约总数 + +```http +GET /ledgers/{ledger}/contracts/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| + + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/contracts/count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | -------- | +| data | 合约数量 | + +### 8.2 获取指定区块高度的合约总数 + +**包含当前区块以及之前区块数据** + +```http +GET /ledgers/{ledger}/blocks/height/{blockHeight}/contracts/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|blockHeight|是|区块高度|数字| + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/height/7/contracts/count +``` + +#### 返回实例 + +```json +{ + "data": 2, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | -------- | +| data | 合约数量 | + + + +### 8.3 获取指定区块哈希的合约总数 + +**包含当前区块以及之前区块数据** + +```http +GET /ledgers/{ledger}/blocks/hash/{blockHash}/contracts/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|blockHash|是|区块哈希|字符串| + + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/hash/j5hhTQPyZQHqkvP5UBq3sAaqxq8QUda6asJLzZ2VFUhvQ8/contracts/count +``` + +#### 返回实例 + +```json +{ + "data": 2, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | -------- | +| data | 合约数量 | + +### 8.4 根据区块高度查询区块内的合约总数 + +**仅包含当前区块数据** + +```http +GET /ledgers/{ledger}/blocks/height/{blockHeight}/contracts/additional-count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | ----------- | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | blockHeight | 是 | 区块高度 | 数字 | + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/height/7/contracts/additional-count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | -------- | +| data | 合约数量 | + + + +### 8.5 根据区块哈希查询区块内的合约总数 + +**仅包含当前区块数据** + +```http +GET /ledgers/{ledger}/blocks/hash/{blockHash}/contracts/additional-count +``` + +#### 参数 + +| 请求类型 | 名称 | 是否必需 | 说明 | 数据类型 | +| -------- | --------- | -------- | -------- | -------- | +| path | ledger | 是 | 账本哈希 | 字符串 | +| path | blockHash | 是 | 区块哈希 | 字符串 | + + +#### 请求实例 + +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/blocks/hash/j5hhTQPyZQHqkvP5UBq3sAaqxq8QUda6asJLzZ2VFUhvQ8/contracts/additional-count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +| 名称 | 说明 | +| ---- | -------- | +| data | 合约数量 | + +### 8.6 获取合约列表 + +```http +GET /ledgers/{ledger}/contracts?fromIndex={fromIndex}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|query|fromIndex|否|查询合约的起始序号,默认为0|数字| +|query|count|否|查询返回合约的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/contracts?fromIndex=0&count=-1 +``` + +#### 返回实例 + +```json +{ + "data" : [ + { + "pubKey" : "7VeRCfSaoBW3uRuvTqVb26PYTNwvQ1iZ5HBY92YKpEVN7Qht", + "address" : { + "value" : "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye" + } + }, + { + "pubKey" : "7VeRALfcPigCTSEPHSwz7U7TDNLoet85z3nRfr5cYspUWLAR", + "address" : { + "value" : "LdeNwApbVMHqTCzNKuynUtJXH7vN2rG8gxHN5" + } + } + ], + "success" : true +} + +``` + +说明 + +|名称|说明| +|---|---| +|address.value|账户地址| +|pubKey|账户公钥| + + +### 8.7 获取合约详细信息 + +```http +GET /ledgers/{ledger}/contracts/address/{address} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|合约地址|字符串| + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/contracts/address/LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye +``` + +#### 返回实例 + +```json +{ + "success" : true, + "data" : { + "dataRootHash" : "j5uJfAqLw1ptaZYJyKVZm37zZybboqxMPpS6Mv59rNd4xF", + "chainCode" : "package com.jdchain.samples.contract;\n\nimport com.jd.blockchain.contract.*;\nimport utils.*;\nimport com.jd.blockchain.crypto.*;\nimport com.jd.blockchain.ledger.*;\n\npublic class SampleContractImpl implements EventProcessingAware, SampleContract\n{\n private ContractEventContext eventContext;\n \n public void setKVWithVersion(final String address, final String key, final String value, final long version) {\n this.eventContext.getLedger().dataAccount(Bytes.fromBase58(address)).setText(key, value, version);\n }\n \n public void setKV(final String address, final String key, final String value) {\n final TypedKVEntry[] entries = this.eventContext.getUncommittedLedger().getDataEntries(address, new String[] { key });\n long version = -1L;\n if (null != entries && entries.length > 0) {\n version = entries[0].getVersion();\n }\n this.eventContext.getLedger().dataAccount(Bytes.fromBase58(address)).setText(key, value, version);\n }\n \n public String registerUser(final String seed) {\n final CryptoAlgorithm algorithm = Crypto.getAlgorithm(\"ed25519\");\n final SignatureFunction signFunc = Crypto.getSignatureFunction(algorithm);\n final AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair(seed.getBytes());\n final BlockchainKeypair keypair = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey());\n this.eventContext.getLedger().users().register(keypair.getIdentity());\n return keypair.getAddress().toBase58();\n }\n \n public String registerDataAccount(final String seed) {\n final CryptoAlgorithm algorithm = Crypto.getAlgorithm(\"ed25519\");\n final SignatureFunction signFunc = Crypto.getSignatureFunction(algorithm);\n final AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair(seed.getBytes());\n final BlockchainKeypair keypair = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey());\n this.eventContext.getLedger().dataAccounts().register(keypair.getIdentity());\n return keypair.getAddress().toBase58();\n }\n \n public String registerEventAccount(final String seed) {\n final CryptoAlgorithm algorithm = Crypto.getAlgorithm(\"ed25519\");\n final SignatureFunction signFunc = Crypto.getSignatureFunction(algorithm);\n final AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair(seed.getBytes());\n final BlockchainKeypair keypair = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey());\n this.eventContext.getLedger().eventAccounts().register(keypair.getIdentity());\n return keypair.getAddress().toBase58();\n }\n \n public void publishEventWithSequence(final String address, final String topic, final String content, final long sequence) {\n this.eventContext.getLedger().eventAccount(Bytes.fromBase58(address)).publish(topic, content, sequence);\n }\n \n public void publishEvent(final String address, final String topic, final String content) {\n final Event event = this.eventContext.getUncommittedLedger().getLatestEvent(address, topic);\n long sequence = -1L;\n if (null != event) {\n sequence = event.getSequence();\n }\n this.eventContext.getLedger().eventAccount(Bytes.fromBase58(address)).publish(topic, content, sequence);\n }\n \n public void beforeEvent(final ContractEventContext eventContext) {\n this.eventContext = eventContext;\n }\n \n public void postEvent(final ContractEventContext eventContext, final Exception error) {\n }\n}\n", + "address" : { + "value" : "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye" + }, + "headerRootHash" : "j5r72A4PMdDrAU4zhniJNRWM5nKV8kAKMdt6naNrtjRp3A", + "chainCodeVersion" : 0, + "pubKey" : "7VeRCfSaoBW3uRuvTqVb26PYTNwvQ1iZ5HBY92YKpEVN7Qht" + } +} +``` + +说明 + +|名称|说明| +|---|---| +|address.value|账户地址| +|pubKey|账户公钥| +|chainCode|合约源代码| + + + +## 9 用户自定义事件 + +### 9.1 获取事件账户列表 + +```http +GET /ledgers/{ledger}/events/user/accounts?fromIndex={fromIndex}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|query|fromIndex|否|查询的起始序号,默认为0|数字| +|query|count|否|查询返回事件账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/events/user/accounts?fromIndex=0&count=-1 +``` + +#### 返回实例 + +```json +{ + "data" : [ + { + "address" : { + "value" : "LdeNqYND7M82fxrej7ffRPXZwahQZEoUSoUzz" + }, + "pubKey" : "7VeRJe66QNfuacfSVPzTfXPooFcRmMJKXPYqkUsn4r9v8DqA" + }, + { + "pubKey" : "7VeRMwxWNcpMszstXtaxJ1fupauuJpwedB81nMJJQB93LiAJ", + "address" : { + "value" : "LdeNiAPuZ5tpYZVrrbELJNjqdvB51PBpNd8QA" + } + } + ], + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|address.value|账户地址| +|pubKey|账户公钥| + +### 9.2 获取事件账户 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|address|账户地址|是|事件账户地址|字符串| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/events/user/accounts/LdeNqYND7M82fxrej7ffRPXZwahQZEoUSoUzz +``` + +#### 返回实例 + +```json +{ + "success" : true, + "data" : { + "address" : { + "value" : "LdeNqYND7M82fxrej7ffRPXZwahQZEoUSoUzz" + }, + "pubKey" : "7VeRJe66QNfuacfSVPzTfXPooFcRmMJKXPYqkUsn4r9v8DqA" + } +} +``` + +说明 + +|名称|说明| +|---|---| +|address.value|账户地址| +|pubKey|账户公钥| + +### 9.3 获取事件账户总数 + +```http +GET /ledgers/{ledger}/events/user/accounts/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/events/user/accounts/count +``` + +#### 返回实例 + +```json +{ + "success" : true, + "data" : 2 +} +``` + +说明 + +|名称|说明| +|---|---| +|data|事件账户数量| + +### 9.4 获取事件名数量 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address}/names/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|事件账户地址|字符串| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/events/user/accounts/LdeNiAPuZ5tpYZVrrbELJNjqdvB51PBpNd8QA/names/count +``` + +#### 返回实例 + +```json +{ + "data" : 5, + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|事件名数量| + +### 9.5 获取事件名列表 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address}/names?fromIndex={fromIndex}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|事件账户地址|字符串| +|query|fromIndex|否|查询的起始序号,默认为0|数字| +|query|count|否|查询返回事件账户的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/events/user/accounts/LdeNiAPuZ5tpYZVrrbELJNjqdvB51PBpNd8QA/names?fromIndex=0&count=-1 +``` + +#### 返回实例 + +```json +{ + "data" : [ + "topic4", + "topic3", + "topic", + "topic1", + "topic2" + ], + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|事件名数量数组| + +### 9.6 获取最新事件 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address}/names/{event_name}/latest +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|事件账户地址|字符串| +|path|event_name|是|事件名|字符串| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/events/user/accounts/LdeNiAPuZ5tpYZVrrbELJNjqdvB51PBpNd8QA/names/topic/latest +``` + +#### 返回实例 + +```json +{ + "success" : true, + "data" : { + "sequence" : 0, + "blockHeight" : 8, + "transactionSource" : "j5p868BwtU4w5BxG7gnuhQCFqpAgddVzTWNEKMAzZ8bnrF", + "eventAccount" : { + "value" : "LdeNiAPuZ5tpYZVrrbELJNjqdvB51PBpNd8QA" + }, + "name" : "topic", + "contractSource" : "", + "content" : { + "bytes" : { + "value" : "4mZ4ZZRGDZ" + }, + "nil" : false, + "value" : "content", + "type" : "TEXT" + } + } +} +``` + +说明 + +|名称|说明| +|---|---| +|sequence|事件序列| +|transactionSource|交易哈希| +|blockHeight|时间产生区块高度| +|contractSource|合约地址| +|eventAccount.value|事件账户地址| +|name|事件名| +|content.nil|事件内容是否为空| +|content.bytes.value|事件内容字节,BASE64编码| +|content.type|事件内容类型| +|content.value|事件内容| + +### 9.7 获取事件数量 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address}/names/{event_name}/count +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|事件账户地址|字符串| +|path|event_name|是|事件名|字符串| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/events/user/accounts/LdeP1yuk8Medq3Sph5ur9y1yE6nJ71XRVPPx1/names/topic/count +``` + +#### 返回实例 + +```json +{ + "data": 1, + "success": true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|事件数量| + +### 9.8 获取事件列表 + +```http +GET /ledgers/{ledger}/events/user/accounts/{address}/names/{event_name}?fromSequence={fromSequence}&count={count} +``` + +#### 参数 + +|请求类型|名称|是否必需|说明|数据类型| +|---|---|---|---|---| +|path|ledger|是|账本哈希|字符串| +|path|address|是|事件账户地址|字符串| +|path|event_name|是|事件名|字符串| +|query|fromSequence|否|查询的起始序号,默认为0|数字| +|query|count|否|查询返回事件的数量,默认最大返回值为100,小于0或大于100均返回最大可返回结果集|数字| + + +#### 请求实例 +```http +http://localhost:8080/ledgers/j5hQrVB8y78xXbDR9vB92WBjiJShH36G7YLdQYsxtRxkpp/events/user/accounts/LdeNiAPuZ5tpYZVrrbELJNjqdvB51PBpNd8QA/names/topic?fromSequenct=0&count=-1 +``` + +#### 返回实例 + +```json +{ + "data" : [ + { + "content" : { + "value" : "content", + "nil" : false, + "type" : "TEXT", + "bytes" : { + "value" : "4mZ4ZZRGDZ" + } + }, + "eventAccount" : { + "value" : "LdeNiAPuZ5tpYZVrrbELJNjqdvB51PBpNd8QA" + }, + "contractSource" : "", + "name" : "topic", + "sequence" : 0, + "transactionSource" : "j5p868BwtU4w5BxG7gnuhQCFqpAgddVzTWNEKMAzZ8bnrF", + "blockHeight" : 8 + } + ], + "success" : true +} +``` + +说明 + +|名称|说明| +|---|---| +|data|事件列表| +|sequence|事件序列| +|transactionSource|交易哈希| +|blockHeight|时间产生区块高度| +|contractSource|合约地址| +|eventAccount.value|事件账户地址| +|name|事件名| +|content.nil|事件内容是否为空| +|content.bytes.value|事件内容字节,BASE64编码| +|content.type|事件内容类型| +|content.value|事件内容| \ No newline at end of file diff --git a/docs/block.md b/docs/block.md new file mode 100644 index 00000000..552f156c --- /dev/null +++ b/docs/block.md @@ -0,0 +1,80 @@ +## 区块 + +采用`BFT-SMaRt`共识协议,即时出块,单个区块交易数限制默认为`2000`(`bftsmart.config`中参数`system.totalordermulticast.maxbatchsize`) + +### 结构 + +- `LedgerBlock`: + +```java +@DataContract(code = DataCodes.BLOCK) +public interface LedgerBlock extends BlockBody { + + /** + * 区块哈希; + */ + @DataField(order = 1, primitiveType = PrimitiveType.BYTES) + HashDigest getHash(); + +} +``` + +- `BlockBody`: + +```java +@DataContract(code= DataCodes.BLOCK_BODY) +public interface BlockBody extends LedgerDataSnapshot{ + + // 上一个区块哈希 + @DataField(order=2, primitiveType = PrimitiveType.BYTES) + HashDigest getPreviousHash(); + + // 账本哈希 + @DataField(order=3, primitiveType = PrimitiveType.BYTES) + HashDigest getLedgerHash(); + + // 区块高度 + @DataField(order=4, primitiveType= PrimitiveType.INT64) + long getHeight(); + + // 交易数据集哈希 + @DataField(order=5, primitiveType = PrimitiveType.BYTES) + HashDigest getTransactionSetHash(); + + // 区块时间戳,毫秒 + @DataField(order=6, primitiveType = PrimitiveType.INT64) + long getTimestamp(); +} +``` + +- `LedgerDataSnapshot`: + +```java +@DataContract(code=DataCodes.DATA_SNAPSHOT) +public interface LedgerDataSnapshot { + + // 管理数据集哈希 + @DataField(order=1, primitiveType = PrimitiveType.BYTES) + HashDigest getAdminAccountHash(); + + // 用户集哈希 + @DataField(order=2, primitiveType = PrimitiveType.BYTES) + HashDigest getUserAccountSetHash(); + + // 数据账户集哈希 + @DataField(order=3, primitiveType = PrimitiveType.BYTES) + HashDigest getDataAccountSetHash(); + + // 合约集哈希 + @DataField(order=4, primitiveType = PrimitiveType.BYTES) + HashDigest getContractAccountSetHash(); + + // 系统事件集哈希 + @DataField(order=5, primitiveType = PrimitiveType.BYTES) + HashDigest getSystemEventSetHash(); + + // 用户事件集哈希 + @DataField(order=6, primitiveType = PrimitiveType.BYTES) + HashDigest getUserEventSetHash(); +} +``` \ No newline at end of file diff --git a/docs/cli/keys.md b/docs/cli/keys.md new file mode 100644 index 00000000..a3410b54 --- /dev/null +++ b/docs/cli/keys.md @@ -0,0 +1,120 @@ +### 密钥管理 + +`jdchain-cli`提供基于本地目录的密钥管理:[密钥对列表](#密钥对列表),[添加密钥对](#添加密钥对),[更新私钥密码](#更新私钥密码),[删除密钥对](#删除密钥对) + +```bash +:bin$ ./jdchain-cli.sh keys -h +Usage: git status [...] [--] [...] +List, create, update or delete keypairs. + -h, --help Show this help message and exit. + --home= Set the home directory. + Default: ../ + --pretty Pretty json print + -V, --version Print version information and exit. +Commands: + list List all the keypairs. + add Create a new keypair. + update Update privkey password. + delete Delete keypair. + help Displays help information about the specified command +``` + +#### 密钥对列表 +```bash +:bin$ ./jdchain-cli.sh keys list -h +List all the keypairs. +Usage: jdchain-cli keys list [-hV] [--pretty] [--home=] + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `home`,指定密钥存储相关目录,`${home}/config/keys` + +如: +```bash +:bin$ ./jdchain-cli.sh keys list +NAME ALGORITHM ADDRESS PUBKEY +``` +- `NAME`,名称 +- `ALGORITHM`,算法 +- `ADDRESS`,地址 +- `PUBKEY`,公钥 + +#### 添加密钥对 +```bash +:bin$ ./jdchain-cli.sh keys add -h +Create a new keypair. +Usage: jdchain-cli keys add [-hV] [--pretty] [-a=] [--home=] + -n= + -a, --algorithm= + Crypto algorithm + -h, --help Show this help message and exit. + --home= Set the home directory. + -n, --name= Name of the key + --pretty Pretty json print + -V, --version Print version information and exit. +``` + +- `a`/`algorithm`,密钥算法:`SM2`,`ED25519`等,默认`ED25519` +- `name`,密钥对名称 + +如: +```bash +:bin$ ./jdchain-cli.sh keys add -n k1 +please input password: > +// 输入私钥密码 +1 +NAME ALGORITHM ADDRESS PUBKEY +k1 ED25519 LdeP1iczD3zpmcayKAxTfSywict9y2r6Jpq6n 7VeRBamwPeMb7jzTNg3Ap2DscBiy3QE3PK5NqBvv9tUjQVk4 +``` + +#### 更新私钥密码 + +```bash +:bin$ ./jdchain-cli.sh keys update -h +Update privkey password. +Usage: jdchain-cli keys update [-hV] [--pretty] [--home=] -n= + -h, --help Show this help message and exit. + --home= Set the home directory. + -n, --name= Name of the key + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `name`,密钥对名称 + +如: +```bash +:bin$ ./jdchain-cli.sh keys update -n k1 +input the current password: > +// 输入当前密码 +1 +input new password: > +// 输入新密码 +2 +NAME ALGORITHM ADDRESS PUBKEY +k1 ED25519 LdeP1iczD3zpmcayKAxTfSywict9y2r6Jpq6n 7VeRBamwPeMb7jzTNg3Ap2DscBiy3QE3PK5NqBvv9tUjQVk4 +``` + +#### 删除密钥对 + +```bash +:bin$ ./jdchain-cli.sh keys delete -h +Delete keypair. +Usage: jdchain-cli keys delete [-hV] [--pretty] [--home=] -n= + -h, --help Show this help message and exit. + --home= Set the home directory. + -n, --name= Name of the key + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `name`,密钥对名称 + +如: +```bash +:bin$ ./jdchain-cli.sh keys delete -n k1 +input the current password: > +// 输入当前密码 +2 +[k1] deleted +``` \ No newline at end of file diff --git a/docs/cli/participant.md b/docs/cli/participant.md new file mode 100644 index 00000000..0d23df02 --- /dev/null +++ b/docs/cli/participant.md @@ -0,0 +1,219 @@ +### 共识节点变更 + +借助`BFT-SMaRt`共识提供的Reconfig操作元语,`JD Chain`实现了在不停机的情况下快速更新共识网络拓扑,实现添加共识节点,移除共识节点,更新共识信息 等功能。 +```bash +:bin$ ./jdchain-cli.sh participant -h +Usage: jdchain-cli participant [-hV] [--pretty] [--home=] [COMMAND] +Add, update or delete participant. + -h, --help Show this help message and exit. + --home= Set the home directory. + Default: ../ + --pretty Pretty json print + -V, --version Print version information and exit. +Commands: + register Register new participant. + active Active participant. + update Update participant. + inactive Inactive participant. + help Displays help information about the specified command +``` +- `register` [注册新节点](#注册新节点) +- `active` [激活节点](#激活节点) +- `active` [更新节点](#更新节点) +- `inactive` [移除节点](#移除节点) + +#### 注册新节点 + +```bash +:bin$ ./jdchain-cli.sh participant register -h +Register new participant. +Usage: jdchain-cli participant register [-hV] [--pretty] [--gw-host=] + [--gw-port=] [--home=] + --name= + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --name= Name of the participant + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `name`,新节点名称 + +注册新节点: +```bash +:bin$ ./jdchain-cli.sh participant register --name node4 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +// 选择账本 +> 0 +// 选择待注册节点公私钥(链上必须不存在此公私钥对应的用户) +select keypair to register, input the index: +0 k1 LdeNq3862vtUCeptww1T5mVvLbAeppYqVNdqD +1 1627618939 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +2 node4 LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T +2 +input password of the key: +> 1 +// 选择此交易签名用户(必须是链上存在的用户,且有相应操作权限) +select keypair to sign tx, input the index: +0 k1 LdeNq3862vtUCeptww1T5mVvLbAeppYqVNdqD +1 1627618939 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +2 node4 LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T +1 +input password of the key: +> 1 +register participant: [LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T] +``` +成功在账本`j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg`中注册了新的节点`LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T` + +可通过[共识节点列表](query.md#共识节点列表)查看新的账本列表: +```bash +:bin$ ./jdchain-cli.sh query participants +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +[{"address":"LdeNwsiuo7n6HULWhNKc87PBXJXAfGKFon9RE","id":2,"name":"2","participantNodeState":"CONSENSUS","pubKey":"7VeRFF1ednwhrFoe5cngKwPUJ2N4iFKD9Jt53GxSCc1MmPQ6"},{"address":"LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY","id":1,"name":"1","participantNodeState":"CONSENSUS","pubKey":"7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW"},{"address":"LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T","id":4,"name":"node4","participantNodeState":"READY","pubKey":"7VeRKiWHcHjNoYH9kJk2fxoJxgBrstVJ7bHRecKewJAKcvUD"},{"address":"LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw","id":0,"name":"0","participantNodeState":"CONSENSUS","pubKey":"7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn"},{"address":"LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6","id":3,"name":"3","participantNodeState":"CONSENSUS","pubKey":"7VeRGE4V9MR7HgAqTrkxGvJvaaKRZ3fAjHUjYzpNBGcjfAvr"}] +register participant: [LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T] +``` +可以看出`node4`注册成功,地址为`LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T` + +#### 激活节点 + +激活节点前请正确配置并启动新节点,以下以刚注册成功的`node4`为例 + +1. 配置`node4` + +解压`peer`压缩包,复制待加入账本其他节点中数据最新的节点数据库数据,然后修改`config/ledger-binding.conf`: +```bash +# Base58编码的账本哈希 +ledger.bindings=<账本hash> +# 账本名字,与账本相关的其他其他peer保持一致 +binding.<账本HASH>.name=<节点名称> +# peer4的名名称,与[向现有共识网络注册新的参与方]操作中保持一致 +binding.<账本hash>.parti.name=<节点名称> +# peer4的用户地址 +binding.<账本hash>.parti.address= +# 新参与方base58编码的私钥,与[向现有共识网络注册新的参与方]操作中保持一致 +binding.<账本hash>.parti.pk=<新参与方base58编码的私钥> +# 新参与方base58编码的私钥读取密码,与[向现有共识网络注册新的参与方]操作中保持一致 +binding.<账本hash>.parti.pwd=<新参与方base58编码的私钥读取密码> +# 新参与方对应的账本数据库连接uri,即peer4的账本数据库存放位置,参照其他peer修改,不可与其他peer混用 +binding.<账本hash>.db.uri=<账本数据库连接> +``` + +2. 启动`node4` +| **一定注意在启动新参与方节点进程之前确保完成了账本数据库的复制工作** + +执行`peer4`中`bin`目录下`peer-startup.sh`脚本启动启动新参与方`peer4`节点进程: +```bash +./peer-startup.sh +``` + +3. 激活新节点 +```bash +:bin$ ./jdchain-cli.sh participant active -h +Active participant. +Usage: jdchain-cli participant active [-hV] [--pretty] [--shutdown] + --consensus-port= + [--home=] --host= + --ledger= --port= + --syn-host= --syn-port= + --consensus-port= + Set the participant consensus port. + -h, --help Show this help message and exit. + --home= Set the home directory. + --host= Set the participant host. + --ledger= Set the ledger. + --port= Set the participant service port. + --pretty Pretty json print + --shutdown Restart the node server. + --syn-host= Set synchronization participant host. + --syn-port= Set synchronization participant port. + -V, --version Print version information and exit. +``` +- `ledger`,账本哈希 +- `host`,新节点地址 +- `port`,新节点服务端口 +- `consensus-port`,新节点共识端口 +- `syn-host`,数据同步节点地址 +- `syn-port`,数据同步节点服务端口 + +在账本`j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg`中激活`node4`(以步骤2中启动的服务地址和端口为`127.0.0.1`和`7084`例),共识端口设置为`10088`,同步节点地址和端口为`127.0.0.1`和`7080`为例: +```bash +./jdchain-cli.sh participant active --ledger j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg --host 127.0.0.1 --port 7084 --consensus-port 10088 --syn-host 127.0.0.1 --syn-port 7080 +participant activated +``` + +成功后可通过[共识节点列表](query.md#共识节点列表)查询最新共识节点列表状态,`node4`为`CONSENSUS` + +#### 更新节点 + +通过[激活节点](#激活节点)操作除了激活新增的节点外,还可以动态修改已经处于激活状态的共识节点的`IP`和`共识端口`信息,从而实现本机的共识端口变更,不同机器之间进行`账本迁移`。 + +| **在进行节点信息变更时,要求暂停向共识网络中发起新的业务数据上链请求** + +1. 变更共识端口 + +| **操作前请确保变更到的端口未被占用** + +如将`node4`共识端口由`10088`修改为`10188`,操作指令如下: + +```bash +./jdchain-cli.sh participant update --ledger j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg --host 127.0.0.1 --port 7084 --consensus-port 10188 --syn-host 127.0.0.1 --syn-port 7080 +participant updated +``` +指令成功执行后,`peer1`的共识端口将自动变更为`10188` + +2. 账本迁移 + +账本迁移指将一台机器(`IP`)上的共识节点迁移到另一台机器(`IP`)上,主要操作流程如下: + +| **操作前请确保变更到的端口未被占用** + +如将`node4`共识`IP`由`127.0.0.1`修改为`192.168.1.100`(另一台机器),操作指令如下: + +```bash +./jdchain-cli.sh participant update --ledger j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg --host 192.168.1.100 --port 7084 --consensus-port 10188 --syn-host 127.0.0.1 --syn-port 7080 -shutdown +participant updated +``` + +**特别注意**:`-shutdown`会停止当前运行的当前账本共识服务,为必填选项,否则可能将导致整个网络需要重启。 + +#### 移除节点 + +``` +:bin$ ./jdchain-cli.sh participant inactive -h +Inactive participant. +Usage: jdchain-cli participant inactive [-hV] [--pretty] --address=
+ [--home=] --host= + --ledger= --port= + --syn-host= + --syn-port= + --address=
Set the participant address. + -h, --help Show this help message and exit. + --home= Set the home directory. + --host= Set the participant host. + --ledger= Set the ledger. + --port= Set the participant service port. + --pretty Pretty json print + --syn-host= Set synchronization participant host. + --syn-port= Set synchronization participant port. + -V, --version Print version information and exit. +``` +- `ledger`,账本哈希 +- `address`,待移除节点共识端口 +- `host`,待移除节点服务地址 +- `port`,待移除节点服务端口 +- `syn-host`,数据同步节点地址 +- `syn-port`,数据同步节点服务端口 + +如移除`node4`: +```bash +:bin$ ./jdchain-cli.sh participant inactive --ledger j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg --address LdeNwG6ECEGz57o2ufhwSbnW4C35TvPqANK7T --host 127.0.0.1 --port 7084 --syn-host 127.0.0.1 --syn-port 7080 +participant inactivated +``` + +成功后可通过[共识节点列表](query.md#共识节点列表)查询最新共识节点列表状态,`node4`为`DEACTIVATED` \ No newline at end of file diff --git a/docs/cli/query.md b/docs/cli/query.md new file mode 100644 index 00000000..87e36020 --- /dev/null +++ b/docs/cli/query.md @@ -0,0 +1,914 @@ +### 链上信息查询 + +```bash +:bin$ ./jdchain-cli.sh query -h +Usage: jdchain-cli query [-hV] [--pretty] [--gw-host=] + [--gw-port=] [--home=] [COMMAND] +Query commands. + --gw-host= Set the gateway host. Default: 127.0.0.1 + Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + Default: ../ + --pretty Pretty json print + -V, --version Print version information and exit. +Commands: + ledgers Query ledgers. + ledger Query ledger. + participants Query participants. + block Query block. + txs-count Query transactions count. + txs Query transactions. + tx Query transaction. + users Query users. + users-count Query users count. + user Query user. + role-privileges Query role privileges. + user-privileges Query user privileges. + data-accounts-count Query data accounts count. + data-accounts Query data accounts. + data-account Query data account. + kvs-count Query key-values count. + kvs Query kvs. + kv Query kv. + user-event-accounts-count Query user event accounts count. + user-event-accounts Query user event accounts. + user-event-account Query user event account. + user-event-names-count Query user event names count. + user-event-names Query user event names. + user-events-count Query user events count. + user-events Query user events. + latest-user-event Query latest user event. + contracts-count Query contracts count. + contracts Query contracts. + contract Query contract. + help Displays help information about the specified command +``` +查询命令:[账本列表](#账本列表),[账本详情](#账本详情),[共识节点列表](#共识节点列表),[区块详情](#区块详情),[交易总数](#交易总数),[交易列表](#交易列表),[交易详情](#交易详情),[用户总数](#用户总数),[用户列表](#用户列表),[用户详情](#用户详情),[角色权限](#角色权限),[用户权限](#用户权限),[数据账户总数](#数据账户总数),[数据账户列表](#数据账户列表),[数据账户详情](#数据账户详情),[KV总数](#KV总数),[KV列表](#KV列表),[KV详情](#KV详情),[用户事件账户总数](#用户事件账户总数),[用户事件账户列表](#用户事件账户列表),[用户事件账户详情](#用户事件账户详情),[用户事件名总数](#用户事件名总数),[用户事件名列表](#用户事件名列表),[用户事件总数](#用户事件总数),[用户事件列表](#用户事件列表),[最新用户事件](#最新用户事件),[合约总数](#合约总数),[合约列表](#合约列表),[合约详情](#合约详情) + +#### 账本列表 + +```bash +:bin$ ./jdchain-cli.sh query ledgers +j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +``` +返回当前网关服务所有账本列表 + +#### 账本详情 + +选择账本,打印当前账本详细信息: +```bash +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"hash":"j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg","latestBlockHash":"j5n8KGMFsRM7jzf99XK1jDK342fauj3myKcdgPJyLYyxws","latestBlockHeight":18} +``` + +可添加`--pretty`格式化输出`json`数据 + +#### 共识节点列表 + +查询共识节点列表: +```bash +:bin$ ./jdchain-cli.sh query participants +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +[{"address":"LdeNwsiuo7n6HULWhNKc87PBXJXAfGKFon9RE","id":2,"name":"2","participantNodeState":"CONSENSUS","pubKey":"7VeRFF1ednwhrFoe5cngKwPUJ2N4iFKD9Jt53GxSCc1MmPQ6"},{"address":"LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY","id":1,"name":"1","participantNodeState":"CONSENSUS","pubKey":"7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW"},{"address":"LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw","id":0,"name":"0","participantNodeState":"CONSENSUS","pubKey":"7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn"},{"address":"LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6","id":3,"name":"3","participantNodeState":"CONSENSUS","pubKey":"7VeRGE4V9MR7HgAqTrkxGvJvaaKRZ3fAjHUjYzpNBGcjfAvr"}] +``` +账本`j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg`中有四个共识节点,均为`CONSENSUS`状态 + +#### 区块详情 + +```bash +:bin$ ./jdchain-cli.sh query block -h +Query block. +Usage: jdchain-cli query block [-hV] [--pretty] [--gw-host=] + [--gw-port=] [--hash=] + [--height=] [--home=] + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --hash= Block hash + --height= Block height. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `height`,区块高度,默认`-1`查询当前最高区块 + +如: +```bash +:bin$ ./jdchain-cli.sh query block --pretty +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{ + "adminAccountHash":"j5p5z4es9RPrQWFu2nSJBQFT68byeGqAdUDu63qa5xV8Df", + "contractAccountSetHash":"j5kbvGQ1tFH2GXgk8ThF1co7H2gCrFdeZn7Nibva7Md72P", + "dataAccountSetHash":"j5fSmQkk8tb9v9SYDmaAko3oJJqmCm54HGbQwgbV2nTCVk", + "hash":"j5n8KGMFsRM7jzf99XK1jDK342fauj3myKcdgPJyLYyxws", + "height":18, + "ledgerHash":"j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg", + "previousHash":"j5motWQdmckqTxkG3x8DcE6quv2oGteKzsHqoV89Lfo4Mj", + "timestamp":1627703544928, + "transactionSetHash":"j5rc9PV5p9C8mXDAt8p9MR4QY3VAr4wQNG7zC3MSvFpcGG", + "userAccountSetHash":"j5haZvthy9gGaJ8M3mEbwtpeUg9Z113ifZbcWtzAeQcQdu", + "userEventSetHash":"j5nke9ZAnVRf1Qgg4u9Ske8RoZFbFVzVrKQid14qcqXaAn" +} +``` +返回当前最高区块详情 + +#### 交易总数 + +```bash +:bin$ ./jdchain-cli.sh query txs-count -h +Query transactions count. +Usage: jdchain-cli query txs-count [-hV] [--in-block] [--pretty] + [--gw-host=] [--gw-port=] + --height= [--home=] + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --height= Block height. + --home= Set the home directory. + --in-block In the given block. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `height`,区块高度 +- `in-block`,是否只统计`height`参数指定区块数据 + +如查询高度`10`区块交易总数(会统计区块`0-10`内所有交易): +```bash +:bin$ ./jdchain-cli.sh query txs-count --height 10 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +11 +``` + +查询高度`10`区块内交易总数(仅统计区块`10`交易): +```bash +:bin$ ./jdchain-cli.sh query txs-count --height 10 --in-block +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +1 +``` + +#### 交易列表 + +```bash +:bin$ ./jdchain-cli.sh query txs -h +Query transactions. +Usage: jdchain-cli query txs [-hV] [--in-block] [--pretty] --count= + [--gw-host=] [--gw-port=] + [--height=] [--home=] --index= + --count= Transaction item count + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --height= Block height. + --home= Set the home directory. + --in-block In the given block. + --index= Transaction item index + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `height`,区块高度 +- `in-block`,是否只统计`height`参数指定区块数据 +- `index`,查询起始位置 +- `count`,最大返回 + +如查询高度`10`区块交易列表(会统计区块`0-10`内所有交易),从第`0`条开始,最大返回`1`条: +```bash +:bin$ ./jdchain-cli.sh query txs --height 10 --index 0 --count 1 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +[{"request":{"endpointSignatures":[],"nodeSignatures":[{"digest":"SMHYntB7uTm3N4mReke4srWHhpDkjDFGRuz7Bis8quJt19igevwA4rEwNmZqFGGLMExgmrPvdGrxgRrhLhpxUo1KGW","pubKey":"7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn"},{"digest":"SMHbyCLcvds5sRKaWPptSjixxoaiwkQfM1noLGpLSvsmxwUSg4J55UhJtK1ZWiQp3rxy5FEMZpwHGkywexYuwXEWHo","pubKey":"7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW"},{"digest":"SMGP3a7GHW6qWbQY3ZXX5UBhHNFLrSkUzRLLfCFA9Gu6CJVoYVvBQjjCEzaYq9ox38DvyZJQFuLWPirV2G6VMeARqQ","pubKey":"7VeRFF1ednwhrFoe5cngKwPUJ2N4iFKD9Jt53GxSCc1MmPQ6"},{"digest":"SMHGzmEVzZPKyvN3zC6nLbVypufWEfd6cFvnMMjuEXFk5WncLeUx4CyAohTnNLP21ksJ6r15usowbkRFeaUYQgJkre","pubKey":"7VeRGE4V9MR7HgAqTrkxGvJvaaKRZ3fAjHUjYzpNBGcjfAvr"}],"transactionContent":{"operations":[{"@type":"com.jd.blockchain.ledger.LedgerInitOperation","initSetting":{"consensusParticipants":[{"address":"LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw","id":0,"name":"0","participantNodeState":"CONSENSUS","pubKey":"7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn"},{"address":"LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY","id":1,"name":"1","participantNodeState":"CONSENSUS","pubKey":"7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW"},{"address":"LdeNwsiuo7n6HULWhNKc87PBXJXAfGKFon9RE","id":2,"name":"2","participantNodeState":"CONSENSUS","pubKey":"7VeRFF1ednwhrFoe5cngKwPUJ2N4iFKD9Jt53GxSCc1MmPQ6"},{"address":"LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6","id":3,"name":"3","participantNodeState":"CONSENSUS","pubKey":"7VeRGE4V9MR7HgAqTrkxGvJvaaKRZ3fAjHUjYzpNBGcjfAvr"}],"consensusProvider":"com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider","consensusSettings":"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","createdTime":1627618941000,"cryptoSetting":{"autoVerifyHash":true,"hashAlgorithm":8216,"supportedProviders":[{"algorithms":[{},{},{},{},{},{},{}],"name":"com.jd.blockchain.crypto.service.classic.ClassicCryptoService"},{"algorithms":[{},{},{}],"name":"com.jd.blockchain.crypto.service.sm.SMCryptoService"}]},"ledgerSeed":"kULN7uzXyZuC7rD9BMLIgA==","ledgerStructureVersion":-1}},{"@type":"com.jd.blockchain.ledger.UserRegisterOperation","userID":{"address":"LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw","pubKey":"7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn"}},{"@type":"com.jd.blockchain.ledger.UserRegisterOperation","userID":{"address":"LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY","pubKey":"7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW"}},{"@type":"com.jd.blockchain.ledger.UserRegisterOperation","userID":{"address":"LdeNwsiuo7n6HULWhNKc87PBXJXAfGKFon9RE","pubKey":"7VeRFF1ednwhrFoe5cngKwPUJ2N4iFKD9Jt53GxSCc1MmPQ6"}},{"@type":"com.jd.blockchain.ledger.UserRegisterOperation","userID":{"address":"LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6","pubKey":"7VeRGE4V9MR7HgAqTrkxGvJvaaKRZ3fAjHUjYzpNBGcjfAvr"}},{"@type":"com.jd.blockchain.ledger.RolesConfigureOperation","roles":[{"disableLedgerPermissions":[],"disableTransactionPermissions":[],"enableLedgerPermissions":["CONFIGURE_ROLES","AUTHORIZE_USER_ROLES","SET_CONSENSUS","SET_CRYPTO","REGISTER_PARTICIPANT","REGISTER_USER","REGISTER_DATA_ACCOUNT","REGISTER_CONTRACT","UPGRADE_CONTRACT","SET_USER_ATTRIBUTES","WRITE_DATA_ACCOUNT","APPROVE_TX","CONSENSUS_TX","REGISTER_EVENT_ACCOUNT","WRITE_EVENT_ACCOUNT"],"enableTransactionPermissions":["DIRECT_OPERATION","CONTRACT_OPERATION"],"roleName":"DEFAULT"}]},{"@type":"com.jd.blockchain.ledger.UserAuthorizeOperation","userRolesAuthorizations":[{"authorizedRoles":[],"policy":"UNION","unauthorizedRoles":[],"userAddresses":["LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw"]}]},{"@type":"com.jd.blockchain.ledger.UserAuthorizeOperation","userRolesAuthorizations":[{"authorizedRoles":[],"policy":"UNION","unauthorizedRoles":[],"userAddresses":["LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY"]}]},{"@type":"com.jd.blockchain.ledger.UserAuthorizeOperation","userRolesAuthorizations":[{"authorizedRoles":[],"policy":"UNION","unauthorizedRoles":[],"userAddresses":["LdeNwsiuo7n6HULWhNKc87PBXJXAfGKFon9RE"]}]},{"@type":"com.jd.blockchain.ledger.UserAuthorizeOperation","userRolesAuthorizations":[{"authorizedRoles":[],"policy":"UNION","unauthorizedRoles":[],"userAddresses":["LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6"]}]}],"timestamp":1627618941000},"transactionHash":"j5vJGDBQLi6Vo5Gxtsab1vyL2TFaf1NoXDi6Xv2uvCcj9T"},"result":{"blockHeight":0,"dataSnapshot":{"adminAccountHash":"j5u4gqeAkKb3DoELpXP9bDgAxCVRQgKsguPvE1Wc9re1UT","userAccountSetHash":"j5hzkPPBJAqKs4rLWbEiFhbh1VW6Jc2xk878X5A6JywPnC"},"executionState":"SUCCESS","transactionHash":"j5vJGDBQLi6Vo5Gxtsab1vyL2TFaf1NoXDi6Xv2uvCcj9T"}}] +``` + +查询高度`10`区块内交易列表(仅统计区块`10`交易),从第`0`条开始,最大返回`1`: +```bash +:bin$ ./jdchain-cli.sh query txs --height 10 --index 0 --count 1 --in-block +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +[{"request":{"endpointSignatures":[{"digest":"SMKgce34AxQ8JEDDZY3x7iMvbL5QymiC93XPWqSirUB2AN8rvx18ynDS9f1zFA6QyXQNowA1XNhaLWnArrt7JHHxhY","pubKey":"7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn"}],"nodeSignatures":[{"digest":"SMKgce34AxQ8JEDDZY3x7iMvbL5QymiC93XPWqSirUB2AN8rvx18ynDS9f1zFA6QyXQNowA1XNhaLWnArrt7JHHxhY","pubKey":"7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn"}],"transactionContent":{"ledgerHash":"j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg","operations":[{"@type":"com.jd.blockchain.ledger.DataAccountKVSetOperation","accountAddress":"LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC","writeSet":[{"expectedVersion":-1,"key":"k1","value":{"bytes":"djE=","type":"TEXT"}}]}],"timestamp":1627632026435},"transactionHash":"j5fo2aAwp2tsneHm4wE8AnWLV7CKyax7BLWJqJm2V3WsrD"},"result":{"blockHeight":10,"dataSnapshot":{"adminAccountHash":"j5p5z4es9RPrQWFu2nSJBQFT68byeGqAdUDu63qa5xV8Df","dataAccountSetHash":"j5fSmQkk8tb9v9SYDmaAko3oJJqmCm54HGbQwgbV2nTCVk","userAccountSetHash":"j5mwiewVaxPLYQciovrB9nShWD5nr7YYFopbmWx28jqiFH","userEventSetHash":"j5wf9v6ixDDSD2gRi47r3vomkmTaRCqSLNbaNxrKcVdtD7"},"executionState":"SUCCESS","transactionHash":"j5fo2aAwp2tsneHm4wE8AnWLV7CKyax7BLWJqJm2V3WsrD"}}] +``` + +#### 交易详情 + +```bash +e:bin$ ./jdchain-cli.sh query tx -h +Query transaction. +Usage: jdchain-cli query tx [-hV] [--pretty] [--gw-host=] + [--gw-port=] [--hash=] [--home=] + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --hash= Transaction hash + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `hash`,交易哈希 + +如查询交易`j5fo2aAwp2tsneHm4wE8AnWLV7CKyax7BLWJqJm2V3WsrD`详情: +```bash +:bin$ ./jdchain-cli.sh query tx --hash j5fo2aAwp2tsneHm4wE8AnWLV7CKyax7BLWJqJm2V3WsrD +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"request":{"endpointSignatures":[{"digest":"SMKgce34AxQ8JEDDZY3x7iMvbL5QymiC93XPWqSirUB2AN8rvx18ynDS9f1zFA6QyXQNowA1XNhaLWnArrt7JHHxhY","pubKey":"7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn"}],"nodeSignatures":[{"digest":"SMKgce34AxQ8JEDDZY3x7iMvbL5QymiC93XPWqSirUB2AN8rvx18ynDS9f1zFA6QyXQNowA1XNhaLWnArrt7JHHxhY","pubKey":"7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn"}],"transactionContent":{"ledgerHash":"j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg","operations":[{"@type":"com.jd.blockchain.ledger.DataAccountKVSetOperation","accountAddress":"LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC","writeSet":[{"expectedVersion":-1,"key":"k1","value":{"bytes":"djE=","type":"TEXT"}}]}],"timestamp":1627632026435},"transactionHash":"j5fo2aAwp2tsneHm4wE8AnWLV7CKyax7BLWJqJm2V3WsrD"},"result":{"blockHeight":10,"dataSnapshot":{"adminAccountHash":"j5p5z4es9RPrQWFu2nSJBQFT68byeGqAdUDu63qa5xV8Df","dataAccountSetHash":"j5fSmQkk8tb9v9SYDmaAko3oJJqmCm54HGbQwgbV2nTCVk","userAccountSetHash":"j5mwiewVaxPLYQciovrB9nShWD5nr7YYFopbmWx28jqiFH","userEventSetHash":"j5wf9v6ixDDSD2gRi47r3vomkmTaRCqSLNbaNxrKcVdtD7"},"executionState":"SUCCESS","transactionHash":"j5fo2aAwp2tsneHm4wE8AnWLV7CKyax7BLWJqJm2V3WsrD"}} +``` + +#### 用户总数 + +查询用户总数: +```bash +:bin$ ./jdchain-cli.sh query users-count +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +10 +``` +当前区块链网络共有`10`个用户 + +#### 用户列表 + +```bash +:bin$ ./jdchain-cli.sh query users -h +Query users. +Usage: jdchain-cli query users [-hV] [--pretty] --count= + [--gw-host=] [--gw-port=] + [--home=] --index= + --count= User item count + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --index= User item index + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `index`,起始位置 +- `count`,最大返回 + +如分页查询用户列表,从第`0`个开始,最大返回`10`条: +```bash +:bin$ ./jdchain-cli.sh query users --index 0 --count 10 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +ADDRESS PUBKEY +LdeP2ji8PR1DPsLt5NoFeiBnhpckrLHgCJge6 7VeRGE4V9MR7HgAqTrkxGvJvaaKRZ3fAjHUjYzpNBGcjfAvr +LdeNq3862vtUCeptww1T5mVvLbAeppYqVNdqD 7VeRGuwP2iUykAL4beftP1DuDTj7y2uFGEM6mx3Dy7YSm2j1 +LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC 7VeRFk4ANQHjWjAmAoL7492fuykTpXujihJeAgbXT2J9H9Yk +LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw 7VeRJpb2XX8XKAaC7G5zQg9DbgKM8gmLhUBtGFmerFbhJTZn +LdeNwTWpyzqioLURrHQuoGcnwA6YLiFWn3LNn 7VeRH7BsRntvJmomjw7YvF5HZVsSMb48GKzPnAP7iekRCLGq +LdeNiXZbsBCsTc2ZGp1PGBX81aUxPekhwEwmY 7VeREmuT4fF9yRPEMbSSaNLKbLa3qoTpfGHRgwpnSWUn5tqW +LdeNisM5oTypwPYv9tnhFNosRjCyXzzViU4SA 7VeREyEcDcY85DRdWAEsmJ4Moh89eE21AU2LEDbYG3t3MrGo +LdeNqvSjL4izfpMNsGpQiBpTBse4g6qLxZ6j5 7VeRFd2LB8ZmYnVNc2pux5TwVqHv3pwT6JXoF3fzDon9bSXK +LdeNwsiuo7n6HULWhNKc87PBXJXAfGKFon9RE 7VeRFF1ednwhrFoe5cngKwPUJ2N4iFKD9Jt53GxSCc1MmPQ6 +LdeNufGZewrvS7sE4VWC9m1SFkPqVwjBN87LB 7VeRMGBMMBQVoZQTU3mcJYGgbVcQzxXiq6NK69TaCjEoktLf +``` +返回`10`个用户的地址和公私钥信息 + +| 由于`JD Chain`网络并不保证用户(数据账户/事件账户/合约账户)按创建顺序排列,所以当有新的用户注册后,前后两次相同参数的查询数据可能不一致!!! + +#### 用户详情 + +```bash +:bin$ ./jdchain-cli.sh query user -h +Query user. +Usage: jdchain-cli query user [-hV] [--pretty] --address=
+ [--gw-host=] [--gw-port=] + [--home=] + --address=
User address + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,用户地址 + +根据地址`LdeNufGZewrvS7sE4VWC9m1SFkPqVwjBN87LB`查询用户详情: +```bash +:bin$ ./jdchain-cli.sh query user --address LdeNufGZewrvS7sE4VWC9m1SFkPqVwjBN87LB +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"address":"LdeNufGZewrvS7sE4VWC9m1SFkPqVwjBN87LB","pubKey":"7VeRMGBMMBQVoZQTU3mcJYGgbVcQzxXiq6NK69TaCjEoktLf"} +``` + +#### 角色权限 + +```bash +:bin$ ./jdchain-cli.sh query role-privileges -h +Query role privileges. +Usage: jdchain-cli query role-privileges [-hV] [--pretty] [--gw-host=] + [--gw-port=] [--home=] --role= + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + --role= Role name + -V, --version Print version information and exit. +``` +- `role`,角色名称 + +查询角色`ROLE1`权限信息: +```bash +:bin$ ./jdchain-cli.sh query role-privileges --role ROLE1 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"ledgerPrivilege":{"permissionCount":2,"privilege":["REGISTER_USER","REGISTER_DATA_ACCOUNT"]},"transactionPrivilege":{"permissionCount":2,"privilege":["DIRECT_OPERATION","CONTRACT_OPERATION"]}} +``` + +#### 用户权限 + +```bash +:bin$ ./jdchain-cli.sh query user-privileges -h +Query user privileges. +Usage: jdchain-cli query user-privileges [-hV] [--pretty] --address=
+ [--gw-host=] [--gw-port=] [--home=] + --address=
User address + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,用户地址 + +查询用户`LdeNufGZewrvS7sE4VWC9m1SFkPqVwjBN87LB`权限信息: +```bash +:bin$ ./jdchain-cli.sh query user-privileges --address LdeNufGZewrvS7sE4VWC9m1SFkPqVwjBN87LB +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"ledgerPrivilegesBitset":{"privilege":["CONFIGURE_ROLES","AUTHORIZE_USER_ROLES","SET_CONSENSUS","SET_CRYPTO","REGISTER_PARTICIPANT","REGISTER_USER","REGISTER_DATA_ACCOUNT","REGISTER_CONTRACT","UPGRADE_CONTRACT","SET_USER_ATTRIBUTES","WRITE_DATA_ACCOUNT","APPROVE_TX","CONSENSUS_TX","REGISTER_EVENT_ACCOUNT","WRITE_EVENT_ACCOUNT"]},"transactionPrivilegesBitset":{"privilege":["DIRECT_OPERATION","CONTRACT_OPERATION"]},"userAddress":"LdeNufGZewrvS7sE4VWC9m1SFkPqVwjBN87LB","userRole":["DEFAULT"]} +``` + +#### 数据账户总数 + +查询数据账户总数: +```bash +:bin$ ./jdchain-cli.sh query data-accounts-count +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +1 +``` +当前账本共有一个数据账户 + +#### 数据账户列表 + +```bash +:bin$ ./jdchain-cli.sh query data-accounts -h +Query data accounts. +Usage: jdchain-cli query data-accounts [-hV] [--pretty] --count= + [--gw-host=] + [--gw-port=] [--home=] + --index= + --count= Data account item count + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --index= Data account item index + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `index`,起始位置 +- `count`,最大返回 + +如分页查询数据账户列表,从第`0`个开始,最大返回`10`条: +```bash +:bin$ ./jdchain-cli.sh query data-accounts --index 0 --count 10 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +ADDRESS PUBKEY +LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC 7VeRFk4ANQHjWjAmAoL7492fuykTpXujihJeAgbXT2J9H9Yk +``` +返回数据账户的地址和公私钥信息 + +#### 数据账户详情 + +```bash +:bin$ ./jdchain-cli.sh query data-account -h +Query data account. +Usage: jdchain-cli query data-account [-hV] [--pretty] --address=
+ [--gw-host=] [--gw-port=] + [--home=] + --address=
Data account address + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,数据账户地址 + +查询数据账户`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`详情: +```bash +:bin$ ./jdchain-cli.sh query data-account --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"address":"LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC","dataRootHash":"j5vyv6SmvSXQNKyjsEVCQJsyqXxKGZMBU62fKvtdJm2W4y","headerRootHash":"j5sA2KPgY9vidgTUCjCJiscn2CXapgSJsVnWe54xXKohej","pubKey":"7VeRFk4ANQHjWjAmAoL7492fuykTpXujihJeAgbXT2J9H9Yk"} +``` + +#### KV总数 + +```bash +:bin$ ./jdchain-cli.sh query kvs-count -h +Query key-values count. +Usage: jdchain-cli query kvs-count [-hV] [--pretty] --address=
+ [--gw-host=] [--gw-port=] + [--home=] + --address=
Data account address + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,数据账户地址 + +查询数据账户`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`中`kv`数据总数: +```bash +:bin$ ./jdchain-cli.sh query kvs-count --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +1 +``` +共有一个`kv` + +#### KV列表 + +```bash +:bin$ ./jdchain-cli.sh query kvs -h +Query kvs. +Usage: jdchain-cli query kvs [-hV] [--pretty] --address=
+ --count= [--gw-host=] + [--gw-port=] [--home=] + --index= + --address=
Data account address + --count= KV item count + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --index= KV item index + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,数据账户地址 +- `index`,起始位置 +- `count`,最大返回 + +如分页查询数据账户`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`中`kv`列表,从第`0`个开始,最大返回`10`条: +```bash +:bin$ ./jdchain-cli.sh query kvs --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC --index 0 --count 10 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"key":"k1","type":"TEXT","value":"v1","version":0} +``` + +#### KV详情 + +```bash +:bin$ ./jdchain-cli.sh query kv -h +Query kv. +Usage: jdchain-cli query kv [-hV] [--pretty] --address=
+ [--gw-host=] [--gw-port=] + [--home=] --key= + --address=
Data account address + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --key= Key + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,数据账户地址 +- `key`,`key` + +查询数据账户`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`中`k1`最新数据: +```bash +:bin$ ./jdchain-cli.sh query kv --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC --key k1 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"key":"k1","type":"TEXT","value":"v1","version":0} +``` + +#### 用户事件账户总数 + +查询数据账户总数: +```bash +:bin$ ./jdchain-cli.sh query user-event-accounts-count +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +4 +``` +当前账本共有`4`个数据账户 + +#### 用户事件账户列表 + +```bash +:bin$ ./jdchain-cli.sh query user-event-accounts -h +Query user event accounts. +Usage: jdchain-cli query user-event-accounts [-hV] [--pretty] --count= + [--gw-host=] [--gw-port=] [--home=] --index= + --count= Event account item count + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --index= Event account item index + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `index`,起始位置 +- `count`,最大返回 + +如分页查询用户事件账户列表,从第`0`个开始,最大返回`10`条: +```bash +:bin$ ./jdchain-cli.sh query user-event-accounts --index 0 --count 10 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +ADDRESS PUBKEY +LdeNhAxxXjbh56LqeB7xHpgZgHG6GDTZ45GgJ 7VeR82o3hZy1AVEjmxfNpHHW3d1zabbELmJUnijGkKJNDXu5 +LdeP33nxsYxYgaELQUkd8tBsTmwrkySiqnAVF 7VeRBA5zD2EDCiRtsiHzMQUEPf52hjKwhAi6PfNCgoiRQrSw +LdeNnDJyqYgxDernBf6Vh68CkM5FbJNYtQCPA 7VeRB71W3anhCBretEP2R9YjiFB7ne2o5qhsivPo3XmHZ7cJ +LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC 7VeRFk4ANQHjWjAmAoL7492fuykTpXujihJeAgbXT2J9H9Yk +``` +返回用户事件账户的地址和公私钥信息 + +#### 用户事件账户详情 + +```bash +:bin$ ./jdchain-cli.sh query user-event-account -h +Query user event account. +Usage: jdchain-cli query user-event-account [-hV] [--pretty] + --address=
[--gw-host=] [--gw-port=] + [--home=] + --address=
Event account address + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,用户事件账户地址 + +查询事件账户`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`详情: +```bash +:bin$ ./jdchain-cli.sh query user-event-account --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"address":"LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC","pubKey":"7VeRFk4ANQHjWjAmAoL7492fuykTpXujihJeAgbXT2J9H9Yk"} +``` + +#### 用户事件名总数 + +```bash +:bin$ ./jdchain-cli.sh query user-event-names-count -h +Query user event names count. +Usage: jdchain-cli query user-event-names-count [-hV] [--pretty] + --address=
[--gw-host=] [--gw-port=] + [--home=] + --address=
Event account address + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,用户事件账户地址 + +查询事件账户`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`事件名总数: +```bash +:bin$ ./jdchain-cli.sh query user-event-names-count --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +1 +``` + +#### 用户事件名列表 + +```bash +:bin$ ./jdchain-cli.sh query user-event-names -h +Query user event names. +Usage: jdchain-cli query user-event-names [-hV] [--pretty] --address=
+ --count= [--gw-host=] [--gw-port=] + [--home=] --index= + --address=
Event account address + --count= Event name item count + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --index= Event name item index + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,事件账户地址 +- `index`,起始位置 +- `count`,最大返回 + +如分页查询用户事件账户`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`事件名列表,从第`0`个开始,最大返回`10`条: +```bash +:bin$ ./jdchain-cli.sh query user-event-names --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC --index 0 --count 10 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +t1 +``` +当前事件账户仅有一个事件名 + +#### 用户事件总数 + +```bash +:bin$ ./jdchain-cli.sh query user-events-count -h +Query user events count. +Usage: jdchain-cli query user-events-count [-hV] [--pretty] --address=
+ [--gw-host=] [--gw-port=] [--home=] --name= + --address=
Event account address + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --name= Event name + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,事件账户地址 +- `name`,事件名 + +查询事件账户`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`事件名`t1`中事件总数: +```bash +:bin$ ./jdchain-cli.sh query user-events-count --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC --name t1 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +1 +``` +当前事件名仅有一个事件 + +#### 用户事件列表 + +```bash +:bin$ ./jdchain-cli.sh query user-events -h +Query user events. +Usage: jdchain-cli query user-events [-hV] [--pretty] --address=
+ --count= [--gw-host=] + [--gw-port=] [--home=] + --index= --name= + --address=
Event account address + --count= Event name item count + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --index= Event name item index + --name= Event name + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,事件账户地址 +- `name`,事件名 +- `index`,起始位置 +- `count`,最大返回 + +分页查询用户事件账户`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`事件名`t1`中事件,从第`0`个开始,最大返回`10`条: +```bash +:bin$ ./jdchain-cli.sh query user-events --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC --name t1 --index 0 --count 10 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"blockHeight":12,"content":{"bytes":"YzE=","type":"TEXT"},"contractSource":"","eventAccount":"LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC","name":"t1","sequence":0,"transactionSource":"j5jSszhiJUTbCGtFgxd6uBWyxj56CEHRyhDF6nAnUvJTp7"} +``` + +#### 最新用户事件 + +```bash +:bin$ ./jdchain-cli.sh query latest-user-event -h +Query latest user event. +Usage: jdchain-cli query latest-user-event [-hV] [--pretty] --address=
+ [--gw-host=] [--gw-port=] [--home=] --name= + --address=
Event account address + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --name= Event name + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,时间账户地址 +- `name`,事件名 + +查询用户事件账户`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`事件名`t1`最新事件: +```bash +:bin$ ./jdchain-cli.sh query latest-user-event --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC --name t1 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +{"blockHeight":12,"content":{"bytes":"YzE=","type":"TEXT"},"contractSource":"","eventAccount":"LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC","name":"t1","sequence":0,"transactionSource":"j5jSszhiJUTbCGtFgxd6uBWyxj56CEHRyhDF6nAnUvJTp7"} +``` + +#### 合约总数 + +查询合约总数: +```bash +:bin$ ./jdchain-cli.sh query contracts-count +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +1 +``` +当前账本仅有一个合约 + +#### 合约列表 + +```bash +:bin$ ./jdchain-cli.sh query contracts -h +Query contracts. +Usage: jdchain-cli query contracts [-hV] [--pretty] --count= + [--gw-host=] [--gw-port=] + [--home=] --index= + --count= Contract item count + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --index= Contract item index + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `index`,起始位置 +- `count`,最大返回 + +分页查询合约,从第`0`个开始,最大返回`10`条: +```bash +:bin$ ./jdchain-cli.sh query contracts --index 0 --count 10 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +ADDRESS PUBKEY +LdeNyF6jdNry5iCqmHdAFTQPvC8UkbJ9avoXH 7VeRFZEqSdXWQxaLUFaAgJVdVTssuwQdBg4KPGgCCTbrzqxA +``` +返回合约地址和公钥信息 + +#### 合约详情 + +```bash +e:bin$ ./jdchain-cli.sh query contract -h +Query contract. +Usage: jdchain-cli query contract [-hV] [--pretty] --address=
+ [--gw-host=] [--gw-port=] + [--home=] + --address=
Contract address + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,合约地址 + +查询合约`LdeNyF6jdNry5iCqmHdAFTQPvC8UkbJ9avoXH`详情: +```bash +:bin$ ./jdchain-cli.sh query contract --address LdeNyF6jdNry5iCqmHdAFTQPvC8UkbJ9avoXH +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +package com.jdchain.samples.contract; + +import com.jd.blockchain.contract.*; +import utils.*; +import com.jd.blockchain.crypto.*; +import com.jd.blockchain.ledger.*; + +public class SampleContractImpl implements EventProcessingAware, SampleContract +{ + private ContractEventContext eventContext; + + public void setKVWithVersion(final String address, final String key, final String value, final long version) { + this.eventContext.getLedger().dataAccount(Bytes.fromBase58(address)).setText(key, value, version); + } + + public void setKV(final String address, final String key, final String value) { + final TypedKVEntry[] entries = this.eventContext.getUncommittedLedger().getDataEntries(address, new String[] { key }); + long version = -1L; + if (null != entries && entries.length > 0) { + version = entries[0].getVersion(); + } + this.eventContext.getLedger().dataAccount(Bytes.fromBase58(address)).setText(key, value, version); + } + + public String registerUser(final String seed) { + final CryptoAlgorithm algorithm = Crypto.getAlgorithm("ed25519"); + final SignatureFunction signFunc = Crypto.getSignatureFunction(algorithm); + final AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair(seed.getBytes()); + final BlockchainKeypair keypair = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey()); + this.eventContext.getLedger().users().register(keypair.getIdentity()); + return keypair.getAddress().toBase58(); + } + + public String registerDataAccount(final String seed) { + final CryptoAlgorithm algorithm = Crypto.getAlgorithm("ed25519"); + final SignatureFunction signFunc = Crypto.getSignatureFunction(algorithm); + final AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair(seed.getBytes()); + final BlockchainKeypair keypair = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey()); + this.eventContext.getLedger().dataAccounts().register(keypair.getIdentity()); + return keypair.getAddress().toBase58(); + } + + public String registerEventAccount(final String seed) { + final CryptoAlgorithm algorithm = Crypto.getAlgorithm("ed25519"); + final SignatureFunction signFunc = Crypto.getSignatureFunction(algorithm); + final AsymmetricKeypair cryptoKeyPair = signFunc.generateKeypair(seed.getBytes()); + final BlockchainKeypair keypair = new BlockchainKeypair(cryptoKeyPair.getPubKey(), cryptoKeyPair.getPrivKey()); + this.eventContext.getLedger().eventAccounts().register(keypair.getIdentity()); + return keypair.getAddress().toBase58(); + } + + public void publishEventWithSequence(final String address, final String topic, final String content, final long sequence) { + this.eventContext.getLedger().eventAccount(Bytes.fromBase58(address)).publish(topic, content, sequence); + } + + public void publishEvent(final String address, final String topic, final String content) { + final Event event = this.eventContext.getUncommittedLedger().getLatestEvent(address, topic); + long sequence = -1L; + if (null != event) { + sequence = event.getSequence(); + } + this.eventContext.getLedger().eventAccount(Bytes.fromBase58(address)).publish(topic, content, sequence); + } + + public void beforeEvent(final ContractEventContext eventContext) { + this.eventContext = eventContext; + } + + public void postEvent(final ContractEventContext eventContext, final Exception error) { + } +} + +``` \ No newline at end of file diff --git a/docs/cli/tx.md b/docs/cli/tx.md new file mode 100644 index 00000000..a6bf3b74 --- /dev/null +++ b/docs/cli/tx.md @@ -0,0 +1,531 @@ +### 交易 + +```bash +:bin$ ./jdchain-cli.sh tx -h +Usage: git status [...] [--] [...] +Build, sign or send transaction. + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + Default: ../ + --pretty Pretty json print + -V, --version Print version information and exit. +Commands: + user-register Register new user. + role Create or config role. + authorization User role authorization. + data-account-register Register new data account. + kv Set key-value. + event Publish event. + contract-deploy Deploy or update contract. + contract Call contract method. + event-account-register Register event account. + sign Sign transaction. + send Send transaction. + help Displays help information about the specified command +``` + +参数: +- `export`,导出交易到指定位置,用于离线交易相关命令 +- `gw-host`,网关服务地址,默认`127.0.0.1` +- `gw-port`,网关服务端口,默认`8080` +- `home`,指定密钥存储相关目录,`${home}/config/keys` + +命令: +- `user-register`,[注册用户](#注册用户) +- `role`,[角色管理](#角色管理) +- `authorization`,[权限配置](#权限配置) +- `data-account-register`,[注册数据账户](#注册数据账户) +- `kv`,[KV设值](#KV设值) +- `event-account-register`,[注册事件账户](#注册事件账户) +- `event`,[发布事件](#发布事件) +- `contract-deploy`,[部署合约](#部署合约) +- `contract`,[合约调用](#合约调用) +- `sign`,[离线交易签名](#离线交易签名) +- `send`,[离线交易发送](#离线交易发送) + +#### 注册用户 + +```bash +:bin$ ./jdchain-cli.sh tx user-register -h +Register new user. +Usage: jdchain-cli tx user-register [-hV] [--pretty] [--export=] + [--gw-host=] [--gw-port=] + [--home=] + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. +``` +从`${home}/config/keys`目录下密钥对选择密钥注册到网关服务对应的区块链网络。 + +如: +```bash +:bin$ ./jdchain-cli.sh tx user-register +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +// 选择账本,当前网关服务只有上面一个可用账本 +> 0 +select keypair to register: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +// 选择公私钥对用于注册用户 +> 1 +input password of the key: +// 输入所选择公私钥对密钥密码 +> 1 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +// 选择链上已存在且有注册用户权限的用户所对应的公私钥对,用于交易签名 +> 0 +input password of the key: +// 输入签名私钥密码 +> 1 +register user: [LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC] +``` +会在链上注册地址为`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`的用户账户信息。 + + +#### 角色管理 +```bash +:bin$ ./jdchain-cli.sh tx role -h +Create or config role. +Usage: jdchain-cli tx role [-hV] [--pretty] [--export=] + [--gw-host=] [--gw-port=] + [--home=] --name= + [--disable-ledger-perms=[, + ...]]... + [--disable-transaction-perms=[,...]]... + [--enable-ledger-perms=[, + ...]]... + [--enable-transaction-perms= + [,...]]... + --disable-ledger-perms=[,...] + Disable ledger permissions + --disable-transaction-perms=[, + ...] + Disable transaction permissions + --enable-ledger-perms=[,...] + Enable ledger permissions + --enable-transaction-perms=[, + ...] + Enable transaction permissions + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --name= Role name + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `name`,角色名称,不存在则创建 +- `disable-ledger-perms`,禁用的账本权限列表,半角逗号分割 +- `disable-transaction-perms`,禁用的交易权限列表,半角逗号分割 +- `enable-ledger-perms`,的账本权限列表,半角逗号分割 +- `enable-transaction-perms`,禁用的交易权限列表,半角逗号分割 + +如: +```bash +:bin$ ./jdchain-cli.sh tx role --name ROLE1 --enable-ledger-perms REGISTER_USER,REGISTER_DATA_ACCOUNT --enable-transaction-perms DIRECT_OPERATION,CONTRACT_OPERATION +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +// 选择账本 +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +// 选择签名账户 +> 0 +input password of the key: +// 输入签名账户私钥密码 +> 1 +Role config success! +``` + +#### 权限配置 + +```bash +:bin$ ./jdchain-cli.sh tx authorization -h +User role authorization. +Usage: jdchain-cli tx authorization [-hV] [--pretty] --address=
+ [--export=] [--gw-host=] + [--gw-port=] [--home=] + [--policy=] + [--authorize=[, + ...]]... + [--unauthorize=[, + ...]]... + --address=
User address + --authorize=[,...] + Authorize roles + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --policy= Role policy + --pretty Pretty json print + --unauthorize=[,...] + Unauthorize roles + -V, --version Print version information and exit. +``` +- `address`,用户地址 +- `authorize`,赋予角色列表,半角逗号分割 +- `unauthorize`,移除角色列表,半角逗号分割 +- `policy`,角色策略,`UNION`/`INTERSECT`,默认`UNION`合并所有角色权限 + +如: +```bash +:bin$ ./jdchain-cli.sh tx authorization --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC --authorize ROLE1 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +> 0 +input password of the key: +> 1 +Authorization config success! +``` + +#### 注册数据账户 + +```bash +:bin$ ./jdchain-cli.sh tx data-account-register -h +Register new data account. +Usage: jdchain-cli tx data-account-register [-hV] [--pretty] + [--export=] [--gw-host=] [--gw-port=] + [--home=] [--pubkey=] + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + --pubkey= The pubkey of the exist data account + -V, --version Print version information and exit. +``` +- `pubkey`,待注册数据账户私钥 + +如: +```bash +:bin$ ./jdchain-cli.sh tx data-account-register --pubkey 7VeRFk4ANQHjWjAmAoL7492fuykTpXujihJeAgbXT2J9H9Yk +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +> 0 +input password of the key: +> 1 +register data account: [LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC] +``` +会在链上注册地址为`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`的数据账户信息。 + +#### KV设值 + +```bash +:bin$ ./jdchain-cli.sh tx kv -h +Set key-value. +Usage: jdchain-cli tx kv [-hV] [--pretty] --address=
+ [--export=] [--gw-host=] + [--gw-port=] [--home=] --key= + --value= [--ver=] + --address=
Data account address + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --key= Key to set + --pretty Pretty json print + -V, --version Print version information and exit. + --value= Value to set + --ver= Version of the key-value +``` +- `address`,数据账户地址 +- `key`,键 +- `value`,值 +- `ver`,版本 + +如向账户地址`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`写入`k1`:`v1`:`-1`键值对数据: +```bash +:bin$ ./jdchain-cli.sh tx kv --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC --key k1 --value v1 --ver -1 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +> 0 +input password of the key: +> 1 +set kv success +``` + +#### 注册事件账户 + +```bash +:bin$ ./jdchain-cli.sh tx event-account-register -h +Register event account. +Usage: jdchain-cli tx event-account-register [-hV] [--pretty] + [--export=] [--gw-host=] [--gw-port=] + [--home=] [--pubkey=] + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + --pubkey= The pubkey of the exist event account + -V, --version Print version information and exit. +``` +- `pubkey`,待注册事件账户私钥 + +如: +```bash +:bin$ ./jdchain-cli.sh tx event-account-register --pubkey 7VeRFk4ANQHjWjAmAoL7492fuykTpXujihJeAgbXT2J9H9Yk +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +> 0 +input password of the key: +> 1 +register event account: [LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC] +``` +会在链上注册地址为`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`的事件账户信息。 + +#### 发布事件 +```bash +:bin$ ./jdchain-cli.sh tx event -h +Publish event. +Usage: jdchain-cli tx event [-hV] [--pretty] --address=
+ --content= [--export=] + [--gw-host=] [--gw-port=] + [--home=] [--sequence=] + --name= + --address=
Contract address + --content= Event content + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + --sequence= Sequence of the event + --name= Event name + -V, --version Print version information and exit. +``` +- `address`,事件账户地址 +- `name`,事件名 +- `content`,事件内容 +- `sequence`,事件序号 + +如向账户地址`LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC`发布事件`n1`:`c1`:`-1`: +```bash +:bin$ ./jdchain-cli.sh tx event --address LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC --name n1 --content c1 --sequence -1 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +> 0 +input password of the key: +> 1 +event publish success +``` + +#### 部署合约 + +```bash +:bin$ ./jdchain-cli.sh tx contract-deploy -h +Deploy or update contract. +Usage: jdchain-cli tx contract-deploy [-hV] [--pretty] --car= + [--export=] [--gw-host=] + [--gw-port=] [--home=] + [--pubkey=] + --car= The car file path + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + --pubkey= The pubkey of the exist contract + -V, --version Print version information and exit. +``` +- `pubkey`,合约公钥,更新合约时使用 +- `car`,合约`car`文件 + +如将`contract-samples-1.5.0.RELEASE.car`文件中的合约部署上链: +```bash +:bin$ ./jdchain-cli.sh tx contract-deploy --car /home/imuge/Desktop/jdchain-cli/1.5.0/contract-samples-1.5.0.RELEASE.car +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +> 0 +input password of the key: +> 1 +deploy contract: [LdeNyF6jdNry5iCqmHdAFTQPvC8UkbJ9avoXH] +``` +合约地址:`LdeNyF6jdNry5iCqmHdAFTQPvC8UkbJ9avoXH` + +#### 合约调用 + +```bash +:bin$ ./jdchain-cli.sh tx contract -h +Call contract method. +Usage: jdchain-cli tx contract [-hV] [--pretty] --address=
+ [--export=] [--gw-host=] + [--gw-port=] [--home=] + --method= [--args=[,...]]... + --address=
Contract address + --args=[,...] + Method arguments + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --method= Contract method + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `address`,合约地址 +- `method`,合约方法 +- `args`,合约参数,半角逗号分割,命令行中会将所有参数处理为字符串,非字符串参数方法调用暂无法通过命令行工具调用 + +如调用合约`LdeNyF6jdNry5iCqmHdAFTQPvC8UkbJ9avoXH`中`registerUser`方法,传参`ed386a148fcb48b281b325f66103c805`: +```bash +:bin$ ./jdchain-cli.sh tx contract --address LdeNyF6jdNry5iCqmHdAFTQPvC8UkbJ9avoXH --method registerUser --args ed386a148fcb48b281b325f66103c805 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +> 0 +input password of the key: +> 1 +call contract success +return string: LdeNqvSjL4izfpMNsGpQiBpTBse4g6qLxZ6j5 +``` +调用成功并返回了字符串:`LdeNqvSjL4izfpMNsGpQiBpTBse4g6qLxZ6j5` + + +#### 离线交易签名 + +1. 离线交易 + +执行以上所有交易时,若`export`参数不为空,则会执行交易写入本地操作,而非签名并发送交易,离线交易可以 + +如构造合约调用操作交易并保存到本地: +```bash +:bin$ ./jdchain-cli.sh tx contract --address LdeNyF6jdNry5iCqmHdAFTQPvC8UkbJ9avoXH --method registerUser --args ed386a148fcb48b281b325f66103c810 --export /txs +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +export transaction success: /txs/j5xR8ty8YbujTYKNRshmbfMYsL4jfe3yRUtMparmeHppd3 +``` +交易内容会被序列化报存在`/txs/j5xR8ty8YbujTYKNRshmbfMYsL4jfe3yRUtMparmeHppd3`中,其中`j5xR8ty8YbujTYKNRshmbfMYsL4jfe3yRUtMparmeHppd3`是该交易哈希。 + +2. 离线签名 + +```bash +:bin$ ./jdchain-cli.sh tx sign -h +Sign transaction. +Usage: jdchain-cli tx sign [-hV] [--pretty] [--export=] + [--gw-host=] [--gw-port=] + [--home=] [--tx=] + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --tx= Local transaction file + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `import`,离线交易路径 + +如对步骤1中创建的离线交易添加终端用户(此用户需是链上存在的且有相关权限的用户)签名: +```bash +:bin$ ./jdchain-cli.sh tx sign --tx /txs/j5xR8ty8YbujTYKNRshmbfMYsL4jfe3yRUtMparmeHppd3 +select keypair to sign tx: +INDEX KEY ADDRESS +0 peer0 LdeNyibeafrAQXgHjBxgQxoLbna6hL4BcXZiw +1 k1 LdeNwQWabrf6WSjZ35saFo52MfQFhVKvm11aC +> 0 +input password of the key: +> 1 +Sign transaction success! +``` + +#### 离线交易发送 + +发送本地已经签名完成的交易 +```bash +:bin$ ./jdchain-cli.sh tx send -h +Send transaction. +Usage: jdchain-cli tx send [-hV] [--pretty] [--export=] + [--gw-host=] [--gw-port=] + [--home=] [--tx=] + --export= Transaction export directory + --gw-host= Set the gateway host. Default: 127.0.0.1 + --gw-port= Set the gateway port. Default: 8080 + -h, --help Show this help message and exit. + --home= Set the home directory. + --tx= Local transaction file + --pretty Pretty json print + -V, --version Print version information and exit. +``` +- `import`,离线交易路径 + +如发送`/txs/j5xR8ty8YbujTYKNRshmbfMYsL4jfe3yRUtMparmeHppd3`中包含的交易数据: +```bash +:bin$ ./jdchain-cli.sh tx send --tx /home/imuge/Desktop/jdchain-cli/1.5.0/txs/j5xR8ty8YbujTYKNRshmbfMYsL4jfe3yRUtMparmeHppd3 +select ledger, input the index: +INDEX LEDGER +0 j5sB3sVTFgTqTYzo7KtQjBLSy8YQGPpJpvQZaW9Eqk46dg +> 0 +Send transaction success: j5xR8ty8YbujTYKNRshmbfMYsL4jfe3yRUtMparmeHppd3 +``` \ No newline at end of file diff --git a/docs/contract.md b/docs/contract.md new file mode 100644 index 00000000..fca1fa53 --- /dev/null +++ b/docs/contract.md @@ -0,0 +1,549 @@ +# 智能合约 + +### 1. 简介 + +JD Chain 智能合约系统由5个部分组成:合约代码语言、合约引擎、合约账户、合约开发框架、合约开发插件。 + +合约代码语言是用来编写智能合约的编程语言,合约引擎是解释和执行合约代码的虚拟机。 + +JD Chain 账本中以合约账户的方式对合约代码进行管理。一份部署上链的合约代码需要关联到一个唯一的公钥上,并生成与公钥对应的区块链账户地址,在账本中注册为一个合约账户。在执行之前,系统从账本中读出合约代码并将其加载到合约引擎,由交易执行器调用合约引擎触发合约执行。 + +JD Chain 账本定义了一组标准的账本操作指令,合约代码的执行过程实质上是向账本输出一串操作指令序列,这些指令对账本中的数据产生了变更,形成合约执行的最终结果。 + +合约开发框架定义了进行合约代码开发中需要依赖的一组编程接口和类库。合约开发插件提供了更方便与IDE集成的合约编译、部署工具,可以简化操作,并与持续集成过程结合。 + +JD Chain 以 Java 语言作为合约代码语言,合约引擎是基于 JVM 构建的安全沙盒。为了实现与主流的应用开发方式无缝兼容, JD Chain 支持以 Maven 来管理合约代码的工程项目,并提供相应的 maven 插件来简化合约的编译和部署。 + +>智能合约是一种可以由计算机执行的合同/协议。不同于现实生活中的合同是由自然语言来编写并约定相关方的权利和义务,智能合约是用合约代码语言来编写,以合约代码的形式存在和被执行。通过账本中的数据状态来表示合同/协议相关条款信息,合约代码的运行过程体现了合同/协议条款的执行,并记录相应的结果。 + +### 2. 快速入门 + +#### 2.1. 准备开发环境 + +按照正常的 Java 应用开发环境要求进行准备,以 Maven 作为代码工程的构建管理工具,无其它特殊要求。 + +>检查 JDK 版本不低于 1.8 ,Maven 版本不低于 3.0。 + +#### 2.2. 创建合约代码工程 +创建一个普通的 Java Maven 工程,打开 pom.xml 把 packaging 设为 contract . + +```xml + + 4.0.0 + your.group.id + your.project + 0.0.1-SNAPSHOT + + contract + + + + + + + + + + + +``` + +> 注:合约代码工程也是一个普通的 Java Maven 工程,因此尽管不同 IDE 创建 Maven 工程有不同的操作方式,由于对于合约开发而言并无特殊要求,故在此不做详述。 + +#### 2.3. 加入合约开发依赖 + +在合约代码工程 pom.xml 加入对合约开发 SDK 的依赖: + + ```xml + + com.jd.blockchain + contract-starter + ${jdchain.version} + + ``` + +#### 2.4. 加入合约插件 + +在合约代码工程的 pom.xml 加入 contract-maven-plugin 插件: + ```xml + + com.jd.blockchain + contract-maven-plugin + ${jdchain.version} + true + + ``` + +完整的 pom.xml 如下: + + ```xml + + 4.0.0 + your.group.id + your.project + 0.0.1-SNAPSHOT + + contract + + + 1.4.2.RELEASE + + + + + + com.jd.blockchain + contract-starter + ${jdchain.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + UTF-8 + false + true + false + false + + + + + + com.jd.blockchain + contract-maven-plugin + ${jdchain.version} + true + + + + + ``` + +#### 2.5. 编写合约代码 + +2.5.1. **注意事项** + +1. 不允许合约(包括合约接口和合约实现类)使用com.jd.blockchain开头的package; +2. 必须有且只有一个接口使用@Contract注解,且其中的event必须大于等于一个; +3. 使用@Contract注解的接口有且只有一个实现类; +4. 黑名单调用限制(具体黑名单可查看配置文件),需要注意的是,黑名单分析策略会递归分析类实现的接口和父类,也就是说调用一个实现了指定黑名单接口的类也是不允许的; + + +目前设置的黑名单如下: +```conf +java.io.File +java.io.InputStream +java.io.OutputStream +java.io.DataInput +java.io.DataOutput +java.io.Reader +java.io.Writer +java.io.Flushable +java.nio.channels.* +java.nio.file.* +java.net.* +java.sql.* +java.lang.reflect.* +java.lang.Class +java.lang.ClassLoader +java.util.Random +java.lang.System-currentTimeMillis +java.lang.System-nanoTime +com.jd.blockchain.ledger.BlockchainKeyGenerator +``` + +2.5.2. **声明合约** + +```java +/** + * 声明合约接口; +**/ +@Contract +public interface AssetContract { + + @ContractEvent(name = "transfer") + String transfer(String address, String from, String to, long amount); + +} +``` + +2.5.3. **实现合约** + +```java +/** + * 实现合约; + * + * 实现 EventProcessingAware 接口是可选的,目的获得 ContractEventContext 上下文对象, + * 通过该对象可以进行账本操作; + */ +public class AssetContractImpl implements AssetContract, EventProcessingAware { + + // 合约事件上下文; + private ContractEventContext eventContext; + + /** + * 执行交易请求中对 AssetContract 合约的 transfer 调用操作; + */ + public String transfer(String address, String from, String to, long amount) { + //当前账本的哈希; + HashDigest ledgerHash = eventContext.getCurrentLedgerHash(); + //当前账本上下文; + LedgerContext ledgerContext = eventContext.getLedger(); + + //做操作; + // ledgerContext. + + //返回合约操作的结果; + return "success"; + } + + /** + * 准备执行交易中的合约调用操作; + */ + @Override + public void beforeEvent(ContractEventContext eventContext) { + this.eventContext = eventContext; + } + + /** + * 完成执行交易中的合约调用操作; + */ + @Override + public void postEvent(ContractEventContext eventContext, Exception error) { + this.eventContext = null; + } +} +``` + +**账本数据可见范围**: + +`ContractEventContext`中`getUncommittedLedger`方法可访问执行中的未提交区块数据,此方法的合理使用可以解决客户并发调用合约方法涉及数据版本/事件序列冲突的问题。 +```java +/** + * 当前包含未提交区块数据账本查询上下文; + */ +LedgerQueryService getUncommittedLedger(); +``` + +`ContractEventContext`中`getLedger`方法访问的是链上已提交的最新区块数据,不包含未提交交易,所以存在未提交交易中多个合约方法调用操作间数据不可见,导致并发时数据版本等冲突问题。 +```java +/** + * 账本操作上下文; + */ +LedgerContext getLedger(); +``` + +合约方法中对账本的操作通过调用`LedgerContext`中相关方法,可参照[示例合约](https://github.com/blockchain-jd-com/jdchain/tree/master/samples/contract-samples/src/main/java/com/jdchain/samples/contract) + +#### 2.6. 编译打包合约代码 + +合约代码工程的编译打包操作与普通的 maven 工程是相同的,在工程的根目录下输入以下命令: + +```bash +mvn clean package +``` + +执行成功之后,在 target 目录中输出合约代码文件 \.\.car 。 + +如果合约代码加入了除 com.jd.blockchain:contract-starter 之外的其它依赖,默认配置下,第三方依赖包将与 .car 文件一起打包一起部署。(也可以把第三方依赖包独立打包,具体参见以下 “3. 合约插件详细配置” + +> 注意:合约代码虽然利用了 Java 语言,遵照 Java 语法进行编写,但本质上是作为一种运行于受限环境(合约虚拟机)的语言来使用,因而一些 Java 语法和 SDK 的 API 是不被允许使用的,在编译过程中将对此进行检查。 + +#### 2.7. 部署合约代码 + +##### 2.7.1. 在项目中部署合约代码 + +如果希望在构建打包的同时将合约代码部署到指定的区块链网络,可以在合约代码工程 pom.xml 的 contract-maven-plugin 插件配置中加入合约部署相关的信息(具体更详细的配置可以参考“3. 合约插件详细配置”)。 + +```xml + + com.jd.blockchain + contract-maven-plugin + 1.2.0.RELEASE + true + + + + + j5rpuGWVxSuUbU3gK7MDREfui797AjfdHzvAMiSaSzydu7 + + + + 192.168.10.10 + 8081 + + + + + 7VeRMpXVeTY4cqPogUHeNoZNk86CGAejBh9Xbd5ndFZXNFj3 + + + + + 7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq + 177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x + DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY + + + + +``` + +加入部署配置信息之后,对工程执行编译打包操作,输出的合约代码(.car)将自动部署到指定的区块链网络。 + +```bash +mvn clean deploy +``` +##### 2.7.2. 发布已编译好的car +如果已经通过插件的打包方式,编译打包完成一个合约文件(.car),可通过命令行的方式进行发布,命令行要求与开发环境一致的Maven环境(包括环境变量及Setting都已配置完成)。 + +```bash +mvn com.jd.blockchain:contract-maven-plugin:${version}:deploy + -DcarPath= + -Dledger= + -DgatewayHost= + -DgatewayPort= + -DcontractPubKey= + -DcontractAddress= + -DsignerPubKey= + -DsignerPrivKey= + -DsignerPrivKeyPwd= +``` + +各参数说明如下: + +| 参数名 | 含义 |是否必填| +| ---- | ---- | ---- | +| ${version} | 合约插件的版本号 | 否,系统会自动选择发布的最新的RELEASE版本,SNAPSHOT版本必须填写 | +| carPath | 合约文件所在路径 | 是 | +| ledger | 账本Hash(Base58编码) | 否,会自动选择线上第一个账本| +| gatewayHost | 可访问的网关节点地址,域名或IP地址 | 是| +| gatewayPort | 网关节点监听端口 | 是 | +| contractPubKey | 合约账户的公钥(Base58编码)| 否,会自动创建 | +| contractAddress | 合约账户的地址(Base58编码)|否,会根据contractPubKey生成| +| signerPubKey | 合约签名公钥信息(Base58编码)|是| +| signerPrivKey | 合约签名私钥信息(Base58编码)|是| +| signerPrivKeyPwd | 合约签名私钥解密密钥(Base58编码)|是| + + +下面是一个示例,供参考: + +```bash +mvn com.jd.blockchain:contract-maven-plugin:1.2.0.RELEASE:deploy \ + -DcarPath=/root/jdchain/contracts/contract-test-1.0-SNAPSHOT.car \ + -Dledger=j5tW5HUvMjEtm2yB7E6MHoSByoH1DXvMwvF2HurEgMSaLW \ + -DgatewayHost=127.0.0.1 \ + -DgatewayPort=11000 \ + -DcontractPubKey= 7VeRBsHM2nsGwP8b2ufRxz36hhNtSqjKTquzoa4WVKWty5sD \ + -DcontractAddress= LdeNt7sEmTirh9PmE7axKvA2txTrbB9kxz6KB \ + -DsignerPubKey=7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq \ + -DsignerPrivKey=177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x \ + -DsignerPrivKeyPwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY +``` + +> 重点说明: +命令行中输入参数的优先级高于配置文件,就是说通过2.7.1方式发布合约时也可以采用命令行的参数(指-D相关配置),其优先级高于配置文件。 + +### 3. 合约插件详细配置 + +```xml + + com.jd.blockchain + contract-maven-plugin + 1.2.0.RELEASE + true + + + + + + false + + + + + 1 + + + MB + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + +
+
+
+``` + +### 4. 最简化合约插件配置示例 + +在pom.xml中有部分配置是非必填项,下面是一份最简化的合约发布(deploy)配置示例,供参考: + + +```xml + + com.jd.blockchain + contract-maven-plugin + 1.2.0.RELEASE + true + + + + + + 127.0.0.1 + 8081 + + + + + 7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq + 177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x + DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY + + + + +``` + +### 5. 合约SDK + +除上述使用 maven 命令方式部署合约外,JD Chain SDK 提供了 Java 和 Go 语言的合约部署/升级,合约调用等方法。 +以下以 Java SDK 为例讲述主要步骤,完整代码参照[JD Chain Samples](https://github.com/blockchain-jd-com/jdchain/tree/master/samples)合约部分。 + +#### 5.1 合约部署 + +```java +// 新建交易 +TransactionTemplate txTemp = blockchainService.newTransaction(ledger); +// 生成合约账户 +BlockchainKeypair contractAccount = BlockchainKeyGenerator.getInstance().generate(); +System.out.println("合约地址:" + contractAccount.getAddress()); +// 部署合约 +txTemp.contracts().deploy(contractAccount.getIdentity(), FileUtils.readBytes("src/main/resources/contract-samples-1.4.2.RELEASE.car")); +``` + +#### 5.2 合约升级 + +```java +// 新建交易 +TransactionTemplate txTemp = blockchainService.newTransaction(ledger); +// 解析合约身份信息 +BlockchainIdentity contractIdentity = new BlockchainIdentityData(KeyGenUtils.decodePubKey("7VeRCfSaoBW3uRuvTqVb26PYTNwvQ1iZ5HBY92YKpEVN7Qht")); +System.out.println("合约地址:" + contractIdentity.getAddress()); +// 指定合约地址,升级合约,如合约地址不存在会创建该合约账户 +txTemp.contracts().deploy(contractIdentity, FileUtils.readBytes("src/main/resources/contract-samples-1.4.2.RELEASE.car")); +``` + +#### 5.3 合约调用 + +5.3.1 动态代理方式 + +基于动态代理方式合约调用,需要依赖合约接口 + +```java +// 新建交易 +TransactionTemplate txTemp = blockchainService.newTransaction(ledger); + +// 一次交易中可调用多个(多次调用)合约方法 +// 调用合约的 registerUser 方法 +SampleContract sampleContract = txTemp.contract("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye", SampleContract.class); +GenericValueHolder userAddress = ContractReturnValue.decode(sampleContract.registerUser(UUID.randomUUID().toString())); + +// 准备交易 +PreparedTransaction ptx = txTemp.prepare(); +// 交易签名 +ptx.sign(adminKey); +// 提交交易 +TransactionResponse response = ptx.commit(); +Assert.assertTrue(response.isSuccess()); + +// 获取返回值 +System.out.println(userAddress.get()); +``` + +5.3.2 非动态代理方式 + +不需要依赖合约接口及实现,传入参数构造合约调用操作 + +```java +// 新建交易 +TransactionTemplate txTemp = blockchainService.newTransaction(ledger); + +ContractEventSendOperationBuilder builder = txTemp.contract(); + +// 一次交易中可调用多个(多次调用)合约方法 +// 调用合约的 registerUser 方法,传入合约地址,合约方法名,合约方法参数列表 +builder.send("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye", "registerUser", + new BytesDataList(new TypedValue[]{ + TypedValue.fromText(UUID.randomUUID().toString()) + }) +); +// 准备交易 +PreparedTransaction ptx = txTemp.prepare(); +// 交易签名 +ptx.sign(adminKey); +// 提交交易 +TransactionResponse response = ptx.commit(); +Assert.assertTrue(response.isSuccess()); + +Assert.assertEquals(1, response.getOperationResults().length); +// 解析合约方法调用返回值 +for (int i = 0; i < response.getOperationResults().length; i++) { + BytesValue content = response.getOperationResults()[i].getResult(); + switch (content.getType()) { + case TEXT: + System.out.println(content.getBytes().toUTF8String()); + break; + case INT64: + System.out.println(BytesUtils.toLong(content.getBytes().toBytes())); + break; + case BOOLEAN: + System.out.println(BytesUtils.toBoolean(content.getBytes().toBytes()[0])); + break; + default: // byte[], Bytes + System.out.println(content.getBytes().toBase58()); + break; + } +} +``` \ No newline at end of file diff --git a/docs/data_account.md b/docs/data_account.md new file mode 100644 index 00000000..b27366cd --- /dev/null +++ b/docs/data_account.md @@ -0,0 +1,63 @@ +## 数据账户 + +`JD Chain`存放`KV`数据的数据结构。 + +### 1. 基本概念 + +可类比传统数据库的表的概念,上层应用需要保存的应用数据最终都应表现为`KV`类型数据写入到数据账户中。 + +写入`KV`数据之前,需要创建或使用已存在数据账户。 + +一个账本可以创建无限多个数据账户,一个数据账户中可以写入无限多个`KV`数据。 + +`KV`数据有`Version`(数据版本)的概念,以`KEY`作为唯一标识,`VALUE`的更新写入需要提供当前该`KEY`的最高版本,`KEY`不存在时为`-1`。 + +### 2. SDK + +以下只描述主要步骤,完整示例代码可参照[JD Chain Samples](samples.md)数据账户部分。 + +#### 2.1 注册数据账户 + +创建数据账户: +```java +BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate(); +System.out.println("数据账户地址:" + dataAccount.getAddress()); +// 注册数据账户 +txTemp.dataAccounts().register(dataAccount.getIdentity()); +``` + +从已存在数据账户公钥恢复: +```java +PubKey pubKey = KeyGenUtils.decodePubKey("7VeRLdGtSz1Y91gjLTqEdnkotzUfaAqdap3xw6fQ1yKHkvVq"); +BlockchainIdentity dataAccountIdentity = new BlockchainIdentityData(pubKey); +System.out.println("数据账户地址:" + dataAccountIdentity.getAddress()); +// 注册数据账户 +txTemp.dataAccounts().register(dataAccountIdentity); +``` + +#### 2.2 写入数据 + +```java +TransactionTemplate txTemp = blockchainService.newTransaction(ledger); + +txTemp.dataAccount("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye") + .setText("key1", "value1", -1) + .setText("key1", "value1", 0) + .setInt64("key2", 1, -1) + .setJSON("key3", "{}", -1) + .setBytes("key4", Bytes.fromInt(2), -1); +``` + +支持写入数据类型: + +- `setText`,字符类型 +- `setInt64`,长整型 +- `setJSON`,`JSON`串 +- `setBytes`,字节数组 +- `setTimestamp`,时间戳,长整型 +- `setXML`,`XML`文本 +- `setImage`,图片字节数据 + +> 本质上仅支持`String/Long/[]byte`这三种数据类型,`JSON/XML/Image/Timestamp`等起标识作用,用于扩展差异化数据展示等场景需求 + +`setText("key1", "value1", -1)`中第三个参数即为数据版本,需要传入`JD Chain`网络中当前`key1`的最高数据版本,首次写入时传入`-1`。 \ No newline at end of file diff --git a/docs/event.md b/docs/event.md new file mode 100644 index 00000000..a753f7f5 --- /dev/null +++ b/docs/event.md @@ -0,0 +1,185 @@ +## 事件 + +`JD Chain`账本中设计了事件数据集,用以存储事件账户,事件数据。 + +`事件账户`与`用户`,`数据账户`,`合约账户`是相互独立的,所承载的数据也是相互隔离的。 + +`JD Chain`事件分为两类:[系统事件](#系统事件),[用户事件](#用户事件) + +`JD Chain SDK` 针对事件数据集开发了[事件发布](#事件发布),[事件监听](#事件监听)实现。 + +### 1. 系统事件 + +系统运行期间产生的事件,目前仅定义了`新区块产生`这一个: + +```java +/** + * 系统事件类型 + */ +public enum SystemEvent { + // 新区块 + NEW_BLOCK_CREATED("new_block_created"); +} +``` + +### 2. 用户事件 + +用户自定义事件类型,需要创建`事件账户`,用户自定义事件名 + +`事件账户`数量没有限制,一个事件账户内`Topic`(事件名)数量没有限制 + +同一个`事件账户`的同一个`Topic`所指向的`Content`(事件内容)有`Sequence`(事件序号)的概念,以`Topic`作为唯一标识,同一个`Topic`的更新发布需要提供当前该`Topic`的最高序号,`Topic`不存在时为`-1`。 + +### 3. 事件结构 + +```java +/** + * 事件; + * + */ +@DataContract(code = DataCodes.EVENT_MESSAGE) +public interface Event { + /** + * 事件名; + * + * @return + */ + @DataField(order = 1, primitiveType = PrimitiveType.TEXT) + String getName(); + + /** + * 事件序号; + * + * @return + */ + @DataField(order = 2, primitiveType = PrimitiveType.INT64) + long getSequence(); + + /** + * 事件内容; + * + * @return + */ + @DataField(order=3, refContract = true) + BytesValue getContent(); + + /** + * 产生事件的交易哈希;  + * + * @return + */ + @DataField(order = 4, primitiveType = PrimitiveType.BYTES) + HashDigest getTransactionSource(); + + /** + * 产生事件的合约地址; + * + * @return + */ + @DataField(order = 5, primitiveType = PrimitiveType.TEXT) + String getContractSource(); + + /** + * 产生事件的区块高度 + * + * @return + */ + @DataField(order = 6, primitiveType = PrimitiveType.INT64) + long getBlockHeight(); + + /** + * 事件账户地址,系统事件此字段为空 + * + * @return + */ + @DataField(order = 7, primitiveType = PrimitiveType.BYTES) + Bytes getEventAccount(); +} +``` + +### 4. SDK + +`JD Chain`事件监听是`SDK`端以`拉`的方式实现,消息可重复消费,需要使用者自行保存消费位置。 + +以下只描述主要步骤,完整示例代码可参照[JD Chain Samples](samples.md)事件相关部分。 + +#### 4.1 生成事件账户 + +> 用户事件才有事件账户 + +```java +// 新建交易 +TransactionTemplate txTemp = blockchainService.newTransaction(ledger); +// 生成事件账户 +BlockchainKeypair eventAccount = BlockchainKeyGenerator.getInstance().generate(); +System.out.println("事件账户地址:" + eventAccount.getAddress()); +// 注册事件账户 +txTemp.eventAccounts().register(eventAccount.getIdentity()); +``` + +#### 4.2 事件发布 + +> 系统事件由系统运行期间自动产生,用户事件可通过SDK发布 + +```java +// 新建交易 +TransactionTemplate txTemp = blockchainService.newTransaction(ledger); + +txTemp.eventAccount(Bytes.fromBase58("LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye")) + .publish("topic1", "content1", -1) + .publish("topic1", "content2", 0) + .publish("topic1", "content3", 1) + .publish("topic2", "content", -1) + .publish("topic3", 1, -1) + .publish("topic4", Bytes.fromInt(1), -1); +``` + +支持发布数据类型: + +- `Text`,字符类型 +- `Int64`,长整型 +- `JSON`,`JSON`串 +- `Bytes`,字节数组 +- `Timestamp`,时间戳,长整型 +- `XML`,`XML`文本 +- `Image`,图片字节数据 + +> 本质上仅支持`String/Long/[]byte`这三种数据类型,`JSON/XML/Image/Timestamp`等起标识作用,用于扩展差异化数据展示等场景需求 + +`publish("topic1", "content1", -1)`中第三个参数即为事件序号,需要传入`JD Chain`网络中当前`topic1`的最高序号,首次写入时传入`-1`。 + +#### 4.3 事件监听 + +- 监听系统事件 +```java +// 目前仅有新区快产生事件 +blockchainService.monitorSystemEvent(ledger, + SystemEvent.NEW_BLOCK_CREATED, 0, (eventMessages, eventContext) -> { + for (Event eventMessage : eventMessages) { + // content中存放的是当前链上最新高度 + System.out.println("New block:" + eventMessage.getSequence() + ":" + BytesUtils.toLong(eventMessage.getContent().getBytes().toBytes())); + } + }); +``` + +- 监听用户事件: +```java +blockchainService.monitorUserEvent(ledger, "LdeNr7H1CUbqe3kWjwPwiqHcmd86zEQz2VRye", "sample-event", 0, (eventMessage, eventContext) -> { + + BytesValue content = eventMessage.getContent(); + switch (content.getType()) { + case TEXT: + case XML: + case JSON: + System.out.println(eventMessage.getName() + ":" + eventMessage.getSequence() + ":" + content.getBytes().toUTF8String()); + break; + case INT64: + case TIMESTAMP: + System.out.println(eventMessage.getName() + ":" + eventMessage.getSequence() + ":" + BytesUtils.toLong(content.getBytes().toBytes())); + break; + default: // byte[], Bytes + System.out.println(eventMessage.getName() + ":" + eventMessage.getSequence() + ":" + new String(content.getBytes().toBytes())); + break; + } +}); +``` \ No newline at end of file diff --git a/docs/gateway.md b/docs/gateway.md new file mode 100644 index 00000000..10574bc4 --- /dev/null +++ b/docs/gateway.md @@ -0,0 +1,53 @@ +## 网关服务 + +`JD Chain`的网关服务是应用的接入层。 +终端接入是`JD Chain`网关的基本功能,在确认终端身份的同时提供连接节点、转发消息和隔离共识节点与客户端等服务。网关确认客户端的合法身份,接收并验证交易;网关根据初始配置文件与对应的共识节点建立连接,并转发交易数据。 + +### 1. 配置 + +网关配置在文件`gateway.conf`中: + +```properties +#网关的HTTP服务地址; +http.host=0.0.0.0 +#网关的HTTP服务端口; +http.port=8080 +#网关的HTTP服务上下文路径,可选; +#http.context-path= + +#共识节点的服务地址(与该网关节点连接的Peer节点的IP地址); +peer.host=127.0.0.1 +#共识节点的服务端口(与该网关节点连接的Peer节点的端口,即在Peer节点的peer-startup.sh中定义的端口); +peer.port=7080 +#共识节点的服务是否启用安全证书; +peer.secure=false + +#是否存储共识拓扑信息,网关重启后若存储存在有效的拓扑信息可快速建立与拓扑中所有节点的连接 +topology.store=false + +#共识节点的服务提供解析器 +#BftSmart共识Provider:com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider +#简单消息共识Provider:com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider +peer.providers=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider + +#数据检索服务对应URL,格式:http://{ip}:{port},例如:http://127.0.0.1:10001 +#若该值不配置或配置不正确,则浏览器模糊查询部分无法正常显示 +data.retrieval.url= +schema.retrieval.url= + +#默认公钥的内容(Base58编码数据); +keys.default.pubkey= +#默认私钥的路径;在 pk-path 和 pk 之间必须设置其一; +keys.default.privkey-path= +#默认私钥的内容(加密的Base58编码数据);在 pk-path 和 pk 之间必须设置其一; +keys.default.privkey= +#默认私钥的解码密码; +keys.default.privkey-password= + +``` + +其中: + +- `data.retrieval.url`与`schema.retrieval.url`分别与[Argus(高级检索)](https://github.com/blockchain-jd-com/jdchain-indexer)中的[区块链基础数据检索服务](https://github.com/blockchain-jd-com/jdchain-indexer#%E5%90%AF%E5%8A%A8%E5%8C%BA%E5%9D%97%E9%93%BE%E5%9F%BA%E7%A1%80%E6%95%B0%E6%8D%AE%E7%B4%A2%E5%BC%95%E6%A3%80%E7%B4%A2%E6%9C%8D%E5%8A%A1)和[`Schema`服务](https://github.com/blockchain-jd-com/jdchain-indexer#%E5%90%AF%E5%8A%A8value%E7%B4%A2%E5%BC%95%E6%9C%8D%E5%8A%A1)相对应,只有启动并正确配置了`Argus`,`JD Chain`浏览器才能正常使用搜索功能。 + +- `keys.default`几个参数代表接入`JD Chain`网络的身份信息,只有处于非停用(`DEACTIVATED`)状态的参与方身份才可作为此处的配置。 \ No newline at end of file diff --git a/docs/images/deployment.jpg b/docs/images/deployment.jpg deleted file mode 100644 index aec66f03d653931de983a14f49dc902983121449..0000000000000000000000000000000000000000 GIT binary patch literal 0 KcmV+b0RR6000031 literal 131011 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 z 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 diff --git a/docs/images/deployment.png b/docs/images/deployment.png deleted file mode 100644 index a0b2e722c2060d15a6bfd3fe01ca94f306487112..0000000000000000000000000000000000000000 GIT binary patch literal 0 KcmV+b0RR6000031 literal 298018 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

YNga86v6_6P}&X(Cf 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

+ * 未提交的`batch`对其他客户端连接不可见。 + * + * @return + * @throws KVDBException + */ +boolean batchCommit() throws KVDBException; + +/** + * 提交批处理 + * + * @param size 此次批处理操作去重后的key数量 + * @return + * @throws KVDBException + */ +boolean batchCommit(long size) throws KVDBException; + +/** + * 关闭 + */ +void close(); +``` + +### 5.管理工具 + +`kvdb-cli`是基于[`SDK`](#SDK)的命令行工具实现: + +```bash +./kvdb-cli.sh -h -p -db -t

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%0AkuXt43-Yu69+&HL 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 z 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] [COMMAND] +JDChain Cli is a convenient tool to manage jdchain keys, sign and send +transactions to jdchain network, query data from jdchain network. + -h, --help Show this help message and exit. + --home= Set the home directory. + --pretty Pretty json print + -V, --version Print version information and exit. + +Commands: + +The most commonly used git commands are: + keys List, create, update or delete keypairs. + tx Build, sign or send transaction. + query Query commands. + participant Add, update or delete participant. + help Displays help information about the specified command + +See 'jdchain-cli help ' to read about a specific subcommand or concept. +``` + +- `keys` [密钥管理](cli/keys.md) +- `tx` [交易](cli/tx.md) +- `query` [链上信息查询](cli/query.md) +- `participant` [共识节点变更](cli/participant.md) \ No newline at end of file diff --git a/docs/kvdb.md b/docs/kvdb.md new file mode 100644 index 00000000..4774f20a --- /dev/null +++ b/docs/kvdb.md @@ -0,0 +1,365 @@ +## RocksDB as a server + +### 1.简介 + +`KVDB`是一个简单的`NoSQL`数据库,支持简单的“键值”读写操作。 + +`KVDB`包装了`RocksDB`作为数据库引擎,实现了单机部署和集群部署。 + +`KVDB`的集群是一个分布式的分片服务集群,每个分片节点是一个`KVDB`的数据库服务实例,采用对等模式部署,没有主节点。 + +### 2.安装 + +> java 版本>= 1.8 + +下载源代码,执行: +```bash +mvn clean package +``` +`kvdb-server`模块`target`下会生成`kvdb-***.zip`,解压缩安装包,结构如下: +```bash +bin # 脚本文件目录 + start # 启动本机的数据库服务的脚本文件 + stop # 停止本机的数据库服务的脚本文件 + kvdb-cli # 连接本机的数据库服务控制台的脚本文件 + kvdb-benchmark # 基准测试 +conf # 配置文件目录 + kvdb.conf # 本机的数据库服务配置 + cluster.conf # 数据库集群的配置 +libs # 数据库服务的代码库目录 +system # 系统数据目录 + dblist # 文件记录了本数据库服务实例装载的数据库列表 + pid # 文件记录了本数据库服务实例的运行进程ID;当服务实例运行时创建,服务实例退出后删除 +``` + +### 3.部署配置 + +#### 3.1 `kvdb.conf` + +```bash +# 数据库服务的本机监听地址; +server.host=0.0.0.0 + +# 数据库服务的本机监听端口; +server.port=7078 + +# 管理控制台的端口; +# 注:管理控制台总是绑定到环回地址 127.0.0.1,只允许本机访问; +manager.port=7060 + +# 数据库实例默认的根目录 +dbs.rootdir=/usr/kvdb/dbs + +# 数据库实例默认的本地分区数 +dbs.partitions=4 + +# 是否禁用WAL +wal.disable=false + +# WAL刷新机制,-1跟随系统,0实时刷新,n(n>0)秒刷新一次 +wal.flush=1 +``` + +> `WAL`写入成功,但`RocksDB`写入失败,服务器将在后续所有数据库读写操作前根据`WAL`进行重试操作,直至成功。 + +#### 3.2 `cluster.conf` +```bash +# 数据库集群的分片数,每一个分片都赋予唯一的编号,分片编号最小为 0,所有分片的编号必须连续递增 +# ‘’表示集群名称,只允许用字母、数字、下划线组成; +cluster..partitions=3 + +# 数据库集群 ‘’ 的第 1 个分片的数据库实例地址(URL格式); +cluster..0=kvdb://:/ + +# 数据库集群 ‘’ 的第 2 个分片的数据库实例地址(URL格式); +cluster..1=kvdb://:/ + +# 数据库集群 ‘’ 的第 3 个分片的数据库实例地址(URL格式); +cluster..2=kvdb://:/ + +# 指定多个不同的集群 +#cluster..partitions=3 +... +``` +> 一个数据库实例只能加入唯一的集群;一旦加入集群,则不能再被客户端以单库连接方式访问,对该库实例的连接自动转为集群连接。集群中配置的数据库必须在`dblist`中已存在且设置为`true` +> 所有`host`使用明确的可通畅连接的地址,不同服务器节点中同一集群配置必须完全一致 + +#### 3.3 `dblist` +```bash +# 是否激活数据库 ‘’ ;如果为`true`,则创建或加载该数据库并提供访问; +# ‘’表示数据库名称,只允许用字母、数字、下划线组成; +# db..enable=true + +# 数据库 的根目录;如果未配置,则从默认目录加载(由`conf/kvdb.conf`指定了默认配置${dbs.rootdir}/); +# db.test.rootdir= + +# 数据库 的本地分区数;如果未配置,则采用`conf/kvdb.conf`中指定的默认配置${dbs.partitions} +# db.test.partitions= +``` +> `dblist`中配置的数据库会在`kvdb-server`启动时自动创建。在`kvdb-server`启动完成后由管理工具执行`create database `创建数据库,创建成功的数据库会追加到`dblist`中。使用`kvdb-cli`命令行工具执行数据库实例更新操作。 + +#### 3.4 日志 + +1. `kvdb-server` + +修改`bin`目录下,`start.sh`文件: +```bash +LOG_SET="-Dlogging.path="$HOME/logs" -Dlogging.level=ERROR" +``` +默认日志路径:程序解压缩后主目录下`logs`目录 +默认日志等级:`ERROR` + +可配置日志等级:`ALL`,`TRACE`,`DEBUG`,`INFO`,`WARN`,`ERROR`,`FATAL`,`OFF` + +2. `kvdb-cli` + +修改`bin`目录下,`kvdb-cli.sh`文件: +```bash +LOG_SET="-Dlogging.path="$HOME/logs" -Dlogging.level.root=error" +``` +默认日志路径:程序解压缩后主目录下`logs`目录 +默认日志等级:`error` + +#### 3.5 启动 + +```bash +./start.sh +``` +#### 停止 +```bash +./stop.sh +``` + +### 4.SDK + +1. 依赖 +```maven + + com.jd.blockchain + kvdb-client + ${project.version} + +``` + +2. 创建客户端连接 +```java +// `host`、`port`为服务器地址和端口,`database`为数据库名称 +KVDBClient client = new KVDBClient("kvdb://:/"); +# KVDBClient client = new KVDBClient(new KVDBURI("kvdb://:/")); +# KVDBClient client = new KVDBClient(new ClientConfig(host, port, db)); +``` + +> 对于集群的连接,客户端将开启`WAL`,在`WAL`写入成功,部分服务器失败的情况下,客户端在执行后续所有操作前都将根据`WAL`日志执行重试操作,直至成功。 + +3. 操作 + +```java +/** + * 存在性查询 + * + * @param key + * @return + * @throws KVDBException + */ +boolean exists(Bytes key) throws KVDBException; + +/** + * 存在性查询,支持多个键值 + * + * @param keys + * @return + * @throws KVDBException + */ +boolean[] exists(Bytes... keys) throws KVDBException; + +/** + * 键值获取 + * + * @param key + * @return + * @throws KVDBException + */ +Bytes get(Bytes key) throws KVDBException; + +/** + * 键值获取,支持多个键值 + * + * @param keys + * @return + * @throws KVDBException + */ +Bytes[] get(Bytes... keys) throws KVDBException; + +/** + * 设置键值对 + * + * @param key + * @param value + * @return + * @throws KVDBException + */ +boolean put(Bytes key, Bytes value) throws KVDBException; + +/** + * 设置键值对 + * + * @param key + * @param value + * @param aSync + * @return + * @throws KVDBException + */ +boolean put(Bytes key, Bytes value, boolean aSync) throws KVDBException; + +/** + * 开启批处理 + * + * @return + * @throws KVDBException + */ +boolean batchBegin() throws KVDBException; + +/** + * 取消批处理 + * + * @return + * @throws KVDBException + */ +boolean batchAbort() throws KVDBException; + +/** + * 提交批处理,服务器掉线重连后会丢失未提交批处理数据 + *