Messages
Proposal Submission
Proposals can be submitted by any account via a MsgSubmitProposal
transaction.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/gov/v1beta1/tx.proto#L24-L39
The Content of a MsgSubmitProposal message must have an appropriate router
set in the governance module.
State modifications:
- Generate new 
proposalID - Create new 
Proposal - Initialise 
Proposalsattributes - Decrease balance of sender by 
InitialDeposit - If 
MinDepositis reached:- Push 
proposalIDinProposalProcessingQueue 
 - Push 
 - Transfer 
InitialDepositfrom theProposerto the governanceModuleAccount 
A MsgSubmitProposal transaction can be handled according to the following
pseudocode.
// PSEUDOCODE //
// Check if MsgSubmitProposal is valid. If it is, create proposal //
upon receiving txGovSubmitProposal from sender do
  if !correctlyFormatted(txGovSubmitProposal)
    // check if proposal is correctly formatted. Includes fee payment.
    throw
  initialDeposit = txGovSubmitProposal.InitialDeposit
  if (initialDeposit.Atoms <= 0) OR (sender.AtomBalance < initialDeposit.Atoms)
    // InitialDeposit is negative or null OR sender has insufficient funds
    throw
  if (txGovSubmitProposal.Type != ProposalTypePlainText) OR (txGovSubmitProposal.Type != ProposalTypeSoftwareUpgrade)
  sender.AtomBalance -= initialDeposit.Atoms
  depositParam = load(GlobalParams, 'DepositParam')
  proposalID = generate new proposalID
  proposal = NewProposal()
  proposal.Title = txGovSubmitProposal.Title
  proposal.Description = txGovSubmitProposal.Description
  proposal.Type = txGovSubmitProposal.Type
  proposal.TotalDeposit = initialDeposit
  proposal.SubmitTime = <CurrentTime>
  proposal.DepositEndTime = <CurrentTime>.Add(depositParam.MaxDepositPeriod)
  proposal.Deposits.append({initialDeposit, sender})
  proposal.Submitter = sender
  proposal.YesVotes = 0
  proposal.NoVotes = 0
  proposal.NoWithVetoVotes = 0
  proposal.AbstainVotes = 0
  proposal.CurrentStatus = ProposalStatusOpen
  store(Proposals, <proposalID|'proposal'>, proposal) // Store proposal in Proposals mapping
  return proposalID
Deposit
Once a proposal is submitted, if
Proposal.TotalDeposit < ActiveParam.MinDeposit, Atom holders can send
MsgDeposit transactions to increase the proposal's deposit.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/gov/v1beta1/tx.proto#L61-L72
State modifications:
- Decrease balance of sender by 
deposit - Add 
depositof sender inproposal.Deposits - Increase 
proposal.TotalDepositby sender'sdeposit - If 
MinDepositis reached:- Push 
proposalIDinProposalProcessingQueueEnd 
 - Push 
 - Transfer 
Depositfrom theproposerto the governanceModuleAccount 
A MsgDeposit transaction has to go through a number of checks to be valid.
These checks are outlined in the following pseudocode.
// PSEUDOCODE //
// Check if MsgDeposit is valid. If it is, increase deposit and check if MinDeposit is reached
upon receiving txGovDeposit from sender do
  // check if proposal is correctly formatted. Includes fee payment.
  if !correctlyFormatted(txGovDeposit)
    throw
  proposal = load(Proposals, <txGovDeposit.ProposalID|'proposal'>) // proposal is a const key, proposalID is variable
  if (proposal == nil)
    // There is no proposal for this proposalID
    throw
  if (txGovDeposit.Deposit.Atoms <= 0) OR (sender.AtomBalance < txGovDeposit.Deposit.Atoms) OR (proposal.CurrentStatus != ProposalStatusOpen)
    // deposit is negative or null
    // OR sender has insufficient funds
    // OR proposal is not open for deposit anymore
    throw
  depositParam = load(GlobalParams, 'DepositParam')
  if (CurrentBlock >= proposal.SubmitBlock + depositParam.MaxDepositPeriod)
    proposal.CurrentStatus = ProposalStatusClosed
  else
    // sender can deposit
    sender.AtomBalance -= txGovDeposit.Deposit.Atoms
    proposal.Deposits.append({txGovVote.Deposit, sender})
    proposal.TotalDeposit.Plus(txGovDeposit.Deposit)
    if (proposal.TotalDeposit >= depositParam.MinDeposit)
      // MinDeposit is reached, vote opens
      proposal.VotingStartBlock = CurrentBlock
      proposal.CurrentStatus = ProposalStatusActive
      ProposalProcessingQueue.push(txGovDeposit.ProposalID)
  store(Proposals, <txGovVote.ProposalID|'proposal'>, proposal)
Vote
Once ActiveParam.MinDeposit is reached, voting period starts. From there,
bonded Atom holders are able to send MsgVote transactions to cast their
vote on the proposal.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/gov/v1beta1/tx.proto#L46-L56
State modifications:
- Record 
Voteof sender 
Note: Gas cost for this message has to take into account the future tallying of the vote in EndBlocker
Next is a pseudocode outline of the way MsgVote transactions are
handled:
  // PSEUDOCODE //
  // Check if MsgVote is valid. If it is, count vote//
  upon receiving txGovVote from sender do
    // check if proposal is correctly formatted. Includes fee payment.
    if !correctlyFormatted(txGovDeposit)
      throw
    proposal = load(Proposals, <txGovDeposit.ProposalID|'proposal'>)
    if (proposal == nil)
      // There is no proposal for this proposalID
      throw
    if  (proposal.CurrentStatus == ProposalStatusActive)
        // Sender can vote if
        // Proposal is active
        // Sender has some bonds
        store(Governance, <txGovVote.ProposalID|'addresses'|sender>, txGovVote.Vote)   // Voters can vote multiple times. Re-voting overrides previous vote. This is ok because tallying is done once at the end.