區塊鏈100講:易錯概念解析——以太坊的帳戶、交易、Gas和Gas Limit

image

本講用來幫助人們理解以太坊網絡上的一些基本概念和體系,包括帳戶體系、gas、礦工在區塊大小設置機制裏的角色等。php

1

什麼是帳戶

外部擁有帳戶 vs 合約帳戶html

以太坊中有兩種帳戶:git

  • 外部擁有帳戶(EOA)github

  • 合約帳戶web

這個區別在即將到來的大都會升級中將會被抽象化(https://github.com/ethereum/EIPs/pull/208)。網絡

外部擁有帳戶函數

一個外部擁有帳戶具備一下特性:區塊鏈

  • 有一個以太幣餘額優化

  • 能夠發送交易(以太幣轉帳或者激活合約代碼)網站

  • 經過私鑰控制

  • 沒有相關聯的代碼

合約帳戶

一個合約帳戶擁有一下特性:

  • 有一個以太幣餘額

  • 有相關聯的代碼

  • 代碼執行是經過交易或者其餘合約發送的call來激活

  • 當被執行時 -- 運行在隨機複雜度 (圖靈完備性)-- 只能操做其擁有的特定儲存,例如能夠擁有其永久state -- 能夠call其餘合約

全部以太坊區塊鏈上的行動都是由各帳戶發送的交易激活。每次一個合約帳戶收到一個交易,交易自帶的參數都會成爲代碼的輸入值運行。合約代碼會被以太坊虛擬機(EVM)在每個參與網絡的節點上運行,以做爲它們新區塊的驗證。

2

什麼是交易和消息

交易

"交易"這個術語在以太坊裏被用來指代一個用來存儲消息的被簽名數據包在區塊鏈上從一個外部擁有帳戶發送至另外一個帳戶的過程。

交易包括:

  • 這個消息的接收者

  • 一個簽名,用來證實發送者有意向經過區塊鏈向接收者發送消息

  • 價值域 - 從發送方轉移到接受方的wei (ether/10^18) 的數量

  • 一個可選的數據域,用來儲存發送給合約的消息

  • 一個GASLIMIT值,表明了這個交易的執行最多被容許使用的計算步驟

  • 一個GASPRICE值,表明了交易發送者願意支付的gas費用。一個單位的gas表示了執行一個基本指令,例如一個計算步驟

具體參考官方接口說明: https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethsendrawtransaction

消息

合約具備發送"消息"到其餘合約的能力。消息是一個永不串行且只在以太坊執行環境中存在的虛擬對象。他們能夠被理解爲函數調用(function calls)。

一個消息包括:

  • 明確的消息發送者

  • 消息的接收者

  • 一個可選的數據域,這是合約實際上的輸入數據

  • 一個GASLIMIT值,用來限制這個消息出發的代碼執行可用的最大gas數量

總的來講,一個消息就像是一個交易,除了它不是由外部帳戶生成,而是合約帳戶生成。當合約正在執行的代碼中運行了CALL 或者DELEGATECALL這兩個命令時,就會生成一個消息。消息有的時候也被稱爲"內部交易"。與一個交易相似,一個消息會引導接收的帳戶運行它的代碼。所以,合約帳戶能夠與其餘合約帳戶發生關係,這點和外部帳戶同樣。有許多人會誤用交易這個詞指代消息,因此可能消息這個詞已經因爲社區的共識而慢慢退出你們的視野,再也不被使用。

3

什麼是 gas?

以太坊在區塊鏈上實現了一個運行環境,被稱爲以太坊虛擬機(EVM)。每一個參與到網絡的節點都會運行都會運行EVM做爲區塊驗證協議的一部分。他們會驗證區塊中涵蓋的每一個交易並在EVM中運行交易所觸發的代碼。每一個網絡中的全節點都會進行相同的計算並儲存相同的值。合約執行會在全部節點中被屢次重複,這個事實得使得合約執行的消耗變得昂貴,因此這也促使你們將能在鏈下進行的運算都不放到區塊鏈上進行。對於每一個被執行的命令都會有一個特定的消耗,用單位gas計數。每一個合約能夠利用的命令都會有一個相應的gas值。

gas和交易消耗的gas

每筆交易都被要求包括一個gas limit(有的時候被稱爲startGas)(https://media.consensys.net/ethereum-gas-fuel-and-fees-3333e17fe1dc)和一個交易願爲單位gas支付的費用。礦工能夠有選擇的打包這些交易並收取這些費用。在現實中,今天全部的交易最終都是由礦工選擇的,可是用戶所選擇支付的交易費用多少會影響到該交易被打包所需等待的時長。若是該交易因爲計算,包括原始消息和一些觸發的其餘消息,須要使用的gas數量小於或等於所設置的gas limit,那麼這個交易會被處理。

若是gas總消耗超過gas limit,那麼全部的操做都會被複原,但交易是成立的而且交易費任會被礦工收取。區塊鏈會顯示這筆交易完成嘗試,但由於沒有提供足夠的gas致使全部的合約命令都被複原。因此交易裏沒有被使用的超量gas都會以以太幣的形式打回給交易發起者。由於gas消耗通常只是一個大體估算,因此許多用戶會超額支付gas來保證他們的交易會被接受。這沒什麼問題,由於多餘的gas會被退回給你。

估算交易消耗

一個交易的交易費由兩個因素組成:

  • gasUsed:該交易消耗的總gas數量

  • gasPrice:該交易中單位gas的價格(用以太幣計算)

交易費 = gasUsed * gasPrice

gasUsed

每一個EVM中的命令都被設置了相應的gas消耗值。gasUsed是全部被執行的命令的gas消耗值總和。

若是但願估算gasUsed,可使用這個estimateGas的API

gasPrice

一個用戶能夠構建和簽名一筆交易,但每一個用戶均可以各自設置本身但願使用的gasPrice,甚至能夠是0。然而,以太坊客戶端的Frontier版本有一個默認的gasPrice,即0.05e12 wei。礦工爲了最大化他們的收益,若是大量的交易都是使用默認gasPrice即0.05e12 wei,那麼基本上就很難又礦工去接受一個低gasPrice交易,更別說0 gasPrice交易了。

交易費案例

MyEtherWallet團隊有一個小頁面(https://www.myetherwallet.com/helpers.html)方便你們把以太幣轉換成小單位的gas計數單位。

你能夠將gasLimit理解爲你汽車油箱的上限。同時將gasPrice理解爲油價。

對於一輛車來講,油價多是 公式輸入有誤2.5的油 = $25。一樣的,21000個20 GWei的gas = 0.00042 ETH。

所以,總交易費將會是0.00042以太幣。

發送代幣一般須要消耗大約5萬至10萬的gas,因此總交易費會上升0.001至0.002個ETH。

4

什麼是"區塊gas limit"?

區塊gas limit是單個區塊容許的最多gas總量,以此能夠用來決定單個區塊中能打包多少筆交易。例如,咱們有5筆交易的gas limit分別是十、20、30、40和50.若是區塊gas limit是100,那麼前4筆交易就能被成功打包進入這個區塊。礦工有權決定將哪些交易打包入區塊。因此,另外一個礦工能夠選擇打包最後兩筆交易進入這個區塊(50+40),而後再將第一筆交易打包(10)。若是你嘗試將一個會使用超過當前區塊gas limit的交易打包,這個交易會被網絡拒絕,你的以太坊客戶端會反饋錯誤"交易超過區塊gas limit"。如下例子是來自於以太坊StackExhcange的帖子(https://ethereum.stackexchange.com/questions/7359/are-gas-limit-in-transaction-and-block-gas-limit-different)。

目前區塊的gas limit是 4,712,357 gas,數據來自於ethstats.net,這表示着大約224筆轉帳交易(gas limit爲21000)能夠被塞進一個區塊(區塊時間大約在15-20秒間波動)。這個協議容許每一個區塊的礦工調整區塊gas limit,任意加減 1/2024(0.0976%)。

誰來決定

區塊的gas limit是由在網絡上的礦工決定的。與可調整的區塊gas limit協議不一樣的是一個默認的挖礦策略,即大多數客戶端默認最小區塊gas limit爲4,712,388。

區塊gas limit是怎樣改變的

以太坊上的礦工須要用一個挖礦軟件,例如ethminer。它會鏈接到一個geth或者Parity以太坊客戶端。Geth和Pairty都有讓礦工能夠更改配置的選項。這裏是geth挖礦命令行選項以及Parity的選項。

5

以太坊網絡上的"DoS"攻擊是什麼?

最近有些評論表示以太坊網絡正在慢慢減速,變得擁堵甚至沒法使用。這些評論把這個減速的過程稱爲對以太坊網絡的"DoS"攻擊。當以太坊網絡上持續地出現全滿區塊而且有大量交易在網絡上待處理時就會出現所謂的DoS狀況。同時,礦工有權利根據交易費選擇打包哪些交易。若是當時隊列中(交易池中)有上千筆交易正在等待打包,那麼就有可能形成幾個小時的非正常交易延遲。DDoS多是惡意的也有多是非惡意的。

惡意的DoS

上個秋天,以太坊被某人或某個團體攻擊了,經過大量製造垃圾交易。此次攻擊在以下博客(https://ethstats.net/)有介紹:

攻擊者經過在他們的智能合約中反覆的調用某些命令來讓客戶端難以處理這些計算,可是這些命令都只消耗少許的gas因此調用起來十分廉價。

在此次攻擊中,礦工被要求下降gas limit到150萬(https://blog.ethereum.org/2016/09/22/transaction-spam-attack-next-steps/),在後來的另外一次事件中更改到了200萬(https://www.reddit.com/r/ethereum/comments/58aelh/attention_miners_recommending_miners_lower_the/)。也有幾回其餘的事件要求礦工在網絡被攻擊時下降區塊gas limit。

非惡意的DoS

非惡意的DoS其實就是當網絡面臨海量交易時須要比日常更多的時間來處理一筆交易。最近因爲ICO的流行,以太坊網絡屢次被交易填滿。Infura的朋友們寫過一篇與此相關的技術分析文章(https://blog.infura.io/when-there-are-too-many-pending-transactions-8ec1a88bc87e)。

6

爲何區塊gas limit在區塊被填滿時不會自動調整?

主要緣由:礦工們沒有使用gas limit動態調整的功能。

以太坊協議中存在着讓礦工能夠經過投票來決定gas limit的機制,因此區塊容量不須要通過硬分叉就能夠調整。最初,這個機制和另外一個默認策略是綁定在一塊兒的,即礦工默認投票使區塊gas limit至少有470萬,而且趨向於最近1024個區塊gas使用量的1.5倍。這使得區塊容量會根據需求來自動上升,同時也有一個可用來防護垃圾交易的限制。

就像"惡意的DoS"部分說的,在歷史上有幾回礦工由於攻擊的緣由不得不使用非默認設置來幫助下降攻擊形成的影響。但如今的問題是礦池在攻擊以後並無將設置改回默認設置。大約一個月前,礦工被要求改變gas limit和gas price設置來再次加入gas limit動態調整功能(https://www.reddit.com/r/ethereum/comments/6ehp60/recommendations_to_miners_to_change_gas_limit_and/)。由於最近的代幣銷售火爆致使不少區塊被填滿而且區塊鏈交易堵塞。

ETH Gas Station(https://ethgasstation.info/index.php)是一我的們能夠查閱最新區塊gas limit設置的網站。

7

礦工須要作什麼才能修復這個問題?

礦工能夠在Geth或者Parity客戶端中更改設置來重啓動態gas limit調整。注意:這些設置是在這個Reddit帖子找到的,其實能夠被設置的更高(參考這個帖子)。

Geth

推薦設置

--gasprice 4000000000 --targetgaslimit 4712388

解釋

--targetgaslimit Target gas limit sets the artificial target gas floor for the blocks to mine (default: 「4712388」) --gasprice Minimal gas price to accept for mining a transactions (default: 「20000000000」). Note: gasprice is listed in wei.

Parity

推薦設置

--gas-floor-target 4712388 --gas-cap 9000000 --gasprice 4000000000

解釋

--gas-floor-target Amount of gas per block to target when sealing a new block (default: 4700000).

--gas-cap A cap on how large we will raise the gas limit per block due to transaction volume (default: 6283184).

--gasprice Minimum amount of Wei per GAS to be paid for a transaction to be accepted for mining. Note: gasprice is listed in wei. Note 2: --gasprice is a 「Legacy Option」

其餘挖礦設置選項

能夠參考CLI選項頁面來看看礦工還能如何調整優化設置。

內容來源:以太坊愛好者

做者: Hudson Jameson

翻譯&校對: 許昕

原文連接: 

http://hudsonjameson.com/2017-06-27-accounts-transactions-gas-ethereum/

image

相關文章
相關標籤/搜索