Gas-Limit

合約部署的虛幻大gas消耗

  • May 1, 2017

我有一份大契約(超過 1000 串程式碼)。我部署它沒有任何問題。當我估算耗氣量時

let gas_need = Web3Helpers.web3.eth.estimateGas({data: code});
console.log("Gas needed="+gas_need);

我得到“需要的氣體=1652040”。但是,如果我在合約中添加一個可以生成事件的函式(任何),當我嘗試部署時,我會收到一個錯誤“無法儲存合約程式碼,請檢查你的 gas 量”,需要的 gas 值為“需要的氣體=1000000000000000000”。誰能解釋發生了什麼?!

編輯

  1. 我想我得到值“需要的氣體 = 1000000000000000000”,因為我使用 –targetgaslimit 1000000000000000000 參數執行節點。
  2. 我寫了小測試。
"use strict";

let Web3 = require('web3');
let web3;
if (typeof web3 !== 'undefined') {
   web3 = new Web3(web3.currentProvider);
} else {
   web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}


function codeGenerator(functions_count)
{
   let code = `
       pragma solidity ^0.4.0;
       contract Test
       {
           event TestEvent(uint a);
           function Test() {}
       `;
   for (let i=0;i<functions_count;i++)
   {
       code+="\nfunction f"+i+`(uint i)
       {
           TestEvent(i);
       }`;
   }
   code+="\n}";
   return code;
}


let start_functions_count=350;
let end_functions_count=360;

let compileAndCheck = function (i)
{
   let code = codeGenerator(i);
   web3.eth.compile.solidity(
       code,
       function (error, compiled_code) {
           if (error)
           {
               console.log("Compilation error. i="+i+" Error=", error);
               process.exit(0);
           }

           let gas_need = web3.eth.estimateGas({data: compiled_code["<stdin>:Test"].code});
           console.log("Number of functions="+i+". Gas needed="+gas_need);

           if (i<end_functions_count)
               compileAndCheck(i+1);
       });
};

compileAndCheck(start_functions_count);

```




When I run this script I get output:



```
   Number of functions=350. Gas needed=1632400
   Number of functions=351. Gas needed=1636991
   Number of functions=352. Gas needed=1641573
   Number of functions=353. Gas needed=1646155
   Number of functions=354. Gas needed=1650737
   Number of functions=355. Gas needed=712069252639603
   Number of functions=356. Gas needed=715552950743727
   Number of functions=357. Gas needed=719053692348094
   Number of functions=358. Gas needed=719053692348094
   Number of functions=359. Gas needed=719053692348094

```

Can anyone tell what happens when Number of functions=355 ?


**EDIT 1**
One more surveillance that wil possibly help to understand what is going on. The output when I do mining.



```
   Number of functions=352. Gas needed=1641573
   Number of functions=353. Gas needed=1646155
   Number of functions=354. Gas needed=1650737
   Number of functions=355. Gas needed=870454639237568800
   Number of functions=356. Gas needed=867906968741702500
   Number of functions=357. Gas needed=864521670116149900
   Number of functions=358. Gas needed=861991364396921200
   Number of functions=359. Gas needed=859468464445823200
   Number of functions=360. Gas needed=856952948587450600

```

If I do not mining, I get this:



```
   Number of functions=352. Gas needed=1641573
   Number of functions=353. Gas needed=1646155
   Number of functions=354. Gas needed=1650737
   Number of functions=355. Gas needed=472655063161557060
   Number of functions=356. Gas needed=472655063161557060
   Number of functions=357. Gas needed=472655063161557060
   Number of functions=358. Gas needed=472655063161557060
   Number of functions=359. Gas needed=472655063161557060
   Number of functions=360. Gas needed=472655063161557060

