以太坊運行原理筆記:?
(參考以太坊黃皮書)
合約創(chuàng)建
之前的文章說到過外部賬戶和合約賬戶贬堵,那么合約的創(chuàng)建告抄,理解為以創(chuàng)建合約賬戶為交易氢哮。
那么首先是來初始化一個合約賬戶畔况。?
合約賬戶中有相關下列參數(shù):發(fā)送者锭碳、原始交易人衅疙、可用的gas很魂、gas單價谐岁、初始費用墨礁,任意長度的字節(jié)數(shù)組幢竹、EVM的初始化代碼、合約常見當前的棧深度恩静、狀態(tài)更改許可焕毫。
新的合約賬戶地址是一個hash值的最右側的160位,通過發(fā)送者的地址和賬戶的nonce(nonce使用時候減去1驶乾,認為在這個調用之前對發(fā)送者的nonce加1邑飒,在一個可靠交易執(zhí)行或者虛擬機操作開始會對這個發(fā)送者的nonce加1)進行RLP編碼后,再經過Keccak HASH計算來獲得级乐。
通過狀態(tài)轉換疙咸,賬戶初始nonce設置為1,balance交易傳出的值风科,storage為空撒轮,codehash為空的Keccak 256位的hash值,減去發(fā)送者相應轉賬值贼穆,狀態(tài)變化题山。通過evm代碼來執(zhí)行。
代碼的執(zhí)行過程中會有gas的消耗故痊,必須要有足夠的gas顶瞳,那么gas不足,出現(xiàn)out-of-gas異常愕秫,gas變?yōu)?慨菱,合約創(chuàng)建是當做交易來處理,那么不影響合約創(chuàng)建的固定費用的支付戴甩,但是gas不足后附帶的金額不會轉移到取消的的合約地址符喝,剩余的gas返還給最原始的交易發(fā)起人,狀態(tài)也改變甜孤。
消息調用
消息調用中有相關下列參數(shù):發(fā)送者洲劣、交易發(fā)起人备蚓、接收者、執(zhí)行代碼的賬戶囱稽、可用的gas郊尝、轉賬金額、gas單價战惊、函數(shù)調用輸入的數(shù)據流昏、消息調用合約創(chuàng)建當前棧深度、狀態(tài)更改許可吞获。
消息調用中有一個額外的元素-由字節(jié)數(shù)組形式表示的輸出數(shù)據况凉,在執(zhí)行交易過程中輸出數(shù)據是被忽略了,那么在消息調研中vm代碼執(zhí)行產生各拷,在這種情況下使用這些信息刁绒。?
就像合約創(chuàng)建一樣,如果消息通信執(zhí)行退出是因為gas不足或交易無效(例如棧溢出烤黍,無效跳轉目的地或無效指令)知市,那么已使用的gas是不會被退回給原始觸發(fā)者的。相反速蕊,所有剩余的未使用gas也會被消耗掉嫂丙,并且狀態(tài)會被立刻重置為余額轉移之前的那個點。沒有任何方法停止或恢復交易的執(zhí)行而不讓系統(tǒng)消耗你提供的所有gas规哲,直到最新的以太坊更新跟啤。例如,假設你編寫了一個合約唉锌,當調用者沒有授權來執(zhí)行這些交易的時候拋出一個錯誤隅肥。在以太坊的前一個版本中,剩余的gas也會被消耗掉袄简,并且沒有任何gas退回給發(fā)送者武福。但是拜占庭更新包括了一個新的“恢復”代碼,允許合約停止執(zhí)行并且恢復狀態(tài)改變而不消耗剩余的gas痘番,此代碼還擁有返回交易失敗原因的能力。如果一個交易是由于恢復而退出平痰,那么未使用的gas就會被返回給發(fā)送者汞舱。
在消息調用的通用執(zhí)行框架中,會有8個所謂的預編譯合約宗雇、地址1-8分別是橢圓曲線公鑰恢復函數(shù)昂芜、SHA2 256 位哈希方案、RIPEMD 160 位哈希方案赔蒲、標識函數(shù)泌神、任?
意精度的模冪運算良漱、橢圓曲線加法、橢圓曲線純量乘法和橢?
圓曲線配對檢查欢际。
執(zhí)行模型
執(zhí)行模型使用一系列的字節(jié)代碼指令和一個環(huán)境數(shù)據的元組去改變系統(tǒng)狀態(tài)母市,使用以太坊虛擬機EVM運行,通過gas來限制损趋。
EVM是圖靈完備虛擬機器患久。EVM存在而典型圖靈完備機器不存在的唯一限制就是EVM本質上是被gas束縛。因此浑槽,可以完成的計算總量本質上是被提供的gas總量限制的蒋失。EVM具有基于堆棧的架構。堆棧機器 就是使用后進先出來保存臨時值的計算機桐玻。
EVM的存儲方式有三種:
棧(Stack)
賬戶存儲(Storage)
內存(Memory)
有一定計算機基礎的應該理解篙挽。棧是常見的線性數(shù)據結構,先進后出的模式镊靴。EVM基于棧的虛擬機铣卡,那么所有的運算都在棧上,一個棧之前提到是256bit邑闲。賬戶存儲和內存將EVM的賬戶存儲和內存類比成我們通乘阈校看到的計算機的硬盤和內存。
EVM中每個堆棧項的大小為256bit苫耸,堆棧有一個最大的大小州邢,為1024bit。
EVM有內存褪子,項目按照可尋址字節(jié)數(shù)組來存儲量淌。內存是易失性的,也就是數(shù)據是不持久的嫌褪。
EVM也有一個存儲器呀枢。不像內存,存儲器是非易失性的笼痛,并作為系統(tǒng)狀態(tài)的一部分進行維護裙秋。EVM分開保存程序代碼,在虛擬ROM 中只能通過特殊指令來訪問缨伊。這樣的話摘刑,EVM就與典型的馮·諾依曼架構 不同,此架構將程序的代碼存儲在內存或存儲器中刻坊。
EVM同樣有屬于它自己的語言:“EVM字節(jié)碼”枷恕,當一個程序員比如你或我寫一個在以太坊上運行的智能合約時,我們通常都是用高級語言例如Solidity來編寫代碼谭胚。然后我們可以將它編譯成EVM可以理解的EVM字節(jié)碼徐块。(摘自以太坊工作原理)
那么問題來了未玻,代碼在EVM中執(zhí)行,以太坊網絡中每個節(jié)點都有一個EVM胡控,的確是每個節(jié)點的EVM都會去工作扳剿,必須通過在EVM中執(zhí)行代碼來驗證區(qū)塊的結果狀態(tài)。這樣通常理解就是大量的計算資源的浪費铜犬,那么從安全性的方面來考慮舞终,在一個去中介化的區(qū)塊鏈系統(tǒng)中,這個是保證整體的安全性的必要操作癣猾。當然每個節(jié)點在執(zhí)行過程中會出現(xiàn)不同的情況敛劝,但是在區(qū)塊鏈系統(tǒng)中必須要達到完全的一致,這就使得EVM和智能合約存在一定的局限性纷宇。出現(xiàn)不確定的結果無法達成共識夸盟。這種場景下必須再次同步區(qū)塊達成一致性。
EVM有專門的指令集像捶,包括了一般常見的算術運算上陕、位運算、邏輯運算拓春、條件判斷等释簿,針對區(qū)塊鏈架構還要專門的合約訪問區(qū)塊號,區(qū)塊時間戳等指令硼莽。所有的指令以256bit位單位來傳遞庶溶。智能合約的編譯就是講高級語言寫的代碼編譯為指令集字節(jié)碼。