應(yīng)用程序開發(fā) - 應(yīng)用程序設(shè)計(jì)元素 - 鏈碼命名空間
鏈碼命名空間允許它保持其世界狀態(tài)與其他鏈碼分離。具體來說唉俗,具有相同鏈碼的智能合約共享對同一世界狀態(tài)的直接訪問配椭,而具有不同鏈碼的智能合約不能直接訪問彼此的世界狀態(tài)。如果智能合約需要訪問另一個(gè)鏈碼世界狀態(tài)衡楞,則可以通過執(zhí)行鏈碼到鏈碼的調(diào)用來做到這一點(diǎn)。最后敦姻,區(qū)塊鏈可以包含與不同世界狀態(tài)相關(guān)的交易歧杏。
在本主題中迷守,我們將介紹:
- 命名空間的重要性
- 什么是鏈碼命名空間
- 通道和名稱空間
- 如何使用鏈碼命名空間
- 如何通過智能合約訪問世界狀態(tài)
- 鏈碼命名空間的設(shè)計(jì)注意事項(xiàng)
1. 動(dòng)機(jī)
命名空間是一個(gè)常見的概念兑凿。我們知道,紐約的公園街和西雅圖的公園街雖然名稱相同礼华,但卻是不同的街道。這個(gè)城市形成了公園街的命名空間圣絮,同時(shí)提供了自由和清晰扮匠。
在計(jì)算機(jī)系統(tǒng)中也是一樣。命名空間允許不同的用戶對共享系統(tǒng)的不同部分進(jìn)行編程和操作餐禁,而不會(huì)互相干擾帮非。許多編程語言都有命名空間讹蘑,因此程序可以自由分配唯一的標(biāo)識(shí)符,例如變量名陨舱,而不必?fù)?dān)心其他程序會(huì)這樣做版仔。我們將看到 Hyperledger Fabric 使用命名空間來幫助智能合約將其帳本世界狀態(tài)與其他智能合約區(qū)分開。
2. 場景
讓我們使用下圖檢查賬本世界狀態(tài)如何組織對組織中重要組織的業(yè)務(wù)對象的事實(shí)益缎。無論這些對象是商業(yè)票據(jù)然想,債券還是車輛登記證,以及它們在其生命周期中的任何位置令哟,都將其維護(hù)為帳本世界狀態(tài)數(shù)據(jù)庫中的狀態(tài)。智能合約通過與帳本 (世界狀態(tài)和區(qū)塊鏈) 進(jìn)行交互來管理這些業(yè)務(wù)對象晴竞,在大多數(shù)情況下役听,這將涉及查詢或更新帳本世界狀態(tài)。
了解帳本世界狀態(tài)是根據(jù)訪問它的智能合約的鏈碼進(jìn)行分區(qū)的甜滨,這一點(diǎn)至關(guān)重要瘤袖,對于架構(gòu)師,管理員和程序員來說艾扮,這種分區(qū)或命名空間是重要的設(shè)計(jì)考慮因素占婉。
賬本世界狀態(tài)根據(jù)訪問它的鏈碼分為不同的命名空間逆济。在給定的通道內(nèi),相同鏈碼中的智能合約共享相同的世界狀態(tài)抛虫,而不同鏈碼中的智能合約無法直接訪問彼此的世界狀態(tài)简僧。同樣,區(qū)塊鏈可以包含與不同鏈碼世界狀態(tài)相關(guān)的交易棉姐。
在我們的示例中啦逆,我們可以看到在兩個(gè)不同的鏈碼中定義了四個(gè)智能合約,每個(gè)合約都在自己的鏈碼容器中扭吁。 euroPaper 和 yenPaper 智能合約在 papers
鏈碼中定義。對于 EuroBond 和 JPYBond 智能合約蝌诡,情況也是如此 - 它們在 bonds
鏈碼中定義枫吧。這種設(shè)計(jì)可以幫助應(yīng)用程序程序員了解他們是在使用歐元還是日元定價(jià)的商業(yè)票據(jù)還是債券,并且由于每種金融產(chǎn)品的規(guī)則對于不同的貨幣并沒有真正改變颁湖,因此有必要使用相同的鏈碼來管理其部署例隆。
該圖 還顯示了此部署選擇的后果。數(shù)據(jù)庫管理系統(tǒng) (DBMS) 為 papers
和 bonds
鏈碼以及其中包含的智能合約創(chuàng)建不同的世界狀態(tài)數(shù)據(jù)庫镰禾。世界狀態(tài) A 和世界狀態(tài) B 分別保存在不同的數(shù)據(jù)庫中唱逢;數(shù)據(jù)彼此隔離,因此單個(gè)世界狀態(tài)查詢 (例如) 無法訪問兩個(gè)世界狀態(tài)备韧。據(jù)說世界狀態(tài)根據(jù)其鏈碼進(jìn)行了命名痪枫。
了解世界狀態(tài) A 如何包含兩個(gè)商業(yè)票據(jù)列表 paperListEuro
和 paperListYen
听怕。狀態(tài) PAP11 和 PAP21 是分別由 euroPaper 和 yenPaper 智能合約管理的每種票據(jù)的實(shí)例虑绵。因?yàn)樗鼈児蚕硐嗤逆湸a命名空間,所以它們的鍵 (PAPxyz) 在 papers
鏈碼的命名空間內(nèi)必須是唯一的声搁,有點(diǎn)像街道名稱在城鎮(zhèn)中是唯一的捕发。注意,有可能在 papers
鏈碼中編寫智能合約檐涝,從而對所有商業(yè)票據(jù) (無論是歐元還是日元) 進(jìn)行匯總計(jì)算,因?yàn)樗鼈児蚕硐嗤拿臻g幅聘。債券的情況與此類似 - 它們保存在世界狀態(tài) B 中窃植,該狀態(tài)映射到單獨(dú)的債券數(shù)據(jù)庫,并且其鍵必須唯一葛超。
同樣重要的是延塑,命名空間意味著 euroPaper 和 yenPaper 無法直接訪問世界狀態(tài) B,而 EuroBond 和 yenBond 無法直接訪問世界狀態(tài) A胖替。這種隔離非常有用豫缨,因?yàn)樯虡I(yè)票據(jù)和債券是非常不同的金融工具好芭;它們具有不同的屬性,并遵循不同的規(guī)則舍败。這也意味著票據(jù)和證券可以具有相同的鍵邻薯,因?yàn)樗鼈兾挥诓煌拿臻g中。這很有幫助累榜;它為命名提供了很大的自由度灵嫌。使用這種自由來有意義地命名不同的業(yè)務(wù)對象。
最重要的是猖凛,我們可以看到區(qū)塊鏈與在特定通道中運(yùn)行的對端節(jié)點(diǎn)相關(guān)聯(lián)绪穆,并且它包含影響世界狀態(tài) A 和世界狀態(tài) B 的交易虱岂。這是因?yàn)閰^(qū)塊鏈?zhǔn)菍Χ斯?jié)點(diǎn)中包含的最基本的數(shù)據(jù)結(jié)構(gòu)量瓜⊥灸耍可以始終從此區(qū)塊鏈重新創(chuàng)建世界狀態(tài)集,因?yàn)樗鼈兪菂^(qū)塊鏈交易的累積結(jié)果烫饼。世界狀態(tài)有助于簡化智能合約并提高其效率试读,因?yàn)樗鼈兺ǔH需要一個(gè)狀態(tài)的當(dāng)前值。通過命名空間將世界狀態(tài)分開可以幫助智能合約將其邏輯與其他智能合約隔離比藻,而不必?fù)?dān)心對應(yīng)于不同世界狀態(tài)的交易倘屹。例如,債券合約不需要擔(dān)心票據(jù)交易务蝠,因?yàn)樗床坏剿鼈儺a(chǎn)生的世界狀態(tài)烛缔。
還值得注意的是践瓷,對端節(jié)點(diǎn),鏈碼容器和 DBMS 在邏輯上都是不同的進(jìn)程喷舀。對端節(jié)點(diǎn)及其所有鏈碼容器始終在物理上獨(dú)立的操作系統(tǒng)進(jìn)程中崖面,但是根據(jù)其 類型梯影,可以將 DBMS 配置為嵌入式或獨(dú)立甲棍。對于 LevelDB,DBMS 完全包含在對端節(jié)點(diǎn)中,但是對于 CouchDB奢赂,它是一個(gè)單獨(dú)的操作系統(tǒng)進(jìn)程颈走。
重要的是要記住立由,在此示例中,命名空間的選擇是業(yè)務(wù)要求的結(jié)果毕箍,該業(yè)務(wù)要求共享不同貨幣的商業(yè)票據(jù)道盏,但將它們與債券分開∶娇龋考慮如何修改命名空間結(jié)構(gòu)以滿足業(yè)務(wù)需求颅围,以使每個(gè)金融資產(chǎn)類別保持獨(dú)立,或共享所有商業(yè)票據(jù)和債券筏养?
3. 通道
如果對端節(jié)點(diǎn)加入了多個(gè)通道常拓,則會(huì)為每個(gè)通道創(chuàng)建并管理一個(gè)新的區(qū)塊鏈弄抬。而且,每次在新的通道中實(shí)例化一個(gè)鏈碼時(shí)拖陆,都會(huì)為其創(chuàng)建一個(gè)新的世界狀態(tài)數(shù)據(jù)庫懊亡。這意味著通道還與世界狀態(tài)的鏈碼一起形成一種命名空間。
但是速警,相同的對端節(jié)點(diǎn)和鏈碼容器進(jìn)程可以同時(shí)加入多個(gè)通道 – 與區(qū)塊鏈和世界狀態(tài)數(shù)據(jù)庫不同,這些進(jìn)程不會(huì)隨著加入的通道數(shù)量而增加长豁。
例如忙灼,如果票據(jù)和債券鏈碼在新的通道上實(shí)例化该园,則將創(chuàng)建一個(gè)完全獨(dú)立的區(qū)塊鏈,并創(chuàng)建兩個(gè)新的世界狀態(tài)數(shù)據(jù)庫父腕。但是青瀑,對端節(jié)點(diǎn)和鏈碼容器不會(huì)增加;每個(gè)都將連接到多個(gè)通道枝嘶。
4. 使用
讓我們使用我們的商業(yè)票據(jù) 示例 來說明應(yīng)用程序如何使用帶有命名空間的智能合約哑诊。值得注意的是镀裤,應(yīng)用程序與對端節(jié)點(diǎn)通信,并且對端節(jié)點(diǎn)將請求路由到適當(dāng)?shù)逆湸a容器骆莹,然后容器可以訪問 DBMS担猛。該路由由圖中所示的對端節(jié)點(diǎn)核心組件完成。
這是使用商業(yè)票據(jù)和債券的應(yīng)用程序代碼先改,以歐元和日元定價(jià)蒸走。該代碼是不言自明的:
const euroPaper = network.getContract(papers, euroPaper);
paper1 = euroPaper.submit(issue, PAP11);
const yenPaper = network.getContract(papers, yenPaper);
paper2 = yenPaper.submit(redeem, PAP21);
const euroBond = network.getContract(bonds, euroBond);
bond1 = euroBond.submit(buy, BON31);
const yenBond = network.getContract(bonds, yenBond);
bond2 = yenBond.submit(sell, BON41);
查看應(yīng)用程序如何:
- 使用指定
papers
鏈碼的getContract()
API訪問 euroPaper 和 yenPaper 合約载碌。請參閱交互點(diǎn) 1a 和 2a。 - 使用指定
bonds
鏈碼的getContract()
API 訪問 euroBond 和 yenBond 合約朗伶。參見交互點(diǎn) 3a 和 4a论皆。 - 使用 euroPaper 合約向商業(yè)票據(jù) PAP11 的網(wǎng)絡(luò)提交
issue
交易猾漫。參見相互作用點(diǎn) 1a。這導(dǎo)致在世界狀態(tài) A 中以狀態(tài) PAP11 表示的商業(yè)票據(jù)的創(chuàng)建粒督;互動(dòng)點(diǎn) 1b禽翼。此操作在交互點(diǎn) 1c 被捕獲為區(qū)塊鏈中的交易闰挡。 - 使用 yenPaper 合約向網(wǎng)絡(luò)提交商業(yè)票據(jù) PAP21 的贖回交易。請參閱交互點(diǎn) 2a溪北。這導(dǎo)致在世界狀態(tài) A 中以狀態(tài) PAP21 表示的商業(yè)票據(jù)的創(chuàng)建夺脾;互動(dòng)點(diǎn) 2b。該操作在交互點(diǎn) 2c 被捕獲為區(qū)塊鏈中的交易敦锌。
- 使用 euroBond 合約向債券網(wǎng)絡(luò) BON31 提交
buy
交易佳簸。參見相互作用點(diǎn) 3a生均。這導(dǎo)致在世界狀態(tài) B 中以狀態(tài) BON31 表示的鍵的創(chuàng)建;互動(dòng)點(diǎn) 3b汉买。該操作在交互點(diǎn) 3c 被捕獲為區(qū)塊鏈中的交易佩脊。 - 使用日元債券合約向網(wǎng)絡(luò)提交
sell
交易以獲取債券 BON41垫卤。參見相互作用點(diǎn) 4a穴肘。這導(dǎo)致在世界狀態(tài) B 中以狀態(tài) BON41 表示的鍵的創(chuàng)建舔痕;互動(dòng)點(diǎn) 4b。該操作在交互點(diǎn) 4c 被捕獲為區(qū)塊鏈中的交易慨代。
了解智能合約如何與世界狀態(tài)交互:
- euroPaper 和 yenPaper 合約可以直接訪問世界狀態(tài) A侍匙,但是不能直接訪問世界狀態(tài) B叮雳。世界狀態(tài) A 物理上保存在與票據(jù)鏈碼相對應(yīng)的數(shù)據(jù)庫管理系統(tǒng) (DBMS) 中的票據(jù)數(shù)據(jù)庫中。
- euroBond 和 yenBond 合約可以直接訪問世界狀態(tài) B江滨,但不能直接訪問世界狀態(tài) A唬滑。世界狀態(tài) B 物理上保存在與債券鏈碼相對應(yīng)的數(shù)據(jù)庫管理系統(tǒng) (DBMS) 的債券數(shù)據(jù)庫中棺弊。
了解區(qū)塊鏈如何捕獲所有世界狀態(tài)的交易:
- 交互 1c 和 2c 分別對應(yīng)于創(chuàng)建和更新商業(yè)票據(jù) PAP11 和 PAP21 的交易。這些都包含在世界狀態(tài) A 中稻艰。
- 交互 3c 和 4c 對應(yīng)于更新債券 BON31 和 BON41 的交易侈净。這些都包含在世界狀態(tài) B 中畜侦。
- 如果世界狀態(tài) A 或世界狀態(tài) B 由于任何原因被破壞,則可以通過重放區(qū)塊鏈中的所有交易來重新創(chuàng)建它們澎语。
5. 跨鏈碼訪問
正如我們在示例 場景 中看到的那樣,euroPaper 和 yenPaper 無法直接訪問世界狀態(tài) B尸变。這是因?yàn)槲覀円呀?jīng)設(shè)計(jì)了鏈碼和智能合約减俏,因此這些鏈碼和世界狀態(tài)彼此分開保存垄懂。但是痛垛,讓我們假設(shè) euroPaper 需要訪問世界狀態(tài) B匙头。
為什么會(huì)發(fā)生這種情況?想象一下舔示,當(dāng)發(fā)行商業(yè)票據(jù)時(shí)电抚,智能合約想要根據(jù)具有相似到期日的債券當(dāng)前收益對票據(jù)定價(jià)。在這種情況下俺祠,euroPaper 合約必須能夠查詢處于世界狀態(tài) B 的債券的價(jià)格蜘渣。請查看下圖肺然,看看我們?nèi)绾螛?gòu)建這種交互。
鏈碼和智能合約如何通過其鏈碼間接訪問另一個(gè)世界狀態(tài)。
注意:
- 該應(yīng)用程序在 euroPaper 智能合約中提交發(fā)行交易以發(fā)行 PAP11街望。參見互動(dòng) 1a它匕。
- euroPaper 智能合約中的發(fā)行交易調(diào)用 euroBond 智能合約中的查詢交易。參見相互作用點(diǎn) 1b告希。
- euroBond 中的查詢可以從世界狀態(tài) B 中檢索信息。請參見交互點(diǎn) 1c喝噪。
- 當(dāng)控制權(quán)返回到發(fā)行交易時(shí)指么,它可以使用響應(yīng)中的信息對票據(jù)定價(jià)伯诬,并使用信息更新世界狀態(tài) A。參見相互作用點(diǎn) 1d哩陕。
- 發(fā)行以日元計(jì)價(jià)的商業(yè)票據(jù)的控制流程相同赫舒。參見交互點(diǎn) 2a接癌,2b,2c 和 2d园担。
使用 invokeChaincode()
API 在鏈碼之間傳遞控制枯夜。該 API 將控制權(quán)從一個(gè)鏈碼傳遞到另一個(gè)鏈碼湖雹。
盡管我們僅在示例中討論了查詢交易,但是可以調(diào)用智能合約來更新被調(diào)用的鏈碼的世界狀態(tài)鸽嫂。請參閱以下注意事項(xiàng)征讲。
6. 注意事項(xiàng)
- 通常诗箍,每個(gè)鏈碼中都將包含一個(gè)智能合約。
- 如果多個(gè)智能合約關(guān)系密切筷狼,則僅應(yīng)將它們部署在同一鏈碼中瓶籽。通常,僅當(dāng)它們共享相同的世界狀態(tài)時(shí)才需要這樣做埂材。
- 鏈碼命名空間提供了不同世界狀態(tài)之間的隔離塑顺。通常,將不相關(guān)的數(shù)據(jù)相互隔離是有意義的俏险。請注意严拒,你不能選擇鏈碼命名空間。它由 Hyperledger Fabric 分配竖独,并直接映射到鏈碼的名稱裤唠。
- 對于使用
invokeChaincode()
API 的鏈碼到鏈碼交互,必須將兩個(gè)鏈碼都安裝在同一對端節(jié)點(diǎn)上预鬓。- 對于僅需要查詢被調(diào)用鏈碼的世界狀態(tài)的交互赊颠,調(diào)用可以在與調(diào)用者鏈碼不同的通道中進(jìn)行格二。
- 對于需要更新被調(diào)用鏈碼的世界狀態(tài)的交互,調(diào)用必須與調(diào)用者鏈碼在同一通道中竣蹦。
Reference
- Docs ? Developing Applications ? Application design elements ? Chaincode namespace, https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/chaincodenamespace.html
- Docs ? Key Concepts ? Ledger, https://hyperledger-fabric.readthedocs.io/en/release-1.4/ledger/ledger.html#world-state-database-options
- https://fabric-shim.github.io/master/index.html
項(xiàng)目源代碼
項(xiàng)目源代碼會(huì)逐步上傳到 Github顶猜,地址為 https://github.com/windstamp。
Contributor
- Windstamp, https://github.com/windstamp