By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
Gaming and Metaverse on blockchain combine play?to?earn (P2E) mechanics, on?chain assets (NFTs, tokens), and persistent virtual worlds that are owned and governed by players. Because every item, character, or piece of land lives as a smart?contract?controlled token, players can truly own, trade, or monetize their in?game achievements without a central publisher. A concrete example is Axie Infinity – a P2E game where each Axie is an ERC?721 NFT, battles are settled by an on?chain battle contract, and the in?game currency (SLP) is an ERC?20 token that can be swapped on decentralized exchanges like Uniswap.
ERC?721 (NFT): Non?fungible token standard for unique game items. solidity contract Hero is ERC721("Hero", "HERO") { function mint(address to, uint256 tokenId) external { _safeMint(to, tokenId); } }
solidity contract Hero is ERC721("Hero", "HERO") { function mint(address to, uint256 tokenId) external { _safeMint(to, tokenId); } }
ERC?1155 (Multi?Token): Single contract that can hold both fungible (currency) and non?fungible (equipment) tokens, saving gas for batch operations. solidity contract GameItems is ERC1155("ipfs://metadata/{id}.json") { function batchMint(address to, uint256[] memory ids, uint256[] memory amounts) external { _mintBatch(to, ids, amounts, ""); } }
solidity contract GameItems is ERC1155("ipfs://metadata/{id}.json") { function batchMint(address to, uint256[] memory ids, uint256[] memory amounts) external { _mintBatch(to, ids, amounts, ""); } }
Play?to?Earn (P2E): Game design where players earn on?chain tokens for actions (e.g., completing quests, winning battles).
GameFi: Fusion of gaming + decentralized finance; includes staking, liquidity mining, and yield farming around game assets.
Metaverse DAO: A decentralized autonomous organization that governs a virtual world (land sales, rule changes, revenue splits). solidity contract WorldDAO is Governor { // inherits OpenZeppelin Governor; proposals vote with ERC20 governance token }
solidity contract WorldDAO is Governor { // inherits OpenZeppelin Governor; proposals vote with ERC20 governance token }
Battle?Proof (Zero?Knowledge): ZK?SNARK proof that a player’s battle outcome is valid without revealing hidden stats, reducing on?chain data.
Layer?2 Rollup (Optimistic/ZK): Scaling solution that batches many game transactions off?chain and posts a succinct proof to Ethereum, cutting gas dramatically.
Randomness (VRF): Verifiable Random Function (Chainlink) to generate provably fair random numbers for loot drops. solidity contract LootBox is VRFConsumerBase { function requestRandom() external { requestRandomWords(keyHash, subId, 3, 200000, 1); } }
solidity contract LootBox is VRFConsumerBase { function requestRandom() external { requestRandomWords(keyHash, subId, 3, 200000, 1); } }
Soulbound Token (SBT): Non?transferable token representing a player’s reputation or achievements; useful for anti?cheat and identity.
Gas?Optimized Loop: Use unchecked { i++ } in Solidity 0.8+ when you know overflow cannot happen, saving ~5 gas per iteration.
unchecked { i++ }
Cross?Chain Bridge: Smart contract pair that locks assets on one chain and mints a wrapped version on another (e.g., moving an NFT from Ethereum to Polygon for cheaper gameplay).
Marketplace Proxy Pattern: Upgradeable contract that forwards calls to a logic contract, allowing the game’s marketplace to be patched without moving user funds.
npx hardhat init && npm install @openzeppelin/contracts
bash npx hardhat run scripts/deploy.js --network goerli
js const contract = new ethers.Contract(address, abi, signer); await contract.requestRandom();
hardhat.config.ts
Mistake: Using tx.origin for player authentication. Correction: Always rely on msg.sender (or signed messages) because tx.origin can be hijacked through phishing contracts.
tx.origin
msg.sender
Mistake: Storing large arrays of player data on?chain (e.g., full inventory). Correction: Keep only essential identifiers on?chain; store heavy data off?chain (IPFS, Arweave) and reference it via a hash.
Mistake: Forgetting to pull ERC?20 tokens before rewarding players, leading to failed transactions. Correction: Use the pull?payment pattern (IERC20.transferFrom) and require users to approve the game contract first.
IERC20.transferFrom
Mistake: Deploying a single?owner upgradeable proxy and never renouncing ownership. Correction: After the initial audit, either renounce ownership (proxyAdmin.transferOwnership(address(0))) or move ownership to a multisig DAO.
proxyAdmin.transferOwnership(address(0))
Mistake: Relying on block timestamps for randomness or cooldowns. Correction: Use Chainlink VRF for randomness and block numbers for deterministic cooldowns; timestamps can be manipulated by miners.
call
delegatecall
call executes code in the target contract’s storage, while delegatecall runs the target’s code in the caller’s storage – essential for proxy upgrades but a common source of re?entrancy bugs.
“Why would you choose ERC?1155 over separate ERC?721 and ERC?20 contracts for a virtual world?”
ERC?1155 batches transfers, reduces gas, and lets you treat consumables (fungible) and gear (non?fungible) uniformly, which is crucial for high?frequency game actions.
“What are the trade?offs between Optimistic Rollups and ZK Rollups for a fast?paced MMO?”
Optimistic rollups have lower on?chain proof costs but require a 7?day challenge period (delayed finality); ZK rollups give instant finality and stronger privacy at higher prover costs.
“How do you prevent ‘item duplication’ attacks when minting NFTs after a battle?”
used
require(!battleUsed[id])
Scenario: A game contract uses tx.origin == player to verify that the caller is the player. Answer: Wrong – tx.origin can be spoofed via a malicious contract. Why: An attacker can trick the player into calling a malicious contract that then calls the game contract, making tx.origin appear legitimate.
tx.origin == player
Scenario: You need to let players stake their ERC?20 gold to earn a share of marketplace fees. Which pattern should you use? Answer: Pull?payment (or “withdraw pattern”). Why: It avoids re?entrancy and lets the contract safely accumulate fees before users withdraw them.
Scenario: A developer wants to store a player’s full inventory on?chain for transparency. Answer: Don’t – store only a hash or token IDs on?chain and keep the heavy data off?chain. Why: On?chain storage is expensive (?20?k gas per 32?byte slot) and can quickly exceed block gas limits.
uint256 public constant MAX_SUPPLY = 10_000;
TransparentUpgradeableProxy
ProxyAdmin
Transfer
Minted
Staked
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.