链码开发学习

链码开发学习

一、编写链码

直接抄袭https://hyperledger-fabric.readthedocs.io/en/release-2.2/chaincode4ade.html

二、链码部署

1、启动测试网络,这个简单

testnet
./network.sh down
./network.sh up createChannel

2、打包链码

设置环境变量

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

添加链码名字的环境变量

export CHAINCODE_NAME=firstcc

打包链码

#注意替换链码文件路径
#注意替换<chaincode-name>内容
peer lifecycle chaincode package $CHAINCODE_NAME.tar.gz --path /root/hyperledger/sacc/ --lang golang --label firstcc_1.0 

3、安装链码

以org1身份运行

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

在org1安装链码

peer lifecycle chaincode install $CHAINCODE_NAME.tar.gz

以org2身份运行

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

添加链码包ID的环境变量

export CC_PACKAGE_ID=firstcc_1.0:e2b1790a571761895b9324b3ff95171215b88f1ab31d370a95a39f48bae426ab #注意替换这里的链码包ID

4、批准链码定义

org2同意该链码定义

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

org1同意该定义

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

5、提交链码

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

注意,这里是以org1身份提交的链码,亦可以用org2进行提交,只需一方提交一次即可。

确认是否提交

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

6、调用链码

初始化资产

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"]}'

可以在测试完成后关闭网络

./network.sh down

nodejs开发

智能合约处理文档:https://hyperledger-fabric.readthedocs.io/en/latest/developapps/smartcontract.html

fabric-contract-api官方文档:https://hyperledger.github.io/fabric-chaincode-node/master/api/#toc1__anchor

在开发模式下运行chaincode

一、搭建开发环境

https://hyperledger-fabric.readthedocs.io/en/latest/peer-chaincode-devmode.html#

1、所有命令均在fabric/文件夹中执行

2、运行以下命令来构建orderer,peer和configtxgen的二进制文件:

make orderer peer configtxgen

会在build/bin目录下生成二进制的执行文件

3、设置PATH环境变量以包括orderer和peer二进制文件:

export PATH=$(pwd)/build/bin:$PATH

4、将FABRIC_CFG_PATH环境变量设置为指向sampleconfig文件夹:

export FABRIC_CFG_PATH=$(pwd)/sampleconfig

5、生成订单服务的创世块。

运行以下命令以生成创世块并将其存储在其中,$(pwd)/sampleconfig/genesisblock以便订购者可以在启动订购者时在下一步中使用它。

configtxgen -profile SampleDevModeSolo -channelID syschannel -outputBlock genesisblock -configPath $FABRIC_CFG_PATH -outputBlock "$(pwd)/sampleconfig/genesisblock"

二、启动orderer

运行以下命令以使用SampleDevModeSolo概要文件启动订购者并启动订购服务:

export PATH=$(pwd)/build/bin:$PATH
export FABRIC_CFG_PATH=$(pwd)/sampleconfig
ORDERER_GENERAL_GENESISPROFILE=SampleDevModeSolo orderer >> log_orderer.log 2>&1 &

三、在DevMode中启动对等

打开另一个终端窗口(不开也没事),并设置所需的环境变量以覆盖对等配置并启动对等节点。以该--peer-chaincodedev=true标志启动对等方会使对等方进入DevMode。(遇上了端口冲突,不知道什么毛病,修改了一下端口)

export PATH=$(pwd)/build/bin:$PATH
export FABRIC_CFG_PATH=$(pwd)/sampleconfig
FABRIC_LOGGING_SPEC=chaincode=debug CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052 peer node start --peer-chaincodedev=true >> log_peer.log 2>&1 &

**提醒:**在中运行时DevMode,无法启用TLS。

四、创建频道并加入peer

打开另一个终端窗口,然后运行以下命令以使用该configtxgen工具生成通道创建事务。此命令ch1使用SampleSingleMSPChannel配置文件创建频道:

export PATH=$(pwd)/build/bin:$PATH
export FABRIC_CFG_PATH=$(pwd)/sampleconfig
configtxgen -channelID ch1 -outputCreateChannelTx ch1.tx -profile SampleSingleMSPChannel -configPath $FABRIC_CFG_PATH
peer channel create -o 127.0.0.1:7050 -c ch1 -f ch1.tx

