# Code Examples

Here are 10 code samples in Solidity demonstrating various concepts and functionalities.

#### 1. Simple Storage Contract

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

contract SimpleStorage {
    uint256 storedData;

    function set(uint256 x) public {
        storedData = x;
    }

    function get() public view returns (uint256) {
        return storedData;
    }
}
```

#### 2. Basic ERC20 Token

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

contract BasicERC20Token {
    string public name = "BasicToken";
    string public symbol = "BTK";
    uint8 public decimals = 18;
    uint256 public totalSupply;

    mapping(address => uint256) balances;
    mapping(address => mapping(address => uint256)) allowed;

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    constructor(uint256 initialSupply) {
        totalSupply = initialSupply * 10 ** uint256(decimals);
        balances[msg.sender] = totalSupply;
    }

    function balanceOf(address owner) public view returns (uint256) {
        return balances[owner];
    }

    function transfer(address to, uint256 value) public returns (bool) {
        require(to != address(0), "Invalid address");
        require(value <= balances[msg.sender], "Insufficient balance");

        balances[msg.sender] -= value;
        balances[to] += value;
        emit Transfer(msg.sender, to, value);
        return true;
    }

    function approve(address spender, uint256 value) public returns (bool) {
        allowed[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;
    }

    function transferFrom(address from, address to, uint256 value) public returns (bool) {
        require(to != address(0), "Invalid address");
        require(value <= balances[from], "Insufficient balance");
        require(value <= allowed[from][msg.sender], "Allowance exceeded");

        balances[from] -= value;
        balances[to] += value;
        allowed[from][msg.sender] -= value;
        emit Transfer(from, to, value);
        return true;
    }

    function allowance(address owner, address spender) public view returns (uint256) {
        return allowed[owner][spender];
    }
}
```

#### 3. Voting Contract

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

contract Voting {
    struct Voter {
        bool voted;
        uint8 vote;
        uint256 weight;
    }

    struct Proposal {
        uint256 voteCount;
    }

    address public chairperson;
    mapping(address => Voter) public voters;
    Proposal[] public proposals;

    constructor(uint8 _numProposals) {
        chairperson = msg.sender;
        voters[chairperson].weight = 1;
        for (uint8 i = 0; i < _numProposals; i++) {
            proposals.push(Proposal({voteCount: 0}));
        }
    }

    function register(address toVoter) public {
        require(msg.sender == chairperson, "Only chairperson can register voters");
        require(!voters[toVoter].voted, "Voter already registered");
        voters[toVoter].weight = 1;
    }

    function vote(uint8 toProposal) public {
        Voter storage sender = voters[msg.sender];
        require(sender.weight != 0, "Has no right to vote");
        require(!sender.voted, "Already voted");
        require(toProposal < proposals.length, "Invalid proposal");

        sender.voted = true;
        sender.vote = toProposal;
        proposals[toProposal].voteCount += sender.weight;
    }

    function winningProposal() public view returns (uint8 _winningProposal) {
        uint256 winningVoteCount = 0;
        for (uint8 p = 0; p < proposals.length; p++) {
            if (proposals[p].voteCount > winningVoteCount) {
                winningVoteCount = proposals[p].voteCount;
                _winningProposal = p;
            }
        }
    }
}
```

#### 4. Simple Auction Contract

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

contract SimpleAuction {
    address public beneficiary;
    uint256 public auctionEndTime;

    address public highestBidder;
    uint256 public highestBid;

    mapping(address => uint256) pendingReturns;
    bool ended;

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

    constructor(
        uint256 _biddingTime,
        address _beneficiary
    ) {
        beneficiary = _beneficiary;
        auctionEndTime = block.timestamp + _biddingTime;
    }

    function bid() public payable {
        require(block.timestamp <= auctionEndTime, "Auction already ended");
        require(msg.value > highestBid, "There already is a higher bid");

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

    function withdraw() public returns (bool) {
        uint256 amount = pendingReturns[msg.sender];
        if (amount > 0) {
            pendingReturns[msg.sender] = 0;
            if (!payable(msg.sender).send(amount)) {
                pendingReturns[msg.sender] = amount;
                return false;
            }
        }
        return true;
    }

    function auctionEnd() public {
        require(block.timestamp >= auctionEndTime, "Auction not yet ended");
        require(!ended, "auctionEnd has already been called");

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

        payable(beneficiary).transfer(highestBid);
    }
}
```

