ethereum-gas-how-it-works-翻譯
本文的目的
理解gas如何工作對於有興趣參與以太坊ICO、使用智慧合約、以及哪怕是最簡單的兩個錢包的交易的所有使用者來說都是非常關鍵的。在本文中,我希望能向大家解釋清楚gas是什麼,以及它如何運轉。你可以跳轉到結尾直接檢視總結。開始之前,我們需要先明白一些以太坊虛擬機器(EVM)的基本概念。
以太坊虛擬機器(EVM)以及Gas
以太坊虛擬機器(EVM)是以太坊經濟系統中的一個重要角色,既然是這樣,我們就有必要研究一下以太坊的經濟系統與gas有什麼關係。簡短的說,EVM是一個可以執行任意智慧合約程式碼和操作的環境。每一個以太坊網路中的節點都會在EVM中執行操作,以冗餘的方式確認執行結果的正確性。
一切交易–從簡單的轉賬到ICO智慧合約,都需要展示出其需要執行操作的總量。每一個操作都會消耗一定數量的gas。因此,簡單的交易(例如轉賬)只需要很少的gas就能執行,而執行起來更麻煩的智慧合約則需要更多gas。
舉個例子說,一個簡單的操作,例如執行程式碼if(var > 1)
也許會消耗1gas,但是一個更加複雜的操作例如儲存一個變數,則可能需要消耗100gas。執行一條交易(可能是轉賬,也可能是智慧合約)所有操作所消耗的gas之和,就是這條交易需要消耗的gas。
Gas的上限
在一些網站上,例如MyEtherWallet,你會看到一個叫做Gas Limit的欄位。這個值指出了你提出的一筆交易能消耗的最大gas值
重點注意:
- 不同型別的交易型別會造成不同數額的gas需求。
- 如果給出的gas過低,則會導致交易失敗,但已執行交易消耗的gas * gas price的交易費仍然會支付給礦工。
- 另外,未消耗掉的gas會被自動退還。
如果我設定的gas太少會怎樣呢?
你的交易會開始執行,但是最終會因為gas耗盡而停止。一旦發生了這事兒,你為這些消耗掉的gas支付的以太幣就永遠拿不回來了,但是隻要交易沒有成功執行完成,區塊鏈不會認為它生效(例如不會認為轉賬成功),所以用於轉賬交易的大部分錢並不會從你的錢包中消失。
這就是說我應該每次都把gas值設定的很大?反正用不完的都會被退回?
不,對於交易來說,最小的gas值是21000 + 需要執行的一切fallback function的總量(如果是轉賬給智慧合約的話才存在這個值,否則就是21000)
size,只是以太坊礦工有權利增加或者減少一個block中的gas limit從而是的它們可以更快地被產生。如果你希望你的交易被處理,那麼你就無法超越這個界限。同樣,礦工也只會在每筆交易中得到與該交易實際消耗gas價值相同的以太幣作為報酬,所以設定過高的gas limit會讓礦工認為這個交易不可計算,因為其gas limit可能甚至都超過了block的gas limit。
Gas Price
Gas Price是指的是你願意為每個gas支付的價格。是的,由你來指定一筆交易你希望消耗的最大gas數量和單位gas的價格。儘管gas limit只是一個值,市場狀態以及礦工挖礦時根據更高的gas price從而優先打包的行為會驅動gas price的變化。當前的gas price可以從Etherscan或者EthGasStation上查到。就像前面說過的,gas價格通常是以gwei為單位的。 Wei是以太幣的最小單位,1 gwei = 1000000000 wei。我們來看看下面的這段程式碼:
var unitMap = {
'wei': '1',
'kwei': '1000',
'ada': '1000',
'femtoether': '1000',
'mwei': '1000000',
'babbage': '1000000',
'picoether': '1000000',
'gwei': '1000000000',
'shannon': '1000000000',
'nanoether': '1000000000',
'nano': '1000000000',
'szabo': '1000000000000',
'microether': '1000000000000',
'micro': '1000000000000',
'finney': '1000000000000000',
'milliether': '1000000000000000',
'milli': '1000000000000000',
'ether': '1000000000000000000',
'kether': '1000000000000000000000',
'grand': '1000000000000000000000',
'einstein': '1000000000000000000000',
'mether': '1000000000000000000000000',
'gether': '1000000000000000000000000000',
'tether': '1000000000000000000000000000000'
};