The PseudonymRound contract (previously named contract Registration) schedules each step of the POI test net 24 hour cycle, so that certain functions can only be called at specific time-periods.

register() is open for the first 10 hours of the round, and will be open for 12 days in the live 28 day cycle version.

function register() payable atTime(registration, commitment) { if(userHash[msg.sender] != bytes32(0)) throw; // already registered if(msg.value < depositSize) throw; // generate a hash for the given user, using previous entropy, // senders address and current blocknumber. bytes32 h = sha3(entropy, msg.sender, block.blockhash(block.number)); entropy = h; userHash[msg.sender] = h;

Registering creates a userHash that is used to assign you into a group by random, in the next step commit() , which deterministically assigns a user to a random group (1-indexed), based on number of users, group size and the user hash.

userGroup[msg.sender] = uint(userHash[msg.sender]) / (uint(maxHash) / numGroups()) + 1;

commit() is open for 10 hours.

The schedule then moves from commitment to generateAddress, where the pseudonymGroup that was randomly put together in the previous step is used to generate a pseudonym party address.

function generatePseudonymPartyAddress() atTime(generateAddress, 0) { uint groupNumber = userGroup[msg.sender]; if(groupNumber == 0) throw; // not in a pseudonymGroup if(partyAddress[groupNumber] != bytes32(0)) throw; partyAddress[groupNumber] = sha3(pseudonymGroup[groupNumber]); }

This here is the partyAddress for group 1 in the first 24 hour round, which is ongoing at the moment, and the pseudonym event starts in 2 hours, as the schedule goes from generateAddress to pseudonymEvent

Each step over the 24 hour cycle uses what was done in the previous step, and the reason users of the system call the functions themselves, is so that the computations are divided across many transactions, and so that each transaction is small and has a low gas cost.

During the pseudonym event, someone has to call countVotes() , which deploys the next round.

function countVotes() atTime(pseudonymEvent, 0) { uint newDepositSize; if(numUsers != 0) newDepositSize = depositGovernance / numUsers; proofOfIndividuality.newRound(newDepositSize); }