In this contract:
contract auction {
address highestBidder;
uint highestBid;
mapping(address => uint) refunds;
function bid() payable external {
require(msg.value >= highestBid);
if (highestBidder != address(0)) {
refunds[highestBidder] += highestBid; // record the refund that this user can claim
}
highestBidder = msg.sender;
highestBid = msg.value;
}
function withdrawRefund() external {
uint refund = refunds[msg.sender];
refunds[msg.sender] = 0;
(bool success, ) = msg.sender.call.value(refund)("");
require(success);
}
}
To write a safe withdrawal function, we need to first empty the refunds mapping for the msg.sender
. Then we call .value(refund)("")
to transfer the ether to msg.sender
. After that, we check if the transfer was successful by writing require(success)
.
my question is what if the transaction failed and require(success)
doesn't pass? will the value of refunds[msg.sender]
remain 0 and he can't withdraw again?
Best Answer
If the transaction get fails all state changes will revert. So refunds[msg.sender] will be equal to what was it.