DEV Community

Cover image for Day 4 of 30 Days of Solidity Challenge: Build a Basic Auction Smart Contract
Saurav Kumar
Saurav Kumar

Posted on

Day 4 of 30 Days of Solidity Challenge: Build a Basic Auction Smart Contract

Hello developers 👋

Welcome to Day 4 of my 30 Days of Solidity Challenge!
Today’s task is to build a simple auction contract — something similar to eBay, but fully decentralized on the blockchain!

Let’s dive in 👇


🎯 Task

Create a basic auction where users can bid on an item, and the highest bidder wins when the auction time ends.

We’ll use:

  • if/else statements to decide the winner based on the highest bid
  • block.timestamp to track time

This project helps you understand conditional logic and time-based control in smart contracts — essential concepts for blockchain applications like auctions, lotteries, and time-locked contracts.


🧠 Learning Goals

By the end of this task, you’ll learn how to:

  • Work with block timestamps for time tracking
  • Compare bids and manage user balances
  • Use conditional logic (if/else) in Solidity
  • Handle Ether safely with refunds and withdrawals

🧩 Smart Contract Code

Here’s the full code for our Basic Auction Contract 👇

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title Basic Auction Contract
 * @dev A simple auction system where users can bid, and the highest bidder wins when time runs out.
 */

contract BasicAuction {
    address public owner;
    uint public auctionEndTime;
    address public highestBidder;
    uint public highestBid;
    bool public ended;

    mapping(address => uint) public pendingReturns;

    event HighestBidIncreased(address bidder, uint amount);
    event AuctionEnded(address winner, uint amount);

    constructor(uint _biddingTime) {
        owner = msg.sender;
        auctionEndTime = block.timestamp + _biddingTime;
    }

    /**
     * @dev Place a bid on the auction.
     * The bid must be higher than the current highest bid.
     * If not, the transaction is reverted.
     */
    function bid() external payable {
        require(block.timestamp < auctionEndTime, "Auction already ended");
        require(msg.value > highestBid, "Bid not high enough");

        if (highestBid != 0) {
            // Refund the previous highest bidder
            pendingReturns[highestBidder] += highestBid;
        }

        highestBidder = msg.sender;
        highestBid = msg.value;
        emit HighestBidIncreased(msg.sender, msg.value);
    }

    /**
     * @dev Withdraw a bid that was overbid by someone else.
     */
    function withdraw() external returns (bool) {
        uint amount = pendingReturns[msg.sender];
        require(amount > 0, "No funds to withdraw");

        pendingReturns[msg.sender] = 0;
        if (!payable(msg.sender).send(amount)) {
            pendingReturns[msg.sender] = amount;
            return false;
        }
        return true;
    }

    /**
     * @dev Ends the auction and sends the highest bid to the owner.
     */
    function endAuction() external {
        require(block.timestamp >= auctionEndTime, "Auction not yet ended");
        require(!ended, "Auction already ended");

        ended = true;
        emit AuctionEnded(highestBidder, highestBid);

        payable(owner).transfer(highestBid);
    }

    /**
     * @dev Returns the remaining time for the auction.
     */
    function getTimeLeft() external view returns (uint) {
        if (block.timestamp >= auctionEndTime) {
            return 0;
        } else {
            return auctionEndTime - block.timestamp;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

⚙️ How It Works

  1. The contract starts when deployed — the deployer becomes the owner.
  2. Users can call bid() and send Ether — but only if it’s higher than the current highest bid.
  3. If they get outbid, they can safely withdraw their previous bid using withdraw().
  4. Once the auction time ends, anyone can call endAuction() to finalize it.
  5. The highest bidder wins, and the owner receives the winning amount.

🧪 Testing on Remix

  1. Go to Remix IDE
  2. Create a file named BasicAuction.sol and paste the code above
  3. Compile using Solidity version 0.8.0 or above
  4. Deploy the contract with an auction duration (e.g., 60 for 60 seconds)
  5. Use multiple accounts to place bids with increasing values
  6. Wait for the timer to expire, then call endAuction()

🧰 Tools Used

  • Solidity
  • Remix IDE
  • Ethereum Virtual Machine (EVM)

📦 Repository

Check out the full code on GitHub 👇
🔗 Day-4 Solidity Auction Smart Contract


🏁 Final Thoughts

This project was fun to build because it combines logic, state management, and blockchain timing — all crucial skills for real-world decentralized apps.

Building this gave me a deeper understanding of how decentralized systems like eBay on blockchain could actually work.


💬 What do you think about this project?
Drop your feedback or share how you would enhance this auction dApp!

If you’re also learning Solidity, follow my #30DaysOfSolidity journey — I’ll be sharing a new project every day 🚀

Top comments (0)