注意:不要在有生产环境的服务器上进行学习测试,(docker-compose关闭服务的时候会清除服务器上所有正在运行的的docker容器)
参考课程:优快云_超级账本智能合约与DApp
环境配置
目录结构
在gopath中创建
mkdir src
mkdir bin
mkdir pkg
在src中创建mkdir github.com
在github.com中创建mkdir hyperledger
docker安装
一行命令,完成安装:(安装之后记得要把docker服务启动起来)
curl -sSL https://get.daocloud.io/docker | sh
service docker start
而且源在国内
docker-compose安装
通过curl进行安装:
curl -L https://github.com/docker/compose/releases/download/1.7.0/docker-compose-``uname -s ``-``uname -m`` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose -v
go安装与配置
参考:http://dicemy.com/29920#Go%E8%AF%AD%E8%A8%80%E5%AE%89%E8%A3%85
一定要注意环境变量的配置
jdk安装
yum list java*
yum install -y java-1.8.0-openjdk-devel.x86_64
java -version
下载fabric的docker镜像
除了baseos下载0.3.1,其余都下1.0.0,然后标记为latest
tools:docker pull hyperledger/fabric-tools:x86_64-1.0.0
ccenv:docker pull hyperledger/fabric-ccenv:x86_64-1.0.0
ca:docker pull hyperledger/fabric-ca:x86_64-1.0.0
orderer:docker pull hyperledger/fabric-orderer:x86_64-1.0.0
peer:docker pull hyperledger/fabric-peer:x86_64-1.0.0
baseos:docker pull hyperledger/fabric-baseos:x86_64-0.3.1
纯命令版:
docker pull hyperledger/fabric-tools:x86_64-1.0.0
docker pull hyperledger/fabric-ccenv:x86_64-1.0.0
docker pull hyperledger/fabric-ca:x86_64-1.0.0
docker pull hyperledger/fabric-orderer:x86_64-1.0.0
docker pull hyperledger/fabric-peer:x86_64-1.0.0
docker pull hyperledger/fabric-baseos:x86_64-0.3.1
注意:记得在所有的安装之后进行tag 编辑成latest状态否则会出现问题
docker tag xxxx xxxx:latest
docker tag hyperledger/fabric-tools:x86_64-1.0.0 hyperledger/fabric-tools:latest
docker tag hyperledger/fabric-ccenv:x86_64-1.0.0 hyperledger/fabric-ccenv:latest
docker tag hyperledger/fabric-ca:x86_64-1.0.0 hyperledger/fabric-ca:latest
docker tag hyperledger/fabric-orderer:x86_64-1.0.0 hyperledger/fabric-orderer:latest
docker tag hyperledger/fabric-peer:x86_64-1.0.0 hyperledger/fabric-peer:latest
docker tag hyperledger/fabric-baseos:x86_64-0.3.1 hyperledger/fabric-baseos:latest
下载fabric源码库
在hyperledger目录下进行git clone https://github.com/hyperledger/fabric.git
git checkout release-1.0
cd /home/gopath/src/github.com/hyperledger/fabric/common/configtx/tool/configtxgen
对工具进行编译。
go install --tags=nopkcs11
注意!!!
奇怪的错误请输入:go env -w GO111MODULE=auto
一定要把这个项目文件的src放在go环境设置下的gopath的文件夹中,输入go env可以查看go安装环境中的gopath文件夹。否则会出现找不到包的报错。
对另一个工具进行编译。
cd /home/gopath/src/github.com/hyperledger/fabric/common/tools/cryptogen
go install --tags=nopkcs11
编译好的工具如下:
下载fabric-samples
cd /home/gopath/src/github.com/hyperledger
git clone https://github.com/hyperledger/fabric-samples.git
git checkout release-1.0
Hello World
1.查看目录
.env:存储一些环境变量
base:储存docker-compose的一些公共服务
byfn.sh:执行脚本
configtx.yaml和crypto-config.yaml:根据之前生成的2个工具,生成相应的配置文件,用来启动网络,放到当前目录的channel-artifacts和crypto-config里面
docker-compose:用于启动网络
scripts:存放测试脚本,做的事:创建通道,加入通道,安装链码,实例化链码,链码交互
2.生成配置
./byfn.sh -m generate -i 1.0.0
注意!!!!
一定要记得吧gopath中的bin目录添加到环境变量中,否则可能无法调用刚才编译好的configtxgen和cryptogen工具
可以通过 export PATH=$PATH:/home/gopath/bin 来临时添加或者使用vim ~/.bash_profile修改PATH 一行,之后使用source ~/.bash_profile生效。
3.启动网络,自动运行测试脚本
./byfn.sh -m up -i 1.0.0
4.关闭网络,自动清楚配置和docker进程
./byfn.sh -m down -i 1.0.0
Hello World 分析
1.查看日志,order和peer分离
peer是按照组织或主体分离的,每一个组织生成ca(存储证书和私钥),msp(存储管理员证书和中间证书),peers(存储每一个peer相关的证书),users(存储每一个用户的证书)
2.查看如下配置
genesis.block:整个网络的创世区块
channel.tx:创建的通道的配置
Org1MSPanchors.tx和Org2MSPanchors.tx:两个主体的锚节点配置
3.启动网络,接着分析日志
fabric网络启动完毕
指定通道名称,和一些变量,通道创建完成
4个peer加入通道
组织中的锚节点在通道中update成功

链码安装到了peer节点
链码实例化
在peer0上进行查询操作,成功
圈圈的是查询结果,查询成功,查询结果为100
进行修改操作,成功
再次查询,结果为90
查看docker进程
3个链码会生成3个image
查看脚本
可以按脚本中的位置找到链码
实现了Init和Invoke接口,就代表是一个fabric智能合约
Init:首先获取参数,不为4个则报错,最终将A和B存到数据库中
Invoke:设置了3个方法,(invoke,delete,query)
invoke:接受3个参数,(谁给谁转账,赚多少)
A给B转账。
持久化数据
接受1个值,从数据库中删除
查询操作,结果以json形式返回
main里只start或者进行一些验证,不写其他代码
srcipts中:初始化操作,A有100元,B有200元
查询A有多少钱,所以打印了100
A给B转账10元
fabric系统架构
架构图
-
应用层
-
API:提供了GRPC,(谷歌)RPC框架
-
SDK:在API基础上封装的SDK,go,java,python,nodejs
-
事件:分布式系统中,达成共识需要一定的时间,fabric使用异步通信模式开发,触发回调函数执行。
-
身份:依托于底层的成员服务,是联盟链的认证功能,例如CA
-
账本:区块链的查询数据,是账本中查出来的,区块高度+交易ID,不重复
-
交易:对区块链数据进行修改,先提交交易到背书节点,签名认证之后再执行。
-
智能合约:做合约的安装,实例化和升级
-
区块链底层
-
成员服务:提供证书,用于加密和签名
-
共识服务:CAP(不能全满足,只能满足2个,一致性,可用性和分区容忍性),实际上区块链是弱化了可用性和分区容忍性,所以需要共识算法保证一致性。fabric的共识大概分为三个阶段:
- 首先客户端向背书节点发送一个背书提案,背书节点进行交易模拟,将背书节点和签名返回客户端。
- 然后将背书后的交易,交给排序节点进行排序。有排序节点生成区块,向全网广播。网络节点接受到广播后,先验证区块交易的正确性。
- 验证通过后,存入本地账本。
- PS:排序节点与组织的锚节点使用的是GRPC通信,组织内使用的是gossip协议通信
-
链码服务:提供安全的,可隔离的交易环境。所以fabric使用docker,链码直接与docker通信。目前阶段对k8s支持的不好,会出问题。
-
安全及密码服务:fabric定义了一个BCCSP接口,定义签名,加密解密功能,是默认实现了一套国际通用的密码服务,如sha256等
网络拓扑图
- 概念:
- 客户端节点:应用程序和底层的交互媒介,与上层和peer和orderer连接发挥作用,连接peer做交易模拟
- peer节点:包含了锚节点(主节点),在一个组织内可以有多个peer,一个组织中锚节点只有一个,锚节点的作用(与orderer进行通信),锚节点需要HA支持,若锚节点挂了,组织内会选举新的节点与orderer节点进行通信,**背书节点(Endorse)**理解为担保,与智能合约绑定的,每一个智能合约安装到区块链中,会有一个专属的背书策略,**记账节点(committer)**所有的peer节点都是记账节点。用于验证从orderer接受的区块,验证交易的有效性,验证通过后,同步到本地账本。
- orderer节点:排序节点,接受全网客户端节点的交易信息,按照一定规则进行排序,将排序好的交易,按照固定的时间间隔打包成区块。与其他组织的主节点进行通信,排序可以用solo(整个网络中只有一个排序节点,使用于开发和测试)和kafka(生产环境下使用,分布式消息队列)模式
- CA节点:可选的,作用:颁发证书,只用被CA认证的节点才能进行交易,fabric不存在51%攻击问题。
- 动作和行为:
- 注册登记:与客户端发起,向CA机构表明自己的身份,获取证书,上图中是第三方的CA,也可以使用官方提供的CA。
- 交易提案:向组织的背书节点提交请求,对应peer节点,组织可以理解为现实中的商业主体,组织是独立的,有两个个数据来源。
- 提交交易:客户端节点向排序节点发请求,orderer内部进行排序打包成区块,广播给其他组织的锚节点,上图是基于kafka实现的,每个组织会选择一个orderer节点进行通信。
交易流程
- 客户端提交交易,最终到记账节点同步数据。
- 智能合约按照要指定背书节点,正常情况下,背书节点返回相同的结果,但签名是不一样的。
- 背书是模拟的过程,不会持久化
- 1,2,3是交易模拟,4,5,6是交易排序,7,8,9是交易同步和记账。交易模拟对应智能合约,交易排序对应共识机制,同步和记账对应账本存储
fabric共识排序
共识机制
- 达成公式需要3个阶段,交易背书,交易排序,交易验证。
- 交易背书:模拟的
- 交易排序:确定交易顺序,最终将排序好的交易打包区块分发。
- 交易验证:区块储存前要进行一下交易验证(不是所有的orderer的东西都能存进去)
Orderer节点的作用
-
交易排序
- 目的:保证系统的最终一致性(有限状态机)
- solo:单节点排序
- kafka:外置的分布式消息队列
-
区块分发:
- orderer中的区块并不是最终持久化的区块,
- 是一个中间状态的区块
- 包含了所有交易,不管是有有效还是无效,都会打包传给组织的锚节点。
-
多通道的数据隔离
- 客户端可以使用某个通道,发送交易
源码目录
-
从goland中阅读
-
源码目录
- bccsp:与密码学相关的,加密,数字签名,证书,将密码学中的函数抽象成了接口,方便调用和扩展
- bddtests:行为驱动开发,从需求直接到开发
- common:公共库,错误处理,日志处理,账本存贮,相关工具
- core:是fabric核心库,子目录是各个模块的目录
- comm:网络通信相关
- devenv:官方提供的开发环境,使用的是Vagrant
- docs:文档
- events:事件监听机制
- gossip:通信协议,组织内部的通信,区块同步
- gotools:用于编译
- images:docker镜像相关的
- msp:成员服务管理,member serivce provider 读取证书做签名
- orderer:排序节点
- peer:peer节点
- proposals:用于扩展,新功能的提案
- protos:数据结构的定义
-
共识机制源码
如果使用goland查看源码时import全部标红的话,进入这个设置,将第一个Enable Go … 这个框勾掉即可。
-
orderer节点的源码
-
首先看orderer目录下的main.go
-
main.go里有一个NewServer
-
从sever.go可以具体查看交易收集和广播区块
-
点击Manager,进入Manager.go查看源码(还在sever.go里)
-
点击chainsupport,查看(在manager.go中)
-
点receiver进去,看区块切割(在chainsupport.go中)
回顾共识机制源码
- main.go是入口,orderer节点的初始化
- manager.go是控制中枢,是对链的操作,拿到chainsupport对象
- chainsupport.go链对象额代理,与链式对应的关系
- Cut()方法是区块切割
- solo和kafka相关的设置
- sever.go有两个Handle,是交易收集和区块扩散的方法
- 将共识简化为了排序,最终一致性
fabric账本存储
账本存储概念
-
peer节点做账本存储
-
orderer是临时存储区块,peer节点时账本存储的持久化,会改变世界状态。
-
文件系统,区块是存储为文件
-
区块索引,用于查询区块,是用levelDB实现的
-
状态数据库,一般村存放区块链最新状态,数据不需要HA,可以从文件系统再次获取,couchDB支持模糊查询
交易读写集
-
回忆交易流程
- 交易模拟
- 在背书节点执行模拟时,最终返回交易读写集(RWset),告诉区块链在交易中读写了哪些数据
- 交易排序
- 交易验证,交易验证后,更新世界状态,更新的就是读写集中的写集
- 交易模拟
-
交易读写集的3个概念
- 读集:包含键的列表,键的提交版本,读取赌赢的值,返回的是已提交的状态的值(读已提交),不能读取交易过程中写入的数据。
- 写集:包含键的列表,写入的数据的值,如果多次写入,以最后一次为准。
- 版本号:用区块高度和交易编号组成的。
-
交易验证阶段是对读写集进行验证(验证读集)
- 验证读集的版本号是和否等于世界状态的版本号
账本存储相关概念
-
世界状态
- 交易执行后,所有键的最新值
-
历史数据索引(可选)
-
区块储存
- 按照文件去存 blockfile_xxxx
- 文件大小是64M,若修改,需要重新编译peer源码
- 账本最大容量64M*
-
区块读取
- 区块文件流
- 区块流
- 迭代器
-
区块索引
- 键:区块高度,区块哈希,交易哈希
- 值:区块文件编号,文件内的偏移量,区块数据的长度
-
区块提交
-
保存到文件
账本存储相关源码
- 从4方面看,读写集,状态数据, 历史数据,区块文件
- 可以先从core/ledger 下的 ledger_interface.go 中看大体结构
- 读写集,分为交易读写集的生成和交易读写集的验证两个部分去看。
- 交易读写集生成
- fabric/core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/lockbased_tx_simulator.go
- 交易读写集验证
- fabric/core/ledger/kvledger/txmgmt/validator/statebasedval/state_based_validator.go
- 交易读写集生成
- 状态数据库:看levelDB的实现
- fabric/core/ledger/kvledger/txmgmt/statedb/stateleveldb/stateleveldb.go
- 历史数据库:看levelDB的实现
- fabric/core/ledger/kvledger/history/historydb/historyleveldb/historyleveldb.go
- 区块文件读取
- fabric/common/ledger/blkstorage/fsblkstorage/fs_blockstore.go
- 区块流:fabric/common/ledger/blkstorage/fsblkstorage/block_stream.go
账本存储相关源码总结
- 首先看了账本根存储的根目录的接口,从宏观上把握
- 交易读写集的生成和验证
- 数据库增删改查
- 要有一个没有实现的方法,数据剪裁的接口,可能去解决数据无限增长的处理
fabric智能合约
智能合约
fabric_asset配置好的文件下载:点击下载fabric_asset.zip
-
执行环境:以太坊虚拟智能合约执行环境EVM,fabric执行环境是docker
-
链码
- 是应用层和区块链底层的中间点
- 每一个链码执行环境是一个独立的docker
- 使用GRPC协议与背书节点通讯,只有背书节点才能运行智能合约
-
链码的生命周期
- 打包,智能合约的编写和编译
- 安装,将打包好的文件,上传到背书节点
- 实例化,实际的安装了,执行Init方法,只执行一次,构造函数
- 升级,升级和修复链码
- 交互,自己定义的方法的调用
-
链码的交互流程
-
系统链码(了解)
- LSCC:管理链码的生命周期
- CSCC:配置管理链码,管理链的配置
- QSCC:查询账本存储,是一个区块索引的外部服务
- ESCC:交易背书的链码,交易执行后的链码进行封装签名,给客户端返回背书交易结果。
- VSCC:交易验证的链码
-
链码编程的接口
- Init():链码初始化,只执行一次
- Invoke():链码的业务逻辑的编写
- 上面2个方法参数一样,参数是SDK的接口
-
链码SDK的接口
- 写代码再看
-
一些注意点
- 分布式多机多节点执行,链码会执行很多次
- 不写随机函数,交易会无效,多次执行不一样
- 系统时间不写,多机时间不一定一样
网络搭建配置的实现
-
crypto-config.yaml:用于配置组织节点的个数,参考firstnetwork去编写
-
编写好后,传到linux对应目录
-
进入deploy目录,设置工作目录为当前目录
export FABRIC_CFG_PATH=$GOPATH/src/fabric_asset/deploy
-
指定按照yaml文件生成配置
cryptogen generate --config=./crypto-config.yaml
-
configtx.yaml:用于区块联盟中的组织信息,配合名字和证书等的位置,参考firstnetwork去编写
-
编写好后,传到linux对应目录
-
创建用于存放配置的目录
-
生成系统链的创世区块
-
-profile 指定联盟配置,-outputBlock 指定存放的位置
configtxgen -profile OneOrgsOrdererGenesis -outputBlock ./config/genesis.block
-
生成通道的创世交易
-
profile 指定业务联盟,outputCreateChannelTx存放的路径,插件的名字叫做mychannel
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./config/mychannel.tx -channelID mychannel
注意:如果使用虚拟机为平台的话,会出现用ssh连接执行命令执行出错的情况发生,具体原因不详,但是在虚拟机上可以正常执行并生成成功。
-
生成两个组织锚节点的交易信息
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./config/Org0MSPanchors.tx -channelID mychannel -asOrg Org0MSP
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./config/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
-
将docker-compose.yaml拖进deploy目录
启动网络
-
启动docker,后台运行
-
查看orderer节点的运行日志
-
与客户端交互操作
-
创建通道
-
-o 指定与哪个orderer节点进行通信,-c指定创建的通道名称,-f指定使用的文件
出现的错误一般情况下是docker-compose中书写有误,e.g.映射路径中etc目录写成了ect
-
加入通道
-
查看peer加入的通道列表:
-
指定主节点
-
基础网络完成了
-
安装链码
-
-n是安装的名字,-v是version,-l是使用的语言
-
克隆一个会话,交互执行peer0,查看安装的链码
-
链码实例化
-
链码交互执行
-
多次执行查询,得到的结果不同,因为invoke()中使用了随机数,不要这么做。
fabric链码案例
链码入门
-
编写hello.go,完成后,拖到linux对应目录
-
安装链码
-
-n是安装的名字,-v是version,-l是使用的语言
-
实例化链码
-
链码调用
账户相关链码
-
Init()方法与例子程序类似
-
Invoke()方法包含query,invoke,set,get,
-
编写完成后拖到linux对应目录
-
启动容器
-
交互执行
-
创建通道
-
加入通道
-
设置主节点
-
安装链码
-
实例化链码
-
查询user1的余额
-
user1给user2转200元
-
向user1存100元
-
向user1取200元
贷款还款相关链码
-
编写Trace下的代码,编写好后,拖到对应linux目录
-
保证网络基础OK的情况下,安装链码
-
实例化链码
-
运行测试
-
贷款500W
-
还款500
公民身份信息相关链码
-
编写citizens下的代码,编写好后,拖到对应linux目录
-
安装链码
-
链码实例化
-
身份查询
合约相关链码
-
编写contract下的代码,编写好后,拖到对应linux目录
-
安装链码
-
链码实例化
-
发布合约
-
响应合约
-
合约成交
-
合约关闭
-
查询合约的最新数据
-
查询合约所有数据
fabric链码案例
流程整理
- 让什么数据上链
- 所有节点备份数据耗费空间,视频等不要上链
- 如何交互
- -c “Args”:[方法名,参数]
- 编写合约
- Init
- Invoke
- 拖到linux运行,基于配置好的网络去部署运行(安装和实例化)
- 合约交互
- SDK调用(页面点击或输入信息)
需求分析
- 开发转让资产
- 功能
- 用户开户和销户
- 资产登记,资产上链,与具体的用户绑定
- 资产转让,资产的所有权变更
- 查询功能,用户查询,资产查询,资产变更的历史查询
- 业务实体
- 用户
- 名字
- 身份证(表示)
- 资产列表
- 资产
- 名字
- 标识
- 特殊属性列表(车:排量,品牌,座位)
- 资产的变更记录
- 资产标识
- 资产的原始拥有者
- 资产变更后的拥有者
- 用户
- 交互方法
- 用户开户
- 参数:名字,标识
- 用户销户
- 标识
- 资产登记
- 名字,标识,特殊属性列表,拥有者
- 资产转让
- 拥有者,资产标识,受让者
- 用户查询
- 参数:标识,返回值:用户实体
- 资产查询
- 参数:标识,返回值:资产实体
- 资产的变更查询
- 参数:资产标识,返回值:资产的变更列表
- 用户开户
合约编写
-
合约编写完成,传到linux对应目录
-
创建通道的创世交易(channel名字不能有大写)
-
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./config/assetschannel.tx -channelID assetschannel
如果出现这个提醒
很有可能是FABRIC_CFG_PATH环境变量没有配置成功,可以直接在deploy目录下设置
export FABRIC_CFG_PATH=$PWD
再次执行该命令即可 -
交互执行
-
创建通道
-
加入通道
-
查看通道
-
安装链码
-
链码实例化
-
注册
-
用户查询
-
资产登记
-
资产查询,查询用户资产绑定
-
注册了第二个用户
-
资产转让
-
查询用户二的用户状态
-
查询资产一的状态
-
查询所有资产的变更历史
-
注销用户2,下面的资产也会随之注销
链码开发者模式
-
将docker-compose关闭
-
修改docker-compose配置
-
运行docker
-
在另一个会话找到编写好的智能合约
-
运行链码
-
在另一个会话进入交互执行
-
链码安装,实例化,调用之后,修改链码
-
将第二个,链码运行的对话ctrl+C结束,重新运行链码执行命令
-
注意:链码开发用这个模式没问题,SDK调用时,可能会出现问题,开发完智能合约关掉开发者模式
外部服务分析
- 如何提供外部服务
- 企业内部各种数据接口,rpc,grpc
- 网站(web),手机(app),通过http
- 智能硬件,socket服务
- SDK提供外部服务,SDK的语言选择
- node.js(官方推荐,效率 9颗星)
- java(实际使用量最大的 9颗星)
- python(使用不太多 3颗星)
- golang(不稳定,常用方法也没有,1颗星)
- SDK的模块
- 区块链的管理:例如通道的创建和加入,链码的安装,实例化等
- 数据查询:区块和交易的查询
- 区块链交互(链码交互):发起交易,invoke,query
- 事件监听:业务事件,系统事件
JavaSDK的使用
maven
为什么使用maven
maven能解决哪些问题?
- 引入jar包
- 解决jar包之间的依赖关系
- 自动获取第三方jar包
- 将项目拆分成多个功能模块
maven简介
1.什么是构建?
- 从开发到运行的一个过程
2.构建的环节
- 清理:删除以前的编译结果,为重新编译做准备
- 编译:将java编译成.class
- 测试:对项目中关键点进行自动测试
- 报告:日志打印
- 打包:将java项目打包成.jar文件,加你个JavaWeb的项目打成.war包
- 安装:将打包结果(jar包或war包),安装到maven仓库
- 部署:将打包结果部署到远程仓库,或者将war部署到服务器上运行。
3.自动化构建
- maven进行自动化构建
maven安装
1.安装
-
解压到一个目录
-
配置环境变量,并加入PATH
-
打开cmd验证安装
-
maven仓库默认目录为
-
修改仓库路径,将settings.xml放到.m2下
-
修改settings.xml,指定仓库位置
Eclipse里配置maven
-
如下
-
去掉勾选
-
使用自己解压的maven
maven工程的创建
创建java工程
-
创建项目
-
创建简单工程
-
填写坐标,选择打包方式
创建web工程
maven仓库
1.仓库的分类
- 本地仓库
- 将maven所有jar存储到本地硬盘
- 远程仓库
- 中央仓库:为全世界所有maven工程提供服务的
- 中央仓库的镜像:亚洲镜像
- 私服:在公司内网自己人访问,
2.仓库中的文件
- 存储三类文件
- maven的插件
- 自己开发的项目模块
- 第三方框架或工具jar包
maven详解
1.maven报错
- 创建工程直接报错,插件下载不完整
2.约定的目录结构
- src/main/java 主程序源码目录
- src/main/resources 主程序配置文件目录
- test是测试的
- target编译结果的目录
3.POM文件
- Project Object Model:项目对象模型
- pom是maven的核心配置
maven父子工程
创建父工程
创建子工程
maven聚合工程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9pjuWAcC-1680336051093)(C:/Users/aa/AppData/Roaming/Typora/typora-user-images/image-20220314191515684.png)]
SDK的下载和编译
-
下载并解压
-
编译前,需要有JDK,maven,编译好仓库位置。
-
进入解压目录,cmd中输入 mvn install -DskipTests,跳过测试并编译
-
有报错的,先将pl.搜出来,注释掉。
-
编译完成,最后将jar包部署到了仓库的如下位置。
搭建网络&&部署链码
-
将编写好的工程传到linux
-
给脚本执行权限
-
启动网络
-
进入容器
-
查看通道
-
安装链码
-
实例化链码
-
将a设置为123
-
取出a
java外部服务调用
-
创建maven工程
-
工程根目录下创建一个cert目录,用于存放证书和私钥
-
将log4j.xml放到resources下
-
编写代码
- 首先定义一个实现了User接口的类