成功后,您应该会看到类似以下结果:

2020-09-14 17:42:56.931 EDT [cli.common] readBlock -> INFO 002 Received block: 0

现在,通过运行以下命令将对等方加入通道:

peer channel join -b ch1.block

成功后,您应该看到类似于以下内容的结果:

2020-09-14 17:43:34.976 EDT [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

同行现在已加入频道ch1

五、建立链码

我们使用目录中的简单链码fabric/integration/chaincode来演示如何在DevMode中运行链码包。在与上一步相同的终端窗口中,运行以下命令来构建链码:

go build -o simpleChaincode ./integration/chaincode/simple/cmd

六、启动链码

DevMode对端已启用,CORE_CHAINCODE_ID_NAME环境变量必须设置为<CHAINCODE_NAME><CHAINCODE_VERSION>否则,对方是无法找到chaincode。在此示例中,我们将其设置为mycc:1.0。运行以下命令以启动链码并将其连接到对等方:(不知道为啥一直在运行,窗口没有关闭,所以我又开了另一个窗口)

CORE_CHAINCODE_LOGLEVEL=debug CORE_PEER_TLS_ENABLED=false CORE_CHAINCODE_ID_NAME=mycc:1.0 ./simpleChaincode -peer.address 127.0.0.1:7052

因为我们是在启动对等节点时在其上设置调试日志的,所以您可以确认链码注册成功。在对等日志中,您应该看到类似于以下内容的结果:(在第二个窗口其实能看到)

2020-09-14 17:53:43.413 EDT [chaincode] sendReady -> DEBU 045 Changed to state ready for chaincode mycc:1.0

七、批准并提交链码定义

现在,您需要运行以下Fabric链码生命周期命令来批准并将链码定义提交给通道:(另开了一个窗口)

export PATH=$(pwd)/build/bin:$PATH
export FABRIC_CFG_PATH=$(pwd)/sampleconfig
#批准链码
peer lifecycle chaincode approveformyorg  -o 127.0.0.1:7050 --channelID ch1 --name mycc --version 1.0 --sequence 1 --init-required --signature-policy "OR ('SampleOrg.member')" --package-id mycc:1.0
#确认批准
peer lifecycle chaincode checkcommitreadiness -o 127.0.0.1:7050 --channelID ch1 --name mycc --version 1.0 --sequence 1 --init-required --signature-policy "OR ('SampleOrg.member')"
#提交链码
peer lifecycle chaincode commit -o 127.0.0.1:7050 --channelID ch1 --name mycc --version 1.0 --sequence 1 --init-required --signature-policy "OR ('SampleOrg.member')" --peerAddresses 127.0.0.1:7051

您应该看到类似于以下内容的结果:

2020-09-14 17:56:30.820 EDT [chaincodeCmd] ClientWait -> INFO 001 txid [f22b3c25dfea7fe0b28af9ee818056db81e29a9421c83fe00eb22fa41d1d1e21] committed with status (VALID) at
Chaincode definition for chaincode 'mycc', version '1.0', sequence '1' on channel 'ch1' approval status by org:
SampleOrg: true
2020-09-14 17:57:43.295 EDT [chaincodeCmd] ClientWait -> INFO 001 txid [fb803e8b0b4eae6b3a9ed35668f223753e1a34ffd2a7042f9e5bb516a383eb32] committed with status (VALID) at 127.0.0.1:7051

八、下一步

您可以根据需要发出CLI命令来调用和查询链码,以验证您的智能合约逻辑。对于此示例,我们发出三个命令。第一个初始化智能合约,第二个命令10从资产移动a到资产b。最后一条命令查询值,a以验证它已成功从更改10090

CORE_PEER_ADDRESS=127.0.0.1:7051 peer chaincode invoke -o 127.0.0.1:7050 -C ch1 -n mycc -c '{"Args":["init","a","100","b","200"]}' --isInit
CORE_PEER_ADDRESS=127.0.0.1:7051 peer chaincode invoke -o 127.0.0.1:7050 -C ch1 -n mycc -c '{"Args":["invoke","a","b","10"]}'
CORE_PEER_ADDRESS=127.0.0.1:7051 peer chaincode invoke -o 127.0.0.1:7050 -C ch1 -n mycc -c '{"Args":["query","a"]}'

您应该看到类似于以下内容的结果:

2020-09-14 18:15:00.034 EDT [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
2020-09-14 18:16:29.704 EDT [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
2020-09-14 18:17:42.101 EDT [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200 payload:"90"

在DevMode中运行对等方的好处是,您现在可以迭代地对智能合约进行更新,保存更改,构建链码,然后使用上述步骤重新启动它。您无需每次更改都运行对等生命周期命令来更新链码。

java开发链码试验性质

二、搭建开发环境

1、启动网络

导航到存储库test-network本地克隆中的子目录 fabric-samples

cd fabric-samples/test-network

如果您已经在运行测试网络,请将其关闭以确保环境干净。

./network.sh down

使用network.shshell脚本启动Fabric测试网络。

./network.sh up createChannel -c mychannel -ca

2、部署链码

./network.sh deployCC -ccn fabcar -ccp ../chaincode/fabcar/java/ -ccl java

3、环境变量配置

#fabric
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
# Environment variavles for Org1
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=$PWD/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_ROOTCERT_FILE=/root/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

4、调用链码

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 fabcar --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 fabcar -c '{"Args":["queryAllCars"]}'

java开发第一个

一、链码编写

抄袭fabcar的编写,写了个ticket,其实就是把属性值换了一下

从idea拷贝过去,然后要给权限

chmod +x gradlew

二、搭建开发环境

1、启动网络

导航到存储库test-network本地克隆中的子目录 fabric-samples

cd fabric-samples/test-network

如果您已经在运行测试网络,请将其关闭以确保环境干净。

./network.sh down

使用network.shshell脚本启动Fabric测试网络。

./network.sh up createChannel -c mychannel -ca

2、部署链码

export CHAINCODE_NAME=ticket
./network.sh deployCC -ccn $CHAINCODE_NAME -ccp /root/hyperledger/contract/java/ticket -ccl java

3、环境变量配置

#fabric
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
# Environment variavles for Org1
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=$PWD/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_ROOTCERT_FILE=/root/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

4、调用链码

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":["queryAllTickets"]}'

ERC-20 token 学习

1、启动网络

导航到存储库test-network本地克隆中的子目录 fabric-samples

cd fabric-samples/test-network

如果您已经在运行测试网络,请将其关闭以确保环境干净。

./network.sh down

使用network.shshell脚本启动Fabric测试网络。

./network.sh up createChannel -ca

2、部署链码

export CHAINCODE_NAME=token_erc20
./network.sh deployCC -ccn $CHAINCODE_NAME -ccp ../token-erc-20/chaincode-javascript/ -ccl javascript

./network.sh deployCC -ccn token -ccp ../commercial-paper/chaincode-token/ -ccl javascript

./network.sh deployCC -ccn ticket -ccp ../commercial-paper/chaincode-ticket/ -ccl javascript

./network.sh deployCC -ccn $CHAINCODE_NAME -ccp ../token-erc-20/chaincode-go/ -ccl go

3、注册身份

智能合约支持来自渠道成员组织的各个客户身份拥有的帐户。在我们的方案中,代币的铸造者将是Org1的成员,而接收者将属于Org2。为了突出显示GetClientIdentity().GetID()API和用户证书中信息之间的联系,我们将使用Org1和Org2证书颁发机构(CA)注册两个新的身份,然后使用CA生成每个身份的证书和私钥。

3.1 Org1

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

我们一直在使用的终端将代表Org1。我们将使用Org1 CA创建铸造者身份。将Fabric CA客户端设置为Org1 CA管理员的MSP(此身份由测试网络脚本生成):

export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org1.example.com/

您可以使用以下fabric-ca-client工具注册新的Minter客户身份:

fabric-ca-client register --caname ca-org1 --id.name minter --id.secret minterpw --id.type client --tls.certfiles "${PWD}/organizations/fabric-ca/org1/tls-cert.pem"

现在,您可以通过将铸币者的注册名称和密码提供给enroll命令来生成身份证书和MSP文件夹:

fabric-ca-client enroll -u https://minter:minterpw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@org1.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org1/tls-cert.pem"

运行以下命令以将节点OU配置文件复制到minter身份MSP文件夹中。

cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@org1.example.com/msp/config.yaml"

3.2 Org2

打开一个代表Org2的新终端,然后导航到fabric-samples / test-network。我们将使用Org2 CA创建Org2收件人身份。将Fabric CA客户端设置为Org2 CA管理员的MSP:

cd fabric-samples/test-network
export PATH=${PWD}/../bin:${PWD}:$PATH
export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org2.example.com/

您可以使用以下fabric-ca-client工具注册收件人客户端身份:

fabric-ca-client register --caname ca-org2 --id.name recipient --id.secret recipientpw --id.type client --tls.certfiles "${PWD}/organizations/fabric-ca/org2/tls-cert.pem"

现在,我们可以注册以生成收件人的身份证书和MSP文件夹:

fabric-ca-client enroll -u https://recipient:recipientpw@localhost:8054 --caname ca-org2 -M "${PWD}/organizations/peerOrganizations/org2.example.com/users/recipient@org2.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org2/tls-cert.pem"

运行以下命令,将节点OU配置文件复制到收件人身份MSP文件夹中。

cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/users/recipient@org2.example.com/msp/config.yaml"

4、铸造一些代币

现在我们已经创建了铸造者的身份,我们可以调用智能合约铸造一些代币。返回Org1终端,我们将设置以下环境变量以将peerCLI作为Org1中的标记身份进行操作。

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@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
export TARGET_TLS_OPTIONS=(-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" --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")

上面的最后一个环境变量将在CLI调用命令中使用,以设置要认可的目标对等方以及目标订购服务端点和TLS选项。

然后,我们可以调用智能合约以铸造5000个代币:

(这个@也可以改成*,表示这个数组内的所有元素)

peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_erc20 -c '{"function":"Mint","Args":["5000"]}'

造币厂功能验证客户是造币厂组织的成员,然后将5000个代币记入造币厂客户的帐户。我们可以通过调用该ClientAccountBalance功能来检查铸造者客户的帐户余额。

peer chaincode query -C mychannel -n token_erc20 -c '{"function":"ClientAccountBalance","Args":[]}'

该函数查询与铸币者客户端ID关联的帐户余额,并返回:

5000

5、转移代币

在Org2的终端下操作

铸造者打算将100个代币转移给Org2接收者,但首先Org2接收者需要提供自己的帐户ID作为付款地址。客户可以从其自己的公共证书中获取其帐户ID,但为确保该帐户ID正确,合同具有ClientAccountID实用程序功能,可以简单地查看呼叫者证书并返回主叫客户的ID,该ID将用作帐户ID。让我们通过为Org2接收者用户设置环境变量来准备Org2终端。

export FABRIC_CFG_PATH=$PWD/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/recipient@org2.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:9051

使用Org2终端,Org2收件人用户可以检索自己的帐户ID:

peer chaincode query -C mychannel -n token_erc20 -c '{"function":"ClientAccountID","Args":[]}'

对于Go合约:

该函数返回收件人的帐户ID:

eDUwOTo6Q049cmVjaXBpZW50LE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzIuZXhhbXBsZS5jb20sTz1vcmcyLmV4YW1wbGUuY29tLEw9SHVyc2xleSxTVD1IYW1wc2hpcmUsQz1VSw==

让base64解码帐户ID以确保它代表Org2收件人用户:

echo eDUwOTo6Q049cmVjaXBpZW50LE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzIuZXhhbXBsZS5jb20sTz1vcmcyLmV4YW1wbGUuY29tLEw9SHVyc2xleSxTVD1IYW1wc2hpcmUsQz1VSw== | base64 --decode

结果表明,主题和颁发者确实是Org2的收件人用户:

x509::CN=recipient,OU=client,O=Hyperledger,ST=North Carolina,C=US::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK

对于JavaScript合同:

该函数返回收件人的客户ID。结果表明,主题和颁发者确实是Org2的收件人用户:

x509::/C=US/ST=North Carolina/O=Hyperledger/OU=client/CN=recipient::/C=UK/ST=Hampshire/L=Hursley/O=org2.example.com/CN=ca.org2.example.com

在Org2收件人向铸造者提供其帐户ID之后,铸造者可以启动从其帐户到接收者帐户的转移。

返回到Org1终端,请求将100个代币转移到接收者帐户:

对于Go合约:

export RECIPIENT="eDUwOTo6Q049cmVjaXBpZW50LE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzIuZXhhbXBsZS5jb20sTz1vcmcyLmV4YW1wbGUuY29tLEw9SHVyc2xleSxTVD1IYW1wc2hpcmUsQz1VSw=="
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_erc20 -c '{"function":"Transfer","Args":[ "'"$RECIPIENT"'","100"]}'

对于JavaScript合同:

export RECIPIENT="x509::/C=US/ST=North Carolina/O=Hyperledger/OU=client/CN=recipient::/C=UK/ST=Hampshire/L=Hursley/O=org2.example.com/CN=ca.org2.example.com"
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_erc20 -c '{"function":"Transfer","Args":[ "'"$RECIPIENT"'","100"]}'

Transfer功能验证与主叫客户ID相关联的帐户是否有足够的资金用于转账。然后,它将从呼叫者的帐户中扣款,并在接收者的帐户中贷记。请注意,示例合同将为收款人自动创建一个余额为零的帐户(如果尚不存在)。

仍在Org1终端中时,让我们再次请求铸造者的帐户余额:

peer chaincode query -C mychannel -n token_erc20 -c '{"function":"ClientAccountBalance","Args":[]}'

该函数查询与铸币者客户端ID关联的帐户余额,并返回:

4900

然后使用Org2终端,要求接收者的余额:

peer chaincode query -C mychannel -n token_erc20 -c '{"function":"ClientAccountBalance","Args":[]}'

该函数查询与收件人客户端ID关联的帐户余额,并返回:

100

恭喜,您已转移了100个代币!现在,Org2收件人可以以相同方式将代币转移给其他注册用户。

6、第三方转帐(TransferFrom)

该示例还有另一种称为的ERC-20转移方法TransferFrom,该方法允许批准的第三方支出者代表帐户所有者转移可替代的代币。此业务情景演示了如何批准支出者和转移可替代代币。

在这种情况下,您将批准支出者并按以下方式转移代币:

  • 铸币商已经根据上述情况创建了代币。
  • 相同的铸造者客户端使用该Approve功能来设置花费者客户端可以代表铸造者转移的代币配额。假定花费者已经将他们的客户ID提供给了Approve呼叫者带外。
  • 然后,消费者客户端将使用该TransferFrom功能代表铸币者将请求数量的代币转移到接收者的帐户中。假定接收者已经将他们的客户ID提供给了TransferFrom呼叫者带外。

1、注册第三方消费者的身份

您已经建立了网络,并将智能合约部署到了渠道。我们将使用相同的网络和智能合约。

我们将使用Org1 CA创建支出者身份。回到Org1终端,您可以使用以下fabric-ca-client工具注册新的客户帐户身份:

fabric-ca-client register --caname ca-org1 --id.name spender --id.secret spenderpw --id.type client --tls.certfiles "${PWD}/organizations/fabric-ca/org1/tls-cert.pem"

现在,您可以通过将花费者的注册名称和秘密提供给enroll命令来生成身份证书和MSP文件夹:

fabric-ca-client enroll -u https://spender:spenderpw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/users/spender@org1.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org1/tls-cert.pem"

运行以下命令以将节点OU配置文件复制到支出者身份MSP文件夹中。

cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/users/spender@org1.example.com/msp/config.yaml"

2、批准支出者

造币商打算批准要由支出者转让的500个代币,但是首先,支出者需要提供自己的客户ID作为付款地址。

打开第三个终端

以代表Org1中的支出者,然后导航到fabric-samples / test-network。为Org1支出者用户设置环境变量。

export PATH=${PWD}/../bin:${PWD}:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/spender@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
export TARGET_TLS_OPTIONS=(-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" --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")

现在,Org1支出者可以检索自己的客户ID:

peer chaincode query -C mychannel -n token_erc20 -c '{"function":"ClientAccountID","Args":[]}'

对于Go合约:

该函数返回支出者的帐户ID:

eDUwOTo6Q049c3BlbmRlcixPVT1jbGllbnQsTz1IeXBlcmxlZGdlcixTVD1Ob3J0aCBDYXJvbGluYSxDPVVTOjpDTj1jYS5vcmcxLmV4YW1wbGUuY29tLE89b3JnMS5leGFtcGxlLmNvbSxMPUR1cmhhbSxTVD1Ob3J0aCBDYXJvbGluYSxDPVVT

对于JavaScript合同:

该函数返回支出者的客户ID。结果表明,主题和颁发者确实是Org2的收件人用户:

x509::/C=US/ST=North Carolina/O=Hyperledger/OU=client/CN=spender::/C=US/ST=North Carolina/L=Durham/O=org1.example.com/CN=ca.org1.example.com

在Org1支出者将其客户ID提供给铸币商之后,铸币者可以批准支出者。

回到Org1造币厂终端,请求批准500个代币,以由支出者撤回。

对于Go合约:

export SPENDER="eDUwOTo6Q049c3BlbmRlcixPVT1jbGllbnQsTz1IeXBlcmxlZGdlcixTVD1Ob3J0aCBDYXJvbGluYSxDPVVTOjpDTj1jYS5vcmcxLmV4YW1wbGUuY29tLE89b3JnMS5leGFtcGxlLmNvbSxMPUR1cmhhbSxTVD1Ob3J0aCBDYXJvbGluYSxDPVVT"
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_erc20 -c '{"function":"Approve","Args":[ "'"$SPENDER"'","500"]}'

对于JavaScript合同:

export SPENDER="x509::/C=US/ST=North Carolina/O=Hyperledger/OU=client/CN=spender::/C=US/ST=North Carolina/L=Durham/O=org1.example.com/CN=ca.org1.example.com"
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_erc20 -c '{"function":"Approve","Args":["'"$SPENDER"'", "500"]}'

批准功能指定支出者客户端可以代表铸造者转移500个代币。我们可以通过调用该allowance功能从铸币厂检查支出者客户的补贴。

让我们从Org1造币厂终端请求支出者的补贴。

对于Go合约:

export MINTER="eDUwOTo6Q049bWludGVyLE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzEuZXhhbXBsZS5jb20sTz1vcmcxLmV4YW1wbGUuY29tLEw9RHVyaGFtLFNUPU5vcnRoIENhcm9saW5hLEM9VVM="
peer chaincode query -C mychannel -n token_erc20 -c '{"function":"Allowance","Args":["'"$MINTER"'", "'"$SPENDER"'"]}'

对于JavaScript合同:

export MINTER="x509::/C=US/ST=North Carolina/O=Hyperledger/OU=client/CN=minter::/C=US/ST=North Carolina/L=Durham/O=org1.example.com/CN=ca.org1.example.com"
peer chaincode query -C mychannel -n token_erc20 -c '{"function":"Allowance","Args":["'"$MINTER"'", "'"$SPENDER"'"]}'

该函数查询与支出者客户ID相关联的配额,并返回:

500

3、TransferFrom代币

支出者打算代表铸币者将100个代币转移给Org2接收者。支出者已经获得了铸造者客户ID和接收者客户ID。

返回第三个终端,请求将100个代币转移到接收者帐户。

对于Go合约:

export MINTER="eDUwOTo6Q049bWludGVyLE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzEuZXhhbXBsZS5jb20sTz1vcmcxLmV4YW1wbGUuY29tLEw9RHVyaGFtLFNUPU5vcnRoIENhcm9saW5hLEM9VVM="
export RECIPIENT="eDUwOTo6Q049cmVjaXBpZW50LE9VPWNsaWVudCxPPUh5cGVybGVkZ2VyLFNUPU5vcnRoIENhcm9saW5hLEM9VVM6OkNOPWNhLm9yZzIuZXhhbXBsZS5jb20sTz1vcmcyLmV4YW1wbGUuY29tLEw9SHVyc2xleSxTVD1IYW1wc2hpcmUsQz1VSw=="
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_erc20 -c '{"function":"TransferFrom","Args":[ "'"$MINTER"'", "'"$RECIPIENT"'", "100"]}'

对于JavaScript合同:

export MINTER="x509::/C=US/ST=North Carolina/O=Hyperledger/OU=client/CN=minter::/C=US/ST=North Carolina/L=Durham/O=org1.example.com/CN=ca.org1.example.com"
export RECIPIENT="x509::/C=US/ST=North Carolina/O=Hyperledger/OU=client/CN=recipient::/C=UK/ST=Hampshire/L=Hursley/O=org2.example.com/CN=ca.org2.example.com"
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_erc20 -c '{"function":"TransferFrom","Args":[ "'"$MINTER"'", "'"$RECIPIENT"'", "100"]}'

TransferFrom函数具有三个参数:发件人,收件人,金额。该功能验证与发件人关联的帐户是否有足够的资金来进行转帐。该功能还验证与主叫客户ID相关的配额是否超过要转账的资金。然后,它将从发件人的帐户中扣除并在收款人的帐户中贷记。这也将减少铸币商批准的支出者补贴。请注意,示例合同将为收款人自动创建一个余额为零的帐户(如果尚不存在)。

在仍处于支出者的第三个终端时,让我们再次请求铸造者的帐户余额:

peer chaincode query -C mychannel -n token_erc20 -c '{"function":"BalanceOf","Args":["'"$MINTER"'"]}'

该函数查询与铸币者客户端ID关联的帐户余额,并返回:

4800

在仍处于支出者的第三个终端时,让我们再次向铸造者请求支出者的津贴。

对于Go合约:

export SPENDER="eDUwOTo6Q049c3BlbmRlcixPVT1jbGllbnQsTz1IeXBlcmxlZGdlcixTVD1Ob3J0aCBDYXJvbGluYSxDPVVTOjpDTj1jYS5vcmcxLmV4YW1wbGUuY29tLE89b3JnMS5leGFtcGxlLmNvbSxMPUR1cmhhbSxTVD1Ob3J0aCBDYXJvbGluYSxDPVVT"
peer chaincode query -C mychannel -n token_erc20 -c '{"function":"Allowance","Args":["'"$MINTER"'", "'"$SPENDER"'"]}'

对于JavaScript合同:

export SPENDER="x509::/C=US/ST=North Carolina/O=Hyperledger/OU=client/CN=spender::/C=US/ST=North Carolina/L=Durham/O=org1.example.com/CN=ca.org1.example.com"
peer chaincode query -C mychannel -n token_erc20 -c '{"function":"Allowance","Args":["'"$MINTER"'", "'"$SPENDER"'"]}'

该函数查询与支出者客户ID相关联的配额,并返回:

400

然后使用Org2终端,要求接收者的余额:

peer chaincode query -C mychannel -n token_erc20 -c '{"function":"ClientAccountBalance","Args":[]}'

该函数查询与收件人客户端ID关联的帐户余额,并返回:

200

恭喜,您已转移了100个代币!现在,Org2收件人可以以相同方式将代币转移给其他注册用户。

7、清理

完成后,您可以关闭测试网络。该命令将删除测试网络的所有节点,并删除您创建的所有分类帐数据:

./network.sh down

合同延期的想法

您可以扩展基本的基于ERC-20帐户的代币示例,以满足其他要求。例如:

  • 您可以将认可策略设置为代表合同执行的信任锚的组织子集,而不是使用默认的“多数”认可策略。
  • 您还可能要求帐户在使用之前进行设置,并对每个已创建的帐户密钥应用基于状态的背书。例如,在Org1帐户上,将基于州的背书策略设置为Org1和中央银行(或其他一些信任锚)。并在Org2帐户上,将基于州的背书策略设置为Org2和中央银行(或其他一些信任锚)。然后,要将代币从Org1帐户转移到Org2帐户,您需要获得Org1,Org2和中央银行(或某些其他信任锚)的认可。
  • 您可以为基于私钥-公钥对的帐户使用匿名地址,而不是由客户端ID键入密钥的帐户。为了花费代币,客户将必须在转移输入上签名以证明他们拥有地址私钥,然后合同将对其进行验证,类似于无许可区块链空间中的以太坊模型。但是,在诸如Fabric之类的许可区块链中,只有注册的客户才有权参与。此外,如果您不想泄漏与每个帐户关联的已注册客户端身份,则可以使用Identity Mixer MSP来注册客户端,以便在每个代币交易中客户端本身也是匿名的。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