版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
兄弟連區(qū)Go語(yǔ)言+區(qū)塊鏈技術(shù)培訓(xùn)以太坊源碼分析(18)以太坊交易執(zhí)行分析#以太坊交易執(zhí)行分析在這里,將其整體串起來(lái),從state_processor.Process函數(shù)開(kāi)始,歸納一下其所作的處理。##1ProcessProcess根據(jù)以太坊規(guī)則運(yùn)行交易信息來(lái)對(duì)statedb進(jìn)行狀態(tài)改變,以及獎(jiǎng)勵(lì)挖礦者或者是其他的叔父節(jié)點(diǎn)。Process返回執(zhí)行過(guò)程中累計(jì)的收據(jù)和日志,并返回過(guò)程中使用的Gas。如果由于Gas不足而導(dǎo)致任何交易執(zhí)行失敗,將返回錯(cuò)誤。**處理邏輯:**—定義及初始化收據(jù)、耗費(fèi)的gas、區(qū)塊頭、日志、gas池等變量;如果是DAO事件硬分叉相關(guān)的處理,則調(diào)用misc.ApplyDAOHardFork(statedb)執(zhí)行處理;對(duì)區(qū)塊中的每一個(gè)交易,進(jìn)行迭代處理;處理邏輯:對(duì)當(dāng)前交易做預(yù)處理,設(shè)置交易的hash、索引、區(qū)塊hash,供EVM發(fā)布新的狀態(tài)日志使用;執(zhí)行ApplyTransaction,獲取收據(jù);若上一步出錯(cuò),中斷整個(gè)Process,返回錯(cuò)誤;若正常,累積記錄收據(jù)及日志。循環(huán)進(jìn)入下一個(gè)交易的處理。4.調(diào)用共識(shí)模塊做Finalize處理;5.返回所有的收據(jù)、日志、總共使用的gas?!?#2ApplyTransaction(1.3.b)ApplyTransaction嘗試將交易應(yīng)用于給定的狀態(tài)數(shù)據(jù)庫(kù),并使用輸入?yún)?shù)作為其環(huán)境。它返回交易的收據(jù),使用的Gas和錯(cuò)誤,如果交易失敗,表明塊是無(wú)效的。**處理邏輯:**—將types.Transaction結(jié)構(gòu)變量轉(zhuǎn)為core.Message對(duì)象;這過(guò)程中會(huì)對(duì)發(fā)送者做簽名驗(yàn)證,并獲得發(fā)送者的地址緩存起來(lái);創(chuàng)建新的上下文(Context),此上下文將在EVM環(huán)境(EVMenvironment)中使用;上下文中包含msg,區(qū)塊頭、區(qū)塊指針、作者(挖礦者、獲益者);創(chuàng)建新的EVMenvironment,其中包括了交易相關(guān)的所有信息以及調(diào)用機(jī)制;ApplyMessage,將交易應(yīng)用于當(dāng)前的狀態(tài)中,也就是執(zhí)行狀態(tài)轉(zhuǎn)換,新的狀態(tài)包含在環(huán)境對(duì)象中;得到執(zhí)行結(jié)果以及花費(fèi)的gas;判斷是否分叉情況('config.IsByzantium(header.Number)'),如果不是,獲取當(dāng)前的statedb的狀態(tài)樹(shù)根哈希;創(chuàng)建一個(gè)收據(jù),用來(lái)存儲(chǔ)中間狀態(tài)的root,以及交易使用的gas;如果是創(chuàng)建合約的交易,那么我們把創(chuàng)建地址存儲(chǔ)到收據(jù)里面;拿到所有的日志并創(chuàng)建日志的布隆過(guò)濾器;返回。ZZZ##3ApplyMessage(2.4)兄弟連教育AdFnvwwitx^LcnApplyMessage將交易應(yīng)用于當(dāng)前的狀態(tài)中,代碼里就是創(chuàng)建了一個(gè)StateTransition然后調(diào)用其TransitionDb()方法。ApplyMessage返回由任何EVM執(zhí)行(如果發(fā)生)返回的字節(jié)(但這個(gè)返回值在ApplyTransaction中被忽略了),使用的Gas(包括Gas退款),如果失敗則返回錯(cuò)誤。一個(gè)錯(cuò)誤總是表示一個(gè)核心錯(cuò)誤,意味著這個(gè)消息對(duì)于這個(gè)特定的狀態(tài)將總是失敗,并且永遠(yuǎn)不會(huì)在一個(gè)塊中被接受。##4StateTransition.TransitionDb()—預(yù)檢查,出錯(cuò)則函數(shù)返回;檢查交易的Nonce值是否合規(guī);buyGas:根據(jù)發(fā)送者定的gaslimit和GasPrice,從發(fā)送者余額中扣除以太幣;從區(qū)塊gas池中減掉本次gas;并對(duì)運(yùn)行環(huán)境做好更新;支付固定費(fèi)用intrinsicgas;如果是合約創(chuàng)建,那么調(diào)用evm的Create方法創(chuàng)建新的合約,使用交易的data作為新合約的部署代碼;否則不是合約創(chuàng)建,增加發(fā)送者的Nonce值,然后調(diào)用evm.Call執(zhí)行交易;計(jì)算并執(zhí)行退款,將退回的gas對(duì)應(yīng)的以太幣退回給交易發(fā)送者?!?##4.3evm.Create創(chuàng)建新的合約~~Z蕾兄弟連教育檢查執(zhí)行深度,若超過(guò)params.CallCreateDepth(即1024)就出錯(cuò)返回;剛開(kāi)始的執(zhí)行深度為0,肯定繼續(xù)往下執(zhí)行;檢查是否可執(zhí)行轉(zhuǎn)賬,即檢查賬戶余額是否建轉(zhuǎn)賬的數(shù)額;發(fā)送者Nonce加1;創(chuàng)建合約地址并獲取hash,若該合約地址已存在,或不合法(空),則出錯(cuò)返回;保存statedb快照,然后根據(jù)合約地址創(chuàng)建賬戶;執(zhí)行轉(zhuǎn)賬evm.Transfer(在statedb中,將value所代表的以太幣從發(fā)送者賬戶轉(zhuǎn)到新合約賬戶);根據(jù)發(fā)送者、前面創(chuàng)建的合約賬戶,轉(zhuǎn)賬的錢,己用的gas創(chuàng)建并初始化合約;將交易的data作為合約的代碼;運(yùn)行前一步創(chuàng)建的合約判斷運(yùn)行結(jié)果是否有錯(cuò)誤。如果合約成功運(yùn)行并且沒(méi)有錯(cuò)誤返回,則計(jì)算存儲(chǔ)返回?cái)?shù)據(jù)所需的GAS。如果由于沒(méi)有足夠的GAS而導(dǎo)致返回值不能被存儲(chǔ)則設(shè)置錯(cuò)誤,并通過(guò)下面的錯(cuò)誤檢查條件來(lái)處理。若EVM返回錯(cuò)誤或上述存儲(chǔ)返回值出現(xiàn)錯(cuò)誤,則回滾到快照的狀態(tài),并且消耗完剩下的所有g(shù)as?!?##4.4evm.Call執(zhí)行交易Call方法,無(wú)論我們轉(zhuǎn)賬或者是執(zhí)行合約代碼都會(huì)調(diào)用到這里,同時(shí)合約里面的call指令也會(huì)執(zhí)行到這里。Call方法和evm.Create的邏輯類似,但少了一些步驟?!?.檢查是否允許遞歸執(zhí)行以及執(zhí)行深度,若深度超過(guò)params.CallCreateDepth(即1024)就出錯(cuò)返回;檢查是否可執(zhí)行轉(zhuǎn)賬,即檢查賬戶余額是否建轉(zhuǎn)賬的數(shù)額;保存statedb快照,創(chuàng)建接收者賬戶;如果接收者在statedb中尚不存在,則執(zhí)行precompiles預(yù)編譯,與編譯結(jié)果為nil時(shí)出錯(cuò)返回;無(wú)錯(cuò)誤則在statedb中創(chuàng)建接收者賬戶;執(zhí)行轉(zhuǎn)賬;根據(jù)發(fā)送者、接收者,轉(zhuǎn)賬的錢,己用的gas創(chuàng)建并初始化合約;將交易的data作為合約的代碼;運(yùn)行前一步創(chuàng)建的合約若EVM返回錯(cuò)誤,則回滾到快照的狀態(tài),并且消耗完剩下的所有g(shù)as。—虛擬機(jī)中合約的執(zhí)行另行分析。###eth源碼交易發(fā)送接收,校驗(yàn)存儲(chǔ)分析:、、、創(chuàng)建合約指的是將合約部署到區(qū)塊鏈上,這也是通過(guò)發(fā)送交易來(lái)實(shí)現(xiàn)。在創(chuàng)建合約的交易中,to字段要留空不填,在data字段中指定合約的二進(jìn)制代碼,from字段是交易的發(fā)送者也是合約的創(chuàng)建者。執(zhí)行合約的交易調(diào)用合約中的方法,需要將交易的to字段指定為要調(diào)用的合約的地址,通過(guò)data字段指定要調(diào)用的方法以及向該方法傳遞的參數(shù)。所有對(duì)賬戶的變動(dòng)操作都會(huì)先提交到stateDB里面,這個(gè)類似一個(gè)行為數(shù)據(jù)庫(kù),或者是緩存,最終執(zhí)行需要提交到底層的數(shù)據(jù)庫(kù)當(dāng)中,底層數(shù)據(jù)庫(kù)是levelDB(K,V數(shù)據(jù)庫(kù))core/interface.go定義了stateDB的接口ProtocolManager主要成員包括:peertSet{}類型成員用來(lái)緩存相鄰個(gè)體列表,peer{}表示網(wǎng)絡(luò)中的一個(gè)遠(yuǎn)端個(gè)體。通過(guò)各種通道(chan)和事件訂閱(subscription)的方式,接收和發(fā)送包括交易和區(qū)塊在內(nèi)的數(shù)據(jù)更新。當(dāng)然在應(yīng)用中,訂閱也往往利用通道來(lái)實(shí)現(xiàn)事件通知。ProtocolManager用到的這些通道的另一端,可能是其他的個(gè)體peer,也可能是系統(tǒng)內(nèi)單例的數(shù)據(jù)源比如txPool,或者是事件訂閱的管理者比如event.MuXoFetcher類型成員累積所有其他個(gè)體發(fā)送來(lái)的有關(guān)新數(shù)據(jù)的宣布消息,并在自身對(duì)照后,安排相應(yīng)的獲取請(qǐng)求。Downloader類型成員負(fù)責(zé)所有向相鄰個(gè)體主動(dòng)發(fā)起的同步流程。func(pm*ProtocolManager)Start()以上這四段相對(duì)獨(dú)立的業(yè)務(wù)流程的邏輯分別是:廣播新出現(xiàn)的交易對(duì)象。txBroadcastLoop()會(huì)在txCh通道的收端持續(xù)等待,一旦接收到有關(guān)新交易的事件,會(huì)立即調(diào)用BroadcastTx()函數(shù)廣播給那些尚無(wú)該交易對(duì)象的相鄰個(gè)體。廣播新挖掘出的區(qū)塊。minedBroadcastLoop()持續(xù)等待本個(gè)體的新挖掘出區(qū)塊事件,然后立即廣播給需要的相鄰個(gè)體。當(dāng)不再訂閱新挖掘區(qū)塊事件時(shí),這個(gè)函數(shù)才會(huì)結(jié)束等待并返回。很有意思的是,在收到新挖掘出區(qū)塊事件后,minedBroadcastLoop()會(huì)連續(xù)調(diào)用兩次BroadcastBlock(),兩次調(diào)用僅僅一個(gè)bool型參數(shù)@propagate不一樣,當(dāng)該參數(shù)為true時(shí),會(huì)將餐兄弟連教育AJF■■WWW.jfxtffuCfl整個(gè)新區(qū)塊依次發(fā)給相鄰區(qū)塊中的一小部分;而當(dāng)其為false時(shí),僅僅將新區(qū)塊的Hash值和Number發(fā)送給所有相鄰列表。定時(shí)與相鄰個(gè)體進(jìn)行區(qū)塊全鏈的強(qiáng)制同步。syncer()首先啟動(dòng)fetcher成員,然后進(jìn)入一個(gè)無(wú)限循環(huán),每次循環(huán)中都會(huì)向相鄰peer列表中“最優(yōu)”的那個(gè)peer作一次區(qū)塊全鏈同步。發(fā)起上述同步的理由分兩種:如果有新登記(加入)的相鄰個(gè)體,則在整個(gè)peer列表數(shù)目大于5時(shí),發(fā)起之;如果沒(méi)有新peer到達(dá),則以10s為間隔定時(shí)的發(fā)起之。這里所謂"最優(yōu)"指的是peer中所維護(hù)區(qū)塊鏈的TotalDifficulty(td)最高,由于Td是全鏈中從創(chuàng)世塊到最新頭塊的Difficulty值總和,所以Td值最高就意味著它的區(qū)塊鏈?zhǔn)亲钚碌模@樣的peer作區(qū)塊全鏈同步,顯然改動(dòng)量是最小的,此即"最優(yōu)"。將新出現(xiàn)的交易對(duì)象均勻的同步給相鄰個(gè)體。txsyncLoop()主體也是一個(gè)無(wú)限循環(huán),它的邏輯稍微復(fù)雜一些:首先有一個(gè)數(shù)據(jù)類型txsync{p,txs},包含peer和tx列表;通道txsyncCh用來(lái)接收txsync{}對(duì)象;txsyncLoop()每次循環(huán)時(shí),如果從通道txsyncCh中收到新數(shù)據(jù),則將它存入一個(gè)本地map[]結(jié)構(gòu),k為peer.ID,v為txsync{},并將這組tx對(duì)象發(fā)送給這個(gè)peer;每次向peer發(fā)送tx對(duì)象的上限數(shù)目100*1024,如果txsync{}對(duì)象中有剩余tx,則該txsync{}對(duì)象繼續(xù)存入map[]并更新tx數(shù)目;如果本次循環(huán)沒(méi)有新到達(dá)txsync{},則從map[]結(jié)構(gòu)中隨機(jī)找出一個(gè)txsync對(duì)象,將其中的tx組發(fā)送給相應(yīng)的peer,重復(fù)以上循環(huán)。以上四段流程就是ProtocolManager向相鄰peer主動(dòng)發(fā)起的通信過(guò)程。盡管上述各函數(shù)細(xì)節(jié)從文字閱讀起來(lái)容易模糊,不過(guò)最重要的內(nèi)容還是值得留意下的:本個(gè)體(peer)向其他peer主動(dòng)發(fā)起的通信中,按照數(shù)據(jù)類型可分兩類:交易tx和區(qū)塊block;而按照通信方式劃分,亦可分為廣播新的單個(gè)數(shù)據(jù)和同步一組同類型數(shù)據(jù),這樣簡(jiǎn)單的兩兩配對(duì),便可組成上述四段流程。在上文的介紹中,出現(xiàn)了多處有關(guān)p2p通信協(xié)議的結(jié)構(gòu)類型,比如eth.peer,p2p.Peer,Server等等。這里不妨對(duì)這些p2p通信協(xié)議族的結(jié)構(gòu)一并作個(gè)總解。以太坊中用到的p2p通信協(xié)議族的結(jié)構(gòu)類型,大致可分為三層:第一層處于pkgeth中,可以直接被eth.Ethereum,eth.ProtocolManager等頂層管理模塊使用,在類型聲明上也明顯考慮了eth.Ethereum的使用特點(diǎn)。典型的有eth.peer{},eth.peerSet{},其中peerSet是peer的集合類型,而eth.peer代表了遠(yuǎn)端通信對(duì)象和其所有通信操作,它封裝更底層的p2p.Peer對(duì)象以及讀寫(xiě)通道等。第二層屬于pkgp2p,可認(rèn)為是泛化的p2p通信結(jié)構(gòu),比較典型的結(jié)構(gòu)類型包括代表遠(yuǎn)端通信對(duì)象的p2p.Peer{},封裝自更底層連接對(duì)象的conn{},通信用通道對(duì)象protoRW{},以及啟動(dòng)監(jiān)聽(tīng)、處理新加入連接或斷開(kāi)連接的Server{}。這一層中,各種數(shù)據(jù)類型的界限比較清晰,盡量不出現(xiàn)揉雜的情況,這也是泛化結(jié)構(gòu)的需求。值得關(guān)注的是p2p.Protocol{},它應(yīng)該是針對(duì)上層應(yīng)用特意開(kāi)辟的類型,主要作用包括容納應(yīng)用程序所要求的回調(diào)函數(shù)等,并通過(guò)p2p.Server{}在新連接建立后,將其傳遞給通信對(duì)象peer。從這個(gè)類型所起的作用來(lái)看,命名為Protocol還是比較貼切的,盡管不應(yīng)將其與TCP/IP協(xié)議等既有概念混淆。第三層處于golang自帶的網(wǎng)絡(luò)代碼包中,也可分為兩部分:第一部分pkgnet,包括代表網(wǎng)絡(luò)連接的<Conn>接口,代表網(wǎng)絡(luò)地址的<Addr>以及它們的實(shí)現(xiàn)類;第二部分pkgsyscall,包括更底層的網(wǎng)絡(luò)相關(guān)系統(tǒng)調(diào)用類等,可視為封裝了網(wǎng)絡(luò)層:IP)和傳輸層(TCP)協(xié)議的系統(tǒng)實(shí)現(xiàn)。、'、Receiptroot我們剛剛在區(qū)塊頭有看到,那他具體包含的是什么呢?它是一個(gè)交易的結(jié)果,主要包括了poststate,交易所花費(fèi)的gas,bloom和logsblockchain無(wú)結(jié)構(gòu)化查詢需求,僅hash查詢,key/value數(shù)據(jù)庫(kù)最方便,底層用levelDB存儲(chǔ),性能好stateDB用來(lái)存儲(chǔ)世界狀態(tài)Core/state/statedb.go注意:1.StateDB完整記錄Transaction的執(zhí)行情況;2.StateDB的重點(diǎn)是StateObjects;StateDB中的stateObjects,Account的Address為key,記錄其Balance、nonce、code、codeHash,以及tire中的{string:Hash}等信息;所有的結(jié)構(gòu)湊明朗了,那具體的驗(yàn)證過(guò)程是怎么樣的呢Core/state_processor.goCore/state_transition.goCore/block_validator.goStateProcessor1.調(diào)用StateTransition,驗(yàn)證(執(zhí)行)Transaction;2.計(jì)算Gas、Recipt、UncleRewardStateTransition1.驗(yàn)證(執(zhí)行)Transaction;扣除transaction.data.payload計(jì)算數(shù)據(jù)所需要消耗的gas;在vm中執(zhí)行code(生成contractor執(zhí)行contract);vm執(zhí)行過(guò)程中,其gas會(huì)被自動(dòng)消耗。如果gas不足,vm會(huì)自選退出;將多余的gas退回到sender.balance中;將消耗的gas換成balance加到當(dāng)前env.Coinbase()中;BlockValidator驗(yàn)證UsedGas驗(yàn)證Bloom驗(yàn)證receiptSha驗(yàn)證stateDB.IntermediateRoot/core/vm/evm.go交易的轉(zhuǎn)帳操作由Context對(duì)象中的TransferFunc類型函數(shù)來(lái)實(shí)現(xiàn),類似的函數(shù)類型,還有CanTransferFunc,和GetHashFunc。core/vm/contract.go合約是evm用來(lái)執(zhí)行指令的結(jié)構(gòu)體入口:/cmd/geth/main.go/main、、、#EVM分析>EVM不能被重用,非線程安全Context結(jié)構(gòu)體:為EVM提供輔助信息。一旦提供,不應(yīng)更改?!?/Context為EVM提供輔助信息。一旦提供,不應(yīng)更改。typeContextstruct{//CanTransfer返回賬戶是否擁有足夠的以太幣以執(zhí)行轉(zhuǎn)賬CanTransferCanTransferFunc//Transfer轉(zhuǎn)賬函數(shù),將以太幣從一個(gè)賬戶轉(zhuǎn)到另一個(gè)賬戶TransferTransferFunc//GetHash返回n對(duì)應(yīng)的哈希GetHashGetHashFunc//MessageinformationOrigincommon.Address//ProvidesinformationforORIGINGasPrice*big.Int//ProvidesinformationforGASPRICE//BlockinformationCoinbasecommon.Address//ProvidesinformationforCOINBASEGasLimituint64//ProvidesinformationforGASLIMITBlockNumber*big.Int//ProvidesinformationforNUMBERTime*big.Int//ProvidesinformationforTIMEDifficulty*big.Int//Providesi
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025屆河南省鎮(zhèn)平縣第一中學(xué)物理高一上期中教學(xué)質(zhì)量檢測(cè)模擬試題含解析
- 2025屆黑龍江省哈爾濱市實(shí)驗(yàn)中學(xué)高二物理第一學(xué)期期末監(jiān)測(cè)模擬試題含解析
- 河南省滎陽(yáng)高中2025屆物理高三第一學(xué)期期末考試模擬試題含解析
- 2025屆江蘇省鹽城市濱??h蔡橋初級(jí)中學(xué)等三校物理高二上期中經(jīng)典模擬試題含解析
- 2025屆湖北省武漢市漢南區(qū)職教中心物理高二上期中復(fù)習(xí)檢測(cè)模擬試題含解析
- 江蘇省揚(yáng)州市紅橋高級(jí)中學(xué)2025屆高二物理第一學(xué)期期中達(dá)標(biāo)測(cè)試試題含解析
- 云南省廣南縣第三中學(xué)校2025屆物理高一上期末綜合測(cè)試模擬試題含解析
- 2025屆黑龍江省鶴崗市一中高二物理第一學(xué)期期中調(diào)研模擬試題含解析
- 2025屆云南省元江第一中學(xué)物理高二第一學(xué)期期末學(xué)業(yè)質(zhì)量監(jiān)測(cè)模擬試題含解析
- 執(zhí)行器基礎(chǔ)知識(shí)單選題100道及答案解析
- 安徽省建設(shè)工程造價(jià)咨詢服務(wù)項(xiàng)目及收費(fèi)標(biāo)準(zhǔn)
- 建筑工程關(guān)鍵施工技術(shù)工藝及工程項(xiàng)目實(shí)施的重點(diǎn)難點(diǎn)和解決方案
- 泌尿系統(tǒng)梗阻病人的護(hù)理.ppt
- (完整版)初中數(shù)學(xué)中考考試大綱
- 柴油機(jī)的振動(dòng)與平衡-文檔資料
- 廣東省河流水功能二級(jí)區(qū)劃成果表
- 純?nèi)几郀t煤氣鍋爐吸熱特點(diǎn)及運(yùn)行
- 酒駕私了協(xié)議書(shū)——范本
- 森林施工組織設(shè)計(jì)(完整版)
- 304不銹鋼冷軋剝片缺陷分析及控制
- 立體停車庫(kù)詳解
評(píng)論
0/150
提交評(píng)論