Hi @jeanphi,
When users call the deposit() function, ether is transferred from their external wallet addresses to the contract address. The contract address balance is therefore the total amount of ether belonging to all account holders. The balances in the mapping perform an internal accounting role, and keep track of each user’s share of the total pooled funds. Without them there would be no way of knowing what each individual user’s entitlement was. The ether itself is held by the contract address, and not in the mapping.
When a user calls the withdraw() function, ether is transferred from the contract address to the user’s external wallet address. First of all we perform the internal accounting adjustment to record the reduction in the user’s share of the total pooled funds:
balance[msg.sender] -= amount;
Then we perform the actual transfer of ether from the contract address balance to the user’s external wallet address, using:
<address payable>.transfer(uint256 amount);
When a user calls the transfer() function, no ether is entering or leaving the contract. The total contract address balance doesn’t change. It is purely an internal transfer between users which results in a decrease in the sender’s share of the total contract balance, and an increase, by an equal amount, in the recipient’s share of the total contract balance. It is therefore only necessary to adjust each user’s individual balance in the mapping (two equal and opposite internal accounting adjustments).
You can see a user’s external wallet address balance increase and decrease as ether is either withdrawn from, or transferred to the Bank contract. We can check the total amount of ether held in the contract (the contract address balance) by creating a getter and returning address(this).balance
e.g.
function getContractBalance() external view returns(uint) {
return address(this).balance;
}
Let me know if anything is still unclear, or if you have any further questions