DEV Community

Cover image for 🪙 Day 6 of 30 Days of Solidity: Build a Digital Piggy Bank
Saurav Kumar
Saurav Kumar

Posted on

🪙 Day 6 of 30 Days of Solidity: Build a Digital Piggy Bank

Smart contracts aren’t just about tokens — they can also help users save and manage Ether securely.
Today, we’ll build a Digital Piggy Bank — a simple yet powerful example of how to store, withdraw, and track Ether safely on the blockchain.

This project demonstrates real-world Solidity skills, including secure fund handling, user-specific balances, reentrancy protection, and event logging.


🎯 What You’ll Learn

By completing this project, you’ll gain hands-on experience in:

  • Managing user balances using mappings.
  • Handling Ether deposits and withdrawals.
  • Using msg.sender to identify users.
  • Emitting events for better traceability.
  • Implementing security best practices like the Checks-Effects-Interactions pattern and reentrancy guards.

🧠 Concept Overview

A Digital Piggy Bank lets each user deposit and withdraw Ether independently.
When a user deposits Ether, it gets recorded under their address.
They can later withdraw their funds safely without affecting others.

This mimics a personalized savings system, showing how decentralized finance (DeFi) apps handle value securely.


💻 Smart Contract Code

// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title DigitalPiggyBank * @notice A secure and gas-efficient smart contract that allows users to deposit and withdraw Ether. * Includes proper checks, events, and a safe withdrawal mechanism. */ contract DigitalPiggyBank { /// @dev Mapping to store each user's Ether balance mapping(address => uint256) private _balances; /// @dev Emitted when a user deposits Ether event Deposited(address indexed user, uint256 amount); /// @dev Emitted when a user withdraws Ether event Withdrawn(address indexed user, uint256 amount); /// @dev Reentrancy guard to prevent reentrancy attacks bool private _locked; modifier nonReentrant() { require(!_locked, "Reentrancy detected"); _locked = true; _; _locked = false; } /** * @notice Deposit Ether into your digital piggy bank. * @dev Ether sent is credited to the sender's balance. */ function deposit() external payable { require(msg.value > 0, "Deposit amount must be greater than zero"); _balances[msg.sender] += msg.value; emit Deposited(msg.sender, msg.value); } /** * @notice Withdraw Ether from your balance. * @param amount The amount of Ether to withdraw (in wei). */ function withdraw(uint256 amount) external nonReentrant { uint256 userBalance = _balances[msg.sender]; require(amount > 0, "Withdrawal amount must be greater than zero"); require(userBalance >= amount, "Insufficient balance"); // Update balance before transferring (Checks-Effects-Interactions pattern) _balances[msg.sender] = userBalance - amount; (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed"); emit Withdrawn(msg.sender, amount); } /** * @notice View the balance of the caller. * @return The Ether balance of the caller in wei. */ function getMyBalance() external view returns (uint256) { return _balances[msg.sender]; } /** * @notice View the total Ether held in this contract. * @return The total Ether in wei. */ function getContractBalance() external view returns (uint256) { return address(this).balance; } } 
Enter fullscreen mode Exit fullscreen mode

🧩 Key Features

Feature Description
💰 Deposit & Withdraw Users can deposit and withdraw Ether anytime.
🔒 Reentrancy Protection Prevents reentrancy attacks using a custom guard.
🧾 Event Logging Transparent tracking of deposits and withdrawals.
⚙️ Safe Transfers Uses .call for modern, gas-efficient Ether transfers.
🧱 Industry Best Practices Implements Checks-Effects-Interactions and private state variables.

🧪 How to Test

  1. Go to Remix IDE.
  2. Paste the code into a new Solidity file.
  3. Compile with Solidity 0.8.20 or above.
  4. Deploy using Injected Web3 (e.g., MetaMask).
  5. Try depositing and withdrawing Ether to test it out!

Example tests:

  • Deposit 0.1 ETH → check your balance.
  • Withdraw 0.05 ETH → verify balance update.
  • Check contract balance to confirm total deposits.

🔐 Security Highlights

  • Non-reentrant withdrawals: Prevents attacks that exploit recursive calls.
  • Validated inputs: Ensures only valid deposit and withdrawal amounts.
  • Safe transfer pattern: Avoids gas limit issues common with transfer() or send().
  • Immutable data flow: Each user can only control their own balance.

🌍 Real-World Use Cases

This project can evolve into:

  • A DeFi savings vault where users lock funds for rewards.
  • A donation wallet that records every contributor.
  • A microbanking system for learning blockchain-based finance.

🔗 Source Code

Check out the full code and other Solidity projects in my repository 👇
👉 GitHub Repository


💬 Closing Thoughts

This Digital Piggy Bank is a major step toward understanding how real-world DeFi systems handle funds securely.
By mastering Ether management and safe coding patterns, you’re moving closer to becoming a professional blockchain developer.

Stay tuned for Day 7, where we’ll continue exploring more advanced Solidity concepts!

Top comments (0)