Skip to content

Instantly share code, notes, and snippets.

@logankilpatrick
Created March 14, 2021 16:23
Show Gist options
  • Save logankilpatrick/de27ef92269d6761d1d2a53d690e1b2c to your computer and use it in GitHub Desktop.
Save logankilpatrick/de27ef92269d6761d1d2a53d690e1b2c to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.7.4+commit.3f05b770.js&optimize=false&runs=200&gist=
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.8.0;
contract AverageStream {
uint private count;
uint private pre_average;
uint public decimal;
constructor() {
count = 0;
pre_average = 0;
decimal = 3;
}
function add_element(uint num) public {
count += 1;
pre_average += num;
}
function set_decimal(uint new_decimal) public {
decimal = new_decimal;
}
// Inspired by https://ethereum.stackexchange.com/questions/65969/how-would-one-divide-a-decimal-by-a-decimal-in-soliditys
function divider(uint numerator, uint denominator) public view returns(uint) {
return numerator * (uint(10) ** uint(decimal)) / denominator;
}
// Issue I opended: https://github.com/ethereum/solidity/issues/11101
function get_average() public view returns (uint) {
return divider(pre_average, count);
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.8.0;
contract Bank {
address private owner;
mapping (address => uint) private balances;
event LogDeposit(address depositor, uint amount);
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not owner");
_;
}
constructor() {
owner = msg.sender;
}
// function internal
function deposit() public payable returns (uint newBalance) {
balances[msg.sender] += msg.value;
emit LogDeposit(msg.sender, msg.value);
return balances[msg.sender];
}
function attemptSend(address payable account, uint withdrawAmount) internal {
bool sent = account.send(withdrawAmount);
if ( !sent ) {
balances[account] += withdrawAmount;
}
}
function withdraw(uint withdrawAmount) external returns (uint newBalance) {
if ( balances[msg.sender] >= withdrawAmount ) {
balances[msg.sender] -= withdrawAmount;
attemptSend(msg.sender, withdrawAmount);
}
return balances[msg.sender];
}
function balance() public view returns (uint) {
return balances[msg.sender];
}
function balance(address account) public view onlyOwner returns (uint) {
return balances[account];
}
fallback () external {
revert();
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.8.0;
contract FactorialMemo {
// maps a address to a uint, with public scope, called memo_dict.
// Similar to a python dict.
mapping(uint => uint) public memo_dict;
constructor() {
memo_dict[0] = 1;
memo_dict[1] = 1;
}
function factorial(uint n) public returns (uint) {
// Greator than zero check since solidity is defaulting the mapping to 0
if (memo_dict[n] > 0) {
return memo_dict[n];
}
memo_dict[n] = n * factorial(n - 1);
return memo_dict[n];
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.8.0;
contract Voting {
// Keep track of owner
address private owner;
mapping (int => uint8) public votesReceived;
// Mapping to keep track of who cast a vote already
mapping (address => bool) private castedVotes;
int[5] candidateList = [int(0),1,2,3,4];
// Keeps track of who the winner is
int private winner;
bytes32 private currentStatus = "INDETERMINATE";
bytes32 private votingStatus = "OPEN";
// Immutable allows the value to be set in the constructor.
int immutable private numVoters;
// Keep track of the number of votes cast to see if there's 50% concensus.
int private totalNumVotes;
constructor(int num) {
numVoters = num;
owner = msg.sender;
}
// Getter for the private winner variable held in contract storage.
function getWinner() view public returns (int) {
assert(votingStatus == "CLOSED");
assert(currentStatus == "WINNER");
// Asserts are the only cool thing about solidity.
return winner;
}
function getnumVoters() view public returns (int) {
return numVoters;
}
function getStatus() public view returns (bytes32) {
return currentStatus;
}
// Note that the logic here may be reversed...
modifier notOwner() {
// If the condition is false, prints the message.
require(msg.sender == owner, "Caller is not the owner");
_;
}
function totalVotesFor(int candidate) view public returns (uint8) {
require(validCandidate(candidate));
return votesReceived[candidate];
}
// Checks if user has already voted, if not, caches vote and returns true
function validateAndCacheVote() public returns (bool) {
if (castedVotes[msg.sender] == true) {
return false;
}
castedVotes[msg.sender] = true;
// x = 1 ether; TODO: Add 1 ether cost per vote
return true;
}
function isVotingOpen() public view returns (bool) {
if (votingStatus != "CLOSED") {
return true;
}
return false;
}
// Does not let the function be called if modifier is false (meaning vote cast by owner)
function voteForCandidate(int candidate) public notOwner {
require(validCandidate(candidate));
// Enforce that voting is open before allowing a vote to be cast.
require(isVotingOpen());
// Before saving a vote, make sure that it is valid.
require(validateAndCacheVote());
votesReceived[candidate] += 1;
// Increase total vote count.
totalNumVotes += 1;
updateStandings();
}
// Loop through the candidateList and figure out who has more votes.
function updateStandings() private {
int tempWinner;
for(uint i = 0; i < candidateList.length; i++) {
// Initial condition
if (i == 0) {
tempWinner = candidateList[i];
}
else {
// If the number of votes is greator than the current #, update winner
if (votesReceived[int(i)] > votesReceived[tempWinner]) {
tempWinner = candidateList[i];
}
// NOTE: This does not handle a runoff with a tie vote.
}
}
if (totalNumVotes == numVoters) {
votingStatus = "CLOSED";
}
// TODO: Take care of the edge case where it is impossible for the winner to change
// ... but all of the votes have not been cast yet.
// Check if the person who has the most votes also has 50%.
// NOTE: This may not work since division in solidity is messed up
if (votesReceived[tempWinner] > (totalNumVotes / 2)) {
winner = tempWinner;
currentStatus = "WINNER";
} else {
// The function only gets called when a vote is case so if there's no winner,
// it is no longer INDETERMINATE.
currentStatus = "NO_WINNER";
// We also do not set the winner variable yet.
}
}
function validCandidate(int candidate) view private returns (bool) {
for(uint i = 0; i < candidateList.length; i++) {
if (candidateList[i] == candidate) {
return true;
}
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment