Hyperledger fabric介绍之智能合约案例(一)——转账
智能合约是在区块链网络中自动执行的计算机程序,用于定义和执行参与方之间的交易规则。这意味着在网络中可以同时存在多个版本的智能合约,并且参与方可以选择使用特定版本的合约进行交易。交易执行顺序:在Hyperledger Fabric中,交易的执行顺序是通过共识算法来确定的。共识算法确保网络中的所有参与方就交易的顺序达成一致,从而确保交易的一致性。事件通知:Chaincode可以触发事件通知,将特定事件
Hyperledger Fabric是一个开源的企业级分布式账本平台,提供了一种创建和执行智能合约的框架。智能合约是在区块链网络中自动执行的计算机程序,用于定义和执行参与方之间的交易规则。
关键:
-
Chaincode(链码):在Hyperledger Fabric中,智能合约被称为Chaincode。Chaincode是一段开发者编写的程序代码,用于定义业务逻辑和交易规则。它可以在网络中的多个节点上部署和执行,并且具有高度的安全性和可扩展性。
-
编写语言:Hyperledger Fabric支持使用多种编程语言编写链码,包括Go、Java和Node.js。这使得开发者可以使用自己熟悉的编程语言来编写智能合约。
-
版本控制:每个Chaincode都有一个唯一的版本号,并且可以通过升级来更新。这意味着在网络中可以同时存在多个版本的智能合约,并且参与方可以选择使用特定版本的合约进行交易。
-
隐私和权限:Hyperledger Fabric允许在智能合约中定义访问控制策略,实现细粒度的权限管理。这意味着只有被授权的参与方可以访问和执行特定的智能合约。
-
交易执行顺序:在Hyperledger Fabric中,交易的执行顺序是通过共识算法来确定的。共识算法确保网络中的所有参与方就交易的顺序达成一致,从而确保交易的一致性。
-
交易验证:智能合约可以对交易进行验证,以确保交易满足特定的条件或规则。如果交易不满足合约中定义的条件,那么交易将被拒绝,并且不会被写入账本。
-
事件通知:Chaincode可以触发事件通知,将特定事件的信息发送给网络中的其他参与方。这使得参与方能够对特定的状态变化做出相应的响应。
func (s *AssetTransfer) Transfer(ctx contractapi.TransactionContextInterface, to string, value int) error {
sender, _ := ctx.GetClientIdentity().GetID()
Transfer
方法是智能合约中的一个函数,用于执行资产转移操作。它接收一个 TransactionContextInterface
对象作为上下文参数,以及接收方地址和转移的数量作为输入参数。
ctx.GetClientIdentity().GetID()
用于获取调用智能合约的客户端身份的唯一标识符(sender)
balance, err := ctx.GetStub().GetState(sender)
if err != nil {
return fmt.Errorf("failed to read from world state: %w", err)
}
if balance == nil {
return fmt.Errorf("sender does not exist: %s", sender)
}
ctx.GetStub().GetState(sender)
用于从账本中读取发送方(sender)的余额
senderBalance, _ := strconv.Atoi(string(balance))
if senderBalance < value {
return fmt.Errorf("insufficient balance")
}
strconv.Atoi(string(balance))
将发送方的余额转换为整数类型。
receiverBalanceStr, err := ctx.GetStub().GetState(to)
if err != nil {
return fmt.Errorf("failed to read receiver balance: %w", err)
}
receiverBalance, err := strconv.Atoi(string(receiverBalanceStr))
if err != nil {
return fmt.Errorf("failed to convert receiver balance to integer: %w", err)
}
receiverBalance += value
senderBalance -= value
ctx.GetStub().GetState(to)
用于从账本中读取接收方(to)的余额。
strconv.Atoi(string(receiverBalanceStr))
将接收方的余额转换为整数类型。将转移的数量 value
加到接收方的余额上,并从发送方的余额中减去转移的数量。
err = ctx.GetStub().PutState(sender, []byte(strconv.Itoa(senderBalance)))
if err != nil {
return fmt.Errorf("failed to update sender balance: %w", err)
}
err = ctx.GetStub().PutState(to, []byte(strconv.Itoa(receiverBalance)))
if err != nil {
return fmt.Errorf("failed to update receiver balance: %w", err)
}
ctx.GetStub().PutState(sender, []byte(strconv.Itoa(senderBalance)))
将更新后的发送方余额存储回账本。
ctx.GetStub().PutState(to, []byte(strconv.Itoa(receiverBalance)))
将更新后的接收方余额存储回账本。
if err := chaincode.Start(); err != nil {
fmt.Printf("Error starting asset transfer chaincode: %s", err.Error())
}
chaincode.Start()
用于启动链码服务,使其能够处理来自Fabric网络的请求。
代码示例
package main
import (
"fmt"
"strconv"
"github.com/hyperledger/fabric-contract-api-go/contractapi"
)
type AssetTransfer struct {
contractapi.Contract
}
func (s *AssetTransfer) Transfer(ctx contractapi.TransactionContextInterface, to string, value int) error {
sender, _ := ctx.GetClientIdentity().GetID()
balance, err := ctx.GetStub().GetState(sender)
if err != nil {
return fmt.Errorf("failed to read from world state: %w", err)
}
if balance == nil {
return fmt.Errorf("sender does not exist: %s", sender)
}
senderBalance, _ := strconv.Atoi(string(balance))
if senderBalance < value {
return fmt.Errorf("insufficient balance")
}
receiverBalanceStr, err := ctx.GetStub().GetState(to)
if err != nil {
return fmt.Errorf("failed to read receiver balance: %w", err)
}
receiverBalance, err := strconv.Atoi(string(receiverBalanceStr))
if err != nil {
return fmt.Errorf("failed to convert receiver balance to integer: %w", err)
}
receiverBalance += value
senderBalance -= value
err = ctx.GetStub().PutState(sender, []byte(strconv.Itoa(senderBalance)))
if err != nil {
return fmt.Errorf("failed to update sender balance: %w", err)
}
err = ctx.GetStub().PutState(to, []byte(strconv.Itoa(receiverBalance)))
if err != nil {
return fmt.Errorf("failed to update receiver balance: %w", err)
}
return nil
}
func main() {
assetTransfer := new(AssetTransfer)
chaincode, err := contractapi.NewChaincode(assetTransfer)
if err != nil {
fmt.Printf("Error creating asset transfer chaincode: %s", err.Error())
return
}
if err := chaincode.Start(); err != nil {
fmt.Printf("Error starting asset transfer chaincode: %s", err.Error())
}
}
更多推荐
所有评论(0)