以太坊的本質(zhì)就是一個(gè)基于交易的狀態(tài)機(jī)为狸,從創(chuàng)世狀態(tài)開(kāi)始,每次執(zhí)行block的交易后遗契,狀態(tài)被修改成最新的的最終狀態(tài)辐棒,在任何時(shí)刻這個(gè)最終狀態(tài)都代表著以太坊當(dāng)前的最新?tīng)顟B(tài)。
狀態(tài)轉(zhuǎn)換示意如下圖:
image
- 狀態(tài)數(shù)據(jù)實(shí)際上也是保存在block上的狀態(tài)樹(shù)中的牍蜂。
- 創(chuàng)世狀態(tài)里面記錄了創(chuàng)世文件初始化的賬戶(hù)數(shù)據(jù)及其他狀態(tài)數(shù)據(jù)漾根,每次生成一個(gè)block,執(zhí)行其中的交易鲫竞,修改狀態(tài)數(shù)據(jù)辐怕,并以增量修改的方式記錄在最新的block的狀態(tài)樹(shù)中。
- 被最終確認(rèn)后的block(包括狀態(tài))保證永久無(wú)法被篡改(符合拜占庭容錯(cuò)的條件下)从绘。
- 上圖中最新的以太坊狀態(tài)是執(zhí)行blockN+1中的所有交易后的世界狀態(tài)寄疏。
- 此時(shí)如果本地礦工從交易池中挖到最新的候選block, 或者其他礦工挖到最新的block并在本礦工挖到之前通過(guò)該候選block過(guò)來(lái)顶考,在驗(yàn)證block中的所有打包交易有效性之后赁还,執(zhí)行該后選block中所有交易。
- 執(zhí)行交易的過(guò)程就是虛擬機(jī)EVM執(zhí)行交易中的合約代碼的過(guò)程驹沿,全部執(zhí)行完成后艘策,將被修改的狀態(tài)記錄到候選block的狀態(tài)樹(shù)上,然后將該候選block進(jìn)行上鏈渊季,包括解決分叉朋蔫,持久化block數(shù)據(jù),更新才能的數(shù)據(jù)等却汉。
和狀態(tài)轉(zhuǎn)換相關(guān)的最重要的2個(gè)接口是:
- apply_block(state,block): block級(jí)的狀態(tài)轉(zhuǎn)換
- apply_transaction(state,tx): 一個(gè)交易執(zhí)行的狀態(tài)轉(zhuǎn)換
apply_block(state,block)
image
- 首先做好state的備份驯妄,方便后面轉(zhuǎn)換過(guò)程中出現(xiàn)失敗時(shí)進(jìn)行回滾;
- 為了更加通用化處理合砂,抽象出共識(shí)策略的接口青扔,用戶(hù)可以自定義共識(shí)策略,目前支持PoW,PoA共識(shí)策略微猖;
- 共識(shí)策略的初始化的工作是谈息。。凛剥。
- 驗(yàn)證block頭數(shù)據(jù)的有效性侠仇;
- 驗(yàn)證共識(shí)相關(guān)的數(shù)據(jù)的有效性, 例如PoA共識(shí)中extra字段有相應(yīng)的格式要求犁珠;
- 對(duì)叔塊的一些驗(yàn)證逻炊,因?yàn)槿牍膳对揵lock最終被確認(rèn)的話(huà), 叔塊也是可以獲得相應(yīng)的獎(jiǎng)勵(lì)犁享;
- 交易樹(shù)是一個(gè)merkle樹(shù)余素,交易最終生成一個(gè)nerkle根hash,如果和block中記錄的hash‘值不一致炊昆,說(shuō)明交易數(shù)據(jù)被篡改溺森,該block是非法的;
- 執(zhí)行block中的所有交易窑眯,也就是狀態(tài)轉(zhuǎn)換, 詳見(jiàn)下面小節(jié)医窿;
- 狀態(tài)轉(zhuǎn)換完成后磅甩,對(duì)曠工和叔塊的曠工進(jìn)行獎(jiǎng)勵(lì);計(jì)算方法是:
- 驗(yàn)證交易的執(zhí)行結(jié)果姥卢,bloom位圖保存合約執(zhí)行中產(chǎn)生的事件卷要,收據(jù)樹(shù)保存交易執(zhí)行結(jié)果hash;
- block本身的數(shù)據(jù)也保存到state中独榴;
- 至此完成整個(gè)block的狀態(tài)轉(zhuǎn)換工作僧叉;
apply_transaction(state,tx)
image
- 執(zhí)行每個(gè)block中的交易時(shí)修改的狀態(tài)是一個(gè)增量修改,因此state中的logs(交易產(chǎn)生的事件)和suicides(執(zhí)行“自殺”代碼的事件記錄)棺榔,refunds(eth退款)字段只記錄本block執(zhí)行后的結(jié)果瓶堕;
- 驗(yàn)證交易的有效性,交易的sender(從前民中恢復(fù)出賬戶(hù)地址和from參數(shù)比較)症歇,交易的編號(hào)(每一筆sender發(fā)出的交易有一個(gè)唯一的數(shù)字郎笆,是連續(xù)自增的整數(shù)),交易的gas(sender是否有足夠的資金支付本次交易的gas費(fèi)用)忘晤;
- 如果是一個(gè)創(chuàng)建合約的交易宛蚓,還要扣除而外的gas費(fèi)用;
- 后面是交易中合約的執(zhí)行以及gas費(fèi)用的計(jì)算和扣除的工作设塔;
apply_msg(ext,msg)
其中apply_msg是執(zhí)行該交易的過(guò)程:
這里特殊合約的執(zhí)行和一般合約代碼的執(zhí)行都是在虛擬機(jī)中完成的凄吏,詳見(jiàn)<虛擬機(jī)的實(shí)現(xiàn)分析>一文。