सॉलिडिटी - विदड्रॉल पैटर्न

निकासी पैटर्न यह सुनिश्चित करता है कि डायरेक्ट ट्रांसफर कॉल न की जाए जिससे सुरक्षा को खतरा हो। निम्नलिखित अनुबंध ईथर भेजने के लिए स्थानांतरण कॉल का असुरक्षित उपयोग दिखा रहा है।

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;
      }
   }
}

उपरोक्त अनुबंध को अनुपयोगी स्थिति में प्रस्तुत किया जा सकता है, जिसके कारण सबसे अमीर व्यक्ति फेलबैक फंक्शन का अनुबंध कर सकता है। जब फॉलबैक फ़ंक्शन विफल होता है, तोRRestest () फ़ंक्शन भी विफल हो जाता है और अनुबंध हमेशा के लिए अटक जाएगा। इस समस्या को कम करने के लिए, हम विथड्राल पैटर्न का उपयोग कर सकते हैं।

निकासी पैटर्न में, हम प्रत्येक हस्तांतरण से पहले लंबित राशि को रीसेट कर देंगे। यह सुनिश्चित करेगा कि केवल कॉलर अनुबंध विफल हो।

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);
   }
}