```

**EDIT 2**


1. I use geth VERSION 1.5.9-stable-a07539fb
2. I start node with comand **geth --shh --fakepow --nodiscover --maxpeers 1 --nat none --rpc --rpcapi="db,eth,net,web3,personal,debug" --rpccorsdomain "*" --datadir "/Users/admin/Desktop/etherium-research/private_chain_directory/" --identity "private_node_1" --networkid 19045 console**
3. I tryed to use different solc java script compiler

“use strict”;

var solc = require(‘solc’);

let Web3 = require(‘web3’); let web3; if (typeof web3 !== ‘undefined’) { web3 = new Web3(web3.currentProvider); } else { web3 = new Web3(new Web3.providers.HttpProvider(“http://localhost:8545”)); }

function codeGenerator(functions_count) { let code = pragma solidity ^0.4.0; contract Test { event TestEvent(uint a); function Test() {}; for (let i=0;i<functions_count;i++) { code+="\nfunction f"+i+(uint i) { TestEvent(i); }; } code+="\n}"; return code; }

let start_functions_count=352; let end_functions_count=357;

let c_version = ‘v0.4.9+commit.364da425’; solc.loadRemoteVersion(c_version, function(err, solcSnapshot) { if (err) { console.log(“Load compiler error="+err); process.exit(0); } compileSolcAndCheck(solcSnapshot); });

function compileSolcAndCheck(complier) { console.log(“Compiler version="+complier.version()); for (let i=start_functions_count; i <=end_functions_count; i++) { let code = codeGenerator(i); console.log(“Compiling for functions count="+i); let compiled_code = complier.compile(code,1); console.log(“Estimating gas usage for functions count="+i); let gas_need = web3.eth.estimateGas({data: “0x”+compiled_code.contracts[’:Test’].bytecode}); console.log(“Number of functions="+i+”. Gas needed="+gas_need); } }





Results:

Compiler version=0.4.9+commit.364da425.Emscripten.clang Compiling for functions count=352 Estimating gas usage for functions count=352 Number of functions=352. Gas needed=1641573 Compiling for functions count=353 Estimating gas usage for functions count=353 Number of functions=353. Gas needed=1646155 Compiling for functions count=354 Estimating gas usage for functions count=354 Number of functions=354. Gas needed=1650737 Compiling for functions count=355 Estimating gas usage for functions count=355 Number of functions=355. Gas needed=8029590240010579 Compiling for functions count=356 Estimating gas usage for functions count=356 Number of functions=356. Gas needed=7557625396430654 Compiling for functions count=357 Estimating gas usage for functions count=357 Number of functions=357. Gas needed=7106455114351858

Compiler version=0.4.10+commit.f0d539ae.Emscripten.clang Compiling for functions count=352 Estimating gas usage for functions count=352 Number of functions=352. Gas needed=1641573 Compiling for functions count=353 Estimating gas usage for functions count=353 Number of functions=353. Gas needed=1646091 Compiling for functions count=354 Estimating gas usage for functions count=354 Number of functions=354. Gas needed=1650737 Compiling for functions count=355 Estimating gas usage for functions count=355 Number of functions=355. Gas needed=15512687238849220 Compiling for functions count=356 Estimating gas usage for functions count=356 Number of functions=356. Gas needed=14501360678935126 Compiling for functions count=357


4. If optimization is disabled gas grow event happens earlier, don't know when exactly


**EDIT 3**


It seems the problem appears when bytecode size is more 48 Kb. I tried different compilers and different solidity source code, with and without optimization. Using optimization just makes code size smaller (I mentioned about optimization above)

Mon Mar 27 2017 18:35:41 GMT+0300 (MSK) Compiling for functions count=181 Mon Mar 27 2017 18:36:16 GMT+0300 (MSK) Code compiled. Byte code size=49140(47.98828125 KB) Estimating gas usage for functions count=181 Number of functions=181. Gas needed=1650521

Mon Mar 27 2017 18:36:21 GMT+0300 (MSK) Compiling for functions count=182 Mon Mar 27 2017 18:36:56 GMT+0300 (MSK) Code compiled. Byte code size=49410(48.251953125 KB) Estimating gas usage for functions count=182 Number of functions=182. Gas needed=2508197197101

Compiled (binary) contract code can not exceed 24576 bytes (48Kb in HEX encoded). See <https://github.com/ethereum/EIPs/issues/170> for details. Thanks to <https://github.com/fjl> for pointing.

引用自:https://ethereum.stackexchange.com/questions/13469