【智能合約開發(fā)】Gas 優(yōu)化小技巧

Gas - 驅(qū)動以太坊DApps的能源

在 Solidity 中似忧,你的用戶想要每次執(zhí)行你的 DApp 都需要支付一定的 gas,gas 可以用以太幣購買丈秩,因此盯捌,用戶每次跑 DApp 都得花費以太幣。

一個 DApp 收取多少 gas 取決于功能邏輯的復雜程度蘑秽。每個操作背后饺著,都在計算完成這個操作所需要的計算資源,(比如肠牲,存儲數(shù)據(jù)就比做個加法運算貴得多)幼衰, 一次操作所需要花費的 gas 等于這個操作背后的所有運算花銷的總和。

由于運行你的程序需要花費用戶的真金白銀缀雳,在以太坊中代碼的編程語言渡嚣,比其他任何編程語言都更強調(diào)優(yōu)化。同樣的功能,使用笨拙的代碼開發(fā)的程序严拒,比起經(jīng)過精巧優(yōu)化的代碼來扬绪,運行花費更高,這顯然會給成千上萬的用戶帶來大量不必要的開銷裤唠。

省 gas 的招數(shù):

1、結(jié)構(gòu)封裝 (Struct packing)

在第1課中莹痢,我們提到除了基本版的 uint 外种蘸,還有其他變種 uint:uint8,uint16竞膳,uint32等航瞭。

通常情況下我們不會考慮使用 uint 變種,因為無論如何定義 uint的大小坦辟,Solidity 為它保留256位的存儲空間刊侯。例如,使用 uint8 而不是uint(uint256)不會為你節(jié)省任何 gas锉走。

除非滨彻,把 uint 綁定到 struct 里面。

如果一個 struct 中有多個 uint挪蹭,則盡可能使用較小的 uint, Solidity 會將這些 uint 打包在一起亭饵,從而占用較少的存儲空間。例如:

struct NormalStruct {
  uint a;
  uint b;
  uint c;
}

struct MiniMe {
  uint32 a;
  uint32 b;
  uint c;
}

// 因為使用了結(jié)構(gòu)打包梁厉,mininormal 占用的空間更少

NormalStruct normal = NormalStruct(10, 20, 30);
MiniMe mini = MiniMe(10, 20, 30); 

所以辜羊,當 uint 定義在一個 struct 中的時候,盡量使用最小的整數(shù)子類型以節(jié)約空間词顾。 并且把同樣類型的變量放一起(即在 struct 中將把變量按照類型依次放置)八秃,這樣 Solidity 可以將存儲空間最小化。例如肉盹,有兩個 struct:

uint c; uint32 a; uint32 b;

uint32 a; uint c; uint32 b;

前者比后者需要的gas更少昔驱,因為前者把uint32放一起了。

2垮媒、存儲非常昂貴

Solidity 使用storage(存儲)是相當昂貴的舍悯,”寫入“操作尤其貴。

這是因為睡雇,無論是寫入還是更改一段數(shù)據(jù)萌衬, 這都將永久性地寫入?yún)^(qū)塊鏈∷В”永久性“帮踉ァ!需要在全球數(shù)千個節(jié)點的硬盤上存入這些數(shù)據(jù),隨著區(qū)塊鏈的增長混移,拷貝份數(shù)更多祠墅,存儲量也就越大。這是需要成本的歌径!

為了降低成本毁嗦,不到萬不得已,避免將數(shù)據(jù)寫入存儲回铛。這也會導致效率低下的編程邏輯 - 比如每次調(diào)用一個函數(shù)狗准,都需要在 memory(內(nèi)存) 中重建一個數(shù)組,而不是簡單地將上次計算的數(shù)組給存儲下來以便快速查找茵肃。

在大多數(shù)編程語言中腔长,遍歷大數(shù)據(jù)集合都是昂貴的。但是在 Solidity 中验残,使用一個標記了external view的函數(shù)捞附,遍歷比 storage 要便宜太多,因為 view 函數(shù)不會產(chǎn)生任何花銷您没。 (gas可是真金白銀澳裾佟!)紊婉。

我們將在下一章討論for循環(huán)药版,現(xiàn)在我們來看一下看如何如何在內(nèi)存中聲明數(shù)組。

在內(nèi)存中聲明數(shù)組
在數(shù)組后面加上 memory關鍵字喻犁, 表明這個數(shù)組是僅僅在內(nèi)存中創(chuàng)建槽片,不需要寫入外部存儲,并且在函數(shù)調(diào)用結(jié)束時它就解散了肢础。與在程序結(jié)束時把數(shù)據(jù)保存進 storage 的做法相比还栓,內(nèi)存運算可以大大節(jié)省gas開銷 -- 把這數(shù)組放在view里用,完全不用花錢传轰。

以下是申明一個內(nèi)存數(shù)組的例子:

function getArray() external pure returns(uint[]) {
  // 初始化一個長度為3的內(nèi)存數(shù)組
  uint[] memory values = new uint[](3);
  // 賦值
  values.push(1);
  values.push(2);
  values.push(3);
  // 返回數(shù)組
  return values;
}

注意:內(nèi)存數(shù)組 必須 用長度參數(shù)(在本例中為3)創(chuàng)建剩盒。目前不支持 array.push()之類的方法調(diào)整數(shù)組大小,在未來的版本可能會支持長度修改慨蛙。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辽聊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子期贫,更是在濱河造成了極大的恐慌跟匆,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件通砍,死亡現(xiàn)場離奇詭異玛臂,居然都是意外死亡烤蜕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門迹冤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讽营,“玉大人,你說我怎么就攤上這事泡徙〕髋簦” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵堪藐,是天一觀的道長蚀瘸。 經(jīng)常有香客問我,道長庶橱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任贪惹,我火速辦了婚禮苏章,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奏瞬。我一直安慰自己枫绅,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布硼端。 她就那樣靜靜地躺著并淋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪珍昨。 梳的紋絲不亂的頭發(fā)上县耽,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音镣典,去河邊找鬼兔毙。 笑死,一個胖子當著我的面吹牛兄春,可吹牛的內(nèi)容都是我干的澎剥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赶舆,長吁一口氣:“原來是場噩夢啊……” “哼哑姚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起芜茵,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤叙量,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后夕晓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宛乃,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了征炼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片析既。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖谆奥,靈堂內(nèi)的尸體忽然破棺而出眼坏,到底是詐尸還是另有隱情,我是刑警寧澤酸些,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布宰译,位于F島的核電站,受9級特大地震影響魄懂,放射性物質(zhì)發(fā)生泄漏沿侈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一市栗、第九天 我趴在偏房一處隱蔽的房頂上張望缀拭。 院中可真熱鬧,春花似錦填帽、人聲如沸蛛淋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽褐荷。三九已至,卻和暖如春嘹悼,著一層夾襖步出監(jiān)牢的瞬間叛甫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工绘迁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留合溺,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓缀台,卻偏偏與公主長得像棠赛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子膛腐,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354