// 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. MySQL--MySQL 日志

    在 MySQL中,有 4 种不同的日志,分别是错误日志.二进制日志(BINLOG 日志).查询日志和慢查询日志. 1.错误日志 错误日志是 MySQL 中最重要的日志之一,它记录了当 mysqld 启 ...

  2. js 经纬度计算直线距离

    function getRad(d) { var PI = Math.PI; return d * PI / 180.0; } function getDistance(lat1, lng1, lat ...

  3. goweb-处理静态资源

    处理静态文件 对于 HTML 页面中的 css 以及 js 等静态文件,需要使用使用 net/http 包下的以下 方法来处理 1) StripPrefix 函数 2) FileServer 函数 3 ...

  4. windows下使用vs code调试简单的C程序

    常使用visual studio code(vs code)打开.c文件,如果让vs code具备调试技能估计会比较有用 准备工作: 1. vs code安装插件:cpptools 2. window ...

  5. java package 包 学习笔记

    编译命令示例: javac -d . Main.java 注:带参数-d自动建立文件目录, 只使用javac 则需要手工创建目录 把 class文件打包 jar命令 jar cvf T.jar *; ...

  6. UML- 其他需求制品有哪些?

     1.其他需求 补充性规格说明(非功能性需求):性能/稳定性.文档.报表.许可授权等. 词汇表 设想:执行摘要. 业务规则(领域规则):如税法 2.准则 初始阶段无需对其他需求彻底分析.但花费一定时间 ...

  7. SaltStack事件驱动 – event reactor

    Event是SaltStack里面的对每个事件的一个记录,它相比job更加底层,Event能记录更加详细的SaltStack事件,比如Minion服务启动后请求Master签发证书或者证书校验的过程, ...

  8. 【转】Linux虚拟终端命令Screen用法详解

    转自 http://www.linuxidc.com/Linux/2013-07/87415.htm 在使用ssh或者telnet登录远程主机后,执行一些耗时的命令,如果此时ssh或者telnet中断 ...

  9. is,数据类型补充,set,深浅拷贝

    十二.基础数据类型补充: 1.join 可以把列表变成字符串. s = ‘abc’ s1 = s.join(‘非常可乐’) print(s1)  #非abc常abc可abc乐abc s = " ...

  10. sockaddr_in 转成string

    string strAcceptIp = inet_ntoa(remoteAddr.sin_addr);