My Very First Simple Smart Contract
- Ali Tuna
- Nov 2
- 2 min read

// 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