Last active
May 22, 2022 02:01
-
-
Save pau1m/baa7e8a8dfe1c2852f0c876b61ba6af2 to your computer and use it in GitHub Desktop.
Donation smart contract
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.4; | |
// TestRPC HD wallet | |
// warrior minimum breeze raven garden express solar flavor obvious twenty alpha actress | |
contract Donation { | |
// Instantiate a variable to hold the account address of the contract administrator | |
address public owner; | |
// Create a data structure to reperesent each of the participants. | |
struct Payee { | |
// If the payee can administer their account. | |
bool status; | |
// The amount relative to aggregate weight that a payee will receive. | |
uint weight; | |
// A record of the amount held for the payee. | |
uint balance; | |
} | |
// Create an associative arrays with account address as key and payee data sturcture as value. | |
mapping(address => Payee) public payees; | |
// Create an array like mapping to behave as an index of addreesses | |
mapping (int8 => address) public payeesIndex; | |
// Keep note of total number of participants in the system so we can iterate over index. | |
int8 public payeesIndexSize; | |
// Declare events for actions we may want to watch | |
event NewDonation(address indexed donator, uint amt); | |
event Transfer(address indexed from, address indexed to, uint amt); | |
event PayeeAction(address indexed payee, bytes32 action); | |
event Withdrawal(address indexed payee, uint amt); | |
event OwnerChanged(address indexed owner, address indexed newOwner); | |
event ContractDestroyed(address indexed contractAddress); | |
// Constructor | |
function Donation() { | |
// Set the address of the contract deployer to be owner. | |
owner = msg.sender; | |
payees[owner].status = true; | |
payees[owner].weight = 10; | |
payeesIndex[0] = owner; | |
payeesIndexSize = 1; | |
} | |
// Check if current account calling methods is the owner. | |
modifier isOwner() { | |
if (msg.sender != owner) throw; | |
_; | |
} | |
// Check if current account calling methods is a valid payee of the contract. | |
modifier isPayee() { | |
if (payees[msg.sender].status != true) throw; | |
_; | |
} | |
// Aggregate all payee weights. | |
function getTotalWeight() private returns (uint) { | |
int8 i; | |
uint totalWeight = 0; | |
for (i=0;i<payeesIndexSize;i++) { | |
if (payees[payeesIndex[i]].status == true) { | |
totalWeight += payees[payeesIndex[i]].weight; | |
} | |
} | |
return totalWeight; | |
} | |
// Function which will accept donations. | |
function deposit() payable { | |
if (msg.value == 0) throw; | |
int8 i; | |
uint totalWeight = 0; | |
totalWeight = getTotalWeight(); | |
// Update account balances for all payees. | |
for (i=0;i<payeesIndexSize;i++) { | |
if (payees[payeesIndex[i]].status == true) { | |
uint divisor = (totalWeight / payees[payeesIndex[i]].weight); | |
payees[payeesIndex[i]].balance = msg.value / divisor; | |
} | |
} | |
NewDonation(msg.sender, msg.value); | |
} | |
// Add a new payee to the contract. | |
function addPayee(address _payee, uint _weight) isOwner returns (bool) { | |
payees[_payee].weight = _weight; | |
payees[_payee].status = true; | |
payeesIndex[payeesIndexSize] = _payee; | |
payeesIndexSize++; | |
PayeeAction(_payee, 'added'); | |
} | |
// Amend payee weight. | |
function updatePayeeWeight(address _payee, uint _weight) isOwner { | |
payees[_payee].weight = _weight; | |
} | |
// Disallow an account address from acting on contract. | |
function disablePayee(address _payee) isOwner returns (bool) { | |
if (_payee == owner) throw; // Don't lock out the main account | |
payees[_payee].status = false; | |
PayeeAction(_payee, 'disabled'); | |
} | |
// Allow an account address from acting on contract. | |
function enablePayee(address _address) isOwner { | |
payees[_address].status = true; | |
PayeeAction(_address, 'enabled'); | |
} | |
// Allows payee to withdraw eth to their Ethereum account address. | |
function withdraw(uint amount) payable isPayee { | |
if (payees[msg.sender].status != true || amount > payees[msg.sender].balance) throw; | |
if (!msg.sender.send(amount)) throw; | |
Withdrawal(msg.sender, amount); | |
payees[msg.sender].balance -= amount; | |
} | |
// Transfer some Ether available to withdraw to another account. | |
function transferBalance(address _from, address _to, uint amount) isOwner { | |
if (payees[_from].balance < amount) throw; | |
payees[_from].balance -= amount; | |
payees[_to].balance += amount; | |
Transfer(_from, _to, amount); | |
} | |
function getBalance(address _address) isPayee returns (uint) { | |
return payees[_address].balance; | |
} | |
function getWeight(address _address) isPayee returns(uint) { | |
return payees[_address].weight; | |
} | |
function getStatus(address _address) returns(bool) { | |
return payees[_address].status; | |
} | |
// Change ownership of the contract. | |
function transferOwner(address newOwner) isOwner returns (bool) { | |
if (!payees[newOwner].status == true) throw; | |
OwnerChanged(owner, newOwner); | |
owner = newOwner; | |
} | |
// Destroy the contract and pay out all enabled members. | |
// Any outstanding value will be transferred to owner. | |
function kill() payable isOwner { | |
int8 i; | |
address payee; | |
for (i=0;i<payeesIndexSize;i++) { | |
payee = payeesIndex[i]; | |
if (payees[payee].balance > 0 ) { | |
if (payee.send(payees[payee].balance)) { | |
Withdrawal(payee, payees[payee].balance); | |
} | |
} | |
} | |
ContractDestroyed(this); | |
selfdestruct(owner); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment