知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
翻看了無數的文章沒有找到一篇關於談徵信在區塊鏈上怎麼落地的文章。也在各種區塊鏈微信群和QQ群中問了一圈,也沒有人知道怎麼落地。
現在的情況是大家都知道區塊鏈做徵信沒問題,區中心化,不可撰改,簡直是徵信系統而設計的。那麼怎麼使項目落地呢?沒有一篇文章談到這個問題。可能有些大公司已經實現了,處于技術保密,沒有分享。
看來只能靠自己了,以太坊和超級賬本一直在研究,最近一段時間研究以太坊比較多,但是發現徵信這個系統是在不適合在以太坊上實現,於是有回到超級賬本上。
回到超級賬本上感覺有點不適應,超級賬本沒有 Token , 超級賬本的合約實現與以太坊完全不同。兩個系統是兩種思維解決同一個區塊鏈需求。
一看 hyperledger 就是當前IBM風格,hyperledger 特點,體系龐大,結構複雜,難以理解,運維複雜。簡單的問題用複雜的方式思考,做出一個複雜的系統,可用性極差。IBM的產品特點是,你只能他們合作,一旦合作(上了船)就摔不掉,從他們小型機,到中間件產品,以及各種行業解決方案。IBM的系統出了問題,只有IBM的人才能解決。
隨者 hyperledger 開源,我希望 hyperledger 的風格能脫離IBM的影子。
回到正題,研究了幾個 hyperledger 提供的 Example 後,對怎麼實現徵信需求,有了一點思路。
首先 chaincode 合約並不複雜,由兩個核心方法組織,分別是Init和Invoke。其次數據操作類似 map 資料結構, shim.ChaincodeStubInterface 介面提供了 get, put, del 等操作。
證信系統信息查詢問題,一怎樣查詢?二查詢哪些信息?
區塊不是關係型資料庫,無法實現SQL那樣的發雜查詢,所以設計介面要儘量迎合區塊鏈的,有些情況需要妥協,適應區塊鏈的弱點和不足。
但是我們可以讓資料庫和區塊鏈同時存在,相互彌補不足。
資料庫部分我這就就不講了,區塊鏈的實現方式是,使用身份證碼號查詢,返回 json 數據。
首先我們定義一個結構體用來存儲身份信息,徵信信息遠不止這幾項,請根據你的實際情況定義即可
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"` }
通過下面的函數,將徵信數據寫入到區塊鏈上。
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) }
通過下面方法查詢鏈上的徵信資料。
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) }
通過下面方法刪除徵信數據。
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) }