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中的变量到底是沿着作用域链还是原型链查找呢? 首先,要分清作用域链与原 ...
随机推荐
- MySQL--OPTIMIZE TABLE碎片整理
参考:http://blog.51yip.com/mysql/1222.html BLOB和TEXT值会引起一些性能问题,特别是在执行了大量的删除操作时.删除操作会在数据表中留下很大的空洞,以后填入这 ...
- Django专题-Cookie
Cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响, ...
- Bless All
# php code $i = 2333 $myJXOI = JXOI() while($i == 2333){ ++myJXOI.score , ++myJXOI.rp , --myJXOI.常数 ...
- servlet 3 通过编程的方式来配置ServletContext
你是否再为配置文件web.xml容易出错而烦恼?是否为web.xml文件存放位置而不知所措?是否为web.xml为什么要这样配?怎么才能更好的配置web.xml而烦恼?那么一种新的方式出现了: spr ...
- php获取客户IP
获取客户真实IP,保存到数据库建议转整 function getIp(){ $ip = ''; if(!empty($_SERVER['HTTP_CLIENT_IP'])){ $ip = $_SERV ...
- AddressUtils
package com.ruoyi.common.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com. ...
- 吴裕雄--天生自然 PYTHON3开发学习:字典
dict = {'} dict1 = { 'abc': 456 } dict2 = { 'abc': 123, 98.6: 37 } dict = {'Name': 'Runoob', 'Age': ...
- Python常见经典
python中if __name__ == '__main__': 的解析 当你打开一个.py文件时,经常会在代码的最下面看到if __name__ == '__main__':,现在就来介 绍一下它 ...
- mysql数据库5.6.45安装后的配置(离线安装包版)
二.windows10下的配置 (1) 环境变量配置 打开控制面板=>系统和安全=>系统=>高级系统设置,选择环境变量,在系统变量中找到path,编辑该选项. 第一行是oracle数 ...
- 蓝桥杯练习Day 2
问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式 输入包含一个整数n ...