VerifiableDB合约使用

使用文档请参考使用文档

开发文档,暨存储引擎的源码编译和测试文档,请参考开发文档

技术文档请参考技术文档

项目代码地址:https://git.chainmaker.org.cn/ibpc/verifiable-database

环境要求

  • 长安链v2.3.1

  • 链下数据库v1.1.0(MySQL v5.7.30)

  • 配套合约v1.1.0

  • docker

  • 7zip

调用流程

  1. 链下数据库定期通过update_offchain_status进行文件的备份并上传根哈希到合约中,用户可以通过get_hash_by_time_table进行查询

  2. 用户通过调用search_from_offchain发起一次查询,触发BeginSearch事件

  3. 链下数据库监听到BeginSearch事件,开始进行查询

  4. 查询完毕后链下数据库上传查询结果、范围证明和默克尔证明,并更新查询事件元信息,触发EndSearch事件

  5. 链上完成查询结果、范围证明和默克尔证明的检验

  6. 用户可以通过get_status_and_result随时获得查询目前的状态,查询成功后可获得查询结果

合约结构

函数结构

│  update_offchain_status              # 上传指定时间和表名的根哈希
│  get_hash_by_time_table              # 从表名和时间查询根哈希是否上传
│  search_from_offchain                # 从链上发起查询事件
│  upload_from_offchain                # 从链下上传查询状态和元信息
│  update_range_proof                  # 上传range proof
│  update_merkle_proof                 # 上传merkle proof
│  update_result                       # 上传查询结果
│  result_and_range_proof_check        # 进行查询结果和range proof的检查
│  merkle_proof_check                  # 进行merkle proof的检查
│  get_status_and_result               # 根据查询号获取查询结果与状态

存储数据结构

TTHash

│  Time                                # 指定时间
│  Table                               # 指定表名
│  Hash                                # 对应的根哈希

Proof

│  SearchId                            # 查询号
│  ProofId                             # 证明序号
│  Hash                                # 节点哈希
│  RawString                           # 节点的叶子结点数据

Result

│  SearchId                            # 查询号
│  ResultId                            # 证明序号
│  K                                   # 主键
│  SK                                  # 次键
│  Data                                # 结果数据
│  Valid                               # 是否满足约束(标识位)

SearchInfo

│  SearchId                            # 查询号
│  Time                                # 指定时间
│  Table                               # 指定表名
│  SK                                  # 主键下限
│  EK                                  # 主键上限
│  SSK                                 # 次键下限
│  SEK                                 # 次键上限
│  Status                              # 查询状态
│  Merkle                              # Merkle证明检验状态
│  ProofNum                            # 证明数量
│  ResultNum                           # 查询结果数量
│  ProofLayer                          # 证明层数
│  LeftKey                             # 查询第一条前一条主键值
│  LeftValue                           # 查询第一条前一条值
│  StartKey                            # 查询第一条主键值
│  StartValue                          # 查询第一条值
│  EndKey                              # 查询最后一条主键值
│  EndValue                            # 查询最后一条值
│  RightKey                            # 查询第一条最后一条主键值
│  RightValue                          # 查询第一条最后一条值

存储事件结构

new_status_update

│  Time                                # 指定时间
│  Table                               # 指定表名
│  Hash                                # 对应的根哈希

BeginSearch

│  SearchId                            # 查询号
│  Time                                # 指定时间
│  Table                               # 指定表名
│  SK                                  # 主键下限
│  EK                                  # 主键上限
│  SSK                                 # 次键下限
│  SEK                                 # 次键上限

EndSearch

│  SearchId                            # 查询号
│  Time                                # 指定时间
│  Table                               # 指定表名
│  SK                                  # 主键下限
│  EK                                  # 主键上限
│  SSK                                 # 次键下限
│  SEK                                 # 次键上限
│  Status                              # 查询状态
│  ResultNum                           # 查询结果数量
│  ProofLayer                          # 证明层数
│  LeftKey                             # 查询第一条前一条主键值
│  LeftValue                           # 查询第一条前一条值
│  StartKey                            # 查询第一条主键值
│  StartValue                          # 查询第一条值
│  EndKey                              # 查询最后一条主键值
│  EndValue                            # 查询最后一条值
│  RightKey                            # 查询第一条最后一条主键值
│  RightValue                          # 查询第一条最后一条值

UploadProof

│  SearchId                            # 查询号
│  ProofId                             # 证明序号
│  Hash                                # 节点哈希
│  RawString                           # 节点的叶子结点数据

UploadResult

│  SearchId                            # 查询号
│  ResultId                            # 证明序号
│  K                                   # 主键
│  SK                                  # 次键
│  Data                                # 结果数据

合约部署

启动一条支持DOCKER_VM的链

详见长安链v2.3.1官方教程

注:此工具兼容长安链版本v2.3.1

部署配套合约

编译合约

go build -ldflags="-s -w" -o VerifiableDB
7z a VerifiableDB VerifiableDB

将编译好的合约7z文件移动到chainmaker-go/tools/cmc/testdata/VerifiableDB目录下,返回cmc目录,运行以下命令

$ ./cmc client contract user create \
--contract-name=VerifiableDB \
--runtime-type=DOCKER_GO \
--byte-code-path=./testdata/VerifiableDB/VerifiableDB.7z \
--version=1.0 \
--sdk-conf-path=./testdata/sdk_config.yml \
--admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.key \
--admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.crt \
--sync-result=true \
--params="{}"

合约使用

用户需要用到的接口

et_hash_by_time_table

通过指定Time和Hash参数,查询是否有对应时间的指定表根哈希已上传到合约中 示例:

./cmc client contract user invoke \
--contract-name=VerifiableDB \
--method=get_hash_by_time_table \
--sdk-conf-path=./testdata/sdk_config.yml \
--params="{\"Time\":\"1\",\"Table\":\"test_tb\"}" \
--sync-result=true 

search_from_offchain

通过指定Time,Table,SK(主键起始值),EK(主键结束值),SSK(次键起始值,如果无则设为NULL),SEK(次键结束值,如果无则设为NULL)来发起一次查询。得到的返回值为本次查询的查询号。 示例:

./cmc client contract user invoke \
--contract-name=VerifiableDB \
--method=search_from_offchain \
--sdk-conf-path=./testdata/sdk_config.yml \
--params="{\"Time\":\"1\",\"Table\":\"test_tb\",\"SK\":\"18\",\"EK\":\"22\",\"SSK\":\"NULL\",\"SEK\":\"NULL\"}" \
--sync-result=true 

get_status_and_result

通过指定SearchId参数,来获取目前查询的状态,如果结果、merkleproof和rangeproof都检验成功则以事件的形式返回查询有效的结果 示例:

$ ./cmc client contract user invoke \
--contract-name=VerifiableDB \
--method=update_offchain_status \
--sdk-conf-path=./testdata/sdk_config.yml \
--params="{\"Time\":\"1\",\"Hash\":\"Hash\"}" \
--sync-result=true 

其他接口和功能

以下接口均由链下脚本直接调用

update_offchain_status

在每次用户备份后调用上传备份版本指定表的根哈希

upload_from_offchain

在查询完后上传查询结果和证明的元信息,

update_range_proof

update_merkle_proof

update_result

分别用于上传rangeproof,merkleproof和result

result_and_range_proof_check

在result和rangeproof上传完由脚本调用,进行检查

merkle_proof_check

在merkleproof上传完后由脚本调用,进行检查