DAO Database

DAO Database

The Record Entity in our subgraphs are what we call the DAO database. These allow DAOs to create content that is indexed in the subgraphs and eliminates the need for off-chain database storage.

dao-database

Create Record

How does a DAO create a RECORD?

  1. Makes a proposal to call the post function in the Poster.sol (opens in a new tab) contract for the DAOs chain. If this proposal passes the function will execute.
  2. A DAO member directly calls the post function on the Poster.sol (opens in a new tab) contract

The DAOHaus subgraph indexes these posts into RECORD entities.

Validate Post

How does the subgraph validate the post?

  1. The TAG argument on the post function instructs the subgraph how to validate.
  • daohaus.summoner.daoProfile: Post must come from the DAOhaus factory contract
  • daohaus.shares.daoProfile: Post function for a DAO profile must come from a share holding address
  • daohaus.proposal.database: Post must come from a proposal execution
  • daohaus.shares.database: Post must come from a share holding address
  • daohaus.member.database: Post must come from a share or loot holding address
  1. The CONTENT argument must conform to json schemas

It needs to be able to parse the json and find daoId, table, queryType fields.

Valid json Schemas (opens in a new tab)

Record can be used for any type of table. We have indexed the following types of data:

Using the subgraph in this way has allowed us to replace centralized databases.

Examples

How to create a record (opens in a new tab) from a txLego

You can see an example of this in UPDATE_METADATA_SETTINGS (opens in a new tab) on the DAO settings page in the Admin app.

You can see an example of this in POST_SIGNAL (opens in a new tab) for the DAO signal proposal.

How to query a record

Get the latest record for a 'table'

{
  records(
    where: { dao: "0x0", table: "daoProfile" }
    first: 1
    orderBy: createdAt
    orderDirection: desc
  ) {
    id
    content
    table
  }
}

Get a list of records for a 'table'

{
  records(where: { dao: "0x0", table: "signalTcrChoice" }, first: 500) {
    id
    content
    table
  }
}

Record Entities

"unique identifier and primary key of the entity"
id: ID!
"block timestamp when the member entity was created"
createdAt: String!
"Address of the dao member creating the record"
createdBy: Bytes!
"Address of the dao the record is related to"
dao: Dao!
"Tag argument in the newPost function call"
tag: Bytes!
"record category identifier to ease querying"
table: String!
"type of content in the content field. currently this is always json"
contentType: String!
"content of the record"
content: String!
"Indicates if the entities  should be queried for latest or as a list"
queryType: String!