区块链银行应用探索(Hyperledger fabric)

简介:

本文节选自电子书《Netkiller Blockchain 手札》

Netkiller Blockchain 手札

本文作者提供有偿顾问服务,有意向致电 13113668890

Mr. Neo Chan, 陈景峯(BG7NYT)

中国广东省深圳市龙华新区民治街道溪山美地 518131 +86 13113668890  <netkiller@msn.com>

文档始创于2018-02-10

版权 © 2018 Netkiller(Neo Chan). All rights reserved.

版权声明

转载请与作者联系,转载时请务必标明文章原始出处和作者信息及本声明。

微信订阅号 netkiller-ebook (微信扫描二维码)

QQ:13721218 请注明“读者”

QQ群:128659835 请注明“读者”

网站:http://www.netkiller.cn

内容摘要

这一部关于区块链开发及运维的电子书。

为什么会写区块链电子书?因为2018年是区块链年。

这本电子书是否会出版(纸质图书)? 不会,因为互联网技术更迭太快,纸质书籍的内容无法实时更新,一本书动辄百元,很快就成为垃圾,你会发现目前市面的上区块链书籍至少是一年前写的,内容已经过时,很多例子无法正确运行。所以我不会出版,电子书的内容会追逐技术发展,及时跟进软件版本的升级,做到内容最新,至少是主流。

这本电子书与其他区块链书籍有什么不同?市面上大部分区块链书籍都是用2/3去讲区块链原理,只要不到 1/3 的干货,干货不够理论来凑,通篇将理论或是大谈特谈区块链行业,这些内容更多是头脑风暴,展望区块链,均无法落地实施。本书与那些书籍完全不同,不讲理论和原理,面向应用落地,注重例子,均是干货。

电子书更新频率?每天都会有新内容加入,更新频率最迟不会超过一周,更新内容请关注 https://github.com/netkiller/netkiller.github.io/commits/master

本文采用碎片化写作,原文会不定期更新,请尽量阅读原文。

http://www.netkiller.cn/blockchain/index.html

您的打赏是我的写作动力:http://www.netkiller.cn/blockchain/donations.html

==============================

33.8. Hyperledger fabric 银行应用探索

一直想写这篇文章,可是我个人对银行系统了解甚少,网上很多文章有多拿银行来举例,铺天盖地的文章,却没有一篇告诉你究竟如何落地。

其中不少文章中提到银行SWIFT系统,什么事 SWIFT 呢?

33.8.1. 电汇年代

这要从电汇说起,年轻时候上学,每个学期都有一笔学费,那时主要交通是铁路,携带现金非常不便,母亲将5000元人民币缝在我的贴身内裤边上。到了学校拆开线取出,味道好极了,呵呵。

后来从同学那里得知,可以使用邮局汇款,首先去邮局,拿一个特殊信封填好地址,然后将钱交给工作人员。一周以后信封皮会记挂号信到收款人手里,那个这个信封去指定邮局取款。

记得第二学期就出现电汇,银行提供的电汇服务比邮政的速度快,也比邮局更方便。

  用户A ----- 汇票 -----> 用户B
   |                     | 
  申请                   提款
   |                     |
   V                     V
  银行A ----- 划账 -----> 银行B		

电汇是用户A银行提出申请,将钱交给A银行。银行马上通过网络通知B银行,用户B就可以提款。没有多久邮政的系统也换成这套系统了。

那个年代只有拨号网络,帧中继,ATM(是一种网络,不是ATM取款机) 等窄带网络,现在用宽带上网的90后无法想法那个网速。

33.8.2. 通存通取年代

ISDN,DDN 专线的出现,才有了稳定窄带通信,银行网点互联成为可能。

MasterCard万事达,Visa维萨卡率先进入中国。很快银行内部就能实现转账了,ATM机互联成为可能,这时结算全部使用 MasterCard万事达,Visa维萨卡。银行需向MasterCard万事达,Visa维萨机构支付费用。促使一些有实力银行研发自己的内部系统,但是这些系统仅限内部使用,如果银行卡上没有MasterCard/Visa 的只能本银行使用,无法跨行。没有实力的银行则会选择门槛稍低的 INTERLINK、PLUS 等机构合作。

98年在学校寝室,一位同学拿了一张牡丹万事达卡,全寝室传看,那个年代在哈尔滨提款机都不普及,只有较大的银行网点才有。

2000来深圳,那时有个深银联,深圳首先实现了跨行业务,2年后(2002年)银联出现,国家强推,所有银行开始支持银联。当时银行卡上同时有两个标示,MasterCard/Visa 和 银联。

同年招商银行率先推出网上银行。招商银行电脑部一度成为IT红黑榜上评价最高的公司,可惜没有跟上互联网的步伐......

目前新开的银行卡已经看不到 MasterCard/Visa 标志了,甚至香港的银行卡也默认使用银联,出国旅游耍刷 UnionPay 跨境支付非常方便。

33.8.3. 跨境汇款

跨境汇款你别想像银联一样,填写一个姓名一个账号,点击一下转账按钮这样的操作。每个国家的政策也不同,政策不允许这样操作。

跨境只能汇款,无法转账,又回到了电汇时代,只是不再主要纸质的汇票了

  用户A ----- SWIFT CODE -----> 用户B
   |                             | 
  申请                           提款
   |                             |
   V                             V
  银行A -------- SWIFT --------> 银行B		

跨境汇款必须依赖 SWIFT 系统,由于我国的政策问题,个人很少涉及跨境业务,所以多数人对 SWIFT 不是很了解。 如果你在香港开一张银行卡例如汇丰银行,拿到银行给的信封里,就会有一个 SWIFT 码。

你会遇到这个问题,无法输入对方的名字,例如:

Nickname:netkiller
English name: Neo chen 
Nippon name: ちんけいほう (音訳) 
Korean name: 천징봉
Thailand name: ภูมิภาพภูเขา
Vietnam: Trần Cảnh Phong

所以就需要每个银行一个代码,每个账号一个代码,由于全世界银行太多,银行系统各种各样,每个国家的语言也不同,难以达成一致,联合国也没有能力统一标准。新建一套系统不太可能,所以80年代的标准仍然沿用至今。

使用 SWIFT 面临的问题

  • 网络速度慢
  • 手续费高
  • 技术落后
  • 不能实时到账
  • 脆弱容易被攻击

SWIFT的诞生甚至早于数字时代,可以说是目前最好的跨境通讯和交易系统,但它的确需要与时俱进。

牵头做一个世界银联不太可能,世界各国银行无法想政府一样,一个红头文件,下面招办,行政手段推动。且业务差异大,系统复杂超乎想象,这个中心数据库谁来管理呢?

SWIFT早就意识到了这些问题,并宣布进军区块链,同时加入超级账本项目(Hyperledger Project)成为会员。可以肯定下一个版本的SWIFT灰使用区块链技术,一步一步逐渐取代就系统。

33.8.4. 区块链能做什么

区块链可以解决银行哪些痛点,先说说 SWIFT 2.0 (区块链SWIFT)我想SWIFT仍然会兼容现有的协议。SWIFT CODE协议仍然会保留。短时间不可能被取代SWIFT CODE因为这个体系已经使用很多年。

  用户A ----- SWIFT CODE -----> 用户B
   |                             | 
  申请                           提款
   |                             |
   V                             V
  银行A -------- 划账  --------> 银行B		
    \                            /
     \                          /
      V                        V
  +---------------------------------+
  | Hyperledger Fabric 盟链          |
  +---------------------------------+
  | Smart Contract                  |
  +---------------------------------+

后端将会被区块链取代

另外银行的跨国业务将会走自己的区块链,不再依赖 SWIFT, 因为费用等问题。

  用户A --------- 转账 ---------> 用户B
   |                             | 
  申请                           提款
   |                             |
   V                             V
英国渣打银行 ----- 划账  -----> 深圳渣打银行		
    \                            /
     \                          /
      V                        V
  +---------------------------------+
  | Hyperledger Fabric 盟链          |
  +---------------------------------+
  | Smart Contract                  |
  +---------------------------------+

33.8.5. 智能合约怎么落地

我对银行业务实在不了解,这里只能设想一下场景。下面是我之前写的一个Token合约,我将它应用到这个场景中

package main 


import (
	"encoding/json"
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
)

type Msg struct{
	Status 	bool	`json:"Status"`
	Code 	int		`json:"Code"`
	Message string	`json:"Message"`
}

type Currency struct{
	TokenName 		string	`json:"TokenName"`
	TokenSymbol 	string	`json:"TokenSymbol"`
	TotalSupply 	float64	`json:"TotalSupply"`
}

type Token struct {
	Lock		bool	`json:"Lock"`
	Currency	map[string]Currency	`json:"Currency"`
}

func (token *Token) transfer (_from *Account, _to *Account, _currency string, _value float64) []byte{

	var rev []byte
	if (token.Lock){
		msg := &Msg{Status: false, Code: 0, Message: "锁仓状态,停止一切转账活动"}
		rev, _ = json.Marshal(msg)
		return rev
	}
	if(_from.Frozen ) {
		msg := &Msg{Status: false, Code: 0, Message: "From 账号冻结"}
		rev, _ = json.Marshal(msg)
		return rev
	}
	if( _to.Frozen) {
		msg := &Msg{Status: false, Code: 0, Message: "To 账号冻结"}
		rev, _ = json.Marshal(msg)
		return rev
	}
	if(!token.isCurrency(_currency)){
		msg := &Msg{Status: false, Code: 0, Message: "货币符号不存在"}
		rev, _ = json.Marshal(msg)
		return rev
	}
	if(_from.BalanceOf[_currency] >= _value){
		_from.BalanceOf[_currency] -= _value;
		_to.BalanceOf[_currency] += _value;

		msg := &Msg{Status: true, Code: 0, Message: "转账成功"}
		rev, _ = json.Marshal(msg)
		return rev
	}else{
		msg := &Msg{Status: false, Code: 0, Message: "余额不足"}
		rev, _ = json.Marshal(msg)
		return rev
	}
	
}
func (token *Token) initialSupply(_name string, _symbol string, _supply float64, _account *Account) []byte{
	if _,ok := token.Currency[_symbol]; ok {
		msg := &Msg{Status: false, Code: 0, Message: "已经存在"}
		rev, _ := json.Marshal(msg)
		return rev
	}

	if _account.BalanceOf[_symbol] > 0 {
		msg := &Msg{Status: false, Code: 0, Message: "账号中存在代币"}
		rev, _ := json.Marshal(msg)
		return rev
	}else{
		token.Currency[_symbol] = Currency{TokenName: _name, TokenSymbol: _symbol, TotalSupply: _supply}
		_account.BalanceOf[_symbol] = _supply

		msg := &Msg{Status: true, Code: 0, Message: "货币初始化成功"}
		rev, _ := json.Marshal(msg)
		return rev
	}

}

func (token *Token) mint(_currency string, _amount float64, _account *Account) []byte{
	if(!token.isCurrency(_currency)){
		msg := &Msg{Status: false, Code: 0, Message: "货币符号不存在"}
		rev, _ := json.Marshal(msg)
		return rev
	}
	cur := token.Currency[_currency]
	cur.TotalSupply += _amount;
	token.Currency[_currency] = cur
	_account.BalanceOf[_currency] += _amount;

	msg := &Msg{Status: true, Code: 0, Message: "货币增发成功"}
	rev, _ := json.Marshal(msg)
	return rev
	
}
func (token *Token) burn(_currency string, _amount float64, _account *Account) []byte{
	if(!token.isCurrency(_currency)){
		msg := &Msg{Status: false, Code: 0, Message: "货币符号不存在"}
		rev, _ := json.Marshal(msg)
		return rev
	}
	if(token.Currency[_currency].TotalSupply >= _amount){
		cur := token.Currency[_currency]
		cur.TotalSupply -= _amount;
		token.Currency[_currency] = cur
		_account.BalanceOf[_currency] -= _amount;

		msg := &Msg{Status: false, Code: 0, Message: "货币回收成功"}
		rev, _ := json.Marshal(msg)
		return rev
	}else{
		msg := &Msg{Status: false, Code: 0, Message: "回收失败,回收额度不足"}
		rev, _ := json.Marshal(msg)
		return rev
	}
	
}
func (token *Token) isCurrency(_currency string) bool {
	if _, ok := token.Currency[_currency]; ok {
		return true
	}else{
		return false
	}
}
func (token *Token) setLock(_look bool) bool {
	token.Lock = _look
	return token.Lock
}
type Account struct {
	Name			string	`json:"Name"`
	Frozen			bool	`json:"Frozen"`
	BalanceOf		map[string]float64	`json:"BalanceOf"`
}
func (account *Account) balance (_currency string) map[string]float64{
	bal	:= map[string]float64{_currency:account.BalanceOf[_currency]}
	return bal
}

