【fabric源码】Goland/Vscode调试Hyperledger Fabric 2.0源码、单机网络(傻瓜式调试)

引言

  • 启动一个peer和一个orderer
  • 使用fabric/sampleconfig下的配置文件(一个组织SampleOrg),生成创世块和通道配置
  • 创建通道myc,peer加入通道
  • 用fabric-sample中的fabcar作为例子,打包、安装、审核、提交链码,再初始化账本,创建一辆car,查询所有所有car。
  • 所有命令执行都使用debug模式,无需敲任何peer命令
  • 可调试链码

环境

  • macOS cataline 10.15.3
  • goland 2019.3 / vscode 1.43.0
  • go 1.14
  • docker-machine 0.16.0
  • docker 19.03.5
  • ss代理

1. 准备工作

注意:$GOPATH修改成你的GOPATH路径

1.1. 下载源码

cd $GOPATH/src/github.com/hyperledger/
git clone https://github.com/hyperledger/fabric.git
git checkout v2.0.1
git clone https://github.com/hyperledger/fabric-samples

下载慢的话需要配置下代理,这里我本地启动了ss代理

git config --global http.proxy socks5://127.0.0.1:1080
git config --global http.sslVerify false
git config --global https.proxy socks5://127.0.0.1:1080

取消代理

git config --global --unset http.proxy
git config --global --unset http.sslVerify 
git config --global --unset https.proxy

1.2.创建配置文件目录

cd fabric
mkdir -p dev-network/config

1.3. 拷贝配置文件、外部构建程序、链码demo

