曹祖晟,丁磊
(廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院,廣州510006)
近年來農(nóng)產(chǎn)品的安全問題得到了社會的廣泛關(guān)注,劣質(zhì)農(nóng)產(chǎn)品給人們的生命財(cái)產(chǎn)安全帶來了巨大威脅,但事后的追責(zé)卻因?yàn)槿狈煽孔C據(jù)或難以定位責(zé)任方而難以繼續(xù),嚴(yán)重侵害了消費(fèi)者的權(quán)益。在農(nóng)產(chǎn)品供應(yīng)鏈中,互信難的問題[1-2]使得參與方之間達(dá)成合作的成本升高,而參與方各自維護(hù)自己的數(shù)據(jù)倉庫,缺乏統(tǒng)一的標(biāo)準(zhǔn)體系,又使得農(nóng)產(chǎn)品在不同流通環(huán)節(jié)中數(shù)據(jù)混亂,且中心化的運(yùn)作方式易造成信息不透明,導(dǎo)致追溯信息可信度不高[3]。
區(qū)塊鏈?zhǔn)且环N去中心化、無需信任的新型數(shù)據(jù)架構(gòu),目前已經(jīng)發(fā)展到3.0時代,成為各行業(yè)去中心化數(shù)據(jù)管理的技術(shù)支撐[4]。區(qū)塊鏈由網(wǎng)絡(luò)中所有的節(jié)點(diǎn)共同擁有、管理和監(jiān)督,不接受單一方面的控制,數(shù)據(jù)上鏈后被永久記錄,不能被篡改,在解決追溯系統(tǒng)可信度問題方面具有先天技術(shù)優(yōu)勢,能夠?qū)崿F(xiàn)可追溯性,有效解決上述農(nóng)產(chǎn)品供應(yīng)鏈中的問題。Kamble等人通過解釋結(jié)構(gòu)模型等方法分析將區(qū)塊鏈技術(shù)運(yùn)用到農(nóng)產(chǎn)品供應(yīng)鏈的驅(qū)動因素,結(jié)果也表明了可追溯性是采用區(qū)塊鏈技術(shù)最重要的原因[5]。近年來國內(nèi)外學(xué)者運(yùn)用區(qū)塊鏈技術(shù)在供應(yīng)鏈領(lǐng)域進(jìn)行了探索研究,如Tian等人運(yùn)用區(qū)塊鏈與RFID技術(shù)相結(jié)合的方法實(shí)現(xiàn)了一個供應(yīng)鏈追溯系統(tǒng)[6];李明佳等人結(jié)合區(qū)塊鏈技術(shù)設(shè)計(jì)了食品安全溯源體系并論證了有效性[7];方燚飚等人設(shè)計(jì)了基于區(qū)塊鏈的供應(yīng)鏈交易系統(tǒng),能夠?qū)崿F(xiàn)更高效、透明的信息共享[8];洪坤明等人結(jié)合GS1編碼標(biāo)準(zhǔn),設(shè)計(jì)了基于聯(lián)盟鏈的水產(chǎn)養(yǎng)殖品質(zhì)量追溯系統(tǒng),使得追溯更高效[9]。在數(shù)據(jù)存儲方面,由于一般區(qū)塊鏈的鏈?zhǔn)酱鎯Ψ绞?,查詢效率低下,為此,楊信廷等人提出了一種“數(shù)據(jù)庫+區(qū)塊鏈”鏈上鏈下追溯信息雙存儲方法,保證了追溯信息可靠性的同時保證了查詢效率[10]?,F(xiàn)在的研究大多都是基于常用的區(qū)塊鏈系統(tǒng)如Bit?coin、Ethereum、Hyperledger Fabric,對 于Hyperledger Sawtooth的研究較少。M.P.Caro等人分別用Ethereum和Sawtooth實(shí)現(xiàn)了同一種供應(yīng)鏈系統(tǒng),并對兩種方案實(shí)現(xiàn)的系統(tǒng)進(jìn)行測試,結(jié)果顯示Sawtooth擁有更優(yōu)的性能,但缺點(diǎn)是Sawtooth不如Ethereum成熟[11]。Fabric和Sawtooth都是Hyperledger下的項(xiàng)目,區(qū)別是在于Fabric注重隱私,而Sawtooth注重特定業(yè)務(wù)[12],在農(nóng)產(chǎn)品供應(yīng)鏈業(yè)務(wù)頻繁的體系中,互信的商戶信息是公開的,對隱私性的要求較低,所以Sawtooth比Fabric更適合農(nóng)產(chǎn)品供應(yīng)鏈追溯系統(tǒng)。綜上,區(qū)塊鏈技術(shù)在解決供應(yīng)鏈面臨的各種問題上具有顯著優(yōu)勢。因此本文對Hyperledger Sawtooth和農(nóng)產(chǎn)品供應(yīng)鏈展開研究,結(jié)合GS1編碼體系,設(shè)計(jì)了一個農(nóng)產(chǎn)品供應(yīng)鏈追溯系統(tǒng),完成農(nóng)產(chǎn)品供應(yīng)鏈交易并記錄數(shù)據(jù),構(gòu)建追溯鏈,解決農(nóng)產(chǎn)品供應(yīng)鏈面臨的參與方互信難、信息不對稱、產(chǎn)品質(zhì)量和安全問題追責(zé)難等問題。
本文系統(tǒng)采用的農(nóng)產(chǎn)品供應(yīng)鏈追溯模型如圖1所示,參與方有生產(chǎn)商、加工商、分銷商、零售商、消費(fèi)者和擁有監(jiān)管職權(quán)的監(jiān)管部門。
圖1 供應(yīng)鏈追溯模型
系統(tǒng)的架構(gòu)分為物理層、數(shù)據(jù)層、區(qū)塊鏈層,如圖2所示。物理層主要包括供應(yīng)鏈中的各參與方和資產(chǎn),即生產(chǎn)商、加工商、分銷商、零售商、消費(fèi)者和監(jiān)管部門等實(shí)體以及商戶創(chuàng)建的產(chǎn)品等各項(xiàng)資產(chǎn);數(shù)據(jù)層主要是各資產(chǎn)的屬性,如:所有者、產(chǎn)品類型、重量、采摘日期或屠宰日期等,屬性在系統(tǒng)中的表現(xiàn)方式為傳輸和存儲在系統(tǒng)中數(shù)據(jù)以及包含索引信息的二維碼;區(qū)塊鏈層是處理和存儲可追溯性數(shù)據(jù)的區(qū)塊鏈平臺,響應(yīng)用戶的操作請求,并對數(shù)據(jù)進(jìn)行持久化存儲。
圖2 系統(tǒng)架構(gòu)
本文設(shè)計(jì)的農(nóng)產(chǎn)品供應(yīng)鏈追溯系統(tǒng)是在Hy?perledger Sawtooth基本框架中實(shí)現(xiàn)的,應(yīng)用區(qū)塊鏈的分布式特征,每個節(jié)點(diǎn)都備份所參與鏈的相同賬本,共同維護(hù)賬本的完整性和不變性[13]?;贖yperledger Saw?tooth的區(qū)塊鏈?zhǔn)且环N聯(lián)盟鏈,通過節(jié)點(diǎn)與節(jié)點(diǎn)雙向連接的方式形成可靠的區(qū)塊鏈網(wǎng)絡(luò),參與方在整個網(wǎng)絡(luò)中共享數(shù)據(jù),有效解決供應(yīng)鏈中不同參與方所維護(hù)的數(shù)據(jù)不同步的問題。多節(jié)點(diǎn)的區(qū)塊鏈網(wǎng)絡(luò)保證了系統(tǒng)的安全性,當(dāng)少量節(jié)點(diǎn)故障時不影響網(wǎng)絡(luò)的正常運(yùn)作,當(dāng)有新節(jié)點(diǎn)加入時也能通過其他節(jié)點(diǎn)獲取完整的賬本。農(nóng)產(chǎn)品供應(yīng)鏈的所有交易信息都將永久記錄在賬本中,通過查找賬本可以準(zhǔn)確構(gòu)建供應(yīng)鏈的歷史過程,從而達(dá)到追溯的目的。
本文設(shè)計(jì)的系統(tǒng)結(jié)構(gòu)模型如圖3所示。區(qū)塊鏈網(wǎng)絡(luò)中有多個Sawtooth節(jié)點(diǎn),每個節(jié)點(diǎn)都擁有相同的驗(yàn)證器、交易處理器、共識引擎和REST API,每個節(jié)點(diǎn)都能以可插拔的方式連接客戶端[14]?;贖yperledger Sawtooth的開發(fā)要求通過定義交易處理器的業(yè)務(wù)邏輯、客戶端的業(yè)務(wù)邏輯和數(shù)據(jù)模型構(gòu)建交易族(TF,Trans?action Family)來完成特定業(yè)務(wù)需求。
圖3 Hyperledger Sawtooth區(qū)塊鏈網(wǎng)絡(luò)結(jié)構(gòu)模型
系統(tǒng)的設(shè)計(jì)細(xì)分為七個模塊,第一模塊系統(tǒng)角色設(shè)區(qū)分了本系統(tǒng)面向的用戶類型;第二模塊GS1編碼設(shè)計(jì)規(guī)定了用戶使用本系統(tǒng)時應(yīng)該遵循的產(chǎn)品數(shù)據(jù)規(guī)范;第三模塊交易和批次,定義了交易和批次的數(shù)據(jù)結(jié)構(gòu),規(guī)定了客戶端打包用戶交易的規(guī)則;第四模塊區(qū)塊鏈結(jié)構(gòu)規(guī)定了區(qū)塊的打包規(guī)則以及區(qū)塊鏈的鏈接方式;第五模塊尋址方案制定了State存儲空間的劃分規(guī)則及索引方式,提供了高效的數(shù)據(jù)庫查找方案;第六模塊交易邏輯設(shè)計(jì)描述了交易從發(fā)起到區(qū)塊產(chǎn)生的全過程;第七模塊追溯鏈構(gòu)建設(shè)計(jì)了追溯鏈條的構(gòu)建算法。
本文系統(tǒng)中的角色主要包括系統(tǒng)管理員、業(yè)務(wù)管理員、操作員、追溯者四類,各角色說明如表1所示。系統(tǒng)管理員擁有管理節(jié)點(diǎn)的權(quán)限,能代表節(jié)點(diǎn)進(jìn)行鏈上治理,驗(yàn)證業(yè)務(wù)管理員的身份并管理其讀寫訪問權(quán)限;業(yè)務(wù)管理員是一個擁有的admin權(quán)限的參與方(組織)代理,擁有一個組織的所有操作權(quán)限,同時可以管理該組織操作員的權(quán)限;操作員也是組織下的代理,擁有組織授予的讀寫權(quán)限,可以進(jìn)行相應(yīng)的業(yè)務(wù)操作;追溯者擁有構(gòu)建農(nóng)產(chǎn)品供應(yīng)鏈中歷史過程的權(quán)限,并查看產(chǎn)品相關(guān)歷史信息。各供應(yīng)鏈商戶以組織的形式參與到區(qū)塊鏈系統(tǒng)中,業(yè)務(wù)管理員對應(yīng)供應(yīng)鏈中的商戶角色,操作員對應(yīng)商戶中的員工角色,追溯者主要對應(yīng)有追溯需求的消費(fèi)者和監(jiān)管部門。不同的角色登錄客戶端將打開不同的操作子集。
表1 角色說明
系統(tǒng)采用嚴(yán)格的身份認(rèn)證機(jī)制,使用公私密鑰對進(jìn)行身份標(biāo)識,交易的產(chǎn)生、打包、處理、數(shù)據(jù)的寫入和讀取都會進(jìn)行相應(yīng)的簽名驗(yàn)證,不符合權(quán)限的操作將被拒絕。
為避免不同參與方的產(chǎn)品編碼規(guī)則不同,造成數(shù)據(jù)的混亂,系統(tǒng)采用標(biāo)準(zhǔn)化的編碼體系,使用GS1編碼體系對農(nóng)產(chǎn)品相關(guān)信息進(jìn)行唯一標(biāo)識[15],關(guān)鍵編碼如表2所示。GTIN-12碼唯一標(biāo)識產(chǎn)品,GLN碼唯一標(biāo)識了廠商的物理位置,編碼都內(nèi)含了廠商識別碼,在區(qū)別產(chǎn)品和位置的同時也區(qū)別了廠商,為追溯鏈的構(gòu)建提供了數(shù)據(jù)上的便捷。
表2 關(guān)鍵編碼
系統(tǒng)對owner、product_id、pre_product_id、dir_prod?uct_id、location、pre_location、dir_location七個字段進(jìn)行了GS1體系的編碼,分別對應(yīng)廠商識別碼、當(dāng)前產(chǎn)品GTIN、來源產(chǎn)品GTIN、廠商GLN碼和來源廠商GLN碼,這七個字段伴隨著供應(yīng)鏈階段的前進(jìn)而更新。
系統(tǒng)中任何事件都通過交易的方式進(jìn)行,如創(chuàng)建產(chǎn)品、記錄產(chǎn)品信息、修改產(chǎn)品信息、創(chuàng)建代理、更新代理權(quán)限等。一個或多個交易在客戶端中被打包成一個批次,通過REST API提交至驗(yàn)證器進(jìn)行處理。一個批次的數(shù)據(jù)結(jié)構(gòu)如圖4所示,一個批次包括批次(Batch)、批次頭(BatchHeader)、交易(Transaction)和交易頭(TransactionHeader)。在批次中,header是經(jīng)過序列化的批次頭,在交易處理器中進(jìn)行反序列化后將得到簽名 公 鑰(signer_public_key)和 交 易 列 表(transac?tion_ids),驗(yàn)證簽名密鑰(header_signature)是否與簽名公鑰匹配,從而驗(yàn)證批次的合法性,交易列表對應(yīng)每一筆交易(Transaction)。交易與批次的結(jié)構(gòu)類似,交易頭中包含了打包批次的公鑰(batcher_public_key),輸入(inputs)和輸出(outputs)分別表示交易需要讀取的狀態(tài)地址和交易寫入的狀態(tài)地址,有效負(fù)載(payload)記錄了交易的具體參數(shù)。
圖4 批次(Batch)數(shù)據(jù)結(jié)構(gòu)圖
交易以批次的形式提交到驗(yàn)證器,一個或多個批次的交易被驗(yàn)證和執(zhí)行成功后被打包成區(qū)塊并發(fā)布,區(qū)塊和批次的嵌套數(shù)據(jù)結(jié)構(gòu)與交易和批次的數(shù)據(jù)結(jié)構(gòu)類似,在此不再贅述。區(qū)塊鏈的結(jié)構(gòu)示意圖如圖5所示,區(qū)塊包含區(qū)塊頭和區(qū)塊體兩部分,區(qū)塊頭中包含前一個區(qū)塊的哈希值、區(qū)塊號、簽名公鑰、時間戳、批次列表、狀態(tài)根哈希值和本區(qū)塊的哈希值。所有交易的相關(guān)數(shù)據(jù)以Merkle-Radix樹的形式存儲在驗(yàn)證器的狀態(tài)(State)中,區(qū)塊打包時將State的當(dāng)前狀態(tài)也打包進(jìn)區(qū)塊。數(shù)據(jù)存放在樹最下層的葉子節(jié)點(diǎn),葉子節(jié)點(diǎn)不斷向上層節(jié)點(diǎn)進(jìn)行哈希運(yùn)算,最終得到樹的根哈希,區(qū)塊一旦被驗(yàn)證,任何數(shù)據(jù)的改變都將導(dǎo)致根哈希的改變,僅檢驗(yàn)根哈希值就能保證數(shù)據(jù)的完整性[16]。
圖5 區(qū)塊鏈結(jié)構(gòu)示意圖
Merkle-Radix樹能夠以索引的方式迅速定位數(shù)據(jù)的物理存放地址,如圖6所示。地址是35字節(jié)的十六進(jìn)制編碼字符串,共70個字符,每個字節(jié)向下索引一個葉子節(jié)點(diǎn),從根節(jié)點(diǎn)到葉子節(jié)點(diǎn),深度最多可以達(dá)到35。
圖6 尋址方式示意圖
根據(jù)業(yè)務(wù)邏輯需求設(shè)計(jì)尋址方案。完成農(nóng)產(chǎn)品供應(yīng)鏈相關(guān)功能的交易族被命名為APSChain,使用SHA512算法對APSChain編碼,取哈希值的前六位“f20ac0”作為命名空間地址的前綴,所有APSChain相關(guān)存放在狀態(tài)中的數(shù)據(jù)的地址都以此前綴開頭。如圖7所示,前6位是命名空間地址前綴,緊接在后面的兩個十六進(jìn)制字符用來對具有相同結(jié)構(gòu)的數(shù)據(jù)進(jìn)行分組,分組情況如表3所示。
圖7 尋址地址結(jié)構(gòu)
表3 尋址地址分組
剩余62個索引字符將根據(jù)分組屬性進(jìn)一步靈活劃分,如User分組的62個字符中,前兩個用于區(qū)分用戶在系統(tǒng)中的身份,11、12、13、14分別對應(yīng)系統(tǒng)管理員、業(yè)務(wù)管理員、操作員和追溯者四種用戶角色,最后60個字符取用戶公鑰進(jìn)行SHA-512后的前60位。再如Product分類,產(chǎn)品對象在系統(tǒng)中更新的頻率很高,為了達(dá)成追溯目的,需要長久且完整地存儲產(chǎn)品的所有歷史記錄,所以將命名空間的最后4個十六進(jìn)制字符規(guī)定為分頁地址。屬性本身存儲在以0000結(jié)尾的命名空間中,屬性的歷史記錄按時間戳的先后順序存儲在0001至ffff的分頁中,每當(dāng)屬性進(jìn)行更新,0000中的數(shù)據(jù)將加入到歷史記錄分頁中,并將0000中的數(shù)據(jù)更新為最新的數(shù)據(jù)。交易處理器將這些分頁視為環(huán)形buffer,當(dāng)ffff分頁被填充后,下一次更新將覆蓋0001分頁,在此方案下,可以在記錄被覆蓋之前存儲162*(1 64-1)=16776960個歷史分頁,充分滿足了記錄產(chǎn)品歷史屬性的需求。分頁地址之前的58個字符取產(chǎn)品的GTIN-12編碼經(jīng)過SHA-512后的前58位,最終生成了特定產(chǎn)品對象的完整命名空間。
交易處理流程如圖8所示。交易由客戶端發(fā)起,經(jīng)過序列化的一筆或多筆交易被打包成批次,通過REST API發(fā)送到驗(yàn)證器。驗(yàn)證器是Sawtooth節(jié)點(diǎn)的核心組件,負(fù)責(zé)檢驗(yàn)交易的合法性,其過程包括對交易信息完整性的檢測和對上下文完整性的檢測,被篡改或不符合權(quán)限要求的交易將被丟棄;若上下文不完整,則向區(qū)塊鏈網(wǎng)絡(luò)中請求上下文信息,在規(guī)定時間內(nèi)未獲得上下文信息的交易也將被丟棄。完成交易合法性驗(yàn)證的交易批次將在區(qū)塊網(wǎng)絡(luò)中進(jìn)行廣播,然后被發(fā)送至對應(yīng)的交易處理器。交易處理器定義了處理交易的業(yè)務(wù)邏輯,即智能合約。收到交易內(nèi)容的交易處理器首先對交易內(nèi)容的有效負(fù)載進(jìn)行反序列化,接著按照智能合約的業(yè)務(wù)邏輯對交易進(jìn)行處理,同時根據(jù)尋址方案找到驗(yàn)證器中存放數(shù)據(jù)的狀態(tài)地址,并改變狀態(tài)。狀態(tài)存儲了區(qū)塊鏈的所有數(shù)據(jù),狀態(tài)完成更新后,驗(yàn)證器將當(dāng)前狀態(tài)的哈希值和批次打包成區(qū)塊,添加到當(dāng)前區(qū)塊鏈的鏈頭。其他收到廣播的節(jié)點(diǎn)也將根據(jù)批次的內(nèi)容進(jìn)行合法性檢驗(yàn)、執(zhí)行智能合約、改變狀態(tài)和區(qū)塊打包等,從而保證了區(qū)塊鏈分布式賬本的統(tǒng)一性。
圖8 交易處理流程圖
追溯分為“追”和“溯”兩個過程,即“向上溯源”和“向下追尋去向”兩個過程。由于農(nóng)產(chǎn)品在供應(yīng)鏈中通常以散裝稱重進(jìn)行交易,所以一批農(nóng)產(chǎn)品可能被分為多批流向供應(yīng)鏈下游,所以“追”的過程不能像“溯”的過程一樣簡單視為一條單鏈,應(yīng)構(gòu)造樹狀的追溯鏈。本文采用基于深度優(yōu)先搜索算法(Depth First Search,DFS)的追溯鏈構(gòu)建算法如下:
算法1追溯鏈構(gòu)建算法
利用該算法在狀態(tài)中查找農(nóng)產(chǎn)品相關(guān)的所有信息構(gòu)建追溯鏈。
開發(fā)與測試平臺如下:Ubuntu 18.04操作系統(tǒng)、Intel Core i5-4210M處理器,內(nèi)存8G,部署Docker 18.03-ce、docker-compose 1.24.0、Nodejs v12.20.1。
運(yùn)用Docker技術(shù),將客戶端和運(yùn)行APSChain智能合約的交易處理器與Sawtooth組件在測試環(huán)境下一起運(yùn)行,運(yùn)行成功顯示如圖9,Docker容器的啟動情況如圖10。
圖9 系統(tǒng)啟動成功示例圖
圖10 Docker容器啟動情況
系統(tǒng)運(yùn)用在生產(chǎn)環(huán)境中還應(yīng)考慮商業(yè)環(huán)境下供應(yīng)鏈參與方維護(hù)區(qū)塊鏈節(jié)點(diǎn)的成本和收益,采用合適的共識機(jī)制,將devmode-engine替換為其他共識引擎,達(dá)成共識后,區(qū)塊鏈網(wǎng)絡(luò)中的各節(jié)點(diǎn)都將運(yùn)行功能相同的docker容器。
追溯者使用移動設(shè)備掃描二維碼進(jìn)行追溯鏈的構(gòu)建,二維碼信息需包含農(nóng)產(chǎn)品的GTIN-12編碼和時間戳。以上信息將攜帶追溯者的公鑰以批次的形式被發(fā)送至驗(yàn)證器,并啟動追溯者的操作子集,結(jié)果將打印在追溯者的客戶端界面。如圖11所示,以追溯者在供應(yīng)鏈中的階段為原點(diǎn),向供應(yīng)鏈上游溯源出一條鏈?zhǔn)浇Y(jié)構(gòu)的鏈,向供應(yīng)鏈下游追尋出一個樹狀結(jié)構(gòu)的鏈,兩條鏈拼接在一起即是一條完整的供應(yīng)鏈追溯鏈。
圖11 追溯鏈?zhǔn)纠?/p>
本文針對農(nóng)產(chǎn)品供應(yīng)鏈情景下參與方互信難、信息不對稱、產(chǎn)品質(zhì)量和安全問題追責(zé)難等問題,研究并設(shè)計(jì)了一種農(nóng)產(chǎn)品供應(yīng)鏈追溯系統(tǒng)。本文首先對供應(yīng)鏈系統(tǒng)的研究現(xiàn)狀進(jìn)行分析,論述了區(qū)塊鏈技術(shù)用于供應(yīng)鏈追溯的有效性,并選取了性能較優(yōu)的Hy?perledger Sawtooth框架進(jìn)行進(jìn)一步研究,然后確定了系統(tǒng)的整體模型,接著對系統(tǒng)的用戶角色、GS1編碼體系、交易批次的數(shù)據(jù)結(jié)構(gòu)和尋址方案等模塊進(jìn)行細(xì)節(jié)的設(shè)計(jì),最后運(yùn)用“追”與“溯”的追溯鏈構(gòu)建算法,實(shí)現(xiàn)了農(nóng)產(chǎn)品追溯鏈的構(gòu)建。經(jīng)過系統(tǒng)的運(yùn)行測試和追溯鏈構(gòu)建測試,系統(tǒng)能夠穩(wěn)定運(yùn)行并構(gòu)建追溯鏈,可滿足農(nóng)產(chǎn)品供應(yīng)鏈的追溯需求。