Solidity Contract Examples

·

Smart contracts are foundational to decentralized applications on blockchain platforms like Ethereum. Solidity, the most widely used language for writing these contracts, enables developers to implement complex logic with transparency and immutability. In this guide, we explore several practical Solidity contract examples—ranging from voting systems and auctions to payment channels and modular design patterns—that demonstrate core concepts such as state management, access control, cryptographic signatures, and secure fund handling.

Whether you're building a decentralized finance (DeFi) protocol or experimenting with Web3 tools, understanding real-world implementations is key. We'll walk through each example in detail, highlighting best practices and critical security considerations.


Voting Contracts with Delegation

One of the most illustrative Solidity examples is a voting system that supports delegation. This contract allows a chairperson to assign voting rights to specific addresses. Voters can either cast their vote directly or delegate it to someone they trust.

The system ensures automatic and fully transparent vote counting. At the end of the voting period, the winningProposal() function returns the index of the proposal with the highest number of votes.

Key features:

struct Voter {
    uint weight;
    bool voted;
    address delegate;
    uint vote;
}

struct Proposal {
    bytes32 name;
    uint voteCount;
}

👉 Discover how blockchain voting can revolutionize digital governance

Why Delegation Matters

Delegation empowers users who may lack time or expertise to make informed decisions. By allowing trusted parties to vote on their behalf, participation increases while maintaining decentralization.

However, challenges remain—such as ensuring only eligible participants receive voting rights and preventing manipulation. While this contract doesn’t solve identity verification, it lays the groundwork for secure, transparent decision-making.


Open and Blind Auctions

Auction contracts are another powerful use case for Solidity smart contracts. Let’s examine two types: open bidding and blind bidding.

Simple Open Auction

In an open auction, all bids are visible. Participants send Ether along with their bid. If outbid, the previous highest bidder can withdraw funds later.

Critical mechanisms:

function bid() external payable {
    require(block.timestamp <= auctionEndTime, "Auction already ended");
    require(msg.value > highestBid, "Bid not high enough");

    if (highestBid != 0) {
        pendingReturns[highestBidder] += highestBid;
    }
    highestBidder = msg.sender;
    highestBid = msg.value;
    emit HighestBidIncreased(msg.sender, msg.value);
}

Blind Auction: Enhanced Privacy

To prevent last-minute sniping, a blind auction hides bid values during the bidding phase. Users submit hashed bids (keccak256(value, fake, secret)). Afterward, they reveal their details.

This approach:

modifier onlyBefore(uint time) {
    require(block.timestamp < time);
    _;
}

👉 Learn how decentralized auctions are reshaping NFT markets


Secure Remote Purchase

Buying goods remotely involves trust issues—how do we ensure both buyer and seller fulfill obligations?

This remote purchase contract uses escrow-like mechanics:

States include:

Using enums and modifiers like inState() ensures transitions happen correctly.

modifier inState(State state_) {
    require(state == state_);
    _;
}

Events such as ItemReceived and SellerRefunded keep interactions traceable.


Micro-Payment Channels

For high-frequency, low-cost transactions (e.g., streaming payments), on-chain fees are impractical. Payment channels solve this by enabling off-chain transfers secured by cryptography.

How It Works

  1. Alice deploys a contract funded with Ether.
  2. She signs messages specifying payment amounts.
  3. Bob redeems them by submitting the signature to the contract.

Security relies on:

function claimPayment(uint256 amount, uint256 nonce, bytes memory signature) external {
    require(!usedNonces[nonce]);
    bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this)));
    require(recoverSigner(message, signature) == owner);
    payable(msg.sender).transfer(amount);
}

This model enables instant, feeless microtransactions—ideal for pay-per-use services.


Modular Contract Design

As contracts grow in complexity, modularity becomes essential. Libraries allow reusable code without duplication.

Using Libraries for Balance Management

The Balances library isolates balance operations:

library Balances {
    function move(mapping(address => uint256) storage balances, address from, address to, uint amount) internal {
        require(balances[from] >= amount);
        require(balances[to] + amount >= balances[to]); // Overflow check
        balances[from] -= amount;
        balances[to] += amount;
    }
}

By attaching this library to a token contract with using Balances for *;, developers ensure consistent, auditable balance changes across all functions.

Benefits:


Frequently Asked Questions

What is a Solidity contract?

A Solidity contract is a collection of code (functions) and data (state variables) that resides at a specific address on the Ethereum blockchain. It defines rules for asset transfers, access control, and business logic in decentralized applications.

How does delegation work in voting contracts?

Delegation allows one user to assign their voting power to another. The delegate can accumulate weight from multiple voters and cast votes on their behalf, increasing efficiency without sacrificing representation.

Can anyone create a blind auction?

Yes. Anyone with basic Solidity knowledge can deploy a blind auction. However, proper testing and security audits are crucial to prevent exploits like front-running or incorrect fund distribution.

Why use payment channels instead of regular transactions?

Payment channels reduce gas costs and latency by moving repeated transactions off-chain. Only two on-chain transactions (opening and closing) are needed regardless of how many payments occur in between.

How do modifiers improve contract security?

Modifiers like onlyOwner, inState, or onlyAfter centralize access control logic. They prevent unauthorized state changes and enforce business rules consistently across functions.

What are common pitfalls when writing Solidity contracts?

Common issues include reentrancy attacks, integer overflow/underflow (mitigated in Solidity 0.8+), incorrect visibility settings, and improper handling of Ether transfers. Always follow known secure patterns and test thoroughly.


Final Thoughts

These Solidity contract examples showcase the language’s versatility—from democratic governance to private auctions and scalable payments. By mastering these patterns, developers can build robust, trustless systems that power the next generation of decentralized applications.

Understanding core principles like state management, cryptographic verification, and modular design is essential for creating secure and maintainable smart contracts.

👉 Start building your own smart contracts today with advanced tools