#### 5. Crowdfunding Contract

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

contract Crowdfunding {
    struct Campaign {
        address payable beneficiary;
        uint256 fundingGoal;
        uint256 amountRaised;
        uint256 deadline;
        mapping(address => uint256) contributions;
    }

    mapping(uint256 => Campaign) public campaigns;
    uint256 public numCampaigns;

    function startCampaign(uint256 fundingGoal, uint256 duration) public {
        numCampaigns++;
        Campaign storage c = campaigns[numCampaigns];
        c.beneficiary = payable(msg.sender);
        c.fundingGoal = fundingGoal;
        c.deadline = block.timestamp + duration;
    }

    function contribute(uint256 campaignID) public payable {
        Campaign storage c = campaigns[campaignID];
        require(block.timestamp < c.deadline, "Campaign has ended");
        c.contributions[msg.sender] += msg.value;
        c.amountRaised += msg.value;
    }

    function withdraw(uint256 campaignID) public {
        Campaign storage c = campaigns[campaignID];
        require(block.timestamp >= c.deadline, "Campaign is still ongoing");
        require(msg.sender == c.beneficiary, "Only the beneficiary can withdraw");

        if (c.amountRaised >= c.fundingGoal) {
            c.beneficiary.transfer(c.amountRaised);
        } else {
            payable(msg.sender).transfer(c.contributions[msg.sender]);
            c.contributions[msg.sender] = 0;
        }
    }
}
```

#### 6. Multi-Signature Wallet

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

contract MultiSigWallet {
    address[] public owners;
    uint256 public required;

    struct Transaction {
        address destination;
        uint256 value;
        bool executed;
        mapping(address => bool) confirmations;
    }

    mapping(uint256 => Transaction) public transactions;
    uint256 public transactionCount;

    modifier onlyOwner() {
        require(isOwner(msg.sender), "Not owner");
        _;
    }

    modifier confirmed(uint256 transactionId, address owner) {
        require(transactions[transactionId].confirmations[owner], "Not confirmed");
        _;
    }

    modifier notConfirmed(uint256 transactionId, address owner) {
        require(!transactions[transactionId].confirmations[owner], "Already confirmed");
        _;
    }

    modifier notExecuted(uint256 transactionId) {
        require(!transactions[transactionId].executed, "Already executed");
        _;
    }

    constructor(address[] memory _owners, uint256 _required) {
        require(_owners.length > 0, "Owners required");
        require(_required > 0 && _required <= _owners.length, "Invalid required number of owners");

        for (uint256 i = 0; i < _owners.length; i++) {
            require(!isOwner(_owners[i]) && _owners[i] != address(0), "Invalid owner");
            owners.push(_owners[i]);
        }
        required = _required;
    }

    function isOwner(address addr) public view returns (bool) {
        for (uint256 i = 0; i < owners.length; i++) {
            if (owners[i] == addr) {
                return true;
            }
        }
        return false;
    }

    function submitTransaction(address destination, uint256 value) public onlyOwner {
        transactionCount++;
        Transaction storage t = transactions[transactionCount];
        t.destination = destination;
        t.value = value;
    }

    function confirmTransaction(uint256 transactionId) public onlyOwner notConfirmed(transactionId, msg.sender) {
        transactions[transactionId].confirmations[msg.sender] = true;
        if (isConfirmed(transactionId)) {
            executeTransaction(transactionId);
        }
    }

    function executeTransaction(uint256 transactionId) public onlyOwner notExecuted(transactionId) {
        if (isConfirmed(transactionId)) {
            Transaction storage t = transactions[transactionId];
            t.executed = true;
            payable(t.destination).transfer(t.value);
        }
    }

    function isConfirmed(uint256 transactionId) public view returns (bool) {
        uint256 count = 0;
        for (uint256 i = 0; i < owners.length; i++) {
            if (transactions[transactionId].confirmations[owners[i]]) {
                count += 1;
            }
            if (count == required) {
                return true;
            }
        }
        return false;
    }
}
```

