Skip to content

Instantly share code, notes, and snippets.

@resilience-me
Last active November 8, 2018 06:29
Show Gist options
  • Save resilience-me/34e2e4132b960a19f843e1ecccd2345f to your computer and use it in GitHub Desktop.
Save resilience-me/34e2e4132b960a19f843e1ecccd2345f to your computer and use it in GitHub Desktop.
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