在fabric2.2.1环境下部署智能合约

1.开启网络
没啥好说的,之前要下samples,二进制和镜像

cd fabric-samples/test-network

把之前网络关闭了

./network.sh down

用下面的指令开启测试网络:

./network.sh up createChannel

createchannel指令创造了一个叫mychannel的channel(两个组织org1和2)。

成功的画面8说了,就是channel successfully joined。

这会可以用peer cli来部署asset-transfer (basic)链码到通道了。

第0步:开启Logspout
这就是一个监测链码的工具了,也可以不打开。

cd fabric-samples/test-network
cp ../commercial-paper/organization/digibank/configuration/cli/monitordocker.sh 

官方第一行指令多了一个.,删掉。接着运行它:

./monitordocker.sh net_test

显示 Starting monitoring on all containers on the network net_basic,就ok了

第一步:打包智能合约
在安装到我们peer节点之前我们要打包。用go,js, Typescript步骤略有不同,我这边用的是go

在打包链码之前,要安装链码的依赖。导航到go版本的那个文件夹(包含the asset-transfer (basic) chaincode.)

cd fabric-samples/asset-transfer-basic/chaincode-go

案例用的是go 模组来安装链码依赖。依赖都在go.mod文件中。(代码不贴了)

go.mod文件把fabric 合约api输出到智能合约包了。
打开asset-transfer-basic/chaincode-go/chaincode/smartcontract.go,能够看到合约api是怎么用来定义smartcontract类型的:

// SmartContract provides functions for managing an Asset
type SmartContract struct {
    
    
    contractapi.Contract
}

这个smartcontract type用于为智能合约中定义的函数创建事务上下文,这些函数用于向区块链分类账读写数据。

// CreateAsset issues a new asset to the world state with given details.
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue 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,
        Color:          color,
        Size:           size,
        Owner:          owner,
        AppraisedValue: appraisedValue,
    }
    assetJSON, err := json.Marshal(asset)
    if err != nil {
    
    
        return err
    }

    return ctx.GetStub().PutState(id, assetJSON)
}

说了那么多,接下来搞依赖,在asset-transfer-basic/chaincode-go目录下运行:

GO111MODULE=on go mod vendor

成功的话,目录里会有vendor文件夹。

接下来就是搞环境变量,复制粘贴就完事了:

export PATH=${
    
    PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/

这两段话我直接就在:

vim ~/.bashrc
source ~/.bashrc

里面搞了,我不知道直接在终端打有没有效果,应该是有的

接下来就打包就完事了

peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-go/ --lang golang --label basic_1.0

–lang:用于定义链码语言
–path:提供智能合约代码位置
–label:用来定义链码的标签

js我就不贴出来了,我电脑deploy cc js一直会很慢有时候都会超时,不知道为什么????

第二步:安装链码包
要把链码装到peer节点上去

先把链码装到org1的peer上去。设置环境变量:

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 basic.tar.gz

终端显示:

2020-07-16 10:09:57.534 CDT [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nJbasic_1.0:e2db7f693d4aa6156e652741d5606e9c5f0de9ebb88c5721cb8248c3aead8123\022\tbasic_1.0" >
2020-07-16 10:09:57.534 CDT [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: basic_1.0:e2db7f693d4aa6156e652741d5606e9c5f0de9ebb88c5721cb8248c3aead8123

就ok

同理,org2上的peer不多说

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 basic.tar.gz

没问题就第三步:同意链码定义(改:这步以后的同意全都改成批准)
在安装完后,需要为你的组织同意一个链码定义。定义包括:链码管理的重要参数:名字版本,背书政策。

需要在部署链码之前批准链码的通道成员集由Application/Channel/lifeycleEndorsement进行管理。默认情况下,此策略要求大多数通道成员需要批准链码,然后才能在通道上使用该链码。因为我们只有两个组织在渠道上,大多数2是2,我们需要批准一个链码定义的资产转移(基本)为Org1和Org2。
如果一个组织已在peer上安装了链码,则需要将packageID包括在其组织批准的链码定义中。包(package)ID用于将安装在对等点上的链码与已批准的链码定义关联起来,并允许组织使用链码来支持事务。你可以通过使用peer lifecycle chaincode queryinstalled命令来查询你的peer来找到一个链码的包ID。(这两段直接机翻再改,我觉得挺重要但我懒得打字)

peer lifecycle chaincode queryinstalled

得到id

Installed chaincodes on peer:
Package ID: basic_1.0:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3, Label: basic_1.0

然后用上面的,label 前面的id来设置环境变量:

export CC_PACKAGE_ID=basic_1.0:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3

(id每个人都不一样,别把我这个id用到你上面去了)

因为环境变量已经被设置,我们可以为组织2同意链码定义。链码在组织层被同意,所以指令只需要target一个peer节点。这个同意事项是组织用gossip来分发给其他节点。同意的指令:

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --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

--package-id:包含package identifier(这里翻译成包身份鉴定者)
--sequence:一个能够追踪一个链码被定义或者更新多少次的指数

这边我觉得他重复了,不知道为什么
We still need to approve the chaincode definition as Org1. Set the following environment variables to operate as the Org1 admin:

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

You can now approve the chaincode definition as Org1:

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --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上启动链码。如果在通道成员批准链码之前提交定义,该组织将无法背书事务。因此,建议所有通道成员在提交链码定义之前先批准一个链码。

第四步:把链码定义提交到通道
用下面的指令来确认是否通道成员同意了相同的链码定义

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --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

结果应该是这样:

 {
    
    
            "Approvals": {
    
    
                    "Org1MSP": true,
                    "Org2MSP": true
            }
    }

用如下指令来把链码定义提交到通道:

peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --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

--peerAddresse:确定目标peer0.org1.example.com from Org1 peer0.org2.example.com from Org2.
commit提交到peer节点。peer节点加入通道来查询被组织同意的链码定义。

用以下指令来确认链码定义被提交到通道:

peer lifecycle chaincode querycommitted --channelID mychannel --name basic --cafile ${
    
    PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

成功的标志:

Committed chaincode definition for chaincode 'basic' on channel 'mychannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]

调用链码就不说了,复制粘贴就完事了,之前都对的不会出错

下面一步我这边跑不起来,更新链码:之前用的是go语言,这个官方要我用js来搞,其实都一样,但是我这边跑js就一直会timeout,非常奇怪。但是流程和之前是一模一样,而且我个人认为更新链码没有很大的意义,一般都是重新从头部署就完事了

最后,清理一下环境

docker stop logspout
docker rm logspout
./network.sh down

本章结束

猜你喜欢

转载自blog.csdn.net/qq_45368275/article/details/109081648