Solidity

“轉發”智能合約可以將收到的乙太幣轉發到另一個“轉發”智能合約,後者將其轉發到一個地址?

  • January 25, 2019

我對 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

  1. EVM 增加 2300 gas 津貼以防你轉移> 0 weis
  2. Solidity 編譯器添加了 2300 氣體來呼叫,以防您準確傳輸0 weis

以下程式碼有兩種不同的工作方式,具體取決於v

a.transfer(v)
  1. 如果v > 0EVM 提供 2300 的氣體,Solidity 編譯器提供 0 的氣體
  2. 如果v == 0EVM 提供 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)());
   }
}

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