共計 5054 個字符,預計需要花費 13 分鐘才能閱讀完成。
本篇文章為大家展示了怎么進行區塊鏈中的 fabric chaincode 分析,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
chaincode 是所有區塊鏈項目的核心,無論是公鏈還是私鏈。
fabric 如何形成 chaincode, 下圖是 fabric chaincode 的核心模塊組成
GenerateDockerfile 是生成 chaincode dockerfile 的函數
func (carPlatform Platform) GenerateDockerfile(cds pb.ChaincodeDeploymentSpec) (string, error) {
var buf []string
//let the executable’s name be chaincode ID’s name
buf = append(buf,“FROM“+cutil.GetDockerfileFromConfig(“chaincode.car.runtime”))
buf = append(buf,“ADD binpackage.tar /usr/local/bin”)
dockerFileContents := strings.Join(buf,“\n”)
return dockerFileContents, nil
}
構建鏡像函數
func (carPlatform *Platform) GenerateDockerBuild(cds *pb.ChaincodeDeploymentSpec, tw *tar.Writer) error {
// Bundle the .car file into a tar stream so it may be transferred to the builder container
codepackage, output := io.Pipe()
go func() {
tw := tar.NewWriter(output)
err := cutil.WriteBytesToPackage(codepackage.car , cds.CodePackage, tw)
tw.Close()
output.CloseWithError(err)
}()
binpackage := bytes.NewBuffer(nil)
err := util.DockerBuild(util.DockerBuildOptions{
Cmd: java -jar /usr/local/bin/chaintool buildcar /chaincode/input/codepackage.car -o /chaincode/output/chaincode ,
InputStream: codepackage,
OutputStream: binpackage,
})
if err != nil {
return fmt.Errorf(Error building CAR: %s , err)
}
return cutil.WriteBytesToPackage(binpackage.tar , binpackage.Bytes(), tw)
}
創建容器并上傳
func DockerBuild(opts DockerBuildOptions) error {
client, err := cutil.NewDockerClient()
if err != nil {
return fmt.Errorf(Error creating docker client: %s , err)
}
if opts.Image == {
opts.Image = cutil.GetDockerfileFromConfig(chaincode.builder)
if opts.Image == {
return fmt.Errorf(No image provided and \ chaincode.builder\ default does not exist)
}
}
logger.Debugf(Attempting build with image %s , opts.Image)
//-----------------------------------------------------------------------------------
// Ensure the image exists locally, or pull it from a registry if it doesn t
//-----------------------------------------------------------------------------------
_, err = client.InspectImage(opts.Image)
if err != nil {
logger.Debugf(Image %s does not exist locally, attempt pull , opts.Image)
err = client.PullImage(docker.PullImageOptions{Repository: opts.Image}, docker.AuthConfiguration{})
if err != nil {
return fmt.Errorf(Failed to pull %s: %s , opts.Image, err)
}
}
//-----------------------------------------------------------------------------------
// Create an ephemeral container, armed with our Env/Cmd
//-----------------------------------------------------------------------------------
container, err := client.CreateContainer(docker.CreateContainerOptions{
Config: docker.Config{
Image: opts.Image,
Env: opts.Env,
Cmd: []string{ /bin/sh , -c , opts.Cmd},
AttachStdout: true,
AttachStderr: true,
},
})
if err != nil {
return fmt.Errorf(Error creating container: %s , err)
}
defer client.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID})
//-----------------------------------------------------------------------------------
// Upload our input stream
//-----------------------------------------------------------------------------------
err = client.UploadToContainer(container.ID, docker.UploadToContainerOptions{
Path: /chaincode/input ,
InputStream: opts.InputStream,
})
if err != nil {
return fmt.Errorf(Error uploading input to container: %s , err)
}
//-----------------------------------------------------------------------------------
// Attach stdout buffer to capture possible compilation errors
//-----------------------------------------------------------------------------------
stdout := bytes.NewBuffer(nil)
_, err = client.AttachToContainerNonBlocking(docker.AttachToContainerOptions{
Container: container.ID,
OutputStream: stdout,
ErrorStream: stdout,
Logs: true,
Stdout: true,
Stderr: true,
Stream: true,
})
if err != nil {
return fmt.Errorf(Error attaching to container: %s , err)
}
//-----------------------------------------------------------------------------------
// Launch the actual build, realizing the Env/Cmd specified at container creation
//-----------------------------------------------------------------------------------
err = client.StartContainer(container.ID, nil)
if err != nil {
return fmt.Errorf(Error executing build: %s \ %s\ , err, stdout.String())
}
//-----------------------------------------------------------------------------------
// Wait for the build to complete and gather the return value
//-----------------------------------------------------------------------------------
retval, err := client.WaitContainer(container.ID)
if err != nil {
return fmt.Errorf(Error waiting for container to complete: %s , err)
}
if retval 0 {
return fmt.Errorf(Error returned from build: %d \ %s\ , retval, stdout.String())
}
//-----------------------------------------------------------------------------------
// Finally, download the result
//-----------------------------------------------------------------------------------
err = client.DownloadFromContainer(container.ID, docker.DownloadFromContainerOptions{
Path: /chaincode/output/. ,
OutputStream: opts.OutputStream,
})
if err != nil {
return fmt.Errorf(Error downloading output: %s , err)
}
return nil
}
上述內容就是怎么進行區塊鏈中的 fabric chaincode 分析,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注丸趣 TV 行業資訊頻道。