Code Examples
Here are 10 code samples in Solidity demonstrating various concepts and functionalities.
1. Simple Storage Contract
// 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
// 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
// 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
// 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
// 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
// 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
// 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
// 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
// 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
// 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.
Last updated