cp -r sampleconfig/* dev-network/
cp -r integration/externalbuilders dev-network/
cp -r $GOPATH/src/github.com/hyperledger/fabric-samples/chaincode $GOPATH/src/github.com/hyperledger/fabric/dev-network/

拷贝完后dev-network目录结构如下

├── chaincode
│   ├── abac
│   ├── abstore
│   ├── fabcar
│   ├── marbles02
│   ├── marbles02_private
│   └── sacc
├── config
├── configtx.yaml
├── core.yaml
├── externalbuilders
│   ├── binary
│   └── golang
├── msp
│   ├── admincerts
│   ├── cacerts
│   ├── config.yaml
│   ├── keystore
│   ├── signcerts
│   ├── tlscacerts
│   └── tlsintermediatecerts
└── orderer.yaml

1.4.修改peer配置文件dev-network/core.yaml

找到fileSystemPath,修改存储路径

peer:
     fileSystemPath: $GOPATH/src/github.com/hyperledger/fabric/dev-network/production/peer

使用docker跑链码配置(不支持调试chaincode):peer会调用docker api执行构建、运行链码等操作。
找到vm,修改endpoint和docker配置(请根据实际情况,修改成你自己docker配置)

vm:
    endpoint: tcp://192.168.99.100:2376
    docker:
        tls:
            enabled: true
            ca:
                file: /Users/USER/.docker/machine/machines/demo/ca.pem
            cert:
                file: /Users/USER/.docker/machine/machines/demo/cert.pem
            key:
                file: /Users/USER/.docker/machine/machines/demo/key.pem

外部跑链码配置(支持调试chaincode)

chaincode:
    externalBuilders:
    - path: $GOPATH/src/github.com/hyperledger/fabric/dev-network/externalbuilders/golang
      name: external-golang
      environmentWhitelist:
      - GOPROXY
      - GOCACHE
      - GOPATH

注意:package的时候label标签需要以-external结尾,eg:--label fabcarv1-external,如果需要修改默认的规则,请修改dev-network/externalbuilders/golang/bin/detect脚本

if [[ "$(jq -r .label "$2/metadata.json")" != *-external* ]]; then
    >&2 echo "only golang chaincode named with an '-external' suffix is supported"
    exit 1
fi

1.5.修改orderer配置文件dev-network/orderer.yaml

修改创世块文件位置(OPT,可不修改,后面01 orderer调试配置中有环境变量ORDERER_GENERAL_GENESISMETHODORDERER_GENERAL_GENESISFILE指定了创世块的位置)

General:
    BootstrapFile: $GOPATH/src/github.com/hyperledger/fabric/dev-network/config/orderer.block

修改账本数据目录

FileLedger:
    Location: $GOPATH/src/github.com/hyperledger/fabric/dev-network/production/orderer

1.6. 调试工具dlv安装、更新(opt,仅供参考)

xcode-select --install
go get -u github.com/go-delve/delve/cmd/dlv
sudo /usr/sbin/DevToolsSecurity -enable

1.7. docker machine启动(opt,仅供参考)

docker-machine start demo

启动后需要导入环境变量

1.8. 环境变量配置(opt,仅供参考)

~/.bash_profile

export GOROOT="/usr/local/Cellar/go/1.14/libexec"
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
export GO111MODULE=auto
export GOPROXY=https://goproxy.io
eval $(docker-machine env demo)

1.9. 安装外部构建依赖(opt,仅供参考)

brew install jq

2. 编译configtxgen

fabric使用dep管理依赖,如果使用go mod init转换成go.mod 会出现不能预知的错误(如viper版本过高,不能正确获取key值),如果GO111MODULE=on请设置为offauto

export GO111MODULE=auto

执行编译,构建这个程序主要为了创建创世块和通道配置

make configtxgen

3. 生成创世块和通道配置

cd dev-netwok
# 创世块
$GOPATH/src/github.com/hyperledger/fabric/build/bin/configtxgen -profile SampleDevModeSolo -channelID sys-channel -outputBlock ./config/orderer.block
# 通道配置
$GOPATH/src/github.com/hyperledger/fabric/build/bin/configtxgen -profile SampleSingleMSPChannel -outputCreateChannelTx ./config/myc.tx -channelID myc

检查是否config目录是否有文件生成

4.导入项目

4.1. 使用goland调试

  1. 用goland打开$GOPATH/src/github.com/hyperledger/fabric目录,会在当前目录下自动生成.idea目录

  2. 修改golang项目配置

cd $GOPATH/src/github.com/hyperledger/fabric
vim .idea/workspace.xml
  1. project下添加RunManager组件(用于调试或运行peer 和orderer等相关命令)
  
    
      
      
      
        
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
        
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
        
        
      
      
      
      
      
      
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
  

没问题的话,将看到下面图中的配置

【fabric源码】Goland/Vscode调试Hyperledger Fabric 2.0源码、单机网络(傻瓜式调试)_第1张图片

4.2. vscode调试

  1. vscode打开$GOPATH/src/github.com/hyperledger/fabric目录
  2. fabric目录下创建项目配置文件.vscode/launch.json,内容如下:
{
   // Use IntelliSense to learn about possible attributes.
   // Hover to view descriptions of existing attributes.
   // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
   "version": "0.2.0",
   "configurations": [


       {
           "name": "01 orderer",
           "type": "go",
           "request": "launch",
           "program": "${workspaceRoot}/cmd/orderer",
           "showLog": true,
           "trace": "log",
           "env": {
              "GO111MODULE": "auto",
              "ORDERER_GENERAL_LISTENADDRESS":"0.0.0.0",
              "ORDERER_GENERAL_GENESISMETHOD":"file",
              "ORDERER_GENERAL_GENESISFILE":"${workspaceRoot}/dev-network/config/orderer.block",
              "ORDERER_GENERAL_LOCALMSPID":"SampleOrg",
              "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network"
           },
           "args": [],
       },
       {
           "name": "02 peer",
           "type": "go",
           "request": "launch",
           "program": "${workspaceRoot}/cmd/peer",
           "showLog": true,
           "trace": "log",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"peer",
               "CORE_PEER_ADDRESS":"192.168.2.5:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",

           },
           "args": ["node","start","--peer-chaincodedev=true"]
       },
       {
           "name": "03 channel create",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["channel","create","-c", "myc","-f","${workspaceRoot}/dev-network/config/myc.tx","-o","127.0.0.1:7050"],
       },
       {
           "name": "04 channel join",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["channel","join","-b","myc.block"]
       },
       {
           "name": "05 chaincode package (docker)",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["lifecycle","chaincode","package","fabcar.tar.gz","--path","${workspaceRoot}/dev-network/chaincode/fabcar/go","--lang" ,"golang","--label", "fabcarv1"],
       },
       {
           "name": "05 chaincode package (externalbuilder)",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["lifecycle","chaincode","package","fabcar.tar.gz","--path","${workspaceRoot}/dev-network/chaincode/fabcar/go","--lang" ,"golang","--label", "fabcarv1-external"],
       },

       {
           "name": "06 chaincode install",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["lifecycle","chaincode","install","fabcar.tar.gz"]
       },

       {
           "name": "07 chaincode queryinstalled",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["lifecycle","chaincode","queryinstalled"]
       },
       {
           "name": "08 chaincode approve (docker)",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["lifecycle", "chaincode", "approveformyorg" ,"--channelID" ,"myc" ,"--name", "fabcar" ,"--version", "1.0", "--init-required", "--package-id", "fabcarv1:03bef137867a85ae6dac8b2b8c3f05d041a9b48597b41b346f1988d268705812" ,"--sequence" ,"1", "--waitForEvent"]
       },
       {
           "name": "08 chaincode approve (externalbuilder)",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["lifecycle", "chaincode", "approveformyorg" ,"--channelID" ,"myc" ,"--name", "fabcar" ,"--version", "1.0", "--init-required", "--package-id", "fabcarv1-external:71e92900aae6b5ed64d53f83940608c9235cd41decf370b346f4833cf3b83345" ,"--sequence" ,"1", "--waitForEvent"]
       },
       {
           "name": "09 chaincode checkcommitreadiness",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["lifecycle", "chaincode", "checkcommitreadiness" ,"--channelID" ,"myc", "--name" ,"fabcar" ,"--version", "1.0" ,"--init-required" ,"--sequence", "1"]
       },
       {
           "name": "10 chaincode commit",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["lifecycle", "chaincode","commit", "--channelID", "myc" ,"--name" ,"fabcar", "--version", "1.0" ,"--sequence" ,"1" ,"--init-required" ,"--waitForEvent"]
       },
       {
           "name": "11 chaincode querycommitted",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["lifecycle", "chaincode","querycommitted", "--channelID", "myc" ,"--output", "json"]
       },
       {
           "name": "12 chaincode  fabcar initLedger",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["chaincode" ,"invoke", "-C" ,"myc" ,"-n" ,"fabcar", "--isInit", "-c","{\"function\":\"initLedger\",\"Args\":[\"\"]}"]
       },
       {
           "name": "13 chaincode  fabcar create car",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["chaincode" ,"invoke", "-C" ,"myc" ,"-n" ,"fabcar", "-c","{\"function\":\"CreateCar\",\"Args\":[\"CAR9\",\"BYD\",\"唐dm\",\"Red\",\"Pld\"]}"]
       },
       {
           "name": "14 chaincode  fabcar QueryAllCars",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/cmd/peer",
           "env": {
               "GO111MODULE": "auto",
               "CORE_PEER_LOCALMSPID":"SampleOrg",
               "CORE_PEER_ID":"cli",
               "CORE_PEER_ADDRESS":"127.0.0.1:7051",
               "FABRIC_CFG_PATH":"${workspaceRoot}/dev-network",
           },
           "args": ["chaincode" ,"invoke", "-C" ,"myc" ,"-n" ,"fabcar",  "-c","{\"function\":\"QueryAllCars\",\"Args\":[\"\"]}"]
       }
       ,
       {
           "name": "15 chaincode debug fabcar",
           "type": "go",
           "request": "launch",
           "showLog": true,
           "trace": "log",
           "program": "${workspaceRoot}/dev-network/chaincode/fabcar/go",
           "env": {
               "GO111MODULE": "on",
               "CORE_CHAINCODE_ID_NAME":"fabcarv1-external:71e92900aae6b5ed64d53f83940608c9235cd41decf370b346f4833cf3b83345",
               "CORE_PEER_TLS_ENABLED":"false"
           },
           "args": ["-peer.address=192.168.2.5:7052"]
       }
       
       
   ]
}

没有问题的话,打开了调试窗口,将看到下面图中的配置
【fabric源码】Goland/Vscode调试Hyperledger Fabric 2.0源码、单机网络(傻瓜式调试)_第2张图片
注意:vscode的go插件默认使用go mod,须传入GO111MODULE=auto禁用go mod ,目录下没有go.mod的时候,不使用go mod构建,否则会出现以下错误。

can't load package: cannot find module providing package github.com/hyperledger/fabric/cmd/peer: working directory is not part of a module
exit status 1
Process exiting with code: 1

5. 开始调试

依次运行01~14配置,在需要的地方设置断点,观察控制台变化

  • 将配置02 peer中环境变量CORE_PEER_ADDRESS的值修改成你网卡ip地址(不能使用127.0.0.1之类的回环地址),否则链码无法连接到peer链码服务
  • 将配置02 peer中环境变量GOCACHE的值修改成go env GOCACHE获取的值,否则externalbuilder无法build
  • 05 chaincode package 有两个配置,需要调试链码请跑externalbuilder
  • 执行06 chaincode install07 chaincode queryinstalled 后需记录下Package ID,执行08 chaincode approve替换package-id的值,链码和标签修改都会导致package-id发生变化
  • 如果使用docker跑链码,执行10 chaincode commit后,执行docker ps查看链码容器是否启动,如果没有启动链码无法调用;如果使用externalbuilder跑链码,执行ps -ef | grep fabcarv1-external检查链码进程是否启动

6. debug chaincode(仅针对externalBuilder模式)

  1. 配置修改
    修改15 chaincode debug fabcar配置中参数
    环境变量CORE_CHAINCODE_ID_NAMEpackage-id
    参数-peer.address参数指定peer的链码服务监听地址。

  2. 下载依赖

 cd chaincode/fabcar/go 
 go get -t github.com/hyperledger/fabric-contract-api-go/contractapi
  1. 杀掉peer启动的chaincode进程(下一步启动成我们自己的chaincode进程)
ps -ef | grep fabcarv1-external | grep -v grep | awk '{print $2}'|xargs kill -9
  1. 打好断点,启动调试程序15
  2. 启动配置13或14调用chaincode ,检查断点是否有效

你可能感兴趣的:(fabric)