func (account *Account) balanceAll() map[string]float64{
	return account.BalanceOf
}

// -----------
const TokenKey = "Token"

// Define the Smart Contract structure
type SmartContract struct {
	
}

func (s *SmartContract) Init(stub shim.ChaincodeStubInterface) pb.Response {

	token := &Token{Currency: map[string]Currency{}}

	tokenAsBytes, err := json.Marshal(token)
	err = stub.PutState(TokenKey, tokenAsBytes)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("Init Token %s \n", string(tokenAsBytes))
	}
	return shim.Success(nil)
}

func (s *SmartContract) Query(stub shim.ChaincodeStubInterface) pb.Response {
	function, args := stub.GetFunctionAndParameters()
	if function == "balance" {
		return s.balance(stub, args)
	} else if function == "balanceAll" {
		return s.balanceAll(stub, args)
	} else if function == "showAccount" {
		return s.showAccount(stub, args)
	}
	return shim.Error("Invalid Smart Contract function name.")
}

func (s *SmartContract) Invoke(stub shim.ChaincodeStubInterface) pb.Response {

	// Retrieve the requested Smart Contract function and arguments
	function, args := stub.GetFunctionAndParameters()
	// Route to the appropriate handler function to interact with the ledger appropriately
	if function == "initLedger" {
		return s.initLedger(stub, args)
	} else if function == "createAccount" {
		return s.createAccount(stub, args)
	} else if function == "initCurrency" {
		return s.initCurrency(stub, args)
	} else if function == "setLock" {
		return s.setLock(stub, args)
	} else if function == "transferToken" {
		return s.transferToken(stub, args)
	} else if function == "frozenAccount" {
		return s.frozenAccount(stub, args)
	} else if function == "mintToken" {
		return s.mintToken(stub, args)
	} else if function == "balance" {
		return s.balance(stub, args)
	} else if function == "balanceAll" {
		return s.balanceAll(stub, args)
	} else if function == "showAccount" {
		return s.showAccount(stub, args)
	} else if function == "showToken" {
		return s.showToken(stub, args)
	}

	return shim.Error("Invalid Smart Contract function name.")
}

func (s *SmartContract) createAccount(stub shim.ChaincodeStubInterface, args []string) pb.Response {

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	key  := args[0]
	name  := args[0]
	existAsBytes,err := stub.GetState(key)
	fmt.Printf("GetState(%s) %s \n", key, string(existAsBytes))
	if string(existAsBytes) != "" {
		fmt.Println("Failed to create account, Duplicate key.")
		return shim.Error("Failed to create account, Duplicate key.")
	}

	account := Account{
		Name: name,
		Frozen: false,
		BalanceOf: map[string]float64{}}

	accountAsBytes, _ := json.Marshal(account)
	err = stub.PutState(key, accountAsBytes)
	if err != nil {
		return shim.Error(err.Error())
	}
	fmt.Printf("createAccount %s \n", string(accountAsBytes))

	return shim.Success(accountAsBytes)
}
func (s *SmartContract) initLedger(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	return shim.Success(nil)
}
func (s *SmartContract) showToken(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	tokenAsBytes,err := stub.GetState(TokenKey)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("GetState(%s)) %s \n", TokenKey, string(tokenAsBytes))
	}
	return shim.Success(tokenAsBytes)
}

func (s *SmartContract) initCurrency(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 4 {
		return shim.Error("Incorrect number of arguments. Expecting 4")
	}

	_name  := args[0]
	_symbol:= args[1]
	_supply,_:= strconv.ParseFloat(args[2], 64)
	_account := args[3]

	coinbaseAsBytes,err := stub.GetState(_account)
	if err != nil {
		return shim.Error(err.Error())
	}
	fmt.Printf("Coinbase before %s \n", string(coinbaseAsBytes))

	coinbase := &Account{}

	json.Unmarshal(coinbaseAsBytes, &coinbase)

	token := Token{}
	existAsBytes,err := stub.GetState(TokenKey)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("GetState(%s)) %s \n", TokenKey, string(existAsBytes))
	}
	json.Unmarshal(existAsBytes, &token)
	
	result := token.initialSupply(_name,_symbol,_supply, coinbase)

	tokenAsBytes, _ := json.Marshal(token)
	err = stub.PutState(TokenKey, tokenAsBytes)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("Init Token %s \n", string(tokenAsBytes))
	}

	coinbaseAsBytes, _ = json.Marshal(coinbase)
	err = stub.PutState(_account, coinbaseAsBytes)
	if err != nil {
		return shim.Error(err.Error())
	}
	fmt.Printf("Coinbase after %s \n", string(coinbaseAsBytes))

	

	return shim.Success(result)
}

func (s *SmartContract) transferToken(stub shim.ChaincodeStubInterface, args []string) pb.Response {

	if len(args) != 4 {
		return shim.Error("Incorrect number of arguments. Expecting 4")
	}
	_from 		:= args[0]
	_to			:= args[1]
	_currency 	:= args[2]
	_amount,_	:= strconv.ParseFloat(args[3], 32)
	
	if(_amount <= 0){
		return shim.Error("Incorrect number of amount")
	}

	fromAsBytes,err := stub.GetState(_from)
	if err != nil {
		return shim.Error(err.Error())
	}
	fmt.Printf("fromAccount %s \n", string(fromAsBytes))
	fromAccount := &Account{}
	json.Unmarshal(fromAsBytes, &fromAccount)

	toAsBytes,err := stub.GetState(_to)
	if err != nil {
		return shim.Error(err.Error())
	}
	fmt.Printf("toAccount %s \n", string(toAsBytes))
	toAccount := &Account{}
	json.Unmarshal(toAsBytes, &toAccount)

	tokenAsBytes,err := stub.GetState(TokenKey)
	if err != nil {
		return shim.Error(err.Error())
	}
	fmt.Printf("Token %s \n", string(toAsBytes))
	token := Token{Currency: map[string]Currency{}}
	json.Unmarshal(tokenAsBytes, &token)

	result := token.transfer(fromAccount, toAccount, _currency, _amount)
	fmt.Printf("Result %s \n", string(result))

	fromAsBytes, err = json.Marshal(fromAccount)
	if err != nil {
		return shim.Error(err.Error())
	}
	err = stub.PutState(_from, fromAsBytes)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("fromAccount %s \n", string(fromAsBytes))
	}

	toAsBytes, err = json.Marshal(toAccount)
	if err != nil {
		return shim.Error(err.Error())
	}
	err = stub.PutState(_to, toAsBytes)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("toAccount %s \n", string(toAsBytes))
	}

	return shim.Success(result)
}
func (s *SmartContract) mintToken(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	
	if len(args) != 3 {
		return shim.Error("Incorrect number of arguments. Expecting 3")
	}
	_currency 	:= args[0]
	_amount,_	:= strconv.ParseFloat(args[1], 32)
	_account	:= args[2]

	coinbaseAsBytes,err := stub.GetState(_account)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("Coinbase before %s \n", string(coinbaseAsBytes))
	}

	coinbase := &Account{}
	json.Unmarshal(coinbaseAsBytes, &coinbase)

	tokenAsBytes,err := stub.GetState(TokenKey)
	if err != nil {
		return shim.Error(err.Error())
	}
	fmt.Printf("Token before %s \n", string(tokenAsBytes))

	token := Token{}

	json.Unmarshal(tokenAsBytes, &token)
	
	result := token.mint(_currency, _amount, coinbase)

	tokenAsBytes, err = json.Marshal(token)
	if err != nil {
		return shim.Error(err.Error())
	}
	err = stub.PutState(TokenKey, tokenAsBytes)
	if err != nil {
		return shim.Error(err.Error())
	}
	fmt.Printf("Token after %s \n", string(tokenAsBytes))

	coinbaseAsBytes, _ = json.Marshal(coinbase)
	err = stub.PutState(_account, coinbaseAsBytes)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("Coinbase after %s \n", string(coinbaseAsBytes))
	}

	fmt.Printf("mintToken %s \n", string(tokenAsBytes))

	return shim.Success(result)
}

