1. 程式人生 > 其它 >徵信區塊鏈解決方案探索(Hyperledger)

徵信區塊鏈解決方案探索(Hyperledger)

本文節選自電子書《Netkiller Blockchain 手札》

Netkiller Blockchain 手札

本文作者最近在找工作,有意向致電 13113668890

Mr. Neo Chan, 陳景峰(BG7NYT)

中國廣東省深圳市龍華新區民治街道溪山美地 518131 +86 13113668890 <[email protected]>

文件始創於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.7. 區塊鏈徵信解決方案探索

翻看了無數的文章沒有找到一篇關於談徵信在區塊鏈上怎麼落地的文章。也在各種區塊鏈微信群和QQ群中問了一圈,也沒有人知道怎麼落地。

現在的情況是大家都知道區塊鏈做徵信沒問題,區中心化,不可撰改,簡直是徵信系統而設計的。那麼怎麼使專案落地呢?沒有一篇文章談到這個問題。可能有些大公司已經實現了,處於技術保密,沒有分享。

看來只能靠自己了,以太坊和超級賬本一直在研究,最近一段時間研究以太坊比較多,但是發現徵信這個系統是在不適合在以太坊上實現,於是有回到超級賬本上。

回到超級賬本上感覺有點不適應,超級賬本沒有 Token , 超級賬本的合約實現與以太坊完全不同。兩個系統是兩種思維解決同一個區塊鏈需求。

一看 hyperledger 就是當前IBM風格,hyperledger 特點,體系龐大,結構複雜,難以理解,運維複雜。簡單的問題用複雜的方式思考,做出一個複雜的系統,可用性極差。IBM的產品特點是,你只能他們合作,一旦合作(上了船)就摔不掉,從他們小型機,到中介軟體產品,以及各種行業解決方案。IBM的系統出了問題,只有IBM的人才能解決。

隨者 hyperledger 開源,我希望 hyperledger 的風格能脫離IBM的影子。

回到正題,研究了幾個 hyperledger 提供的 Example 後,對怎麼實現徵信需求,有了一點思路。

首先 chaincode 合約並不複雜,由兩個核心方法組織,分別是Init和Invoke。其次資料操作類似 map 資料結構, shim.ChaincodeStubInterface 介面提供了 get, put, del 等操作。

33.7.1. 需求分析與概要設計

證信系統資訊查詢問題,一怎樣查詢?二查詢哪些資訊?

區塊不是關係型資料庫,無法實現SQL那樣的發雜查詢,所以設計介面要儘量迎合區塊鏈的,有些情況需要妥協,適應區塊鏈的弱點和不足。

但是我們可以讓資料庫和區塊鏈同時存在,相互彌補不足。

資料庫部分我這就就不講了,區塊鏈的實現方式是,使用身份證碼號查詢,返回 json 資料。

33.7.2. 資料結構

首先我們定義一個結構體用來儲存身份資訊,徵信資訊遠不止這幾項,請根據你的實際情況定義即可

package main

import "fmt"
import "encoding/json"

type Person struct {
	No string	`json:"no"`
	Name string	`json:"name"`
	Sex	bool	`json:"sex"`
	Age int		`json:"age"`
    Address string	`json:"address"`
}

func main(){
	
	person := &Person{"430725198001190911","景峰",true,30,"Shenzhen,China"}

	personJson, _ := json.Marshal(person)

	fmt.Println(string(personJson));

	person1 := &Person{
        No: "430725198001190911",
		Name: "Neo Chen",
		Sex: true,
		Age: 35,
		Address: "Shenzhen, China"}

    json2, _ := json.Marshal(person1)
    fmt.Println(string(json2))
}	

編譯,執行,測試定義json是否正確。

neo@MacBook-Pro ~/golang/contract % rm -rf person &&  go build person.go  && ./person
{"no":"430725198001190911","name":"景峰","sex":true,"age":30,"address":"Shenzhen,China"}
{"no":"430725198001190911","name":"Neo Chen","sex":true,"age":35,"address":"Shenzhen, China"}

最終我們只需要結構體複製到合約程式碼中。

type Person struct {
	No string	`json:"no"`
	Name string	`json:"name"`
	Sex	bool	`json:"sex"`
	Age int		`json:"age"`
    Address string	`json:"address"`
}		

33.7.3. 將徵信資料寫入區塊鏈

通過下面的函式,將徵信資料寫入到區塊鏈上。

func (s *SmartContract) createPerson(stub shim.ChaincodeStubInterface, args []string) sc.Response {
 
    if len(args) != 6 {
        return shim.Error("Incorrect number of arguments. Expecting 6")
    }
 
    var person = Person{No: args[1], Name: args[2], Sex: args[3], Age: args[4], Address: args[5]}
 
    personAsBytes, _ := json.Marshal(person)
    stub.PutState(args[0], personAsBytes)
 
    return shim.Success(nil)
}		

33.7.4. 查詢區塊資料

通過下面方法查詢鏈上的徵信資料。

func (s *SmartContract) queryPerson(stub shim.ChaincodeStubInterface, args []string) sc.Response {
 
    if len(args) != 1 {
        return shim.Error("Incorrect number of arguments. Expecting 1")
    }
    personAsBytes, _ := stub.GetState(args[0])
    return shim.Success(personAsBytes)
}		

33.7.5. 刪除區塊

通過下面方法刪除徵信資料。

func (s *SmartContract) deletePerson(stub shim.ChaincodeStubInterface, args []string) sc.Response {
 
    if len(args) != 1 {
        return shim.Error("Incorrect number of arguments. Expecting 1")
    }
    personAsBytes, _ := stub.GetState(args[0])
    
    err= stub.DelState(args[0])
	if err != nil {
		return shim.Error("Failed to delete Student from DB, key is: "+args[0])
	}
    
    return shim.Success(personAsBytes)
}	

這裡僅僅講了一下思路,因為家中重新整理(刷牆)所以我的小伺服器被覆蓋起來了,沒有 hyperledger 開發環境,所以無法提供完整的合約程式碼。