WeCross¶
由微众银行自主研发并完全开源的分布式商业区块链跨链协作平台。该平台能解决业界主流的区块链产品间接口不互通、无法协作的问题,以及区块链系统无法平行扩展、计算能力和存储容量存在瓶颈等问题。WeCross作为未来分布式商业区块链互联的基础架构,秉承公众联盟链多方参与、共享资源、智能协同和价值整合的理念,致力于促进跨行业、机构和地域的跨区块链价值交换和商业合作,实现了高效、通用和安全的区块链跨链协作机制。

平台介绍¶
基本介绍¶
区块链作为构建未来价值互联网的重要基础设施,深度融合分布式存储、点对点通信、分布式架构、共识机制、密码学等前沿技术,正在成为技术创新的前沿阵地。全球主要国家都在加快布局区块链技术,用以推动技术革新和产业变革。经过行业参与者十年砥砺前行,目前区块链在底层技术方案上已趋于完整和成熟,国内外均出现可用于生产环境的区块链解决方案。其所面向的创新应用场景覆盖广泛,已在对账与清结算、跨境支付、供应链金融、司法仲裁、政务服务、物联网、智慧城市等众多领域落地企业级应用。
在广泛的场景应用背后,来自于性能、安全、成本、扩展等方面的技术挑战也愈发严峻。目前不同区块链应用之间互操作性不足,无法有效进行可信数据流通和价值交换,各个区块链俨然成为一座座信任孤岛,很大程度阻碍了区块链应用生态的融合发展。未来,区块链想要跨越到真正的价值互联网,承担传递信任的使命,开启万链互联时代,需要一种通用、高效、安全的区块链跨链协作机制,实现跨场景、跨地域不同区块链应用之间的互联互通,以服务数量更多、地域更广的公众群体。
作为一家具有互联网基因的高科技、创新型银行,微众银行自成立之初即高度重视新兴技术的研究和探索,在区块链领域积极开展技术积累和应用实践,不断致力于运用区块链技术提升多机构间的协作效率和降低协作成本,支持国家推进关键技术安全可控战略和推动社会普惠金融发展。微众银行区块链团队基于一揽子自主研发并开源的区块链技术方案,针对不同服务形态、不同区块链平台之间无法进行可信连接与交互的行业痛点,研发区块链跨链协作平台——WeCross,以促进跨行业、机构和地域的跨区块链信任传递和商业合作。
WeCross 着眼应对区块链行业现存挑战,不局限于满足同构区块链平行扩展后的可信数据交换需求,还进一步探索异构区块链之间因底层架构、数据结构、接口协议、安全机制等多维异构性导致无法互联互通问题的有效解决方案。作为未来区块链互联的基础设施,WeCross 秉承多方参与、共享资源、智能协同和价值整合的理念,面向公众完全开源,欢迎广大企业及技术爱好者踊跃参与项目共建。
关键词¶
- 跨链路由(WeCross Router)
- 与链对接,对链上的资源进行抽象
- 向外暴露统一的接口
- 将调用请求路由至对应的区块链
- 控制台(WeCross Console)
- 命令行式的交互
- 查询跨链信息,发送调用请求
- 跨链 SDK(WeCross Java SDK)
- WeCross开发工具包,供开发者调用WeCross
- 集成于各种跨链APP中,提供统一的调用接口
- 与跨链路由建立连接,调用跨链路由
- 跨链资源(Resource)
- 各种区块链上内容的抽象
- 包括:合约、资产、信道、数据表
- 跨链适配器(Stub)
- 跨链路由中对接入的区块链的抽象
- 跨链路由通过配置Stub与相应的区块链对接
- FISCO BCOS需配置FISCO BCOS Stub、Fabric需配置Fabric Stub
- IPath(Interchain Path)
- 跨链资源的唯一标识
- 跨链路由根据IPath将请求路由至相应区块链上
- 在代码和文档中将IPath简称为path
- 跨链分区
- 多条链通过跨链路由相连,形成跨链分区
- 跨链分区有唯一标识,即IPath中的第一项(
payment.stub3.resource-d
的payment
)
更多资料¶
程序版本¶
v1.0.0-rc1¶
(2019-12-30)
功能
- 接入区块链
- 适配 FISCO BCOS
- 适配 Fabric
- 统一接口:跨链路由将各种区块链的操作接口进行抽象,向外暴露统一的调用API
- 路由请求:跨链路由可自动将调用请求路由至相应的区块链
- 交易验证:向FISCO BCOS的链发交易时,能验证交易上链后的Merkle证明
架构
- 跨链路由:对接不同区块链的服务,对区块链的调用接口进行统一的抽象,彼此互连,将操作请求路由至相应链
- 跨链SDK:Java语言的API,用统一的接口向不同的链发请求
- 控制台:方便的操作终端,方便进行查询和发送请求
工具
- 跨链分区搭建脚本
- 接入FISCO BCOS和Fabric的配置框架生成脚本
v1.0.0-rc2¶
(2020-05-12)
新增
- 账户管理:用户账户统一由Router管理
- HTLC事务:支持同/异构链之间基于HTLC合约完成跨链转账
- Stub插件化:FISCO BCOS Stub和Fabric Stub通过jar包方式引入
- 安全通讯:WeCross SDK和Router之间采用TLS协议通讯
- 跨链Demo: 支持快速搭建WeCross Demo,体验简单跨链调用
更新
- 跨链接口:跨链调用需要指定账户名
- 跨链合约:跨链合约的参数类型和返回值类型限定为字符串数组
- 配置文件:主配置新增TLS以及HTLC配置项,Stub配置移除账户配置项
- 使用脚本:部署脚本、配置脚本以及证书生成脚本适配新的配置项
v1.0.0-rc3¶
(2020-06-16)
新增
- Driver新增异步API定义:asyncCall、asyncSendTransaction,采用异步的方式调用插件接口
更新
- P2P通信:Router间的通信更新为异步的方式
- RPC接口:将性能较差的spring boot tomcat替换成netty的http server
- HTLC:适配Driver的异步API,采用异步的方式进行调用
下载程序¶
下载WeCross¶
提供三种方式,根据网络环境选择合适的方式进行下载。
方式1:命令下载
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_wecross.sh)
方式2:命令下载(源码编译模式)
# 默认下载master分支
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_wecross.sh) -s
# 下载特定版本下的
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_wecross.sh) -s -t v1.0.0-rc3
方式3:手动下载
github release(下载最新版本的
WeCross.tar.gz
)手动下载后解压
tar -zxvf WeCross.tar.gz
解压后,目录下包含WeCross/
文件夹。
下载WeCross控制台¶
同样提供三种方式,根据网络环境选择合适的方式进行下载。
方式1:命令下载
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_console.sh)
方式2:命令下载(源码编译模式)
# 默认下载master分支
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_console.sh) -s
# 下载特定版本下的控制台
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_console.sh) -s -t v1.0.0-rc3
方式3:手动下载
github release(下载最新版本的
WeCross-Console.tar.gz
)手动下载解压
tar -zxvf WeCross-Console.tar.gz
下载后,目录下包含WeCross-Console/
文件夹。
下载WeCross Demo¶
同样提供两种方式,根据网络环境选择合适的方式进行下载。
方式1:命令下载
# 下载最新demo
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_demo.sh)
# 下载特定版本下的demo
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_demo.sh) -t v1.0.0-rc3
方式2:手动下载
github release(下载最新release下的
demo.tar.gz
)手动下载解压
tar -zxvf demo.tar.gz
下载后,目录下包含demo/
文件夹。
快速入门¶
本章介绍WeCross所需的软硬件环境配置,以及为用户提供了快速入门WeCross的教程。
环境要求¶
硬件¶
WeCross负责管理多个Stub并与多条链通讯,同时作为Web Server提供RPC调用服务,为了能保证服务的稳定性,尽量使用推荐配置。
配置 | 最低配置 | 推荐配置 |
---|---|---|
CPU | 1.5GHz | 2.4GHz |
内存 | 4GB | 8GB |
核心 | 4核 | 8核 |
带宽 | 2Mb | 10Mb |
支持的平台¶
- Ubuntu 16.04及以上
- CentOS 7.2及以上
- MacOS 10.14及以上
快速体验¶
我们提供一个Demo帮助用户快速体验并理解WeCross的原理。Demo搭建了一个WeCross跨链网络,连接FISCO BCOS和Hyperledger Fabric区块链。用户可通过WeCross控制台,对不同的链上资源进行操作。
搭建 Demo¶
- 下载
若下载较慢,可选择更多下载方式。
cd ~
# 下载,生成demo文件夹
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_demo.sh)
- 部署
cd demo
# 运行部署脚本,耗时10-30分钟左右
bash build.sh # 若出错,可用 bash clear.sh 清理后重试
注解
- MacOS用户若出现“无法打开”,“无法验证开发者”的情况,可参考 FAQ问题3 的方式解决
部署成功后会输出Demo的网络架构,FISCO BCOS和Fabric通过各自的WeCross Router相连。(输入Y,回车,进入WeCross控制台)
[INFO] Success! WeCross demo network is running. Framework:
FISCO BCOS Fabric
(4node pbft) (first-network)
(HelloWeCross.sol) (abac.go)
| |
| |
WeCross Router <----------> WeCross Router
(127.0.0.1-8250-25500) (127.0.0.1-8251-25501)
|
|
WeCross Console
Start console? [Y/n]
操作跨链资源¶
查看资源
进入控制台,用listResources
命令查看WeCross跨连网络中的所有资源。可看到有两个资源:
- payment.bcos.HelloWeCross
- 对应于FISCO BCOS链上的HelloWeCross.sol合约
- payment.fabric.abac
- 对应于Fabric链上的abac.go合约
[WeCross]> listResources
path: payment.bcos.HelloWeCross, type: BCOS2.0, distance: 0
path: payment.fabric.abac, type: Fabric1.4, distance: 1
total: 2
查看账户
用listAccounts
命令查看WeCross Router上已存在的账户,操作资源时用相应账户进行操作。
[WeCross]> listAccounts
name: fabric_user1, type: Fabric1.4
name: fabric_default_account, type: Fabric1.4
name: bcos_user1, type: BCOS2.0
name: bcos_default_account, type: BCOS2.0
total: 4
操作资源:payment.bcos.HelloWeCross
- 读资源
- 命令:
call path 账户名 接口名 [参数列表]
- 示例:
call payment.bcos.HelloWeCross bcos_user1 get
- 命令:
# 调用HelloWeCross合约中的get接口
[WeCross]> call payment.bcos.HelloWeCross bcos_user1 get
Result: [Talk is cheap, Show me the code]
- 写资源
- 命令:
sendTransaction path 账户名 接口名 [参数列表]
- 示例:
sendTransaction payment.bcos.HelloWeCross bcos_user1 set Tom
- 命令:
# 调用HelloWeCross合约中的set接口
[WeCross]> sendTransaction payment.bcos.HelloWeCross bcos_user1 set Tom
Txhash : 0x21a412a1eb5239f2da9d40d09d11ce0107a5d82d113f1ecb315f2aa5bd3cc0cd
BlockNum: 2
Result : [Tom] // 将Tom给set进去
[WeCross]> call payment.bcos.HelloWeCross bcos_user1 get
Result: [Tom] // 再次get,Tom已set
操作资源:payment.fabric.abac
跨链资源是对各个不同链上资源的统一和抽象,因此操作的命令是保持一致的。
- 读资源
# 调用abac合约中的query接口
[WeCross]> call payment.fabric.abac fabric_user1 query a
Result: [90] // 初次query,a的值为90
- 写资源
# 调用abac合约中的invoke接口
[WeCross]> sendTransaction payment.fabric.abac fabric_user1 invoke a b 10
Txhash : db44b064c54d4dc97f01cdcd013cae219f7849c329f38ee102853344d8f0004d
BlockNum: 5
Result : []
[WeCross]> call payment.fabric.abac fabric_user1 query a
Result: [80] // 再次query,a的值变成80
# 退出WeCross控制台
[WeCross]> quit # 若想再次启动控制台,cd至WeCross-Console,执行start.sh即可
WeCross Console是基于WeCross Java SDK开发的跨链应用。搭建好跨链网络后,可基于WeCross Java SDK开发更多的跨链应用,通过统一的接口对各种链上的资源进行操作。
跨链转账¶
WeCross基于哈希时间锁合约实现了异构链之间资产的原子互换,如下图所示:
配置哈希时间锁合约
可通过脚本htlc_config.sh
完成相关配置,并体验跨链转账。
# 请确保demo已搭建完毕,并在demo根目录执行,耗时5分钟左右
bash htlc_config.sh
跨链转账涉及两条链、两个用户、四个账户,两条链上的资产转出者各自通过WeCross控制台创建一个转账提案,之后router会自动完成跨链转账。
创建转账提案
跨链转账需在跨链的两端都提交转账提案,提交后,router自动实现跨链转账。
- BCOS链资产转出者提交提案
BCOS链连的是router-8250,启动与该router连接的控制台。
cd ~/demo/WeCross-Console
bash start.sh
# 先查看接收方余额
[WeCross]> call payment.bcos.htlc bcos_sender balanceOf 0x2b5ad5c4795c026514f8317c7a215e218dccd6cf
Result: [0]
# 创建转账提案
[WeCross]> newHTLCTransferProposal payment.bcos.htlc bcos_sender bea2dfec011d830a86d0fbeeb383e622b576bb2c15287b1a86aacdba0a387e11 9dda9a5e175a919ee98ff0198927b0a765ef96cf917144b589bb8e510e04843c true 0x55f934bcbe1e9aef8337f5551142a442fdde781c 0x2b5ad5c4795c026514f8317c7a215e218dccd6cf 700 2000010000 Admin@org1.example.com User1@org1.example.com 500 2000000000
# 输出
Txhash: a0c48eb7d1ca3a01ddf3563aeb6a1829f23dd0d778e7de2ce22406d1e84ba00f
BlockNum: 6
Result: create a htlc transfer proposal successfully
# 退出当前控制台
[WeCross]> quit
- Fabric链资产转出者提交提案
BCOS链连的是router-8251,启动与该router连接的控制台。
cd ~/demo/WeCross-Console-8251
bash start.sh
# 先查看接收方余额
[WeCross]> call payment.fabric.htlc fabric_admin balanceOf User1@org1.example.com
Result: [0]
# 创建转账提案
[WeCross]> newHTLCTransferProposal payment.fabric.htlc fabric_admin bea2dfec011d830a86d0fbeeb383e622b576bb2c15287b1a86aacdba0a387e11 null false 0x55f934bcbe1e9aef8337f5551142a442fdde781c 0x2b5ad5c4795c026514f8317c7a215e218dccd6cf 700 2000010000 Admin@org1.example.com User1@org1.example.com 500 2000000000
# 输出
Txhash: 0x40ae8e2e284de813f8b071e0261e627ddc4d91e365e63f222638db9b1a70d05a
BlockNum: 7
Result: create a htlc transfer proposal successfully
# 退出当前控制台
[WeCross]> quit
跨链资产转移
当两个资产转出者都创建完提案后,router开始执行调度,并完成跨链转账。一次跨链转账存在5-25s的交易时延,主要取决于两条链以及机器的性能。
查询转账结果
在各自的WeCross控制台查询资产是否到账。
- 查询BCOS链上资产接收者余额
cd ~/demo/WeCross-Console
bash start.sh
[WeCross]> call payment.bcos.htlc bcos_sender balanceOf 0x2b5ad5c4795c026514f8317c7a215e218dccd6cf
Result: [700]
# 退出当前控制台
[WeCross]> quit
- 查询Fabric链上资产接收者余额
cd ~/demo/WeCross-Console-8251
bash start.sh
[WeCross]> call payment.fabric.htlc fabric_admin balanceOf User1@org1.example.com
Result: [500]
# 退出当前控制台
[WeCross]> quit
手动组网¶
本文档介绍以手动的方式,一步步搭建一个与Demo相同的跨链网络。
快速部署¶
- 跨链路由:与区块链节点对接,并彼此互连,形成跨链分区,负责跨链请求的转发
- 跨链控制台:查询和发送交易的操作终端
操作以~/wecross/
目录下为例进行。若Demo未清理,请先清理Demo环境。
mkdir -p ~/wecross/ && cd ~/wecross/
部署 WeCross Router¶
下载WeCross,用WeCross中的工具生成跨链路由,并启动跨链路由。
下载WeCross¶
WeCross中包含了生成跨链路由的工具,执行以下命令进行下载(提供三种下载方式,可根据网络环境选择合适的方式进行下载),程序下载至当前目录WeCross/
中。
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_wecross.sh)
生成跨链路由¶
本例将构建两个跨链路由。首先创建一个ipfile
配置文件,将需要构建的两个跨链路由信息(ip:rpc_port:p2p_port
)按行分隔,保存到文件中。
注:请确保机器的8250
,8251
, 25500
,25501
端口没有被占用。
cd ~/wecross
vim ipfile
# 在文件中键入以下内容
127.0.0.1:8250:25500
127.0.0.1:8251:25501
生成好ipfile
文件后,使用脚本build_wecross.sh生成两个跨链路由。
# -f 表示以文件为输入
bash ./WeCross/build_wecross.sh -n payment -o routers-payment -f ipfile
# 成功输出如下信息
[INFO] Create routers-payment/127.0.0.1-8250-25500 successfully
[INFO] Create routers-payment/127.0.0.1-8251-25501 successfully
[INFO] All completed. WeCross routers are generated in: routers-payment/
注解
- -n 指定跨链分区标识符(zone id),跨链分区通过zone id进行区分,可以理解为业务名称。
- -o 指定输出的目录,并在该目录下生成一个跨链路由。
- -f 指定需要生成的WeCross跨链路由的列表,包括ip地址,rpc端口,p2p端口,生成后的router已完成互联配置。
在routers-payment目录下生成了两个跨链路由。
tree routers-payment/ -L 1
routers-payment/
├── 127.0.0.1-8251-25501
├── 127.0.0.1-8252-25502
└── cert
生成的跨链路由目录内容如下,以127.0.0.1-8250-25500
为例。
# 已屏蔽lib目录,该目录存放所有依赖的jar包
tree routers-payment/127.0.0.1-8250-25500/ -I "lib"
routers-payment/127.0.0.1-8250-25500/
├── add_account.sh # 账户生成脚本
├── add_chain.sh # 区块链配置文件创建脚本
├── apps
│ └── WeCross.jar # WeCross路由jar包
├── build_wecross.sh
├── conf # 配置文件目录
│ ├── accounts # 账户配置目录
│ ├── application.properties
│ ├── chains # 区块链配置目录,要接入不同的链,在此目录下进行配置
│ ├── log4j2.xml
│ ├── ca.crt # 根证书
│ ├── ssl.crt # 跨链路由证书
│ ├── ssl.key # 跨链路由私钥
│ ├── node.nodeid # 跨链路由nodeid
│ └── wecross.toml # WeCross Router主配置文件
├── create_cert.sh # 证书生成脚本
├── download_wecross.sh
├── plugin # 插件目录,接入相应类型链的插件
│ ├── bcos-stub-gm.jar
│ ├── bcos-stub.jar
│ └── fabric-stub.jar
├── start.sh # 启动脚本
└── stop.sh # 停止脚本
启动跨链路由¶
# 启动 router-8250
cd ~/wecross/routers-payment/127.0.0.1-8250-25500/
bash start.sh # 停止: bash stop.sh
# 启动 router-8251
cd ~/wecross/routers-payment/127.0.0.1-8251-25501/
bash start.sh # 停止: bash stop.sh
启动成功,输出如下:
WeCross booting up .........
WeCross start successfully
如果启动失败,检查8250, 25500
端口是否被占用。
netstat -napl | grep 8250
netstat -napl | grep 25500
netstat -napl | grep 8251
netstat -napl | grep 25501
部署WeCross控制台¶
WeCross提供了控制台,方便用户进行跨链开发和调试。可通过脚本build_console.sh
搭建控制台。
下载WeCross控制台
执行如下命令进行下载(提供三种下载方式,可根据网络环境选择合适的方式进行下载),下载完成后在当前目录下生成WeCross-Console
目录。
cd ~/wecross/
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_console.sh)
配置控制台
cd ~/wecross/WeCross-Console
# 拷贝连接router所需的TLS证书,从生成的routers-payment/cert/sdk目录下拷贝
cp ~/wecross/routers-payment/cert/sdk/* conf/ # 包含:ca.crt、node.nodeid、ssl.crt、ssl.key
# 拷贝配置文件,并配置跨链路由RPC服务地址以及端口。此处采用默认配置,默认连接至本地8250端口。
cp conf/application-sample.toml conf/application.toml
重要
- 若搭建WeCross的IP和端口未使用默认配置,需自行更改WeCross-Console/conf/application.toml,详见 控制台配置。
启动控制台
bash start.sh
启动成功则输出如下信息,通过help
可查看控制台帮助
=================================================================================
Welcome to WeCross console(v1.0.0-rc3)!
Type 'help' or 'h' for help. Type 'quit' or 'q' to quit console.
=================================================================================
测试功能
# 查看连接的router当前支持接入的链类型
[WeCross]> supportedStubs
[BCOS2.0, GM_BCOS2.0, Fabric1.4]
# 退出控制台
[server1]> q
更多控制台命令及含义详见控制台命令。
接入区块链¶
完成了WeCross的部署,如何让它和一条真实的区块链交互,相信优秀的您一定在跃跃欲试。本节包括
- 接入BCOS链:在router-8250上接入,配置交易发送账户
- 接入Fabric链:在router-8251上接入,配置交易发送账户
搭建区块链¶
在接入区块链前,先给出BCOS和Fabric链的搭建过程。
搭建BCOS链¶
FISCO BCOS官方提供了一键搭链的教程,详见单群组FISCO BCOS联盟链的搭建
详细步骤如下:
- 脚本建链
# 创建操作目录
mkdir -p ~/wecross/bcos && cd ~/wecross/bcos
# 下载build_chain.sh脚本
curl -LO https://github.com/FISCO-BCOS/FISCO-BCOS/releases/download/v2.4.0/build_chain.sh && chmod u+x build_chain.sh
# 搭建单群组4节点联盟链
# 在fisco目录下执行下面的指令,生成一条单群组4节点的FISCO链。请确保机器的30300~30303,20200~20203,8545~8548端口没有被占用。
# 命令执行成功会输出All completed。如果执行出错,请检查nodes/build.log文件中的错误信息。
bash build_chain.sh -l "127.0.0.1:4" -p 30300,20200,8545
- 启动所有节点
bash nodes/127.0.0.1/start_all.sh
启动成功会输出类似下面内容的响应。否则请使用netstat -an | grep tcp
检查机器的30300~30303,20200~20203,8545~8548
端口是否被占用。
try to start node0
try to start node1
try to start node2
try to start node3
node1 start successfully
node2 start successfully
node0 start successfully
node3 start successfully
部署HelloWeCross合约¶
通过FISCO BCOS控制台部署HelloWeCross
合约,控制台的安装和使用详见官方文档配置及使用控制台
HelloWeCros
合约位于~/wecross/routers-payment/127.0.0.1-8250-25500/conf/chains-sample/bcos/
控制台安装配置完后启动并部署HelloWeCross.sol
,详细步骤如下:
- 安装控制台
# 获取控制台
cd ~/wecross/bcos/nodes/127.0.0.1/
bash download_console.sh -v 1.0.9
# 拷贝控制台配置文件
# 若节点未采用默认端口,请将文件中的20200替换成节点对应的channle端口。
cp -n console/conf/applicationContext-sample.xml console/conf/applicationContext.xml
# 配置控制台证书
cp ~/wecross/bcos/nodes/127.0.0.1/sdk/* console/conf/
- 拷贝合约文件
将HelloWeCross
合约拷贝至FISCO BCOS控制台目录。
cp ~/wecross/routers-payment/127.0.0.1-8250-25500/conf/chains-sample/bcos/HelloWeCross.sol console/contracts/solidity/
- 启动控制台
bash console/start.sh
输出下述信息表明启动成功,否则请检查conf/applicationContext.xml
中节点端口配置是否正确。
=============================================================================================
Welcome to FISCO BCOS console(1.0.9)!
Type 'help' or 'h' for help. Type 'quit' or 'q' to quit console.
________ ______ ______ ______ ______ _______ ______ ______ ______
| \| \ / \ / \ / \ | \ / \ / \ / \
| $$$$$$$$ \$$$$$$| $$$$$$\| $$$$$$\| $$$$$$\ | $$$$$$$\| $$$$$$\| $$$$$$\| $$$$$$\
| $$__ | $$ | $$___\$$| $$ \$$| $$ | $$ | $$__/ $$| $$ \$$| $$ | $$| $$___\$$
| $$ \ | $$ \$$ \ | $$ | $$ | $$ | $$ $$| $$ | $$ | $$ \$$ \
| $$$$$ | $$ _\$$$$$$\| $$ __ | $$ | $$ | $$$$$$$\| $$ __ | $$ | $$ _\$$$$$$\
| $$ _| $$_ | \__| $$| $$__/ \| $$__/ $$ | $$__/ $$| $$__/ \| $$__/ $$| \__| $$
| $$ | $$ \ \$$ $$ \$$ $$ \$$ $$ | $$ $$ \$$ $$ \$$ $$ \$$ $$
\$$ \$$$$$$ \$$$$$$ \$$$$$$ \$$$$$$ \$$$$$$$ \$$$$$$ \$$$$$$ \$$$$$$
=============================================================================================
- 部署合约
[group:1]> deploy HelloWeCross
contract address: 0x19a70c01e801d3cac241de5f11686e3aa01e463b
# 退出控制台
[group:1]> quit
将HelloWeCross
的合约地址记录下来,后续步骤中使用:
contract address: 0x19a70c01e801d3cac241de5f11686e3aa01e463b
搭建Fabric链¶
为方便Fabric链的搭建,WeCross Demo包中提供了Fabric链搭建脚本。若下载较慢,可选择更多下载方式。
mkdir -p ~/wecross/fabric && cd ~/wecross/fabric
# 下载Demo包
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_demo.sh)
cp demo/fabric/* ./
# 搭建
bash build.sh # 若出错,执行 bash clear.sh 后重新 bash build.sh
搭建成功,查看Fabric链各个容器运行状态。
docker ps
可看到各个容器的状态:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3b55f9681227 dev-peer1.org2.example.com-mycc-1.0-26c2ef32838554aac4f7ad6f100aca865e87959c9a126e86d764c8d01f8346ab "chaincode -peer.add…" 13 minutes ago Up 13 minutes dev-peer1.org2.example.com-mycc-1.0
2d8d660c9481 dev-peer0.org1.example.com-mycc-1.0-384f11f484b9302df90b453200cfb25174305fce8f53f4e94d45ee3b6cab0ce9 "chaincode -peer.add…" 13 minutes ago Up 13 minutes dev-peer0.org1.example.com-mycc-1.0
b82b0b8dcc0f dev-peer0.org2.example.com-mycc-1.0-15b571b3ce849066b7ec74497da3b27e54e0df1345daff3951b94245ce09c42b "chaincode -peer.add…" 14 minutes ago Up 14 minutes dev-peer0.org2.example.com-mycc-1.0
441ca8a493fc hyperledger/fabric-tools:latest "/bin/bash" 14 minutes ago Up 14 minutes cli
de0d32730926 hyperledger/fabric-peer:latest "peer node start" 14 minutes ago Up 14 minutes 0.0.0.0:9051->9051/tcp peer0.org2.example.com
ad98565bfa57 hyperledger/fabric-peer:latest "peer node start" 14 minutes ago Up 14 minutes 0.0.0.0:10051->10051/tcp peer1.org2.example.com
bf0d9b0c54bf hyperledger/fabric-peer:latest "peer node start" 14 minutes ago Up 14 minutes 0.0.0.0:8051->8051/tcp peer1.org1.example.com
b4118a65f01a hyperledger/fabric-orderer:latest "orderer" 14 minutes ago Up 14 minutes 0.0.0.0:7050->7050/tcp orderer.example.com
fcf1bfe17dbe hyperledger/fabric-peer:latest "peer node start" 14 minutes ago Up 14 minutes 0.0.0.0:7051->7051/tcp peer0.org1.example.com
接入BCOS链¶
添加账户¶
在router中添加用于向链上发交易的账户。账户配置好后,可通过跨链网络向相应的链发交易,交易可被router转发至对应的链上。
添加BCOS账户
所配置的账户可用于向BCOS2.0
类型的链发交易。
# 切换至对应router的目录下
cd ~/wecross/routers-payment/127.0.0.1-8250-25500/
# 用脚本生成BCOS账户:账户类型(BCOS2.0),账户名(bcos_user1)
bash add_account.sh -t BCOS2.0 -n bcos_user1
生成的bcos_user1文件目录如下:
tree conf/accounts/bcos_user1/
conf/accounts/bcos_user1/
├── account.key
└── account.toml
添加Fabric账户
所配置的账户可用于向Fabric1.4
类型的链发交易。
# 用脚本生成Fabric账户:账户类型(Fabric1.4),账户名(fabric_user1)
bash add_account.sh -t Fabric1.4 -n fabric_user1
cp ~/wecross/fabric/certs/accounts/fabric_user1/* conf/accounts/fabric_user1/ # 拷贝 Fabric链的证书,具体说明请参考《跨链接入》章节
生成的fabric_user1文件目录如下:
tree conf/accounts/fabric_user1/
conf/accounts/fabric_user1/
├── account.crt
├── account.key
└── account.toml
配置接入BCOS链¶
为router添加需要接入的链配置。
生成配置文件
切换至跨链路由的目录,用 add_chain.sh 脚本在conf
目录下生成bcos的配置文件框架。
cd ~/wecross/routers-payment/127.0.0.1-8250-25500
# -t 链类型,-n 指定链名字
bash add_chain.sh -t BCOS2.0 -n bcos
生成的目录结构如下:
tree conf/chains/bcos
conf/chains/bcos
└── stub.toml # chain配置文件
命令执行成功会输出operator: chain type: BCOS2.0 path: conf/chains/bcos
,如果执行出错,请查看屏幕打印提示。
之后只需要配置证书、群组以及资源信息。
配置BCOS节点连接
- 拷贝证书
cp ~/wecross/bcos/nodes/127.0.0.1/sdk/* conf/chains/bcos/
- 修改配置
vim conf/chains/bcos/stub.toml
如果搭FISCO BCOS链采用的都是默认配置,那么将会得到一条单群组四节点的链,群组ID为1,可连接至节点0的channel端口20200
,则配置如下:
[chain]
groupId = 1 # default 1
chainId = 1 # default 1
[channelService]
caCert = 'ca.crt'
sslCert = 'sdk.crt'
sslKey = 'sdk.key'
timeout = 300000 # ms, default 60000ms
connectionsStr = ['127.0.0.1:20200']
配置跨链资源
在stub.toml
文件中配置HelloWeCross
合约资源信息,让此跨链路由能够访问此合约。可将配置中多余的资源配置举例删除。
在前面的步骤中,已经通过FISCO BCOS控制台部署了一个HelloWeCross
合约,地址为0x19a70c01e801d3cac241de5f11686e3aa01e463b
,将contractAddress
配置为该地址中。
[[resources]]
# name cannot be repeated
name = 'HelloWeCross'
type = 'BCOS_CONTRACT'
contractAddress = '0x19a70c01e801d3cac241de5f11686e3aa01e463b'
完整配置
此时已完成bcos
的连接配置,并注册了一个合约资源,最终的stub.toml
文件如下。参考此处获取更详尽的配置说明
[common]
name = 'bcos'
type = 'BCOS2.0' # BCOS
[chain]
groupId = 1 # default 1
chainId = 1 # default 1
[channelService]
caCert = 'ca.crt'
sslCert = 'sdk.crt'
sslKey = 'sdk.key'
timeout = 300000 # ms, default 60000ms
connectionsStr = ['127.0.0.1:20200']
# resources is a list
[[resources]]
# name cannot be repeated
name = 'HelloWeCross'
type = 'BCOS_CONTRACT'
contractAddress = '0x19a70c01e801d3cac241de5f11686e3aa01e463b'
启动路由
启动跨链路由加载已配置的跨链资源。
cd ~/wecross/routers-payment/127.0.0.1-8250-25500
# 若WeCross跨链路由未停止,需要先停止
bash stop.sh
# 重新启动
bash start.sh
检查日志,可看到刷出已加载的跨链资源,ctrl + c
退出。
tail -f logs/info.log |grep "active resources"
2020-04-24 20:07:20.966 [Thread-4] INFO WeCrossHost() - Current active resources: payment.bcos.HelloWeCross(local)
2020-04-24 20:07:30.973 [Thread-4] INFO WeCrossHost() - Current active resources: payment.bcos.HelloWeCross(local)
2020-04-24 20:07:40.980 [Thread-4] INFO WeCrossHost() - Current active resources: payment.bcos.HelloWeCross(local)
接入Fabric链¶
添加账户¶
在router中添加用于向链上发交易的账户。
添加Fabric账户
# 切换至对应router的目录下
cd ~/wecross/routers-payment/127.0.0.1-8251-25501/
# 用脚本生成Fabric账户配置:账户类型(Fabric1.4),账户名(fabric_admin)
# 接入Fabric链,需要配置一个admin账户
bash add_account.sh -t Fabric1.4 -n fabric_admin
# 拷贝 Fabric链的证书,具体说明请参考《跨链接入》章节
cp ~/wecross/fabric/certs/accounts/fabric_admin/* conf/accounts/fabric_admin/
# router-8250上配置的账户直接拷贝也可用
cp -r ~/wecross/routers-payment/127.0.0.1-8250-25500/conf/accounts/fabric_user1 conf/accounts/
目前配置了两个账户,若此router需要向BCOS的链发交易,也可配置BCOS的账户。账户配置与接入的链无关,router间自动转发交易至相应的链。账户目录结构如下:
tree conf/accounts
conf/accounts
├── fabric_admin
│ ├── account.crt
│ ├── account.key
│ └── account.toml
└── fabric_user1
├── account.crt
├── account.key
└── account.toml
配置接入Fabric链¶
为router添加需要接入的链配置。
生成配置文件
切换至跨链路由的目录,用 add_chain.sh 脚本在conf
目录下生成Fabric的配置文件框架。
cd ~/wecross/routers-payment/127.0.0.1-8251-25501
# -t 链类型,-n 指定链名字
bash add_chain.sh -t Fabric1.4 -n fabric
生成的目录结构如下:
tree conf/chains/fabric
conf/chains/fabric
└── stub.toml # chain配置文件
命令执行成功会输出operator: connection type: Fabric1.4 path: conf/chains//fabric
,如果执行出错,请查看屏幕打印提示。
配置Fabric节点连接
- 拷贝证书
# 证书具体说明请参考《跨链接入》章节
cp ~/wecross/fabric/certs/chains/fabric/* conf/chains/fabric/
- 修改配置
vim conf/chains/fabric/stub.toml
相关配置项使用默认即可。
[fabricServices]
channelName = 'mychannel'
orgName = 'Org1'
mspId = 'Org1MSP'
orgUserName = 'fabric_admin'
orgUserAccountPath = 'classpath:accounts/fabric_admin'
ordererTlsCaFile = 'orderer-tlsca.crt'
ordererAddress = 'grpcs://localhost:7050'
[peers]
[peers.org1]
peerTlsCaFile = 'org1-tlsca.crt'
peerAddress = 'grpcs://localhost:7051'
[peers.org2]
peerTlsCaFile = 'org2-tlsca.crt'
peerAddress = 'grpcs://localhost:9051'
配置跨链资源
vim conf/chains/fabric/stub.toml
内容如下,fabric链中自带了一个名字为mycc
的chaincode,此处将mycc
配置为跨链资源,使其能够在WeCross网络中被调用。
[[resources]]
# name cannot be repeated
name = 'abac'
type = 'FABRIC_CONTRACT'
chainCodeName = 'mycc'
chainLanguage = "go"
peers=['org1','org2']
完整配置
此时已完成fabric
的连接配置,并注册了一个合约资源,最终的stub.toml
文件如下。参考此处获取更详尽的配置说明
[common]
name = 'fabric'
type = 'Fabric1.4'
[fabricServices]
channelName = 'mychannel'
orgName = 'Org1'
mspId = 'Org1MSP'
orgUserName = 'fabric_admin'
orgUserAccountPath = 'classpath:accounts/fabric_admin'
ordererTlsCaFile = 'orderer-tlsca.crt'
ordererAddress = 'grpcs://localhost:7050'
[peers]
[peers.org1]
peerTlsCaFile = 'org1-tlsca.crt'
peerAddress = 'grpcs://localhost:7051'
[peers.org2]
peerTlsCaFile = 'org2-tlsca.crt'
peerAddress = 'grpcs://localhost:9051'
# resources is a list
[[resources]]
# name cannot be repeated
name = 'abac'
type = 'FABRIC_CONTRACT'
chainCodeName = 'mycc'
chainLanguage = "go"
peers=['org1','org2']
启动路由
启动跨链路由加载配置好的跨链资源。
cd ~/wecross/routers-payment/127.0.0.1-8251-25501
# 若WeCross跨链路由未停止,需要先停止
bash stop.sh
# 重新启动
bash start.sh
检查日志,可看到刷出已加载的跨链资源,ctrl + c
退出。
tail -f logs/info.log |grep "active resources"
2020-04-24 20:30:30.444 [Thread-2] INFO WeCrossHost() - Current active resources: payment.bcos.HelloWeCross(remote), payment.fabric.abac(local)
2020-04-24 20:30:40.458 [Thread-2] INFO WeCrossHost() - Current active resources: payment.bcos.HelloWeCross(remote), payment.fabric.abac(local)
2020-04-24 20:30:50.469 [Thread-2] INFO WeCrossHost() - Current active resources: payment.bcos.HelloWeCross(remote), payment.fabric.abac(local)
调用跨链资源¶
至此,已搭建了如图所示的跨链网络,本节将用控制台调用跨链资源。开发者也可基于WeCross Java SDK开发自己的跨链应用。
启动控制台
控制台连接的是router-8250
。
cd ~/wecross/WeCross-Console
# 配置连接至 router-8250,默认已配置,直接保存退出
vim conf/application.toml
# 启动控制台
bash start.sh
查看资源
进入控制台,用listResources
命令查看WeCross跨连网络中的所有资源。可看到有两个资源:
- payment.bcos.HelloWeCross
- 对应于FISCO BCOS链上的HelloWeCross.sol合约
- payment.fabric.abac
- 对应于Fabric链上的abac.go合约
[WeCross]> listResources
path: payment.bcos.HelloWeCross, type: BCOS2.0, distance: 0
path: payment.fabric.abac, type: Fabric1.4, distance: 1
total: 2
查看账户
用listAccounts
命令查看WeCross Router上已存在的账户,操作资源时用相应账户进行操作。
[WeCross]> listAccounts
name: fabric_user1, type: Fabric1.4
name: bcos_user1, type: BCOS2.0
total: 2
操作资源:payment.bcos.HelloWeCross
- 读资源
- 命令:
call path 账户名 接口名 [参数列表]
- 示例:
call payment.bcos.HelloWeCross bcos_user1 get
- 命令:
# 调用HelloWeCross合约中的get接口
[WeCross]> call payment.bcos.HelloWeCross bcos_user1 get
Result: [Talk is cheap, Show me the code]
- 写资源
- 命令:
sendTransaction path 账户名 接口名 [参数列表]
- 示例:
sendTransaction payment.bcos.HelloWeCross bcos_user1 set Tom
- 命令:
# 调用HelloWeCross合约中的set接口
[WeCross]> sendTransaction payment.bcos.HelloWeCross bcos_user1 set Tom
Txhash : 0x21a412a1eb5239f2da9d40d09d11ce0107a5d82d113f1ecb315f2aa5bd3cc0cd
BlockNum: 2
Result : [Tom] // 将Tom给set进去
[WeCross]> call payment.bcos.HelloWeCross bcos_user1 get
Result: [Tom] // 再次get,Tom已set
操作资源:payment.fabric.abac
跨链资源是对各个不同链上资源的统一和抽象,因此操作的命令是保持一致的。
- 读资源
# 调用abac合约中的query接口
[WeCross]> call payment.fabric.abac fabric_user1 query a
Result: [90] // 初次query,a的值为90
- 写资源
# 调用abac合约中的invoke接口
[WeCross]> sendTransaction payment.fabric.abac fabric_user1 invoke a b 10
Txhash : db44b064c54d4dc97f01cdcd013cae219f7849c329f38ee102853344d8f0004d
BlockNum: 5
Result : []
[WeCross]> call payment.fabric.abac fabric_user1 query a
Result: [80] // 再次query,a的值变成80
# 退出当前控制台
[WeCross]> quit
恭喜,你已经完成了整个WeCross网络的体验。相信优秀的你已经对WeCross有了大致的了解。接下来,你可以基于WeCross Java SDK开发更多的跨连应用,通过统一的接口对各种链上的资源进行操作。
操作手册¶
配置文件¶
本节描述WeCross Router的配置。
配置结构¶
WeCross Router的配置位于conf
目录下,分为:
- 主配置(
wecross.toml
):配置Router连接等信息 - 链配置(
chains/<chain_name>/stub.toml
):配置连接至对应区块链、链上资源 - 账户配置(
accounts/<account_name>/account.toml
):配置可用于发交易账户的公私钥等信息
配置的目录结构如下:
# 这是conf目录下标准的配置结构,Router配置连接了两条链,分别叫bcos和fabric
.
├── log4j2.xml // 日志配置文件,无需更改
├── accounts
│ ├── bcos_user1
│ │ └── account.toml // 账户配置
│ └── fabric_user1
│ └── account.toml // 账户配置
├── chains
│ ├── bcos
│ │ └── stub.toml // 链配置
│ └── fabric
│ └── stub.toml // 链配置
└── wecross.toml // 主配置
主配置¶
主配置为 conf/wecross.toml
,配置示例如下:
[common]
zone = 'payment'
visible = true
[chains]
path = 'classpath:chains'
[rpc] # rpc ip & port
address = '127.0.0.1'
port = 8250
caCert = 'classpath:ca.crt'
sslCert = 'classpath:ssl.crt'
sslKey = 'classpath:ssl.key'
[p2p]
listenIP = '0.0.0.0'
listenPort = 25500
caCert = 'classpath:ca.crt'
sslCert = 'classpath:ssl.crt'
sslKey = 'classpath:ssl.key'
peers = ['127.0.0.1:25501']
threadNum = 500
#[[htlc]]
# selfPath = 'payment.bcos.htlc'
# account1 = 'bcos_default_account'
# counterpartyPath = 'payment.fabric.htlc'
# account2 = 'fabric_default_account'
跨链服务配置有五个配置项,分别是[common]
、[chains]
、[rpc]
、[p2p]
以及[test]
,各个配置项含义如下:
[common]
通用配置- zone:字符串;跨链分区标识符;通常一种跨链业务/应用为一个跨链分区
- visible:布尔;可见性;标明当前跨链分区下的资源是否对其他跨链分区可见
[chains]
链配置- path:字符串;链配置的根目录;WeCross从该目录下去加载各个链的配置
[rpc]
RPC配置- address:字符串;RPC服务监听地址,通常设置为本机IP地址
- port:整型;WeCross Router的RPC端口;WeCross Java SDK调用Router的端口
- caCert :字符串;WeCross Router根证书路径
- sslCert :字符串;WeCross Router证书路径
- sslKey :字符串;WeCross Router私钥路径
[p2p]
组网配置- listenIP:字符串;P2P服务监听地址;一般为’0.0.0.0’
- listenPort :整型;P2P服务监听端口;WeCross Router之间交换消息的端口
- caCert :字符串;WeCross Router根证书路径
- sslCert :字符串;WeCross Router证书路径
- sslKey :字符串;WeCross Router私钥路径
- peers:字符串数组;peer列表;需要互相连接的WeCross Router列表
- threadNum:p2p线程数,默认500
[htlc]
htlc配置(可选)- selfPath:本地配置的htlc合约资源路径
- account1:可调用本地配置的htlc合约的账户
- counterpartyPath:本地配置的htlc合约的对手方合约路径
- account2:可调用对手方htlc合约的账户
注:
- WeCross启动时会把
conf
目录指定为classpath,若配置项的路径中开头为classpath:
,则以conf
为相对目录。 [p2p]
配置项中的证书和私钥可以通过create_cert.sh脚本生成。- 若通过build_wecross.sh脚本生成的项目,那么已自动帮忙配置好了
wecross.toml
,包括P2P的配置,其中链配置的根目录默认为chains
。
链配置¶
链配置是Router连接每个区块链的配置:
- 指定链名
在chains/<chain_name>/stub.toml
目录下,通过目录名<chain_name>
指定链名。
- 区块链链接信息
在stub.toml
中配置与区块链交互所需链接的信息。
- 跨链资源
在stub.toml
中配置需要参与跨链的资源。
WeCross启动后会在wecross.toml
中所指定的chains
的根目录下去遍历所有的一级目录,目录名即为chain的名字,不同的目录代表不同的链,然后尝试读取每个目录下的stub.toml
文件。
目前WeCross支持的Stub类型包括:FISCO BCOS和Fabric。
配置FISCO BCOS
配置Fabric
请参考:Fabric 1.4插件配置
账户配置¶
在Router中配置账户,与链进行交互。配置操作包括:
- 指定账户名(
accounts/<account_name>/account.toml
下,通过目录名<account_name>
指定账户名) - 指定账户类型(用于BCOS、Fabric等,在
account.toml
中配置) - 指定账户其它信息(密钥等,在
account.toml
中配置)
WeCross启动后会在accounts
的根目录下去遍历所有的一级目录,目录名即为账户的名字,不同的目录代表不同的链,然后尝试读取每个目录下的account.toml
文件。
配置不同类型的账户,与不同类型的链进行操作。目前WeCross支持的类型包括:FISCO BCOS和Fabric。
配置FISCO BCOS
配置Fabric
请参考:Fabric 1.4账户配置
控制台¶
控制台是WeCross重要的交互式客户端工具,它通过WeCross-Java-SDK与WeCross 跨链代理建立连接,实现对跨链资源的读写访问请求。控制台拥有丰富的命令,包括获取跨链资源列表,查询资源状态,以及所有的JSON-RPC接口命令。
控制台命令¶
控制台命令可分为两类,普通命令和交互式命令。
普通命令¶
普通命令由两部分组成,即指令和指令相关的参数:
- 指令: 指令是执行的操作命令,包括获取跨链资源列表,查询资源状态指令等,其中部分指令调用JSON-RPC接口,因此与JSON-RPC接口同名。 使用提示: 指令可以使用tab键补全,并且支持按上下键显示历史输入指令。
- 指令相关的参数: 指令调用接口需要的参数,指令与参数以及参数与参数之间均用空格分隔。与JSON-RPC接口同名命令的输入参数和获取信息字段的详细解释参考JSON-RPC API。
常用命令链接¶
普通命令¶
- 状态查询
- listResources:查看资源列表
- detail:查看资源详情
- listAccounts:查看账户列表
- supportedStubs:查看连接的router支持接入的链类型
- 资源调用
- call:调用链上资源,用于查询,不触发出块
- sendTransaction:发交易,用于改变链上资源,触发出块
- 跨链转账
- newHTLCTransferProposal:创建转账提案
交互式命令¶
- 初始化资源实例: WeCross.getResource
- 访问资源UBI接口: [resource].[command]
快捷键¶
Ctrl+A
:光标移动到行首Ctrl+E
:光标移动到行尾Ctrl+R
:搜索输入的历史命令- ↑: 向前浏览历史命令
- ↓: 向后浏览历史命令
tab
: 自动补全,支持命令、变量名、资源名以及其它固定参数的补全
控制台响应¶
当发起一个控制台命令时,控制台会获取命令执行的结果,并且在终端展示执行结果,执行结果分为2类:
- 正确结果: 命令返回正确的执行结果,以字符串或是json的形式返回。
- 错误结果: 命令返回错误的执行结果,以字符串或是json的形式返回。
- 状态码: 控制台的命令调用JSON-RPC接口时,状态码参考这里。
控制台配置与运行¶
重要
前置条件:部署WeCross请参考 快速部署。
获取控制台¶
可通过脚本download_console.sh
获取控制台。
cd ~ && mkdir -p wecross && cd wecross
# 获取控制台
bash <(curl -sL https://github.com/WeBankFinTech/WeCross-Console/releases/download/resources/download_console.sh)
执行成功后,会生成WeCross-Console
目录,结构如下:
├── apps
│ └── wecross-console.jar # 控制台jar包
├── conf
│ ├── application-sample.toml # 配置示例文件
│ └── log4j2.xml # 日志配置文件
├── download_console.sh # 获取控制台脚本
├── lib # 相关依赖的jar包目录
├── logs # 日志文件
└── start.sh # 启动脚本
配置控制台¶
控制台配置文件为 conf/application-toml
,启动控制台前需配置
cd ~/wecross/WeCross-Console
# 拷贝配置sample
cp conf/application-sample.toml conf/application.toml
# 拷贝连接router所需的TLS证书,从生成的routers-payment/cert/sdk目录下拷贝
cp ~/wecross/routers-payment/cert/sdk/* conf/ # 包含:ca.crt、node.nodeid、ssl.crt、ssl.key
# 配置
vim conf/application.toml
配置与控制台r与某个router的连接
[connection]
server = '127.0.0.1:8250' # 对应router的ip和rpc端口
sslKey = 'classpath:ssl.key'
sslCert = 'classpath:ssl.crt'
caCert = 'classpath:ca.crt'
启动控制台¶
在WeCross已经开启的情况下,启动控制台
cd ~/wecross/WeCross-Console
bash start.sh
# 输出下述信息表明启动成功
=============================================================================================
Welcome to WeCross console(1.0.0-rc3)!
Type 'help' or 'h' for help. Type 'quit' or 'q' to quit console.
=============================================================================================
普通命令¶
以下所有跨链资源相关命令的执行结果以实际配置为准,此处只是示例。
help¶
输入help或者h,查看控制台所有的命令。
[WeCross]> help
---------------------------------------------------------------------------------------------
quit Quit console.
supportedStubs List supported stubs of WeCross router.
listAccounts List all accounts stored in WeCross router.
listLocalResources List local resources configured by WeCross server.
listResources List all resources including remote resources.
status Check if the resource exists.
detail Get resource information.
call Call constant method of smart contract.
sendTransaction Call non-constant method of smart contract.
genTimelock Generate two valid timelocks.
genSecretAndHash Generate a secret and its hash.
newHTLCTransferProposal Create a htlc transfer agreement.
checkTransferStatus Check htlc transfer status by hash.
WeCross.getResource Init resource by path and account name, and assign it to a custom variable.
[resource].[command] Equal to: command [path] [account name].
---------------------------------------------------------------------------------------------
注:
- help显示每条命令的含义是:命令 命令功能描述
- 查看具体命令的使用介绍说明,输入命令 -h或--help查看。例如:
[WeCross]> detail -h
---------------------------------------------------------------------------------------------
Get the resource information
Usage: detail [path]
---------------------------------------------------------------------------------------------
listAccounts¶
显示所有已配置的账户列表。
name: fabric_user1, type: Fabric1.4
name: fabric_default_account, type: Fabric1.4
name: bcos_user1, type: BCOS2.0
name: bcos_sender, type: BCOS2.0
name: bcos_default_account, type: BCOS2.0
total: 5
listLocalResources¶
显示router配置的跨链资源。
[WeCross]> listLocalResources
path: payment.bcos.htlc, type: BCOS2.0, distance: 0
path: payment.bcos.HelloWeCross, type: BCOS2.0, distance: 0
total: 2
listResources¶
查看WeCross跨链代理本地配置的跨链资源和所有的远程资源。
[WeCross]> listResources
path: payment.bcos.htlc, type: BCOS2.0, distance: 0
path: payment.bcos.HelloWeCross, type: BCOS2.0, distance: 0
path: payment.fabric.htlc, type: Fabric1.4, distance: 1
path: payment.fabric.abac, type: Fabric1.4, distance: 1
total: 4
status¶
查看跨链资源的状态,即是否存在于连接的router中。
参数:
- path:跨链资源标识。
[WeCross]> status payment.bcos.HelloWeCross
exists
detail¶
查看跨链资源的详细信息。
参数:
- path:跨链资源标识。
[WeCross]> detail payment.bcos.HelloWeCross
ResourceDetail{
path='payment.bcos.HelloWeCross',
distance=0',
stubType='BCOS2.0',
properties={
BCOS_PROPERTY_CHAIN_ID=1,
BCOS_PROPERTY_GROUP_ID=1,
HelloWeCross=0x708133d132372727ce3848a16d47ab4daf77698c
},
checksum='0xb452f3d12c91b6cd93e083a518d2ea2cffbcf3d8b971221a5224f07a3be5e41a'
}
[WeCross]> detail payment.fabric.abac
ResourceDetail{
path='payment.fabric.abac',
distance=1',
stubType='Fabric1.4',
properties={
PROPOSAL_WAIT_TIME=120000,
CHAINCODE_TYPE=GO_LANG,
CHANNEL_NAME=mychannel,
CHAINCODE_NAME=mycc
},
checksum='c77f0ac3ead48d106d357ffe0725b9761bd55d3e27edd8ce669ad8b470a27bc8'
}
call¶
调用智能合约的方法,不涉及状态的更改,不发交易。
参数:
- path:跨链资源标识。
- accountName:交易签名账户,router上配置的账户名(
listAccounts
命令可查询)。 - method:合约方法名。
- args:参数列表。
[WeCross]> call payment.bcos.HelloWeCross bcos_user1 get
Result: [Talk is cheap, Show me the code]
sendTransaction¶
调用智能合约的方法,会更改链上状态,需要发交易。
参数:
- path:跨链资源标识。
- accountName:交易签名账户,router上配置的账户名。
- method:合约方法名。
- args:参数列表。
[WeCross]> sendTransaction payment.bcos.HelloWeCross bcos_user1 set hello wecross
Txhash : 0x66f94d387df2b16bea26e6bcf037c23f0f13db28dc4734588de2d57a97051c54
BlockNum: 2219
Result : [hello, wecross]
genTimelock¶
跨链转账辅助命令,根据时间差生成两个合法的时间戳。
参数:
- interval:时间间隔
[WeCross]> genTimelock 300
timelock0: 1586917289
timelock1: 1586916989
genSecretAndHash¶
跨链转账辅助命令,生成一个秘密和它的哈希。
[WeCross]> genSecretAndHash
secret: afd1c0f9c2f8acc2c1ed839ef506e8e0d0b4636644a889f5aa8e65360420d2a9
hash : 66ebd11ec6cc289aebe8c0e24555b1e58a5191410043519960d26027f749c54f
newHTLCTransferProposal¶
新建一个基于哈希时间锁合约的跨链转账提案,该命令由两条链的资金转出方分别执行。
参数:
- path:跨链转账资源标识。
- accountName:资产转出者在router上配置的账户名。
- args:提案信息,包括两条链的转账信息。
- hash: 唯一标识,提案号,
- secret: 提案号的哈希原像
- role: 身份,发起方-true,参与方-false。发起方需要传入secret,参与方secret传null。
- sender0:发起方的资金转出者在对应链上的地址
- receiver0:发起方的资金接收者在对应链上的地址
- amount0:发起方的转出金额
- timelock0:发起方的超时时间
- sender1:参与方的资金转出者在对应链上的地址
- receiver1:参与方的资金接收者在对应链上的地址
- amount1:参与方的转出金额
- timelock1:参与方的超时时间,小于发起方的超时时间
[WeCross]> newHTLCTransferProposal payment.bcos.htlc bcos_sender 88b6cea9b5ece573c6c35cb3f1a2237bf380dfbbf9155b82d5816344cdac0185 null false Admin@org1.example.com User1@org1.example.com 200 2000010000 0x55f934bcbe1e9aef8337f5551142a442fdde781c 0x2b5ad5c4795c026514f8317c7a215e218dccd6cf 100 2000000000
Txhash: 0x244d302382d03985eebcc1f7d95d0d4eef7ff2b3d528fdf7c93effa94175e921
BlockNum: 2222
Result: [create a htlc transfer proposal successfully]
checkTransferStatus¶
根据提案号(Hash)查询htlc转账状态。
参数:
- path:跨链资源标识。
- accountName:交易签名账户,router上配置的账户名。
- method:合约方法名。
- hash:转账提案号。
[WeCross]> checkTransferStatus payment.bcos.htlc bcos_sender dcbdf73ee6fdbe6672142c7776c2d21ff7acc6f0d61975e83c3b396a364bee93
status: succeeded!
交互式命令¶
WeCross.getResource¶
WeCross控制台提供了一个资源类,通过方法getResource
来初始化一个跨链资源实例,并且赋值给一个变量。
这样调用同一个跨链资源的不同UBI接口时,不再需要每次都输入跨链资源标识。
# myResource 是自定义的变量名
[WeCross]> myResource = WeCross.getResource payment.bcos.HelloWeCross bcos_user1
# 还可以将跨链资源标识赋值给变量,通过变量名来初始化一个跨链资源实例
[WeCross]> path = payment.bcos.HelloWeCross
[WeCross]> myResource = WeCross.getResource path bcos_user1
[resource].[command]¶
当初始化一个跨链资源实例后,就可以通过.command
的方式,调用跨链资源的UBI接口。
# 输入变量名,通过tab键可以看到能够访问的所有命令
[WeCross]> myResource.
myResource.call myResource.status
myResource.detail myResource.sendTransaction
status¶
[WeCross]> myResource.status
exists
detail¶
[WeCross]> myResource.detail
ResourceDetail{
path='payment.bcos.HelloWeCross',
distance=0',
stubType='BCOS2.0',
properties={
BCOS_PROPERTY_CHAIN_ID=1,
BCOS_PROPERTY_GROUP_ID=1,
HelloWeCross=0x9bb68f32a63e70a4951d109f9566170f26d4bd46
},
checksum='0x888d067b77cbb04e299e675ee4b925fdfd60405241ec241e845b7e41692d53b1'
}
call¶
[WeCross]> myResource.call get
Result: [hello, wecross]
sendTransaction¶
[WeCross]> myResource.sendTransaction set hello world
Txhash : 0x616a55a7817f843d81f8c7b65449963fc2b7a07398b853829bf85b2e1261516f
BlockNum: 2224
Result : [hello, world]
脚本介绍¶
为了方便用户使用,WeCross提供了丰富的脚本,脚本位于WeCross跨链路由的根目录下(如:~/demo/routers-payment/127.0.0.1-8250-25500/
),本章节将对这些脚步做详细介绍。
启动脚本¶
start.sh
启动脚本start.sh
用于启动WeCross服务,启动过程中的完整信息记录在start.out中。
bash start.sh
成功输出:
Wecross start successfully
失败输出:
WeCross start failed
See logs/error.log for details
构建WeCross脚本¶
build_wecross.sh
生成WeCross跨链路由网络
Usage:
-n <zone id> [Required] set zone ID
-l <ip:rpc-port:p2p-port> [Optional] "ip:rpc-port:p2p-port" e.g:"127.0.0.1:8250:25500"
-f <ip list file> [Optional] split by line, every line should be "ip:rpc-port:p2p-port". eg "127.0.0.1:8250:25500"
-c <ca dir> [Optional] dir of existing ca
-o <output dir> [Optional] default <your pwd>
-z <generate tar packet> [Optional] default no
-T <enable test mode> [Optional] default no. Enable test resource.
-h call for help
e.g
bash build_wecross.sh -n payment -l 127.0.0.1:8250:25500
bash build_wecross.sh -n payment -f ipfile
-n
:指定跨链分区标识-l
:可选,指定生成一个跨链路由,与-f
二选一,单行,如:192.168.0.1:8250:25500
-f
:可选,指定生成多个跨链路由,与-l
二选一,多行,不可有空行,例如:
192.168.0.1:8250:25500
192.168.0.1:8251:25501
192.168.0.2:8252:25502
192.168.0.3:8253:25503
192.168.0.4:8254:25504
-c
:可选,指定跨链路由基于某个路径下的ca证书生成-o
:可选,指定跨链路由生成目录,默认wecross/
-z
:可选,若设置,则生成跨链路由的压缩包,方便拷贝至其它机器-T
:可选,若设置,生成的跨链路由开启测试资源-h
:可选,打印Usage
添加账户脚本¶
add_account.sh
脚本add_account.sh
用于在router中创建特定区块链的账户。
可通过-h查看帮助信息
Usage:
-t <type> [Required] type of account, BCOS2.0 or Fabric1.4
-n <name> [Required] name of account
-d <dir> [Optional] generated target_directory, default conf/accounts/
-h [Optional] Help
-t
:账户类型,按照插件选择,如BCOS2.0
,GM_BCOS2.0
或Fabric1.4
-n
:指定账户名,发交易时使用,用区分不同的账户-d
:账户目录,默认生成在conf/accounts
下
不同的链有不同的操作方法,具体操作请查看(操作后,请重启router,让router重启加载配置):
添加新接入链脚本¶
add_chains.sh
脚本add_chains.sh
用于在router中创建特定区块链的连接配置
Usage:
-t <type> [Required] type of chain, BCOS2.0 or Fabric1.4
-n <name> [Required] name of chain
-d <dir> [Optional] generated target_directory, default conf/stubs/
-h [Optional] Help
-t
:连接类型,按照插件选择,如BCOS2.0或Fabric1.4-n
:连接名,账户名称-d
:连接配置目录,默认生成在conf/chains/下
不同的链有不同的操作方法,具体操作请查看(操作后,请重启router,让router重启加载配置):
创建P2P证书脚本¶
create_cert.sh
创建P2P证书脚本create_cert.sh
用于创建P2P证书文件。WeCross Router之间通讯需要证书用于认证,只有具有相同ca.crt
根证书的WeCross Router直接才能建立连接。
可通过-h查看帮助信息:
Usage:
-c [Optional] generate ca certificate
-C <number> [Optional] the number of node certificate generated, work with '-n' opt, default: 1
-D <dir> [Optional] the ca certificate directory, work with '-n', default: './'
-d <dir> [Required] generated target_directory
-n [Optional] generate node certificate
-t [Optional] cert.cnf path, default: cert.cnf
-h [Optional] Help
e.g
bash create_cert.sh -c -d ./ca
bash create_cert.sh -n -D ./ca -d ./ca/node
bash create_cert.sh -n -D ./ca -d ./ca/node -C 10
c
: 生成ca证书,只有生成了ca证书,才能生成节点证书。C
:配合-n
,指定生成节点证书的数量。D
:配合-n
,指定ca证书路径。d
:指定输出目录。n
:生成节点证书。t
:指定cert.cnf
的路径
跨链接入¶
接入 FISCO BCOS 2.0¶
WeCross BCOS2 Stub 是 WeCross Router的插件,让Router具备接入FISCO-BCOS 2.0的能力。关于该插件包含下列方面内容:
- 跨链合约
- 插件安装
- 账户配置
- 插件配置
重要
FISCO-BCOS版本需要 >= v2.4.0
跨链合约¶
BCOS2 Stub的跨链合约接口需要满足下面格式
function funcName(string[] params) qualifier public returns(string[])
或者
function funcName() qualifier public returns(string[])
HelloWeCross
合约示例
pragma solidity ^0.4.24;
pragma experimental ABIEncoderV2;
contract HelloWeCross {
string[] ss = ["Talk is cheap", "Show me the code"];
function set(string[] memory _ss) public returns (string[] memory) {
ss = _ss;
return ss;
}
function getAndClear() public constant returns(string[] memory) {
string[] memory _ss = ss;
ss.length = 0;
return _ss;
}
function get() public constant returns(string[] memory) {
return ss;
}
}
插件安装¶
在生成router时,默认安装FISCO-BCOS stub插件,安装目录为router下的plugin
目录:
plugin/
|-- bcos2-stub-gm-xxxx.jar # 国密插件
|-- bcos2-stub-xxxx.jar # 非国密插件
└-- fabric-stub.jar
用户如有特殊需求,可以自行编译,替换plugin
目录下的插件。
手动安装¶
下载编译
git clone https://github.com/WeBankFinTech/WeCross-BCOS2-Stub.git
cd WeCross-BCOS2-Stub
bash gradlew build -x test
WeCross-BCOS2-Stub编译生成两个插件
- 国密插件
- 非国密插件
dist/apps
├── bcos2-stub-gm-xxxx.jar # 国密插件
└── bcos2-stub-xxxx.jar # 非国密插件
安装插件
cp dist/apps/* ~/wecross/routers-payment/127.0.0.1-8250-25500/plugin/
注:若router中配置了两个相同的插件,插件冲突,会导致router启动失败。
账户配置¶
WeCross中账户用于交易签名,BCOS2 Stub支持pem
和p12
两种格式文件。
配置路径¶
WeCross Router账户配置位于conf/accounts/
目录。每个账户使用单独目录配置,使用账户名称作为子目录名称,每个目录包含account.toml
配置文件以及配置文件中配置的私钥文件,私钥文件可以为pem
或者p12
格式。
// 示例
conf/accounts/
|-- bcos_pem
| |-- 0x5399e9ca7b444afb537a7a9de2762d17c3c7f63a.pem
| `-- account.toml
└-- bcos_p12
|-- 0x0ed9d10e1520a502a41115a4fc8b6e3edb201940.p12
└-- account.toml
上面的示例中配置了两个账户,账户名称分别为: bcos_pem、bcos_p12
配置格式¶
// account.toml
[account]
type = 'BCOS2.0'
accountFile = '0x15469c4af049c6441f6ef3f8d22d44547031ebea.p12'
password = '123456'
type
: 账户类型,GM_BCOS2.0
或者BCOS2.0
,GM_BCOS2.0
表示国密账户,BCOS2.0
表示非国密账户accountFile
: 私钥文件password
: p12文件密码,pem文件时忽略
配置步骤¶
在router目录下,用add_account.sh
直接生成账户即可,无需其他手动配置。
cd ~/wecross/routers-payment/127.0.0.1-8250-25500/
# 举例1:生成非国密账户,-t 指定使用BCOS2.0插件(非国密插件) -n 设置一个账户名
bash add_account.sh -t BCOS2.0 -n bcos_normal_user1
# 举例2:生成国密账户,-t 指定使用GM_BCOS2.0插件(国密插件) -n 设置一个账户名
bash add_account.sh -t GM_BCOS2.0 -n bcos_gm_user1
账户生成至conf/accounts
目录下
conf/accounts/
├── bcos_gm_user1
│ ├── account.key
│ └── account.toml
└── bcos_normal_user1
├── account.key
└── account.toml
插件配置¶
stub插件的配置文件为stub.toml
,作用:
- 配置资源信息
- 配置SDK连接信息,与链进行交互
配置路径¶
conf/chains/bcos/
|-- ca.crt
|-- sdk.crt
|-- sdk.key
└-- stub.toml
配置格式¶
stub插件的配置文件stub.toml
格式以及字段含义
[common] # 通用配置
name = 'bcos' # stub配置名称
type = 'BCOS2.0' # stub类型,`GM_BCOS2.0`或者`BCOS2.0`,`GM_BCOS2.0`国密类型,`BCOS2.0`非国密类型
[chain] # FISCO-BCOS 链配置
groupId = 1 # 连接FISCO-BCOS群组id,默认为1
chainId = 1 # 连接FISCO-BCOS链id,默认为1
[channelService] # FISCO-BCOS 配置
caCert = 'ca.crt' # 根证书
sslCert = 'sdk.crt' # sdk证书
sslKey = 'sdk.key' # sdk私钥
timeout = 5000 # SDK请求超时时间
connectionsStr = ['127.0.0.1:20200','127.0.0.2:20200'] # 连接列表
# [[resources]] 资源列表
[[resources]]
name = 'htlc' # 资源名称
type = 'BCOS_CONTRACT' # 资源类型,BCOS_CONTRACT
contractAddress = '0x7540601cce8b0802980f9ebf7aeee22bb4d73c22' # 合约地址
重要
- BCOS2 Stub当前只支持合约类型的资源
接入 Fabric 1.4¶
WeCross Fabric Stub 是 WeCross Router的插件,让Router具备接入Fabric 1.4的链的能力。其要点包括:
- 插件安装
- 接入配置:用于接入相应的Fabric 1.4链
- 账户配置:用于用相应账户发交易
插件安装¶
在生成router时,默认安装Fabric 1.4插件,安装目录为router下的plugin
目录:
cd ~/wecross/routers-payment/127.0.0.1-8251-25501/
tree plugin/
plugin/
└── fabric1-stub-XXXXX.jar
用户如有特殊需求,可以自行编译,替换plugin
目录下的插件。
手动安装¶
下载编译
git clone https://github.com/WeBankFinTech/WeCross-Fabric1-Stub.git
cd WeCross-Fabric1-Stub
bash gradlew assemble # 在 dist/apps/下生成fabric1-stub-XXXXX.jar
安装插件
cp dist/apps/fabric1-stub-XXXXX.jar ~/wecross/routers-payment/127.0.0.1-8250-25500/plugin/
注:若router中配置了两个相同的插件,插件冲突,会导致router启动失败。
账户配置¶
在router中配置Fabric账户,用户可在sdk中指定router用相应的账号发交易。
完整配置¶
配置完成的账户如下,在accounts
目录中
accounts/ # router的账户目录,所有账户的文件夹放在此目录下
└── fabric_admin # 目录名即为此账户名,SDK发交易时,指定的即为处的账户名
├── account.toml # 账户配置文件
├── user.crt # Fabric的用户证书
└── user.key # Fabric的用户私钥
其中 account.toml
为账户配置文件
[account]
type = 'Fabric1.4' # 采用插件的名字
mspid = 'Org1MSP' # 账户对应机构的MSP ID
keystore = 'user.key' # 账户私钥文件名字,指向与此文件相同目录下的私钥文件
signcert = 'user.crt' # 账户证书名字,指向与此文件相同目录下的证书文件
配置步骤¶
生成配置文件
为router生成某个账户的配置,在router目录下执行
cd ~/wecross/routers-payment/127.0.0.1-8251-25501/
# 举例1:生成名字为fabric_admin的账户配置 -t 指定使用Fabric1.4插件生成 -n 设置一个账户名
bash add_account.sh -t Fabric1.4 -n fabric_admin
# 举例2:生成名字为fabric_user1的账户配置 -t 指定使用Fabric1.4插件生成 -n 设置一个账户名
bash add_account.sh -t Fabric1.4 -n fabric_user1
生成后,conf/accounts
目录下出现对应名字的账户目录,接下来需将相关账户文件拷贝入目录中。
拷贝账户文件
以fabric-sample/first-network
的crypto-config
为例,配置其中一个账户即可
- 若配置 Org1 的 Admin
# 拷贝用户私钥,命名为 user.key
cp ~/demo/fabric/fabric-sample/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/*_sk accounts/fabric_admin/user.key
# 拷贝用户证书,命名为 user.crt
cp ~/demo/fabric/fabric-sample/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/*.pem accounts/fabric_admin/user.crt
- 若配置 Org1的 User1
# 拷贝用户私钥,命名为 user.key
cp ~/demo/fabric/fabric-sample/first-network/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/*_sk accounts/fabric_user1/user.key
# 拷贝用户证书,命名为 user.crt
cp ~/demo/fabric/fabric-sample/first-network/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/*.pem accounts/fabric_user1/user.crt
编辑配置文件
编辑 account.toml
vim conf/accounts/<account_name>/account.toml
内容为
[account]
type = 'Fabric1.4' # 采用插件的名字
mspid = 'Org1MSP' # 账户对应机构的MSP ID
keystore = 'user.key' # 账户私钥文件名字,指向与此文件相同目录下的私钥文件
signcert = 'user.crt' # 账户证书名字,指向与此文件相同目录下的证书文件
插件配置¶
在router中配置需接入的链,访问链上资源。
完整配置¶
配置完成如下,在chains
目录中
chains # router的stub的配置目录,所有的stub都在此目录下配置
└── fabric # 此链的名字,名字可任意指定,与链类型无关
├── orderer-tlsca.crt # orderer证书
├── org1-tlsca.crt # 需要连接的peer的证书1,有则配
├── org2-tlsca.crt # 需要连接的peer的证书2,有则配
└── stub.toml # stub配置文件
其中,stub.toml
为接入的链的配置文件
[common]
name = 'fabric'
type = 'Fabric1.4'
[fabricServices]
channelName = 'mychannel'
orgName = 'Org1'
mspId = 'Org1MSP'
orgUserName = 'fabric_admin'
orgUserAccountPath = 'classpath:accounts/fabric_admin'
ordererTlsCaFile = 'orderer-tlsca.crt'
ordererAddress = 'grpcs://localhost:7050'
[peers]
[peers.org1]
peerTlsCaFile = 'org1-tlsca.crt'
peerAddress = 'grpcs://localhost:7051'
[peers.org2]
peerTlsCaFile = 'org2-tlsca.crt'
peerAddress = 'grpcs://localhost:9051'
# resources is a list
[[resources]]
# name cannot be repeated
name = 'abac'
type = 'FABRIC_CONTRACT'
chainCodeName = 'mycc'
chainLanguage = "go"
peers=['org1','org2']
配置步骤¶
生成配置文件
cd ~/wecross/routers-payment/127.0.0.1-8251-25501
bash add_chain.sh -t Fabric1.4 -n fabric # -t 链类型,-n 指定链名字
# 查看生成目录
tree conf/chains/fabric
生成的目录结构如下:
conf/chains/fabric
└── stub.toml # chain配置文件
拷贝链证书
以fabric-sample/first-network
的crypto-config
为例
# 拷贝 orderer证书
cp ~/demo/fabric/fabric-sample/first-network/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem conf/chains/fabric/orderer-tlsca.crt
# 拷贝 peer.org1 证书
cp ~/demo/fabric/fabric-sample/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt conf/chains/fabric/org1-tlsca.crt
# 拷贝 peer.org2 证书
cp ~/demo/fabric/fabric-sample/first-network/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt conf/chains/fabric/org2-tlsca.crt
编辑配置文件
vim conf/chains/fabric/stub.toml
- 基础配置
[common]
name = 'fabric' # 指定的连接的链的名字,对应path中的{zone}/{chain}/{resource}的chain
type = 'Fabric1.4' # 采用插件的名字
- 配置链
[fabricServices]
channelName = 'mychannel'
orgName = 'Org1' # 指定一个机构机构名
mspId = 'Org1MSP' # 相应的机构MSP ID
orgUserName = 'fabric_admin' # 机构的 admin 账户名
orgUserAccountPath = 'classpath:accounts/fabric_admin'# 账户配置步骤已配置好的admin账户目录
ordererTlsCaFile = 'orderer-tlsca.crt' # orderer证书名字,指向与此配置文件相同目录下的证书
ordererAddress = 'grpcs://localhost:7050' # orderer的url
[peers] # peers列表
[peers.org1]
peerTlsCaFile = 'org1-tlsca.crt' # peer.org1证书名,指向与此配置文件相同目录下的证书
peerAddress = 'grpcs://localhost:7051' # peer.org1的URL
[peers.org2]
peerTlsCaFile = 'org2-tlsca.crt' # peer.org2证书名,指向与此配置文件相同目录下的证书
peerAddress = 'grpcs://localhost:9051' # peer.org2的URL
- 配置跨链资源
# resources is a list
[[resources]]
# name cannot be repeated
name = 'HelloWeCross' # 资源名,对应path中的{zone}/{chain}/{resource}中的resource
type = 'FABRIC_CONTRACT' # 合约类型,默认即可
chainCodeName = 'mycc' # chaincode名字
chainLanguage = "go" # chaincode编程语言
peers=['org1','org2'] # 此chaincode对应的peers列表,在[peers]中需
[[resources]] # 另一个资源的配置
name = 'HelloWorld'
type = 'FABRIC_CONTRACT'
chainCodeName = 'mygg'
chainLanguage = "go"
peers=['org1','org2']
开发手册¶
跨链SDK开发应用¶
WeCross router向外部暴露了所有的UBI接口,开发者可以通过SDK实现这些接口的快速调用。
Java应用引入SDK¶
通过gradle或maven引入SDK到java应用
gradle:
compile ('com.webank:wecross-java-sdk:1.0.0-rc3')
maven:
<dependency>
<groupId>com.webank</groupId>
<artifactId>wecross-java-sdk</artifactId>
<version>1.0.0-rc3</version>
</dependency>
使用方法¶
示例代码如下:
try {
// 初始化 Service
WeCrossRPCService weCrossRPCService = new WeCrossRPCService();
// 初始化Resource
WeCrossRPC weCrossRPC = WeCrossRPCFactory.build(weCrossRPCService);
Resource resource = ResourceFactory.build(weCrossRPC, "payment.bcos.HelloWecross", "bcos_user1"); // RPC服务,资源的path,用哪个账户名操作此resource
// 用初始化好的resource进行调用
String[] callRet = resource.call("get"); // call 接口函数名 参数列表
System.out.println((Arrays.toString(callRet)));
// 用初始化好的resource进行调用
String[] sendTransactionRet = resource.sendTransaction("set", "Tom"); // sendTransaction 接口函数名 参数列表
System.out.println((Arrays.toString(sendTransactionRet)));
} catch (WeCrossSDKException e) {
System.out.println("Error: " + e);
}
WeCross Java SDK API¶
SDK API分为两大类型,一种是RPC接口,一种是资源接口,其中资源接口是对RPC接口进行了封装。
API列表¶
RPC接口
RemoteCall
supportedStubs(); RemoteCall
listAccounts(); RemoteCall
listResources(Boolean ignoreRemote); RemoteCall
detail(String path); RemoteCall
call(Request request); RemoteCall
call(String path, String accountName, String method, String… args); RemoteCall
sendTransaction(Request request); RemoteCall
sendTransaction(String path, String accountName, String method, String… args); 资源接口
Resource ResourceFactory.build(WeCrossRPC weCrossRPC, String path, String accountName)
boolean isActive();
ResourceDetail detail();
TransactionResponse call(Request
request); String[] call(String method);
String[] call(String method, String… args);
TransactionResponse sendTransaction(Request
request); String[] sendTransaction(String method);
String[] sendTransaction(String method, String… args);
RPC接口解析¶
supportedStubs¶
显示router当前支持的插件列表。
参数¶
- 无
返回值¶
StubResponse
- 响应包version
:String
- 版本号errorCode
:int
- 状态码message
:String
- 错误消息data
:Stubs
- 支持的插件列表
java示例¶
// 初始化RPC实例
WeCrossRPCService weCrossRPCService = new WeCrossRPCService();
WeCrossRPC weCrossRPC = WeCrossRPCFactory.build(weCrossRPCService);
// 调用RPC接口,目前只支持同步调用
StubResponse response = weCrossRPC.supportedStubs().send();
注 - 之后的java示例,会省去初始化WeCrossRPC的步骤。
listAccounts¶
显示所有已配置的账户列表。
参数¶
- 无
返回值¶
AccountResponse
- 响应包version
:String
- 版本号errorCode
:int
- 状态码message
:String
- 错误消息data
:Accounts
- 配置的账户列表
java示例¶
AccountResponse response = weCrossRPC.listAccounts().send();
listResources¶
显示router配置的跨链资源。
参数¶
ignoreRemote
:Boolean
- 是否忽略远程资源
返回值¶
ResourceResponse
- 响应包version
:String
- 版本号errorCode
:int
- 状态码message
:String
- 错误消息data
:Resources
- 配置的资源列表
java示例¶
ResourceResponse response = weCrossRPC.listResources(true).send();
detail¶
获取资源详情。
参数¶
path
:String
- 跨链资源标识
返回值¶
ResourceDetailResponse
- 响应包version
:String
- 版本号errorCode
:int
- 状态码message
:String
- 错误消息data
:ResourceDetail
- 资源详情
java示例¶
ResourceDetailResponse response = weCrossRPC.detail("payment.bcos.HelloWeCross").send();
call(无参数)¶
调用智能合约,不更改链状态,不发交易。
参数¶
path
:String
- 跨链资源标识accountName
:String
- 账户名method
:String
- 调用的方法
返回值¶
TransactionResponse
- 响应包version
:String
- 版本号errorCode
:int
- 状态码message
:String
- 错误消息data
:Receipt
- 调用结果
java示例¶
TransactionResponse transactionResponse =
weCrossRPC
.call(
"payment.bcos.HelloWeCross","get")
.send();
call(带参数)¶
调用智能合约,不更改链状态,不发交易。
参数¶
path
:String
- 跨链资源标识accountName
:String
- 账户名method
:String
- 调用的方法args
:String...
- 可变参数列表
返回值¶
TransactionResponse
- 响应包version
:String
- 版本号errorCode
:int
- 状态码message
:String
- 错误消息data
:Receipt
- 调用结果
java示例¶
TransactionResponse transactionResponse =
weCrossRPC
.call(
"payment.bcos.HelloWeCross","get","key")
.send();
sendTransaction(无参数)¶
调用智能合约,会改变链状态,发交易。
参数¶
path
:String
- 跨链资源标识accountName
:String
- 账户名method
:String
- 调用的方法
返回值¶
TransactionResponse
- 响应包version
:String
- 版本号errorCode
:int
- 状态码message
:String
- 错误消息data
:Receipt
- 调用结果
java示例¶
TransactionResponse transactionResponse =
weCrossRPC
.sendTransaction(
"payment.bcos.HelloWeCross","set")
.send();
sendTransaction(带参数)¶
调用智能合约,会改变链状态,发交易。
参数¶
path
:String
- 跨链资源标识accountName
:String
- 账户名method
:String
- 调用的方法args
:String...
- 可变参数列表
返回值¶
TransactionResponse
- 响应包version
:String
- 版本号errorCode
:int
- 状态码message
:String
- 错误消息data
:Receipt
- 调用结果
java示例¶
TransactionResponse transactionResponse =
weCrossRPC
.call(
"payment.bcos.HelloWeCross","set","value")
.send();
资源接口解析¶
ResourceFactory.build¶
初始化一个跨链资源
参数¶
weCrossRPC
:WeCrossRPC
- RPC实例path
:String
- 跨链资源标识accountName
:String
- 账户名
返回值¶
Resource
- 跨链资源实例
java示例¶
// 初始化RPC实例
WeCrossRPCService weCrossRPCService = new WeCrossRPCService();
WeCrossRPC weCrossRPC = WeCrossRPCFactory.build(weCrossRPCService);
// 初始化资源实例
Resource resource = ResourceFactory.build(weCrossRPC, path, accountName);
注 - 之后的java示例,会省去初始化Resource的步骤。
isActive¶
获取资源状态,true
:可达,false
:不可达。
参数¶
- 无
返回值¶
bool
- 资源状态
java示例¶
bool status = resource.isActive();
call¶
调用智能合约,不更改链状态,不发交易。
参数¶
request
:Request<TransactionRequest>
- 请求体
返回值¶
TransactionResponse
- 响应包version
:String
- 版本号errorCode
:int
- 状态码message
:String
- 错误消息data
:Receipt
- 调用结果
java示例¶
TransactionResponse transactionResponse = resource.call(request);
call(无参数)¶
调用智能合约,不更改链状态,不发交易。
参数¶
method
:String
- 调用的方法
返回值¶
String[]
- 调用结果
java示例¶
String[] result = resource.call("get");
call(带参数)¶
调用智能合约,不更改链状态,不发交易。
参数¶
method
:String
- 调用的方法args
:String...
- 可变参数列表
返回值¶
String[]
- 调用结果
java示例¶
String[] result = resource.call("get", "key");
sendTransaction¶
调用智能合约,会改变链状态,发交易。
参数¶
request
:Request<TransactionRequest>
- 请求体
返回值¶
TransactionResponse
- 响应包version
:String
- 版本号errorCode
:int
- 状态码message
:String
- 错误消息data
:Receipt
- 调用结果
java示例¶
TransactionResponse transactionResponse = resource.sendTransaction(request);
RPC状态码¶
当一个RPC调用遇到错误时,返回的响应对象必须包含error错误结果字段,该字段有下列成员参数:
- errorCode: 使用数值表示该异常的错误类型,必须为整数。
- message: 对该错误的简单描述字符串。
标准状态码及其对应的含义如下:
code | 含义 |
---|---|
0 | 执行成功 |
10100 | 内部错误 |
10201 | 版本错误 |
10202 | 资源标识错误 |
10203 | 资源不存在 |
10205 | 请求解码错误 |
10301 | htlc错误 |
2000x | 内部错误,结合message查看错误原因 |
5xxxx | 插件内错误,结合message查看错误原因 |
WeCross Stub插件开发¶
本章内容介绍区块链接入WeCross的完整开发流程,用户可以根据本教程实现一个WeCross区块链Stub
插件,通过该插件接入WeCross。
注解
- Java编程语言
WeCross使用Java实现,接入的区块链需要支持Java版本的SDK,要求开发人员具备Java开发能力。
- Gradle构建工具
WeCross组件目前使用Gradle进行构建,因此假定用户能够使用Gradle,maven能达到相同的效果,用户可以自行探索。
创建Gradle项目¶
Gradle依赖分类
- Stub API定义
- Java SDK,区块链Java版的SDK
- 其他依赖,例如:toml解析工具
// Gradle 依赖示例
dependencies {
// Stub接口定义Jar
implementation 'com.webank:wecross-java-stub:1.0.0-rc3'
// BCOS JavaSDK
implementation 'org.fisco-bcos:web3sdk:2.4.0'
// toml文件解析
implementation
'com.moandjiezana.toml:toml4j:0.7.2'
// 其他依赖
}
新建Gradle工程,并且在build.gradle
中添加依赖。
Gradle配置参考: WeCross-BCOS-Stub build.gradle
核心组件¶
Stub
插件需要实现的组件接口:
- StubFactory: 创建其他组件
- Account: 账户,用于交易签名
- Connection: 与区块链交互
- Driver: 区块链数据的编解码
StubFactory¶
StubFactory功能
- 添加
@Stub
注解,指定插件类型 - 提供Account、Connection、Driver实例化入口
只有添加@Stub注解的插件才能被Wecross Router识别加载!
StubFactory
接口定义
public interface StubFactory {
/** 创建Driver对象 */
public Driver newDriver();
/** 解析Connection配置stub.toml,创建Connection对象 */
public Connection newConnection(String path);
/** 解析Account配置account.toml,创建Account对象 */
public Account newAccount(String name, String path);
}
BCOS Stub示例:
/** @Stub注解,插件类型: BCOS2.0 */
@Stub("BCOS2.0")
public class BCOSStubFactory implements StubFactory {
@Override
public Driver newDriver() {
// 创建返回BCOSDriver对象
}
@Override
public Connection newConnection(String path) {
// 解析stub.toml配置, 创建返回BCOSConnection对象
}
@Override
public Account newAccount(String name, String path) {
// 解析account.toml账户配置,创建返回BCOSAccount对象
}
}
Account¶
Account
包含账户私钥,用于交易签名。
接口定义
public interface Account {
/** 账户名称 */
String getName();
/** 账户类型 */
String getType();
/** 账户公钥 */
String getIdentity();
}
Account由StubFactory对象newAccount
接口创建,用户需要解析配置生成Account对象
Account newAccount(String name, String path)
- name: 账户名称
- path: 配置文件
account.toml
所在目录路径
账户配置文件位于conf/accounts/
目录,可以配置多个账户,每个账户置于单独的子目录。
# 目录结构, conf/accounts/账户名称/
conf/accounts
└── bcos # 账户名称: bcos
├── 0x4c9e341a015ce8200060a028ce45dfea8bf33e15.pem # BCOS私钥文件
└── account.toml # account.toml配置文件
# account.toml内容
[account]
type = "BCOS2.0" # 必须项,账户类型,与插件@Stub注解定义的类型保持一致
accountFile = '0x4c9e341a015ce8200060a028ce45dfea8bf33e15.pem' # 配置的私钥文件名称
account.toml
解析流程可以参考BCOS Stub account.toml解析
BCOS Stub示例
public class BCOSAccount implements Account {
/** 名称 */
private final String name;
/** 类型 */
private final String type;
/** 公钥 */
private final String publicKey;
/** BCOS私钥对象,交易签名,加载配置的私钥文件生成 */
private final Credentials credentials;
public Credentials getCredentials() {
return credentials;
}
/** 其他接口 */
}
Connection¶
Connection用于
- 为Driver提供统一发送接口,与区块链交互
- 获取配置的资源列表,资源在Connection初始化时从配置文件加载
接口定义
public interface Connection {
/** 发送接口请求给区块链 */
Response send(Request request);
/** 获取资源列表,资源列表在stub.toml文件配置 */
List<ResourceInfo> getResources();
}
接口列表
- getResources
获取资源列表,资源在Connection初始化时加载,表示Stub可以访问的区块链资源。
- send
提供统一的发送请求接口给Driver使用,Driver设置请求类型并将参数序列化生成Request,调用send接口,返回Response对象,Response包含返回值、错误信息以及返回内容。
/** Request请求对象,包含请求类型与请求内容 */
public class Request {
/** 请求类型,用户自定义,区分不同的区块链请求 */
private int type;
/** 请求内容,序列化的请求参数,用户自定义序列化方式 */
private byte[] data;
/** 请求资源 */
private ResourceInfo resourceInfo;
}
/** Response返回值对象,包含错误码、错误描述以及返回内容 */
public class Response {
/** 返回状态 */
private int errorCode;
/** 返回错误描述 */
private String errorMessage;
/** 返回内容,序列化的返回参数,可以反序列化为返回对象 */
private byte[] data;
}
/** 资源对象 */
public class ResourceInfo {
/** 资源名称 */
private String name;
/** 资源类型,用户自定义 */
private String stubType;
/** 额外属性,用户自定义 */
private Map<Object, Object> properties = new HashMap<Object, Object>();
}
Connection由StubFactory对象newConnection
接口创建,解析配置生成Connection对象
Connnection newConnection(String path)
- path: 配置文件
stub.toml
所在目录路径
- path: 配置文件
插件配置stub.toml
- 通用配置:插件名称、类型
- SDK配置:初始化JavaSDK,与区块链交互
- 资源列表:区块链可以访问的资源列表
插件配置默认位于chains/
目录,可以配置多个stub,每个stub位于单独的子目录。
# 目录结构, conf/chains/stub名称/
conf/chains/
└── bcos # stub名称: bcos
└── stub.toml # stub.toml配置文件
# 其他文件列表,比如:证书文件
stub.toml
解析流程可以参考BCOS Stub stub.toml解析
BCOS示例
/** Request type定义,用户自定义 */
public class BCOSRequestType {
// call
public static final int CALL = 1000;
// sendTransaction
public static final int SEND_TRANSACTION = 1001;
// 获取区块高度
public static final int GET_BLOCK_NUMBER = 1002;
// 获取BlockHeader
public static final int GET_BLOCK_HEADER = 1003;
// 获取交易Merkle证明
public static final int GET_TRANSACTION_PROOF = 1004;
}
public class BCOSConnection implements Connection {
/** BCOS SDK对象,调用区块链接口 */
private final Web3jWrapper web3jWrapper;
/** 为Driver提供统一发送接口,根据不同请求类型分别与区块链完成交互 */
@Override
public Response send(Request request) {
switch (request.getType()) {
/** call请求 */
case BCOSRequestType.CALL:
/** handle call request */
/** sendTransaction请求 */
case BCOSRequestType.SEND_TRANSACTION:
/** handle sendTransaction request */
/** 获取区块头 */
case BCOSRequestType.GET_BLOCK_HEADER:
/** handle getBlockeHeader request */
/** 获取块高 */
case BCOSRequestType.GET_BLOCK_NUMBER:
/** handle getBlockNumber request */
/** 获取交易Merkle证明 */
case BCOSRequestType.GET_TRANSACTION_PROOF:
/** handle getTransactionProof request */
default:
/** unrecognized request type */
}
}
/** 获取资源列表 */
@Override
public List<ResourceInfo> getResources() {
return resourceInfoList;
}
}
BCOS stub.toml示例
[common] # 通用配置
name = 'bcos' # 名称,必须项
type = 'BCOS2.0' # 必须项,插件类型,与插件@Stub注解定义的类型保持一致
[chain] # BCOS链属性配置
groupId = 1 # default 1
chainId = 1 # default 1
[channelService] # BCOS JavaSDK配置
caCert = 'ca.crt'
sslCert = 'sdk.crt'
sslKey = 'sdk.key'
timeout = 300000 # ms, default 60000ms
connectionsStr = ['127.0.0.1:20200', '127.0.0.1:20201', '127.0.0.1:20202']
[[resources]] # 资源配置列表
name = 'HelloWeCross' # 资源名称
type = 'BCOS_CONTRACT' # 资源类型,BCOS合约
contractAddress = '0x8827cca7f0f38b861b62dae6d711efe92a1e3602' # 合约地址
Driver¶
Driver是Stub与WeCross Router交互的入口,用途包括:
- 发送交易
- 编解码交易
- 编解码区块
- 验证交易
- 其他功能
接口定义
public interface Driver {
/** call或者sendTransaction请求,返回为true,其他类型返回false */
public boolean isTransaction(Request request);
/** 解码BlockHeader数据 */
public BlockHeader decodeBlockHeader(byte[] data);
/** 获取区块链当前块高 */
public long getBlockNumber(Connection connection);
/** 获取Block Header */
public byte[] getBlockHeader(long blockNumber, Connection connection);
/** 解析交易请求,请求可能为call或者sendTransaction */
public TransactionContext<TransactionRequest> decodeTransactionRequest(byte[] data);
/** 调用合约,查询请求 */
public TransactionResponse call(
TransactionContext<TransactionRequest> request, Connection connection);
/** 调用合约,交易请求 */
public TransactionResponse sendTransaction(
TransactionContext<TransactionRequest> request, Connection connection);
/** 获取交易,并且对交易进行验证 */
public VerifiedTransaction getVerifiedTransaction(
String transactionHash,
long blockNumber,
BlockHeaderManager blockHeaderManager,
Connection connection);
}
接口列表
isTransaction 是否为请求交易
- 参数列表:
- Request request: 请求对象
- 返回值:
- request为call或者sendTransaction请求返回true,否则返回false
- 参数列表:
getBlockNumber 获取当前区块高度
- 参数列表:
- Connection connection: Connection对象,发送请求
- 返回值
- 区块高度,负值表示获取区块高度失败
- 参数列表:
getBlockHeader 获取区块头数据,区块头为序列化的二进制数据
- 参数列表:
- long blockNumber: 块高
- Connection connection: Connection对象,发送请求
- 返回值
- 序列化的区块头数据,返回null表示获取区块头数据失败,可以使用decodeBlockHeader获取区块头对象
- 参数列表:
decodeBlockHeader 解析区块头数据,返回区块头对象
参数列表:
- byte[] data: 序列化的区块头数据
返回值
区块头BlockHeader对象,返回null表示解析区块头数据失败
区块头对象 public class BlockHeader { /** 区块高度 */ private long number; /** 上一个区块hash */ private String prevHash; /** 区块hash */ private String hash; /** 状态根,验证状态 */ private String stateRoot; /** 交易根,验证区块交易 */ private String transactionRoot; /** 交易回执根,验证区块交易回执 */ private String receiptRoot; }
call、sendTransaction
call
与sendTransaction
接口类似,前者用于查询状态,后者发送交易,修改区块链状态参数列表
- TransactionContext
request: 请求上下文,获取构造交易需要的数据,构造交易 - Connection connection: Connection对象,发送请求
- TransactionContext
返回值
- TransactionResponse: 返回对象
注意:
sendTransaction
接口要对返回交易进行验证,各个区块链的验证方式有所不同,BCOS采用Merkle证明的方式对交易及交易回执进行验证// 请求对象 public class TransactionRequest { /** 接口 */ private String method; /** 参数 */ private String[] args; } // 返回对象 public class TransactionResponse { // 返回状态,0表示成功,其他表示错误码 private Integer errorCode; // 错误信息 private String errorMessage; // 交易hash,sendTransaction时有效 private String hash; // 区块高度,交易所在的区块的块高,sendTransaction时有效 private long blockNumber; // 返回结果 private String[] result; } // 交易请求上下文参数,获取构造交易需要的参数 public class TransactionContext<TransactionRequest> { // 交易请求 private TransactionRequest data; // 账户,用于交易签名 private Account account; // 请求资源,用于获取资源相关信息 private ResourceInfo resourceInfo; // 区块头管理器,获取区块头信息 private BlockHeaderManager blockHeaderManager; } // 区块头管理器 public interface BlockHeaderManager { // 获取当前块高 public long getBlockNumber(); // 获取区块头,阻塞操作 public byte[] getBlockHeader(long blockNumber); }
getVerifiedTransaction 根据哈希和块高查询交易并校验交易,返回交易的请求与返回对象,校验交易方式与sendTransaction接口校验交易方式保持一致。
参数列表
- String transactionHash: 交易hash
- long blockNumber: 交易所在区块高度
- BlockHeaderManager blockHeaderManager: 区块头管理器,获取区块头
- Connection connection: 发送请求
返回值
VerifiedTransaction对象
public class VerifiedTransaction { /** 交易所在块高 */ private long blockNumber; /** 交易hash */ private String transactionHash; /** 交易调用的合约地址 */ private String realAddress; /** 交易请求参数 */ private TransactionRequest transactionRequest; /** 交易返回 */ private TransactionResponse transactionResponse; }
BCOS示例
这里给个完整的BCOS Stub发送交易的处理流程,说明Driver与Connection的协作,以及在BCOS中如何进行交易验证。
- BCOSDriver
@Override
public TransactionResponse sendTransaction(
TransactionContext<TransactionRequest> request, Connection connection) {
TransactionResponse response = new TransactionResponse();
try {
ResourceInfo resourceInfo = request.getResourceInfo();
/** 合约的额外属性,BCOS构造交易需要这些参数,参考BCOS Stub.toml配置 */
Map<Object, Object> properties = resourceInfo.getProperties();
/** 获取合约地址 */
String contractAddress = (String) properties.get(resourceInfo.getName());
/** 获取群组Id */
Integer groupId = (Integer) properties.get(BCOSConstant.BCOS_RESOURCEINFO_GROUP_ID);
/** 获取链Id */
Integer chainId = (Integer) properties.get(BCOSConstant.BCOS_RESOURCEINFO_CHAIN_ID);
/** 获取块高 */
long blockNumber = request.getBlockHeaderManager().getBlockNumber();
BCOSAccount bcosAccount = (BCOSAccount) request.getAccount();
/** 获取私钥 参考account.toml配置 */
Credentials credentials = bcosAccount.getCredentials();
/** 交易签名,使用credentials对构造的交易进行签名 */
String signTx =
SignTransaction.sign(
credentials,
contractAddress,
BigInteger.valueOf(groupId),
BigInteger.valueOf(chainId),
BigInteger.valueOf(blockNumber),
FunctionEncoder.encode(function));
// 构造Request参数
TransactionParams transaction = new TransactionParams(request.getData(), signTx);
Request req = new Request();
/** Request类型 SEND_TRANSACTION */
req.setType(BCOSRequestType.SEND_TRANSACTION);
/** 参数JSON序列化 */
req.setData(objectMapper.writeValueAsBytes(transaction));
/** Connection send发送请求 */
Response resp = connection.send(req);
if (resp.getErrorCode() != BCOSStatusCode.Success) {
/** Connection返回异常 */
throw new BCOSStubException(resp.getErrorCode(), resp.getErrorMessage());
}
/** 获取返回的交易回执,回执被序列化为byte[] */
TransactionReceipt receipt =
objectMapper.readValue(resp.getData(), TransactionReceipt.class);
// Merkle证明,校验交易hash及交易回执,失败抛出异常
verifyTransactionProof(
receipt.getBlockNumber().longValue(),
receipt.getTransactionHash(),
request.getBlockHeaderManager(),
receipt);
/** 其他逻辑,构造返回 */
} catch (Exception e) {
/** 异常场景 */
response.setErrorCode(BCOSStatusCode.UnclassifiedError);
response.setErrorMessage(" errorMessage: " + e.getMessage());
}
return response;
}
- BCOSConnection
public class BCOSConnection implements Connection {
/** BCOS JavaSDK 实例句柄 */
private final Web3jWrapper web3jWrapper;
@Override
public Response send(Request request) {
switch (request.getType()) {
case BCOSRequestType.SEND_TRANSACTION:
/** type: SEND_TRANSACTION */
return handleTransactionRequest(request);
/** 其他case场景 */
}
}
/** 发送交易请求处理 */
public Response handleTransactionRequest(Request request) {
Response response = new Response();
try {
/** 参数JSON序列化,反序列化得到请求参数*/
TransactionParams transaction =
objectMapper.readValue(request.getData(), TransactionParams.class);
/** 签名交易 */
String signTx = transaction.getData();
/** 调用BCOS RPC发送交易接口,获取回执以及Merkle证明 */
TransactionReceipt receipt = web3jWrapper.sendTransactionAndGetProof(signTx);
/** 交易回执不存在 */
if (Objects.isNull(receipt)
|| Objects.isNull(receipt.getTransactionHash())
|| "".equals(receipt.getTransactionHash())) {
throw new BCOSStubException(
BCOSStatusCode.TransactionReceiptNotExist,
BCOSStatusCode.getStatusMessage(BCOSStatusCode.TransactionReceiptNotExist));
}
/** 交易执行失败 */
if (!receipt.isStatusOK()) {
throw new BCOSStubException(
BCOSStatusCode.SendTransactionNotSuccessStatus,
StatusCode.getStatusMessage(receipt.getStatus()));
}
/** 交易正确执行 */
response.setErrorCode(BCOSStatusCode.Success);
response.setErrorMessage(BCOSStatusCode.getStatusMessage(BCOSStatusCode.Success));
/** 返回交易回执,回执JSON方式序列化 */
response.setData(objectMapper.writeValueAsBytes(receipt));
} catch (Exception e) {
/** 异常情况 */
response.setErrorCode(BCOSStatusCode.HandleSendTransactionFailed);
response.setErrorMessage(" errorMessage: " + e.getMessage());
}
return response;
}
}
生成Jar¶
Stub插件需要打包生成shadow jar
才可以被WeCross Router
加载使用,在Gradle中引入shadow
插件。
shadow
插件使用: Gradle Shadow Plugin
- 引入shadow插件
plugins {
// 其他插件列表
id 'com.github.johnrengelman.shadow' version '5.2.0'
}
- 添加打包task
jar.enabled = false
project.tasks.assemble.dependsOn project.tasks.shadowJar
shadowJar {
destinationDir file('dist/apps')
archiveName project.name + '.jar'
// 其他打包逻辑
}
- 执行build操作
bash gradlew build
dist/apps
目录生成jar
文件
跨链事务¶
哈希时间锁定¶
哈希时间锁合约(hash time lock contract,htlc)能够实现两条异构链之间资产的原子交换,即跨链转账。
如果你想快速体验跨链转账可以参考体验WeCross。
WeCross提供了Solidity和Golang版本的htlc基类合约,基于htlc基类合约可以轻松开发适用于不同资产类型的htlc应用合约。
本章节以FISCO BCOS和Hyperledger Fabric的示例资产合约为例,演示如何实现两条异构链的资产互换。
准备工作¶
要完成资产互换,需要在各自链上部署资产合约以及哈希时间锁合约,然后通过WeCross控制台创建跨链转账提案,router会根据提案信息自动完成跨链转账。
部署WeCross和控制台
FISCO BCOS前期准备¶
部署合约
- 拷贝合约
假设当前位于router的根目录,将conf/chains-sample/bcos/htlc
目录下的LedgerSample.sol
、HTLC.sol
以及LedgerSampleHTLC.sol
文件拷贝至BCOS控制台的contracts/solidity
目录。
- 部署
LedgerSampleHTLC.sol
[group:1]> deploy LedgerSampleHTLC
# 合约地址需要记录下来
contract address: 0xc25825d8c0c9819e1302b1cd0019d3228686b2b1
发行资产
FISCO BCOS提供的资产示例合约可借助ledger-tool完成资产的发行、转账和授权。
git clone https://github.com/Shareong/ledger-tool.git
cd ledger-tool
gradle build
# 工具包需要和节点通讯,将节点sdk目录下的证书文件ca.crt, sdk.crt, sdk.key拷贝到dist/conf目录,并根据实际情况配置conf目录下的application.xml,账户用默认的pem文件即可。
# 根据金额发行资产,在dist目录下执行
java -cp 'apps/*:lib/*:conf' Application init 100000000
# 输出资产地址,以及资产的拥有者
assetAddress: 0x1796f3f195697c38bedaaaa27e424d05f359ca0f
owner: 0x55f934bcbe1e9aef8337f5551142a442fdde781c
资产授权
要完成跨链转账,资产拥有者需要将资产的转移权授权给哈希时间锁合约。
# approve [资产地址],[被授权者地址](此处为自己的哈希时间锁合约地址),[授权金额]
java -cp 'apps/*:lib/*:conf' Application approve 0x1796f3f195697c38bedaaaa27e424d05f359ca0f 0xc25825d8c0c9819e1302b1cd0019d3228686b2b1 1000000
# 成功输出如下
approve successfully
amount: 1000000
哈希时间锁合约初始化
需要将资产合约的地址和对手方的哈希时间锁合约地址保存到自己的哈希时间锁合约。
# 在FISCO BCOS控制台执行,此处约定Fabric的合约名为fabric_htlc,之后将以该名称安装和初始化链码
call LedgerSampleHTLC 0xc25825d8c0c9819e1302b1cd0019d3228686b2b1 init ["0x1796f3f195697c38bedaaaa27e424d05f359ca0f","fabric_htlc"]
# 查看owner余额,检查是否初始化成功
call LedgerSampleHTLC 0xc25825d8c0c9819e1302b1cd0019d3228686b2b1 balanceOf ["0x55f934bcbe1e9aef8337f5551142a442fdde781c"]
[100000000]
重要
- 初始化只能进行一次,所以在执行命令前务必确保相关参数都是正确的。
- 如果初始化时传参有误,只能重新部署哈希时间锁合约,并重新做资产授权。
Fabric前期准备¶
拷贝链码
# 获取docker容器id
docker ps -a|grep cli
0523418f889d hyperledger/fabric-tools:latest
# 假设当前位于router根目录, 将链码拷贝到Fabric的chaincode目录下
docker cp conf/chains-sample/fabric/ledger 0523418f889d:/opt/gopath/src/github.com/chaincode/ledger
docker cp conf/chains-sample/fabric/htlc 0523418f889d:/opt/gopath/src/github.com/chaincode/htlc
部署资产合约
# 启动容器
docker exec -it cli bash
# 安装链码,-n指定名字,此处命名为ledgerSample
peer chaincode install -n ledgerSample -v 1.0 -p github.com/chaincode/ledger/
# 初始化
peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n ledgerSample -l golang -v 1.0 -c '{"Args":["init","HTLCoin","htc","100000000"]}' -P 'OR ('\''Org1MSP.peer'\'','\''Org2MSP.peer'\'')'
# 查看账户余额
peer chaincode query -C mychannel -n ledgerSample -c '{"Args":["balanceOf","Admin@org1.example.com"]}'
# 输出应该为100000000
资产授权 ledgerSample合约通过创建一个托管账户实现资产的授权。
# 该命令默认使用admin账户发交易,即admin账户完成了一次授权
peer chaincode invoke -C mychannel -n ledgerSample -c '{"Args":["createEscrowAccount","1000000"]}' -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
部署哈希时间锁合约
# 安装链码,命名为fabric_htlc
peer chaincode install -n fabric_htlc -v 1.0 -p github.com/chaincode/htlc/
# 初始化,需要指定己方资产合约名和对手方的哈希时间锁合约地址
# init [己方资产合约名] [channel] [对手方哈希时间锁合约地址]
peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n fabric_htlc -l golang -v 1.0 -c '{"Args":["init","ledgerSample","mychannel","0xc25825d8c0c9819e1302b1cd0019d3228686b2b1"]}'
# 查看admin余额,检查是否初始化成功
peer chaincode query -C mychannel -n fabric_htlc -c '{"Args":["balanceOf","Admin@org1.example.com"]}'
# 输出应该为99000000,因为有一部资产已经转到了托管账户。
哈希时间锁合约配置¶
配置FISCO BCOS端router
在插件配置文件stub.toml
中配置htlc资源。
[[resources]]
# name cannot be repeated
name = 'htlc'
type = 'BCOS_CONTRACT' # BCOS_CONTRACT or BCOS_SM_CONTRACT
contractAddress = '0xc25825d8c0c9819e1302b1cd0019d3228686b2b1'
在主配置文件wecross.toml
中配置htlc任务。
[[htlc]]
#本地配置的哈希时间锁资源路径
selfPath = 'payment.bcos.htlc'
#确保已在router的accounts目录配置了bcos_default_account账户
account1 = 'bcos_default_account'
#对手方的哈希时间锁资源路径
counterpartyPath = 'payment.fabric.htlc'
#确保已在router的accounts目录配置了fabric_default_account账户
account2 = 'fabric_default_account'
重要
- 主配置中的htlc资源路径以及能访问这两个资源的账户请结合实际情况配置。
配置Fabric端router
在插件配置文件stub.toml
中配置htlc资源。
[[resources]]
# name cannot be repeated
name = 'htlc'
type = 'FABRIC_CONTRACT'
chainCodeName = 'fabric_htlc'
chainLanguage = "go"
peers=['org1']
在主配置文件wecross.toml
中配置htlc任务。
[[htlc]]
#本地配置的哈希时间锁资源路径
selfPath = 'payment.fabric.htlc'
#确保已在router的accounts目录配置了fabric_default_account账户
account1 = 'fabric_default_account'
#对手方的哈希时间锁资源路径
counterpartyPath = 'payment.bcos.htlc'
#确保已在router的accounts目录配置了bcos_default_account账户
account2 = 'bcos_default_account'
配置发送者账户
两个router需要在accounts目录下配置发送者的账户,因为跨链提案只能由资产的转出者创建。
FISCO BCOS用户需要将ledger-tool/dist/conf
目录下的私钥文件配置到router端的accounts目录,并假设命名为bcos,配置方法详见BCOS账户配置。
Fabric用户需要将admin账户配置到router端的accounts
目录,并假设命名为fabric,配置方法详见Fabric账户配置。
重启两个router
bash stop.sh && bash start.sh
发起跨链转账¶
假设跨链转账发起方是FISCO BCOS的用户,发起方选择一个secret
,计算
$$
hash = sha256(secret)
$$
得到hash
,然后和Fabric的用户即参与方协商好各自转账的金额、账户以及时间戳。
协商内容
- FISCO BCOS的两个账户:
- 资产转出者:0x55f934bcbe1e9aef8337f5551142a442fdde781c(和ledger-tool初始化时返回的owner地址保持一致)
- 资产接收者:0x2b5ad5c4795c026514f8317c7a215e218dccd6cf
- FISCO BCOS转账金额:700
- Fabric的两个账户:
- 资产转出者:Admin@org1.example.com (admin账户)
- 资产接收者:User1@org1.example.com
- Fabric转账金额500
- 哈希: 2afe76d15f32c37e9f219ffd0a8fcefc76d850fa9b0e0e603cbd64a2f4aa670d
- 哈希原像: e7d5c31dcc6acae547bb0d84c2af05413994c92599bff89c4abd72866f6ac5c6(协商时只有发起方知道)
- 时间戳t0:发起方的超时时间,单位s
- 时间戳t1: 参与方的超时时间,单位s
注解
- 哈希原像和哈希可通过控制台命令 genSecretAndHash 生成。
- 两个时间戳可通过控制台命令 genTimelock 生成。
- 时间戳需要满足条件:t0 > t1 + 300 > now + 300
创建跨链转账提案
两条链的资产转出者通过WeCross控制台创建跨链转账提案,将协商的转账信息写入各自的区块链。
- 命令介绍
- 命令:
newHTLCTransferProposal
- 参数:
path
,account
(资产转出者账户名),hash
,secret
,role
,sender0
,receiver0
,amount0
,timelock0
,sender1
,receiver1
,amount1
,timelock1
- 命令:
- 注意事项
- 其中下标为0的参数是发起方信息。
- 发起方
secret
传入哈希原像,role
传入true;参与方secret
传入null,role
传入false。
- 启动控制台
# 进入控制台dist目录
bash start.sh
- 发起方创建转账提案
该步骤由发起方即BCOS链的资产转出者完成。
newHTLCTransferProposal payment.bcos.htlc bcos edafd70a27887b361174ba5b831777c761eb34ef23ee7343106c0b545ec1052f 049db09dd9cf6fcf69486512c1498a1f6ea11d33b271aaad1893cd590c16542a true 0x55f934bcbe1e9aef8337f5551142a442fdde781c 0x2b5ad5c4795c026514f8317c7a215e218dccd6cf 700 2000010000 Admin@org1.example.com User1@org1.example.com 500 2000000000
- 参与方创建转账提案
该步骤由参与方即Fabric链的资产转出者完成。
newHTLCTransferProposal payment.fabric.htlc fabric edafd70a27887b361174ba5b831777c761eb34ef23ee7343106c0b545ec1052f null false 0x55f934bcbe1e9aef8337f5551142a442fdde781c 0x2b5ad5c4795c026514f8317c7a215e218dccd6cf 700 2000010000 Admin@org1.example.com User1@org1.example.com 500 2000000000
结果确认
哈希时间锁合约提供了查询余额的接口,可通过WeCross控制台调用,查看两方的接收者是否到账。
- FISCO BCOS用户确认
[WeCross]> call payment.bcos.htlc bcos balanceOf 0x2b5ad5c4795c026514f8317c7a215e218dccd6cf
Result: [700]
- Fabric用户确认
[WeCross]> call payment.fabric.htlc fabric balanceOf User1@org1.example.com
Result: [500]
注:跨链转账存在交易时延,取决于两条链以及机器的性能,一般需要5~25s完成转账。
应用场景¶
数字资产跨链¶
区块链天然具有金融属性,有望为金融业带来更多创新。支付清算方面,在基于区块链技术的架构下,市场多个参与者维护的多个账本或区块链融合连通并实时交互,短短几分钟内就能完成现在两三天才能完成的支付、对账、清算任务,降低了跨行跨境交易的复杂性和成本;同时,区块链技术能够确保交易记录透明安全,方便监管部门追踪链上交易,快速定位高风险交易流向。数字票据和供应链金融方面,区块链技术可以有效解决中小企业融资难问题。目前的供应链金融很难惠及产业链上游的中小企业,因为他们跟核心企业往往没有直接贸易往来,金融机构难以评估其信用资质。基于区块链技术,可以建立一种联盟多链网络,涵盖核心企业、上下游供应商、金融机构等,核心企业发放应收账款凭证给其供应商,票据数字化上链后可在供应商之间跨链流转,每一级供应商可凭数字票据实现对应额度的融资。
伴随着区块链在金融领域落地应用的飞速增长,多元化的数字资产场景和区块链应用带来了区块链资产相互隔离的问题,不同数字资产业务彼此搭建的区块链上的数字资产无法安全可信地实现互通,区块链上存在的数字资产价值越来越大,跨链的需求愈发迫切。
WeCross支持以多种网络拓扑模型搭建数字资产的跨链分区。在交易逻辑上,两阶段事务模型和HTLC事务模型将实现数字资产的去中心、去信任和不可篡改的转移。在安全防护上,加密和准入机制将保障数字资产转移的安全与可信。通过以上技术优势,WeCross将助力过去纸质形态的资产凭证全面数字化,让资产和信用层层深入传递到产业链末端,促进数字经济的发展。
司法跨域仲裁¶
随着数字经济高速发展,司法证据正逐步进入电子化时代。2017年9月,微众银行区块链团队与第三方存证公司合作,推出区块链司法存证与仲裁平台,开创将仲裁、法院等机构作为链上节点的先河,并于2018年2月,联合仲裁机构基于该平台出具业内首份裁决书,标志着区块链应用在司法领域的真正落地并完成价值验证;2018年6月,杭州互联网法院开始探求区块链在司法场景中的运用,进一步确立了区块链存证电子证据的合法性;2018年9月,北京互联网法院推出电子证据平台“天平链”,加速推动在网络空间治理的法治化进程。由于区块链司法应用能够极大缩减仲裁流程,仲裁机构得以快速完成证据核实,快速解决纠纷。
随着区块链应用在司法存证领域的普及,不同司法存证链之间连通的需求愈发强烈。但区块链的信任模型使得不同的司法存证链上的证据无法互通互信,当司法仲裁需要异地取证或是联合举证时,需要引入一个中心化的可信机构来进行协调,影响了区块链的实用价值。
WeCross跨链技术可以将各家存证链的证据统一抽象成证据资源,在不同的司法存证链之间可信地传输证据。WeCross可以搭建一个拥有多类型存证的存证链网络,在面向重大问题和重大纠纷时,去中心化地帮助各个链交互完备、可信和强有力的证据材料,帮助仲裁机构完成裁决。
个体数据跨域授权¶
随着WeIdentity、Hyperledger Indy等遵循DID协议的区块链身份认证系统出现,多个国家和地区开展了多中心化身份认证的实践与落地,多中心化身份认证目前市场需求巨大,加之政策鼓励支持,行业方兴未艾,处于高速发展的黄金时期。2019年2月27日,微众银行区块链团队与澳门政府设立的澳门科学技术发展基金签署合作协议,在智慧城市、民生服务、政务管理、人才培训等方面开展合作。双方合作的首个项目基于“WeIdentity”的实体身份标识及可信数据交换解决方案展开,这是区块链在粤港澳大湾区应用落地的重要一步。
身份认证正向跨地域的方向发展,不同地域、业务和基于不同区块链平台的身份认证产品之间尚不能互认的现状造成信息的鸿沟,导致身份和资质等数据仍然局限在小范围的地域和业务内, 无法互通。
WeCross 可以将多个不同架构、行业和地域的多中心化身份认证平台联结起来,帮助多中心化身份认证更好地解决数据孤岛、数据滥用和数据黑产的问题,在推进数据资源开放共享与信息流通,促进跨行业、跨领域、跨地域大数据应用,形成良性互动的产业发展格局上,发挥更大的作用。
物联网跨平台联动¶
随着智能穿戴、智能家居、无人机及以人脸识别等人工智能设备的普及,智能设备的类别越来越多,人机交互的频次也越来越高,物联网数据的类型和结构呈现多样化和复杂化的趋势。在5G时代,实现万物互联之后,数据和场景的复杂度更是呈几何倍数增长。区块链技术为物联网设备提供信任机制,保证所有权、交易等记录的可信性、可靠性及透明性,同时还可为用户隐私提供保障机制,从而有效解决物联网发展面临的大数据管理、信任、安全和隐私等问题,推进物联网向更加灵活化、智能化的形态演进。
目前物联网行业的区块链项目,有的旨在解决物联网碎片化严重、物联网产品没有标准化等痛点,有的则探索区块链在智能城市、基础设施、智能电网、供应链以及运输等领域的应用。然而,它们都面临着相同的困境。物联网设备硬件模块的选择和组合非常多样,对区块链平台的支持能力不尽相同,一旦硬件部署完成后难以更新,单一的区块链平台在连通多样化的物联网设备时必然会遇到瓶颈,无法全面满足所有物联网设备在多样化场景中的需求。
WeCross跨链技术支持物联网设备跨链平行扩展,可用于构建高效、安全的分布式物联网网络,以及部署海量设备网络中运行的数据密集型应用;WeCross跨链技术可以安全可信地融合连通多个物联网设备的区块链,在功能和安全上满足多样的场景需求。
FAQ¶
问题2¶
在搭建Demo时报错
========== ERROR !!! FAILED to execute End-2-End Scenario ==========
ERROR !!!! Test failed
回答
Fabric 的demo和机器上的Fabric网络冲突了,尝试用demo目录下的clear.sh
用脚本清理机器上已有的Fabric网络。
问题3¶
在部署demo时,MacOS用户若出现“无法打开”,“无法验证开发者”的情况。
回答
MacOS对下载的包权限要求较为严格,必须同一个进程下载的才可执行,可采用如下方法解决:
# 清理环境
cd ~/demo/ && bash clear.sh && cd ~ && rm -rf demo
# 将三个步骤的命令拼成一条命令执行
bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_demo.sh) && cd demo && bash build.sh