Skip to content

Instantly share code, notes, and snippets.

@kdelwat
Created June 23, 2021 11:28
Show Gist options
  • Save kdelwat/5e100e9a3d432f9c028ca8b579962753 to your computer and use it in GitHub Desktop.
Save kdelwat/5e100e9a3d432f9c028ca8b579962753 to your computer and use it in GitHub Desktop.
Example smart contracts from the Women in Digital workshop. Adapted from the examples at https://docs.soliditylang.org/en/v0.8.6/solidity-by-example.html
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract KV {
bytes32[] private reservedKeys;
mapping(bytes32 => string) private values;
constructor(bytes32[] memory _reservedKeys) {
reservedKeys = _reservedKeys;
}
function setValue(bytes32 _key, string memory _value) public {
require(!isReservedKey(_key));
values[_key] = _value;
}
function getValue(bytes32 _key) public view returns (string memory) {
return values[_key];
}
function isReservedKey(bytes32 _key) private view returns (bool) {
for (uint256 i = 0; i < reservedKeys.length; i++) {
if (reservedKeys[i] == _key) {
return true;
}
}
return false;
}
}
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract KV {
mapping(bytes32 => bool) private reservedKeys;
mapping(bytes32 => string) private values;
address private admin;
constructor(bytes32[] memory _reservedKeys) {
for (uint256 i = 0; i < _reservedKeys.length; i++) {
reservedKeys[_reservedKeys[i]] = true;
}
admin = msg.sender;
}
modifier onlyAdmin() {
require(msg.sender == admin, "User is not an admin");
_;
}
function setValue(bytes32 _key, string memory _value) public onlyAdmin {
// Conditions
require(!isReservedKey(_key), "Key is reserved");
// Effects
values[_key] = _value;
}
function addReservedKey(bytes32 _key) public onlyAdmin {
reservedKeys[_key] = true;
}
function getValue(bytes32 _key) public view returns (string memory) {
return values[_key];
}
function isReservedKey(bytes32 _key) private view returns (bool) {
return reservedKeys[_key];
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
interface SimpleAuction {
event HighestBidIncreased(address bidder, uint amount);
event AuctionEnded(address winner, uint amount);
function bid() external payable;
function withdraw() external returns (bool);
function auctionEnd() external;
}
contract Auction is SimpleAuction {
address payable public beneficiary;
uint public auctionEndTime;
mapping(address => uint) bids;
address[] bidders;
mapping(address => uint) pendingReturns;
bool ended;
constructor(
uint _biddingTime,
address payable _beneficiary
) {
beneficiary = _beneficiary;
auctionEndTime = block.timestamp + _biddingTime;
}
function bid() external payable override {
require(
block.timestamp <= auctionEndTime,
"Auction already ended."
);
address highestBidder = getHighestBidder();
uint256 highestBid = bids[highestBidder];
require(
msg.value > highestBid,
"There already is a higher bid."
);
bidders.push(msg.sender);
bids[msg.sender] = msg.value;
emit HighestBidIncreased(msg.sender, msg.value);
}
function withdraw() public override returns (bool) {
uint 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() override public {
require(block.timestamp >= auctionEndTime, "Auction not yet ended.");
require(!ended, "auctionEnd has already been called.");
address highestBidder = getHighestBidder();
uint256 highestBid = bids[highestBidder];
emit AuctionEnded(highestBidder, highestBid);
beneficiary.transfer(highestBid);
for (uint256 i = 0; i < bidders.length; i++) {
if (bidders[i] != highestBidder) {
pendingReturns[bidders[i]] += bids[bidders[i]];
}
}
}
function getHighestBidder() private view returns (address) {
address highestBidder;
uint256 highestBid;
for (uint256 i = 0; i < bidders.length; i++) {
if (bids[bidders[i]] > highestBid) {
highestBid = bids[bidders[i]];
highestBidder = bidders[i];
}
}
return highestBidder;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
interface SimpleAuction {
function bid() external payable;
function withdraw() external returns (bool);
function auctionEnd() external;
}
interface SimpleAuctionEvents {
event HighestBidIncreased(address bidder, uint amount);
event AuctionEnded(address winner, uint amount);
}
contract Auction is SimpleAuction, SimpleAuctionEvents {
address payable public beneficiary;
uint public auctionEndTime;
bool public ended;
address public highestBidder;
uint public highestBid;
// WITHDRAWAL PATTERN
mapping(address => uint) public pendingReturns;
constructor(uint _biddingTime, address payable _beneficiary) {
beneficiary = _beneficiary;
auctionEndTime = block.timestamp + _biddingTime;
}
function bid() external payable override {
// CONDITIONS
// Has auction ended?
require(block.timestamp <= auctionEndTime, "Auction has ended.");
// Is there a higher bidder?
require(msg.value > highestBid, "Bid is too low.");
// EFFECTS
if (highestBid != 0) {
pendingReturns[highestBidder] += highestBid;
}
// Store my bid
highestBid = msg.value;
highestBidder = msg.sender;
// INTERACTIONS
// Create an event!
emit HighestBidIncreased(msg.sender, msg.value);
}
function auctionEnd() external override {
// CONDITIONS
// HAve we reached the end of the bidding period?
require(block.timestamp > auctionEndTime, "Auction has not yet ended.");
// Has the auction already ended?
require(!ended, "auctionEnd has already been called.");
// INTERACTIONS
// Transfer the winning bid to the beneficiary
beneficiary.transfer(highestBid);
// Emit an event telling people that the auction has ended
emit AuctionEnded(highestBidder, highestBid);
}
function withdraw() external override returns (bool) {
// CONDITIONS
// Is there ETH to withdraw?
uint amount = pendingReturns[msg.sender];
require(amount > 0, "Nothing to withdraw.");
// EFFECTS
// Mark the withdraw as complete
// GOOD!
pendingReturns[msg.sender] = 0;
// INTERACTIONS
// Send the withdrawal amount to the withdrawer
if (!payable(msg.sender).send(amount)) {
pendingReturns[msg.sender] = amount;
return false;
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment