TeamEmpireCoin / EmpireCoin

EmpireCoin is an experimental cryptocurrency where players vote on outcomes to win coins
http://empirecoin.org
MIT License
2 stars 2 forks source link

Voting payouts should be weighted by coin rounds destroyed rather than coins staked. #5

Open xmadisco opened 8 years ago

xmadisco commented 8 years ago

I don't think they're correct at the moment. Can you describe the issue @joeyfrich ?

joeyfrich commented 8 years ago

For this issue, the idea is that spending old UTXOs should get you more votes and therefore a bigger share of the payout transaction than young UTXOs. This changes the user experience since logging in once in a while and casting votes is now a reasonable strategy since your votes build up over time. Without this change, you really need to vote in every round through an automated voting strategy to get a fair share of the inflation, bloating the blockchain. This change would also resolve the problem of double-voting since anyone who votes the same coins twice in a round will be credited for 0 votes for the second transaction.

In this enhancement, the definition of EmpireCoin votes is changed. Instead of a vote being defined as one coin sent to voting address, a vote is defined as one coin round destroyed to a voting address. So for each coin that you hold, you accumulate one vote every time a round is completed where you did not spend those coins in any transaction.

Here is some pseudocode describing the payout logic that should run at the end of a voting round:

// For each transaction in this voting round, sum up the coin blocks destroyed in creating the transaction
// For each transaction, also sum up the coins out of this transaction which were sent to a voting address
// Calculating the 2 values above gives us the votes per coin-out for this transaction.
for each transaction in the past round as TRANSACTION:
    TRANSACTION.votes = 0

    for each input utxo in TRANSACTION as UTXO_IN:
        utxo_age = (TRANSACTION.confirm_block_id - UTXO_IN.CREATE_TRANSACTION.confirm_block_id)
        TRANSACTION.votes += utxo_age*UTXO_IN.coins

    TRANSACTION.coins_voted = 0

    for each output in this transaction as UTXO_OUT:
        if (UTXO_OUT.nation_id != NULL) // Only count outputs sent to voting addresses
            TRANSACTION.coins_voted += UTXO_OUT.coins

// Next, for each voting UTXO created in this round
//  - Calculate the total votes cast
//  - Calculate the votes cast for each nation

total_votes = 0
votes_by_nation[16] = {0}

for each transaction in the past round as TRANSACTION where TRANSACTION.coins_voted > 0 and TRANSACTION.votes > 0:
    for each output utxo in TRANSACTION as UTXO_OUT:
        if (UTXO_OUT.nation_id != NULL)
            UTXO_OUT.votes = floor(TRANSACTION.votes*(UTXO.coins/TRANSACTION.coins_voted))
            total_votes += UTXO_OUT.votes
            votes_by_nation[UTXO_OUT.nation_id] += UTXO_OUT.votes

// Now calculate the winning nation, then loop through the winning UTXO's
// and create the corresponding payouts as a share of the 750 coin total payout.

winning_nation_id = get_winning_nation(votes_by_nation)

if (winning_nation_id)
    winning_score = votes_by_nation[winning_nation_id]

    for each UTXO_OUT in this round where UTXO_OUT.nation_id = winning_nation_id
        reward = floor(750*(10^8)*UTXO_OUT.votes/winning_score)
        PAYOUT_TRANSACTION.add(UTXO_OUT.address, reward)