Free Blockchain Developer Smart Contract Development Questions and Answers — Questions and Answers
Question 1: A developer is creating a decentralized finance (DeFi) application that allows users to lend and borrow assets. To prevent price manipulation of the collateral, the smart contract needs to fetch the latest asset prices from multiple off-chain exchanges. What is the most appropriate component to integrate for this purpose?
- A state channel to directly communicate with exchange APIs.
- A centralized server managed by the development team to push prices on-chain.
- A decentralized oracle network to retrieve and aggregate price data. (Correct answer)
- An on-chain library that calculates prices based on transaction volumes.
Correct answer: A decentralized oracle network to retrieve and aggregate price data.
Blockchains are deterministic, closed systems and cannot natively access external, off-chain data. A decentralized oracle network is the standard and most secure solution to this problem, acting as a bridge to bring real-world data, like asset prices, onto the blockchain for smart contracts to use.
Question 2: Which of the following Solidity code snippets is most vulnerable to a reentrancy attack during a withdrawal operation?
- function withdraw() public { require(balances[msg.sender] > 0); uint amount = balances[msg.sender]; balances[msg.sender] = 0; (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed."); }
- function withdraw() public { uint amount = balances[msg.sender]; require(amount > 0); (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed."); balances[msg.sender] = 0; } (Correct answer)
- function withdraw() public nonReentrant { require(balances[msg.sender] > 0); uint amount = balances[msg.sender]; balances[msg.sender] = 0; (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed."); }
- function withdraw() public { require(balances[msg.sender] > 0); balances[msg.sender] = 0; (bool success, ) = payable(msg.sender).send(balances[msg.sender]); require(success); }
Correct answer: function withdraw() public { uint amount = balances[msg.sender]; require(amount > 0); (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed."); balances[msg.sender] = 0; }
This code is vulnerable because it performs the external call (sending Ether) *before* it updates the user's balance. An attacker's contract can use its fallback function to call the `withdraw` function again before the balance is set to zero, allowing them to drain funds. The secure approach, known as the Checks-Effects-Interactions pattern, is to update the state (the balance) *before* interacting with the external contract (sending the Ether).
Question 3: A team is developing a smart contract system where the core logic may need to be updated over time to fix bugs or add new features, without requiring users to migrate their data to a new contract address. Which design pattern should they implement?
- The Factory Pattern
- The Singleton Pattern
- The Proxy Pattern (Correct answer)
- The Observer Pattern
Correct answer: The Proxy Pattern
The Proxy Pattern is specifically designed for upgradeability. It works by separating the contract's state and address (the proxy contract) from its logic (the implementation contract). To upgrade, a new implementation contract is deployed, and the proxy is updated to point to the new logic address, all while preserving the original state and public-facing address.
Question 4: In the context of an Ethereum transaction, what is the primary difference between `gas limit` and `gas price`?
- Gas limit is the total fee in ETH, while gas price is the computational complexity.
- Gas limit is the maximum amount of computational work a user is willing to pay for, while gas price is the fee paid per unit of that work. (Correct answer)
- Gas price is set by the network and is constant, while gas limit fluctuates based on transaction complexity.
- Gas limit is the amount of gas refunded if a transaction fails, while gas price is the non-refundable portion of the fee.
Correct answer: Gas limit is the maximum amount of computational work a user is willing to pay for, while gas price is the fee paid per unit of that work.
The `gas limit` is the maximum total number of gas units a user is willing to consume for a transaction. It's a cap to prevent runaway code from draining an account. The `gas price` (measured in Gwei) is the amount of ETH the user is willing to pay for each unit of gas. The total transaction fee is the gas used multiplied by the gas price.
Question 5: A developer needs to create a token to represent unique digital collectibles, where each token is distinct and has a specific owner. Which token standard is the most appropriate for this use case?
- ERC-1155, because it is the newest and most gas-efficient standard.
- ERC-20, because it is the most widely adopted standard for all token types.
- ERC-721, because it provides a standard interface for non-fungible tokens (NFTs). (Correct answer)
- ERC-777, because it offers advanced features for token interaction.
Correct answer: ERC-721, because it provides a standard interface for non-fungible tokens (NFTs).
The ERC-721 standard is specifically designed for non-fungible tokens (NFTs), where each token is unique and not interchangeable. This makes it the ideal choice for representing unique assets like digital art, collectibles, or real estate. ERC-20, in contrast, is for fungible tokens where each token is identical to another.
Question 6: In Solidity, which function visibility modifier restricts access to only the contract that defines the function, excluding even derived contracts?
- internal
- external
- public
- private (Correct answer)
Correct answer: private
The `private` visibility modifier is the most restrictive. Functions marked as `private` can only be called from within the same contract in which they are defined. They are not accessible to derived contracts or external contracts.
A developer is creating a decentralized finance (DeFi) application that allows users to lend and borrow assets.
To prevent price manipulation of the collateral, the smart contract needs to fetch the latest asset prices from multiple off-chain exchanges.
What is the most appropriate component to integrate for this purpose?