The withdrawal pattern lays the burden of proof on the fund receiver. The fund recipient must send a transaction to withdraw and retrieve their money.
This simplifies a smart contract that sends payments to recipients. This is because the contract doesn’t have to deal with the funds not being delivered. A smart contract has no way of knowing whether the money was sent due to an error or whether the receiver is a malevolent smart contract refusing to accept the purpose payments.
The article, Building Ethereum Payment Channels, raised the question of why shutting a channel adds funds to a balance rather than simply returning cash to channel members. This process is called the withdrawal pattern. This part of the shot explains why it is required. The problem develops when an Ethereum transaction attempts to transmit funds to an address, not under the sender’s control. The following is a much-simplified sample contract that does this:
pragma solidity ^0.5.0;contract BadSplitter {uint256 funds;address sender;address recipient;// Deposit some funds in to the contractfunction deposit(address other) payable {funds = msg.value;sender = msg.sender;recipient = other;}// Split an amount of funds between the sender and the recipientfunction split() {// Can only be called by the recipientrequire(msg.sender == recipient);// Split the fundssender.transfer(funds / 2);recipient.transfer(funds / 2);}}
Please notice that this contract is just meant to be used as an example and is completely unsuited for actual work.The following is how this contract works.
The sender makes a deposit()
transaction, and the receiver submits a split()
transaction with the recipient’s address. This sends half of the deposit to the recipient and half back to the sender. In-line comments are also provided for better understanding. We can also explain this graphically in the following way: