Solidity - 提款模式



提款模式確保不會進行直接轉賬呼叫,這會帶來安全風險。以下合約展示了不安全的轉賬呼叫方式來發送以太幣。

pragma solidity ^0.5.0;

contract Test {
   address payable public richest;
   uint public mostSent;

   constructor() public payable {
      richest = msg.sender;
      mostSent = msg.value;
   }
   function becomeRichest() public payable returns (bool) {
      if (msg.value > mostSent) {
         // Insecure practice
         richest.transfer(msg.value);
         richest = msg.sender;
         mostSent = msg.value;
         return true;
      } else {
         return false;
      }
   }
}

上述合約可以透過使最富有者成為回退函式失敗的合約來使其處於不可用狀態。當回退函式失敗時,becomeRichest() 函式也會失敗,合約將永遠卡住。為了減輕這個問題,我們可以使用提款模式。

在提款模式中,我們將在每次轉賬前重置待處理金額。這將確保只有呼叫者合約失敗。

pragma solidity ^0.5.0;

contract Test {
   address public richest;
   uint public mostSent;

   mapping (address => uint) pendingWithdrawals;

   constructor() public payable {
      richest = msg.sender;
      mostSent = msg.value;
   }
   function becomeRichest() public payable returns (bool) {
      if (msg.value > mostSent) {
         pendingWithdrawals[richest] += msg.value;
         richest = msg.sender;
         mostSent = msg.value;
         return true;
      } else {
         return false;
      }
   }
   function withdraw() public {
      uint amount = pendingWithdrawals[msg.sender];
      pendingWithdrawals[msg.sender] = 0;
      msg.sender.transfer(amount);
   }
}
廣告
© . All rights reserved.