Solidity

呼叫已部署合約的函式時,呼叫者合約轉發了多少gas?

  • January 6, 2022

考慮這個簡單的函式,

function setXFromAddress(address _addr, uint _x) public {
       Callee callee = Callee(_addr);
       callee.setX(_x);
   }

上面的程式碼從地址創建一個合約實例並呼叫它的方法。Solidity-by-example 表示與低級呼叫相比,這是推薦的方式。

我的問題是,有多少gas被轉發給被呼叫者合約?我知道通過電話我可以指定這樣發送多少,

function testCallFoo(address payable _addr) public payable {
       // You can send ether and specify a custom gas amount
       (bool success, bytes memory data) = _addr.call{value: msg.value, gas: 5000}(
           abi.encodeWithSignature("foo(string,uint256)", "call foo", 123)
       );

   }

那麼是什麼決定了第一種情況下發送了多少呢?假設被呼叫函式是狀態改變函式。此外,是否有任何方法會創建新交易?

從 Solidity 0.5.0 開始,預設情況下,所有可用的 gas 都將通過外部呼叫進行轉發(請參閱changelog)。

但重要的是要注意“所有可用氣體”的含義。EIP-150定義了“除一個 64 之外的所有”規則,該規則規定始終至少有 1/64 仍未用於此交易的氣體不能被發送。

錢包如何確定交易需要多少 gas?

大多數錢包用於eth_estimateGas估計交易的總氣體使用量。Geth 通過設置氣體限制進行二進制搜尋來實現這一點,直到他們找到交易不會失敗的值(例如,從塊氣體限制開始,然後嘗試一半等)。

如果您要求您的內部呼叫成功(例如require(success, "Internal call failed")),那麼此過程將估計正確的氣體量以使您的內部呼叫也成功(如果可能)。

如果您不執行此操作,那麼估計的氣體可能低於所需的氣體,因為即使內部交易失敗,外部交易也會成功。在這種情況下,使用 other 可能是有意義的,以強制有足夠的 gas 可用(例如require(gasleft() > 1000000, "I need a lot of gas"),但不鼓勵硬編碼,因為 gas 成本會隨著時間而變化。

最後一點:僅僅因為你指定了應該與呼叫一起發送的氣體,並不意味著真的會發送那麼多氣體。再次查看EIP-150,它定義瞭如果請求發送的氣體多於可用的氣體,那麼除了 1/64 之外的所有氣體都會被發送。

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