func (s *SmartContract) setLock(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	
	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 2")
	}

	_look := args[0]

	tokenAsBytes,err := stub.GetState(TokenKey)
	if err != nil {
		return shim.Error(err.Error())
	}
	// fmt.Printf("setLock - begin %s \n", string(tokenAsBytes))

	token := Token{}

	json.Unmarshal(tokenAsBytes, &token)

	if(_look == "true"){
		token.setLock(true)
	}else{
		token.setLock(false)
	}

	tokenAsBytes, err = json.Marshal(token)
	if err != nil {
		return shim.Error(err.Error())
	}
	err = stub.PutState(TokenKey, tokenAsBytes)
	if err != nil {
		return shim.Error(err.Error())
	}
	fmt.Printf("setLock - end %s \n", string(tokenAsBytes))

	return shim.Success(nil)
}
func (s *SmartContract) frozenAccount(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	
	if len(args) != 2 {
		return shim.Error("Incorrect number of arguments. Expecting 2")
	}

	_account	:= args[0]
	_status		:= args[1]

	accountAsBytes,err := stub.GetState(_account)
	if err != nil {
		return shim.Error(err.Error())
	}
	// fmt.Printf("setLock - begin %s \n", string(tokenAsBytes))

	account := Account{}

	json.Unmarshal(accountAsBytes, &account)

	var status bool
	if(_status == "true"){
		status = true;
	}else{
		status = false
	}

	account.Frozen = status
	
	accountAsBytes, err = json.Marshal(account)
	if err != nil {
		return shim.Error(err.Error())
	}
	err = stub.PutState(_account, accountAsBytes)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("frozenAccount - end %s \n", string(accountAsBytes))
	}

	return shim.Success(nil)
}

func (s *SmartContract) showAccount(stub shim.ChaincodeStubInterface, args []string) pb.Response {

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}
	_account 	:= args[0]

	accountAsBytes,err := stub.GetState(_account)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("Account balance %s \n", string(accountAsBytes))
	}
	return shim.Success(accountAsBytes)
}

func (s *SmartContract) balance(stub shim.ChaincodeStubInterface, args []string) pb.Response {

	if len(args) != 2 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}
	_account 	:= args[0]
	_currency 	:= args[1]

	accountAsBytes,err := stub.GetState(_account)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("Account balance %s \n", string(accountAsBytes))
	}

	account := Account{}
	json.Unmarshal(accountAsBytes, &account)
	result := account.balance(_currency)

	resultAsBytes, _ := json.Marshal(result)
	fmt.Printf("%s balance is %s \n", _account, string(resultAsBytes))	

	return shim.Success(resultAsBytes)
}

func (s *SmartContract) balanceAll(stub shim.ChaincodeStubInterface, args []string) pb.Response {

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}
	_account 	:= args[0]

	accountAsBytes,err := stub.GetState(_account)
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("Account balance %s \n", string(accountAsBytes))
	}

	account := Account{}
	json.Unmarshal(accountAsBytes, &account)
	result := account.balanceAll()
	resultAsBytes, _ := json.Marshal(result)
	fmt.Printf("%s balance is %s \n", _account, string(resultAsBytes))	

	return shim.Success(resultAsBytes)
}

// The main function is only relevant in unit test mode. Only included here for completeness.
func main() {

	// Create a new Smart Contract
	err := shim.Start(new(SmartContract))
	if err != nil {
		fmt.Printf("Error creating new Smart Contract: %s", err)
	}
}

部署链码,然后实例化链码

peer chaincode install -n token3 -v 1.0 -p chaincodedev/chaincode/token
peer chaincode instantiate -C myc -n token3 -v 1.0 -c '{"Args":[""]}' -P "OR ('Org1MSP.member','Org2MSP.member')"		

首先初始化账号,需要将现有账号同步到区块链上,这是上链操作。账号分为两种,一个是 coinbase 银行的总账号,另外是用户账号

peer chaincode invoke -C myc -n token3 -c '{"function":"createAccount","Args":["coinbase"]}'		

