10. 可验证数据库使用文档
10.1. 概述
链下可验证数据库是长安链可扩展性项目的一部分,主要通过Merkle B+树实现链下SQL数据存储和长安链的链上验证。链下可验证数据库是独立的存储引擎,支持MySQL生态工具。
本文档主要介绍链下可验证数据库及配套合约的部署和使用方式,便于用户快速上手使用。
开发文档,暨存储引擎的源码编译和测试文档,请参考开发文档。
配套的智能合约文档,请参考合约使用文档。
技术文档请参考技术文档。
项目代码地址:https://git.chainmaker.org.cn/ibpc/verifiable-database
10.2. 快速开始
10.2.1. 安装准备
安装长安链所需依赖:go, 7zip, docker
安装go 1.19.9
参考:https://golang.google.cn/doc/installwget https://golang.google.cn/dl/go1.19.9.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.19.9.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin go version
国内需配置Go代理
go env -w GO111MODULE=on go env -w GOPROXY=goproxy.cn
安装7zip
sudo yum -y install epel-release sudo yum -y install p7zip p7zip-plugins
安装docker
sudo yum -y install yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo systemctl start docker sudo docker run hello-world
安装长安链v2.3.1,参考官方文档
注:此工具兼容长安链版本v2.3.1
启动长安链Docker VM相关组件,参考官方文档
10.2.2. 安装方法
推荐使用Mysql插件模式安装和使用,也可直接通过mbt_store
独立模式使用,但独立模式不支持SQL语句。
安装Mysql
下载Mysql 5.7.30社区版
https://downloads.mysql.com/archives/community/
Product Version: 5.7.30
Operating System: Linux - Generic
OS Version: Linux - Generic (glibc 2.12) (x86, 64-bit)wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.30-linux-glibc2.12-x86_64.tar.gz tar zxvf mysql-5.7.30-linux-glibc2.12-x86_64.tar.gz sudo cp -r mysql-5.7.30-linux-glibc2.12-x86_64 /usr/local/mysql
安装Mysql依赖并创建用户
sudo yum install -y libaio sudo groupadd -g 315 mysql sudo useradd -u 315 -g mysql -d /var/lib/mysql -M mysql
修改
/etc/my.cnf
,参考:[mysqld] bind-address=0.0.0.0 port=3306 user=mysql basedir=/usr/local/mysql datadir=/data/mysql socket=/tmp/mysql.sock [mysqld_safe] log-error=/var/log/mysql/mysql.err pid-file=/var/log/mysql/mysql.pid # # include all files from the config directory # !includedir /etc/my.cnf.d
根据
/etc/my.cnf
创建必要目录和文件sudo mkdir /var/log/mysql sudo touch /var/log/mysql/mysql.err sudo touch /var/log/mysql/mysql.pid sudo chown -R mysql:mysql /var/log/mysql/ sudo mkdir -p /data/mysql sudo chown -R mysql:mysql /data/mysql/
复制本项目插件到Mysql插件目录并创建必要目录
sudo cp ha_mbtree.so /usr/local/mysql/lib/plugin sudo chmod 755 /usr/local/mysql/lib/plugin/ha_mbtree.so sudo mkdir -p /data/chainmaker_mbt/mbt_store_data/mbt_db_files sudo mkdir -p /data/chainmaker_mbt/merkle_proofs sudo mkdir -p /data/chainmaker_mbt/search_results sudo chown -R $USER:$(groups) /data/chainmaker_mbt/
在
/usr/local/mysql/bin/
目录启动Mysql并加载本项目插件sudo ./mysqld --initialize --user=mysql sudo ./mysqld_safe --user=mysql ./mysql -uroot -p mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; mysql> INSTALL PLUGIN mbtree SONAME 'ha_mbtree.so'; mysql> SHOW PLUGINS;
安装OpenSSL 1.1.1n
openssl的版本应为1.1.1n
手动安装(推荐)
wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1n.tar.gz tar -zxvf openssl-1.1.1n.tar.gz cd openssl-1.1.1n ./config --prefix=/usr/local/openssl ./config -t make & sudo make install sudo mv /usr/bin/openssl /usr/bin/openssl.bak sudo mv /usr/include/openssl /usr/include/openssl.bak sudo ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl sudo ln -s /usr/local/openssl/include/openssl /usr/include/openssl sudo echo "/usr/local/openssl/lib" >> /etc/ld.so.conf sudo ldconfig -v sudo ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/lib64/libssl.so.1.1 sudo ln -s /usr/local/openssl/lib/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1 sudo ln -sf /usr/local/openssl/lib/libssl.so.1.1 /usr/lib64/libssl.so sudo ln -sf /usr/local/openssl/lib/libcrypto.so.1.1 /usr/lib64/libcrypto.so openssl version
10.2.3. 使用方法
本部分演示使用SQL语句纯链下插入查询数据和使用智能合约链上链下协同插入查询数据两种方式。
使用SQL语句插入和查询数据
mysql> CREATE DATABASE IF NOT EXISTS test_db; mysql> USE test_db; mysql> CREATE TABLE IF NOT EXISTS test_tb (id INT not null, num INT not null, PRIMARY KEY ( id ) ) ENGINE=MBTREE; mysql> INSERT INTO test_tb (id, num) VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6,6), (7, 7), (8,8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15), (16, 16), (17, 17), (18, 18), (19, 19), (20, 20); mysql> SELECT id,num FROM test_tb WHERE id >=18 and id <= 22;
部署长安链智能合约
创建
chainmaker-go/tools/cmc/testdata/VerifiableDB
目录并将VerifiableDB.go
智能合约移动到该目录下,编译智能合约,编译过程中可能需要根据提示go get
依赖包go build -ldflags="-s -w" -o VerifiableDB 7z a VerifiableDB 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="{}"
上传Merkle根到长安链智能合约
使用
mbt_store
生成Merkle根,table_path为MySQL数据库中数据库文件位置,后缀为mb,mbt_store中Insert data命令在和插件同时使用时构成链下数据库时不能使用。sudo ./mbt_store Tables loaded from TXT file: /home/chainmaker_mbt/mbstore_data/config.txt 1. Create table 2. Import table 3. Insert data 4. Query data 5. Verify Merkle proof 6. Duplicate table 7. Exit Enter your choice: 2 Enter table name:__test_tb Enter table version:__1 Enter table path (if imported enter NULL):__/data/mysql/test_db/test_tb.mb Table root hash file: /data/chainmaker_mbt/merkle_proofs/test_tb-1.hash Table imported and opened
调用智能合约上传
Table root hash file
中的Merkle根./cmc client contract user invoke \ --contract-name=VerifiableDB \ --method=update_offchain_status \ --sdk-conf-path=./testdata/sdk_config.yml \ --params="{\"Time\":\"1\",\"Table\":\"test_tb\",\"Hash\":\"$(cat /data/chainmaker_mbt/merkle_proofs/test_tb-1.hash)\"}" \ --sync-result=true
链上查询数据
使用长安链客户端调用合约,使用merkle1版本查询id>=18且id<=22的数据,执行以下命令:
./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
使用
mbt_store
在本地生成查询结果和Proofsudo ./mbt_store Tables loaded from TXT file: /data/chainmaker_mbt/mbt_store_data/config.txt 1. Create table 2. Import table 3. Insert data 4. Query data 5. Verify Merkle proof 6. Duplicate table 7. Exit Enter your choice: 2 Enter table name:__test_tb Enter table version:__1 Enter table path (if imported enter NULL):__/data/mysql/test_db/test_tb.mb Table root hash file: /data/chainmaker_mbt/merkle_proofs/test_tb-1.hash Table imported and opened 1. Create table 2. Import table 3. Insert data 4. Query data 5. Verify Merkle proof 6. Duplicate table 7. Exit Enter your choice: 4 Enter table name:__test_tb Enter table version:__1 Enter query left value:__18 Enter query right value:__22 Search result: [result]18 | 1200000012000000 [result]19 | 1300000013000000 [result]20 | 1400000014000000 Range Merkle Proof saved at: /data/chainmaker_mbt/merkle_proofs/test_tb-1-18-22.rmkp Search result saved at: /data/chainmaker_mbt/search_results/test_tb-1-18-22.res
订阅长安链上事件,
contracts
目录下已提供基础版本的订阅程序,如需通过其他合约调用或者其他程序调用可以参考subscribe.go
实现。subscribe.go
需先复制到SDK指定目录后再运行。cd ~ git clone git@git.chainmaker.org.cn:chainmaker/sdk-go.git mkdir -p ~/sdk-go/examples/VerifiableDB cp subscribe.go ~/sdk-go/examples/VerifiableDB cp ~/chainmaker-go/tools/cmc/testdata/sdk_config.yml ~/sdk-go/examples/sdk_configs/sdk_config_org1_client1.yml cd ~/sdk-go/examples/VerifiableDB mkdir testdata cp -r ~/chainmaker-go/build/crypto-config/ ~/sdk-go/examples/VerifiableDB/testdata/ go run subscribe.go
使用长安链客户端调用合约,获取查询结果和验证结果
./cmc client contract user invoke \ --contract-name=VerifiableDB \ --method=get_status_and_result \ --sdk-conf-path=./testdata/sdk_config.yml \ --params="{\"SearchId\":\"1\"}" \ --sync-result=true