Web3-Bites / Web3 Smart Contract Adventure
Theo-Web3's picture
Create Web3 Smart Contract Adventure
16d2b60 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web3 Smart Contract Adventure</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.blockchain-animation {
background: linear-gradient(90deg, #1a202c 0%, #2d3748 50%, #1a202c 100%);
background-size: 200% 100%;
animation: blockchainFlow 5s linear infinite;
}
@keyframes blockchainFlow {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.contract-code {
font-family: 'Courier New', monospace;
background-color: #2d3748;
border-left: 4px solid #4299e1;
}
.wallet-pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(66, 153, 225, 0.7); }
70% { box-shadow: 0 0 0 10px rgba(66, 153, 225, 0); }
100% { box-shadow: 0 0 0 0 rgba(66, 153, 225, 0); }
}
.transaction-animation {
transition: all 0.5s ease;
}
.terminal {
background-color: #1a202c;
font-family: 'Courier New', monospace;
height: 200px;
overflow-y: auto;
}
.terminal-line {
animation: typing 0.5s steps(40, end);
}
@keyframes typing {
from { width: 0 }
to { width: 100% }
}
</style>
</head>
<body class="bg-gray-900 text-gray-100 min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<header class="flex justify-between items-center mb-12">
<div class="flex items-center space-x-4">
<i class="fas fa-cube text-blue-400 text-3xl"></i>
<h1 class="text-3xl font-bold bg-gradient-to-r from-blue-400 to-purple-500 bg-clip-text text-transparent">
Web3 Smart Contract Adventure
</h1>
</div>
<div class="flex items-center space-x-4">
<div class="bg-gray-800 px-4 py-2 rounded-full flex items-center">
<i class="fas fa-coins text-yellow-400 mr-2"></i>
<span id="balance">100</span> ETH
</div>
<div id="wallet" class="wallet-pulse bg-blue-900 px-4 py-2 rounded-full cursor-pointer hover:bg-blue-800 transition">
<i class="fas fa-wallet mr-2"></i>
<span>0x7f...3a4b</span>
</div>
</div>
</header>
<!-- Game Progress -->
<div class="mb-8">
<div class="flex justify-between mb-2">
<span class="text-sm">Beginner's Journey</span>
<span class="text-sm">25% Complete</span>
</div>
<div class="w-full bg-gray-700 rounded-full h-2.5">
<div class="bg-blue-500 h-2.5 rounded-full" style="width: 25%"></div>
</div>
</div>
<!-- Main Game Area -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Left Panel - Lessons -->
<div class="lg:col-span-2 space-y-8">
<!-- Current Lesson -->
<div class="bg-gray-800 rounded-xl p-6 shadow-lg border-l-4 border-blue-500">
<h2 class="text-2xl font-bold mb-4 flex items-center">
<i class="fas fa-file-contract mr-3 text-blue-400"></i>
Lesson 2: Understanding Smart Contracts
</h2>
<div class="mb-6">
<p class="mb-4">Smart contracts are self-executing contracts with the terms of the agreement directly written into code. They run on blockchain networks like Ethereum.</p>
<div class="contract-code p-4 rounded-lg mb-4 text-sm">
<p class="text-blue-300">// Simple Storage Contract Example</p>
<p class="text-purple-300">pragma solidity ^0.8.0;</p>
<br>
<p class="text-blue-300">contract SimpleStorage {</p>
<p class="ml-4 text-gray-300"> uint storedData;</p>
<br>
<p class="ml-4 text-blue-300"> function set(uint x) public {</p>
<p class="ml-8 text-gray-300"> storedData = x;</p>
<p class="ml-4 text-blue-300"> }</p>
<br>
<p class="ml-4 text-blue-300"> function get() public view returns (uint) {</p>
<p class="ml-8 text-gray-300"> return storedData;</p>
<p class="ml-4 text-blue-300"> }</p>
<p class="text-blue-300">}</p>
</div>
<p class="mb-4">Key characteristics of smart contracts:</p>
<ul class="list-disc pl-6 space-y-2 mb-4">
<li><span class="font-semibold">Immutable:</span> Once deployed, the code cannot be changed</li>
<li><span class="font-semibold">Transparent:</span> Code is visible to everyone on the blockchain</li>
<li><span class="font-semibold">Self-executing:</span> Runs automatically when conditions are met</li>
<li><span class="font-semibold">Trustless:</span> No need for intermediaries</li>
</ul>
</div>
<div class="bg-blue-900 bg-opacity-30 p-4 rounded-lg mb-6">
<h3 class="font-bold text-lg mb-2 flex items-center">
<i class="fas fa-lightbulb mr-2 text-yellow-300"></i>
Interactive Exercise
</h3>
<p class="mb-4">Let's interact with a simulated smart contract. This contract stores a number that anyone can update.</p>
<div class="flex flex-wrap gap-4 mb-4">
<button id="readContract" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg flex items-center">
<i class="fas fa-book-open mr-2"></i> Read Contract
</button>
<button id="writeContract" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg flex items-center">
<i class="fas fa-edit mr-2"></i> Update Value
</button>
<button id="deployContract" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded-lg flex items-center">
<i class="fas fa-rocket mr-2"></i> Deploy New Contract
</button>
</div>
<div id="contractInteractionResult" class="bg-gray-700 p-3 rounded-lg hidden">
<p class="text-sm">Transaction result will appear here...</p>
</div>
</div>
<div class="flex justify-between">
<button class="bg-gray-700 hover:bg-gray-600 px-4 py-2 rounded-lg flex items-center">
<i class="fas fa-arrow-left mr-2"></i> Previous Lesson
</button>
<button class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg flex items-center">
Next Lesson <i class="fas fa-arrow-right ml-2"></i>
</button>
</div>
</div>
<!-- Quiz Section -->
<div id="quizSection" class="bg-gray-800 rounded-xl p-6 shadow-lg border-l-4 border-purple-500 hidden">
<h2 class="text-2xl font-bold mb-4 flex items-center">
<i class="fas fa-question-circle mr-3 text-purple-400"></i>
Knowledge Check
</h2>
<div class="mb-6">
<p class="mb-4">Test your understanding of smart contracts with these questions:</p>
<div class="space-y-4">
<div class="quiz-question bg-gray-700 p-4 rounded-lg">
<p class="font-semibold mb-2">1. What makes smart contracts different from traditional contracts?</p>
<div class="space-y-2">
<label class="flex items-center">
<input type="radio" name="q1" class="mr-2" value="a">
They are written in programming languages
</label>
<label class="flex items-center">
<input type="radio" name="q1" class="mr-2" value="b">
They are stored on a blockchain and execute automatically
</label>
<label class="flex items-center">
<input type="radio" name="q1" class="mr-2" value="c">
They require lawyers to interpret them
</label>
</div>
</div>
<div class="quiz-question bg-gray-700 p-4 rounded-lg">
<p class="font-semibold mb-2">2. What happens when you deploy a smart contract to Ethereum?</p>
<div class="space-y-2">
<label class="flex items-center">
<input type="radio" name="q2" class="mr-2" value="a">
It gets stored on the blockchain and receives an address
</label>
<label class="flex items-center">
<input type="radio" name="q2" class="mr-2" value="b">
It gets sent to all Ethereum users' computers
</label>
<label class="flex items-center">
<input type="radio" name="q2" class="mr-2" value="c">
It becomes part of the Ethereum core software
</label>
</div>
</div>
<div class="quiz-question bg-gray-700 p-4 rounded-lg">
<p class="font-semibold mb-2">3. Why are smart contracts considered "trustless"?</p>
<div class="space-y-2">
<label class="flex items-center">
<input type="radio" name="q3" class="mr-2" value="a">
Because you shouldn't trust them
</label>
<label class="flex items-center">
<input type="radio" name="q3" class="mr-2" value="b">
Because they eliminate the need for trusted third parties
</label>
<label class="flex items-center">
<input type="radio" name="q3" class="mr-2" value="c">
Because they are anonymous
</label>
</div>
</div>
</div>
</div>
<button id="submitQuiz" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full flex items-center justify-center">
<i class="fas fa-check-circle mr-2"></i> Submit Answers
</button>
</div>
</div>
<!-- Right Panel - Blockchain Simulator -->
<div class="space-y-8">
<!-- Blockchain Visualization -->
<div class="bg-gray-800 rounded-xl p-6 shadow-lg">
<h2 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-link mr-2 text-green-400"></i>
Blockchain Simulator
</h2>
<div class="blockchain-animation rounded-lg p-4 mb-4">
<div class="flex overflow-x-auto space-x-4 pb-2">
<div class="block bg-gray-700 p-3 rounded-lg min-w-[200px]">
<div class="text-xs text-gray-400 mb-1">Block #1</div>
<div class="text-sm mb-1">Genesis Block</div>
<div class="text-xs text-gray-400">0x000...000</div>
</div>
<div class="block bg-gray-700 p-3 rounded-lg min-w-[200px]">
<div class="text-xs text-gray-400 mb-1">Block #2</div>
<div class="text-sm mb-1">Your Wallet Created</div>
<div class="text-xs text-gray-400">0x7f3...a4b</div>
</div>
<div id="latestBlock" class="block bg-blue-900 p-3 rounded-lg min-w-[200px]">
<div class="text-xs text-gray-400 mb-1">Block #3</div>
<div class="text-sm mb-1">Ready for new transactions</div>
<div class="text-xs text-gray-400">Pending...</div>
</div>
</div>
</div>
<div class="terminal p-3 rounded-lg mb-4">
<div class="terminal-line text-green-400">$ Welcome to Web3 Adventure!</div>
<div class="terminal-line">$ Your wallet is connected: 0x7f...3a4b</div>
<div class="terminal-line">$ Balance: 100 ETH</div>
<div id="terminalOutput" class="terminal-line"></div>
</div>
<div class="text-center">
<button id="mineBlock" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded-lg flex items-center mx-auto">
<i class="fas fa-hammer mr-2"></i> Mine Block
</button>
</div>
</div>
<!-- Wallet Transactions -->
<div class="bg-gray-800 rounded-xl p-6 shadow-lg">
<h2 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-exchange-alt mr-2 text-yellow-400"></i>
Transaction History
</h2>
<div class="space-y-3">
<div class="transaction bg-gray-700 p-3 rounded-lg transaction-animation">
<div class="flex justify-between text-sm">
<span class="text-blue-300">Wallet Creation</span>
<span class="text-gray-400">2 min ago</span>
</div>
<div class="text-xs text-gray-400">+100 ETH</div>
</div>
<div id="newTransactions" class="space-y-3">
<!-- New transactions will appear here -->
</div>
</div>
</div>
<!-- Achievement Badges -->
<div class="bg-gray-800 rounded-xl p-6 shadow-lg">
<h2 class="text-xl font-bold mb-4 flex items-center">
<i class="fas fa-trophy mr-2 text-yellow-300"></i>
Your Achievements
</h2>
<div class="grid grid-cols-3 gap-3">
<div class="achievement bg-blue-900 bg-opacity-30 p-2 rounded-lg text-center">
<div class="mx-auto bg-blue-500 rounded-full w-10 h-10 flex items-center justify-center mb-1">
<i class="fas fa-check"></i>
</div>
<div class="text-xs">Wallet Setup</div>
</div>
<div class="achievement bg-gray-700 p-2 rounded-lg text-center opacity-50">
<div class="mx-auto bg-gray-500 rounded-full w-10 h-10 flex items-center justify-center mb-1">
<i class="fas fa-file-contract"></i>
</div>
<div class="text-xs">First Contract</div>
</div>
<div class="achievement bg-gray-700 p-2 rounded-lg text-center opacity-50">
<div class="mx-auto bg-gray-500 rounded-full w-10 h-10 flex items-center justify-center mb-1">
<i class="fas fa-code"></i>
</div>
<div class="text-xs">Solidity Pro</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// Game state
let gameState = {
balance: 100,
contractValue: 0,
transactions: [],
quizAnswers: {
q1: null,
q2: null,
q3: null
},
lessonProgress: 25
};
// DOM Elements
const balanceElement = document.getElementById('balance');
const terminalOutput = document.getElementById('terminalOutput');
const contractInteractionResult = document.getElementById('contractInteractionResult');
const newTransactions = document.getElementById('newTransactions');
const quizSection = document.getElementById('quizSection');
const latestBlock = document.getElementById('latestBlock');
// Buttons
const readContractBtn = document.getElementById('readContract');
const writeContractBtn = document.getElementById('writeContract');
const deployContractBtn = document.getElementById('deployContract');
const mineBlockBtn = document.getElementById('mineBlock');
const submitQuizBtn = document.getElementById('submitQuiz');
const walletBtn = document.getElementById('wallet');
// Event Listeners
readContractBtn.addEventListener('click', readContract);
writeContractBtn.addEventListener('click', writeContract);
deployContractBtn.addEventListener('click', deployContract);
mineBlockBtn.addEventListener('click', mineBlock);
submitQuizBtn.addEventListener('click', submitQuiz);
walletBtn.addEventListener('click', showWalletInfo);
// Game Functions
function readContract() {
addTerminalOutput(`> Reading contract value...`);
setTimeout(() => {
contractInteractionResult.classList.remove('hidden');
contractInteractionResult.innerHTML = `
<p class="text-green-400">Contract read successful!</p>
<p class="text-sm mt-1">Current stored value: ${gameState.contractValue}</p>
`;
addTerminalOutput(`βœ“ Contract value is ${gameState.contractValue}`);
addTransaction('Contract Read', '0 ETH', 'Read operation');
}, 1000);
}
function writeContract() {
addTerminalOutput(`> Updating contract value...`);
const newValue = Math.floor(Math.random() * 100);
setTimeout(() => {
contractInteractionResult.classList.remove('hidden');
contractInteractionResult.innerHTML = `
<p class="text-green-400">Contract write successful!</p>
<p class="text-sm mt-1">Value updated from ${gameState.contractValue} to ${newValue}</p>
<p class="text-xs mt-2 text-gray-400">Gas used: 0.00042 ETH</p>
`;
gameState.contractValue = newValue;
gameState.balance -= 0.00042;
balanceElement.textContent = gameState.balance.toFixed(5);
addTerminalOutput(`βœ“ Contract value updated to ${newValue}`);
addTerminalOutput(`- 0.00042 ETH (gas fee)`);
addTransaction('Contract Write', '-0.00042 ETH', 'Value updated');
// Show quiz after first contract interaction
if (!localStorage.getItem('quizShown')) {
setTimeout(() => {
quizSection.classList.remove('hidden');
localStorage.setItem('quizShown', 'true');
}, 1500);
}
}, 1500);
}
function deployContract() {
addTerminalOutput(`> Deploying new contract...`);
setTimeout(() => {
contractInteractionResult.classList.remove('hidden');
contractInteractionResult.innerHTML = `
<p class="text-green-400">Contract deployed successfully!</p>
<p class="text-sm mt-1">Contract address: 0x89...f2c1</p>
<p class="text-xs mt-2 text-gray-400">Gas used: 0.024 ETH</p>
`;
gameState.balance -= 0.024;
balanceElement.textContent = gameState.balance.toFixed(5);
addTerminalOutput(`βœ“ New contract deployed at 0x89...f2c1`);
addTerminalOutput(`- 0.024 ETH (gas fee)`);
addTransaction('Contract Deploy', '-0.024 ETH', 'New contract');
// Update achievement
const contractAchievement = document.querySelectorAll('.achievement')[1];
contractAchievement.classList.remove('bg-gray-700', 'opacity-50');
contractAchievement.classList.add('bg-purple-900', 'bg-opacity-30');
}, 2000);
}
function mineBlock() {
addTerminalOutput(`> Mining new block...`);
mineBlockBtn.disabled = true;
mineBlockBtn.innerHTML = `<i class="fas fa-cog fa-spin mr-2"></i> Mining...`;
setTimeout(() => {
// Create new block
const blockNumber = Math.floor(Math.random() * 1000) + 4;
const newBlockHash = `0x${Math.random().toString(16).substr(2, 10)}...${Math.random().toString(16).substr(2, 6)}`;
// Update blockchain visualization
latestBlock.innerHTML = `
<div class="text-xs text-gray-400 mb-1">Block #${blockNumber}</div>
<div class="text-sm mb-1">Contains ${gameState.transactions.length || 1} txns</div>
<div class="text-xs text-gray-400">${newBlockHash}</div>
`;
// Add new block to chain
const blocksContainer = document.querySelector('.flex.overflow-x-auto.space-x-4');
const newBlock = document.createElement('div');
newBlock.className = 'block bg-gray-700 p-3 rounded-lg min-w-[200px]';
newBlock.innerHTML = `
<div class="text-xs text-gray-400 mb-1">Block #${blockNumber}</div>
<div class="text-sm mb-1">Contains ${gameState.transactions.length || 1} txns</div>
<div class="text-xs text-gray-400">${newBlockHash}</div>
`;
// Create new pending block
const pendingBlock = document.createElement('div');
pendingBlock.className = 'block bg-blue-900 p-3 rounded-lg min-w-[200px]';
pendingBlock.id = 'latestBlock';
pendingBlock.innerHTML = `
<div class="text-xs text-gray-400 mb-1">Block #${blockNumber + 1}</div>
<div class="text-sm mb-1">Ready for new transactions</div>
<div class="text-xs text-gray-400">Pending...</div>
`;
blocksContainer.appendChild(newBlock);
blocksContainer.appendChild(pendingBlock);
addTerminalOutput(`βœ“ New block mined (#${blockNumber})`);
mineBlockBtn.disabled = false;
mineBlockBtn.innerHTML = `<i class="fas fa-hammer mr-2"></i> Mine Block`;
// Clear transactions
gameState.transactions = [];
document.getElementById('newTransactions').innerHTML = '';
}, 3000);
}
function submitQuiz() {
// Get selected answers
gameState.quizAnswers.q1 = document.querySelector('input[name="q1"]:checked')?.value;
gameState.quizAnswers.q2 = document.querySelector('input[name="q2"]:checked')?.value;
gameState.quizAnswers.q3 = document.querySelector('input[name="q3"]:checked')?.value;
// Check answers
const correctAnswers = {
q1: 'b',
q2: 'a',
q3: 'b'
};
let score = 0;
if (gameState.quizAnswers.q1 === correctAnswers.q1) score++;
if (gameState.quizAnswers.q2 === correctAnswers.q2) score++;
if (gameState.quizAnswers.q3 === correctAnswers.q3) score++;
// Display results
quizSection.innerHTML = `
<h2 class="text-2xl font-bold mb-4 flex items-center">
<i class="fas fa-poll mr-3 text-purple-400"></i>
Quiz Results
</h2>
<div class="mb-6">
<div class="bg-${score >= 2 ? 'green' : 'red'}-900 bg-opacity-30 p-4 rounded-lg mb-4">
<p class="text-lg font-semibold">You scored ${score}/3</p>
<p class="text-sm mt-2">
${score === 3 ? 'Perfect! You understand smart contracts well.' :
score >= 2 ? 'Good job! Review the incorrect answers to improve.' :
'Keep practicing! Review the lesson and try again.'}
</p>
</div>
<div class="space-y-4">
<div class="quiz-result bg-gray-700 p-3 rounded-lg">
<p class="font-semibold mb-1">1. What makes smart contracts different from traditional contracts?</p>
<p class="text-sm ${gameState.quizAnswers.q1 === 'b' ? 'text-green-400' : 'text-red-400'}">
${gameState.quizAnswers.q1 === 'b' ? 'βœ“ Correct' : 'βœ— Incorrect'}
</p>
<p class="text-xs text-gray-400 mt-1">Correct answer: They are stored on a blockchain and execute automatically</p>
</div>
<div class="quiz-result bg-gray-700 p-3 rounded-lg">
<p class="font-semibold mb-1">2. What happens when you deploy a smart contract to Ethereum?</p>
<p class="text-sm ${gameState.quizAnswers.q2 === 'a' ? 'text-green-400' : 'text-red-400'}">
${gameState.quizAnswers.q2 === 'a' ? 'βœ“ Correct' : 'βœ— Incorrect'}
</p>
<p class="text-xs text-gray-400 mt-1">Correct answer: It gets stored on the blockchain and receives an address</p>
</div>
<div class="quiz-result bg-gray-700 p-3 rounded-lg">
<p class="font-semibold mb-1">3. Why are smart contracts considered "trustless"?</p>
<p class="text-sm ${gameState.quizAnswers.q3 === 'b' ? 'text-green-400' : 'text-red-400'}">
${gameState.quizAnswers.q3 === 'b' ? 'βœ“ Correct' : 'βœ— Incorrect'}
</p>
<p class="text-xs text-gray-400 mt-1">Correct answer: Because they eliminate the need for trusted third parties</p>
</div>
</div>
</div>
<button onclick="location.reload()" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg w-full">
<i class="fas fa-sync-alt mr-2"></i> Continue Learning
</button>
`;
// Reward for good score
if (score >= 2) {
gameState.balance += 0.5;
balanceElement.textContent = gameState.balance.toFixed(5);
addTerminalOutput(`+ 0.5 ETH (quiz reward)`);
addTransaction('Quiz Reward', '+0.5 ETH', 'Good score');
}
}
function showWalletInfo() {
terminalOutput.innerHTML = `
<div class="text-blue-300">Wallet Details:</div>
<div class="text-sm">Address: 0x7f3c5a9e1b2d4f6a8c0e3d7b5a4b3a2c1d0e9f8</div>
<div class="text-sm">Network: Ethereum Testnet</div>
<div class="text-sm">Balance: ${gameState.balance} ETH</div>
`;
}
// Helper Functions
function addTerminalOutput(message) {
const line = document.createElement('div');
line.className = 'terminal-line';
line.textContent = message;
terminalOutput.appendChild(line);
terminalOutput.scrollTop = terminalOutput.scrollHeight;
}
function addTransaction(title, amount, description) {
const transaction = {
title,
amount,
description,
timestamp: new Date().toLocaleTimeString()
};
gameState.transactions.push(transaction);
const transactionElement = document.createElement('div');
transactionElement.className = 'transaction bg-gray-700 p-3 rounded-lg transaction-animation';
transactionElement.innerHTML = `
<div class="flex justify-between text-sm">
<span class="${amount.startsWith('+') ? 'text-green-400' : 'text-blue-300'}">${title}</span>
<span class="text-gray-400">just now</span>
</div>
<div class="text-xs text-gray-400">${amount} (${description})</div>
`;
newTransactions.prepend(transactionElement);
}
// Initialize
addTerminalOutput('$ Ready to learn about smart contracts!');
</script>
</body>
</html>