Skip to content
Snippets Groups Projects
Commit d3017a19 authored by Robert Martin-Legene's avatar Robert Martin-Legene
Browse files

New Sealers contract.

parent cab694f9
No related branches found
No related tags found
No related merge requests found
#!/bin/bash
# Robert Martin-Legene <robert@nic.ar>
# Proposes to promote a new sealer or to demote an existing sealer.
# Also sends this vote to the new Sealers contract, so we have a place
# a contract can look up which addresses are sealers.
if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi
source ${BFAHOME}/bin/libbfa.sh || exit 1
operation="false"
if [ $( basename $0 ) == "sealeradd.sh" ]
then
operation="true"
fi
victim="$1"
(
echo "clique.propose(\"0x${victim#0x}\", ${operation});"
contractCall Sealers admin_promote \"0x${victim#0x}\" ${operation}
) | geth_attach
sealeradd.sh
\ No newline at end of file
pragma solidity ^0.4.22;
contract Sealers {
struct Proposal {
address victim; // Whom are we voting about.
uint votestart; // In which block did this vote begin?
bool promotion; // true=promotion, false=demotion
address[] voters; // List of voters.
}
Proposal[] public adminproposals;
address[] public sealers;
event vote( address voter, address victim, bool promotionOrDemotion );
event adminChange( address admin, bool promotionOrDemotion );
constructor() public {
sealers[0] = msg.sender;
}
function isSealer( address subj ) public view returns (bool) {
for (uint i=sealers.length; i>0; i--)
{
if (subj == sealers[i-1])
return true;
}
return false;
}
modifier onlySealersTX {
require( isSealer( tx.origin ), "tx.origin is not a known sealer and can not call this function." );
_;
}
modifier onlySealers {
require( isSealer( msg.sender ), "msg.sender is not a known sealer and can not call this function." );
_;
}
function sealerLength() public view returns (uint) {
return sealers.length;
}
function sealerPosition( uint idx ) public view returns (address) {
require( idx <= sealers.length, "There are not that many sealers registered in the list." );
return sealers[idx];
}
function _trimProposals() private {
uint i = adminproposals.length;
while ( i-- > 0 )
{
if ( adminproposals[i].votestart < block.number+30000 )
{
while ( i < adminproposals.length )
{
adminproposals[i] = adminproposals[i+1];
i--;
}
adminproposals.length--;
}
}
}
function admin_promote( address victim, bool promotion ) public onlySealersTX {
// Janitor
_trimProposals();
bool isS = isSealer(victim);
// Is already Sealer and want to promote him?
if ( isS && promotion )
revert("You can't promote someone who is already a sealer.");
// Is not Sealer and want to demote him?
if ( !isS && !promotion )
revert("You can't demote someone who is not a sealer.");
// First see if we can find the index of an already running proposal for this victim,promotion tupple.
uint proppos = adminproposals.length;
while ( proppos>0 && adminproposals[proppos-1].victim != victim && adminproposals[proppos-1].promotion != promotion)
proppos--;
// If we found no matching proposals, we will add it, so we can now vote on it.
if (proppos == 0)
{
address[] memory sillycompiler;
proppos = adminproposals.push( Proposal(victim, block.number, promotion, sillycompiler ) );
}
// substract one, to make proppos actually reflect the position in the index.
proppos--;
// Make things a bit more easy to read by using a shorter variable name
Proposal memory prop = adminproposals[proppos];
// Now look through the proposal and see if this sender already voted.
uint voterpos = prop.voters.length;
while ( voterpos>0 && prop.voters[voterpos-1] != msg.sender )
voterpos--;
// Return if sender already voted
if ( voterpos > 0 )
revert("You can not vote twice.");
// Send notification of the valid vote
emit vote( msg.sender, victim, promotion );
// Do we have enough votes to perform the operation?
if ( prop.voters.length < sealers.length/2+1 )
return;
//
// Is it a promotion or a demotion?
if ( prop.promotion )
{
sealers.push( victim );
}
else
{
uint i = sealers.length;
// Delete all occurences of the victim from the sealer list (should be just a single occurence)
while ( i-- > 0 ) {
if (sealers[i] == victim )
{
for (uint j=i; j<sealers.length-1; j--)
sealers[j] = sealers[j+1];
sealers.length--;
}
}
}
// Remove the proposal, as the voting is complete.
for (i=proppos; i<adminproposals.length-1; i--)
adminproposals[i] = adminproposals[i+1];
adminproposals.length--;
// Send notification
emit adminChange( victim, promotion );
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment