Skip to content

Instantly share code, notes, and snippets.

@simondlr
Created February 19, 2016 13:25
Show Gist options
  • Select an option

  • Save simondlr/0e0ca655bd13c1dad072 to your computer and use it in GitHub Desktop.

Select an option

Save simondlr/0e0ca655bd13c1dad072 to your computer and use it in GitHub Desktop.
contract TinyHuman {
/* STRUCTS */
struct Owner {
address addr; // Can be linked off-chain to a persona (like "Imogen Heap" or "Guitar Guy Bob")
bytes32 name;
}
mapping(bytes32 => mapping(bytes32 => uint)) public shares;
struct Payment {
address payee; // Somebody who has paid for this download. Can't be linked to a persona,
// but can still be visualized as a cloud of anonymized purchasers.
bytes32 right; // The type of the right that was paid
uint blockNum; // The block number at which this payee made the purchase
// (so we can visualize purchases over time)
uint amount; // The amount paid.
uint exchangePrice;
}
struct Transfer {
address owner; //to whom the right is transferred
bytes32 right;
uint blockNum;
}
/* addresses */
address public admin;
address public oracle;
address public BLOCKAPPS; //potentially for BLOCKAPPS
address public BOARD_1;
address public BOARD_2;
address public BOARD_3;
mapping (address => address) boardVotesForNewAdmin;
/* Prices */
//must be granular to order of 3. So stored as 120 = 1.20 USD.
uint public constant USDDOWNLOADPRICE = 60; //0.6 usd.
uint public constant USDSTEMPRICE = 4500; //45.00.usd.
uint public usdEthPrice;
uint public downloadPriceInWei;
uint public stemPriceInWei;
uint public priceLastUpdated; //in timestamp
/* OWNERS */
/*
ImogenHeap 91.25%
Violin1 StephanieAppelhans 1.25%
Violin2 DiegoRomano 1.25%
Viola YasinGündisch 1.25%
Cello HoangNguyen 1.25%
BassTrombone SimonMinshall 1.25%
FrenchHorn DavidHorwich 1.25%
Masteringengineer SimonHeyworth 1.25%
*/
uint public constant TOTALSHARES = 1000000; //100% = 100.0000 = 1000000
Owner[] public owners;
uint public ownersCount = 8;
Payment[] public txLog;
uint public txCount;
Transfer[] public transferLog;
uint public transferCount;
event purchasedRight(address indexed payee, bytes32 right);
event transferredRight(address indexed owner, bytes32 right);
/* Constructor */
function TinyHuman(address _board1, address _board2, address _board3) {
admin = msg.sender;
oracle = msg.sender;
BOARD_1 = _board1;
BOARD_2 = _board2;
BOARD_3 = _board3;
Owner memory ImogenHeap;
Owner memory StephanieAppelhans;
Owner memory DiegoRomano;
Owner memory YasinGundisch;
Owner memory HoangNguyen;
Owner memory SimonMinshall;
Owner memory DavidHorwich;
Owner memory SimonHeyworth;
/*owners*/
ImogenHeap.addr = msg.sender;
ImogenHeap.name = "Imogen Heap";
StephanieAppelhans.addr = msg.sender;
StephanieAppelhans.name = "Stephanie Appelhans";
DiegoRomano.addr = msg.sender;
DiegoRomano.name = "Diego Romano";
YasinGundisch.addr = msg.sender;
YasinGundisch.name = "Yasin Gundisch";
HoangNguyen.addr = msg.sender;
HoangNguyen.name = "Hoang Nguyen";
SimonMinshall.addr = msg.sender;
SimonMinshall.name = "Simon Minshall";
DavidHorwich.addr = msg.sender;
DavidHorwich.name = "David Horwich";
SimonHeyworth.addr = msg.sender;
SimonHeyworth.name = "Simon Heyworth";
shares["Imogen Heap"]['DOWNLOAD'] = 912500; //91.2500
shares["Stephanie Appelhans"]['DOWNLOAD'] = 12500; //1.2500
shares["Diego Romano"]['DOWNLOAD'] = 12500; //1.2500
shares["Yasin Gundisch"]['DOWNLOAD'] = 12500; //1.2500
shares["Hoang Nguyen"]['DOWNLOAD'] = 12500; //1.2500
shares["Simon Minshall"]['DOWNLOAD'] = 12500; //1.2500
shares["David Horwich"]['DOWNLOAD'] = 12500; //1.2500
shares["Simon Heyworth"]['DOWNLOAD'] = 12500; //1.2500
shares["Imogen Heap"]['STEM'] = 912500; //91.2500
shares["Stephanie Appelhans"]['STEM'] = 14583; //1.4583
shares["Diego Romano"]['STEM'] = 14583; //1.4583
shares["Yasin Gundisch"]['STEM'] = 14583; //1.4583
shares["Hoang Nguyen"]['STEM'] = 14583; //1.4583
shares["Simon Minshall"]['STEM'] = 14583; //1.4583
shares["David Horwich"]['STEM'] = 14583; //1.4583
shares["Simon Heyworth"]['STEM'] = 0; //0.0000. Mastering Engineer. No split for stem.
owners.length = 8;
owners[0] = ImogenHeap;
owners[1] = StephanieAppelhans;
owners[2] = DiegoRomano;
owners[3] = YasinGundisch;
owners[4] = HoangNguyen;
owners[5] = SimonMinshall;
owners[6] = DavidHorwich;
owners[7] = SimonHeyworth;
priceLastUpdated = block.timestamp;
txCount = 0;
transferCount = 0;
BLOCKAPPS = msg.sender;
}
modifier isAdmin() {
if(msg.sender == admin) {
_
}
}
modifier isOracle() {
if(msg.sender == oracle) {
_
}
}
/* Buy the right to download Tiny Human */
function purchase(bytes32 _right) public returns (bool) {
if((_right == 'DOWNLOAD' && msg.value >= downloadPriceInWei)
|| (_right == 'STEM' && msg.value >= stemPriceInWei)
) {
addTransaction(_right);
return true;
} else {
msg.sender.send(msg.value); //send back money.
return false;
}
}
function addTransaction(bytes32 _right) internal {
Payment memory newPayment;
newPayment.payee = msg.sender;
newPayment.right = _right;
newPayment.blockNum = block.number;
newPayment.amount = msg.value;
newPayment.exchangePrice = usdEthPrice;
txLog.length = txCount + 1;
txLog[txCount] = newPayment;
txCount = txCount + 1;
for(uint i = 0; i < ownersCount; i+=1) {
if(shares[owners[i].name][_right] > 0) {
(owners[i].addr).send(msg.value * shares[owners[i].name][_right] / TOTALSHARES);
}
}
purchasedRight(msg.sender, _right);
transferRight(msg.sender, _right);
}
//think of a better function name.
function transferRightIfApproved(address _owner, bytes32 _right) external {
if(msg.sender == BLOCKAPPS) {
transferRight(_owner, _right);
}
}
function transferRight(address _owner, bytes32 _right) internal {
Transfer memory newTransfer;
newTransfer.owner = _owner;
newTransfer.right = _right;
newTransfer.blockNum = block.number;
transferLog.length = transferCount + 1;
transferLog[transferCount] = newTransfer;
transferCount += 1;
transferredRight(_owner, _right);
}
function setAddr(uint _index, address _newAddr) isAdmin() returns (bool _success) {
owners[_index].addr = _newAddr;
_success = true;
}
function setBlockappsAddr(address _newBlockapps) isAdmin() returns (bool _success) {
BLOCKAPPS = _newBlockapps;
_success = true;
}
function setNewAdmin(address _newAdmin) isAdmin() returns (bool _success) {
admin = _newAdmin;
_success = true;
}
function setNewOracle(address _newOracle) isAdmin() returns (bool _success) {
oracle = _newOracle;
_success = true;
}
function setPrice(uint _newPrice) isOracle() returns (bool _success) {
usdEthPrice = _newPrice;
downloadPriceInWei = getDownloadPrice();
stemPriceInWei = getStemPrice();
priceLastUpdated = block.timestamp;
_success = true;
}
//for exceptional circumstance if admin is compromised, the board can vote a new one in.
function changeAdminFromBoard(address _newAdmin) returns (bool) {
if(msg.sender == BOARD_1 ||
msg.sender == BOARD_2 ||
msg.sender == BOARD_3) {
boardVotesForNewAdmin[msg.sender] = _newAdmin;
}
if(boardVotesForNewAdmin[BOARD_1] == _newAdmin &&
boardVotesForNewAdmin[BOARD_2] == _newAdmin &&
boardVotesForNewAdmin[BOARD_3] == _newAdmin) {
admin = _newAdmin;
return true;
} else { return false; }
}
function getDownloadPrice() private returns (uint) {
//price granularity is 3 levels deep. 1.20 usd = 120.
//trackPrice/ExchangeRate = multiplier
//then multiplier * wei = price in wei.
return (USDDOWNLOADPRICE*(10**18)) / (usdEthPrice);
}
function getStemPrice() private returns (uint) {
return (USDSTEMPRICE*(10**18)) / (usdEthPrice);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment