1. 程式人生 > >以太坊中的賬戶、交易、Gas和區塊Gas Limit

以太坊中的賬戶、交易、Gas和區塊Gas Limit

原文地址:https://blog.csdn.net/wo541075754/article/details/77505299

 

什麼是賬戶?

外部擁有賬戶 vs 合約賬戶

以太坊中有兩種賬戶: 
(1)外部擁有賬戶(EOA) 
(2)合約賬戶

外部擁有賬戶

一個外部擁有賬戶具有一下特性:

  • 有一個以太幣餘額
  • 可以傳送交易(以太幣轉賬或者啟用合約程式碼)
  • 通過私鑰控制
  • 沒有相關聯的程式碼

合約賬戶

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

  • 有一個以太幣餘額
  • 有相關聯的程式碼
  • 程式碼執行是通過交易或者其他合約傳送的call來啟用
  • 當被執行時執行在隨機複雜度 (圖靈完備性)、只能操作其擁有的特定儲存,例如可以擁有其永久state 、可以call其他合約

所有以太坊區塊鏈上的行動都是由各賬戶傳送的交易啟用。每次一個合約賬戶收到一個交易,交易自帶的引數都會成為程式碼的輸入值執行。合約程式碼會被以太坊虛擬機器(EVM)在每一個參與網路的節點上執行,以作為它們新區塊的驗證。

什麼是交易和訊息?

交易

“交易”這個術語在以太坊裡被用來指代一個用來儲存訊息的被簽名資料包在區塊鏈上從一個外部擁有賬戶傳送至另一個賬戶的過程。

交易包括:

  • 這個訊息的接收者
  • 一個簽名,用來證明發送者有意向通過區塊鏈向接收者傳送訊息
  • 價值域 - 從傳送方轉移到接受方的wei (ether/10^18) 的數量
  • 一個可選的資料域,用來儲存傳送給合約的訊息
  • 一個GASLIMIT值,代表了這個交易的執行最多被允許使用的計算步驟
  • 一個GASPRICE值,代表了交易傳送者願意支付的gas費用。一個單位的gas表示了執行一個基本指令,例如一個計算步驟

訊息

合約具有傳送”訊息”到其他合約的能力。訊息是一個永不序列且只在以太坊執行環境中存在的虛擬物件。他們可以被理解為函式呼叫(function calls)。

一個訊息包括:

  • 明確的訊息傳送者
  • 訊息的接收者
  • 一個可選的資料域,這是合約實際上的輸入資料
  • 一個GASLIMIT值,用來限制這個訊息出發的程式碼執行可用的最大gas數量

總的來說,一個訊息就像是一個交易,除了它不是由外部賬戶生成,而是合約賬戶生成。當合約正在執行的程式碼中運行了CALL 或者DELEGATECALL這兩個命令時,就會生成一個訊息。訊息有的時候也被稱為”內部交易”。與一個交易類似,一個訊息會引導接收的賬戶執行它的程式碼。因此,合約賬戶可以與其他合約賬戶發生關係,這點和外部賬戶一樣。有許多人會誤用交易這個詞指代訊息,所以可能訊息這個詞已經由於社群的共識而慢慢退出大家的視野,不再被使用。

什麼是 gas?

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

gas和交易消耗的gas

每筆交易都被要求包括一個gas limit(有的時候被稱為startGas)和一個交易願為單位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團隊的例子並借用他們的分析。請參考他們與gas相關的介紹。他們還有一個小頁面方便大家把以太幣轉換成小單位的gas計數單位。

你可以將gasLimit理解為你汽車油箱的上限。同時將gasPrice理解為油價。

對於一輛車來說,油價可能是 2.5(價格)每升(單位)。在以太坊中,就是20GWei(價格)每gas(單位)。為了填滿你的"油箱",需要10升2.5(價格)每升(單位)。在以太坊中,就是20GWei(價格)每gas(單位)。為了填滿你的"油箱",需要10升2.5的油 = $25。同樣的,21000個20 GWei的gas = 0.00042 ETH。

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

傳送代幣通常需要消耗大約5萬至10萬的gas,所以總交易費會上升0.001至0.002個ETH。

什麼是”區塊gas limit”?

區塊gas limit是單個區塊允許的最多gas總量,以此可以用來決定單個區塊中能打包多少筆交易。例如,我們有5筆交易的gas limit分別是10、20、30、40和50.如果區塊gas limit是100,那麼前4筆交易就能被成功打包進入這個區塊。礦工有權決定將哪些交易打包入區塊。所以,另一個礦工可以選擇打包最後兩筆交易進入這個區塊(50+40),然後再將第一筆交易打包(10)。如果你嘗試將一個會使用超過當前區塊gas limit的交易打包,這個交易會被網路拒絕,你的以太坊客戶端會反饋錯誤”交易超過區塊gas limit”。以下例子是來自於以太坊StackExhcange的帖子。

目前區塊的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的選項。

以太坊網路上的”DoS”攻擊是什麼?

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

惡意的DoS

上個秋天,以太坊被某人或某個團體攻擊了,通過大量製造垃圾交易。這次攻擊在如下部落格有介紹:

攻擊者通過在他們的智慧合約中反覆的呼叫某些命令來讓客戶端難以處理這些計算,但是這些命令都只消耗少量的gas所以呼叫起來十分廉價。 
在這次攻擊中,礦工被要求降低gas limit到150萬,在後來的另一次事件中更改到了200萬。也有幾次其他的事件要求礦工在網路被攻擊時降低區塊gas limit。

非惡意的DoS

非惡意的DoS其實就是當網路面臨海量交易時需要比平常更多的時間來處理一筆交易。最近由於ICO的流行,以太坊網路多次被交易填滿。Infura的朋友們寫過一篇與此相關的技術分析文章。

為什麼區塊gas limit在區塊被填滿時不會自動調整?

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

以太坊協議中存在著讓礦工可以通過投票來決定gas limit的機制,所以區塊容量不需要經過硬分叉就可以調整。最初,這個機制和另一個預設策略是繫結在一起的,即礦工預設投票使區塊gas limit至少有470萬,並且趨向於最近1024個區塊gas使用量的1.5倍。這使得區塊容量會根據需求來自動上升,同時也有一個可用來防禦垃圾交易的限制。

就像”惡意的DoS”部分說的,在歷史上有幾次礦工因為攻擊的原因不得不使用非預設設定來幫助降低攻擊造成的影響。但現在的問題是礦池在攻擊之後並沒有將設定改回預設設定。大約一個月前,礦工被要求改變gas limit和gas price設定來再次加入gas limit動態調整功能。因為最近的代幣銷售火爆導致很多區塊被填滿並且區塊鏈交易堵塞。

ETH Gas Station是一個人們可以查閱最新區塊gas limit設定的網站。

礦工需要做什麼才能修復這個問題?

礦工可以在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選項頁面來看看礦工還能如何調整優化設定。