Solidity 智能合約 - Custom Error
本篇文章介紹 Solidity 中的 Custom Error 用法,包含定義錯誤、用法和錯誤處理的方式。 用法Solidity v0.8.4 之後新增這個功能,能夠用自訂的錯誤來回傳錯誤原因。在之前我們一般使用以下方式丟出錯誤: 1234567require(shouldPass, "MyError");// 或是if (!shouldPass) { revert("MyError");} 使用 Custom Error 用法如下: 123456789101112// 定義自訂錯誤error MyError();contract MyContract { function test() external { // ... if (!shouldPass) { revert MyError(); } // ... }} Custom Error 也可以帶參數 1234567891011121314// 定義自訂錯誤error M ...
Solidity 智能合約 Gas 優化技巧 - 變數順序
說明你也許不知道,Solidity 宣告變數的順序也會影響 gas 的消耗。由於 EVM 的操作都是以 32 bytes 為單位進行,所以編譯器會嘗試在讀寫變數時,將小於 32 bytes 的變數打包成 32 bytes 一組來進行存取,以達到節省存取次數的目的。不過編譯器並沒有足夠聰明,能自動將合約的變數做最佳化的分組。他會將固定大小的變數,依序每 32 bytes 為一組。例如下面的例子: 12345678910111213contract MyContract { uint64 public a; uint64 public b; uint64 public c; uint64 public d; function test() { a = 1; b = 2; c = 3; d = 4; }} 在執行 test() 時,雖然看起來寫入了四個變數,但是由於這四個變數加起來剛好是 32 bytes ,可以做一次性的寫入,所以實際上執行一個 SSTORE ,消耗 20000 gas 。接著看下面的例子: 123 ...
Solidity 智能合約 Gas 優化技巧 - 資料壓縮
在開發智能合約的過程,由於想要能夠達到多筆撮合的功能,我們實作了一個函式能夠輸入多筆訂單資料。在隨著我們加入了越來越多的功能,同時為了確保合約公正性,而需要越來越的參數,例如:礦工手續費、taker 手續費、maker 手續費和支付手續費方式等,我們遇到了變數過多而無法編譯的情況,而大量的資料所消耗的 gas 也成為一個問題。 我們在撮合的函式中,最後每個訂單會有這些資料: 1234567891011121314uint256 amountSell,uint256 amountBuy,address tokenSell,address tokenBuy,address user,uint256 nonce,uint256 gasFee,uint256 takerFee,uint256 makerFee,uint256 joyPrice,bool isBuy,uint8 v,byte32 r,byte32 s 於是我們試著想辦法減少變數的數量,在某次我看著 Etherscan 某交易顯示如下的參數資料時 12345678910111213Function: trade(address t ...
Solidity 智能合約 Gas 優化技巧 - 函式名稱
說明你也許不會想到,函式名稱也會對 gas 消耗造成影響,事實上,在最糟的情況下,甚至會有上千 gas 的差距。我們來看看下面程式: 1234contract Test { function b() public { }} 上面程式執行 b() 會消耗 125 gas,接著改成下面: 1234567contract Test { function a() public { } function b() public { }} 這次執行 b() 變成消耗 147 gas,一樣的空函式怎麼消耗增加了呢?試著執行 a() 會發現只消耗 125 gas。原來在智能合約中,函式存在前後順序,排序越後面的會消耗越多,每差一個順位就會多 22 gas。此時你可能會想把它改成下面: 1234567contract Test { function b() public { } function a() public { }} ...
Solidity 智能合約 Gas 優化技巧
如果一間區塊鏈公司業務,成本都來自於智能合約的交易,那麼智能合約的 gas 消耗,就直接影響公司營業成本。寫出節能的智能合約,在商用上有其重要性。這篇文章將整理分析智能合約中,影響 gas 消耗的一些因素,有助於我們了解消耗最大的指令是哪些,並謹慎的使用。gas 消耗可參考下面兩個表: 表一 表二 表一中的 Gas Used 為消耗的 gas。如果顯示為 FORMULA,表示不是一個固定值,要參考右邊的說明。由於我們通常使用 Solidity 開發,所以可能無法直接對應到上面表一中的指令;這時可參考表二,他有多加上一些額外的指令。以下列出消耗較多 gas 的行為與指令: 建立合約對應到 CREATE 和 CODECOPY 兩個指令。在合約中建立另一個空的合約消耗 42901 gas ( 總共 64173 gas),如果是直接部署一個空合約則總共是 68653 gas。加上合約的功能實作,可能會有幾十萬甚至百萬的 gas,應該是所有指令中消耗最多一個。拆分多個類別與實例的實作方式,gas 消耗可能會很可觀。避免用 Contract 當作資料結構: 不好 123456789contra ...