I was following a tutorial on building a simple Solidity program for Ethereum transactions between a smart contract and account. However, I didn't understand the following code:-

balanceReceived[msg.sender].payments[balanceReceived[msg.sender].numPayments] = payment;

Here's the full code:-

pragma solidity >=0.5.11 <0.7.0;
contract MappingsStructExample {
     struct Payment {
         uint amount;
         uint timestamps;
     struct Balance {
         uint totalBalance;
         uint numPayments;
         mapping (uint => Payment) payments;
     mapping(address => Balance)public balanceReceived;
     function getBalance() public view returns(uint) {
        return address(this).balance;
     function sendMoney() public payable {
         balanceReceived[msg.sender].totalBalance += msg.value;
         Payment memory payment = Payment(msg.value, now);//this stores 
         balanceReceived[msg.sender].payments[balanceReceived[msg.sender].numPayments] = payment;
     function withdrawMoney(address payable _to, uint _amount) public {
         require(_amount <= balanceReceived[msg.sender].totalBalance, "not enough funds");
         balanceReceived[msg.sender].totalBalance -= _amount;
     function withdrawAllMoney(address payable _to) public {
        uint balanceToSend = balanceReceived[msg.sender].totalBalance;
        balanceReceived[msg.sender].totalBalance = 0;

If I were to remove the code, the program won't have an impact. The program will still keep track of the payments made from the account as well as keep track of the amount being sent. Therefore, is it important to keep the code?

1 Answer 1


Payment memory payment = Payment(msg.value, now);//this stores

^ The comment //this stores is incorrect. This line just creates an instance of the payment struct and does not save it.

memory variables are temporary variables that exist only inside the calling function (they cannot be declared outside of one). They get wiped after the function exits...


The line you are asking about is what actually saves the payment struct within the balanceReceived mapping.

balanceReceived[msg.sender].payments[balanceReceived[msg.sender].numPayments] = payment;

This line would read: Get the Balance struct that corresponds to the current sender. In this balance struct, save the payment struct that was created in the previous line, to this balance struct's payments mapping at index numPayments.

  • Thank you. However, I don't understand the relation between numPayments and payments. Why would we store the payment struct to the balance struct's payments mapping at index numPayments? Why not totalBalance? Commented Jul 28, 2020 at 16:45
  • The numPayments essentially becomes a unique id for that payment struct so that you can look up that specific payment using the mapping and it's payment number at any point in the future. This also makes the payments relatively easy to find - in the future, you could read from the mapping by increasing the indexes by one. If you used total balance as the index for the mapping there would be a few problems. The total balance would not be unique which would result in overwriting old payments if you happened to end up at the same total value.
    – Steven V
    Commented Jul 28, 2020 at 21:55
  • 1
    That makes sense. Thank you for the explanation! Commented Jul 29, 2020 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.