• centos7.6部署fabric以及链码


    参考
    Fabric学习
    Fabric2.2 全面学习

    如果是最小化安装

    遇到找不到命令时,自行用yum安装
    如
    yum install vim
    yum install wget
    
    • 1
    • 2
    • 3
    • 4

    环境

    yum -y install git 		
    git --version
    
    
    yum -y install curl 		
    curl --version
    
    
    sudo yum install -y yum-utils
    sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
        
    
    sudo yum install docker-ce docker-ce-cli containerd.io
    sudo systemctl start docker
    sudo systemctl enable docker
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://ppztf0yr.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    
    curl -L https://get.daocloud.io/docker/compose/releases/download/1.26.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    chmod +x /usr/local/bin/docker-compose
    docker-compose version
    
    cd /usr/local
    wget https://studygolang.com/dl/golang/go1.14.7.linux-amd64.tar.gz
    tar -zxvf go1.14.7.linux-amd64.tar.gz
    
    
    vim /etc/profile  
    # 添加如下
    #export GOROOT=/usr/local/go
    #export GOPATH=$HOME/go
    #export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
    source /etc/profile
    
    go version
    go env -w GO111MODULE=on
    go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    安装fabric-samples

    cd /usr/local
    mkdir hyperledger 
    cd hyperledger
    touch bootstrap.sh
    
    • 1
    • 2
    • 3
    • 4

    我这里给出bootstrap.sh文件内容,

    #!/bin/bash
    #
    # Copyright IBM Corp. All Rights Reserved.
    #
    # SPDX-License-Identifier: Apache-2.0
    #
    
    # if version not passed in, default to latest released version
    VERSION=2.2.0
    # if ca version not passed in, default to latest released version
    CA_VERSION=1.4.8
    ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m |sed 's/x86_64/amd64/g')" |sed 's/darwin-arm64/darwin-amd64/g')
    MARCH=$(uname -m)
    : ${CONTAINER_CLI:="docker"}
    
    printHelp() {
        echo "Usage: bootstrap.sh [version [ca_version]] [options]"
        echo
        echo "options:"
        echo "-h : this help"
        echo "-d : bypass docker image download"
        echo "-s : bypass fabric-samples repo clone"
        echo "-b : bypass download of platform-specific binaries"
        echo
        echo "e.g. bootstrap.sh 2.4.6 1.5.5 -s"
        echo "will download docker images and binaries for Fabric v2.4.6 and Fabric CA v1.5.5"
    }
    
    # dockerPull() pulls docker images from fabric and chaincode repositories
    # note, if a docker image doesn't exist for a requested release, it will simply
    # be skipped, since this script doesn't terminate upon errors.
    
    dockerPull() {
        #three_digit_image_tag is passed in, e.g. "1.4.7"
        three_digit_image_tag=$1
        shift
        #two_digit_image_tag is derived, e.g. "1.4", especially useful as a local tag for two digit references to most recent baseos, ccenv, javaenv, nodeenv patch releases
        two_digit_image_tag=$(echo "$three_digit_image_tag" | cut -d'.' -f1,2)
        while [[ $# -gt 0 ]]
        do
            image_name="$1"
            echo "====> hyperledger/fabric-$image_name:$three_digit_image_tag"
            ${CONTAINER_CLI} pull "hyperledger/fabric-$image_name:$three_digit_image_tag"
            ${CONTAINER_CLI} tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name"
            ${CONTAINER_CLI} tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name:$two_digit_image_tag"
            shift
        done
    }
    
    cloneSamplesRepo() {
        # clone (if needed) hyperledger/fabric-samples and checkout corresponding
        # version to the binaries and docker images to be downloaded
        if [ -d test-network ]; then
            # if we are in the fabric-samples repo, checkout corresponding version
            echo "==> Already in fabric-samples repo"
        elif [ -d fabric-samples ]; then
            # if fabric-samples repo already cloned and in current directory,
            # cd fabric-samples
            echo "===> Changing directory to fabric-samples"
            cd fabric-samples
        else
            echo "===> Cloning hyperledger/fabric-samples repo"
            git clone -b main https://github.com/hyperledger/fabric-samples.git && cd fabric-samples
        fi
    
        if GIT_DIR=.git git rev-parse v${VERSION} >/dev/null 2>&1; then
            echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
            git checkout -q v${VERSION}
        else
            echo "fabric-samples v${VERSION} does not exist, defaulting to main. fabric-samples main branch is intended to work with recent versions of fabric."
            git checkout -q main
        fi
    }
    
    # This will download the .tar.gz
    download() {
        local BINARY_FILE=$1
        local URL=$2
        echo "===> Downloading: " "${URL}"
        curl -L --retry 5 --retry-delay 3 "${URL}" | tar xz || rc=$?
        if [ -n "$rc" ]; then
            echo "==> There was an error downloading the binary file."
            return 22
        else
            echo "==> Done."
        fi
    }
    
    pullBinaries() {
        echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
        download "${BINARY_FILE}" "https://github.com/hyperledger/fabric/releases/download/v${VERSION}/${BINARY_FILE}"
        if [ $? -eq 22 ]; then
            echo
            echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
            echo
            exit
        fi
    
        echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
        download "${CA_BINARY_FILE}" "https://github.com/hyperledger/fabric-ca/releases/download/v${CA_VERSION}/${CA_BINARY_FILE}"
        if [ $? -eq 22 ]; then
            echo
            echo "------> ${CA_TAG} fabric-ca-client binary is not available to download  (Available from 1.1.0-rc1) <----"
            echo
            exit
        fi
    }
    
    pullDockerImages() {
        command -v ${CONTAINER_CLI} >& /dev/null
        NODOCKER=$?
        if [ "${NODOCKER}" == 0 ]; then
            FABRIC_IMAGES=(peer orderer ccenv tools)
            case "$VERSION" in
            2.*)
                FABRIC_IMAGES+=(baseos)
                shift
                ;;
            esac
            echo "FABRIC_IMAGES:" "${FABRIC_IMAGES[@]}"
            echo "===> Pulling fabric Images"
            dockerPull "${FABRIC_TAG}" "${FABRIC_IMAGES[@]}"
            echo "===> Pulling fabric ca Image"
            CA_IMAGE=(ca)
            dockerPull "${CA_TAG}" "${CA_IMAGE[@]}"
            echo "===> List out hyperledger docker images"
            ${CONTAINER_CLI} images | grep hyperledger
        else
            echo "========================================================="
            echo "${CONTAINER_CLI} not installed, bypassing download of Fabric images"
            echo "========================================================="
        fi
    }
    
    DOCKER=true
    SAMPLES=true
    BINARIES=true
    
    # Parse commandline args pull out
    # version and/or ca-version strings first
    if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
        VERSION=$1;shift
        if [ -n "$1" ]  && [ "${1:0:1}" != "-" ]; then
            CA_VERSION=$1;shift
            if [ -n  "$1" ] && [ "${1:0:1}" != "-" ]; then
                THIRDPARTY_IMAGE_VERSION=$1;shift
            fi
        fi
    fi
    
    # prior to 1.2.0 architecture was determined by uname -m
    if [[ $VERSION =~ ^1\.[0-1]\.* ]]; then
        export FABRIC_TAG=${MARCH}-${VERSION}
        export CA_TAG=${MARCH}-${CA_VERSION}
        export THIRDPARTY_TAG=${MARCH}-${THIRDPARTY_IMAGE_VERSION}
    else
        # starting with 1.2.0, multi-arch images will be default
        : "${CA_TAG:="$CA_VERSION"}"
        : "${FABRIC_TAG:="$VERSION"}"
        : "${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"}"
    fi
    
    BINARY_FILE=hyperledger-fabric-${ARCH}-${VERSION}.tar.gz
    CA_BINARY_FILE=hyperledger-fabric-ca-${ARCH}-${CA_VERSION}.tar.gz
    
    # then parse opts
    while getopts "h?dsb" opt; do
        case "$opt" in
            h|\?)
                printHelp
                exit 0
                ;;
            d)  DOCKER=false
                ;;
            s)  SAMPLES=false
                ;;
            b)  BINARIES=false
                ;;
        esac
    done
    
    if [ "$SAMPLES" == "true" ]; then
        echo
        echo "Clone hyperledger/fabric-samples repo"
        echo
        cloneSamplesRepo
    fi
    if [ "$BINARIES" == "true" ]; then
        echo
        echo "Pull Hyperledger Fabric binaries"
        echo
        pullBinaries
    fi
    if [ "$DOCKER" == "true" ]; then
        echo
        echo "Pull Hyperledger Fabric docker images"
        echo
        pullDockerImages
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199

    运行下载程序
    注意最后这三个if...fi,分别是克隆fabric-samples文件夹、获得bin和config文件夹、拉取镜像的作用
    其中pullBinaries耗时最长,最易出错,最易搞心态,建议单独执行(或者往下面看)
    即可以先将137行的BINARIES=true改为BINARIES=false,执行bootstrap.sh,再重新设BINARIES=true,并将其他两个设为false,再执行bootstrap.sh,并将第二次获得到的bin和config目录移入fabric-samples文件夹内
    如果出现

    可以出现 /bin/bash^M: 坏的解释器: 没有那个文件或目录,解决方案如下:
    在这里插入图片描述

    如果克隆fabric-samples失败,即设SAMPLES=true并运行后无fabric-samples文件夹出现,则自己手动安装(因为这个也挺花时间的)

    git clone -b main https://github.com/hyperledger/fabric-samples.git
    cd fabric-samples
    git checkout -q v2.2.0
    git checkout -b branch
    
    • 1
    • 2
    • 3
    • 4

    如果下载二进制文件的时间很长很长,可以考虑在windows上通过Github直接下好再上传到服务器上,因为shell里下载的方法就是git。将这两个文件在/usr/local/hyperledger/下载并解压

    第一个下载的
    wget https://github.com/hyperledger/fabric/releases/download/v2.2.0/hyperledger-fabric-linux-amd64-2.2.0.tar.gz
    第二个下载的
    wget https://github.com/hyperledger/fabric-ca/releases/download/v1.4.8/hyperledger-fabric-ca-linux-amd64-1.4.8.tar.gz
    tar -zxvf hyperledger-fabric-linux-amd64-2.2.0.tar.gz
    tar -zxvf hyperledger-fabric-ca-linux-amd64-1.4.8.tar.gz
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    我们继续放命令

    chmod +X bootstrap.sh
    ./bootstrap.sh
    mv config/ fabric-samples/
    mv bin/ fabric-samples/
    vim /etc/profile
    # 添加如下
    #export PATH=$PATH:/usr/local/hyperledger/fabric-samples/bin
    source /etc/profile 
    fabric-ca-client version
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    使用测试网络

    cd /usr/local/hyperledger/fabric-samples/test-network
    ./network.sh up createChannel
    
    • 1
    • 2

    注意上面有可能报错,无报错的 跳转

    ERROR: The Compose file './docker/docker-compose-test-net.yaml' is invalid because:
    networks.test value Additional properties are not allowed ('name' was unexpected)
    ERROR: The Compose file './addOrg3/docker/docker-compose-couch-org3.yaml' is invalid because:
    networks.test value Additional properties are not allowed ('name' was unexpected)
    
    • 1
    • 2
    • 3
    • 4

    此时需要将
    /usr/local/hyperledger/fabric-samples/test-network/docker/docker-compose-test-net.yaml

    的13、14、15行改为
    在这里插入图片描述

    并将59、96行的fabric_test改为docker_test
    在这里插入图片描述
    再将文件夹/usr/local/hyperledger/fabric-samples/test-network/下的

    docker/docker-compose-couch.yaml
    docker/docker-compose-ca.yaml
    addOrg3/docker/docker-compose-org3.yaml
    addOrg3/docker/docker-compose-couch-org3.yaml
    addOrg3/docker/docker-compose-ca-org3.yaml
    
    • 1
    • 2
    • 3
    • 4
    • 5

    的第一个networks也改成
    在这里插入图片描述
    然后再

    ./network.sh down
    ./network.sh up createChannel
    
    • 1
    • 2

    就行了

    正常后我们继续,当前路径为/usr/local/hyperledger/fabric-samples/test-network

    # 部署链码
    ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
    
    • 1
    • 2

    可能会有下面的报错,此时要去这个链码包下删除mod并重新tidy
    在这里插入图片描述

    cd ../asset-transfer-basic/chaincode-go
    rm -f go.sum
    go env -w GOSUMDB=off
    go mod tidy
    go env -w GOSUMDB=GOSUMDB="sum.golang.org"
    
    # 重新开启
    ./network.sh down
    ./network.sh up createChannel
    ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    vim /etc/profile
    # 添加如下
    # export PATH=/usr/local/hyperledger/fabric-samples/bin:$PATH
    # export FABRIC_CFG_PATH=/usr/local/hyperledger/fabric-samples/config/
    source /etc/profile
    
    
    export CORE_PEER_TLS_ENABLED=true
    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    export CORE_PEER_ADDRESS=localhost:7051
    
    # 调用初始化函数
    peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"InitLedger","Args":[]}'
    # 输出
    #-> INFO 001 Chaincode invoke successful. result: status:200
    
    
    # 调用查询
    peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
    # 输出
    #[
    #  {"ID": "asset1", "color": "blue", "size": 5, "owner": "Tomoko", "appraisedValue": 300},
    #  {"ID": "asset2", "color": "red", "size": 5, "owner": "Brad", "appraisedValue": 400},
    #  {"ID": "asset3", "color": "green", "size": 10, "owner": "Jin Soo", "appraisedValue": 500},
    #  {"ID": "asset4", "color": "yellow", "size": 10, "owner": "Max", "appraisedValue": 600},
    #  {"ID": "asset5", "color": "black", "size": 15, "owner": "Adriana", "appraisedValue": 700},
    #  {"ID": "asset6", "color": "white", "size": 15, "owner": "Michel", "appraisedValue": 800}
    #]
    
    
    # 测试网络搭建成功
    # 关闭网络
    ./network.sh down 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    编写自己的链码

    cd /usr/local/hyperledger/fabric-samples/asset-transfer-basic
    mkdir atcc && cd atcc
    go mod init atcc
    touch atcc.go
    
    • 1
    • 2
    • 3
    • 4

    链码内容如下

    package main
    
    import (
    	"encoding/json"
    	"fmt"
    	"log"
    	"github.com/hyperledger/fabric-contract-api-go/contractapi"
    )
    
    // SmartContract provides functions for managing an Asset
    type SmartContract struct {
    	contractapi.Contract
    }
    
    // Asset describes basic details of what makes up a simple asset
    type Asset struct {
    	ID             string `json:"ID"`
    	Owner          string `json:"owner"`
    	Value          int    `json:"Value"`
    }
    
    // InitLedger adds a base set of assets to the ledger
    func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
    	assets := []Asset{
    		{ID: "asset1", Owner: "ZhangSan", Value: 300},
    		{ID: "asset2", Owner: "LiSi", Value: 400},
    		{ID: "asset3", Owner: "Klay", Value: 500},
    	}
    
    	for _, asset := range assets {
    		assetJSON, err := json.Marshal(asset)
    		if err != nil {
    			return err
    		}
    
    		err = ctx.GetStub().PutState(asset.ID, assetJSON)
    		if err != nil {
    			return fmt.Errorf("failed to put to world state. %v", err)
    		}
    	}
    
    	return nil
    }
    
    // CreateAsset issues a new asset to the world state with given details.
    func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, owner string, Value int) error {
    	exists, err := s.AssetExists(ctx, id)
    	if err != nil {
    		return err
    	}
    	if exists {
    		return fmt.Errorf("the asset %s already exists", id)
    	}
    
    	asset := Asset{
    		ID:             id,
    		Owner:          owner,
    		Value:          Value,
    	}
    	assetJSON, err := json.Marshal(asset)
    	if err != nil {
    		return err
    	}
    
    	return ctx.GetStub().PutState(id, assetJSON)
    }
    
    // ReadAsset returns the asset stored in the world state with given id.
    func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, id string) (*Asset, error) {
    	assetJSON, err := ctx.GetStub().GetState(id)
    	if err != nil {
    		return nil, fmt.Errorf("failed to read from world state: %v", err)
    	}
    	if assetJSON == nil {
    		return nil, fmt.Errorf("the asset %s does not exist", id)
    	}
    
    	var asset Asset
    	err = json.Unmarshal(assetJSON, &asset)
    	if err != nil {
    		return nil, err
    	}
    
    	return &asset, nil
    }
    
    // UpdateAsset updates an existing asset in the world state with provided parameters.
    func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id string, owner string, Value int) error {
    	exists, err := s.AssetExists(ctx, id)
    	if err != nil {
    		return err
    	}
    	if !exists {
    		return fmt.Errorf("the asset %s does not exist", id)
    	}
    
    	// overwriting original asset with new asset
    	asset := Asset{
    		ID:             id,
    		Owner:          owner,
    		Value:          Value,
    	}
    	assetJSON, err := json.Marshal(asset)
    	if err != nil {
    		return err
    	}
    
    	return ctx.GetStub().PutState(id, assetJSON)
    }
    
    // DeleteAsset deletes an given asset from the world state.
    func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface, id string) error {
    	exists, err := s.AssetExists(ctx, id)
    	if err != nil {
    		return err
    	}
    	if !exists {
    		return fmt.Errorf("the asset %s does not exist", id)
    	}
    
    	return ctx.GetStub().DelState(id)
    }
    
    // AssetExists returns true when asset with given ID exists in world state
    func (s *SmartContract) AssetExists(ctx contractapi.TransactionContextInterface, id string) (bool, error) {
    	assetJSON, err := ctx.GetStub().GetState(id)
    	if err != nil {
    		return false, fmt.Errorf("failed to read from world state: %v", err)
    	}
    
    	return assetJSON != nil, nil
    }
    
    // TransferAsset updates the owner field of asset with given id in world state.
    func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, id string, newOwner string) error {
    	asset, err := s.ReadAsset(ctx, id)
    	if err != nil {
    		return err
    	}
    
    	asset.Owner = newOwner
    	assetJSON, err := json.Marshal(asset)
    	if err != nil {
    		return err
    	}
    
    	return ctx.GetStub().PutState(id, assetJSON)
    }
    
    // GetAllAssets returns all assets found in world state
    func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface) ([]*Asset, error) {
    	// range query with empty string for startKey and endKey does an
    	// open-ended query of all assets in the chaincode namespace.
    	resultsIterator, err := ctx.GetStub().GetStateByRange("", "")
    	if err != nil {
    		return nil, err
    	}
    	defer resultsIterator.Close()
    
    	var assets []*Asset
    	for resultsIterator.HasNext() {
    		queryResponse, err := resultsIterator.Next()
    		if err != nil {
    			return nil, err
    		}
    
    		var asset Asset
    		err = json.Unmarshal(queryResponse.Value, &asset)
    		if err != nil {
    			return nil, err
    		}
    		assets = append(assets, &asset)
    	}
    
    	return assets, nil
    }
    
    func main() {
    	assetChaincode, err := contractapi.NewChaincode(&SmartContract{})
    	if err != nil {
    		log.Panicf("Error creating asset-transfer-basic chaincode: %v", err)
    	}
    
    	if err := assetChaincode.Start(); err != nil {
    		log.Panicf("Error starting asset-transfer-basic chaincode: %v", err)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187

    处理项目依赖

    go mod tidy
    go mod vendor
    
    • 1
    • 2

    使用测试网络进行链码部署

    当前位置:/usr/local/hyperledger/fabric-samples/test-network

    ./network.sh down
    ./network.sh up createChannel
    
    # 注意下面那个尖括号的玩意要替换为自定义的链码文件夹名,设为环境变量只是为了方便操作,比如我这里就要换为export CHAINCODE_NAME=atcc
    export CHAINCODE_NAME=<chaincode-name>
    
    peer lifecycle chaincode package 打包后的压缩包名.tar.gz --path ../asset-transfer-basic/$CHAINCODE_NAME/ --lang golang --label atcc_1.0 
    
    peer lifecycle chaincode package $CHAINCODE_NAME.tar.gz \
    --path ../asset-transfer-basic/$CHAINCODE_NAME/ \ #注意替换链码文件路径
    --lang golang \
    --label <chaincode-name>_1.0 #注意替换内容
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    ./network.sh down
    ./network.sh up createChannel
    
    
    
    export CHAINCODE_NAME=flower_fabric
    
    
    peer lifecycle chaincode package $CHAINCODE_NAME.tar.gz --path $CHAINCODE_NAME/ --lang golang --label flower_fabric_1.0 
    
    
    export CORE_PEER_TLS_ENABLED=true
    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    export CORE_PEER_ADDRESS=localhost:7051
    
    
    peer lifecycle chaincode install $CHAINCODE_NAME.tar.gz
    
    
    export CORE_PEER_LOCALMSPID="Org2MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
    export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
    export CORE_PEER_ADDRESS=localhost:9051
    
    peer lifecycle chaincode install $CHAINCODE_NAME.tar.gz
    
    
    
    
    # 查询包ID
    peer lifecycle chaincode queryinstalled
    
    
    export CC_PACKAGE_ID=<Package ID> #注意替换这里的链码包ID
    export CC_PACKAGE_ID=atcc_1.0:5657426d49d01aadeaabfd8ea13fa7f431931702f534120335ead5acd107e8cd
    
    
    peer lifecycle chaincode approveformyorg \
    -o localhost:7050 \
    --ordererTLSHostnameOverride orderer.example.com \
    --channelID mychannel \
    --name $CHAINCODE_NAME \
    --version 1.0 \
    --package-id $CC_PACKAGE_ID \
    --sequence 1 \
    --tls \
    --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
    
    
    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
    export CORE_PEER_ADDRESS=localhost:7051
    
    
    peer lifecycle chaincode approveformyorg \
    -o localhost:7050 \
    --ordererTLSHostnameOverride orderer.example.com \
    --channelID mychannel \
    --name $CHAINCODE_NAME \
    --version 1.0 \
    --package-id $CC_PACKAGE_ID \
    --sequence 1 \
    --tls \
    --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
    
    peer lifecycle chaincode checkcommitreadiness \
    --channelID mychannel \
    --name $CHAINCODE_NAME \
    --version 1.0 \
    --sequence 1 \
    --tls \
    --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
    --output json
    
    peer lifecycle chaincode commit \
    -o localhost:7050 \
    --ordererTLSHostnameOverride orderer.example.com \
    --channelID mychannel \
    --name $CHAINCODE_NAME \
    --version 1.0 \
    --sequence 1 \
    --tls \
    --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
    --peerAddresses localhost:7051 \
    --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
    --peerAddresses localhost:9051 \
    --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
    
    peer lifecycle chaincode querycommitted \
    --channelID mychannel \
    --name $CHAINCODE_NAME \
    --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
    
    
    echo "链码安装完毕,下面为测试代码"
    
    
    peer chaincode invoke \
    -o localhost:7050 \
    --ordererTLSHostnameOverride orderer.example.com \
    --tls \
    --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
    -C mychannel \
    -n $CHAINCODE_NAME \
    --peerAddresses localhost:7051 \
    --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
    --peerAddresses localhost:9051 \
    --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
    -c '{"function":"initLedger","Args":[]}'
    
    
    peer chaincode query \
    -C mychannel \
    -n $CHAINCODE_NAME \
    -c '{"Args":["getAllAssets"]}'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119

    记录一下我自己的链码的测试代码

    peer chaincode invoke \
    -o localhost:7050 \
    --ordererTLSHostnameOverride orderer.example.com \
    --tls \
    --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
    -C mychannel \
    -n $CHAINCODE_NAME \
    --peerAddresses localhost:7051 \
    --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
    --peerAddresses localhost:9051 \
    --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
    -c '{"function":"CreateWallet","Args":["1"]}'
    
    
    
    
    peer chaincode query \
    -C mychannel \
    -n $CHAINCODE_NAME \
    -c '{"Args":["getAllWallets"]}'
    
    
    peer chaincode invoke \
    -o localhost:7050 \
    --ordererTLSHostnameOverride orderer.example.com \
    --tls \
    --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
    -C mychannel \
    -n $CHAINCODE_NAME \
    --peerAddresses localhost:7051 \
    --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
    --peerAddresses localhost:9051 \
    --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
    -c '{"function":"UpdateWalletIntegral","Args":["1","20","a"]}'
    
    
    
    
    peer chaincode query \
    -C mychannel \
    -n $CHAINCODE_NAME \
    -c '{"Args":["getAllWallets"]}'
    
    peer chaincode query \
    -C mychannel \
    -n $CHAINCODE_NAME \
    -c '{"Args":["ReadWallet","1"]}'
    
    peer chaincode query \
    -C mychannel \
    -n $CHAINCODE_NAME \
    -c '{"Args":["ReadHistory","1"]}'
    
    
    
    
    
    peer chaincode invoke \
    -o localhost:7050 \
    --ordererTLSHostnameOverride orderer.example.com \
    --tls \
    --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
    -C mychannel \
    -n $CHAINCODE_NAME \
    --peerAddresses localhost:7051 \
    --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
    --peerAddresses localhost:9051 \
    --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
    -c '{"function":"initLedger","Args":[]}'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
  • 相关阅读:
    力扣(LeetCode)1106. 解析布尔表达式(C++)
    Duchefa细胞分裂素丨二氢玉米素 (DHZ)说明书
    Eureka的使用
    面试 Java 并发编程八股文十问十答第四期
    Electron基础学习笔记
    pytorch环境安装和配置
    学生家乡网页设计作品静态HTML网页—— HTML+CSS+JavaScript制作辽宁沈阳家乡主题网页源码(11页)
    window server事件ID说明
    08-React路由6.3.0(高亮, 嵌套, 参数传递... )
    超分辨篇----用于图像超分辨率的残差稠密网络
  • 原文地址:https://blog.csdn.net/qq_51955445/article/details/126812120