Skip to content

Instantly share code, notes, and snippets.

@resilience-me
Last active January 30, 2017 18:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save resilience-me/08c6de3167ed04cb3ecc8f9a2170e2ee to your computer and use it in GitHub Desktop.
Save resilience-me/08c6de3167ed04cb3ecc8f9a2170e2ee to your computer and use it in GitHub Desktop.
proof of concept 3
pragma solidity ^0.4.6;
contract ProofOfIndividuality {
PseudonymRound public currentPOIs;
address public currentRound;
uint public groupSize;
uint public commitment;
uint public generateAddress;
uint public pseudonymEvent;
uint public issuePOIs;
uint public roundLength;
uint public previousRound;
function ProofOfIndividuality() {
groupSize = 5;
roundLength = 28 days;
commitment = 14 days;
generateAddress = 26 days;
pseudonymEvent = 28 days - 15 minutes;
issuePOIs = 28 days;
currentRound = new PseudonymRound(
now,
groupSize,
0,
commitment,
generateAddress,
pseudonymEvent,
issuePOIs
);
previousRound = now;
}
function newRound(uint _newDepositSize) {
if(msg.sender != currentRound) throw;
currentPOIs = PseudonymRound(currentRound);
currentRound = new PseudonymRound(
previousRound + roundLength,
groupSize,
_newDepositSize,
commitment,
generateAddress,
pseudonymEvent,
issuePOIs
);
previousRound += roundLength;
}
function verifyPOI(address _nym) public returns (bool) {
return currentPOIs.verifyPOI(_nym);
}
}
contract PseudonymRound {
ProofOfIndividuality public proofOfIndividuality;
uint public numUsers;
uint public groupSize;
uint public depositSize;
mapping(address => uint256) public deposit;
mapping(address => bytes32) public userHash;
mapping(address => uint) public userGroup;
mapping(uint => address[]) public pseudonymGroup;
mapping(uint => bytes32) public partyAddress;
mapping(address => bool) public POI;
function verifyPOI(address _nym) public returns (bool) { return POI[_nym]; }
bytes32 entropy;
// max value of a sha3 hash
bytes32 maxHash = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
uint public registration;
uint public commitment;
uint public generateAddress;
uint public pseudonymEvent;
uint public issuePOIs;
modifier atTime(uint _currentState, uint _nextState) {
if(_nextState == 0) {
if(now < _currentState) throw;
_;
}
else {
if (now < _currentState
|| now > _nextState) throw;
_;
}
}
function numGroups() public constant returns(uint){
uint numberOfGroups = numUsers / groupSize;
if(numUsers%groupSize > 0) numberOfGroups++;
return numberOfGroups;
}
function PseudonymRound(uint _deployment, uint _groupSize, uint _newDepositSize, uint _commitment, uint _generateAddress, uint _pseudonymEvent, uint _issuePOIs) {
proofOfIndividuality = ProofOfIndividuality(msg.sender);
registration = _deployment;
groupSize = _groupSize;
depositSize = _newDepositSize;
commitment = _deployment + _commitment;
generateAddress = _deployment + _generateAddress;
pseudonymEvent = _deployment + _pseudonymEvent;
issuePOIs = _deployment + _issuePOIs;
entropy = sha3(block.blockhash(block.number));
}
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;
numUsers++;
deposit[msg.sender] += msg.value;
depositSizeVote[msg.sender] += msg.value;
}
function commit() atTime(commitment, pseudonymEvent) {
if(userHash[msg.sender] == bytes32(0)) // not registered
if(userGroup[msg.sender] != 0) throw; // group already assigned
uint groupNumber = uint(userHash[msg.sender]) / (uint(maxHash) / numGroups()) + 1;
if(pseudonymGroup[groupNumber].length >= groupSize) {
for(uint i = 0; i < numGroups(); i++) {
if(groupNumber - i >= 1) {
if(pseudonymGroup[groupNumber - i].length < groupSize) { groupNumber -= i; break; }
}
if(groupNumber + i <= numGroups()) {
if(pseudonymGroup[groupNumber + i].length < groupSize) { groupNumber += i; break; }
}
}
}
userGroup[msg.sender] = groupNumber;
pseudonymGroup[groupNumber].push(msg.sender);
Nym[msg.sender].positiveNYM = 5000;
Nym[msg.sender].negativeNYM = 2000;
}
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]);
}
function getPseudonymAddress() atTime(generateAddress, 0) returns (bytes32) {
uint groupNumber = userGroup[msg.sender];
if(partyAddress[groupNumber] == 0) generatePseudonymPartyAddress();
return partyAddress[groupNumber];
}
struct NYM {
int positiveNYM;
int negativeNYM;
}
mapping(address => NYM) public Nym;
mapping(address => int) public points;
modifier inParty(address _to) {
if(userGroup[_to] != userGroup[msg.sender]) throw;
_;
}
/* Each pseudonym can give out +5000 NYM. A pseudonyms points can not go above 6000 */
function givePositiveNYM(address _to, int _nym) atTime(pseudonymEvent, issuePOIs) inParty(_to) {
if(_to == msg.sender) throw;
if(_nym > Nym[msg.sender].positiveNYM) _nym = Nym[msg.sender].positiveNYM;
if(points[_to] + _nym > 6000) _nym = 6000 - points[_to];
points[_to] += _nym;
Nym[msg.sender].positiveNYM -= _nym;
}
/* Each pseudonym can give out -2000 NYM. A pseudonyms points can not go below 0 */
function giveNegativeNYM(address _to, int _nym) atTime(pseudonymEvent, issuePOIs) inParty(_to) {
if(_to == msg.sender) throw;
if(_nym > Nym[msg.sender].negativeNYM) _nym = Nym[msg.sender].negativeNYM;
if(points[_to] - _nym < 0) _nym = points[_to];
points[_to] -= _nym;
Nym[msg.sender].negativeNYM -= _nym;
}
/* Each pseudonym needs 4000 points to be verified */
function submitVerifiedUsers() atTime(issuePOIs, 0) {
uint groupNumber = userGroup[msg.sender];
for(uint i = 0; i < pseudonymGroup[groupNumber].length; i++){
address nym = pseudonymGroup[groupNumber][i];
if(points[nym] >= 4000) POI[nym] = true;
}
}
uint public depositGovernance;
mapping(address => uint) public depositSizeVote;
function vote(uint _depositSize) payable atTime(registration, pseudonymEvent) {
if(depositSizeVote[msg.sender] + msg.value < _depositSize) _depositSize = depositSizeVote[msg.sender] + msg.value;
depositGovernance -= depositSizeVote[msg.sender];
depositGovernance += _depositSize;
depositSizeVote[msg.sender] = _depositSize;
deposit[msg.sender] += msg.value;
}
function countVotes() atTime(pseudonymEvent, 0) {
uint newDepositSize;
if(numUsers != 0) newDepositSize = depositGovernance / numUsers;
proofOfIndividuality.newRound(newDepositSize);
}
function withdrawDeposit() atTime(issuePOIs, 0) {
if(deposit[msg.sender] == 0) throw;
uint d = deposit[msg.sender];
deposit[msg.sender] = 0;
if(!msg.sender.send(d)) throw;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment