These are the notes I took while trying to figure out how Solana's spl-governace program works. My advice is to actually go through these steps-- once you complete them all you will have a much better understanding of everything.

Useful links

Setup

  • Install Rust and Solana CLI tools (the Anchor project has good installation instructions
  • Start a local solana cluster
    • Run solana-node-validator -r (the -r flag resets any previous state)
  • Setup and fund a localhost wallet
    • Instal the Phantom wallet chrome extension and go through setup instructions
    • In the Phantom wallet click on the little gear icon, click "Change Network", and point the wallet to localhost
    • In the Phantom wallet click on the little gear icon and click on "Show Secret Recovery Phrase". Copy it.
    • Run solana-keygen recover 'prompt://?key=0/0' and paste the recovery phrase. This will import the phantom wallet private key into Solana CLI. (Note that the wallet and CLI use different default derivation paths, so the Phantom's 0/0 path must be specified to Solana CLI explicitly.)
    • Run solana airdrop 1000 to fund the wallet. If you run solana balance you should now see 1000 SOL. You should also see 1000 SOL in your Phantom wallet.
  • Deploy the spl-governance program
    • Run git clone https://github.com/solana-labs/solana-program-library.git. This will pull the solana program library codebase which, among other things, contains the governance program.
    • cd into solana-program-library and run cargo build-bpf. This will build all the programs (if you figure out how to build just governance let me know)
    • Run solana program deploy target/deploy/spl_governance.so to deploy the governance program to your local cluster. Note the printed Program Id.
  • Run the Oyster governance GUI
    • Run git clone https://github.com/solana-labs/oyster.git. This will pull the web Ui for the governance program (among other things)
    • cd into oyster and run yarn bootstrap followed by yarn start governance. This will start the web ui.

Creating a Realm

A "realm" is an account that ties everything in spl-governance together. A realm is basically a DAO, so you create one realm account per DAO. So the first step is to create a realm account.

  • Open the webui and add ?programId=GOVERNANCE_PROGRAM_ID_HERE to the query string in the url bar to point the ui to your deployed governance program.
  • Click "Connect" on the top right of the GUI to connect it to your Phantom wallet
  • Click "Register realm"
  • Pick any name you want
  • Realms support "community" and "council" tokens. You can then push any proposal either through community voting or council voting. One way to think about it is that the "council" can act like admins of the DAO that can override or bypass the will of the community. For brewity we're only going to create community tokens here. The process for creating council tokens is the same.
  • Create a community token
    • Run spl-token create-token. Note the token mint address.
    • Paste the token mint address into the "community token mint" input box
    • In the UI click "Register" to register the realm
    • Other options
      • "min community tokens to create governance"-- percent of the token supply you need to create governances. This can be used to prevent small shareholders to spam governances.
      • "advance settings" > "community mint supply factor (max vote weight)"-- fraction of the minted token to use as max vote weight. For example if there are 100 tokens minted and the fraction is .5 (i.e. 50%), it would take 26 tokens for the vote to pass assuming 51% majority is required (100 tokens * .5 / 2 + 1). This setting is documented here-- https://docs.rs/spl-governance/1.1.1/spl_governance/state/enums/enum.MintMaxVoteWeightSource.html
  • Relevant resources

Creating a governance

A "governance" is an account for collectively controlling an asset. You create a governance per asset you want the DAO to control. For example if you wanted the DAO to control minting new supply of a particular token, you'd create a governance to manage that mint. If you wanted the DAO to control transfering a token out of a treasury's token account, you'd create another governance for that treasury. You'd have as many governance accounts as you have things you want the DAO to control.

Step 1: prerequisites

  • To create a governance you need to hold a minimum amount of a community governance token (we specified this during realm creation). So a prerequisite to creating a governance is minting some amount of governance token into an account you control.
    • Run spl-token create-account TOKEN_MINT_ADDRESS_HERE to create an account to hold the token. Note the account address. The token mint address is address for the community token mint we've created before.
    • Run spl-token mint TOKEN_MINT_ADDRESS_HERE 100 to mint 100 units of the token into the holding account
    • In the realm UI the "Deposit Governance Tokens" button will become enabled. Before you can create a governance or vote, you need to deposit your governance tokens. (The governance tokens you simply hold in your account can't be used to perform realm operations).
      • Click the "deposit governance tokens" button and confirm the deposit. (You can always withdraw your tokens)
  • Now if you click the three dots in the realm UI "Create New Governance" will be enabled
  • Relevant resources

Step 2: registering a governance

There are four types of governance you can create: program, mint, token account, and account. The first three are useful for governing program version upgrades, mint supply of a token, and transfering token out of an account, respectively. I think the "account" governance is a less specialized governance for executing arbitrary code on accounts in general, but I haven't verified this yet.

Creating a proposal

Step 1: create a proposal draft

Step 2: add instructions to the proposal

Now that we have the draft of a proposal, we can add instructions to it. These are serialized Solana instructions that we can execute if the proposal were to pass.

Step 3: sign off on the proposal

Vote

Execute instructions

Once the proposal passes and the hold period has passed (in our case the hold period is zero), you can execute the proposal. To do that you must execute the instructions manually one by one. Anyone can execute the instructions, but only so long as the proposal has passed.