By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
Smart contract development is the practice of writing, testing, and deploying self‑executing programs that run on the Ethereum Virtual Machine (EVM). These contracts replace trusted intermediaries with code, enabling decentralized finance (DeFi), NFTs, DAOs, and more. Real‑world example: the Uniswap V2 router contract that atomically swaps ERC‑20 tokens, guaranteeing the constant‑product invariant (x*y = k) without a central order book.
x*y = k
solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.21; contract Counter { uint256 public n; function inc() external { n++; } }
bash npx hardhat compile # compiles contracts in ./contracts npx hardhat test # runs Mocha/Chai tests against a local node
bash forge build # compile forge test # run tests anvil --fork https://eth-mainnet.alchemyapi.io/v2/<key> # local fork node
bash truffle compile truffle migrate --network goerli
solidity interface IERC20 { function transfer(address to, uint256 amount) external returns (bool); }
solidity contract MyNFT is ERC721("MyNFT", "MNFT") { function mint(address to, uint256 id) external { _safeMint(to, id); } }
solidity require(balances[msg.sender] >= amount); balances[msg.sender] -= amount; // effect (bool ok,) = msg.sender.call{value: amount}(""); // interaction require(ok);
js const { deploy } = deployments; const token = await deploy("MyToken", { from: deployer, args: [] });
vm
vm.prank(address)
msg.sender
MyToken.sol
npx hardhat node
anvil
test/MyToken.test.js
bash npx hardhat run scripts/deploy.js --network goerli # uses Infura/Alchemy RPC
forge script script/Deploy.s.sol --rpc-url $GOERLI_RPC --broadcast
new ethers.Contract(address, abi, signer)
transfer
mint
vote
Mistake: Using tx.origin for access control. Correction: Always rely on msg.sender; tx.origin can be spoofed through a malicious contract, opening a phishing vector.
tx.origin
Mistake: Forgetting to reset state after a failed external call (e.g., not rolling back a token transfer). Correction: Follow the CEI pattern or use require on the call’s return value; Solidity automatically reverts on a failed require.
require
Mistake: Hard‑coding the compiler version (pragma solidity 0.8.0;) and then compiling with a newer version that introduces breaking changes. Correction: Use a caret (^) or specify the exact version in hardhat.config.js / foundry.toml to guarantee reproducible builds.
pragma solidity 0.8.0;
^
hardhat.config.js
foundry.toml
Mistake: Deploying a contract with uninitialized storage variables (e.g., forgetting to set the owner in the constructor). Correction: Initialize all critical state in the constructor or via an initializer function when using proxies.
Mistake: Ignoring gas‑limit errors on testnets because the local node auto‑adjusts gas. Correction: Simulate realistic gas limits (hardhat set --gas-price 20gwei) and monitor estimateGas before sending transactions.
hardhat set --gas-price 20gwei
estimateGas
tokensReceived
ReentrancyGuard
Scenario: A contract uses tx.origin == owner to restrict withdrawals. Answer: Dangerous – a phishing contract can call the vulnerable contract on behalf of the owner, making tx.origin the owner’s address and allowing theft.
tx.origin == owner
Scenario: You deploy an ERC‑20 token but forget to emit the Transfer event in the mint function. Answer: Wallets and indexers rely on the Transfer event to track balances; omitting it breaks UI visibility and can cause off‑chain services to miss the mint.
Transfer
Scenario: A Hardhat test passes locally but fails on Goerli with “out‑of‑gas” errors. Answer: The local node may have an artificially high block gas limit; always run estimateGas and set realistic limits before mainnet deployment.
unchecked {}
SafeMath
TransparentUpgradeableProxy
UUPS
proxiableUUID
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.