Yuque Archive
工作资料 - 新新

完整交接文档_王宇_20210723

负二、关于本文档

提供在线访问地址:https://www.yuque.com/docs/share/4fdc37ea-2d34-4979-824c-c8cb3414aef2?# 《完整交接文档_王宇_20210723》

以避免文档内容丢失或者出现预期外的变更。交接时会导出 PDF 和 Word 两个版本。

负一、基本信息

注:账号权限回收后,个人仓库可能被转移至管理员账户,请与 scm 同事确认

所有仓库列表:http://10.10.77.113:8888/users/wangyu/projects

说明:这里放了我接触过的所有项目的代码,不能比这个更全了

一共涉及 39 个仓库:

文档仓库:http://10.10.77.113:8888/wangyu/docs

说明:仓库里主要放了 项目代码列表.xlsx 文件,有仓库和项目的对应关系。(附表一)

〇、中云智农部署情况

一、相关代码仓库

1. 节点程序

仓库位置:http://10.10.77.113:8888/blockchain/uchains

仓库说明:优链节点程序

编译环境:go1.14.14 linux/amd64 以上

分支说明:

附归档说明:

2. 合约程序

仓库位置:http://10.10.77.113:8888/blockchain/uchains_contract

仓库说明:优链合约程序。如果需要从合约启动,需要依赖节点程序源码

编译环境:go1.14.14 linux/amd64 以上

3. 旧版本节点程序

注:

  • 账号权限回收后,仓库可能被转移至管理员账户,请与 scm 同事确认
  • 旧版本节点请严格使用指定 Golang 版本

仓库位置:http://10.10.77.113:8888/wangyu/uchains

仓库说明:客户生产环境使用旧版本的节点程序,编译后部署

编译环境:go1.12.15 linux/amd64

分支说明:

注意要区分,这里的分支指代码包,如 zyzn0511, zyzn0526, zyzn0615,此外还有一个部署包,就是打包好的用于部署的二进制文件,这四个部署包的压缩包在 10.10.77.120:/home/mpsp/wangyu/deploy/deploy.tar.gz

解压后会包含:

附项目部署使用的编译环境 env 信息:

4. 节点操作脚本

注:账号权限回收后,仓库可能被转移至管理员账户,请与 scm 同事确认

仓库位置:http://10.10.77.113:8888/wangyu/uchains-script

仓库说明:节点相关脚本工具,之前在节点的源码包里,我拆分出作为单独项目,依赖管理方式为 mod。

5. 节点部署脚本

注:账号权限回收后,仓库可能被转移至管理员账户,请与 scm 同事确认

仓库位置:http://10.10.77.113:8888/wangyu/uchains-deploy

仓库说明:节点部署脚本工具,因为部署只需要更改二进制程序、配置文件等,目录结构是固定的,这是我自己用的脚本。

二、归档版本的改动说明

1. 配置文件拆分

interfaceConfig.yaml 拆分

以前的接口配置全在 interfaceConfig.yaml 文件中,配置文件达到 1000 行,考虑到太累赘了,就更改了相关代码。目前只需要在同目录下放入 interfaceConfig-xxx.yaml 形式的接口配置文件,程序会自动合并相关配置。如:

可以每个合约都用自己的接口配置文件,达到接口配置可以增量新增的效果。当然,保留原样全写在一个文件里也不会有问题。

peer.yaml 拆分

以前的节点配置全在 peer.yaml 文件中,配置文件达到 500 行,而每次部署节点只需要修改两行配置,操作繁琐,就更改了相关代码。目前只需要在同目录下放入 peer-xxx.yaml 形式的配置文件,后载入的配置文件会自动覆盖 peer.yaml 文件。如:

2. REST 系统接口多前缀支持

比如,查询链信息的接口为 http://127.0.0.1:18611/UChains/chainsinfo/1/100

URL 中的 UChains 是写死在代码里的,而且大小写很反人类。目前将这个前缀支持体现在配置文件中,如:

接口可以支持各种前缀:

同时,我在链信息这个接口上加了默认值,可以直接使用 http://127.0.0.1:18611/chainsinfo

3. 修改网络 id

从 umfnet 修改为 main。修改网络 id 只需要两步操作,1 是重新生成证书,2 是修改配置文件,就可以了。

重新生成证书

脚本位置在目录下:

同级目录 certGen 下的脚本用于生成证书文件,首先在 genRSACert.sh 中配置 subject:

其中的 CN = 就是主体信息,然后直接执行 genAll.py :

新的证书就生成在目录下了。

genpubkey.go 文件用于从证书文件生成公钥字符串,用于 peer.yaml 中配置,如:

修改配置文件

修改 peer.yaml 文件中 uchains.networkGroup 相关配置。

4. 支持 jsvm

基本说明

一层合约代码在 uchains_contract/vmEngine/jsvm

二层合约代码在 uchains_contract/javascript/template

注册一层合约的脚本和之前的脚本一样,入口脚本是 uchains-script/main.sh,实际执行 UChainsTest 目录下的脚本。UChainsTest 目录下的配置规则是,根据 config.json选择要执行的配置文件,如:

config_jsvm.yaml 配置文件的内容为:

注册一层合约

要注意 contractconfig 下面的配置,其中 checkType 是新增的配置项。如果为 1 需要,则在这个合约引擎下的所有二层合约,包括二层合约的升级操作,都需要各节点审查后才能正常使用。

使用二层合约(新建链)

二层合约的代码模板在 uchains_contract/javascript/template :

app.js 是惟一的用于使用的合约文件,data.js 是测试数据的位置,debug.js 用于本地调试运行合约,执行过程如:

app.js 中有一段代码,调试的时候需要打开注释,真正部署时需要注释掉:

发起新建链的请求时,要注意 chainconfig 下的配置,其中 VMConfig 是新增的配置内容,Type 指定二层合约类型,SourceCode 指定初始化的脚本内容,CodeVersion 执行合约的初始版本。

升级二层合约

升级二层合约的示例入口脚本在 uchains-script/chain.sh,实际执行 tool_chain 目录下的脚本,升级二层合约所需的示例配置为:

url 指定目标节点和链 id,Type 是合约类型,SourceCode指向合约文件,PrivKey 是指向节点的私钥文件,脚本中会使用私钥对内容进行签名,CodeVersion 是要升级的版本。

审查二层合约

审查二层合约所需的示例配置为:

Result 为 1 说明审查通过,否则不通过。目前 jsvm 合约内的校验逻辑是,根据接收交易的节点获取相应的公钥,然后用公钥验证这里的签名,如果收到 3 个以上节点审查通过,则通过。

jsvm 合约接口

jsvm 存在问题

  1. 只支持 ES5 语法
  2. 偶发出现 map 并发读写导致 panic 的问题,待详细排查

三、节点和合约的启动和使用

1. 节点的启动

节点程序的启动需要的目录结构为:

把节点二进制程序放到同级目录下就可以启动。

为了方便调试,节点程序的仓库已经包含可以启动的目录结构,进入 uchains/uchains 目录,执行 go run ./main/start.go 就可以启动节点,输出日志为:

2. 合约的启动

以模板合约 uchains_contract/golang/empty为例。

优链的合约加载,一种是启动节点后,把合约 so 文件放到 umfnet/contract 目录下,然后调用注册合约注册链的脚本,也是最正常的启动方式。

再一种是需要修改优链源码的方案。在 uchains/uchains/applications/appManager/appManager.go 文件的第 430 行附近,将 import 进来的合约文件对象,作为参数传入函数中。相应的,peer.yaml 中的 netid 部分需要新增一项配置(参考系统链配置),系统会自动匹配程序读入的程序和配置文件中的配置。也就是所谓的 solo 模式。(目前仍然可用,但是要改源码的)

第三种也就是后来的改进,是由于节点程序和合约文件分离,合约文件引入节点源码作为依赖,合约的 go.mod 如:

然后,节点程序会根据 peer.yaml 中的 netid 相关的配置,如:

程序会根据配置到 umfnet/contract 目录下读取 main_empty_1-0-0.so 合约文件,并自动加载。

合约这边的编译脚本为 build.sh

启动脚本为 start.sh

启动脚本会在启动的时候把合约编译为 so 放到 umfnet/contract 目录下,正好对应节点程序去读取。

注:window 系统不可行,编译不出 so 文件。


3. 详细操作步骤(uchains-script 的使用)


本小节详细描述:

  1. 从合约启动节点
  2. 使用脚本注册合约
  3. 使用脚本新建链

假设目前已经从 gitlab clone 了 uchains, uchains_contract, uchains-script 三个项目,并且把三个项目放到了同样的父级目录下。

从合约启动节点

进入 uchains_contract,找到 vmEngine 下的 jsvm,这是一个合约:

