Hyperledger fabric介绍之智能合约案例(一)——转账

Hyperledger Fabric是一个开源的企业级分布式账本平台,提供了一种创建和执行智能合约的框架。智能合约是在区块链网络中自动执行的计算机程序,用于定义和执行参与方之间的交易规则。

关键:

  1. Chaincode(链码):在Hyperledger Fabric中,智能合约被称为Chaincode。Chaincode是一段开发者编写的程序代码,用于定义业务逻辑和交易规则。它可以在网络中的多个节点上部署和执行,并且具有高度的安全性和可扩展性。

  2. 编写语言:Hyperledger Fabric支持使用多种编程语言编写链码,包括Go、Java和Node.js。这使得开发者可以使用自己熟悉的编程语言来编写智能合约。

  3. 版本控制:每个Chaincode都有一个唯一的版本号,并且可以通过升级来更新。这意味着在网络中可以同时存在多个版本的智能合约,并且参与方可以选择使用特定版本的合约进行交易。

  4. 隐私和权限:Hyperledger Fabric允许在智能合约中定义访问控制策略,实现细粒度的权限管理。这意味着只有被授权的参与方可以访问和执行特定的智能合约。

  5. 交易执行顺序:在Hyperledger Fabric中,交易的执行顺序是通过共识算法来确定的。共识算法确保网络中的所有参与方就交易的顺序达成一致,从而确保交易的一致性。

  6. 交易验证:智能合约可以对交易进行验证,以确保交易满足特定的条件或规则。如果交易不满足合约中定义的条件,那么交易将被拒绝,并且不会被写入账本。

  7. 事件通知: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())
	}
}

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值