Solidity

Populus:合約因solidity gas限製而失敗

  • May 28, 2018
  • 平台 darwin——Python 2.7.12、pytest-3.0.2、py-1.4.31、pluggy-0.3.1
  • 外掛:彈出=2.0.1
  • 作業系統:Mac OS X

我相信由於 Solidity 編譯器的預設氣體限制為 3,000,000,我會遇到此錯誤。

**$$ Q $$**由於此錯誤或 populus 讀取的另一個氣體限制,我如何增加我的 Solidity 編譯器的氣體限制?

in estimate_gas-> 是否超過氣體限制?當我刪除契約中的某些功能時,錯誤得到修復。我猜populus部署合約有gas限制,是否可以擴展?如果是怎麼辦?

錯誤:

========================================== FAILURES ==========================================
________________________________________ test_receipt ________________________________________

web3 = <web3.main.Web3 object at 0x1061af2d0>
accounts = ['0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1', '0x7d577a597B2742b498Cb5Cf0C26cDCD726d39E6e', '0xDCEceAF3fc5C0a63d195d6...1d7585Bd0577402861E5', '0x13cBB8D99C6C4e0f2728C7d72606e78A29C4E224', '0x77dB2BEBBA79Db42a978F896968f4afCE746ea1F', ...]
chain = <populus.chain.tester.TesterChain object at 0x105489b50>

   def test_receipt(web3, accounts, chain): #{
       web3._requestManager = web3.manager
       global blkArrayIndex;
       global runTime;
>       my_contract, _   = chain.provider.get_or_deploy_contract('eBlocBroker');

tests/test.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/Library/Python/2.7/site-packages/populus/contracts/provider.py:143: in get_or_deploy_contract
   deploy_kwargs=deploy_kwargs,
/Library/Python/2.7/site-packages/populus/contracts/provider.py:121: in deploy_contract
   kwargs=deploy_kwargs,
/Library/Python/2.7/site-packages/web3/contract.py:311: in deploy
   txn_hash = cls.web3.eth.sendTransaction(deploy_transaction)
/Library/Python/2.7/site-packages/web3/eth.py:216: in sendTransaction
   get_buffered_gas_estimate(self.web3, transaction),
/Library/Python/2.7/site-packages/web3/utils/transactions.py:28: in get_buffered_gas_estimate
   gas_estimate = web3.eth.estimateGas(gas_estimate_transaction)
/Library/Python/2.7/site-packages/web3/eth.py:263: in estimateGas
   [transaction],
/Library/Python/2.7/site-packages/web3/manager.py:93: in request_blocking
   response = self._make_request(method, params)
/Library/Python/2.7/site-packages/web3/manager.py:76: in _make_request
   return request_func(method, params)
/Library/Python/2.7/site-packages/web3/middleware/attrdict.py:20: in middleware
   response = make_request(method, params)
/Library/Python/2.7/site-packages/web3/middleware/formatting.py:23: in middleware
   response = make_request(method, formatted_params)
/Library/Python/2.7/site-packages/web3/middleware/formatting.py:25: in middleware
   response = make_request(method, params)
/Library/Python/2.7/site-packages/web3/middleware/exception_handling.py:20: in middleware
   return make_request(method, params)
/Library/Python/2.7/site-packages/web3/providers/tester.py:86: in middleware
   return make_request(method, params)
/Library/Python/2.7/site-packages/web3/providers/tester.py:115: in make_request
   response = rpc_fn(*params)
/Library/Python/2.7/site-packages/testrpc/rpc.py:138: in eth_estimateGas
   return self.client.estimate_gas(**formatted_transaction)
/Library/Python/2.7/site-packages/testrpc/client/client.py:253: in estimate_gas
   txn_hash = self.send_transaction(*args, **kwargs)
/Library/Python/2.7/site-packages/testrpc/client/client.py:263: in send_transaction
   self._send_transaction(*args, **kwargs)
/Library/Python/2.7/site-packages/testrpc/client/client.py:58: in inner
   return client_method(self, *args, **kwargs)
/Library/Python/2.7/site-packages/testrpc/client/utils.py:104: in inner
   return fn(*bytes_args, **bytes_kwargs)
/Library/Python/2.7/site-packages/testrpc/client/client.py:225: in _send_transaction
   output = self.evm.send(sender=sender, to=to, value=value, evmdata=data)
/Library/Python/2.7/site-packages/ethereum/tester.py:338: in send
   return self._send(*args, **kwargs)["output"]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <ethereum.tester.state object at 0x1061af590>
sender = '\x04HR\xb2\xa6p\xad\xe5@~x\xfb(c\xc5\x1d\xe9\xfc\xb9eB\xa0q\x86\xfe:\xed\xa6\xbb\x8a\x11m'
to = '', value = 0
evmdata = "```@R4\x15a\x00\x0fW`\x00\x80\xfd[C`\x00\x81\x90UP3`\x01`\x00a\x01\x00\n\x81T\x81s\xff\xff\xff\xff\xff\xff\xff\xff\xf...c3V[P\x90V[\x90V\x00\xa1ebzzr0X Ks\x04pt'-\x02$\\\xbf\x86\x9c\x0f\xf8\xfa\xbf\x97\xda\xb8/\xd6X\xc8|\xadp\xc6JQpC\x00)"
funid = None, abi = None, profiling = 0

   def _send(self, sender, to, value, evmdata='', funid=None, abi=None,  # pylint: disable=too-many-arguments
             profiling=0):
       # pylint: disable=too-many-locals

       if funid is not None or abi is not None:
           raise Exception(
               'Send with funid+abi is deprecated. Please use the abi_contract mechanism'
           )

       start_time = time.time()
       gas_used = self.block.gas_used

       sendnonce = self.block.get_nonce(privtoaddr(sender))
       transaction = transactions.Transaction(sendnonce, gas_price, gas_limit, to, value, evmdata)
       self.last_tx = transaction
       transaction.sign(sender)
       recorder = None

       if profiling > 1:
           recorder = LogRecorder(
               disable_other_handlers=True,
               log_config=TRACE_LVL_MAP[3],
           )

       try:
           (success, output) = processblock.apply_transaction(self.block, transaction)

           if not success:
>               raise TransactionFailed()
E               TransactionFailed

/Library/Python/2.7/site-packages/ethereum/tester.py:296: TransactionFailed
------------------------------------- Captured log call --------------------------------------
rpc.py                     129 INFO     eth_blockNumber
============================ 1 failed, 4 warnings in 1.41 seconds ============================

更新:

我使用楊樹的方式:

$ mkdir populus_workspace && cd populus_workspace
$ [~/populus_workspace] populus init
Created Directory: ./contracts
Created Example Contract: ./contracts/Greeter.sol
Created Directory: ./tests
Created Example Tests: ./tests/test_greeter.py
$ py.test --capture=fd tests/test_greeter.py -s --disable-pytest-warnings
==================================== test session starts =====================================
platform darwin -- Python 2.7.10, pytest-3.5.0, py-1.5.3, pluggy-0.6.0
rootdir: /Users/alper/mu, inifile:
plugins: populus-2.0.1
collected 2 items

tests/test_greeter.py ..

============================ 2 passed, 6 warnings in 0.82 seconds ============================

我嘗試時基於@mafrasi2 的回答:

my_contract, _   = chain.provider.get_or_deploy_contract('eBlocBroker', deploy_transaction={"gas": 4000001})

我收到以下錯誤消息:

block = <Block(#1 2bb28319)>, tx = <Transaction(751d)>

   def validate_transaction(block, tx):

       def rp(what, actual, target):
           return '%r: %r actual:%r target:%r' % (tx, what, actual, target)

       # (1) The transaction signature is valid;
       if not tx.sender:  # sender is set and validated on Transaction initialization
           if block.number >= config.default_config["METROPOLIS_FORK_BLKNUM"]:
               tx._sender = normalize_address(config.default_config["METROPOLIS_ENTRY_POINT"])
           else:
               raise UnsignedTransaction(tx)
       if block.number >= config.default_config["HOMESTEAD_FORK_BLKNUM"]:
               tx.check_low_s()

       # (2) the transaction nonce is valid (equivalent to the
       #     sender account's current nonce);
       acctnonce = block.get_nonce(tx.sender)
       if acctnonce != tx.nonce:
           raise InvalidNonce(rp('nonce', tx.nonce, acctnonce))

       # (3) the gas limit is no smaller than the intrinsic gas,
       # g0, used by the transaction;
       if tx.startgas < tx.intrinsic_gas_used:
           raise InsufficientStartGas(rp('startgas', tx.startgas, tx.intrinsic_gas_used))

       # (4) the sender account balance contains at least the
       # cost, v0, required in up-front payment.
       total_cost = tx.value + tx.gasprice * tx.startgas
       if block.get_balance(tx.sender) < total_cost:
           raise InsufficientBalance(rp('balance', block.get_balance(tx.sender), total_cost))

       # check block gas limit
       if block.gas_used + tx.startgas > block.gas_limit:
>           raise BlockGasLimitReached(rp('gaslimit', block.gas_used + tx.startgas, block.gas_limit))
E           BlockGasLimitReached: <Transaction(751d)>: 'gaslimit' actual:4000001 target:4000000

/Library/Python/2.7/site-packages/ethereum/processblock.py:112: BlockGasLimitReached

不幸的是,您現在不能在命令行上執行此操作。但是,Populus 還允許您使用腳本來部署您的合約,這為您提供了大量的自定義。

文件中的範例使用預設氣體量:

txhash = Crowdsale.deploy(
   transaction={"from": beneficiary},
   args=[beneficiary, multisig_address, 1]
)

您可以通過添加"gas": x到事務參數來簡單地更改它:

txhash = Crowdsale.deploy(
   transaction={"from": beneficiary, "gas": 4000000},
   args=[beneficiary, multisig_address, 1]
)

一般來說,您可以在 Populus中使用web3py的所有功能。甚至還有預先自動估計所需氣體量的功能:

gas_needed = Crowdsale.constructor(beneficiary, multisig_address, 1).estimateGas()

編輯:

我認為您打電話時會出現問題get_or_deploy_contract()?在這種情況下,您可以使用:

chain.provider.get_or_deploy_contract('eBlocBroker', deploy_transaction={"gas": 4000000})

編輯2:

經過大量程式碼後,我有了一些新資訊。Populustester預設使用它的鏈。tester鍊錶示EthereumTesterProvider來自 web3py 。現在,有兩個版本EthereumTesterProvider:一個使用eth-tester,另一個使用eth-testrpc。第二個已棄用,但它是 Populus 使用的那個。現在,有兩種方法可以在 eth-testrpc 中設置塊氣體限制:

  • 或者,在呼叫之前將環境變數設置TESTRPC_GAS_LIMIT為非常高的值,例如 8000000py.test ...
  • 或者,將此程式碼段放入您的 test_*.py 文件中:
import pytest

@pytest.fixture(scope="session", autouse=True)
def adjust_block_gas_limit():
   import testrpc.client
   testrpc.client.client.DEFAULT_GAS_LIMIT = 8000000

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