賬本結(jié)構(gòu)

1.區(qū)塊鏈數(shù)據(jù),這是用文件系統(tǒng)存儲在Committer節(jié)點上的。區(qū)塊鏈中存儲了Transaction的讀寫集。
2.為了檢索區(qū)塊鏈的方便,所以用LevelDB對其中的Transaction進行了索引。
3.ChainCode操作的實際數(shù)據(jù)存儲在State Database中,這是一個Key Value的數(shù)據(jù)庫,默認采用的LevelDB,現(xiàn)在1.0也支持使用CouchDB作為State Database
交易流程
1.客戶端構(gòu)造交易提案
客戶端構(gòu)造交易提案,發(fā)送給一個或多個Peer節(jié)點,交易提案中包含本次交易要調(diào)用的合約標識、合約方法和參數(shù)信息以及客戶端簽名等。
Peer節(jié)點模擬執(zhí)行交易
Peer節(jié)點收到交易提案后,會模擬執(zhí)行交易,然后將原始交易提案和執(zhí)行結(jié)果打包到一起,進行簽名并發(fā)回給客戶端,其中在模擬執(zhí)行交易期間產(chǎn)生的數(shù)據(jù)修改不會寫到賬本上。
客戶端打包
客戶端收到各個Peer的應(yīng)答后,打包到一起組成一個交易并簽名,發(fā)送給Orderer。
共識排序,生成新區(qū)塊
Orderer對接收到的交易進行共識排序,然后按照區(qū)塊生成策略,將一批交易打包到一起,生成新的區(qū)塊,發(fā)送給Peer節(jié)點。
交易校驗
Peer節(jié)點收到區(qū)塊后,會對區(qū)塊中的每筆交易進行校驗,檢查交易依賴的輸入輸出是否符合當前區(qū)塊鏈的狀態(tài),完成后將區(qū)塊寫入賬本,并修改K-V狀態(tài)數(shù)據(jù)。
示例
example2
{"Args":["invoke","a","b","10"]}
Avalbytes, err := stub.GetState(A)
Bvalbytes, err := stub.GetState(B)
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
1.客戶端SDK把'{"Args":["invoke","a","b","10"]}'這些參數(shù)發(fā)送到endorser peer節(jié)點,
2.endorser peer會與ChainCode的docker實例通信,并為其提供模擬的State Database的讀寫集,也就是說ChainCode會執(zhí)行完邏輯,但是并不會在stub.PutState的時候?qū)憯?shù)據(jù)庫。
3.endorser把這些讀寫集連同簽名返回給Client SDK。
4.SDK再把讀寫集發(fā)送給Orderer節(jié)點,Orderer節(jié)點是進行共識的排序節(jié)點,在測試的情況下,只啟動一個orderer節(jié)點,沒有容錯。在生產(chǎn)環(huán)境,要進行Crash容錯,需要啟用Zookeeper和Kafka。在1.0中移除了拜占庭容錯,沒有0.6的PBFT,也沒有傳說中的SBFT,不得不說是一個遺憾。
5.Orderer節(jié)點只是負責排序和打包工作,處理的結(jié)果是一個Batch的Transactions,也就是一個Block,這個Block的產(chǎn)生有兩種情況,一種情況是Transaction很多,Block的大小達到了設(shè)定的大小,而另一種情況是Transaction很少,沒有達到設(shè)定的大小,那么Orderer就會等,等到大小足夠大或者超時時間。這些設(shè)置是在configtx.yaml中設(shè)定的。
6.打包好的一堆Transactions會發(fā)送給Committer Peer提交節(jié)點,
7.提交節(jié)點收到Orderer節(jié)點的數(shù)據(jù)后,會先進行VSCC校驗,檢查Block的數(shù)據(jù)是否正確。接下來是對每個Transaction的驗證,主要是驗證Transaction中的讀寫數(shù)據(jù)集是否與State Database的數(shù)據(jù)版本一致。驗證完Block中的所有Transactions后,提交節(jié)點會把吧Block寫入?yún)^(qū)塊鏈。然后把所有驗證通過的Transaction的讀寫集中的寫的部分寫入State Database。另外對于區(qū)塊鏈,本身是文件系統(tǒng),不是數(shù)據(jù)庫,所有也會有把區(qū)塊中的數(shù)據(jù)在LevelDB中建立索引。