Hi @chen,
msg.sender
is used in the body of a Solidity function to reference the address that calls this function. We may need to reference the caller’s address for very different reasons within the same function:
(1) Each user’s share of the total amount of ether held in the contract is recorded and tracked in the mapping. This is our internal accounting mechanism, and each individual user is identified by their external address (the address they are depositing ether into the contract from, and withdrawing ether out of the contract to). The mapping doesn’t hold ether: it records each individual user’s entitlement to withdraw ether from the Bank smart contract.
require(balances[msg.sender] >= amount);
So, as @alexdemc has explained …
Notice that it doesn’t check the total contract balance. It checks whether the address of the function caller is entitled to withdraw their requested amount from the smart contract. In order for the mapping to be used in this way, it is essential that …
(2)
Correct
Or in other words… the address calling the withdraw function is requesting that the Bank contract transfers the ether amount from the Bank contract address to their own external address (let’s say their wallet).
And as @alexdemc has also said …
e.g.
function withdraw(uint amount, address recipient) public {
require(balances[msg.sender] >= amount);
balances[msg.sender] -= amount;
payable(recipient).transfer(amount);
}
Here, the function caller (msg.sender
) is requesting that the Bank contract sends the ether amount
from the Bank contract to the external address input as the recipient
argument. But notice that the amount
has to be checked against, and deducted from, the msg.sender
's individual account balance in the mapping, because they are effectively transferring ether from their individual share of the total contract balance to the recipient.
The transfer function is different to the deposit and withdraw functions, in that it doesn’t involve any ether entering or leaving the Bank contract. It handles internal transfers of funds between existing Bank account holders. So, the net effect to the contract balance is zero. However, the contract still needs to adjust the amount each of the parties involved in the internal transfer is entitled to withdraw from the contract (their share of the total pooled funds) i.e. increase the receiver’s entitlement (balance) by the same amount the sender’s entitlement is reduced, with the code…
balance[from] -= amount;
balance[to] += amount;
I hope things are gradually becoming clearer