| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- -- # DAO::mint()
- --
- -- First one person will create the DAO
- --
- -- $ drk dao create_dao \
- -- PROPOSER_LIMIT \
- -- QUORUM \
- -- APPROVAL_RATIO_BASE \
- -- APPROVAL_RATIO_QUOTIENT \
- -- GOV_TOKEN_ID > dao.dat
- --
- -- dat.dat contains:
- --
- -- * DAO parameters as listed above
- -- * secret key for the DAO
- -- * bulla blind
- --
- -- We can view the data like so:
- --
- -- $ drk dao view_dao < dao.dat
- --
- -- Now everyone inside the DAO exchanges dao.dat out of band will import
- -- it into their wallets.
- --
- -- $ drk dao import_dao DAO_NAME < dao.dat
- -- Imported DAO ccb8XXX8af6
- --
- -- Where ccb8XXX8af6 is the DAO's bulla.
- --
- -- Next one person will mint it on chain
- --
- -- $ drk dao mint DAO_NAME
- -- Broadcasted DAO ccb8XXX8af6
- --
- -- And then the others will receive confirmation that the DAO they imported
- -- into their wallet has also been accepted on chain.
- -- # Minting and Receiving Coin
- --
- -- Assume that the governance tokens have been created and distributed
- -- appropriately among DAO members. We will skip that part here.
- --
- -- Now the DAO can receive coins into its treasury. These coins simply
- -- have both the coin's spend_hook and user_data fields set correctly
- -- otherwise they are rejected as invalid/malformed.
- -- # DAO::propose()
- --
- -- Create a proposal for the DAO
- --
- -- $ drk dao propose \
- -- DAO_NAME \
- -- RECV_PUBKEY \
- -- AMOUNT \
- -- SERIAL \
- -- SENDCOIN_TOKEN_ID
- --
- -- If we don't have enough tokens to meet the proposer_limit threshold
- -- then this call will simply fail with an error message. Nothing will
- -- be added to the database or sent to the network.
- --
- -- The other participants should automatically receive the proposal
- -- ready to vote on it.
- -- # DAO::vote()
- --
- -- You have received a proposal which is active. You can now vote on it.
- --
- -- $ drk dao proposals DAO_NAME
- -- [0] f6cae63ced53d02b372206a8d3ed5ac03fde18da306a520285fd56e8d031f6cf
- -- [1] 1372622f4a38be6eb1c90fa67864474c6603d9f8d4228106e20e2d0d04f2395e
- -- [2] 88b18cbc38dbd3af8d25237af3903e985f70ea06d1e25966bf98e3f08e23c992
- --
- -- $ drk dao show_proposal 1
- -- Proposal: 1372622f4a38be6eb1c90fa67864474c6603d9f8d4228106e20e2d0d04f2395e
- -- destination: ...
- -- amount: ...
- -- token_id: ...
- -- dao_name: DAO_NAME
- -- dao_bulla: ...
- -- Current yes votes: X
- -- Current no votes: Y
- -- Total votes: X + Y
- -- [================ ] 45.56%
- -- DAO quorum threshold: Z
- -- DAO approval ratio: 60%
- --
- -- $ drk dao vote 1 yes
- -- # DAO::exec()
- --
- -- Once there are enough yes votes to satisfy the quorum and approval ratio,
- -- then any DAO member can execute the payment out of the treasury.
- --
- -- $ drk dao exec 1
- --
- -- FUTURE NOTE: We have to assume that 2 people could try to exec at once.
- -- So if our exec fails, then the tx fee we pay should be returned
- -- to our wallet.
- -- We should design our tables for exec accordingly.
- -- For now I didn't put anything, but we should keep this minor
- -- point in mind and ruminate on it for later.
- PRAGMA foreign_keys = ON;
- CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_daos (
- dao_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
- name BLOB UNIQUE NOT NULL,
- proposer_limit BLOB NOT NULL,
- -- minimum threshold for total number of votes for proposal to pass.
- -- If there's too little activity then it cannot pass.
- quorum BLOB NOT NULL,
- -- Needed ratio of yes/total for proposal to pass.
- -- approval_ratio = approval_ratio_quot / approval_ratio_base
- approval_ratio_base INTEGER NOT NULL,
- approval_ratio_quot INTEGER NOT NULL,
- gov_token_id BLOB NOT NULL,
- secret BLOB NOT NULL,
- bulla_blind BLOB NOT NULL,
- -- these values are NULL until the DAO is minted on chain and received
- leaf_position BLOB,
- tx_hash BLOB,
- call_index INTEGER
- );
- -- The merkle tree containing DAO bullas
- CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_trees (
- daos_tree BLOB NOT NULL,
- proposals_tree BLOB NOT NULL
- );
- CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_proposals (
- proposal_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
- dao_id INTEGER NOT NULL,
- -- Public key of person that would receive the funds
- recv_public BLOB NOT NULL,
- -- Amount of funds that would be sent
- amount BLOB NOT NULL,
- -- Token ID we propose to send
- sendcoin_token_id BLOB NOT NULL,
- bulla_blind BLOB NOT NULL,
- -- these values are NULL until the proposal is minted on chain
- -- and received by the DAO
- leaf_position BLOB,
- money_snapshot_tree BLOB,
- tx_hash BLOB,
- call_index INTEGER,
- -- this is NULL until we have voted on this proposal
- our_vote_id INTEGER UNIQUE,
- FOREIGN KEY(our_vote_id) REFERENCES Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_votes(vote_id) ON DELETE CASCADE ON UPDATE CASCADE,
- FOREIGN KEY(dao_id) REFERENCES Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_daos(dao_id) ON DELETE CASCADE ON UPDATE CASCADE
- );
- CREATE TABLE IF NOT EXISTS Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_votes (
- vote_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
- proposal_id INTEGER NOT NULL,
- vote_option INTEGER NOT NULL,
- yes_vote_blind BLOB NOT NULL,
- all_vote_value BLOB NOT NULL,
- all_vote_blind BLOB NOT NULL,
- -- these values are NULL until the vote is minted on chain
- -- and received by the DAO
- tx_hash BLOB,
- call_index INTEGER,
- -- My code has votes merkle tree and position for votes, but
- -- that might be a mistake...
- FOREIGN KEY(proposal_id) REFERENCES Fd8kfCuqU8BoFFp6GcXv5pC8XXRkBK7gUPQX5XDz7iXj_dao_proposals(proposal_id) ON DELETE CASCADE ON UPDATE CASCADE
- );
|