天天看点

手把手教你用Go语言编写Fabric智能合约,轻松入门区块链开发

作者:威哥说编程

以下是使用Go语言编写的一个简单的转账智能合约,代码中有详细的注释:

package main

import (
	"fmt"

	"github.com/hyperledger/fabric-contract-api-go/contractapi"
)

// 定义智能合约结构体
type TransferContract struct {
	contractapi.Contract
}

// 转账方法,接收转出账户名、转入账户名和转账金额三个参数
func (tc *TransferContract) Transfer(ctx contractapi.TransactionContextInterface, from, to string, amount int) error {
	// 检查转账金额是否合法
	if amount <= 0 {
		return fmt.Errorf("转账金额 %d 不合法", amount)
	}

	// 读取转出账户的余额
	fromAccount, err := ctx.GetStub().GetState(from)
	if err != nil {
		return fmt.Errorf("读取账户 %s 失败", from)
	}

	// 如果转出账户不存在,则返回错误
	if fromAccount == nil {
		return fmt.Errorf("账户 %s 不存在", from)
	}

	// 将余额从字节数组中解码为整数
	fromBalance := int(fromAccount[0])

	// 如果余额不足,则返回错误
	if fromBalance < amount {
		return fmt.Errorf("账户 %s 余额不足", from)
	}

	// 更新转出账户余额
	fromBalance -= amount
	if fromBalance == 0 {
		// 如果余额为0,则从账本中删除该账户
		err = ctx.GetStub().DelState(from)
		if err != nil {
			return fmt.Errorf("删除账户 %s 失败", from)
		}
	} else {
		// 如果余额不为0,则将新余额保存到账本中
		err = ctx.GetStub().PutState(from, []byte{byte(fromBalance)})
		if err != nil {
			return fmt.Errorf("更新账户 %s 失败", from)
		}
	}

	// 更新转入账户余额
	toAccount, err := ctx.GetStub().GetState(to)
	if err != nil {
		return fmt.Errorf("读取账户 %s 失败", to)
	}

	// 如果转入账户不存在,则创建一个新账户
	if toAccount == nil {
		err = ctx.GetStub().PutState(to, []byte{byte(amount)})
		if err != nil {
			return fmt.Errorf("创建账户 %s 失败", to)
		}
	} else {
		// 如果转入账户已存在,则将转账金额添加到账户余额中
		toBalance := int(toAccount[0])
		toBalance += amount
		err = ctx.GetStub().PutState(to, []byte{byte(toBalance)})
		if err != nil {
			return fmt.Errorf("更新账户 %s 失败", to)
		}
	}

	// 输出转账信息
	fmt.Printf("账户 %s 转账 %d 到账户 %s 成功\n", from, amount, to)

	return nil
}

func main() {
	// 创建新的链码对象
	transferContract := new(TransferContract)

// 创建新的链码
cc, err := contractapi.NewChaincode(transferContract)
if err != nil {
	return fmt.Errorf("创建链码失败: %v", err)
}

// 启动链码服务器
if err := cc.Start(); err != nil {
	return fmt.Errorf("启动链码服务器失败: %v", err)
}

return nil           

以上代码中,我们创建了一个名为`TransferContract`的智能合约,包含一个`Transfer`方法,用于实现转账功能。在该方法中,我们首先检查转账金额是否合法,然后读取转出账户的余额,更新转出账户和转入账户的余额,并输出转账信息。最后,我们使用`contractapi.NewChaincode`创建了一个新的链码,并使用`cc.Start()`方法启动了链码服务器。

请注意,此示例仅用于演示目的。在实际开发中,您需要根据您的实际需求编写更复杂的智能合约,并遵循Fabric的安全最佳实践。