// payment project main.go
package main import (
"fmt"
"strconv" "github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
) type PaymentChaincode struct {
} func (t *PaymentChaincode) Init(stub shim.ChaincodeStubInterface) peer.Response {
_, args := stub.GetFunctionAndParameters()
if len(args) != 4 {
return shim.Error("初始化时必须指定两个用户并指定相应的初始余额")
} var a = args[0]
var avalStr = args[1]
var b = args[2]
var bvalStr = args[3] if len(a) < 2 {
return shim.Error(a + " 用户名长度不能少于2个字符长度")
}
if len(b) < 2 {
return shim.Error(b + " 用户名长度不能少于2个字符长度")
} _, err := strconv.Atoi(avalStr)
if err != nil {
return shim.Error("指定账户的初始余额错误:" + avalStr)
}
_, err = strconv.Atoi(bvalStr)
if err != nil {
return shim.Error("指定账户的初始余额错误:" + bvalStr)
} err = stub.PutState(a, []byte(avalStr))
if err != nil {
return shim.Error(a + " 保存状态时发生错误")
}
err = stub.PutState(b, []byte(bvalStr))
if err != nil {
return shim.Error(b + " 保存状态时发生错误")
}
return shim.Success([]byte("初始化成功"))
} func (t *PaymentChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
fun, args := stub.GetFunctionAndParameters()
if fun == "find" {
return find(stub, args)
} else if fun == "payment" {
return payment(stub, args)
} else if fun == "del" {
return delAccount(stub, args)
} else if fun == "add" {
return t.addAccount(stub, args)
} else if fun == "set" {
return t.set(stub, args)
} else if fun == "get" {
return t.get(stub, args)
}
return shim.Error("非法操作") } func find(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 1 {
return shim.Error("必须且只能指定要查询的用户名")
} result, err := stub.GetState(args[0])
if err != nil {
return shim.Error("查询 " + args[0] + " 账户信息失败:" + err.Error())
}
if result == nil {
return shim.Error("账户 " + args[0] + "没有查到余额信息")
}
return shim.Success(result)
} func payment(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 3 {
return shim.Error("必须且只能指定源账户、目标账户以及转账金额")
} source := args[0]
target := args[1]
x := args[2] svalStr, err := stub.GetState(source)
if err != nil {
return shim.Error("查询" + source + "账户失败")
} tvalStr, err := stub.GetState(target)
if err != nil {
return shim.Error("查询" + target + "账户失败")
} //转账
xval, err := strconv.Atoi(x)
if err != nil {
return shim.Error("转账金额错误")
} sval, err := strconv.Atoi(string(svalStr))
if err != nil {
return shim.Error("处理源账户余额时发生错误")
}
tval, err := strconv.Atoi(string(tvalStr))
if err != nil {
return shim.Error("处理目标账户余额时发生错误")
} if xval > sval {
return shim.Error("目标账户余额不足,交易失败")
} sval = sval - xval
tval = tval + xval //记账
err = stub.PutState(source, []byte(strconv.Itoa(sval)))
if err != nil {
return shim.Error("保存转账后源账户信息失败")
}
err = stub.PutState(target, []byte(strconv.Itoa(tval)))
if err != nil {
return shim.Error("保存转账后目标账户信息失败")
}
return shim.Success([]byte("转账成功"))
} func delAccount(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 1 {
return shim.Error("必须且只能指定要删除的账户名称")
}
result, err := stub.GetState(args[0])
if err != nil {
return shim.Error("查询 " + args[0] + " 账户信息失败" + err.Error())
}
if result == nil {
return shim.Error("根据指定 " + args[0] + " 没有查询到对应的余额")
}
err = stub.DelState(args[0])
if err != nil {
return shim.Error("删除指定的账户失败: " + args[0] + ", " + err.Error())
}
return shim.Success([]byte("删除指定的账户成功" + args[0]))
} func (t *PaymentChaincode) addAccount(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 2 {
return shim.Error("必须且只能指定要新增的账户及初始金额")
} a := args[0]
val := args[1] if len(a) < 2 {
return shim.Error(a + " 用户名长度不能少于2个字符长度")
}
_, err := strconv.Atoi(val)
if err != nil {
return shim.Error("指定账户的初始余额错误:" + val)
} result, err := stub.GetState(args[0])
if err != nil {
return shim.Error("查询 " + args[0] + " 账户信息失败" + err.Error())
}
if result == nil {
err = stub.PutState(args[0], []byte(args[1]))
if err != nil {
return shim.Error("保存账户:" + a + " 时发生错误")
}
return shim.Success([]byte("新增账户成功"))
}
return t.set(stub, args)
} func (t *PaymentChaincode) set(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 2 {
return shim.Error("必须且只能指定账户名和存入的金额")
} result, err := stub.GetState(args[0])
if err != nil {
return shim.Error("查询指定账户信息失败")
}
if result == nil {
return shim.Error("指定账户不存在")
} val, err := strconv.Atoi(string(result))
if err != nil {
return shim.Error("处理账户余额时发生错误")
} x, err := strconv.Atoi(args[1])
if err != nil {
return shim.Error("处理账户转入金额时发生错误")
} val = val + x
err = stub.PutState(args[0], []byte(strconv.Itoa(val)))
if err != nil {
return shim.Error("存入金额时发生错误")
}
return shim.Success([]byte("存入操作成功"))
} func (t *PaymentChaincode) get(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 2 {
return shim.Error("必须且只能指定要查询的账户及要提取的金额")
} x, err := strconv.Atoi(args[1])
if err != nil {
return shim.Error("提取金额输入有误")
} result, err := stub.GetState(args[0])
if err != nil {
return shim.Error("查询指定账户余额时发生错误")
}
if result == nil {
return shim.Error("指定账户不存在或已注销")
} val, err := strconv.Atoi(string(result))
if err != nil {
return shim.Error("处理账户余额时发生错误")
}
if val < x {
return shim.Error("账户余额不足,无法提取")
} val = val - x
err = stub.PutState(args[0], []byte(strconv.Itoa(val)))
if err != nil {
return shim.Error("提取失败,保存余额信息时发生错误")
}
return shim.Success([]byte("提取成功"))
} func main() {
err := shim.Start(new(PaymentChaincode))
if err != nil {
fmt.Println("启动 Payment 链码时发生错误:%s", err)
}
}

BTCU(高校区块链联盟)-联盟链第6讲作业的更多相关文章

  1. 用Java为Hyperledger Fabric(超级账本)开发区块链智能合约链代码之部署与运行示例代码

    部署并运行 Java 链代码示例 您已经定义并启动了本地区块链网络,而且已构建 Java shim 客户端 JAR 并安装到本地 Maven 存储库中,现在已准备好在之前下载的 Hyperledger ...

  2. 利用js查找页面中的内链,外链

    起初没听说过内链外链,只有链接锚文本,在面试中被问到如何查找到页面中的内链和外链,就在想,什么是内链和外链啊??????? 后来面试官给我解释了一下他们的区别,自己稍微懂了,自己当时回答的是通过获取a ...

  3. 谈JS中的作用域链与原型链(1)

    学习前端也有一段时间了,觉得自己可以与大家分享一些我当初遇到疑惑的东西,希望能给对此问题有疑惑的朋友带来一点帮助. 先来普及一下JS的概念(不要嫌我啰嗦,可能一些朋友开始学习JS是跟着视频和写好的代码 ...

  4. js 原型,原型链,原型链继承浅析

    对于网上的关于原型,原型链和原型链继承的晦涩语言说明就不累赘了,复制粘贴过来再解释一遍怕自己也整蒙了,本人最怕空气突然安静,四目对视,大眼对小眼,一脸懵逼. 我们先看下面

  5. 责任链模式 职责链模式 Chain of Responsibility Pattern 行为型 设计模式(十七)

    责任链模式(Chain of Responsibility Pattern) 职责链模式 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系 将这些对象连接成一条链,并沿着这 ...

  6. JS的作用域链与原型链

    来一波,好记性不如烂笔头. 这两条链子可是很重要的. 作用域链 当执行一段JS代码(全局代码或函数)时,JS引擎会创建为其创建一个作用域又称为执行上下文(Execution Context),在页面加 ...

  7. js原型、原型链、作用链、闭包全解

    https://www.2cto.com/kf/201711/698876.html [对象.变量] 一个对象就是一个类,可以理解为一个物体的标准化定义.它不是一个具体的实物,只是一个标准.而通过对象 ...

  8. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  9. js通过沿着作用域链还是原型链查找变量

    这是一道非常典型的JS闭包问题,结果和具体的解析请看这里. 对于其中的`函数作用域链的问题`博主似乎没有解释清楚,有一些疑问:js中的变量到底是沿着作用域链还是原型链查找呢? 首先,要分清作用域链与原 ...

随机推荐

  1. uboot对Flash和DDR的分区管理

    1.uboot阶段对Flash的分区 (1).所谓分区,就是对Flash进行分块管理. (2).PC机等产品中,因为大家都是在操作系统下使用硬盘的,整个硬盘由操作系统统一管理,操作系统会使用文件系统帮 ...

  2. Travelling Businessmen Problem

    Travelling Businessmen Problem 先求出图的两个部分,可能只有一个部分 然后用set模拟,得到不同部分差最小的 #include <bits/stdc++.h> ...

  3. Python实现自动处理表格,让你拥有更多的自由时间!

    相信有不少朋友日常工作会用到 Excel 处理各式表格文件,更有甚者可能要花大把时间来做繁琐耗时的表格整理工作.最近有朋友问可否编程来减轻表格整理工作量,今儿我们就通过实例来实现 Python 对表格 ...

  4. 深度学习数据集MNIST ImageNet COCO PASCAL VOC介绍

    参考文档 深度学习数据集汇总介绍 1.  MNIST 深度学习领域的“Hello World!”,入门必备!MNIST是一个手写数字数据库,它有60000个训练样本集和10000个测试样本集,每个样本 ...

  5. 八皇后问题 2n皇后问题

    Description 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某 ...

  6. shell手册

    摘自雪松同学 0说明{ # shell实例手册最新下载地址: http://hi.baidu.com/quanzhou722/item/f4a4f3c9eb37f02d46d5c0d9 # pytho ...

  7. RDD(九)——序列化问题

    在实际开发中我们往往需要自己定义一些对于RDD的操作,那么此时需要考虑的主要问题是,初始化工作是在Driver端进行的,而实际运行程序是在Executor端进行的,这就涉及到了跨进程通信,是需要序列化 ...

  8. Android之布局androidmanifest.xml 资源清单 概述

    转载:https://www.cnblogs.com/wytings/p/4083463.html AndroidManifest.xml配置文件对于Android应用开发来说是比较细但又很重要的基础 ...

  9. Papa开启“点播孙子”模式,新型老年人服务能在国内扎根吗?

    "互联网+"对多个行业的全面赋能和渗入,的确让我们的生活与工作处处充满了便利.很多"跑断腿"才能办的事,现在只要在PC.智能手机上滑动鼠标.点击屏幕就能轻松搞定 ...

  10. SAP PM:参考维护工单创建测量凭证

    (1)使用FM:CO_BC_ORDER_POST获取工单资料(Aufnr, aufpo and materials etc): (2)使用FM:MEASUREM_DOCUM_RFC_SINGLE_00 ...