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--MySQL 日志
在 MySQL中,有 4 种不同的日志,分别是错误日志.二进制日志(BINLOG 日志).查询日志和慢查询日志. 1.错误日志 错误日志是 MySQL 中最重要的日志之一,它记录了当 mysqld 启 ...
- js 经纬度计算直线距离
function getRad(d) { var PI = Math.PI; return d * PI / 180.0; } function getDistance(lat1, lng1, lat ...
- goweb-处理静态资源
处理静态文件 对于 HTML 页面中的 css 以及 js 等静态文件,需要使用使用 net/http 包下的以下 方法来处理 1) StripPrefix 函数 2) FileServer 函数 3 ...
- windows下使用vs code调试简单的C程序
常使用visual studio code(vs code)打开.c文件,如果让vs code具备调试技能估计会比较有用 准备工作: 1. vs code安装插件:cpptools 2. window ...
- java package 包 学习笔记
编译命令示例: javac -d . Main.java 注:带参数-d自动建立文件目录, 只使用javac 则需要手工创建目录 把 class文件打包 jar命令 jar cvf T.jar *; ...
- UML- 其他需求制品有哪些?
1.其他需求 补充性规格说明(非功能性需求):性能/稳定性.文档.报表.许可授权等. 词汇表 设想:执行摘要. 业务规则(领域规则):如税法 2.准则 初始阶段无需对其他需求彻底分析.但花费一定时间 ...
- SaltStack事件驱动 – event reactor
Event是SaltStack里面的对每个事件的一个记录,它相比job更加底层,Event能记录更加详细的SaltStack事件,比如Minion服务启动后请求Master签发证书或者证书校验的过程, ...
- 【转】Linux虚拟终端命令Screen用法详解
转自 http://www.linuxidc.com/Linux/2013-07/87415.htm 在使用ssh或者telnet登录远程主机后,执行一些耗时的命令,如果此时ssh或者telnet中断 ...
- is,数据类型补充,set,深浅拷贝
十二.基础数据类型补充: 1.join 可以把列表变成字符串. s = ‘abc’ s1 = s.join(‘非常可乐’) print(s1) #非abc常abc可abc乐abc s = " ...
- sockaddr_in 转成string
string strAcceptIp = inet_ntoa(remoteAddr.sin_addr);