初始化外币,银行有多少外币存量,初始化到 coinbase 账号

peer chaincode invoke -C myc -n token3 -c '{"function":"initCurrency","Args":["Chain","RMB","1000000000","coinbase"]}'
peer chaincode invoke -C myc -n token3 -c '{"function":"initCurrency","Args":["Japan","JPY","1000000000","coinbase"]}'
peer chaincode invoke -C myc -n token3 -c '{"function":"initCurrency","Args":["USA","USD","1000000000","coinbase"]}'		

为用户创建账号

peer chaincode invoke -C myc -n token3 -c '{"function":"createAccount","Args":["netkiller"]}'
peer chaincode invoke -C myc -n token3 -c '{"function":"createAccount","Args":["neo"]}'	

同步用户账号中的外币

peer chaincode invoke -C myc -n token3 -c '{"function":"transferToken","Args":["coinbase","netkiller","RMB","10000"]}'
peer chaincode invoke -C myc -n token3 -c '{"function":"transferToken","Args":["coinbase","netkiller","USD","100"]}'


peer chaincode invoke -C myc -n token3 -c '{"function":"transferToken","Args":["coinbase","neo","RMB","10000"]}'
peer chaincode invoke -C myc -n token3 -c '{"function":"transferToken","Args":["coinbase","neo","USD","100"]}'	

现在区块链上的用户资金已经跟数据库中的资金同步。

现在netkiller这个用户需要给neo转账 50 美金

peer chaincode invoke -C myc -n token3 -c '{"function":"transferToken","Args":["netkiller","neo","USD","50"]}'	

现在 netkiller 账号中又 50美金,neo 账号中有 150美金。

peer chaincode invoke -C myc -n token3 -c '{"function":"balanceAll","Args":["netkiller"]}'
peer chaincode invoke -C myc -n token3 -c '{"function":"balanceAll","Args":["neo"]}'

如果 neo 账号被法院申请冻结了,怎么办?可以使用下面方法设置冻结账号

peer chaincode invoke -C myc -n token3 -c '{"function":"frozenAccount","Args":["neo","true"]}'

此时 neo 账号被冻结,资金无法转入,转出。

33.8.6. 总结

以上仅仅是提供一个区块链学历案例,作者也设想了一个场景。但是真是情况怎样作者也不清楚。

上面通正合约没有考虑到汇率和中间价问题,需要进一步完善。

另外还需要一个守护进程订阅 Event 状态,每做一笔转账交易,event 会受到然后将这个操作同步到中心化数据库。

         用户A ------------- 转账 ------------> 用户B
           |                                    | 
          申请                                 提款
           |                                    |
           V                                    V
       英国渣打银行 --------- 划账  ---------> 深圳渣打银行		
       /        \                            /      \
      /          \                          /        \
     V            V                        V          V
+----------+  +---------------------------------+  +----------+ 
|          |  | Hyperledger Fabric 盟链          |  |          |
| Database |  +---------------------------------+  | Database |
|          |  | Smart Contract                  |  |          |
+----------+  +---------------------------------+  +----------+ 
     ^                 o               o                 ^
     |                 |               |                 |
     +----- Event -----+               +----- Event -----+




原文发布时间为:2018-03-12
本文作者:netkiller
本文来源:腾讯云 云+社区,如需转载请联系原作者。

