Project Objectives – by building this project you will:
  • Model an auction with three structs, two mappings and counters.
  • Use a modifier with an argument to validate bid values.
  • Receive Ether in a payable function and forward it with transfer.
Synopsis

An e-auction lets bidders compete for an item online, but participants usually have to trust the auction house to record bids honestly and to declare the true highest bidder. In this project the bidding rules run in a smart contract, so every registration and bid is recorded on the blockchain and the winner is determined by public code.

The deploying account is the Auction Manager, who puts an item up for auction with a starting value. Other accounts register as bidders and place open, increasing bids – each bid must be higher than the current highest. When the manager declares the result, the last (highest) bid wins, and the winner pays the bid amount in Ether through the contract to the manager.

Contract Architecture
PartDetails
BlockMaster.solStructs ItemMaster { itemName, initBidValue, auctionResult }, BiddersMaster { bidderName, bidderAddress }, AuctionRegister { userAddress, bidValue }
AuctionContract.solContract AuctionContract; imports contracts/BlockMaster.sol
stateaddress payable auctionManager, ItemMaster public auctionItem, maxBidValue, counters regNo and chainNo, AuctionRegister public winner
mappingsauctionBidderRegister (registration no. → bidder) and auctionChain (bid no. → bid)
modifierscheckAuctionManager, checkUserIsNotAuctionManager, checkAuctionBidderRegister (not yet registered), checkAuctionBidderExistence (registered), checkBidValue(uint) (bid > current max), checkItemBiddingStatus (auction open), checkWinnerAddress, checkTransactionAmount
functionssetAuctionItem(name, value) → BidderRegisterMaster(name) → MyBidding(value) → declareAuctionResult() → transferBidAmount() (payable)
How It Works
1. ItemManager sets item & starting value
2. RegisterBidders register once
3. BidEach bid must exceed the current maximum
4. ResultLast (highest) bid becomes winner
5. PayWinner sends exactly bid × 1018 wei; forwarded to the manager

Bid values are entered in whole ETH. checkTransactionAmount converts them to wei (bidValue * 10**18) and requires msg.value to match exactly.

Key Requirements (Concepts Used)
  • Structs imported from a separate file (Chapters 2, 13).
  • Mappings with counters used as keys (Chapter 12).
  • Modifiers, including a modifier with an argument (Chapter 22).
  • Payable function and transfer to an address payable (Chapters 3, 24).
  • Private helper functions such as gotoNextBidder() (Chapter 15).
How to Run in Remix
  1. Create contracts/BlockMaster.sol and contracts/AuctionContract.sol from the resource files; compile and deploy AuctionContract from the first account (manager).
  2. Manager: call setAuctionItem("Painting", 1).
  3. From two or three other accounts call BidderRegisterMaster, then MyBidding with rising values (e.g. 2, 3, 5).
  4. Manager: call declareAuctionResult() and read winner.
  5. Winner: set the VALUE field to the bid in Ether (e.g. 5 ether) and call transferBidAmount(); the manager’s balance increases.
Limitations and Extension Exercises
Observation in the teaching versionImprovement to try
Bids are only numbers; the winner may never pay.Require bidders to send Ether with each bid (escrow) and refund out-bid users.
Bids are public, so this is an open (English-style) auction, not a sealed-bid auction.Study commit–reveal for sealed bids.
No end time; the manager decides when to close.Add an endTime set at item creation.
Declaring a result with no bids underflows chainNo - 1 and reverts.Require at least one bid with a clear message.
Registration checks loop over all bidders.Use mapping(address => bool) registered.
Exercise solution (escrow auction with refunds)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract EscrowAuction {
    address payable public immutable seller = payable(msg.sender);
    uint public immutable endTime;
    address public highestBidder;
    uint public highestBid;
    bool public ended;
    mapping(address => uint) public refunds;      // out-bid amounts to withdraw

    constructor(uint durationSeconds) {
        endTime = block.timestamp + durationSeconds;
    }

    function bid() external payable {
        require(block.timestamp < endTime, "Auction over");
        require(msg.value > highestBid, "Bid too low");
        if (highestBidder != address(0)) {
            refunds[highestBidder] += highestBid;  // previous leader can withdraw
        }
        highestBidder = msg.sender;
        highestBid = msg.value;
    }

    function withdrawRefund() external {
        uint amount = refunds[msg.sender];
        require(amount > 0, "Nothing to withdraw");
        refunds[msg.sender] = 0;                   // effects before interaction
        (bool ok, ) = payable(msg.sender).call{value: amount}("");
        require(ok, "Refund failed");
    }

    function endAuction() external {
        require(block.timestamp >= endTime, "Not yet ended");
        require(!ended, "Already ended");
        ended = true;
        (bool ok, ) = seller.call{value: highestBid}("");
        require(ok, "Payment failed");
    }
}
Key Takeaways
  • Modifiers (including one with an argument) enforce who may bid and that bids keep increasing.
  • Payable functions receive Ether; amounts must be converted between ETH and wei carefully.
  • Real auctions need escrow, refunds (pull pattern) and a fixed end time.
Video : Project 3 : Smart Contract for Bidding / e-Auction System
Resource Files
Question / Answer (15 questions)

Answer : An open, ascending (English-style) auction: bids are public and each new bid must be higher than the current highest bid; the last bid wins.

Answer : ItemMaster (itemName, initBidValue, auctionResult), BiddersMaster (bidderName, bidderAddress) and AuctionRegister (userAddress, bidValue).

Answer : The account that deploys the contract (stored as auctionManager). The manager sets the auction item and declares the result, and receives the winner’s payment; the manager cannot register or bid.

Answer : Because the contract sends the winner’s Ether to the manager with auctionManager.transfer(msg.value), which requires an address payable.

Answer : It is a modifier with an argument: checkBidValue(uint bidderValue) requires the new bid to be greater than maxBidValue, otherwise the bid is rejected.

Answer : First by calling BidderRegisterMaster(name) once, then by calling MyBidding(value) with a value higher than the current maximum while the auction is open.

Answer : Because each bid must be higher than the previous one, the last recorded bid (auctionChain[chainNo - 1]) is the highest, so it becomes the winner. The item is then marked as closed.

Answer : It converts the winning bid from whole ETH to wei by multiplying by 10^18 and requires msg.value to be exactly that amount.

Answer : Because the winner sends Ether with the call; only payable functions can receive Ether.

Answer : chainNo is 0, so chainNo - 1 underflows; Solidity 0.8 checked arithmetic reverts the transaction.

Answer : Bids are only numbers, so the winner is not forced to pay. An escrow design in which bidders send Ether with each bid solves this.

Answer : It records the previous highest bid in a refunds mapping, and the out-bid user later withdraws it (pull pattern), with the balance set to zero before sending.

Answer : All function inputs and state on a public blockchain are visible. A sealed-bid auction needs a commit–reveal scheme where bids are hidden as hashes first.

Answer : A fixed end time based on block.timestamp makes the closing rule public and prevents the manager from ending the auction at a convenient moment.

Answer : gotoNextBidder() and gotoNextBlockchain() increment the regNo and chainNo counters. They are private because only the contract’s own functions should advance these counters.
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. In the AuctionContract, each new bid must be:

Show Answer

Correct Answer : C. Greater than the current maximum
checkBidValue requires bid > maxBidValue.

Q2. checkBidValue(uint bidderValue) is an example of:

Show Answer

Correct Answer : C. A modifier with an argument
Modifiers can take parameters.

Q3. A winning bid of 3 (ETH) requires msg.value of:

Show Answer

Correct Answer : D. 3 × 10^18 wei
checkTransactionAmount multiplies by 10^18.

Q4. Which function must be payable for the winner to pay?

Show Answer

Correct Answer : B. transferBidAmount
transferBidAmount receives the winner’s Ether.

Q5. In an escrow auction, out-bid users get their Ether back by:

Show Answer

Correct Answer : A. Calling a withdraw/refund function
The pull pattern lets users withdraw refunds.

Bibliography/References

The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.

  1. Solidity Team. (n.d.). Contracts (creating contracts, visibility and getters, function modifiers, constant and immutable, functions, events, custom errors, inheritance, abstract contracts, interfaces, libraries). Solidity Documentation. https://docs.soliditylang.org/en/latest/contracts.html
  2. Solidity Team. (n.d.). Units and Globally Available Variables. Solidity Documentation. https://docs.soliditylang.org/en/latest/units-and-global-variables.html
  3. Solidity Team. (n.d.). Security Considerations. Solidity Documentation. https://docs.soliditylang.org/en/latest/security-considerations.html
  4. ethereum.org. (n.d.). Smart contract security. Ethereum Developer Documentation. https://ethereum.org/en/developers/docs/smart-contracts/security/
  5. Remix Project. (n.d.). Remix IDE Documentation. https://remix-ide.readthedocs.io/en/latest/
  6. Modi, R. (2018). Solidity Programming Essentials: A beginner’s guide to build smart contracts for Ethereum and blockchain. Packt Publishing. ISBN 978-1-78883-138-3.