Last active
November 8, 2018 06:29
-
-
Save resilience-me/34e2e4132b960a19f843e1ecccd2345f to your computer and use it in GitHub Desktop.
This file contains 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 MazeHashFunction { | |
function generateRandomNumber(uint _treasureMap) view internal returns (uint) { | |
bytes memory randomNumber = new bytes(32); | |
bytes memory treasureMapInBytes = toBytes(_treasureMap); | |
uint8 nextByteInTreasureMap = uint8(treasureMapInBytes[31]); | |
uint8 pointerToNextPosition = nextByteInTreasureMap; | |
for(uint i = 31; i >0; i--) { | |
uint nextHashInLabyrinth = uint(blockhash(block.number - 1 - pointerToNextPosition)); | |
bytes memory blockHashToBytes = toBytes(nextHashInLabyrinth); | |
uint8 byteFromBlockhash = uint8(blockHashToBytes[i]); | |
nextByteInTreasureMap = uint8(treasureMapInBytes[i]); | |
uint8 nextRandomNumber = nextByteInTreasureMap ^ byteFromBlockhash; | |
randomNumber[i] = bytes1(nextRandomNumber); | |
pointerToNextPosition = nextRandomNumber; | |
} | |
return toUint(randomNumber); | |
} | |
function toBytes(uint256 x) pure internal returns (bytes b) { | |
b = new bytes(32); | |
assembly { mstore(add(b, 32), x) } | |
} | |
function toUint(bytes x) pure internal returns (uint b) { | |
assembly { | |
b := mload(add(x, 0x20)) | |
} | |
} | |
} | |
contract PseudonymPairs is MazeHashFunction { | |
enum State { interlude, pseudonymEvent, endOfPeriod } | |
uint[3] timeperiods; | |
uint genesisTimestamp = now; | |
modifier atTime(State _inState, State _nextState) { | |
require(now > getTime(_inState)); | |
require(now < getTime(_nextState)); | |
_; | |
} | |
function getTime(State _state) view returns (uint) { | |
return genesisTimestamp + (timeperiods[2] * eventCounter) + timeperiods[uint(_state)]; | |
} | |
modifier incrementEventCounter { | |
if(now > getTime(State.endOfPeriod)) eventCounter++; | |
_; | |
} | |
constructor() { | |
genesisTimestamp = now; | |
timeperiods[2] = 28 days; // 13 events per year, 364 day year | |
timeperiods[1] = 28 days - 20 minutes; // pseudonym event lasts 20 minutes | |
timeperiods[0] = 0; | |
} | |
function register(uint _nym) internal atTime(State.interlude, State.pseudonymEvent) { } | |
mapping(uint => uint) sortingMechanism; // Actual position of the ID, after being shuffled with each new person joining the pool | |
mapping(address => uint) pseudonymID; | |
mapping(uint => address) pseudonymIndex; | |
uint totalSorted; | |
mapping(uint => uint) virtualBorder; // Mapped to sortingMechanism, hitch-hikes on a registered person, and the shuffling on their end | |
mapping(uint => uint) borderPatrol; // immigrantID mapped to the actual position in the immigrant pool, after shuffling each new person | |
mapping(address => uint) immigrantID; | |
mapping(uint => address) immigrantIndex; | |
uint totalImmigrants; | |
uint entropy; | |
function sortMe() atTime(State.interlude, State.pseudonymEvent) { | |
require(pseudonymID[msg.sender] == 0); | |
totalSorted++; | |
pseudonymID[msg.sender] = totalSorted; | |
pseudonymIndex[totalSorted] = msg.sender; | |
entropy = generateRandomNumber(entropy); | |
uint randomNumber = 1 + (entropy % totalSorted); | |
sortingMechanism[randomNumber] = totalSorted; | |
sortingMechanism[totalSorted] = randomNumber; | |
} | |
function getPair(address _nym) view atTime(State.pseudonymEvent, State.endOfPeriod) returns (uint) { | |
uint ID = pseudonymID[_nym] | |
uint nominator = sortingMechanism[ID]; | |
if(sortingMechanism[ID] % 2 == 1) nominator += 1; | |
uint pair = denominator / 2; | |
return pair; | |
} | |
function optIn() atTime(State.interlude, State.pseudonymEvent) { | |
require(immigrantID[msg.sender] == 0); | |
require(borderToken.balanceOf[msg.sender] >= 1); | |
borderToken.balanceOf[msg.sender]--; | |
totalImmigrants++; | |
immigrantID[msg.sender] = totalImmigrants; | |
immigrantIndex[totalImmigrants] = msg.sender; | |
entropy = generateRandomNumber(entropy); | |
uint randomImmigrant = 1 + (entropy % totalImmigrants); | |
borderPatrol[randomImmigrant] = totalImmigrants; | |
borderPatrol[totalImmigrants] = randomImmigrant; | |
entropy = generateRandomNumber(entropy); | |
uint randomNumber = 1 + (entropy % totalSorted); // Hitch-hike on a registered person, and the shuffling on their end | |
if(randomNumber % 2 == 1) randomNumber - 1; // Sort into even numbers, to map with the pairs, see getPair() | |
virtualBorder[totalImmigrants] = randomNumber; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment