-
-
Save simondlr/0e0ca655bd13c1dad072 to your computer and use it in GitHub Desktop.
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
| 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