From 7b11fd54f9dba77416b983cd652a93181e30a3db Mon Sep 17 00:00:00 2001 From: narodnik Date: Sat, 14 May 2022 10:01:42 +0200 Subject: [PATCH] daod: add gov token --- bin/daod/demo/main.py | 106 ++++++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 30 deletions(-) diff --git a/bin/daod/demo/main.py b/bin/daod/demo/main.py index d117e233f..466524dce 100644 --- a/bin/daod/demo/main.py +++ b/bin/daod/demo/main.py @@ -21,9 +21,6 @@ class MoneyState: for coin, enc_note in zip(update.coins, update.enc_notes): self.all_coins.add(coin) - # Try to decrypt notes here - print(f"Received {enc_note.value} DRK") - def money_state_transition(state, tx): for input in tx.clear_inputs: pk = input.signature_public @@ -162,12 +159,17 @@ def main(argv): ec = crypto.pallas_curve() money_state = MoneyState() + gov_state = MoneyState() dao_state = DaoState() # Money parameters money_initial_supply = 21000 money_token_id = 110 + # Governance token parameters + gov_initial_supply = 10000 + gov_token_id = 4 + # DAO parameters proposal_auth_secret = ec.random_scalar() proposal_auth_public = ec.multiply(proposal_auth_secret, ec.G) @@ -218,9 +220,71 @@ def main(argv): return -1 money_state.apply(update) + # payment state transition in coin specifies dependency + # the tx exists and ruleset is applied + + assert len(tx.outputs) > 0 + note = tx.outputs[0].enc_note + coin = crypto.ff_hash( + ec.p, + dao_public_key[0], + dao_public_key[1], + note.value, + note.token_id, + note.serial, + note.coin_blind, + spend_hook, + user_data + ) + assert coin == tx.outputs[0].mint_proof.get_revealed().coin + + for coin, enc_note in zip(update.coins, update.enc_notes): + # Try decrypt note here + print(f"Received {enc_note.value} DRK") + ################################################ - # The treasury token is minted - # Mint the initial supply of governance token + # Mint the governance token + # Send it to two hodlers + ################################################ + + # Hodler 1 + gov_secret_1 = ec.random_scalar() + gov_public_1 = ec.multiply(gov_secret_1, ec.G) + # Hodler 2 + gov_secret_2 = ec.random_scalar() + gov_public_2 = ec.multiply(gov_secret_2, ec.G) + + # Only used for this tx. Discarded after + signature_secret = ec.random_scalar() + + builder = money.SendPaymentTxBuilder(ec) + builder.add_clear_input(gov_initial_supply, gov_token_id, + signature_secret) + assert 2 * 5000 == gov_initial_supply + builder.add_output(5000, gov_token_id, gov_public_1, + b"0x0000", b"0x0000") + builder.add_output(5000, gov_token_id, gov_public_1, + b"0x0000", b"0x0000") + tx = builder.build() + + # This state_transition function is the ruleset for anon payments + if (update := money_state_transition(gov_state, tx)) is None: + return -1 + gov_state.apply(update) + + # Decrypt output notes + assert len(tx.outputs) == 2 + gov_user_1_note = tx.outputs[0].enc_note + gov_user_2_note = tx.outputs[1].enc_note + + for coin, enc_note in zip(update.coins, update.enc_notes): + # Try decrypt note here + print(f"Received {enc_note.value} GOV") + + ################################################ + # Propose the vote + # In order to make a valid vote, first the proposer must + # meet a criteria for a minimum number of gov tokens ################################################ # State @@ -243,29 +307,8 @@ def main(argv): votes_yes = 10 votes_no = 5 - # payment state transition in coin specifies dependency - # the tx exists and ruleset is applied - - assert len(tx.outputs) > 0 - note = tx.outputs[0].enc_note - coin = crypto.ff_hash( - ec.p, - dao_public_key[0], - dao_public_key[1], - note.value, - note.token_id, - note.serial, - note.coin_blind, - spend_hook, - user_data - ) - assert coin == tx.outputs[0].mint_proof.get_revealed().coin - all_coins = set([coin]) - ################################################ - # Now the coin is minted, and all supply was sent to the DAO - # In order to make a valid vote, first the proposer must - # meet a criteria for a minimum number of gov tokens + # Execute the vote ################################################ # Used to export user_data from this coin so it can be accessed @@ -273,13 +316,14 @@ def main(argv): user_data_blind = ec.random_base() builder = money.SendPaymentTxBuilder(ec) - builder.add_input(all_coins, dao_shared_secret, note, user_data_blind) + witness = money_state.all_coins + builder.add_input(witness, dao_shared_secret, note, user_data_blind) user_secret = ec.random_scalar() user_public = ec.multiply(user_secret, ec.G) builder.add_output(1000, money_token_id, user_public, - spend_hook=[b"0x0000"], user_data=[]) + spend_hook=b"0x0000", user_data=b"0x0000") # Change builder.add_output(note.value - 1000, money_token_id, dao_public_key, spend_hook, user_data) @@ -318,8 +362,10 @@ def main(argv): # Now enforce DAO rules: # 1. proposals must be submitted by minimum amount # - need protection so can't collude? must be a single signer?? - # 2. number of votes > quorum + # - stellar: doesn't have to be robust for this MVP + # 2. number of votes >= quorum # - just positive votes or all votes? + # - stellar: no that's all votes # 3. outcome > approval_ratio # 3. structure of outputs # output 0: value and address