BTCU(高校区块链联盟)-联盟链第6讲作业
// 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讲作业的更多相关文章
- 用Java为Hyperledger Fabric(超级账本)开发区块链智能合约链代码之部署与运行示例代码
部署并运行 Java 链代码示例 您已经定义并启动了本地区块链网络,而且已构建 Java shim 客户端 JAR 并安装到本地 Maven 存储库中,现在已准备好在之前下载的 Hyperledger ...
- 利用js查找页面中的内链,外链
起初没听说过内链外链,只有链接锚文本,在面试中被问到如何查找到页面中的内链和外链,就在想,什么是内链和外链啊??????? 后来面试官给我解释了一下他们的区别,自己稍微懂了,自己当时回答的是通过获取a ...
- 谈JS中的作用域链与原型链(1)
学习前端也有一段时间了,觉得自己可以与大家分享一些我当初遇到疑惑的东西,希望能给对此问题有疑惑的朋友带来一点帮助. 先来普及一下JS的概念(不要嫌我啰嗦,可能一些朋友开始学习JS是跟着视频和写好的代码 ...
- js 原型,原型链,原型链继承浅析
对于网上的关于原型,原型链和原型链继承的晦涩语言说明就不累赘了,复制粘贴过来再解释一遍怕自己也整蒙了,本人最怕空气突然安静,四目对视,大眼对小眼,一脸懵逼. 我们先看下面
- 责任链模式 职责链模式 Chain of Responsibility Pattern 行为型 设计模式(十七)
责任链模式(Chain of Responsibility Pattern) 职责链模式 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系 将这些对象连接成一条链,并沿着这 ...
- JS的作用域链与原型链
来一波,好记性不如烂笔头. 这两条链子可是很重要的. 作用域链 当执行一段JS代码(全局代码或函数)时,JS引擎会创建为其创建一个作用域又称为执行上下文(Execution Context),在页面加 ...
- js原型、原型链、作用链、闭包全解
https://www.2cto.com/kf/201711/698876.html [对象.变量] 一个对象就是一个类,可以理解为一个物体的标准化定义.它不是一个具体的实物,只是一个标准.而通过对象 ...
- 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释
P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...
- js通过沿着作用域链还是原型链查找变量
这是一道非常典型的JS闭包问题,结果和具体的解析请看这里. 对于其中的`函数作用域链的问题`博主似乎没有解释清楚,有一些疑问:js中的变量到底是沿着作用域链还是原型链查找呢? 首先,要分清作用域链与原 ...
随机推荐
- dht算法原理描述
dht原理 dht是P2P网络(结构化P2P)核心路由算法,主要是利用一致性hash,把节点和资源都表示成一个hash值,放入到这个大的hash环中,每个节点负责路由靠近它的资源. 一.重要概念: ...
- webapp项目vue框架点击按钮实现微信好友分享,朋友圈分享
当时做这个这个效果真把人给*了,网上能搜到的基本是微信页面的分享,特征是方法是wx.**开头,不适用于app内.思路都是一样的,先调取服务(这里使用plus的内置方法),再发送分享请求 <tem ...
- python图像处理常用方法
在线标注网站 https://gitlab.com/vgg/via http://www.robots.ox.ac.uk/~vgg/software/via/via.html 数组与图像互转 from ...
- 批量刷数据sql
update t_free_m** m set m.plate_no = ( select v.plate_num from t_wh_vehi*** v where v.vin = m.car_v ...
- JS - ES5与ES6面向对象编程
1.面向对象 1.1 两大编程思想 1.2 面向过程编程 POP(Process-oriented programming) 1.3 面向对象编程 OOP (Object Oriented Progr ...
- Kali 安装 Google 中文输入法
前言 安装了 Linux 并设置中文后,为了操作起来更便捷准备安装一个中文输入法 之前安装搜狗输入法,由于搜狗输入法基于 qt4,估计短期是 GG 了 所以这次选择了 Google 输入法 以下是安装 ...
- 学习LCA( 最近公共祖先·二)
http://poj.org/problem?id=1986 离线找u,v之间的最小距离(理解推荐) #include<iostream> #include<cstring> ...
- codeforce 1189C Candies! ----前缀和
题目大意:给你一个数组每个数不大于9,然后给你m个区间,每个区间的长度都是2的k次方(k=0 1 2.....) 有一种操作是把奇数位和偶数位相加 用和来代替之前的两个数,如果和大于等于10就要膜 ...
- MQ消息队列的12点核心原理总结
1. 消息生产者.消息者.队列 消息生产者Producer:发送消息到消息队列. 消息消费者Consumer:从消息队列接收消息. Broker:概念来自与Apache ActiveMQ,指MQ的服务 ...
- linux 添加常用长命令别名
## 设置linux下常用命令别名,提高效率 将要使用的命令别名写入到~/.bashrc文件,通过source ~/.bashrc命令使变更生效 alias sst='systemctl status ...