Bird
Raised Fist0
Blockchain / Solidityprogramming~20 mins

msg.value and msg.sender in Blockchain / Solidity - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Master of msg.value and msg.sender
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Solidity event log?

Consider the following Solidity contract snippet. A user calls sendEther with 1 ether. What will be the values emitted in the event?

Blockchain / Solidity
pragma solidity ^0.8.0;

contract Test {
    event Log(address sender, uint amount);

    function sendEther() public payable {
        emit Log(msg.sender, msg.value);
    }
}
AThe event logs the contract's address and zero ether.
BThe event logs the caller's address and zero ether.
CThe event logs the caller's address and the amount of ether sent (1 ether).
DThe event logs the zero address and the amount of ether sent.
Attempts:
2 left
💡 Hint

Remember, msg.sender is the caller's address and msg.value is the amount of ether sent with the call.

🧠 Conceptual
intermediate
1:30remaining
What does msg.value represent in Solidity?

Choose the best description of msg.value in a Solidity function call.

A<code>msg.value</code> is the amount of ether (in wei) sent with the transaction.
B<code>msg.value</code> is the block timestamp when the transaction was mined.
C<code>msg.value</code> is the address of the sender.
D<code>msg.value</code> is the amount of gas used by the transaction.
Attempts:
2 left
💡 Hint

Think about what value is transferred along with a payable function call.

❓ Predict Output
advanced
2:00remaining
What happens if a non-payable function tries to access msg.value with ether sent?

Given this contract, what will happen if nonPayableFunction is called with 1 ether?

Blockchain / Solidity
pragma solidity ^0.8.0;

contract Test {
    function nonPayableFunction() public {
        uint amount = msg.value;
    }
}
AThe transaction will revert because the function is not payable but ether was sent.
BThe function will run and <code>amount</code> will be 1 ether.
CThe function will run and <code>amount</code> will be zero.
DThe function will ignore <code>msg.value</code> and continue without error.
Attempts:
2 left
💡 Hint

Consider the payable modifier and what happens when ether is sent to a non-payable function.

🧠 Conceptual
advanced
1:30remaining
Which statement about msg.sender is true?

Choose the correct statement about msg.sender in Solidity.

A<code>msg.sender</code> is the address of the contract currently executing the code.
B<code>msg.sender</code> can be a contract address if the call was made by another contract.
C<code>msg.sender</code> is always the original external account that started the transaction.
D<code>msg.sender</code> is always the zero address when called internally.
Attempts:
2 left
💡 Hint

Think about calls between contracts and external accounts.

🔧 Debug
expert
2:30remaining
Why does this contract fail to receive ether?

Examine the contract below. Why does sending ether to receiveEther fail?

Blockchain / Solidity
pragma solidity ^0.8.0;

contract Test {
    function receiveEther() public {
        uint received = msg.value;
    }
}
AThe function does not emit an event to confirm ether reception.
BThe function does not have a fallback function to accept ether.
CThe contract does not have a constructor to initialize ether reception.
DThe function is not marked payable, so it cannot receive ether.
Attempts:
2 left
💡 Hint

Check the function modifiers required to accept ether.

Practice

(1/5)
1. What does msg.sender represent in a smart contract?
easy
A. The amount of ether sent with the transaction
B. The address of the account that called the contract
C. The balance of the contract
D. The gas price of the transaction

Solution

  1. Step 1: Understand the role of msg.sender

    msg.sender always holds the address of the account or contract that called the current function.
  2. Step 2: Differentiate from msg.value

    msg.value holds the amount of ether sent, not the caller's address.
  3. Final Answer:

    The address of the account that called the contract -> Option B
  4. Quick Check:

    msg.sender = caller address [OK]
Hint: Remember: sender is who calls, value is what is sent [OK]
Common Mistakes:
  • Confusing msg.sender with msg.value
  • Thinking msg.sender is contract balance
  • Assuming msg.sender is always a user (it can be a contract)
2. Which of the following is the correct way to check if the caller sent at least 1 ether in Solidity?
easy
A. if (msg.value >= 1 ether) {}
B. if (msg.value == msg.sender) {}
C. if (msg.sender >= 1 ether) {}
D. if (msg.sender == 1 ether) {}

Solution

  1. Step 1: Identify the variable holding sent ether amount

    msg.value stores the amount of ether sent with the call.
  2. Step 2: Use comparison to check minimum ether sent

    Checking if msg.value >= 1 ether correctly tests if at least 1 ether was sent.
  3. Final Answer:

    if (msg.value >= 1 ether) {} -> Option A
  4. Quick Check:

    Check ether amount with msg.value [OK]
Hint: Use msg.value to check ether sent, not msg.sender [OK]
Common Mistakes:
  • Using msg.sender to compare ether amounts
  • Using equality instead of >= for minimum check
  • Mixing up msg.sender and msg.value in conditions
3. What will be the output of this Solidity function when called by address 0xABC with 2 ether sent?
function pay() public payable returns (address, uint) {
    return (msg.sender, msg.value);
}
medium
A. (0xABC, 0)
B. (msg.sender, msg.value)
C. (address(0), 2 ether)
D. (0xABC, 2 ether)

Solution

  1. Step 1: Understand msg.sender and msg.value in the function

    msg.sender is the caller's address (0xABC), and msg.value is the ether sent (2 ether).
  2. Step 2: Return values match caller and sent ether

    The function returns these two values exactly as (0xABC, 2 ether).
  3. Final Answer:

    (0xABC, 2 ether) -> Option D
  4. Quick Check:

    Caller and sent ether returned correctly [OK]
Hint: Returned values match caller address and sent ether [OK]
Common Mistakes:
  • Assuming msg.value is zero if not explicitly set
  • Confusing msg.sender with zero address
  • Expecting variable names instead of actual values
4. Identify the error in this Solidity function that tries to check if the caller sent ether:
function deposit() public {
    require(msg.value > 0, "Send some ether");
}
medium
A. Missing payable keyword in function declaration
B. Incorrect use of require syntax
C. msg.value cannot be compared with > 0
D. Function should return a value

Solution

  1. Step 1: Check function declaration for payable

    To receive ether and access msg.value, the function must be marked payable.
  2. Step 2: Identify missing payable keyword

    The function lacks payable, so msg.value will always be zero and cause errors.
  3. Final Answer:

    Missing payable keyword in function declaration -> Option A
  4. Quick Check:

    Functions receiving ether must be payable [OK]
Hint: Add payable to receive ether and use msg.value [OK]
Common Mistakes:
  • Forgetting payable keyword
  • Thinking require syntax is wrong
  • Expecting function to return value unnecessarily
5. You want to write a Solidity function that only accepts payments from a specific address and requires at least 0.5 ether sent. Which code snippet correctly enforces both conditions?
hard
A. function pay() public payable { require(msg.sender != 0x123 && msg.value > 0.5 ether); }
B. function pay() public { require(msg.sender == 0x123); require(msg.value >= 0.5 ether); }
C. function pay() public payable { require(msg.sender == 0x123 && msg.value >= 0.5 ether, "Unauthorized or insufficient funds"); }
D. function pay() public payable { if (msg.sender == 0x123 || msg.value >= 0.5 ether) {} }

Solution

  1. Step 1: Ensure function is payable to accept ether

    Only options A, C, and D have payable, needed to receive ether.
  2. Step 2: Check conditions for sender and ether amount

    function pay() public payable { require(msg.sender == 0x123 && msg.value >= 0.5 ether, "Unauthorized or insufficient funds"); } uses require with AND (&&) to enforce both sender address and minimum ether sent.
  3. Step 3: Evaluate other options for correctness

    function pay() public { require(msg.sender == 0x123); require(msg.value >= 0.5 ether); } lacks payable, so msg.value is always zero. function pay() public payable { if (msg.sender == 0x123 || msg.value >= 0.5 ether) {} } uses OR (||), allowing either condition alone. function pay() public payable { require(msg.sender != 0x123 && msg.value > 0.5 ether); } uses != which rejects the correct sender.
  4. Final Answer:

    function pay() public payable { require(msg.sender == 0x123 && msg.value >= 0.5 ether, "Unauthorized or insufficient funds"); } -> Option C
  5. Quick Check:

    Use payable and require with AND for both checks [OK]
Hint: Use payable and require with && to check sender and value [OK]
Common Mistakes:
  • Forgetting payable keyword
  • Using OR instead of AND for conditions
  • Checking msg.sender with != instead of ==
  • Not combining conditions in one require
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard