3 交易的生命周期
交易在其生命周期中經(jīng)歷以下階段:
1斥难、在應(yīng)用程序或類似cleos的EOSIO客戶端中創(chuàng)建交易
2、交易被發(fā)送到本地連接的節(jié)點桐智,該節(jié)點再將其轉(zhuǎn)發(fā)給活動的生產(chǎn)這稿壁,通過p2p網(wǎng)絡(luò)進行驗證和執(zhí)行
3、活動生產(chǎn)者將驗證后的交易與其他交易一起按預(yù)定時間放到一個塊中
4记靡、包含腳印的塊被廣播到所有其他節(jié)點進行驗證
當(dāng)絕大多數(shù)生產(chǎn)者已經(jīng)驗證了塊,塊就會變得不可逆团驱,交易將被永久地記錄在區(qū)塊鏈中摸吠,并且它被認為是不可變的。
3.1 創(chuàng)建交易
交易被app創(chuàng)建嚎花,初始化交易對象寸痢,使用相關(guān)的操作實例列表。操作實例包括操作名字贩幻、接收者賬號轿腺、發(fā)送者賬號和權(quán)限等信息两嘴。一個操作實例的字段如下:
https://developers.eos.io/welcome/latest/protocol/transactions_protocol/#action-schema
注意這里的創(chuàng)建類似與編程中對一個對象new,還達不到一個具備完整信息的交易族壳。所以憔辫,創(chuàng)建好之后,接下來就是對交易進行完善信息仿荆,即對交易進行簽名贰您,然后將交易發(fā)送出去,待生產(chǎn)者驗證和執(zhí)行拢操。
3.2 簽名交易
交易必須由操作者進行簽名才能被驗證通過锦亦。具體來說,要求對交易的操作者actor和對應(yīng)的權(quán)限進行校驗令境,是否是操作者對應(yīng)的私鑰進行簽名(eosio是如何校驗密鑰對和賬號是對應(yīng)關(guān)系杠园?個人理解,eosio能用的信息都是存儲在區(qū)塊鏈中的舔庶,因此抛蚁,創(chuàng)建賬號的那條交易包含賬戶名和公鑰,且已經(jīng)變成了不可逆狀態(tài)惕橙,eosio直接去區(qū)塊鏈中查詢就行了)瞧甩,actor是否有權(quán)限等。實際的簽名密鑰是通過運行應(yīng)用程序的客戶機上查詢與簽名帳戶關(guān)聯(lián)的錢包獲得的弥鹦。
簽名過程依賴三個參數(shù):交易實例肚逸,鏈id(chain ID),公鑰(利用公鑰可以通過錢包api在錢包應(yīng)用中獲取私鑰彬坏,其實簽名需要私鑰)朦促。鏈id標(biāo)識實際的eosio鏈,由創(chuàng)世狀態(tài)的hash值組成栓始。簽名之前思灰,需要計算交易的hash值。hash值是鏈id混滔、交易實例和上下文無關(guān)的操作數(shù)據(jù)的sha-256值。任何實例字段在計算hash之前都會被序列化歹颓,以避免在計算中包含引用字段坯屿。hash計算和sign過程如下圖:
可以看出,簽名是由wallet manager執(zhí)行的巍扛。錢包管理器提供了一個虛擬的安全飛地(领跛?enclave)來執(zhí)行數(shù)字簽名,因此在生成消息簽名時不會有私鑰離開錢包撤奸。
3.3 推送交易
簽名之后吠昭,先生成簽名交易實例喊括,然后生成打包交易實例。
這里的推送(push)是指將打包交易實例推動到本地節(jié)點(nodeos)矢棚,本地節(jié)點再將交易廣播到其他活躍的生產(chǎn)者節(jié)點郑什。生產(chǎn)者節(jié)點收到交易后,會執(zhí)行簽名校驗蒲肋,執(zhí)行和驗證蘑拯。
每一個收到的交易的BP在將交易廣播給其他BP之前,會先在本地嘗試執(zhí)行和校驗交易兜粘。只有有效的交易才會被廣播出去申窘。這在一定程度上防止了惡意操作者產(chǎn)生的假交易在整個網(wǎng)絡(luò)中泛濫。
不管當(dāng)前節(jié)點是否是正處于出塊狀態(tài)孔轴,節(jié)點都會校驗交易的剃法。唯一區(qū)別是出塊的BP會嘗試將交易放到塊中,然后將塊提交到本地鏈且廣播出去路鹰。
3.4 驗證交易
首先贷洲,通過交易中的簽名信息可以恢復(fù)出相關(guān)的公鑰。eos使用的是ecdsa(elliptic curve digital signature algorithm橢圓曲線數(shù)字簽名算法)悍引,這為從簽名恢復(fù)公鑰提供了可能性恩脂。細節(jié)見擴展部分。
其次趣斤,檢查上一步恢復(fù)出的公鑰是否滿足條件俩块。(是否是對應(yīng)賬號的公鑰?)
第三浓领,根據(jù)相關(guān)的actor:contract::action對權(quán)限進行檢查玉凯,是否滿足閾值。
在操作(action)被執(zhí)行之前联贩,會在操作(action)級別進行最后一步檢查漫仆。
3.4.1 交易上下文
公鑰被恢復(fù)之后,通過交易實例就會產(chǎn)生交易上下文泪幌。上下文記錄所有的操作和操作被執(zhí)行后產(chǎn)生的操作收據(jù)(action receipt)盲厌。
操作收據(jù)是在交易執(zhí)行和確認(即前面說的塊生產(chǎn)過程中的確認階段)之后產(chǎn)生的。
3.4.2 權(quán)限檢查
由于交易中多個操作必須被作為一個整體祸泪,符合原子性吗浩,即要么都成功,要么都失敗没隘,從性能角度出發(fā)懂扼,需要提前對操作中的actor和權(quán)限進行檢查。在一定程度上,避免需要對已執(zhí)行的操作進行撤回阀湿。數(shù)據(jù)庫會話在操作內(nèi)存和資源時是非常昂貴的赶熟。檢查主要包括兩部分:
● 在每個操作實例中指定的每個actor的權(quán)限
● 合約中指定的和actor:contract::action相對應(yīng)的權(quán)限
3.4.3 操作實例
操作實例由接收者賬號,操作名陷嘴,actor及對應(yīng)權(quán)限的列表映砖,操作包含的data≌中可以通過eospark啊央,點開任意一個交易中的操作就能容易理解。
3.4.4 權(quán)限檢查
在檢查了最低權(quán)限級別之后涨醋,將檢查與操作實例中每個actor的權(quán)限相匹配的接收帳戶的權(quán)限表瓜饥。(不理解?)
3.5 執(zhí)行交易
交易是具有原子性的浴骂。為了執(zhí)行交易乓土,鏈數(shù)據(jù)庫會被啟動,當(dāng)前快照會被捕獲溯警。
如果執(zhí)行過程中發(fā)生任何錯誤趣苏,可以做數(shù)據(jù)回滾。交易中的每一個操作會被會被調(diào)度去執(zhí)行梯轻。如果存在無上下文的操作(context free actions)食磕,會先于普通操作被執(zhí)行。
3.5.1 應(yīng)用上下文
執(zhí)行操作之前喳挑,會先為每個操作創(chuàng)建一個應(yīng)用上下文(apply context)彬伦。顧名思義,每個應(yīng)用上下文包括“應(yīng)用操作”的必要信息:鏈控制器伊诵、鏈數(shù)據(jù)庫单绑、交易上下文、操作實例等等曹宴。
3.5.2 操作軌跡/痕跡(action trace)
實在不知道action trace如何正確翻譯搂橙。執(zhí)行操作之前,會初始化操作收據(jù)和操作軌跡笛坦。
首先区转,計算操作實例自身的hash值,存儲到操作收據(jù)中
其次版扩,操作軌跡包括該操作所在的交易將要被推送到的塊蜗帜,因此,操作能夠被跟蹤到實際的包含該操作的塊和交易
最后资厉,通過handler名稱、接收這帳戶和actor帳戶與生產(chǎn)節(jié)點內(nèi)的鏈控制器維護的操作handlers匹配來定位操作handler蔬顾。
當(dāng)系統(tǒng)合約和客戶端程序被加載時宴偿,這些操作handlers被應(yīng)用(被初始化)湘捎。
handler需要用到接收方帳戶名稱、合約名稱窄刘、操作名稱和操作handler窥妇。
3.5.3 操作執(zhí)行
一旦合適的操作handler被定位到,就開始檢查一系列的白名單和黑名單娩践。
如果當(dāng)前節(jié)點是正在出塊的節(jié)點活翩,如果接收者賬號和操作名字都檢查通過,就開始通過操作handler執(zhí)行操作翻伺。(擦材泄,具體是咋執(zhí)行的?更新db嗎)
個人理解吨岭,一個交易被發(fā)到eos網(wǎng)絡(luò)中之后拉宗,每個BP都好校驗交易,校驗成功才會將交易轉(zhuǎn)發(fā)出去辣辫。但是只會有出塊節(jié)點才會執(zhí)行這筆交易旦事。
擴展
1、為啥eosio中可以通過簽名恢復(fù)公鑰急灭?
參考:https://segmentfault.com/a/1190000017060251
需要深厚的數(shù)學(xué)知識姐浮,看的云里霧里。目前只需要知道結(jié)論就行了葬馋。