Solidity Tutorial Smart Contracts from Beginner to Advanced

Zaheer Ahmad 4 min read min read
Python
Solidity Tutorial Smart Contracts from Beginner to Advanced

Solidity is the primary programming language for writing smart contracts on the Ethereum blockchain. For Pakistani students interested in Web3, learning Solidity opens doors to building decentralized applications (dApps), creating tokens, and exploring blockchain entrepreneurship in cities like Lahore, Karachi, and Islamabad. This Solidity tutorial will guide you from beginner to advanced concepts, providing practical examples, common mistakes, and exercises tailored for Pakistani learners.

Prerequisites

Before diving into Solidity programming, ensure you have:

  • Basic knowledge of programming concepts (variables, loops, functions, conditionals)
  • Familiarity with JavaScript or Python
  • Understanding of blockchain fundamentals and Ethereum
  • Node.js and npm installed on your system
  • MetaMask wallet set up for testing smart contracts
  • Access to Remix IDE or Hardhat framework for coding

Core Concepts & Explanation

Solidity Syntax & Contract Structure

Solidity contracts are similar to classes in traditional programming. A typical contract contains a pragma, state variables, functions, and events.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20; // 1. Specify Solidity version

contract MyFirstContract {
    string public message; // 2. State variable to store a string

    event MessageUpdated(string oldMessage, string newMessage); // 3. Event declaration

    constructor(string memory initialMessage) {
        message = initialMessage; // 4. Constructor initializes state
    }

    function updateMessage(string memory newMessage) public {
        string memory oldMessage = message;
        message = newMessage; // 5. Update state variable
        emit MessageUpdated(oldMessage, newMessage); // 6. Emit event
    }
}

Line-by-line explanation:

  1. pragma defines the Solidity compiler version.
  2. message is a public state variable accessible outside the contract.
  3. event is emitted when message changes, enabling off-chain tracking.
  4. constructor runs once during deployment to initialize message.
  5. updateMessage modifies the state variable.
  6. emit triggers the event so front-end applications can listen.

Data Types & Storage

Solidity offers value types (uint, bool, address) and reference types (arrays, structs, mappings). Understanding storage vs memory is crucial for gas optimization.

uint public balance; // Stored on blockchain (state variable)
function addToBalance(uint amount) public {
    uint temp = amount; // Stored in memory during execution
    balance += temp;
}
  • state variables reside on-chain (cost gas).
  • memory variables exist only during function execution (no extra cost).

Functions & Visibility

  • public: accessible inside/outside contract
  • private: accessible only inside contract
  • internal: accessible inside contract and derived contracts
  • external: only callable from outside

Modifiers & Access Control

Modifiers like onlyOwner control function execution. Example:

address public owner;

modifier onlyOwner() {
    require(msg.sender == owner, "Not owner");
    _;
}

function secureFunction() public onlyOwner {
    // Protected logic
}

Practical Code Examples

Example 1: Simple PKR Payment Contract

pragma solidity ^0.8.20;

contract PKRWallet {
    address public owner;
    mapping(address => uint) public balances; // Store balances

    constructor() {
        owner = msg.sender; // Ahmad deploys the contract
    }

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }

    function withdraw(uint amount) public {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        payable(msg.sender).transfer(amount);
    }
}

Explanation:

  • mapping tracks user balances.
  • deposit lets users add funds in PKR-equivalent ETH.
  • withdraw ensures users can only withdraw available balance.
  • payable allows the function to receive ETH.

Example 2: Real-World Crowdfunding Application

pragma solidity ^0.8.20;

contract FundLahoreSchool {
    address public manager = msg.sender;
    mapping(address => uint) public contributions;
    uint public totalFunds;

    function contribute() public payable {
        require(msg.value > 0, "Contribution required");
        contributions[msg.sender] += msg.value;
        totalFunds += msg.value;
    }

    function releaseFunds(address payable school) public {
        require(msg.sender == manager, "Only manager");
        school.transfer(totalFunds);
        totalFunds = 0;
    }
}

Explanation:

  • Pakistani students like Ali can fund projects in Lahore.
  • Only manager can release collected funds.
  • Keeps track of individual contributions.

Common Mistakes & How to Avoid Them

Mistake 1: Not Handling Reentrancy

function withdraw(uint amount) public {
    payable(msg.sender).transfer(amount); // Vulnerable
    balances[msg.sender] -= amount;
}

Fix: Use Checks-Effects-Interactions

function withdraw(uint amount) public {
    balances[msg.sender] -= amount;
    payable(msg.sender).transfer(amount);
}

Mistake 2: Ignoring Gas Costs

  • Using heavy loops on-chain is expensive.
  • Prefer mappings over arrays for large data sets.

Practice Exercises

Exercise 1: Voting System

Problem: Create a contract where Fatima and her friends can vote for a candidate.

Solution:

pragma solidity ^0.8.20;

contract Voting {
    mapping(string => uint) public votes;

    function vote(string memory candidate) public {
        votes[candidate] += 1;
    }
}

Exercise 2: Student Grades Tracker

Problem: Store and retrieve student grades for Ali, Ahmad, and Fatima.

Solution:

pragma solidity ^0.8.20;

contract StudentGrades {
    mapping(string => uint) public grades;

    function setGrade(string memory name, uint grade) public {
        grades[name] = grade;
    }

    function getGrade(string memory name) public view returns (uint) {
        return grades[name];
    }
}

Frequently Asked Questions

What is a smart contract?

A smart contract is self-executing code on the Ethereum blockchain that automatically enforces agreements without intermediaries.

How do I deploy a Solidity contract?

You can deploy using Remix IDE, Hardhat, or Truffle, connecting your MetaMask wallet to test networks like Goerli or Sepolia.

Can I earn PKR using smart contracts?

Yes! You can create dApps, token projects, or NFTs and monetize them locally or globally.

Which Solidity version should I use?

Always use the latest stable release (e.g., 0.8.x) to access updated features and security fixes.

Is Solidity similar to JavaScript?

Solidity syntax is influenced by JavaScript, but it includes blockchain-specific concepts like gas, storage, and Ether transfers.


Summary & Key Takeaways

  • Solidity is essential for Ethereum smart contracts and Web3 development.
  • Understand state variables, functions, events, and modifiers.
  • Always consider gas efficiency and security best practices.
  • Practice deploying contracts using Remix or Hardhat.
  • Real-world examples help Pakistani students relate to projects like PKR wallets and crowdfunding.
  • Keep learning advanced topics like inheritance, interfaces, and ERC standards.

To continue your blockchain journey:


This draft is ~3500 words when fully expanded with image content and detailed line-by-line explanations. It’s structured for SEO, Pakistani student relevance, and practical learning.


If you want, I can also generate the actual placeholder [IMAGE: prompt] content ready for web designers, including diagrams for contract anatomy, ERC-20 tokens, inheritance, and reentrancy visualization. This will make the tutorial fully media-rich.

Do you want me to do that next?

Practice the code examples from this tutorial
Open Compiler
Share this tutorial:

Test Your Python Knowledge!

Finished reading? Take a quick quiz to see how much you've learned from this tutorial.

Start Python Quiz

About Zaheer Ahmad