#### 7. Lottery Contract

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

contract Lottery {
    address public manager;
    address[] public players;

    constructor() {
        manager = msg.sender;
    }

    function enter() public payable {
        require(msg.value > .01 ether, "Minimum ether not met");
        players.push(msg.sender);
    }

    function random() private view returns (uint256) {
        return uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp, players)));
    }

    function pickWinner() public restricted {
        uint256 index = random() % players.length;
        payable(players[index]).transfer(address(this).balance);
        players = new address ;
    }

    modifier restricted() {
        require(msg.sender == manager, "Not manager");
        _;
    }

    function getPlayers() public view returns (address[] memory) {
        return players;
    }
}
```

#### 8. Time-Locked Wallet

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

contract TimeLockedWallet {
    address public creator;
    address public owner;
    uint256 public unlockTime;

    constructor(
        address _creator,
        address _owner,
        uint256 _unlockTime
    ) payable {
        creator = _creator;
        owner = _owner;
        unlockTime = _unlockTime;
    }

    function withdraw() public {
        require(block.timestamp >= unlockTime, "Funds are locked");
        require(msg.sender == owner, "Only owner can withdraw");
        payable(owner).transfer(address(this).balance);
    }

    function info() public view returns (address, address, uint256, uint256) {
        return (creator, owner, unlockTime, address(this).balance);
    }
}
```

#### 9. Decentralized Marketplace

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

contract Marketplace {
    struct Product {
        uint256 id;
        string name;
        uint256 price;
        address payable seller;
        address buyer;
        bool delivered;
    }

    uint256 public productCount;
    mapping(uint256 => Product) public products;

    function listProduct(string memory _name, uint256 _price) public {
        require(_price > 0, "Price must be greater than zero");
        productCount++;
        products[productCount] = Product(productCount, _name, _price, payable(msg.sender), address(0), false);
    }

    function buyProduct(uint256 _id) public payable {
        Product storage product = products[_id];
        require(msg.value == product.price, "Incorrect amount sent");
        require(product.seller != msg.sender, "Seller cannot buy their own product");
        require(product.buyer == address(0), "Product already sold");

        product.buyer = msg.sender;
        product.seller.transfer(msg.value);
    }

    function markAsDelivered(uint256 _id) public {
        Product storage product = products[_id];
        require(msg.sender == product.buyer, "Only buyer can mark as delivered");
        product.delivered = true;
    }

    function getProduct(uint256 _id) public view returns (Product memory) {
        return products[_id];
    }
}
```

#### 10. Decentralized Library

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

contract DecentralizedLibrary {
    struct Book {
        uint256 id;
        string title;
        string author;
        address currentHolder;
    }

    uint256 public bookCount;
    mapping(uint256 => Book) public books;

    function addBook(string memory _title, string memory _author) public {
        bookCount++;
        books[bookCount] = Book(bookCount, _title, _author, msg.sender);
    }

    function borrowBook(uint256 _id) public {
        Book storage book = books[_id];
        require(book.currentHolder != msg.sender, "You already have this book");
        book.currentHolder = msg.sender;
    }

    function returnBook(uint256 _id) public {
        Book storage book = books[_id];
        require(book.currentHolder == msg.sender, "You do not have this book");
        book.currentHolder = address(0);
    }

    function getBook(uint256 _id) public view returns (Book memory) {
        return books[_id];
    }
}
```

These examples cover a range of functionalities, including simple storage, tokens, voting, auctions, crowdfunding, multi-signature wallets, lotteries, time-locked wallets, decentralized marketplaces, and libraries. Each contract demonstrates key Solidity concepts and patterns.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://apiary.bharatblockchain.io/smart-contract-writing/code-examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
