為什麼address.call
函式在內部執行後“節省”了不必要的gas?
我為 ropsten 部署了一個多重簽名錢包的合約並嘗試測試它的能力: https ://ropsten.etherscan.io/address/0x8bf20c41ee6a9fd84e81d6f6df872d9628cd08b2
工作正常的事情:
- 提取 ETH
- 向其他合約發送交易(轉賬 erc20 代幣)
沒有按預期工作的事情:
- 添加所有者
- 更換所有者
- 基本上每一次錢包找零交易都失敗了
為什麼以及如何失敗?
交易範例:https ://ropsten.etherscan.io/tx/0xf4074abba33252d79dcdd234071dff25c7eba205ddb777076e623d6d108b7392
First I use the wallet
submitTransaction
function and submitted a transaction to the same wallet contract with data that call the internal transaction change,addOwner
. Then I used another owner key to confirm it. When the transaction got the required confirmations the contract called the methodexecuteTransaction
which execute this call:
txn.destination.call.value(txn.value)(txn.data)
In this example
txn.data
is0x7065cb480000000000000000000000009ac4f6e64d56043991f486e375994f67ecbfdde0
callingaddOwner("0x9ac4f6e64d56043991f486e375994f67ecbfdde0")
txn.value
is0
As you can see, the internal transaction is failing due to
out of gas
.Did a little research and found out that after the
call
function, the contract “saves” some gas for after the internal transaction invoke, and the internal transaction invoked with only 700 gas that consumed immediately by theCALL
opcode.https://ropsten.etherscan.io/vmtrace?txhash=0xf4074abba33252d79dcdd234071dff25c7eba205ddb777076e623d6d108b7392 line 728:
Funny thing is, that at the end of the external transaction, the execution left with 27511 gas.
Some other wired stuff:
- If I give the transaction a lot of gas (x10) it works fine.
- If I use different contract to interact with (for example
erc20.transfer
) it works fine.- If I use the
executeTransaction
by itself (after the transaction is confirmed), it works fine.So, What is going on? Why the gas estimation not working?
PS I tried it both with MEW and web3 js code for gas estimation.
So there is some unexpected behavior in the solidity compiler:
https://github.com/ethereum/solidity/issues/2999
適用於
pragma experimental "v0.5.0";
編譯器 0.4.18。