(Fabric Learning Pit) Regarding the existence of two smart contracts in one chain code, how to request another smart contract on the command line; and how to solve the problem when the parameters are in JSON format when calling the chain code

1. Problem background

In the process of learning fabric at station b, the blogger DevX_ has an example of java chain code 

hepeng/hyperledger-fabric-contract-java-demo

There are two sets of smart contracts in this chain code: CatContract and UserContract.

The two contracts are not related to each other, but are written in the same chain code. We package the chaincode into a jar package, and both sets of smart contracts should exist in the jar package. It stands to reason that both should be able to call.

I first called CatContract's chaincode and found that it could be called, but calling UserContract found that it could not be called.

【Put a picture here】

It stands to reason that we can just call the function method name directly. Why is there a situation where only CatContract can be called, but UserContract cannot be called.

2. Reason analysis

The reason analysis is as follows:

 After seeing the difference between the two pictures above, you can find that UserContract has a @Default annotation and UserContract does not have such an annotation.

Combined with getContract() method in fabric-gateway

It can be seen that if there are multiple contracts in a chaincode, @Default is the default contract.

At this time, CatContract is the default contract, so calling a non-default contract directly will result in an error.

3. Solutions

So how do we call non-default contracts?

3.1 The method of calling non-default contract in fabric-gateway

 As can be seen from the above example, if you want to call a non-default smart contract in the chaincode, you must explicitly write the ContractName and then call it.

This is the method specified in fabric-gateway, so we can check the source code to clarify how to call it on the command line.

3.2 Calling in the command line

It can be seen that in the process of fabric-gateway accessing the bottom layer of the block

The contract name contractName is called through the contract: method name , which is very important, and we also need to call it in the command line.

4. Practice

I redeployed the chaincode to give @Default to UserContract, and CatContract will be used as a non-default contract.

Let's call CatContract specifically

When I fill in the command line:

peer chaincode invoke -o orderer0.example.com:7050 --ordererTLSHostnameOverride orderer0.example.com --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C businesschannel -n hyperledger-fabric-contract-java-demo --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"CatContract:createCat","Args":["cat-0" , "tom" ,  "3" , "蓝色" , "大懒猫"]}'

 The result is as follows:

It worked!

Description contractName: method name is valid! !

Problem solved successfully! !

5. Some pits in the process

5.1 Passing JSON parameters on the command line

In this smart contract, we need to pass in data in JSON format

It cannot be passed like this:

peer chaincode invoke -o orderer0.example.com:7050 --ordererTLSHostnameOverride orderer0.example.com --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C businesschannel -n hyperledger-fabric-contract-java-demo --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"regUser","Args":["person-30" , "20211" ,  "aa" , "男" , "10月1日","19525"]}'

 This way of passing is not in JSON format, but passing parameters one by one, and an error will be reported!

 

The JSON format should be:

peer chaincode invoke -o orderer0.example.com:7050 --ordererTLSHostnameOverride orderer0.example.com --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C businesschannel -n hyperledger-fabric-contract-java-demo --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"regUser","Args":["{\"key\": \"person-30\",\"idCard\": \"202125201151\",\"name\": \"aaa\",\"sex\": \"男\",\"birthday\": \"1001\",\"phone\": \"123456\"}"]}'

Write JSON as a parameter and escape each quotation mark with \, so that the parameter can be passed successfully!

 

Guess you like

Origin blog.csdn.net/Wannabe_hacker/article/details/129337348