Creating a DAO Survey Microservice with the DAOkit in Two Lines of Solidity Code

HaAI Labs
5 min readJan 3, 2023

Tl. Dr. To initiate our DAO-microservice contract, we will import the DAOkit contract, inherit from it, and deploy our contract.

import "https://github.com/haailabs/DAOkit/blob/main/contracts/DAOkit.sol";
contract DAOMicroservice is DAOkit{}

These are the only lines of Solidity code we will have to write.

Microservices powered by your DAO

The attention, preferences, and intelligence of your Decentralized Autonomous Organization (DAO) are a valuable asset. For the outside world, members of your DAO can represent domain experts or potential clients. Surveying them can be an extremely useful way to gather valuable insights. However, ensuring the quality and integrity of the responses, using traditional, centralized survey tools is not an easy task. Verifying the credentials of respondents, and ensuring that the survey does not turn into a click farm is where most web2 tools out there fail. Centralized systems also tend to alienate respondents, as they don’t get to see the outcome of their labor. Moreover, to incentivize participation, respondents should be guaranteed transparency and fair compensation.

The DAOkit allows you to easily create microservices powered by you DAO to put this asset to work, and constitute a source of income for your community. To top it off, surveys are managed, in an abstract form, on-chain, so respondents can be guaranteed the maximum levels of transparency and trustlessness, while semantic data (i.e. the meaning of responses) are stored off-chain and are only accessible to respondents and other authorized parties.

Use cases for ranking

In this short tutorial, we will learn how to quickly create a token-gated ranking survey, using the DAOkit. For this, we will use a ranking Human Intelligence Primitive (HIP).

Surveys using ranking questions allows respondents to prioritize their responses, which results in a richer representation of their priorities and concerns, than a simple yay/nay vote on proposals.
For example, one of the most important investment an individual or organization has to make is deciding what to work on next. Responses to a ranking question, from the right community, can help you answer this question. For example, you might ask: “How would you rank the following problems from most to least important?” This type of question can help you identify the key issues that are top of mind for your audience, and allow you to focus your efforts on addressing those issues.
There are many different industries and domains of expertise where ranking questions can be useful. Here are a few examples of ranking questions for some different industries:

  • Healthcare: “How would you rank the following treatments from most to least pressing effective?”
  • Finance: “How would you rank the following financial priorities from most to least important?”
  • Marketing: “How would you rank the following marketing channels in terms of effectiveness for your business?”
  • Technology: “How would you rank the following tech challenges from most to least pressing for your organization?”

Example of a ranking survey

This example is taken from this medical publication on treatment rankings.

Let’s say we are a researcher, and after providing detailed data about a patient’s condition, we want to ask members of a medical DAO, to rank the following nine antihypertensive treatment for primary prevention of cardiovascular disease treatments, based on their efficacy: 1. Diuretic; 2. Conventional; 3. Placebo; 4. ARB; 5. Alpha-blocker; 5. CCB; 6. Diuretic/Beta-blocker; 7. ACE-inhibitor; 8. Beta-blocker.

As a researcher, we care about ensuring the integrity and reproducibility of our results, without fully revealing the highly sensitive data in the survey question, or the precise survey results.

Moreover, we want guarantees that respondents are really medical experts.

How we manage data

The DAOkit smart contract only stores survey questions and responses in an abstract form. For the above survey example, the only information stored on-chain would be that we are dealing with a ranking problem, with nine options, and an eventual deadline to submit answers. Likewise, responses would only be stored in the form of abstract rankings of the four proposed options (for instance, [7,5,9,8,6,1,4,3,2]).

The question asked, as well as the meaning of each of the nine options, and eventual related data are stored off-chain (for instance in your private web server, or a decentralized storage solution such as IPFS or Arweave), and only accessible to vetted respondents and to the researcher who ordered the survey.

How we verify the credentials of respondents

We will initialize our contract by calling the function initialize(address _tokenContract, uint[] calldata _fees ), specifying the address of the Non-Fungible Token distributed to vetted respondents, as well as the fee that users have to pay to initiate a new HIP.

Once our contract is initialized, our user (the researcher, in the above example) can initiate the creation of a ranking HIP, by calling the function function submitHIP( types _HIPType, uint _numOptions, uint _numClasses, uint _duration), with the following arguments submitHIP(1, 9, 1, 36000), in which:

  • _HIPType=1 indicates a ranking primitive;
  • _numOptions=9 that we have nine options;
  • _numClasses=1 as classes are only needed for a classification or sorting problem;
  • _duration=36000 sets the duration of our survey to be 10 hours.

How we collect responses

DAO members who hold the NFT we have specified can submit their responses using the function submitResponse(address _proposer, uint _id, uint[] calldata _response). For the particular ranking survey at hand, the _response array would be an arrangement of the 9 digits {0,…,8}, but this inpur can be presented more creatively on the front-end of your application.

How we retrieve HIPs and responses

For indexing purposes, the contract uses four mapping.

  • mapping(address => HIP[]) public HIPs maps proposers with an array of their proposed HIPs.
  • mapping(address => mapping(uint => Response[])) internal responses maps proposers and HIP indices with the responses they received.
  • mapping(address => ResponseRef[]) public responseRefs maps respondents with the HIPs they responded to.
  • mapping(address => mapping(address => mapping (uint =>bool))) public responded maps possible respondents’ addresses and HIPs with a boolean indicating whether they have responded.

How we manage payments

To encourage participation in under-participated HIPs, the fee paid by the proposer is fixed and divided over all respondents by the HIP’s deadline. Respondents can consult their total payment balance (i.e. the remuneration they have received from all HIPs they responded to), using the getBalance() function, and withdraw it using the requestPayment() function.

--

--