チャンネル作成したソースコードの解析
チャネル構成と操作コマンドを作成します。1.
主にconfigtx.yaml。プロファイルアプリケーションチャネルの通過によって作成されたコンフィギュレーション・ファイルを生成します。
TwoOrgsChannel:
Consortium: SampleConsortium
<<: *ChannelDefaults
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities
次に、クライアント上でチャンネルを作成するには、次のコマンドを実行します。
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile $ORDERER_CA
ピア・チャネルは、コマンドを作成します。
Create a channel and write the genesis block to a file.
Usage:
peer channel create [flags]
Flags:
-c, --channelID string In case of a newChain command, the channel ID to create. It must be all lower case, less than 250 characters long and match the regular expression: [a-z][a-z0-9.-]*
-f, --file string Configuration transaction file generated by a tool such as configtxgen for submitting to orderer
-h, --help help for create
--outputBlock string The path to write the genesis block for the channel. (default ./<channelID>.block)
-t, --timeout duration Channel creation timeout (default 10s)
Global Flags:
--cafile string Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint
--certfile string Path to file containing PEM-encoded X509 public key to use for mutual TLS communication with the orderer endpoint
--clientauth Use mutual TLS when communicating with the orderer endpoint
--connTimeout duration Timeout for client to connect (default 3s)
--keyfile string Path to file containing PEM-encoded private key to use for mutual TLS communication with the orderer endpoint
-o, --orderer string Ordering service endpoint
--ordererTLSHostnameOverride string The hostname override to use when validating the TLS connection to the orderer.
--tls Use TLS when communicating with the orderer endpoint
チャネルコマンド実行プロセスを作成します。2.
最初は、メインピアmain.goファイル()メソッドでは、関連の操作コマンドをピアを追加します。
mainCmd.AddCommand(version.Cmd())
mainCmd.AddCommand(node.Cmd())
mainCmd.AddCommand(chaincode.Cmd(nil))
mainCmd.AddCommand(clilogging.Cmd(nil))
mainCmd.AddCommand(channel.Cmd(nil))
チャネルに関連するコマンドコード:
// Cmd returns the cobra command for Node
func Cmd(cf *ChannelCmdFactory) *cobra.Command {
AddFlags(channelCmd)
channelCmd.AddCommand(createCmd(cf))
channelCmd.AddCommand(fetchCmd(cf))
channelCmd.AddCommand(joinCmd(cf))
channelCmd.AddCommand(listCmd(cf))
channelCmd.AddCommand(updateCmd(cf))
channelCmd.AddCommand(signconfigtxCmd(cf))
channelCmd.AddCommand(getinfoCmd(cf))
return channelCmd
}
このうち、インタフェース・チャネルコールを作成すると、作成される(CMD、引数、CF)
func createCmd(cf *ChannelCmdFactory) *cobra.Command {
createCmd := &cobra.Command{
Use: "create",
Short: "Create a channel",
Long: "Create a channel and write the genesis block to a file.",
RunE: func(cmd *cobra.Command, args []string) error {
return create(cmd, args, cf)
},
}
flagList := []string{
"channelID",
"file",
"outputBlock",
"timeout",
}
attachFlags(createCmd, flagList)
return createCmd
}
peerコマンドのビルドプロセスのためのチャネルを作成するには、上記の。create()メソッドとして実装され、特定のチャネルを作成します。
- もしチャネルID「」エラー
- 何CmdFactory、初期設定がない場合CmdFactory
- CmdFactory着信executeCreate()メソッドは、論理チャネルを作成するプロセス
func create(cmd *cobra.Command, args []string, cf *ChannelCmdFactory) error {
// the global chainID filled by the "-c" command
if channelID == common.UndefinedParamValue {
return errors.New("must supply channel ID")
}
// Parsing of the command line is done so silence cmd usage
cmd.SilenceUsage = true
var err error
if cf == nil {
cf, err = InitCmdFactory(EndorserNotRequired, PeerDeliverNotRequired, OrdererRequired)
if err != nil {
return err
}
}
return executeCreate(cf)
}
今InitCmdFactory()メソッドを見て:
// InitCmdFactory init the ChannelCmdFactory with clients to endorser and orderer according to params
func InitCmdFactory(isEndorserRequired, isPeerDeliverRequired, isOrdererRequired bool) (*ChannelCmdFactory, error) {
// 只从peer或者orderer其中一个获取区块
if isPeerDeliverRequired && isOrdererRequired {
// this is likely a bug during development caused by adding a new cmd
return nil, errors.New("ERROR - only a single deliver source is currently supported")
}
var err error
cf := &ChannelCmdFactory{}
// 获取默认签名(默认peer)
cf.Signer, err = common.GetDefaultSignerFnc()
if err != nil {
return nil, errors.WithMessage(err, "error getting default signer")
}
cf.BroadcastFactory = func() (common.BroadcastClient, error) {
// 获取BroadcastClient
return common.GetBroadcastClientFnc()
}
// for join and list, we need the endorser as well
if isEndorserRequired {
//创建背书客户端
// creating an EndorserClient with these empty parameters will create a
// connection using the values of "peer.address" and
// "peer.tls.rootcert.file"
cf.EndorserClient, err = common.GetEndorserClientFnc(common.UndefinedParamValue, common.UndefinedParamValue)
if err != nil {
return nil, errors.WithMessage(err, "error getting endorser client for channel")
}
}
// for fetching blocks from a peer
// NewDeliverClientForPeer creates a new DeliverClient from a PeerClient
if isPeerDeliverRequired {
cf.DeliverClient, err = common.NewDeliverClientForPeer(channelID)
if err != nil {
return nil, errors.WithMessage(err, "error getting deliver client for channel")
}
}
// for create and fetch, we need the orderer as well
if isOrdererRequired {
if len(strings.Split(common.OrderingEndpoint, ":")) != 2 {
return nil, errors.Errorf("ordering service endpoint %s is not valid or missing", common.OrderingEndpoint)
}
cf.DeliverClient, err = common.NewDeliverClientForOrderer(channelID)
if err != nil {
return nil, err
}
}
logger.Infof("Endorser and orderer connections initialized")
return cf, nil
}
概要:唯一のソース発注を届ける/ブロックを取得するためにチャネルを作成し、クライアントの承認を作成する必要はありません。作成は、発注者からのクライアントの要件を提供します。
チャネル実現を作成します3。
チャネルは、トランザクションを作成し、送信チャネルに基づいて、トランザクションがChannelCmdFactory CF作成され、その後、作成ブロックを取得し、格納するexecuteCreate()メソッド
- トランザクションを送信するためのチャネルを作成します。
- ブロックを取得します。
- プロトシリアライズして保存
func executeCreate(cf *ChannelCmdFactory) error {
//发送创建通道的Transaction到Order节点
err := sendCreateChainTransaction(cf)
if err != nil {
return err
}
//获取该通道内的创世区块(该过程在Order节点共识完成之后)
block, err := getGenesisBlock(cf)
if err != nil {
return err
}
//序列化创世区块
b, err := proto.Marshal(block)
if err != nil {
return err
}
file := channelID + ".block"
if outputBlock != common.UndefinedParamValue {
file = outputBlock
}
//将创世区块保存到本地
err = ioutil.WriteFile(file, b, 0644)
if err != nil {
return err
}
return nil
}
トランザクションを送信するためのチャネルを作成するには、3.1
- ビューの貿易データ構造
// Envelope wraps a Payload with a signature so that the message may be authenticated
type Envelope struct {
// A marshaled Payload
// 序列化后的相关信息
Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
// A signature by the creator specified in the Payload header
// 签名
Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
取引方法のコードを送信します。
func sendCreateChainTransaction(cf *ChannelCmdFactory) error {
var err error
var chCrtEnv *cb.Envelope
// 如果存在tx文件,则从tx文件生成创建通道交易
if channelTxFile != "" {
if chCrtEnv, err = createChannelFromConfigTx(channelTxFile); err != nil {
return err
}
} else {
// 不存在,则利用默认模版生成
if chCrtEnv, err = createChannelFromDefaults(cf); err != nil {
return err
}
}
// 对创建通道交易进行验证
if chCrtEnv, err = sanityCheckAndSignConfigTx(chCrtEnv); err != nil {
return err
}
// 创建广播客户端
var broadcastClient common.BroadcastClient
broadcastClient, err = cf.BroadcastFactory()
if err != nil {
return errors.WithMessage(err, "error getting broadcast client")
}
// 将交易广播出去
defer broadcastClient.Close()
err = broadcastClient.Send(chCrtEnv)
return err
}
- これは、構造を定義するエンベロープ
- 判定channelTxFileファイル(ネットワークを開始する前に作成したchannel.tx)、それは一般的に存在する、存在しています。
- ある場合は、そのファイルから設定情報を読み込むには存在しない、デフォルトのテンプレートから作成し、最終的に封筒を返します
- 検証するファイルの封筒
情報を放送するためのクライアントを作成し、封筒のファイルは、放送のうちに作成されます。
3.2発注プロセス取引
このセクションでは、意志の詳細取引プロセスと発注元
4.付録
channel.txファイル
{
"payload":{
"data":{
"config_update":{
"channel_id":"mychannel",
"read_set":{
"groups":{
"Application":{
"groups":{
"Org1MSP":{
"mod_policy":"",
"version":"0"
},
"Org2MSP":{
"mod_policy":"",
"version":"0"
}
},
"mod_policy":"",
"version":"0"
}
},
"mod_policy":"",
"values":{
"Consortium":{
"mod_policy":"",
"version":"0"
}
},
"version":"0"
},
"write_set":{
"groups":{
"Application":{
"groups":{
"Org1MSP":{
"mod_policy":"",
"version":"0"
},
"Org2MSP":{
"mod_policy":"",
"version":"0"
}
},
"mod_policy":"Admins",
"policies":{
"Admins":{
"mod_policy":"Admins",
"policy":{
"type":3,
"value":{
"rule":"MAJORITY",
"sub_policy":"Admins"
}
},
"version":"0"
},
"Readers":{
"mod_policy":"Admins",
"policy":{
"type":3,
"value":{
"rule":"ANY",
"sub_policy":"Readers"
}
},
"version":"0"
},
"Writers":{
"mod_policy":"Admins",
"policy":{
"type":3,
"value":{
"rule":"ANY",
"sub_policy":"Writers"
}
},
"version":"0"
}
},
"values":{
"Capabilities":{
"mod_policy":"Admins",
"value":{
"capabilities":{
"V1_2":{
}
}
},
"version":"0"
}
},
"version":"1"
}
},
"mod_policy":"",
"values":{
"Consortium":{
"mod_policy":"",
"value":{
"name":"SampleConsortium"
},
"version":"0"
}
},
"version":"0"
}
}
},
"header":{
"channel_header":{
"channel_id":"mychannel",
"epoch":"0",
"timestamp":"2019-11-26T02:46:37.000Z",
"tx_id":"",
"type":2,
"version":0
}
}
}
}