参考文档:Truora介绍 — FISCO BCOS v3 v3.1.0 文档
Fiscobcos提供的预言机是Truora,完整的Truora功能包括:
预言机合约 -- 系统提供合约,是请求-应答模式设计的。
客户端合约 -- 系统提供模板,应用程序需要继承模板合约,并重写请求和回调处理方法
预言机事件服务--监听预言机合约事件,完成网络调用获取数据,调用预言机合约的callback方法将数据写入到客户端合约。
数据源网站 -- 通过url查询数据
关键点:
提供预言机事件服务的是我们部署的服务程序,内置了一个链上地址私钥,可以调用预言机合约发起交易。
预言机合约有多种,例如普通查询的OracleCore合约,特殊的VRF合约vrf25519Core。
预言机事件服务(Truora-Service)是一个单独的java工程,配置文件中指定是否启动startOracleCore、startVRF25519。如果配置启动会在启动程序后自动部署OracleCore、VRF25519Core合约,注意要耐心等待一会儿才能完成部署,之后就可以通过接口API查询到这个合约地址了。
Truora-Service版本跟随V3.3.0节点升级了, 可以使用最新的V3.3.0节点。
Truora-Service服务程序有bug,测试发现在访问 “https://api.exchangerate-api.com/v4/latest/CNY”获取汇率数据时出现异常,估计是用的okhttp访问不行了。已经反馈给Fiscobcos,等待官方跟踪解决。
Truora配套了预言机web管理端(Truora-Web),可以查看链上部署的OracleCore、VRF25519Core合约,得到合约地址,供客户端合约使用。
但是Truora-Web代码较老,停留在2.6+版本,不能支持现在的V3.3.0链节点。 即使部署起来也无法得到这两个合约信息,需要等待Fiscobcos升级。
流程:
- 安装Truora-Service服务
- 安装Truora-Web前端组件 -- 现在无法使用不用部署
- 部署应用合约
- 编写客户端
环境: 服务器上部署好了单机4节点,webase工具。
1 安装Truora-Service预言机服务
(1) 拉取预言机代码
一定要拉取这个github代码,不能用gitee.com上的代码,那个已经两年没更新了,太老了不能用。
cd /fiscV3.2
git clone https://github.com/WeBankBlockchain/Truora-Service.git
(2)编译代码
系统中没有安装gradle,如果使用apt install gradle命令,安装的版本是4.4.1, 咱们就不用安装了,直接执行gradlew脚本编译。构建完成后,会在根目录 Truora-Service 下生成已编译的代码目录 dist。
cd Truora-Service/
chmod +x ./gradlew && ./gradlew build -x test
(3)获取链节点证书
拷贝 sdk/ 目录下 ca.crt、node.crt 和 node.key 文件,将链证书复制到编译后的dist/conf/sdk目录下。
cp /fiscoV3.2/nodes/127.0.0.1/sdk/*.* /fiscoV3.2/Truora-Service/dist/conf/sdk
# 复制后要更改名称为chian0_*.*格式,用于后面的链id识别。
root@tom:/fiscoV3.2/Truora-Service/dist/conf/sdk# ls
chain0_ca.crt chain0_cert.cnf chain0_sdk.crt chain0_sdk.key chain0.sdk.nodeid
(4) 配置mysql数据库
进入数据库后,首先要先手工建库truora, 然后执行建表脚本。
root@tom:/fiscoV3.2# mysql -u root -p
mysql> create database truora;
mysql> user truora;
mysql> source /fiscoV3.2/Truora-Service/dbscripts/V2022.10__v1.0.0_init_table.sql;
mysql> exit
(5)修改Turora预言机服务配置文件
这一步最重要也最复杂,稍有不慎就会造成服务启动失败无法运行。需要创建并修改3个文件:application.yml、bcos3sdk_config_chain0.toml、application-fiscobcos3.yml,原始参考文档语焉不详让我这个门外汉撞的满头包,折腾很久才配置成功,接下来我仔细说明配置过程。
我们使用的是Fiscobcos3.3版本节点,链id是chain0,组id是group0。
创建application.yml, 设置数据库用户名、密码,开启profile。
#根据模板复制一份并修改配置
root@tom:/fiscoV3.2/Truora-Service/dist/conf# cp application-template.yml application.yml
root@tom:/fiscoV3.2/Truora-Service/dist/conf# vi application.yml
#server config
server:
port: 5022
servlet:
context-path: /truora
config:
# 服务版本
version: v3.0.0
#log config
logging:
config: classpath:log4j2.xml
level:
org.springframework: WARN
org.hibernate: WARN
com.zaxxer: WARN
org.fisco.bcos.channel: WARN
org.fisco.bcos.sdk.jni: WARN
org.fisco.bcos.sdk.v3: WARN
springfox: WARN
com.webank.oracle: info
# constant
constant:
transMaxWait: 30
restTemplateMaxWait: 30
spring:
main:
banner-mode: OFF
jackson:
date-format: "yyyy-MM-dd HH:mm:ss"
time-zone: "GMT+8"
default-property-inclusion: non_null
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/truora?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false
username: "root"
password: "12345678"
flyway:
enabled: false
jpa:
show-sql: true
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
openInView: false
# generate-ddl: true
hibernate:
ddl-auto: none
session:
events:
log: false
properties:
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: false
hibernate.show_sql: false
############ add in v1.1.0 ############
contract:
version: {oracleCoreVersion: 'v1.1.0', vrfCoreVersion: 'v1.1.0'}
########### eventWorker thread pool########
eventWorker:
pool:
core-size: 25
max-size: 100
queue-capacity: 200
thread-name-prefix: eventWorker-t
keep-alive: 120
---
#按需打开配置文件。即如果只连接fiscobcos2.x只需include: fiscobcos2,如果同时并存,则都include,
#对应application-fiscobcos2/fiscobcos3.yml文件
#application-dapps.yml是供测试demo的配置用的
spring:
profiles:
#include: dapps,fiscobcos2,fiscobcos3
#include: fiscobcos2
include: dapps,fiscobcos3
#include: fiscobcos3
ecvrflib:
debugLevel: 0
创建application-fiscobcos3.yml。
下面的chain0:bcos3sdk_config_chain0.toml 表示针对chain0链的配置文件。
#根据模板复制一份并修改配置
root@tom:/fiscoV3.2/Truora-Service/dist/conf# cp application-fiscobcos3-template.yml application-fiscobcos3.yml
root@tom:/fiscoV3.2/Truora-Service/dist/conf#vi application-fiscobcos3.yml
# 如果包含了这个配置文件,runner.fiscobcos2也需要为true,才会使适配fiscobcos2的部分生效
runner:
fiscobcos3: true
#----------------------------------------------------------
# fisco-bcos 3.x
#----------------------------------------------------------
fiscobcos3:
platform: fiscobcos3
# 可忽略,每个chain/group可配置不同的key file
defaultKeyfile: "./ECC/keyStoreUser.txt"
sdkconfigs:
# 配置指向一到多个链/群组实例的sdk。
# fisco bcos3.x版本的sdk使用独立的toml配置文件,每个链客户端实例写一个toml配置,里面可以配置连接多个节点
chain0: bcos3sdk_config_chain0.toml
#chain1: bcos3sdk_config_1.toml
eventRegisters:
# 配置一到多个chain/group的Oracle/VRF监听服务,如果数据库里没有合约地址记录,会做自动部署
- chainId: chain0
groupId: group0
fromBlock:
toBlock:
#是否启动oracleCore合约监听,一般是要起来的,除非有别的实现,可以不启动这个版本
startOracleCore : true
#是否启动VRF25519Core合约监听,在fisco bcos3上推荐
startVRF25519: true
#是否启动VRFK1Core合约监听,面向VRFK1算法的实现不支持国密,在国密版本上无法启动,在fisco bcos3上推荐使用VRF25519
startVRFK1: false
#为每个监听实例指定不同的keyflie
keyfile: "./ECC/keyStoreUser.txt"
创建bcos3sdk_config_chain0.toml, 从模板复制后需要修改证书名称。
#根据模板复制一份并修改配置
root@tom:/fiscoV3.2/Truora-Service/dist/conf# cp bcos3sdk_config-template.toml bcos3sdk_config_chain0.toml
root@tom:/fiscoV3.2/Truora-Service/dist/conf#vi bcos3sdk_config_chain0.toml
[cryptoMaterial]
useSMCrypto = "false" # 注意,这一个参数按实际是否适用国密来配置,true表示连接的是国密链
#certPath = "classpath" # The certification path
# The following configurations take the certPath by default if commented
caCert = "sdk/chain0_ca.crt" # CA cert file path
# If connect to the GM node, default CA cert path is ${certPath}/gm/gmca.crt
sslCert = "sdk/chain0_sdk.crt" # SSL cert file path
# If connect to the GM node, the default SDK cert path is ${certPath}/gm/gmsdk.crt
sslKey = "sdk/chain0_sdk.key" # SSL key file path
# If connect to the GM node, the default SDK privateKey path is ${certPath}/gm/gmsdk.key
# enSslCert = "conf/gm/gmensdk.crt" # GM encryption cert file path
# default load the GM SSL encryption cert from ${certPath}/gm/gmensdk.crt
# enSslKey = "conf/gm/gmensdk.key" # GM ssl cert file path
# default load the GM SSL encryption privateKey from ${certPath}/gm/gmensdk.key
[network]
peers=["127.0.0.1:20200"] # The peer list to connect
# Configure a private topic as a topic message sender.
# [[amop]]
# topicName = "PrivateTopic1"
# publicKeys = [ "conf/amop/consumer_public_key_1.pem" ] # Public keys of the nodes that you want to send AMOP message of this topic to.
# Configure a private topic as a topic subscriber.
# [[amop]]
# topicName = "PrivateTopic2"
# privateKey = "conf/amop/consumer_private_key.p12" # Your private key that used to subscriber verification.
# password = "123456"
[account]
keyStoreDir = "account" # The directory to load/store the account file, default is "account"
# accountFilePath = "" # The account file path (default load from the path specified by the keyStoreDir)
accountFileFormat = "pem" # The storage format of account file (Default is "pem", "p12" as an option)
# accountAddress = "" # The transactions sending account address
# Default is a randomly generated account
# The randomly generated account is stored in the path specified by the keyStoreDir
# password = "" # The password used to load the account file
[threadPool]
# channelProcessorThreadSize = "16" # The size of the thread pool to process channel callback
# Default is the number of cpu cores
# receiptProcessorThreadSize = "16" # The size of the thread pool to process transaction receipt notification
# Default is the number of cpu cores
maxBlockingQueueSize = "102400" # The max blocking queue size of the thread pool
(6)启动服务
root@tom:/fiscoV3.2/Truora-Service/dist# ./start.sh
===============================================================================================
Server com.webank.truora.Application Port 5022.--------------------------
/usr/lib/jvm/java-11-openjdk-amd64/bin/java -Djdk.tls.namedGroups=secp256k1 -Dfile.encoding=UTF-8 -Xmx256m -Xms256m -Xmn128m -Xss512k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/fiscoV3.2/Truora-Service/dist/log/heap_error.log -Djava.library.path=/fiscoV3.2/Truora-Service/dist/conf -cp conf/:apps/*:lib/* com.webank.truora.Application
PID(877610) [Starting]. Please check message through the log file (default path:./log/).
===============================================================================================
root@tom:/fiscoV3.2/Truora-Service/dist# ps -aux | grep truora
root 877610 74.8 2.4 3184784 396196 pts/0 Sl 09:50 0:19 /usr/lib/jvm/java-11-openjdk-amd64/bin/java -Djdk.tls.namedGroups=secp256k1 -Dfile.encoding=UTF-8 -Xmx256m -Xms256m -Xmn128m -Xss512k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/fiscoV3.2/Truora-Service/dist/log/heap_error.log -Djava.library.path=/fiscoV3.2/Truora-Service/dist/conf -cp conf/:apps/*:lib/* com.webank.truora.Application
root 878267 0.0 0.0 6608 2272 pts/0 S+ 09:51 0:00 grep --color=auto truora
root@tom:/fiscoV3.2/Truora-Service/dist#
#停止服务
root@tom:/fiscoV3.2/Truora-Service/dist# ./stop.sh
#查看服务状态
root@tom:/fiscoV3.2/Truora-Service/dist# ./status.sh
===============================================================================================
Server com.webank.truora.Application Port 5022 is running PID(877610)
===============================================================================================
启动成功后查看log:黄色标记的是自动部署的预言机合约地址。
root@tom:/fiscoV3.2/Truora-Service/dist/log# cat truora-service.log
2023-05-18 05:52:00.671 [main] INFO Application() - Starting Application on tom with PID 368038 (/fiscoV3.2/Truora-Service/dist/apps/Truora-Service.jar started by root in /fiscoV3.2/Truora-Service/dist)
2023-05-18 05:52:00.682 [main] INFO Application() - The following profiles are active: dapps,fiscobcos3,ecdsa
2023-05-18 05:52:02.605 [main] INFO Http11NioProtocol() - Initializing ProtocolHandler ["http-nio-5022"]
2023-05-18 05:52:02.606 [main] INFO StandardService() - Starting service [Tomcat]
2023-05-18 05:52:02.606 [main] INFO StandardEngine() - Starting Servlet engine: [Apache Tomcat/9.0.37]
2023-05-18 05:52:02.721 [main] INFO [/truora]() - Initializing Spring embedded WebApplicationContext
2023-05-18 05:52:04.123 [main] INFO Bcos3SdkHelper() - Using Bcos3SDK Configfile: /fiscoV3.2/Truora-Service/dist/conf/bcos3sdk_config_chain0.toml
2023-05-18 05:52:05.866 [main] INFO Bcos3SdkFactory() - Bcos3sdkFactory build sdk chain0,grouporg.fisco.bcos.sdk.v3.client.ClientImpl@d5d9d92
2023-05-18 05:52:05.873 [main] INFO Bcos3EventRegisterFactory() - Bcos3EventRegisterFactory init! 1
2023-05-18 05:52:06.224 [main] INFO Bcos3KeyTools() - Bcos3KeyTools getKeyFile from: /fiscoV3.2/Truora-Service/dist/conf/ECC/keyStoreUser.txt
2023-05-18 05:52:06.939 [main] INFO Http11NioProtocol() - Starting ProtocolHandler ["http-nio-5022"]
2023-05-18 05:52:07.404 [main] INFO Application() - Started Application in 7.224 seconds (JVM running for 8.179)
2023-05-18 05:52:07.406 [main] INFO Application() - ----Console START---
2023-05-18 05:52:07.407 [main] INFO Bcos3EventRunner() - Bcos3 Register event listener call back...
2023-05-18 05:52:07.618 [main] INFO AbstractContractWorker() - LoadOrDeploy contract on group of chain:[chain0:group0:0x495763688813f965d76fd46455ee5da6ae51c2fe],
2023-05-18 05:52:07.656 [main] INFO Bcos3EventCallback() - *** chainId: chain0 ,groupId: group0,from blockNumber: 366
2023-05-18 05:52:07.673 [Thread-4] INFO Bcos3EventCallback() - ReceivLog but Logs is Empty.eventSubId 74d68fb76cd84231a312a59d067184f6, status:0
2023-05-18 05:52:07.668 [main] INFO Bcos3EventCallback() - [OracleRequest]: subscribe_Event ,address:[0x495763688813f965d76fd46455ee5da6ae51c2fe] , topics: [[0xbfa61b1af63d18b42d712f1f698b554a963ad19f86120d2e08f0afb46a28fd49], null, null, null],from :366,to: -1
2023-05-18 05:52:07.673 [main] INFO Bcos3EventRunner() - OracleCore contract address:[0x495763688813f965d76fd46455ee5da6ae51c2fe] of chain:[chain0:group0]
2023-05-18 05:52:07.711 [main] INFO AbstractContractWorker() - LoadOrDeploy contract on group of chain:[chain0:group0:0x1d6361dfdf5a77d2d5081d6935fe72f5ad6a5773],
2023-05-18 05:52:07.714 [main] INFO Bcos3EventCallback() - *** chainId: chain0 ,groupId: group0,from blockNumber: latest
2023-05-18 05:52:07.715 [main] INFO Bcos3EventCallback() - [RandomnessRequest]: subscribe_Event ,address:[0x1d6361dfdf5a77d2d5081d6935fe72f5ad6a5773] , topics: [[0xc06fcf6ce6367ae604bd05fb6b104a7d6dad2212994be259d5fd64a54a6ea494], null, null, null],from :-1,to: -1
2023-05-18 05:52:07.716 [main] INFO Bcos3EventRunner() - Vrf 25519 contract address:[0x1d6361dfdf5a77d2d5081d6935fe72f5ad6a5773] of chain:[chain0:group0]
2023-05-18 05:52:07.716 [main] INFO Bcos3EventRunner() - EventRunner !SKIP! VRFK1 by config
2023-05-18 05:52:07.716 [Thread-5] INFO Bcos3EventCallback() - ReceivLog but Logs is Empty.eventSubId 8aaaf316be6f441da4147828d4cfb4c0, status:0
2023-05-18 05:52:07.718 [main] INFO HttpUtil() - Init http util, connect timeout:[5000], read timeout:[5000], write timeout:[5000]
2023-05-18 05:52:07.835 [main] INFO ServerConfig() - Server init with config: [{"version":"v3.0.0","operator":"oracle operator","url":"http://localhost:5120"}]
(7) 调用服务接口
查看所有服务
http://192.168.2.231:5022/truora/index
应答:
{
"code": 0,
"message": "success",
"data": [
"http://192.168.2.231:5022",
"http://192.168.2.231:5022/truora/index",
"http://192.168.2.231:5022/truora/version",
"http://192.168.2.231:5022/truora/chain/group/list",
"http://192.168.2.231:5022/truora/chain/group/ping",
"http://192.168.2.231:5022/truora/oracle/address",
"http://192.168.2.231:5022/truora/oracle/address?chainId=chain0&groupId=group0", "http://192.168.2.231:5022/truora/history/query/280ac496641910d37a6e6d4638f67844f1efdf00869838213c1e98ec94909337", "http://192.168.2.231:5022/truora/history/list?chainId=chain0&groupId=group0&pageSize=50&hideResult=false", "http://192.168.2.231:5022/truora/dapps/get",
"http://192.168.2.231:5022/truora/dapps/get?url=1",
"http://192.168.2.231:5022/truora/dapps/get?url=2",
"http://192.168.2.231:5022/truora/dapps/get?url=3",
"http://192.168.2.231:5022/truora/dapps/get?url=4&input=sampletext",
"http://192.168.2.231:5022/truora/dapps/vrf/deploy?type=25519",
"http://192.168.2.231:5022/truora/dapps/vrf/get?type=25519",
"http://192.168.2.231:5022/truora/dapps/vrf/get?type=k1",
"http://192.168.2.231:5022/truora/source/exchange",
"http://192.168.2.231:5022/truora/source/rand",
"http://192.168.2.231:5022/truora/source/text?input=sampletext"],
"totalCount": 0
}