Bird
Raised Fist0
Blockchain / Solidityprogramming~20 mins

Reading contract state in Blockchain / Solidity - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Master of Reading Contract State
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 contract state read?

Consider the following Solidity contract snippet. What will be the output of the getBalance function call?

Blockchain / Solidity
pragma solidity ^0.8.0;

contract Wallet {
    mapping(address => uint) private balances;

    constructor() {
        balances[msg.sender] = 100;
    }

    function getBalance(address user) public view returns (uint) {
        return balances[user];
    }
}
A0
BRevert error
CCompilation error
D100
Attempts:
2 left
💡 Hint

Think about which address is passed to getBalance and what the mapping contains.

🧠 Conceptual
intermediate
1:30remaining
Which statement about reading contract state is true?

Choose the correct statement about reading state variables in a smart contract.

AState variables cannot be read from outside the contract.
BState variables can be read without gas cost if called externally as a view function.
CReading state variables always costs gas regardless of call type.
DState variables are automatically public and readable by anyone.
Attempts:
2 left
💡 Hint

Consider the difference between view functions and transactions.

🔧 Debug
advanced
2:30remaining
Why does this contract state read revert?

Examine the following Solidity function that reads a contract's state. Why does calling getOwnerBalance revert?

Blockchain / Solidity
pragma solidity ^0.8.0;

contract Bank {
    address private owner;
    mapping(address => uint) private balances;

    constructor() {
        owner = msg.sender;
        balances[owner] = 500;
    }

    function getOwnerBalance() public view returns (uint) {
        require(owner != address(0), "Owner not set");
        return balances[owner];
    }

    function resetOwner() public {
        owner = address(0);
    }
}
ABecause constructor did not initialize balances, it reverts.
BBecause balances mapping is private, reading it causes revert.
CBecause owner was reset to address(0), the require fails causing revert.
DBecause getOwnerBalance is not marked view, it reverts.
Attempts:
2 left
💡 Hint

Check the require condition and what happens if resetOwner is called before getOwnerBalance.

📝 Syntax
advanced
1:30remaining
Which option correctly reads a public state variable in Solidity?

Given a public state variable uint public count;, which function correctly returns its value?

Blockchain / Solidity
pragma solidity ^0.8.0;

contract Counter {
    uint public count;

    // Choose the correct function to read count
}
Afunction getCount() public returns (uint) { return count; }
Bfunction getCount() external pure returns (uint) { return count; }
Cfunction getCount() private view returns (uint) { return count; }
Dfunction getCount() public view returns (uint) { return count; }
Attempts:
2 left
💡 Hint

Remember the keywords needed to read state variables without modifying state.

🚀 Application
expert
3:00remaining
How many items are in the returned array after reading contract state?

Consider this Solidity contract that stores user addresses and balances. After calling getUsersWithBalanceAbove(50), how many addresses are returned?

Blockchain / Solidity
pragma solidity ^0.8.0;

contract UserBalances {
    address[] private users;
    mapping(address => uint) private balances;

    constructor() {
        users.push(0x1111111111111111111111111111111111111111);
        balances[0x1111111111111111111111111111111111111111] = 100;
        users.push(0x2222222222222222222222222222222222222222);
        balances[0x2222222222222222222222222222222222222222] = 40;
        users.push(0x3333333333333333333333333333333333333333);
        balances[0x3333333333333333333333333333333333333333] = 60;
    }

    function getUsersWithBalanceAbove(uint threshold) public view returns (address[] memory) {
        uint count = 0;
        for (uint i = 0; i < users.length; i++) {
            if (balances[users[i]] > threshold) {
                count++;
            }
        }

        address[] memory result = new address[](count);
        uint index = 0;
        for (uint i = 0; i < users.length; i++) {
            if (balances[users[i]] > threshold) {
                result[index] = users[i];
                index++;
            }
        }
        return result;
    }
}
A2
B3
C1
D0
Attempts:
2 left
💡 Hint

Count how many users have balances strictly greater than 50.

Practice

(1/5)
1. What is the main purpose of using .call() when interacting with a blockchain smart contract?
easy
A. To send tokens to another address
B. To read data from the contract without changing its state
C. To deploy a new smart contract
D. To mine a new block on the blockchain