go.mod 文件描述了 uchains_contract 项目依赖的 uchains 模块的路径关系:

可以执行 build.sh 尝试是否编译成功:

确认可以编译后,编辑 configFile 下的 peer.yaml 文件,确保配置正确:

然后执行 start.sh 启动节点:

这个时候访问 http://127.0.0.1:18611/UChains/chainsinfo/1/100,可以看到链信息:

使用脚本注册合约、新建链

进入 uchains-script/UChainsTest 目录,这里是向节点发起请求的脚本:

修改 config.json 文件,exec 后的值指向下面的 key,比如值 boa 就执行key 为 boa 的下面的操作:

boa 的值是一个数组,MainType 指测试类型,具体关系为:

数组里包含了两个操作,3-1 是注册合约,2-1 是新建链,subType 的对应关系比较多,具体请查看代码(别的类型没有改造,不确定好不好用)。顶级的配置 interval 配置是指两步操作之间 sleep 的秒数。

FileName 指配置文件的名称,不带后缀,如 config_boa.yaml,在配置文件中修改合约名称、链名称等配置信息:

执行脚本:

如果收到了成功响应,交易会成功。

四、合约的开发

uchains_contract/golang/empty 是最新的一个空合约的模板。

1. 合约命名

首先复制一份合约文件:

然后要修改 go.mod 中对合约的命名:

修改编译脚本中合约的命名:

struct.go 中 import 的路径名:

以及 app.go 中 import 的路径名:

一共至少 4 个地方,总之确保合约的所有程序文件不会引用其他依赖包(除了 uchains 节点)。

2. 内容开发

一般的合约开发只需要关注 4 个函数(其他函数我也不知道干什么用的),我把他们分别放到了 4 个文件里:

  • InitApp 函数在合约初始化时调用,负责实例化数据库操作句柄等操作。
  • Check 函数是共识前后的检查,用于排除失败交易。
  • AppProcess 函数是共识结束后,写块时被调用,用于处理业务表的函数。所有的 POST 请求会走到这个函数上。
  • Query 函数是处理 GET 请求的地方。如果 POST 请求的 queryType 不是 255,POST 请求也会走到这个函数上。

3. 接口配置

接口配置示例:

需要关注的是 queryType,用于在合约内区分不同接口,比如 POST 请求有 5 个接口,分别用 5 个不同的 queryType 标识。

如果 5 个 POST 接口都需要标识 queryType 为 255,那就得用 cmdType 作为区分不同 POST 接口的标识。

4. 其他注意事项

  • Check 函数中的 bitmap 数组长度,必须和入参的交易数量一致。
  • Check 函数中的交易有可能为 nil,排查定位到 uchains/uchains/consensus/txManager/queue.go 文件,EnQueue 的不包含 nil, GetFrontElemt 的就有 nil 了,概率性问题,原因不明。
  • Query 函数中的 res.Data 不可以为 nil

五、更换数据库的操作

更换数据库的操作步骤:

  • 修改数据库配置
  • 更改链配置
  • 替换数据库配置文件

1. 修改数据库配置

2. 更改链配置

如果是系统链,就修改 peer.yaml 中的这个配置:

如果是后面注册的链,这些配置会体现在注册时带的参数上。

3. 替换数据库配置文件

configFile 目录下,也就是 peer.yaml 同级目录下,用哪种数据库,就用相应的配置文件替换 struct.yml,这个文件主要是配置,一条链里面的 索引表、ledger 表 等分别用什么数据库

4. 其他注意事项

尽量在每次切换数据库时,都使用新的数据库。

比如,节点 1/2/3/4 都使用 mysql,现在 节点 4 想切换为 mongoDB,建议 1/2/3 的数据库都切换为全新的数据库,否则有可能会发现,节点 4 对 mongoDB 的切换没有生效。(猜测程序优先使用数据库已有的配置,本地文件不生效)

六、链下数据防篡改

测试项之一,和应用层配合使用。

合约位置在 uchains_contract/golang/record

七、跨合约调用

目前的跨合约调用是一个简单的 demo,根据请求参数,直接读取 umfnet/contract/ 的 so 文件,读取出方法并执行。

Golang 没有脚本语言的 eval 之类的方法,type assertion 时只能用 type switch 的方式。

1. 目标合约

合约位置:uchains_contract/golang/targetContract

关键代码:export.go 文件

当这个方法被调用时,会打印出一行日志。

2. 发起调用的合约

合约位置:uchains_contract/golang/contract

发起请求(POST):

触发的关键词代码:

执行结果:

3. 注意事项

类型转换如果出错会直接 panic,要小心。如:

八、公证人跨链

相关代码在王杰的交接内容里,在 svn 上一个叫 crossChainScript 的项目。

uchainsFabricNotary 是 java 客户端,负责调用两条链。

umfNotaryAsset 是 fabric 的合约代码,可以在 fabric 上直接注册。

assetBoa 是 uchains 的合约代码。

测试过程

fabric 的配置文件在 crossChainScript/uchainsFabricNotary/src/main/java/fabric/config/Config.java ,主要配置节点证书等内容

uchains 的配置文件在 crossChainScript/uchainsFabricNotary/src/main/java/uchains/config/SysConfig.java,主要配置 IP 地址和端口:

流程相关配置在 crossChainScript/uchainsFabricNotary/src/main/java/process/Notary.java ,主要需要配置 fabric 的chainid:

配置完成后,直接到 test 类 crossChainScript/uchainsFabricNotary/src/test/java/TestCmdLine.java 中执行 main 方法就可以:

测试结果

  • 客户端、优链合约、fabric合约代码程序都完整
  • java 客户端代码流程正常
  • uchains 所有交易都成功
  • fabric 创建账户交易成功,转账交易失败,待解决

Fabric 转账交易失败的问题

测试时 fabric 按照官网 getting started 文档(https://hyperledger-fabric.readthedocs.io/en/release-2.2/install.html)的流程部署 2.2.2 版本。

fabric 的创建账户交易是成功的,转账交易报错 unexpected end of json file,将 java sdk 的版本从 1.4.4 升级到 2.2.2 依然存在同样的问题。尝试过更改节点的背书策略为 NA、向多个 peer 同时发送交易等,都没有解决报错,因此猜测出错原因是,合约使用 1.4.4 版本开发,运行在 2.2.2 的节点(fabric component)上会不兼容。

官网的 1.4.4 版本操作比新版复杂,实际测试时,合约可以成功注册,但客户端调用时遇到 grpc 报错 tls 证书 no record 之类,未解决。

比较靠谱的解决方法可能就是,恢复内网版本的 fabric 环境。

assetBoa 合约的问题


优链的合约需要使用旧版本节点编译运行,因为 assetBoa 合约里的 sql 调用是用的 xorm-plus 库,之前旧的节点程序,直接在 vender 包中对 xorm-plus 的源码进行了改动,新的节点使用 modules 管理依赖,导致依赖的库有出入。

在使用网络上的依赖库时,会遇到这样的错误:

对应代码中的多处调用:

session Execute 方法本来是没有参数的,之前的同事(昵称大双,不知道真名)在 xorm-plus 上手动加上了几个带参数的函数。

如果使用旧版本的依赖(xormplus/core, xormplus/xorm):

会遇到另一个(我)没有排查到原因的问题,报错说 xorm 下缺少 log 包:

这个 xormplus 被改动的问题在其他合约里也有可能出现,比如之前的 utxo 合约,未完全验证 utxo 的功能是否正常。

九、其他可能会用到的操作

1. UTXO测试脚本

UTXO合约位置:uchains_contract/golang/assetUtxo

操作UTXO合约的脚本位置:uchains-script/UChainsTest/YaCe/YaCeForUtxo

这个操作脚本是一个命令行交互的脚本,go run 启动后去执行一系列操作,有至少 8 个测试项都依赖于 UTXO 合约和脚本。这个脚本本地维护了一个 json 形式的数据库(utxo.json),涉及具体操作时会向节点发送请求,但要保证本地数据库和节点数据库一致,否则节点数据会出现多份数据。(我也不明白为什么要这样)

2. 储存方式验证

mysql 和 mongodb 可以直接连数据库验证。rocksdb 目前应该不支持。

tikv 的脚本在 uchsin_test/tool_tikv,可以从 tikv 服务器查出最新的块数据,用于验证。

3. 加密方式验证

非对称加密验证通过,脚本位置在 uchains-script/Coupon_yace/signverify

对称加密的二进制脚本在 (72 服务器) /home/mpsp/duyong/trustedScript/10_Usecase302,我没看懂怎么跑。

4. 同态加密

boaPaillier 合约只支持 mongodb。

合约代码位置:uchains_contract/golang/boaPaillier

测试脚本代码位置:wangyu/uchains-script/UChainsTest/YaCe/BoaPaillier

执行脚本后的报错内容:

节点:

脚本:

十、保理代理相关项目

1. 保理代理

项目源码:http://10.10.77.113:8888/wangyu/scf-demo

项目目录:

项目说明(一共 5 个):

导入数据文件

数据库要求:不区分大小写,(我用的 5.7 版本)

需要导入的数据库文件:

dubbo provider

项目包含三个子模块:

scf-dubbo-interface 需要先 install 一下,然后主要 package scf-dubbo-provider 项目。

如果遇到依赖包不全的问题,可以将 scf-dubbo-provider 项目 lib 目录下的 jar 包安装到 maven 仓库,README 中有安装命令。

scf-dubbo-provider 的配置文件是 application.yml,需要改两处配置,一是数据库,二是 dubbo 配置:

(数据库名和 sql 文件的数据库名默一致认)

(address 指 zookeeper 地址,group 目前的仓库配置是一致的 )

admin (前台后端)

配置文件是 application-dev.yml,也是注意修改数据库配置和 dubbo 配置。

admin-ui (前台前端)

  • 执行 npm i 安装依赖
  • 执行 npm run dev 本地启动调试项目
  • 执行 npm run build 编译出静态页面文件,在 dist 目录下

默认账号密码:

  • 18518417985
  • 11111111 (8个1)

(不需要可以不改)开发时的后台地址:config/index.js 中配置

(不需要可以不改)部署时向后台请求的前缀: utils/server.js 中配置

jeecg-boot (后台后端)

后台后端包含三个子模块:

(1)首先需要配置 activiti-middleware 中 acctiviti.cfg.xml 的数据库配置:

注意:目前这个配置文件没办法提出到项目外面,只能打包到 jar 包里

(2)然后修改 jeecg-boot-module-system 模块中的 application-dev.yml 文件

这个配置文件中需要关注 3 个地方,一个是数据库配置,二是 dubbo 配置,三是 redis 配置

ant-design-vue-jeecg (后台前端 )

  • 执行 npm i 安装依赖
  • 执行 npm run serve 本地启动调试项目
  • 执行 npm run build 编译出静态页面文件,在 dist 目录下

默认账号密码:

  • admin
  • 123456

(不需要可以不改)开发时的后台地址:vue.config.js 中配置

(不需要可以不改)部署时向后台请求的前缀: utils/request.js 中配置

其他注意事项

  • 前端项目开发调试,目前启动和编译都是根路径
  • 前端项目编译出的都是静态文件,部署的时候要用 web 服务器

2. H5 电子办公

项目源码:http://10.10.77.113:8888/wangyu/scf_factoring

项目目录:

项目说明(一共 5 个):

导入数据文件

数据库要求:不区分大小写,(我用的 5.7 版本)

需要导入的数据库文件:

dubbo provider

和保理代理的一模一样。

admin (前台后端)

和保理代理的一模一样。

factorings-page (前台前端)

  • 执行 npm i 安装依赖
  • 执行 npm run serve 本地启动调试项目
  • 执行 npm run build 编译出静态页面文件,在 dist 目录下

默认账号密码:

  • 信用代码:111111(随便填)
  • 手机号码:18649332454
  • 密码:12345678

(不需要可以不改)开发时的后台地址:vue.config.js 中配置

(不需要可以不改)部署时向后台请求的前缀: vue.config.js 中配置(publicPath)

jeecg-boot (后台后端)

和保理代理的一模一样。

ant-design-vue-jeecg (后台前端 )

和保理代理的一模一样。

默认账号密码:

  • admin
  • 123456

其他注意事项

  • dubbo 的 group 配置一定要和保理代理项目区分开。

3. 参考 docker 命令

启动数据库:

启动 zookeeper:

启动 redis:

十一、附

(表一)代码仓库和项目对应关系

(表二)可信区块链测试(个人)进度

绿色标注为测试通过,红色标注为测试遇到报错未解决,有备注项为存疑待确认。

**这个测试列表以及测试进度和测试结果,仅仅代表个人情况。**一些明显可以通过的测试项,没有按部就班动手实际操作(也没有在列表上标注)。另外由于一些场外原因,这个列表后来没有再刻意的更新,仅做参考。

测试通过的测试项有操作记录,在 http://10.10.77.113:8888/wangyu/docs/可信区块链测试 目录下,但是内容相对简单,没有太大参考价值。测试过程中可能用到的关键操作,在这个交接文档上应该全部有涉及,再多的我也不知道了。