共计 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 行业资讯频道。