国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

以太坊源碼分析—交易的執(zhí)行

Lowky / 2755人閱讀

摘要:前言以太坊是一個(gè)運(yùn)行智能合約的平臺(tái),被稱作可編程的區(qū)塊鏈,允許用戶將編寫的智能合約部署在區(qū)塊鏈上運(yùn)行。交易執(zhí)行以太坊是一個(gè)基于交易的狀態(tài)機(jī),一筆交易可以使以太坊從一個(gè)狀態(tài)切換到另一個(gè)狀態(tài),即交易的執(zhí)行伴隨著狀態(tài)的改變。

前言

以太坊是一個(gè)運(yùn)行智能合約的平臺(tái),被稱作可編程的區(qū)塊鏈,允許用戶將編寫的智能合約部署在區(qū)塊鏈上運(yùn)行。而運(yùn)行合約的主體便是以太坊虛擬機(jī)(EVM)

區(qū)塊 交易 合約

區(qū)塊鏈由區(qū)塊(Block)組成,而區(qū)塊中打包一定數(shù)量的交易(Transaction),交易可能是一個(gè)單純的轉(zhuǎn)賬操作,也可能是調(diào)用一個(gè)智能合約,無論是哪一種,EVM在運(yùn)行(excute)交易時(shí)都會(huì)創(chuàng)建合約(Contract)

外部賬戶 合約賬戶

以太坊中的賬戶有兩類

外部賬戶 由賬戶持有人的私鑰控制的真實(shí)存在的賬戶

合約賬戶 由合約代碼控制,保存著合約代碼

一筆交易總是有發(fā)送方(sender),接收方(recipient)和數(shù)額(value) 三要素。發(fā)送方將一定數(shù)額的ETH轉(zhuǎn)移到接收方的賬戶,在單純的轉(zhuǎn)賬交易中,接收方是外部賬戶。而在調(diào)用智能合約的交易時(shí),接收方是合約賬戶。

gas

如同現(xiàn)實(shí)中的稅費(fèi)一樣,交易也需要將支付少量的費(fèi)用,稱為gas,費(fèi)用支付給礦工,這可以激勵(lì)礦工打包交易到區(qū)塊,也使得區(qū)塊鏈避免惡意運(yùn)算攻擊。gas由交易的發(fā)送者使用ETH購買,在執(zhí)行交易的每一步都會(huì)消耗gas,如果gas用完了,交易狀態(tài)會(huì)被回退,但消耗的gas不會(huì)返還。

交易執(zhí)行

以太坊是一個(gè)基于交易的狀態(tài)機(jī),一筆交易可以使以太坊從一個(gè)狀態(tài)(state)切換到另一個(gè)狀態(tài),即交易的執(zhí)行伴隨著狀態(tài)的改變。
交易執(zhí)行的入口在 core/state_processor.goProcess()方法,下面是該方法的輪廓

func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts,[]*types.Log,uint64,error) {
    ......
    var (
        usedGas = new(uint) 
        header = block.Header()
        gp = new(GasPool).AddGas(block.GasLimit())
    )
    for i, tx := range block.Transactions() {
        receipt, _, _ := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg)
        receipts = append(receipts, receipt)
        allLogs = append(allLogs, receipt.Logs...)        
    }
    p.engine.Finalize(p.bc. header, statedb, block.Transactions(), block.Uncles(), receipts)
    ......
}

Process()方法對(duì)block中的每個(gè)交易tx調(diào)用ApplyTransaction()來執(zhí)行交易,入?yún)?b>state存儲(chǔ)了各個(gè)賬戶的信息,如賬戶余額、合約代碼(僅對(duì)合約賬戶而言),我們姑且將其理解為一個(gè)內(nèi)存中的數(shù)據(jù)庫。其中每個(gè)賬戶以state object表示

ApplyTransaction()方法完成以下功能

調(diào)用AsMessage()tx為參數(shù)生成core.Message。也就是將tx中的一些字段存入Message,再從tx的數(shù)字簽名中反解出txsender,重點(diǎn)關(guān)注其中的data字段:如果是普通的轉(zhuǎn)賬交易,該字段為空,如果是創(chuàng)建一個(gè)新的合約,該字段為新的合約的代碼,如果是執(zhí)行一個(gè)已經(jīng)在區(qū)塊鏈上存在的合約,該參數(shù)為合約代碼的輸入?yún)?shù)

調(diào)用NewEVMContext()創(chuàng)建一個(gè)EVM運(yùn)行上下文vm.Context。注意其中的Coinbase字段需要填入的礦工的地址,Transfer是具體的轉(zhuǎn)賬方法,其實(shí)就是操作senderrecipient的賬戶余額

調(diào)用NewEVM()創(chuàng)建一個(gè)虛擬機(jī)運(yùn)行環(huán)境EVM,它主要作用是匯集之前的信息以及創(chuàng)建一個(gè)代碼解釋器(Interpreter),這個(gè)解釋器之后會(huì)用來解釋并執(zhí)行合約代碼

接下來就是調(diào)用ApplyMessage()將以上的信息施加在以太坊當(dāng)前狀態(tài)上,使得狀態(tài)機(jī)發(fā)生狀態(tài)變換

ApplyMessage()的頂層比較簡單,它創(chuàng)建一個(gè)StateTransition結(jié)構(gòu)并調(diào)用其TransitionDb()方法,StateTransition表示一次以太訪的狀態(tài)轉(zhuǎn)移 其定義如下:

type StateTransition struct {
    gp  *GasPool
    msg Message
    gas  uint64
    gasPrice  *big,Int
    initialGas   uint64
    value   *big.Int
    data    []byte
    state   vm.StateDB
    evm    *vm.EVM
}

其中的字段都是之前ApplyTransaction()方法中創(chuàng)建的結(jié)構(gòu)得到。一次狀態(tài)轉(zhuǎn)移包括以下流程

nonce檢查:交易的nonce值用于標(biāo)識(shí)這是sender發(fā)起的交易的序號(hào),該值總是等于上一筆交易的nonce值遞增1,當(dāng)我們檢查發(fā)現(xiàn)當(dāng)前Apply的這筆交易與該sender期待的nonce不一致時(shí),就會(huì)拒絕此次狀態(tài)轉(zhuǎn)換

gas預(yù)購:sender預(yù)購此次轉(zhuǎn)換需要的gas,簡單說來就是扣除sender賬戶的ETH(變化反映在stateDB),扣除的數(shù)量卻決于交易設(shè)定的gasPricegasLimit的乘積,單位是gwei

合約賬戶創(chuàng)建: 如果交易的recipient為空的話,標(biāo)識(shí)這筆交易需要?jiǎng)?chuàng)建一個(gè)合約,那么就創(chuàng)建一個(gè)合約賬戶(反映在state object)

價(jià)值轉(zhuǎn)移:每筆交易都伴隨著價(jià)值轉(zhuǎn)移,即ETHsender賬戶發(fā)送到receipt賬戶,如果創(chuàng)建了合約,還要執(zhí)行合約代碼

TransitionDB()完成這樣的狀態(tài)轉(zhuǎn)換,其實(shí)現(xiàn)流程如下:

最終由交易的receipt是否為空決定是使用evm.Create()還是evm.Call(),無論是哪種,最終都是創(chuàng)建一個(gè)Contract結(jié)構(gòu),然后調(diào)用run()方法運(yùn)行之。注意,即使是外部賬戶之間普通的轉(zhuǎn)賬也會(huì)調(diào)用Call()run(),只是由于receipt上沒有代碼,運(yùn)行會(huì)很快結(jié)束而已。run()最終調(diào)用InterpreterRun()方法。

前面提到過,在調(diào)用NewEVM()時(shí)創(chuàng)建了一個(gè)解釋器(Interpreter)

func NewInterpreter(evm *EVM,cfg Config)  *Interpreter {
     switch {
         case evm.ChainConfig().IsConstantinople(evm.BlockNumber):
             cfg.JumpTable = constantinopleInstructionSet
         case evm.ChainConfig().IsByzantium(evm.BlockNumber):
             cfg.JumpTable = byzantiumInstructionSet
         case evm.ChainConfig().IsHomestead(evm.BlockNumber):
             cfg.JumpTable = homesteadInstructionSet
         default:
             cfg.JumpTable = fromtierInstructionSet  
     }
     return &Interpreter{
         evm:      evm,
         cfg:      cfg,
         ......
     }
}

根據(jù)當(dāng)前Block的高度,計(jì)算出它處于以太坊演進(jìn)的階段,得到該階段支持的指令集(InstructionSet),新的階段在兼容老的階段的所有指令前提下,再增加了獨(dú)特的新指令。最終存儲(chǔ)在Interpretercfg字段

合約代碼本質(zhì)上上是由Solidity語言編譯后形成的EVM字節(jié)碼,字節(jié)碼中的操作也正是指令集中定義的指令

再回到Run()方法,其大概流程如下

EVM逐字節(jié)的解析合約代碼并調(diào)用excute()方法運(yùn)行,直到運(yùn)行完成或者gas提前耗盡。

關(guān)于具體的EVM指令解釋方式和虛擬機(jī)內(nèi)部內(nèi)存等內(nèi)部實(shí)現(xiàn),參考本系列文章

小結(jié)

在以太坊中,交易的執(zhí)行是由EVM完成的,網(wǎng)絡(luò)中的所有全節(jié)點(diǎn)都會(huì)去執(zhí)行每一筆交易(這樣所有人的狀態(tài)才可以保持一致)

交易分為普通轉(zhuǎn)賬和執(zhí)行(創(chuàng)建)智能合約,兩者都由sender付費(fèi),后者相比前者,EVM要額外執(zhí)行合約的字節(jié)碼

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/24382.html

相關(guān)文章

  • 以太源碼分析:共識(shí)(2)引擎

    摘要:前言是以太坊封定義的一個(gè)接口,它的功能可以分為類驗(yàn)證區(qū)塊類,主要用在將區(qū)塊加入到區(qū)塊鏈前,對(duì)區(qū)塊進(jìn)行共識(shí)驗(yàn)證。輔助類生成以太坊共識(shí)相關(guān)的。被使用,是以太坊狀態(tài)管理服務(wù),當(dāng)報(bào)告數(shù)據(jù)的時(shí)候,需要獲取區(qū)塊的信息。 前言 engine是以太坊封定義的一個(gè)接口,它的功能可以分為3類: 驗(yàn)證區(qū)塊類,主要用在將區(qū)塊加入到區(qū)塊鏈前,對(duì)區(qū)塊進(jìn)行共識(shí)驗(yàn)證。 產(chǎn)生區(qū)塊類,主要用在挖礦時(shí)。 輔助類。 接下...

    YuboonaZhang 評(píng)論0 收藏0
  • 區(qū)塊鏈技術(shù)學(xué)習(xí)指引

    摘要:引言給迷失在如何學(xué)習(xí)區(qū)塊鏈技術(shù)的同學(xué)一個(gè)指引,區(qū)塊鏈技術(shù)是隨比特幣誕生,因此要搞明白區(qū)塊鏈技術(shù),應(yīng)該先了解下比特幣。但區(qū)塊鏈技術(shù)不單應(yīng)用于比特幣,還有非常多的現(xiàn)實(shí)應(yīng)用場(chǎng)景,想做區(qū)塊鏈應(yīng)用開發(fā),可進(jìn)一步閱讀以太坊系列。 本文始發(fā)于深入淺出區(qū)塊鏈社區(qū), 原文:區(qū)塊鏈技術(shù)學(xué)習(xí)指引 原文已更新,請(qǐng)讀者前往原文閱讀 本章的文章越來越多,本文是一個(gè)索引帖,方便找到自己感興趣的文章,你也可以使用左側(cè)...

    Cristic 評(píng)論0 收藏0
  • 以太源碼分析—賬戶管理

    摘要:前言以太坊是一個(gè)巨大的狀態(tài)機(jī),在網(wǎng)絡(luò)中,每一個(gè)全節(jié)點(diǎn)都保存著以太坊狀態(tài)機(jī)的全部歷史,只要愿意,我們可以查詢到任何時(shí)刻的狀態(tài)黃皮書中,而賬戶狀態(tài)便是其中的狀態(tài),這部分功能由主要由代碼中的包提供基本概念賬戶地址在以太坊中,無論是外部賬戶還是合約 前言 以太坊是一個(gè)巨大的狀態(tài)機(jī),在網(wǎng)絡(luò)中,每一個(gè)全節(jié)點(diǎn)都保存著以太坊狀態(tài)機(jī)的全部歷史,只要愿意,我們可以查詢到任何時(shí)刻的狀態(tài)(黃皮書中World ...

    WilsonLiu95 評(píng)論0 收藏0
  • 以太源碼分析--MPT樹

    摘要:是以太坊中存儲(chǔ)區(qū)塊數(shù)據(jù)的核心數(shù)據(jù)結(jié)構(gòu),它和融合一個(gè)樹形結(jié)構(gòu),理解結(jié)構(gòu)對(duì)之后學(xué)習(xí)以太坊區(qū)塊以及智能合約狀態(tài)存儲(chǔ)結(jié)構(gòu)的模塊源碼很有幫助。 MPT(Merkle Patricia Tries)是以太坊中存儲(chǔ)區(qū)塊數(shù)據(jù)的核心數(shù)據(jù)結(jié)構(gòu),它Merkle Tree和Patricia Tree融合一個(gè)樹形結(jié)構(gòu),理解MPT結(jié)構(gòu)對(duì)之后學(xué)習(xí)以太坊區(qū)塊header以及智能合約狀態(tài)存儲(chǔ)結(jié)構(gòu)的模塊源碼很有幫助。 首...

    roadtogeek 評(píng)論0 收藏0
  • 以太源碼分析:共識(shí)(1)礦工

    摘要:接下來我們將從以下角度介紹礦工角色。我們分別使用礦長副礦長礦工進(jìn)行類比。副礦長,負(fù)責(zé)具體挖礦工作的安排,把挖礦任務(wù)安排給。礦工的主要函數(shù)介紹和的主要函數(shù),他們是礦工的具體運(yùn)作機(jī)制。負(fù)責(zé)處理外部事件。 前言 礦工在PoW中負(fù)責(zé)了產(chǎn)生區(qū)塊的工作,把一大堆交易交給它,它生成一個(gè)證明自己做了很多工作的區(qū)塊,然后將這個(gè)區(qū)塊加入到本地區(qū)塊鏈并且廣播給其他節(jié)點(diǎn)。 接下來我們將從以下角度介紹礦工: ...

    tylin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<