以下是使用Go语言编写的一个简单的转账智能合约,代码中有详细的注释:
package mainimport ( "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的安全最佳实践。