# VerifiableDB合约使用 使用文档请参考[使用文档](./可验证数据库使用文档.md)。 开发文档,暨存储引擎的源码编译和测试文档,请参考[开发文档](./可验证数据库开发文档.md)。 技术文档请参考[技术文档](../tech/可验证数据库技术文档.md)。 项目代码地址:[https://git.chainmaker.org.cn/ibpc/verifiable-database](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[官方教程](https://docs.chainmaker.org.cn/v2.3.1/html/instructions/启动支持Docker_VM的链.html) > 注:此工具兼容长安链版本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上传完后由脚本调用,进行检查