目录
相关文章
|
7天前
|
供应链 安全 分布式数据库
探索区块链技术在供应链管理中的应用
【10月更文挑战第21天】 本文深入探讨了区块链技术如何在供应链管理中发挥关键作用,通过具体案例分析,揭示了区块链提高透明度、降低成本和增强安全性的潜力。文章首先概述了区块链技术的基本原理及其对传统供应链模式的挑战,接着详细讨论了区块链如何在不同供应链环节中实施,并分析了其带来的变革。最后,文章提出了企业在采纳区块链技术时可能面临的挑战和应对策略,为供应链管理者提供了宝贵的参考。
|
29天前
|
传感器 物联网 区块链
新技术趋势与应用:探讨新兴技术如区块链、物联网、虚拟现实等的发展趋势和应用场景
在当今科技飞速发展的时代,新兴技术的涌现正在改变我们的生活和工作方式。本文将深入探讨区块链技术、物联网以及虚拟现实等新兴技术的发展趋势和应用场景。我们将从这些技术的本质出发,分析它们的发展现状,并展望未来可能带来的变革。同时,我们也将通过一些简单的代码示例,展示这些技术如何在实际中发挥作用。让我们一起探索这个充满无限可能的科技世界吧!
|
17天前
|
存储 安全 物联网
未来已来:区块链技术在物联网与虚拟现实中的应用
随着科技的不断进步,新兴技术如区块链、物联网(IoT)和虚拟现实(VR)正在逐渐改变我们的生活和工作方式。本文将探讨这些技术的发展趋势和应用场景,以及它们如何相互融合,为我们带来更便捷、安全和沉浸式的体验。
|
18天前
|
存储 供应链 算法
深入探索区块链技术:原理、应用与未来展望
本文将带你深入了解区块链技术的基本原理,探讨其在金融、供应链、医疗等多个领域的应用案例,并展望其未来的发展趋势。通过本文,你将对区块链技术有一个全面的认识,理解其背后的技术逻辑和应用场景。
|
24天前
|
供应链 安全 区块链
探索区块链技术在数据安全中的应用
本文深入探讨了区块链技术如何革新数据安全领域,特别是在保护个人隐私、增强数据完整性和透明度方面的作用。通过分析区块链的去中心化特性、加密技术以及智能合约的功能,文章阐述了这一技术如何有效防止数据篡改、确保交易记录的不可逆性,并促进跨组织间的信任建立。此外,还讨论了当前区块链技术面临的挑战及未来发展趋势,为理解其在数据安全领域的潜力提供了全面视角。
|
20天前
|
供应链 物联网 区块链
新技术趋势与应用:探讨新兴技术如区块链、物联网、虚拟现实等的发展趋势和应用场景
本文将探讨新兴技术的发展趋势和应用场景,包括区块链技术、物联网和虚拟现实等。我们将深入了解这些技术的发展现状,以及它们在未来可能带来的变革。同时,我们还将提供一些代码示例,以帮助读者更好地理解这些技术的应用。
|
20天前
|
存储 供应链 监控
深入探索区块链技术在供应链管理中的应用####
本文旨在探讨区块链技术如何革新供应链管理,通过分析其核心特性与实际案例,揭示该技术如何增强透明度、提升效率并降低成本。我们将从区块链的基本原理入手,逐步剖析其在供应链各环节中的具体应用,最终展望其未来发展趋势。 ####
52 3
|
23天前
|
存储 供应链 分布式数据库
深入理解区块链技术:原理、应用与挑战
本文旨在探讨区块链技术的基本原理、主要应用及其面临的挑战。通过分析区块链的分布式账本技术、加密算法和共识机制,我们揭示了其如何在无需中心化权威的情况下确保数据的不可篡改性和透明性。此外,文章还讨论了区块链在金融、供应链管理、智能合约等领域的应用案例,并指出了当前区块链技术面临的可扩展性、隐私保护和法律监管等挑战。通过对这些内容的深入分析,我们希望为读者提供一个全面而深入的区块链技术概览。
49 6
|
25天前
|
供应链 安全 数据挖掘
深度剖析区块链技术在金融科技领域的创新应用与挑战####
本文旨在探讨区块链技术于金融科技(FinTech)领域的革新性应用,分析其如何重塑传统金融服务模式,并深入剖析面临的技术与监管挑战。通过案例研究与数据分析,揭示区块链在提升金融效率、增强安全性及促进金融包容性方面的潜力,同时强调构建健全的法律法规框架与技术创新之间的平衡对于推动行业健康发展的重要性。本文不涉及具体代码实现或技术细节,而是聚焦于区块链应用的战略意义与实践挑战。 ####
|
29天前
|
存储 供应链 安全
探索区块链技术在供应链管理中的应用
本文深入探讨了区块链技术在供应链管理中的应用,分析了其如何提高透明度、安全性和效率。通过具体案例研究,展示了区块链如何解决传统供应链中的信任问题,降低成本,并促进更高效的物流管理。文章还讨论了实施区块链技术面临的挑战和未来发展趋势。