Solidity
“轉發”智能合約可以將收到的乙太幣轉發到另一個“轉發”智能合約,後者將其轉發到一個地址?
我對 Solidity 很陌生。我正在嘗試創建一個智能合約,該合約部署另一個智能合約並在向父合約支付大於 0.01 乙太幣的付款時將乙太幣轉移到新創建的合約。部署完成,但是當我嘗試將乙太幣發送到父合約時,我不斷收到“氣體不足”錯誤。有人可以讓我知道可能是什麼問題嗎?
謝謝!
pragma solidity ^0.4.8; contract Bakery { address[] public contracts; address public ContractAddress; event LogForwarded(address indexed sender, uint amount); event LogFlushed(address indexed sender, uint amount); function() payable external { emit LogForwarded(msg.sender, msg.value); if(msg.value > 0.001 ether) { Cookie c = new Cookie(); contracts.push(c); address(c).transfer(msg.value); } } } contract Cookie { address public destinationAddress; event LogForwarded(address indexed sender, uint amount); event LogFlushed(address indexed sender, uint amount); function Cookie() public { destinationAddress = 0x2e46E9A4542B28B39C21Ed859486147969CB949F; } function() payable external { emit LogForwarded(msg.sender, msg.value); destinationAddress.transfer(msg.value); } function flush() public { emit LogFlushed(msg.sender, address(this).balance); destinationAddress.transfer(address(this).balance); } }
這個特定的程式碼不能這樣做,因為
<address>.transfer()
只為接收者提供了 2300 個氣體,這不足以進行另一次乙太幣轉移。這可以通過在乙太轉移中提供更多的氣體來實現,例如
address(c).call.gas(50000)("")
。這轉發了 50,000 個 gas,這對於進行後續轉移應該綽綽有餘。
你應該知道https://ethereum-magicians.org/t/remediations-for-eip-1283-reentrancy-bug/2434/29:
- EVM 增加 2300 gas 津貼以防你轉移
> 0 weis
- Solidity 編譯器添加了 2300 氣體來呼叫,以防您準確傳輸
0 weis
以下程式碼有兩種不同的工作方式,具體取決於
v
:a.transfer(v)
- 如果
v > 0
EVM 提供 2300 的氣體,Solidity 編譯器提供 0 的氣體- 如果
v == 0
EVM 提供 0 的氣體,Solidity 編譯器提供 2300 的氣體所以
transfer
內部等於下面的程式碼:a.call.gas(v == 0 ? 2300 : 0).value(v)();
所以你不能通過提供少於 2300 的 gas 來轉發資金,因為 EVM 會嘗試提供額外的 2300 津貼:
contract A { address to = 0x***; function() payable external { // Will try to give 1150+2300 of gas require(to.call.gas(1150).value(msg.value)()); } }