1. 程式人生 > >Hyperledger fabric網絡中transaction產生以及流轉過程

Hyperledger fabric網絡中transaction產生以及流轉過程

sta 並不會 font eid teset amp 包括 ntb 當前

一、發起transaction

當client想要發起一個transaction時,它會首先發送一個PROPOSE消息到它選擇的一組endorser節點,消息模式有以下兩種,節點可以自由選擇(可能有更多種):

  • client首先將<PROPOSE, tx>消息發送給某個單個的endorser,該endorser會產生相應的版本依賴(anchor),以供client稍後作為PROPOSE消息的參數發送給其它endorser節點;
  • client直接將<PROPOSE, tx>消息發送給它選擇的這一組endorser節點。

PROPOSE消息的格式為<PROPOSE, tx, [anchor]>,其中anchor參數為可選,表示讀版本依賴,通常是指key-version對,必選的tx參數代表transaction的內容,包括發起該transaction的client唯一標識符clientID,指向transaction所涉及chaincode的chaincodeID,包含所發起的transaction本身的txPayload,一個由client維護的單調遞增的整數timestamp以及client的簽名clientSig。其中txPayload根據transaction的不同而分成兩種不同的類型:

  • 喚醒事務(invoke transaction):txPayload=<operation, metadata>,其中operation表示chaincode操作以及傳遞給chaincode的參數,metadata表示與調用相關的屬性;
  • 部署事務(deploy transaction):txPayload=<source, metadata, policies>,其中source表示chaincode的源碼,metadata表示與chaincode和應用相關的屬性,policies表示與chaincode相關的策略,包括備書策略等。

二、模擬transaction

  • 當endorser接收到一個PROPOSE消息後,它會首先驗證其中的clientSig,通過驗證後會對該transaction進行模擬。如果PROPOSE消息中包含anchor字段,endorser會根據anchor中的key獲取當前本地狀態中對應該key值的version值,從而生成readset(讀集),如當前endorser本地保存的狀態為s,對任意一個transaction中的key k,(k, s(k).version)就會被添加到讀集中,只有在anchor與readset匹配即完全相等時,endorser才會模擬該transaction。模擬transaction基於endorser本地保存的狀態副本,調用對應的chaincode來試探性地執行該transaction,從而生成一個被稱為writeset(寫集)的狀態更新,如任意一個transaction中的key k對應的值被修改成為v,則(k, v)就會被加入到寫集中去。
  • endorser內部轉發tran-proposal到它備書transaction的邏輯部分——備書邏輯,默認情況下,備書邏輯會接受該tran-proposal並給它加上簽名,當然,也可以通過任意函數來達成是否備書的決定。
  • 如果endorser決定給一個transaction備書,它會給提交的client發送一個<TRANSACTION-ENDORSED, tid, tran-proposal,epSig>消息,其中tid是對PROPOSE消息中的tx進行哈希運算生成的,用來指向某個transaction,epSig是備書節點的簽名,tran-proposal = (epID,tid,chaincodeID,txContentBlob,readset,writeset),其中epID是備書節點的節點ID,txContentBlob是chaincode/transaction的具體信息,作為tx的某種形式進行使用,如txContentBlob = tx.txPayload。
  • 如果endorser拒絕給一個transaction備書,它只需要直接給發起該transaction的client發送(TRANSACTION-INVALID, tid, REJECTED)消息。
  • 整個過程中,endorser並不會修改它本地狀態,只是對transaction進行模擬。

三、接收備書消息

發起transaction的client發出PROPOSE消息後會一直等待接收備書消息,是否備書成功取決於當前的備書策略,如當前client選擇的備書節點集合為{Alice, Bob, Charlie, Dave, Eve, Frank, George},當前的備書策略為有5個備書節點通過即通過,則client在收集到5個TRANSACTION-ENDORSED消息後即認為當前transaction備書成功,接收到的TRANSACTION-ENDORSED消息集被稱為endorsement。

之後,client會發送broadcast(blob)(此時blob即為endorsement)消息到Orderer system channel中,通過orderer來將該transaction同步到整個channel內的節點中。orderer會將一段時間內的所有transaction進行排序並打包成block然後通過deliver(seqno, prevhash, blob)消息將block發送給所有節點,其中seqno表示一個非負的序號,prevhash表示最近一次block的哈希值,blob表示一個block區塊。

四、同步transaction

當節點收到一個deliver消息時,它會根據chaincode的策略來檢查blob.endorsement是否有效,再檢查readset是否與當前節點的本地狀態一致。

如果所有的驗證都通過後,transaction被視為有效的。此時,節點將PeerLedger的位掩碼中將該transaction標記為1,通過blob.endorsement.tran-proposal.writeset 修改本地的帳本狀態。

如果blob.endorsement的備書策略驗證失敗,則該transaction被認為是無效的,節點在PeerLedger的位掩碼中將該transaction標記為0。重要的是要註意,無效的交易雖然會被放入區塊中,但不會改變本地的帳本狀態。

Hyperledger fabric網絡中transaction產生以及流轉過程