Brother Lian Blockchain technical training Fabric 1.0 Source Code Analysis (chaincode) Peer #peer Command and Sub-command implementation
# Fabric 1.0 Source Notes Peer #peer chaincode Command and Sub-command implementation
# 1, Peer Chaincode Install sub-command implementation (installation chain code)
# # 1.0, Peer Chaincode Install sub-command overview
Peer Chaincode installs the source code and environment of the chain code as a chain-code installation package file and transfers it to the endorsement node.
Peer Chaincode install supports the following two ways:
* Specify code mode, peer Chaincode install-n < chain code name >-v < link code version >-p < link path >
* Based on chain code package file, peer Chaincode install < chain code package file >
# # # 1.1, initialize the endorser client
"Go
CF, err = Initcmdfactory (true, False)
Code in Peer/chaincode/install.go
```
CF, err = Initcmdfactory (True, false) code is as follows:
"Go
Func initcmdfactory (isendorserrequired, isordererrequired bool) (*chaincodecmdfactory, error) {
var err error
var endorserclient pb. Endorserclient
If isendorserrequired {
Get endorser Client
Endorserclient, err = common. GETENDORSERCLIENTFNC ()//func getendorserclient () (PB. Endorserclient, error)
}
Get signature
Signer, err: = Common. GETDEFAULTSIGNERFNC ()
var broadcastclient common. Broadcastclient
If isordererrequired {
Not used here, temporary
}
Construction Chaincodecmdfactory
Return &chaincodecmdfactory{
Endorserclient:endorserclient,
Signer:signer,
Broadcastclient:broadcastclient,
}, Nil
}
Code in Peer/chaincode/common.go
```
# # # 1.2, construct Chaincodedeploymentspec message (chain code information and chain code file packaging)
"Go
if ccpackfile = = "" {//Specify code mode, reconstruct construct Chaincodedeploymentspec message
Ccpackmsg, err = Genchaincodedeploymentspec (cmd, chaincodename, chaincodeversion)
} else {//chain code-based package file mode, direct read CHAINCODEDEPLOYMENTSPEC message
var CDs *pb. Chaincodedeploymentspec
Ccpackmsg, CDs, err = Getpackagefromfile (ccpackfile)
}
Code in Peer/chaincode/install.go
```
Ccpackmsg, err = Genchaincodedeploymentspec (cmd, chaincodename, chaincodeversion) code is as follows:
"Go
Func genchaincodedeploymentspec (cmd *cobra.command, chaincodename, chaincodeversion string) (*PB. Chaincodedeploymentspec, error) {
already exists, direct error
If existed, _: = Ccprovider. Chaincodepackageexists (Chaincodename, chaincodeversion); existed {
return nil, FMT. Errorf ("Chaincode%s:%s already exists", Chaincodename, Chaincodeversion)
}
Spec, err: = Getchaincodespec (cmd)
CDS, ERR: = Getchaincodedeploymentspec (Spec, true)
return CDs, NIL
}
Code in Peer/chaincode/install.go
```
Spec, err: = Getchaincodespec (cmd) code is as follows:
"Go
Func getchaincodespec (cmd *cobra.command) (*PB. Chaincodespec, error) {
Spec: = &PB. chaincodespec{}
ERR: = Checkchaincodecmdparams (cmd)//Check parameter legitimacy
Input: = &PB. chaincodeinput{}
Flags. Stringvarp (&chaincodectorjson, "ctor", "C", "{}", ctor specific execution parameter information for the chain code, default = {}
ERR: = json. Unmarshal ([]byte (Chaincodectorjson), &input)
Flags. Stringvarp (&chaincodelang, "Lang", "L", "Golang", Lang is the programming language of the chain code, the default is Golang
Chaincodelang = strings. ToUpper (Chaincodelang)
Spec = &PB. chaincodespec{
TYPE:PB. Chaincodespec_type (PB. Chaincodespec_type_value[chaincodelang]),
Chaincodeid: &PB. Chaincodeid{path:chaincodepath, Name:chaincodename, version:chaincodeversion},
Input:input,
}
Return spec, Nil
}
Code in Peer/chaincode/common.go
```
CDS, ERR: = Getchaincodedeploymentspec (spec, true) code is as follows:
"Go
Func getchaincodedeploymentspec (Spec *PB. Chaincodespec, crtpkg bool) (*PB. Chaincodedeploymentspec, error) {
var codepackagebytes []byte
If Chaincode. Isdevmode () = = False && crtpkg {
var err error
Err = Checkspec (spec)//Check spec legality
Codepackagebytes, err = container. Getchaincodepackagebytes (SPEC)//packaging chain code files and dependent files
}
Construction Chaincodedeploymentspec
Chaincodedeploymentspec: = &PB. Chaincodedeploymentspec{chaincodespec:spec, Codepackage:codepackagebytes}
Return Chaincodedeploymentspec, Nil
Code in Peer/chaincode/common.go
```
# # # 1.3, create LSCC proposal and sign
"Go
Creator, Err: = cf. Signer.serialize ()//Get Signer
Proposal is constructed by Chaincodedeploymentspec, that is, the chain code Chaincodedeploymentspec message is passed as a parameter to the LSCC system chain code and called
Call Createproposalfromcds (Chainid, CDs, creator, policy, ESCC, VSCC, "deploy")
Prop, _, Err: = Utils. Createinstallproposalfromcds (msg, creator)
var signedprop *pb. Signedproposal
Signedprop, err = Utils. Getsignedproposal (prop, cf. Signer)//signature proposal
Code in Peer/chaincode/install.go
```
Createproposalfromcds (Chainid, CDs, creator, policy, ESCC, VSCC, "deploy") codes are as follows:
"Go
Func Createproposalfromcds (Chainid string, msg Proto. Message, creator []byte, Policy []byte, ESCC []byte, VSCC []byte, PropType string] (*peer. Proposal, string, error) {
var ccinp *peer. Chaincodeinput
var b []byte
var err error
B, err = Proto. Marshal (msg)
Switch PropType {
Case "Deploy":
Fallthrough
Case "Upgrade":
CDS, OK: = Msg. (*peer. CHAINCODEDEPLOYMENTSPEC)
CCINP = &peer. Chaincodeinput{args: [][]byte{[]byte (PropType), []byte (Chainid), B, Policy, ESCC, VSCC}}
Case "Install":
CCINP = &peer. Chaincodeinput{args: [][]byte{[]byte (PropType), b}}
}
Lsccspec: = &peer. chaincodeinvocationspec{//Construction LSCC Chaincodeinvocationspec
Chaincodespec: &peer. chaincodespec{
Type:peer. Chaincodespec_golang,
Chaincodeid: &peer. Chaincodeid{name: "LSCC"},
INPUT:CCINP}}
return Createproposalfromcis (common. Headertype_endorser_transaction, Chainid, Lsccspec, creator)
}
Code in Protos/utils/proputils.go
```
# # 1.4, Submit and process proposal
"Go
Proposalresponse, err: = cf. Endorserclient.processproposal (context. Background (), Signedprop)
Code in Peer/chaincode/install.go
```
# 2, Peer Chaincode instantiate sub-command implementation (instantiation of the chain code)
# # 2.0, Peer Chaincode Instantiate overview
The peer Chaincode Instantiate command instantiates the installed chain code on the specified channel by constructing a transaction of the lifecycle Management System chain code (LSCC).
Create a container on peer to start, and perform initialization operations.
! [] (Peer_chaincode_instantiate.png)
# # # 2.1, Initialize endorserclient, signer, and broadcastclient
Close to 2.1, the Broadcastclient initialization code is as follows:
"Go
CF, err = Initcmdfactory (true, True)
Code in Peer/chaincode/instantiate.go
```
"Go
Func initcmdfactory (isendorserrequired, isordererrequired bool) (*chaincodecmdfactory, error) {
Initialize endorserclient, signer, ref. 1.1
var broadcastclient common. Broadcastclient
If isordererrequired {
Flags. Stringvarp (&orderingendpoint, "Orderer", "O", "", "ordering service endpoint")
Orderingendpoint for Orderer service address
Broadcastclient, err = common. GETBROADCASTCLIENTFNC (Orderingendpoint, TLS, Cafile)
}
}
Code in Peer/chaincode/common.go
```
Broadcastclient For more details, refer to [Fabric 1.0 source Note Peer #BroadcastClient (broadcast client)] (BROADCASTCLIENT.MD)
# # # 2.2, construct Chaincodedeploymentspec message
"Go
Spec, err: = Getchaincodespec (cmd)//Construction Chaincodespec, refer to this article 1.2
Constructs the Chaincodedeploymentspec, references this article 1.2, but cannot package the chain code file
CDS, ERR: = Getchaincodedeploymentspec (spec, false)
Code in Peer/chaincode/instantiate.go
```
# # # 2.3, create LSCC proposal and sign
"Go
Creator, Err: = cf. Signer.serialize ()//Get Signer
Policymarhsalled is Flags.stringvarp (&policy, "policy", "P", common. Undefinedparamvalue, the endorsement strategy of Link Code Association
Call Createproposalfromcds (Chainid, CDs, creator, policy, ESCC, VSCC, "deploy"), refer to this article 1.3
Prop, _, Err: = Utils. Createdeployproposalfromcds (Chainid, CDs, creator, policymarhsalled, []byte (ESCC), []byte (VSCC))
var signedprop *pb. Signedproposal
Signedprop, err = Utils. Getsignedproposal (prop, cf. Signer)//signature proposal
Code in Peer/chaincode/instantiate.go
```
# # 2.4, Submit and process proposal, get proposal response and create a signed transaction envelope
"Go
Proposalresponse, err: = cf. Endorserclient.processproposal (context. Background (), Signedprop)
If proposalresponse! = Nil {
ENV, err: = Utils. CREATESIGNEDTX (prop, cf. Signer, proposalresponse)//create signed transactions by proposal envelope
Return env, Nil
}
Code in Peer/chaincode/instantiate.go
```
ENV, err: = Utils. CREATESIGNEDTX (prop, cf. Signer, Proposalresponse) code is as follows:
"Go
Func CREATESIGNEDTX (Proposal *peer. Proposal, signer MSP. Signingidentity, RESPs ... *peer. Proposalresponse) (*common. Envelope, error) {
HDR, ERR: = GetHeader (proposal. Header)//deserialize to common. Header
Ppayl, err: = Getchaincodeproposalpayload (proposal. Payload)//deserialize to peer. Chaincodeproposalpayload
Signerbytes, err: = signer. Serialize ()//signer serialization
SHDR, err: = Getsignatureheader (HDR. Signatureheader)//deserialize to common. Signatureheader
If Bytes.compare (Signerbytes, Shdr. Creator)! = 0 {//proposal Creator needs to be the same as the current signer
return nil, FMT. Errorf ("The signer needs to being the same as the one referenced in the header")
}
Hdrext, err: = Getchaincodeheaderextension (HDR)//header.channelheader deserialized to Peer.chaincodeheaderextension
var A1 []byte
For n, r: = Range RESPs {
if n = = 0 {
A1 = R.payload
If r.response.status! = 200 {//Check if Response.Status is 200
return nil, FMT. Errorf ("Proposal response is not successful, error code%d, msg%s", R.response.status, R.response.message)
}
Continue
}
If Bytes.compare (A1, r.payload)! = 0 {//check if all proposalresponse.payload are the same
return nil, FMT. Errorf ("Proposalresponsepayloads do not Match")
}
}
Endorsements: = Make ([]*peer. Endorsement, Len (RESPs))
For n, r: = Range RESPs {
Endorsements[n] = r.endorsement
}
The following is a layered build of common. Envelope
CEA: = &peer. Chaincodeendorsedaction{proposalresponsepayload:resps[0]. Payload, endorsements:endorsements}
Proppayloadbytes, err: = Getbytesproposalpayloadfortx (Ppayl, hdrext.payloadvisibility)
Cap: = &peer. Chaincodeactionpayload{chaincodeproposalpayload:proppayloadbytes, Action:cea}
Capbytes, err: = Getbyteschaincodeactionpayload (CAP)
TAA: = &peer. Transactionaction{header:hdr. Signatureheader, Payload:capbytes}
Taas: = Make ([]*peer. Transactionaction, 1)
Taas[0] = TAA
TX: = &peer. Transaction{actions:taas}
Txbytes, err: = Getbytestransaction (TX)
Payl: = &common. PAYLOAD{HEADER:HDR, Data:txbytes}
Paylbytes, err: = Getbytespayload (Payl)
SIG, Err: = signer. Sign (paylbytes)
Return &common. Envelope{payload:paylbytes, Signature:sig}, Nil
}
Code in Protos/utils/txutils.go
```
Common. Envelope More details, refer to: [Fabric 1.0 Source Code notes Appendix-Key data structure (figure)] (.. /ANNEX/DATASTRUCTURE.MD)
# # 2.5, to Orderer broadcast transaction envelope
"Go
Err = cf. Broadcastclient.send (ENV)
Code in Peer/chaincode/instantiate.go
```
# 3, Peer Chaincode invoke sub-command implementation (call chain code)
# # 3.0, Peer Chaincode Invoke overview
The Invoke command allows you to invoke the method of a running chain code.
! [] (Peer_chaincode_invoke (query). png)
# # # 3.1, Initialize endorserclient, signer, and broadcastclient
Refer to this article 1.1 and 2.1.
"Go
CF, err = Initcmdfactory (true, True)
Code in Peer/chaincode/invoke.go
```
# # 3.2, Construction Chaincodeinvocationspec
"Go
Spec, err: = Getchaincodespec (cmd)//Construction Chaincodespec
Invocation: = &PB. CHAINCODEINVOCATIONSPEC{CHAINCODESPEC:SPEC}//Construction Chaincodeinvocationspec
Code in Peer/chaincode/common.go
```
# # # 3.3, create Chaincode proposal and sign
"Go
Creator, Err: = signer. Serialize ()
VAR prop *pb. Proposal
Prop, _, err = Putils. Createproposalfromcis (Pcommon. Headertype_endorser_transaction, CID, invocation, creator)
var signedprop *pb. Signedproposal
Signedprop, err = putils. Getsignedproposal (prop, signer)//proposal signature
Code in Peer/chaincode/common.go
```
# # 3.4, submit and process proposal, get proposal response
"Go
var proposalresp *pb. Proposalresponse
PROPOSALRESP, err = endorserclient.processproposal (context. Background (), Signedprop)
Code in Peer/chaincode/common.go
```
# # # 3.5, create a signed transaction envelope and broadcast the transaction to Orderer envelope
"Go
If invoke {
ENV, err: = Putils. CREATESIGNEDTX (prop, signer, PROPOSALRESP)//Create a signed transaction
err = BC. Send (env)//Broadcast transaction
}
Code in Peer/chaincode/common.go
```
# 4, Peer Chaincode Query Sub-command implementation (query chain code)
With 3, peer Chaincode Invoke subcommand implementation (call chain code) is basically the same, the difference is that after the submission and processing of proposal, no longer create transactions and broadcast transactions.
Is the technology development too fast, or we have lost the end? From July 7 onwards, two hours a day with the Tsinghua Microsoft Google Daniel team to combat the blockchain. HTTP://WWW.YDMA.CN/OPEN/COURSE/16 to come, Tsinghua Genius Yin Cheng Big Brother take you fly up ~ ~ ~