Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control Protocol Parameters with on-chain governance #182

Closed
CJentzsch opened this issue Dec 6, 2016 · 11 comments
Closed

Control Protocol Parameters with on-chain governance #182

CJentzsch opened this issue Dec 6, 2016 · 11 comments
Labels

Comments

@CJentzsch
Copy link

CJentzsch commented Dec 6, 2016

  EIP: draft
  Title: Control Protocol Parameters by defined governance
  Author: Christoph Jentzsch 
  Status: Draft
  Type: Informal
  Layer: Consensus (hard-fork)
  Created: 2016-12-06

==Abstract==

This is a proposal to move most constants of the protocol (https://github.com/ethereum/common/blob/master/params.json) in a contract, to be controlled by a choosen goverment model.

==Motivation==

  1. This is in line with Proposed initial abstraction changes for Metropolis #86, which intends to move protocol logic and data needed to construct a new block into the EVM.

  2. Most constants are gas costs for several opcodes. Fine tuning will be an ongoing process and currently requires a hard fork each time. This EIP would remove the necessity for a hard fork for future optimizations.

==Specification==

The following contract is used to specify the parameters:

contract Governance{
    function vote(bytes32 _voteID, bool _support) payable;
    function result(bytes32 _voteID) returns (bool);
}


contract ProtocolParameters {
    mapping(uint => uint) public parameters;
    Governance public governanceAddress = Governance(0x00); // to be replaced by correct address
    
    function setParameter(uint _key, uint _value){
        bytes32 hash = sha256(this, _key, _value);
        if (governanceAddress.result(hash))
            parameters[_key] = _value;
    }
}

The parameters in https://github.com/ethereum/common/blob/master/params.json, except of genesisGasLimit and genesisDifficulty, are indexed with 0..47 in the order of appearance.
This index is used as the key in the parameters map.
Clients use this contract to read the current value in order to correctly process blocks.

Governance:

Variant A - MinerGovernance:

In this case the miners vote for those parameters, the following contract (or a derivative of it) is used:

contract MinerVote is Governance{
    struct Vote {
        uint approve;
        uint oppose;
        uint startBlock;
    }
    
    uint constant minQuorum = 10000;
    
    mapping (bytes32 => Vote) public votes;
    
    function vote(bytes32 _voteID, bool _support) payable {
        if (msg.sender != block.coinbase) throw;
        Vote vote = votes[_voteID];
        if (vote.startBlock == 0) vote.startBlock = block.number;
        if (_support)
            vote.approve++;
        else
            vote.oppose++;
    }
    
    function result(bytes32 _voteID) returns (bool) {
        Vote vote = votes[_voteID];
        if (vote.approve > vote.oppose 
            && (vote.approve + vote.oppose) * 4 > (block.number - vote.startBlock) // at least 25% of hash power has voted
            && vote.approve + vote.oppose > minQuorum)
        // alternatives:
        //  if (vote.approve > vote.oppose && vote.approve > minQuorum)
        //  more advanced voting rules could be used (prevention of ambush attacks, ...)
            return true;
    }
}

Variant B - Stake governance

In this case voting is weighted by the amount of Ether given as a deposit, similar in spirit as Proof Of Stake.

the following contract (or a derivative of it) is used:

contract StakeVote is Governance{
    struct Vote {
        uint approve;
        uint oppose;
        mapping (address => uint) deposits;
        mapping (address => bool) support;
    }
    
    uint constant minQuorum = 10000000 ether;
    
    mapping (bytes32 => Vote) public votes;
    
    function vote(bytes32 _voteID, bool _support) payable {
        Vote vote = votes[_voteID];
        if (vote.deposits[msg.sender] > 0 && vote.support[msg.sender] != _support) throw; // user has to withdraw first
        if (_support)
            vote.approve += msg.value;
        else
            vote.oppose += msg.value;
            
        vote.deposits[msg.sender] += msg.value;
        vote.support[msg.sender] = _support;
    }
    
    function withdraw(bytes32 _voteID){
        Vote vote = votes[_voteID];
        if (vote.support[msg.sender])
            vote.approve -= vote.deposits[msg.sender];
        else
            vote.oppose -= vote.deposits[msg.sender];
        
        uint deposit = vote.deposits[msg.sender];
        vote.deposits[msg.sender] = 0;
        if (!msg.sender.send(deposit))
            throw;
    }
    
    function result(bytes32 _voteID) returns (bool) {
        Vote vote = votes[_voteID];
        if (vote.approve > vote.oppose && vote.approve + vote.oppose > minQuorum)
        // alternative:
        //  if (vote.approve > vote.oppose && vote.approve > minQuorum)
        //  more advanced voting rules could be used (prevention of ambush attacks, ...)
            return true;
    }
}

Other Variants:

One could use government models which separate voting from making proposals. For example having an expert consortium which are the ones proposing changes and Miners and/or Ether owners voting on them.
Additionally one could differentiate the governance model depending on the parameter type (gas price parameter for miners, everything else for Ether owner).

==Rationale==

This allows protocol changes, especially optimizing gas prices for opcodes, without the need for a hard fork.

==Implementation==

Not implemented.

==Remarks==

This should be seen as a starting point for a discussion, the contracts are not tested or reviewed but should show the general idea. The governance model in the contracts also need improvement (e.g.: only relative change of parameters (to avoid attacks and big jumps in the numbers), what is the right min quorum, ...)

@CJentzsch
Copy link
Author

CJentzsch commented Dec 6, 2016

I personally would prefer the miner vote, since it is in there self interest to optimize the opcode prices.

@tjade273
Copy link

tjade273 commented Dec 7, 2016

@CJentzsch Maybe not likely, but miners could potentially be incentivised to optimize based on their own abilities, not necessarily those of the network as a whole. i.e. buy a lot of storage, then decrease the SSTORE price, and spam the network, potentially taking other miners offline.

@janx
Copy link
Member

janx commented Dec 7, 2016

Thanks @CJentzsch for starting this discussion.

I'm in favor of stake vote. My concerns on variation B (vote by transfer) are:

  1. Transfer is a 'heavy' operation, like payment in online shopping. The willingness to transfer for vote is weak.
  2. In Casper era, locking stakes in governance contract means you would give up interests, which will further reduce the desire to vote.
  3. If we want to collect as many votes as possible, the stakes accumulated in such a global governance contract could be unbounded, not a good practice consider security.

I like the scheme used by Carbonvote, it (with delegated vote) may address the concerns above. One problem is it's hard to be implemented purely in smart contract. Maybe governance is worth to be done in underlying layer.

@CJentzsch
Copy link
Author

@tjade273 sure. But that's also a current danger. Miners could try to find a weakness in the current opcode pricing, optimize there hardware for it and spam the network. Or even easier, just look for the most used contract (may be a "buyToken" function in a contract during an ICO) during a certain time, optimize the client to precompile this function to bypass the EVM, and thereby being orders of magnitudes faster to process those transactions.
The key will be to find the right governance model. For example a high relative hash power which needs to vote in order to activate a parameter change.

@CJentzsch
Copy link
Author

@janx As you said, Carbonvote is nice, but can not be used in a smart contract, the tallying is done off-chain. But in the stake vote contract, you do not really freeze your ether, since you can withdraw them at any time, although you will undo your vote when doing so.

@vbuterin
Copy link
Contributor

vbuterin commented Dec 8, 2016

In Casper era, locking stakes in governance contract means you would give up interests, which will further reduce the desire to vote.

Casper deposits can be queried by other contracts, so we can definitely create a scheme where stake votes can be done by Casper validators; that is no problem.

I am starting to like the idea of putting gas policies into a contract for easier editing, although it is important to note that we do want to balance adaptability with the goal of giving contract developers assurances that contracts they write will not suddenly become unusable due to gas cost increases. That said, the concept of putting gas policies in-protocol does not in principle imply any specific governance mechanism; we could even still rely on hard forks to change the contents of the contract, it would just be a much safer way of executing the hard fork as you only need to make one state change instead of a few parameter changes.

@3esmit
Copy link
Contributor

3esmit commented Mar 12, 2017

I think this is really important feature to have, especially with the need of autoupdate in clients, where Mist and Parity already have their own autoupdate feature.
For me is not clear if is the most secure way of doing it and if there is a better way of doing it, but if well implemented would be an evolution to autoupdate.
I like carbonvote of stakes in the validator for PoS chains, and for PoW I like carbonvote by account holdings in some account.
Delegative voting is important, so instead of voting, people cold just drop his trust in the hands of other, until reaching someone who actually votes in something (if anything).

@CJentzsch the voting contract should be watched by default in wallets, and if user move his funds he would need to redelegate/revote. The delegation/vote could be attached using a wrapper ETH contract and/or using incoming features of ethereum, such as zsnarks or raiden, so the redelegation would be needed only for changing your direction.
This might be interesting for all contracts using a quorum, and even become an ethereum defined standard, such as the current in progress ERC20.
A solution for the current consesus system we can try some transfer function in wrapped eth with vote delegation, look this implementation of liquid delegative democracy:
https://github.com/ethereans/direct-democracy/blob/master/contracts/LiquidDelegativeDemocracy.sol
example in a wrapped eth token:
https://github.com/ethereans/direct-democracy/blob/master/contracts/DelegativeVoteToken.sol
https://github.com/ethereans/abstract-token/blob/master/contracts/WrappedEthToken.sol

@3esmit
Copy link
Contributor

3esmit commented Aug 17, 2017

I'm working in a democracy model for this project https://github.com/HiveCommons/Hive-Democracy/ that might be useful for this case.

@MicahZoltu
Copy link
Contributor

While a cool concept, I'm generally against any democratic solution to chain governance. Democracy results in the masses, people without in-depth knowledge/understanding of the issues being voted on and their repercussions, deciding the fate of the system. We can see this in democracies all over the world and in many forms, where people vote with their gut despite the fact that experts repeatedly tell them that their gut is wrong.

While one would assume that miners would at least vote in their own self interest, and due to mining pools the votes are controlled by experts, they don't have a large incentive to vote for the long-term stability of the platform. Also, with PoS coming miner voting doesn't really make sense. Stake voting sounds good on the surface but again, it preferences short term thinking rather than long term thinking. Unless stakers are forced to lock their voting ETH up for very long periods of time, the stakers are incentivized to optimize for short term increases in ETH profits over long-term stability.

At the moment, the system does not have any group who has the proper incentives for long-term stability from an economic standpoint. The closest we have is the Ethereum Foundation, but even they don't have economic incentives (they have just socially signaled that they care about the long-term success of the project).

@github-actions
Copy link

github-actions bot commented Jan 3, 2022

There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added the stale label Jan 3, 2022
@github-actions
Copy link

This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants