_images/menu_logo_wecross1.svg

WeCross

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

_images/4S.png

平台介绍

基本介绍

区块链作为构建未来价值互联网的重要基础设施,深度融合分布式存储、点对点通信、分布式架构、共识机制、密码学等前沿技术,正在成为技术创新的前沿阵地。全球主要国家都在加快布局区块链技术,用以推动技术革新和产业变革。经过行业参与者十年砥砺前行,目前区块链在底层技术方案上已趋于完整和成熟,国内外均出现可用于生产环境的区块链解决方案。其所面向的创新应用场景覆盖广泛,已在对账与清结算、跨境支付、供应链金融、司法仲裁、政务服务、物联网、智慧城市等众多领域落地企业级应用。

在广泛的场景应用背后,来自于性能、安全、成本、扩展等方面的技术挑战也愈发严峻。目前不同区块链应用之间互操作性不足,无法有效进行可信数据流通和价值交换,各个区块链俨然成为一座座信任孤岛,很大程度阻碍了区块链应用生态的融合发展。未来,区块链想要跨越到真正的价值互联网,承担传递信任的使命,开启万链互联时代,需要一种通用、高效、安全的区块链跨链协作机制,实现跨场景、跨地域不同区块链应用之间的互联互通,以服务数量更多、地域更广的公众群体。

作为一家具有互联网基因的高科技、创新型银行,微众银行自成立之初即高度重视新兴技术的研究和探索,在区块链领域积极开展技术积累和应用实践,不断致力于运用区块链技术提升多机构间的协作效率和降低协作成本,支持国家推进关键技术安全可控战略和推动社会普惠金融发展。微众银行区块链团队基于一揽子自主研发并开源的区块链技术方案,针对不同服务形态、不同区块链平台之间无法进行可信连接与交互的行业痛点,研发区块链跨链协作平台——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-dpayment

_images/framework.png

程序版本

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配置移除账户配置项
  • 使用脚本:部署脚本、配置脚本以及证书生成脚本适配新的配置项

下载程序

下载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-rc2

方式3:手动下载

解压后,目录下包含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-rc2

方式3:手动下载

  • 国内资源:点击下载MD5

  • 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-rc2

方式2:手动下载

下载后,目录下包含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及以上

软件依赖

WeCross作为Java项目,需要安装Java环境包括:

WeCross提供了多种脚本帮助用户快速体验,这些脚本依赖openssl, curl, expect,使用下面的指令安装。

# Ubuntu
sudo apt-get install -y openssl curl expect tree

# CentOS
sudo yum install -y openssl curl expect tree

# MacOS
brew install openssl curl expect tree

快速体验

我们提供一个Demo帮助用户快速体验并理解WeCross的原理。Demo搭建了一个WeCross跨链网络,连接FISCO BCOS和Hyperledger Fabric区块链。用户可通过WeCross控制台,对不同的链上资源进行操作。

_images/demo.png

搭建 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 清理后重试

部署成功后会输出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
  • 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 

WeCross Console是基于WeCross Java SDK开发的跨链应用。搭建好跨链网络后,可基于WeCross Java SDK开发更多的跨链应用,通过统一的接口对各种链上的资源进行操作。

跨链转账

WeCross基于哈希时间锁合约实现了异构链之间资产的原子互换,如下图所示:

_images/htlc_sample.png

配置哈希时间锁合约

可通过脚本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

为了不影响手动组网章节的体验,可将搭建的Demo清理掉。

cd ~/demo/
bash clear.sh

至此,恭喜你,快速体验完成!可进入手动组网章节深入了解更多细节。

手动组网

本文档介绍以手动的方式,一步步搭建一个与Demo相同的跨链网络。

_images/demo.png

快速部署

本章指导完成跨链路由跨链控制台的部署。

  • 跨链路由:与区块链节点对接,并彼此互连,形成跨链分区,负责跨链请求的转发
  • 跨链控制台:查询和发送交易的操作终端

_images/routers.png

操作以~/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)按行分隔,保存到文件中。

:请确保机器的82508251, 2550025501端口没有被占用。

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-rc2)!
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上接入,配置交易发送账户

_images/demo.png

搭建区块链

在接入区块链前,先给出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开发自己的跨链应用。

_images/demo.png

启动控制台

控制台连接的是router-8250

cd ~/wecross/WeCross-Console

# 配置连接至 router-8250,默认已配置,直接保存退出
vim conf/application.toml

# 启动控制台
bash start.sh

查看资源

进入控制台,用listResources命令查看WeCross跨连网络中的所有资源。可看到有两个资源:

  • payment.bcos.HelloWeCross
  • 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合约的账户

注:

  1. WeCross启动时会把conf目录指定为classpath,若配置项的路径中开头为classpath:,则以conf为相对目录。
  2. [p2p]配置项中的证书和私钥可以通过create_cert.sh脚本生成。
  3. 若通过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 BCOSFabric

配置FISCO BCOS

请参考:FISCO BCOS 2.0插件配置

配置Fabric

请参考:Fabric 1.4插件配置

账户配置

在Router中配置账户,与链进行交互。配置操作包括:

  • 指定账户名(accounts/<account_name>/account.toml下,通过目录名<account_name>指定账户名)
  • 指定账户类型(用于BCOS、Fabric等,在account.toml中配置)
  • 指定账户其它信息(密钥等,在account.toml中配置)

WeCross启动后会在accounts的根目录下去遍历所有的一级目录,目录名即为账户的名字,不同的目录代表不同的链,然后尝试读取每个目录下的account.toml文件。

配置不同类型的账户,与不同类型的链进行操作。目前WeCross支持的类型包括:FISCO BCOSFabric

配置FISCO BCOS

请参考:FISCO BCOS 2.0账户配置

配置Fabric

请参考:Fabric 1.4账户配置

控制台

控制台是WeCross重要的交互式客户端工具,它通过WeCross-Java-SDK与WeCross 跨链代理建立连接,实现对跨链资源的读写访问请求。控制台拥有丰富的命令,包括获取跨链资源列表,查询资源状态,以及所有的JSON-RPC接口命令。

控制台命令

控制台命令可分为两类,普通命令和交互式命令。

普通命令

普通命令由两部分组成,即指令和指令相关的参数:

  • 指令: 指令是执行的操作命令,包括获取跨链资源列表,查询资源状态指令等,其中部分指令调用JSON-RPC接口,因此与JSON-RPC接口同名。 使用提示: 指令可以使用tab键补全,并且支持按上下键显示历史输入指令。
  • 指令相关的参数: 指令调用接口需要的参数,指令与参数以及参数与参数之间均用空格分隔。与JSON-RPC接口同名命令的输入参数和获取信息字段的详细解释参考JSON-RPC API
交互式命令

WeCross控制台为了方便用户使用,还提供了交互式的使用方式,比如将跨链资源标识赋值给变量,初始化一个类,并用.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-rc2)!
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]
---------------------------------------------------------------------------------------------
supportedStubs

显示router当前支持的插件列表。

[WeCross]> supportedStubs
[BCOS2.0, GM_BCOS2.0, Fabric1.4]
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 

停止脚本

stop.sh

停止脚本stop.sh用于停止WeCross服务。

bash  stop.sh

构建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.0GM_BCOS2.0Fabric1.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快速部署

账户配置

WeCross中账户用于交易签名,BCOS2 Stub支持pemp12两种格式文件。

配置路径

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.0GM_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-networkcrypto-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-networkcrypto-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版本
  • WeCross服务部署

Java应用引入SDK

通过gradle或maven引入SDK到java应用

gradle:

compile ('com.webank:wecross-java-sdk:1.0.0-rc2')

maven:

<dependency>
    <groupId>com.webank</groupId>
    <artifactId>wecross-java-sdk</artifactId>
    <version>1.0.0-rc2</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();
detail

获取资源详情。

参数
返回值
  • ResourceDetail - 资源详情
java示例
    ResourceDetail detail = resource.detail();
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);
sendTransaction(无参数)

调用智能合约,会改变链状态,发交易。

参数
  • method: String - 调用的方法
返回值
  • String[] - 调用结果
java示例
    String[] result = resource.sendTransaction("set");
sendTransaction(带参数)

调用智能合约,会改变链状态,发交易。

参数
  • method: String - 调用的方法
  • args: String... - 可变参数列表
返回值
  • String[] - 调用结果
java示例
    String[] result = resource.sendTransaction("set", "value");

RPC状态码

当一个RPC调用遇到错误时,返回的响应对象必须包含error错误结果字段,该字段有下列成员参数:

  • errorCode: 使用数值表示该异常的错误类型,必须为整数。
  • message: 对该错误的简单描述字符串。

标准状态码及其对应的含义如下:

code 含义
0 执行成功
10100 内部错误
10201 版本错误
10202 资源标识错误
10203 资源不存在
10205 请求解码错误
10301 htlc错误
20000 内部错误,结合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-rc2'
    // 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所在目录路径

插件配置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 callsendTransaction接口类似,前者用于查询状态,后者发送交易,修改区块链状态

    • 参数列表

      • TransactionContext request: 请求上下文,获取构造交易需要的数据,构造交易
      • Connection connection: Connection对象,发送请求
    • 返回值

      • 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.solHTLC.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(资产转出者账户名), hashsecretrolesender0receiver0amount0timelock0sender1receiver1amount1timelock1
  • 注意事项
    • 其中下标为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完成转账。

应用场景

数字资产跨链

区块链天然具有金融属性,有望为金融业带来更多创新。支付清算方面,在基于区块链技术的架构下,市场多个参与者维护的多个账本或区块链融合连通并实时交互,短短几分钟内就能完成现在两三天才能完成的支付、对账、清算任务,降低了跨行跨境交易的复杂性和成本;同时,区块链技术能够确保交易记录透明安全,方便监管部门追踪链上交易,快速定位高风险交易流向。数字票据和供应链金融方面,区块链技术可以有效解决中小企业融资难问题。目前的供应链金融很难惠及产业链上游的中小企业,因为他们跟核心企业往往没有直接贸易往来,金融机构难以评估其信用资质。基于区块链技术,可以建立一种联盟多链网络,涵盖核心企业、上下游供应商、金融机构等,核心企业发放应收账款凭证给其供应商,票据数字化上链后可在供应商之间跨链流转,每一级供应商可凭数字票据实现对应额度的融资。

伴随着区块链在金融领域落地应用的飞速增长,多元化的数字资产场景和区块链应用带来了区块链资产相互隔离的问题,不同数字资产业务彼此搭建的区块链上的数字资产无法安全可信地实现互通,区块链上存在的数字资产价值越来越大,跨链的需求愈发迫切。

_images/asset.png

WeCross支持以多种网络拓扑模型搭建数字资产的跨链分区。在交易逻辑上,两阶段事务模型和HTLC事务模型将实现数字资产的去中心、去信任和不可篡改的转移。在安全防护上,加密和准入机制将保障数字资产转移的安全与可信。通过以上技术优势,WeCross将助力过去纸质形态的资产凭证全面数字化,让资产和信用层层深入传递到产业链末端,促进数字经济的发展。

司法跨域仲裁

随着数字经济高速发展,司法证据正逐步进入电子化时代。2017年9月,微众银行区块链团队与第三方存证公司合作,推出区块链司法存证与仲裁平台,开创将仲裁、法院等机构作为链上节点的先河,并于2018年2月,联合仲裁机构基于该平台出具业内首份裁决书,标志着区块链应用在司法领域的真正落地并完成价值验证;2018年6月,杭州互联网法院开始探求区块链在司法场景中的运用,进一步确立了区块链存证电子证据的合法性;2018年9月,北京互联网法院推出电子证据平台“天平链”,加速推动在网络空间治理的法治化进程。由于区块链司法应用能够极大缩减仲裁流程,仲裁机构得以快速完成证据核实,快速解决纠纷。

随着区块链应用在司法存证领域的普及,不同司法存证链之间连通的需求愈发强烈。但区块链的信任模型使得不同的司法存证链上的证据无法互通互信,当司法仲裁需要异地取证或是联合举证时,需要引入一个中心化的可信机构来进行协调,影响了区块链的实用价值。

_images/evidence.png

WeCross跨链技术可以将各家存证链的证据统一抽象成证据资源,在不同的司法存证链之间可信地传输证据。WeCross可以搭建一个拥有多类型存证的存证链网络,在面向重大问题和重大纠纷时,去中心化地帮助各个链交互完备、可信和强有力的证据材料,帮助仲裁机构完成裁决。

个体数据跨域授权

随着WeIdentity、Hyperledger Indy等遵循DID协议的区块链身份认证系统出现,多个国家和地区开展了多中心化身份认证的实践与落地,多中心化身份认证目前市场需求巨大,加之政策鼓励支持,行业方兴未艾,处于高速发展的黄金时期。2019年2月27日,微众银行区块链团队与澳门政府设立的澳门科学技术发展基金签署合作协议,在智慧城市、民生服务、政务管理、人才培训等方面开展合作。双方合作的首个项目基于“WeIdentity”的实体身份标识及可信数据交换解决方案展开,这是区块链在粤港澳大湾区应用落地的重要一步。

身份认证正向跨地域的方向发展,不同地域、业务和基于不同区块链平台的身份认证产品之间尚不能互认的现状造成信息的鸿沟,导致身份和资质等数据仍然局限在小范围的地域和业务内, 无法互通。

_images/identity.png

WeCross 可以将多个不同架构、行业和地域的多中心化身份认证平台联结起来,帮助多中心化身份认证更好地解决数据孤岛、数据滥用和数据黑产的问题,在推进数据资源开放共享与信息流通,促进跨行业、跨领域、跨地域大数据应用,形成良性互动的产业发展格局上,发挥更大的作用。

物联网跨平台联动

随着智能穿戴、智能家居、无人机及以人脸识别等人工智能设备的普及,智能设备的类别越来越多,人机交互的频次也越来越高,物联网数据的类型和结构呈现多样化和复杂化的趋势。在5G时代,实现万物互联之后,数据和场景的复杂度更是呈几何倍数增长。区块链技术为物联网设备提供信任机制,保证所有权、交易等记录的可信性、可靠性及透明性,同时还可为用户隐私提供保障机制,从而有效解决物联网发展面临的大数据管理、信任、安全和隐私等问题,推进物联网向更加灵活化、智能化的形态演进。

目前物联网行业的区块链项目,有的旨在解决物联网碎片化严重、物联网产品没有标准化等痛点,有的则探索区块链在智能城市、基础设施、智能电网、供应链以及运输等领域的应用。然而,它们都面临着相同的困境。物联网设备硬件模块的选择和组合非常多样,对区块链平台的支持能力不尽相同,一旦硬件部署完成后难以更新,单一的区块链平台在连通多样化的物联网设备时必然会遇到瓶颈,无法全面满足所有物联网设备在多样化场景中的需求。

_images/iot.png

WeCross跨链技术支持物联网设备跨链平行扩展,可用于构建高效、安全的分布式物联网网络,以及部署海量设备网络中运行的数据密集型应用;WeCross跨链技术可以安全可信地融合连通多个物联网设备的区块链,在功能和安全上满足多样的场景需求。

FAQ

问题1

下载速度太慢,下不下来。

回答

我们提供了多种下载方式,点击此处查看


问题2

在搭建Demo时报错

========== ERROR !!! FAILED to execute End-2-End Scenario ==========

ERROR !!!! Test failed

回答

Fabric 的demo和机器上的Fabric网络冲突了,尝试用demo目录下的clear.sh用脚本清理机器上已有的Fabric网络。


社区

贡献代码

接入更多链

WeCross,目前适配了

  • FISCO BCOS
  • Fabric

WeCross一直在迭代 ,想接入什么链?一起来写代码吧

  • 联系社区(issue) -> 手把手指导 -> 开发 -> 贡献PR -> 合入 -> WeCross!

更多