--- ###### tags: `V3 Docs` --- # Subgraphs - [The Graph has really great documentation!](https://thegraph.com/docs/en/) - [Check out the DAOhaus Goerli Subgraph](https://thegraph.com/hosted-service/subgraph/hausdao/daohaus-v3-goerli), which also includes a powerful playground feature that will help you understand how data is queried. Contracts on Ethereum have events that can be written into your contracts. When there is a state change, these events fire off in the contracts. The Graph provides a framework for listening to those events, allowing you to map, rewrite, and transform that data into really sensible entities and databases representing the current state of your contracts. Our Subgraph references the Moloch v3 contracts. We have deployed a factory contract for deploying DAO contracts on Moloch v3 and our Subgraph listens to this factory to create templates for each DAO that is launched. We then listen to each DAO contract for the events that they fire off. The core Moloch v3 contract contains all of the governance and proposal variables. There is also a Gnosis Safe contract comprising the DAO treasury, which we do not listen to (although there may be use cases in the future). A Loot and Share ERC-20 contract is also generated and registered in our Subgraph so we can track every time a token is transferred, created, minted, or burned to display holders and token balances. Our Subgraph is composed of the following entities (database tables): - DAO - Proposal - Vote - Record - Member - RageQuit - Shaman - EventTransaction - TokenLookup ##### DAO Displays all the data we track across the DAO contracts. Each DAO has one DAO record. ``` unique identifier and primary key of the entity id: ID! timestamp of the block when the dao was summoned createdAt: String! address that created the dao createdBy: Bytes! transaction hash of the dao contract deployment txHash: Bytes! contract address of the loot erc20 token lootAddress: Bytes! contract address of the shares erc20 token sharesAddress: Bytes! contract address of the gnosis safe treasury safeAddress: Bytes! indicates if loot transferability is on/off lootPaused: Boolean! indicates if shares transferability is on/off sharesPaused: Boolean! length in seconds of the current grace period gracePeriod: BigInt! length in seconds of the current voting period votingPeriod: BigInt! length in seconds of the current voting period and grace period votingPlusGraceDuration: BigInt! amount of network token required as tribute to submit a proposal proposalOffering: BigInt! minimum % of shares that must vote yes for it to pass quorumPercent: BigInt! amount of shares needed to automatically sponsor a proposal sponsorThreshold: BigInt! auto-fails a proposal if more than (1- minRetentionPercent) * total shares exit before processing minRetentionPercent: BigInt! name of the erc20 shares token shareTokenName: String symbol of the erc20 shares token shareTokenSymbol: String name of the erc20 loot token lootTokenName: String symbol of the erc20 loot token lootTokenSymbol: String total circulating shares tokens totalShares: BigInt! total circulating loot tokens totalLoot: BigInt! ID of the last sponsored proposal latestSponsoredProposalId: BigInt! count of proposal submitted proposalCount: BigInt! count of share or loot holding members activeMemberCount: BigInt! name of the DAO name: String was Dao summoned by an existing safe or did it create a new safe. existingSafe: Boolean! proposals scoped to this dao proposals: [Proposal!] members scoped to this dao members: [Member!]! rage quits scoped to this dao rageQuits: [RageQuit!] shaman scoped to this dao shaman: [Shaman!] records: [Record!] eventTransactions: EventTransactio ``` ##### Proposal Every time a proposal is made, we create a proposal entity that is related to the DAO. Most of the logic in our apps are related to proposal state changes: cancellation, sponsorship, voting periods, grace periods, pass, fail, and process. Each of these events updates the state of the proposal. ``` unique identifier and primary key of the entity id: ID! block timestamp when the proposal was submitted createdAt: String! address that submitted the proposal createdBy: Bytes! related DAO entity dao: Dao! id of the proposal proposalId: BigInt! id of the previous proposal, set at sponsorship prevProposalId: BigInt! transaction hash of the proposal txHash: Bytes! hash of raw transaction data that will be executed if the proposal passes proposalDataHash: Bytes! raw transaction data that will be executed if the proposal passes proposalData: Bytes! duration of the voting period for this proposal in seconds votingPeriod: BigInt! unix timestamp of when the voting period starts votingStarts: BigInt! unix timestamp of when the voting period ends votingEnds: BigInt! duration in seconds of the grace period for this proposal in seconds gracePeriod: BigInt! duration in seconds of the grace and voting periods for this proposal in seconds votingPlusGraceDuration: BigInt! unix timestamp of when the grace period ends graceEnds: BigInt! unix timestamp after which proposal should be considered invalid and skipped expiration: BigInt! estimated gas needed to execute the proposal actions actionGasEstimate: BigInt! string with human readable description of the proposal details: String! indicates if the proposal was automatically sponsored selfSponsor: Boolean! indicates if the proposal is sponsored sponsored: Boolean! address that sponsored the proposal sponsor: Bytes transaction hash of the proposal sponsor sponsorTxHash: Bytes unix timestamp of when the proposal was sponsored sponsorTxAt: BigInt indicates if the proposal is cancelled cancelled: Boolean! transaction hash of the cancelled proposal cancelledTxHash: Bytes unix timestamp of when the proposal was cancelled cancelledTxAt: BigInt the address that cancelled the proposal cancelledBy: Bytes indicates if the proposal is processed processed: Boolean! transaction hash of processing the proposal processTxHash: Bytes the unix timestamp of when the proposal was processed processTxAt: BigInt address that processed the proposal processedBy: Bytes indicates if the proposal is processed actionFailed: Boolean! indicates if the proposal passed passed: Boolean! amount of native token that was provided as tribute when the proposal was submitted proposalOffering: BigInt! number of current yes votes yesVotes: BigInt! number of current no votes noVotes: BigInt! amount of current shares that have voted yes yesBalance: BigInt! amount of current shares that have voted no noBalance: BigInt! is currently paasing quorum and has more yes votes than no votes currentlyPassing: Boolean! highest share+loot count during any individual yes vote maxTotalSharesAndLootAtYesVote: BigInt! The following tribute fields will only have values if the proposal was submitted through the trbute minion contract. token address in tribute proposals. tributeToken: Bytes amount of tribute token offered tributeOffered: BigInt symbol of the tribute token tributeTokenSymbol: String decimal places of the tribute token tributeTokenDecimals: BigInt applicant submitting the tribute proposal tributeEscrowRecipient: Bytes proposal type derived from the details field proposalType: String! proposal title derived from the details field title: String proposal description derived from the details field description: String proposal content URI derived from the details field contentURI: String proposal Content URI type (ipfs hash, url) derived from the details field contentURIType: String votes scoped to this proposal votes: [Vote!] ``` ##### Vote Every time a member votes it the process gets attached to the proposal entity. ``` unique identifier and primary key of the entity id: ID! transaction hash of the vote txHash: Bytes! block timestamp when the vote was submitted createdAt: String! contract address of the DAO related to this vote daoAddress: Bytes! indicates yes vote/no vote approved: Boolean! shares balance of the voting member at the time of the vote balance: BigInt! related proposal proposal: Proposal! related/voting member member: Member! ``` ##### Record This is what we call the DAO database. We use Poster contracts to track. We have begun defining various schemas for other tables that DAOs might want to manage. This represents off-chain data, so not representing function calls to the contract. Instead we make calls to the Poster contract to generate json that is standardized and mapped into our subgraph to maintain that data. This allows us to validate to ensure alignment our schema, ensure that the individual sending a transaction is a member of the DAO, and verify that the call is made through a DAO vote (ratification). This can be used for any type of table! Pretty exciting stuff. ``` id: ID! createdAt: String! createdBy: Bytes! dao: Dao! tag: Bytes! table: String! contentType: String! content: String! ``` ##### Member Every time an address receives loots or shares in the DAO a member entity is created. A member is composed on an address and the amount of shares they hold, as well as events like burning and transferring shares. ``` unique identifier and primary key of the entity id: ID! block timestamp when the member entity was created (when the address first recieved shares or loot) createdAt: String! transaction where the member was created txHash: Bytes! related dao dao: Dao! address of the member memberAddress: Bytes! current shares held by the member shares: BigInt! current loot held by the member loot: BigInt! address the member is delegating to delegatingTo: Bytes! subgraph id of member the address is delegating to delegatingToMember: Member the transaction hash when the delegate was last updated lastDelegateUpdateTxHash: Bytes total amount of shares this address votes with (thier own plus delegated shares) delegateShares: BigInt! members this member is delegating too delegateOf: [Member!] related votes delegateOfCount: BigInt! votes: [Vote!] ``` ##### RageQuit Upon executing the RageQuit event, this data represents the updates loot and shares. ``` unique identifier and primary key of the entity id: ID! block timestamp when the member rage quit createdAt: String! the transaction where the RageQuit occurred txHash: Bytes! related DAO dao: Dao! related member member: Member! address the tokens where rage quit to to: Bytes! number of shares rage quit shares: BigInt! number of loot rage quit loot: BigInt! list of treasury token addresses requested in the rage quit tokens: [Bytes!]! ``` ##### Shaman Every time a Shaman is added to the DAO, the event is recorded here. A DAO can have many Shamans. This simple entity conveys the Shaman's contract address, its related DAO, and permission level. ``` unique identifier and primary key of the entity id: ID! block timestamp when the shaman was added createdAt: String! related DAO dao: Dao! address of the shaman shamanAddress: Bytes! permission level of the shaman (0-7) permissions: BigInt! ``` ##### EventTransaction This entity conveys ways to query the subgraph after transactions are submitted to see when they are completed or failed. All interactions with DAO contracts are recorded here. ``` unique identifier and primary key of the entity id: ID! block timestamp of the transaction createdAt: String! related DAO dao: Dao daoAddress: Bytes ``` ##### TokenLookup This entity connects the token, share, and loot addresses to the DAO. It allows us to record the state changes of these variables. ``` unique identifier and primary key of the entity (share or loot token address) id: ID! related DAO dao: Bytes! ```