Solution

  1. Step 1: Understand what .call() does

    .call() is used to read data from a smart contract without creating a transaction or changing the blockchain state.
  2. Step 2: Compare with other blockchain actions

    Sending tokens or deploying contracts changes state and requires transactions, unlike .call().
  3. Final Answer:

    To read data from the contract without changing its state -> Option B
  4. Quick Check:

    .call() reads state without transactions [OK]
Hint: Use .call() only to read data, not to write [OK]
Common Mistakes:
  • Thinking .call() sends transactions
  • Confusing .call() with contract deployment
  • Assuming .call() changes contract state
2. Which of the following is the correct syntax to read a contract's public variable balance using .call() in JavaScript?
easy
A. const bal = contract.methods.balance().call();
B. const bal = contract.call.methods.balance();
C. const bal = contract.methods.balance();
D. const bal = contract.balance.call();

Solution

  1. Step 1: Recall the correct method call pattern

    To read a contract variable, use contract.methods.variableName().call() in JavaScript.
  2. Step 2: Check each option's syntax

    const bal = contract.methods.balance().call(); matches the correct pattern. Options B, C, and D have incorrect method chaining or missing .call().
  3. Final Answer:

    const bal = contract.methods.balance().call(); -> Option A
  4. Quick Check:

    Correct syntax = const bal = contract.methods.balance().call(); [OK]
Hint: Remember: contract.methods.<name>().call() reads state [OK]
Common Mistakes:
  • Placing .call() before .methods
  • Omitting .call() when reading
  • Using contract.balance.call() directly
3. Given the following Solidity contract snippet:
contract Wallet {
    uint public balance = 100;
    function getBalance() public view returns (uint) {
        return balance;
    }
}

What will be the output of this JavaScript code?
const bal = await contract.methods.getBalance().call();
console.log(bal);
medium
A. 100
B. undefined
C. Error: getBalance is not a function
D. 0

Solution

  1. Step 1: Understand the Solidity function

    The getBalance() function returns the current balance value, which is 100.
  2. Step 2: Analyze the JavaScript call

    The JavaScript code calls getBalance() using .call(), which reads the value without changing state, returning 100.
  3. Final Answer:

    100 -> Option A
  4. Quick Check:

    Calling view function returns stored value [OK]
Hint: View functions return stored values via .call() [OK]
Common Mistakes:
  • Expecting a transaction receipt instead of value
  • Confusing .call() with sending a transaction
  • Assuming default value is zero
4. You try to read a contract's state variable using contract.methods.value.call (without parentheses). What error will you most likely encounter?
medium
A. TypeError: contract.methods.value.call is not a function, missing parentheses
B. SyntaxError: Unexpected token
C. No error, returns the value directly
D. TypeError: contract.methods.value.call is not a function

Solution

  1. Step 1: Identify the missing parentheses issue

    .call is a function and must be invoked with parentheses ().
  2. Step 2: Understand the error message

    Without parentheses, JavaScript treats .call as a property, causing a TypeError indicating it's not a function call.
  3. Final Answer:

    TypeError: contract.methods.value.call is not a function -> Option D
  4. Quick Check:

    Missing () on .call() causes TypeError [OK]
Hint: Always add () after .call to execute it [OK]
Common Mistakes:
  • Forgetting parentheses on .call()
  • Assuming .call is a property, not a function
  • Ignoring JavaScript function call syntax
5. You want to read multiple state variables owner (address) and totalSupply (uint) from a deployed contract efficiently. Which approach is best?
hard
A. Call contract.methods.owner().call() and contract.methods.totalSupply().call() separately
B. Use contract.methods.owner.call and contract.methods.totalSupply.call without parentheses
C. Create a new contract function that returns both variables in a tuple and call it once
D. Read owner with .call() and read totalSupply from the blockchain directly

Solution

  1. Step 1: Understand multiple calls cost

    Calling each variable separately sends multiple requests, which is less efficient.
  2. Step 2: Use a combined function

    Creating a contract function that returns both variables together reduces calls and improves efficiency.
  3. Final Answer:

    Create a new contract function that returns both variables in a tuple and call it once -> Option C
  4. Quick Check:

    Batch reading state reduces calls and improves performance [OK]
Hint: Batch reads in one call for efficiency [OK]
Common Mistakes:
  • Making multiple separate calls unnecessarily
  • Trying to read blockchain data outside contract calls
  • Forgetting parentheses on .call()