top of page

My Very First Simple Smart Contract

ree
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;

contract SimpleContract {

    event TransferMoney(address from, address to, uint amount);
    event WithdrawMoney(address from, uint amount);
    event Deposit(address  from, uint amount);

    mapping(address => uint) public balances;

    // 🔹 Deposit Ether into the contract
    function deposit() external payable {
        require(msg.value > 0, "Send some Ether");
        balances[msg.sender] += msg.value;
        emit Deposit(msg.sender, msg.value);
    }

    // 🔹 Transfer balance (internal ledger transfer)
    function transferMoney(address to, uint amount) external {
        require(to != address(0), "Invalid address");
        require(balances[msg.sender] >= amount, "Insufficient balance");

        balances[msg.sender] -= amount;
        balances[to] += amount;

        emit TransferMoney(msg.sender, to, amount);
    }

    // 🔹 Withdraw Ether from your balance
    function withdrawMoney(uint amount) external {
        require(amount > 0, "Invalid amount");
        require(balances[msg.sender] >= amount, "Insufficient balance");

        balances[msg.sender] -= amount;

        emit WithdrawMoney(msg.sender, amount);
    }

    // 🔹 Get your balance
    function getBalance() external view returns (uint) {
        return balances[msg.sender];
    }
}

What Makes This Interesting?

Perhaps you’ve seen our previous blockchain development guides. Those posts covered fundamental concepts for developers. Today, we’re putting all those pieces into one basket and seeing how they work together in a real smart contract. Let’s dive in!

Mapping

For those coming from other programming languages, you might already know that a mapping is a way to store key-value pairs. In Solidity:

mapping(address => uint) public balances;

This line maps every unique wallet address to a uint value representing that wallet’s balance. Think of it as a digital ledger inside the contract — each address has its own account that stores the amount of Ether or tokens it holds.

Events

Events are like logs that the blockchain creates whenever certain actions occur in the contract. In our example, we fire events such as:

  • TransferMoney

  • WithdrawMoney

  • Deposit

These events allow developers (and frontends) to listen for specific actions, such as fund transfers or state changes. For example, a DApp can instantly update a user’s balance on the interface whenever a TransferMoney event is emitted. Events make the smart contract interactive and trackable, which is crucial for user experience in Web3 applications.

External and Payable Keywords

  • external: Functions marked external can only be called from outside the contract. This is important for security because it prevents internal misuse or unintended calls, making your contract more robust.

  • payable: Only functions that need to receive Ether should be marked payable. For example, deposit functions require payable to accept funds, while internal transfers (like sending balance from one user to another) do not need it.

Additionally, we always check for address(0) when transferring funds. This ensures we don’t accidentally send money to a nonexistent or invalid address, which could result in lost funds.

Conclusion

By combining mappings, events, external/payable keywords, and safe transfer logic, you’re ready to start building beginner-level Web3 projects. These concepts form the backbone of smart contracts that are both secure and interactive.

Once you master these, you can extend your contracts further:

  • Adding owner/admin controls

  • Implementing multi-user wallets

  • Building transaction histories or frontend dashboards

Comments


bottom of page