Tutorial: Off-chain voting on Aragon DAOs powered by Witnet

Mario Cao
The Witnet Oracle Blog
9 min readAug 30, 2021

This tutorial is a follow-up to this article about the integration between Witnet and Aragon Govern by using Discord as an off-chain voting platform. We will present how the integration works and how to spin up your own Discord bot for an Aragon Govern DAO.

Behind the curtains…

In May 2021, the Witnet decentralized oracle project released an integration with Aragon Govern, a framework for DAOs that enables off-chain voting with on-chain execution, and Discord, the leading voice, video and chat app for online communities.

Integration architecture

The integration is based on 2 main components:

  1. A Conversational Bot, in charge of reacting to Discord messages (!setup and !proposal) and managing the proposals lifecycle powered by Witnet and Aragon Govern contracts.
  2. Several Reaction Monitors, servers in charge of monitoring proposal votings so that results can be queried by the Witnet network.

In addition, there are 2 required external components:

  1. Ethereum node, which will receive the Aragon Govern transactions.
  2. Witnet node, which will be responsible for querying the proposal voting results.

Other components included in the architecture diagram are:

  • Discord server, used to read and write in Discord channels.
  • Subgraph Server, used to query Aragon Govern data required by the Conversational Bot.

The following image depicts the default execution scenario featuring no exceptional or error conditions, aka the “happy path”.

Default execution scenario

Despite being the execution complexity hidden from the users, it can be used to better understand the solution and all its “moving pieces”:

  1. The Discord Bot obtains all required information from the Aragon Govern contracts by querying the subgraph server.
  2. The Discord Bot reads a new Govern proposals from the users (e.g. “transfer funds to an address”).
  3. Once, the proposal voting period is over, the Discord Bot triggers proposal resolution by first creating a Witnet Data Request that will query the voting results.
  4. The Witnet Data Request is broadcasted to the Witnet network and its execution starts.
  5. As part of the execution, secret randomly selected Witnet nodes retrieve proposal voting results by querying all Reaction Monitors.
  6. As part of that query, each Reaction Monitors fetch the reactions for the proposal from the Discord Server.
  7. The data request execution is finalized by aggregating all Reaction Monitors voting results and checking if there was consensus among them.
  8. The Discord Bot detects that the data request has been executed.
  9. If the data request was successful, the Discord Bot will trigger the proposal schedule and, after the dispute/challenge window, the execute in the Govern Aragon smart contract.

Step 0: Requirements

This tutorial has the following requirements:

  • Access to Ethereum: run an Ethereum node (e.g. geth) or have access to a JSON-RPC interface to be able to sign and send Ethereum transactions.
  • Access to Witnet: run a Witnet node or have access to a JSON-RPC interface to send data requests to the Witnet network.

Ethereum node

The second requirement is about having access to an Ethereum node to be able to interact with the Aragon Govern contracts. There are 2 possibilities to access a node:

  1. Spin up your own Ethereum node.
  2. Use a Web3 provider (e.g. nodes-as-a-service).

In both configurations, an unlocked Ethereum account is required to interact with the Aragon contracts and sign transactions.

This account will be used later in the tutorial as an environment variable called WEB3_ACCOUNT.

Witnet node

The first requirement is access to a Witnet node is needed to send data requests (i.e. querying for the proposal results). More concretely, a JSON-RPC interface with a Witnet node is required.

To run a Witnet node follow the instructions from the documentation but make sure that the JSON-RPC port will be accessible for the next step (discord bot), by default on port 21338.

The docker instructions to also make accessible port 21338 are:

$ docker run -d \
--name witnet_node \
--volume ~/.witnet:/.witnet \
--publish 21337:21337 \
--publish 21338:21338 \
--restart always \
witnet/witnet-rust

Note: The Witnet node needs to have some funds to be able to send data requests to the network.

The Witnet node host and port will be used later in this tutorial as WITNET_NODE_HOST and WITNET_NODE_PORT respectively.

Step 1: Create an Aragon DAO

Create an Aragon DAO by using the Aragon Govern website.

To be compatible with the current implementation of the Aragon bot, it is important to set up the DAO as follows:

  • Collateral amounts must be set to 0.0 tokens.
  • Scheduling transaction whitelist must be set to “Any address” or to the same address that the Ethereum node has unblocked, i.e. WEB3_ACCOUNT.

For example, the angry-violet DAO was configured as follows:

Step 2: Create the Discord bots

The Discord bot will operate on Discords servers it has been invited. If the server has not been created yet, follow these instructions.

Once, the server exists, bots can be created as:

  1. Go to https://discord.com/developers/applications
  2. Create a new application
    a. Click on “New application” and give an application name
    b. Fill out the “General information” of the application
  3. Create a bot
    a. On the application dashboard, go to the side menu “Bot”
    b. Click on the “Add Bot” button
    c. Configure the bot username (by default it will be the same as the application name)
    d. Copy the bot TOKEN (it will be required in the next steps)
    e. Configure your bot as you want (e.g. public bot, permissions, …)
  4. Invite bot to the Discord server
    a. On the application dashboard, go to the side menu “OAuth2”
    b. In “OAuth2 URL Generator section” click on “bot”
    c. Click on the “Copy” button to copy the authorize URL
    d. Go to the copied URL (it should start with: https://discord.com/oauth2/authorize?client_id=<CLIENT_ID>)
    d. Select the Discord server and authorize the bot to join

After creating the bots, they should be listed as offline within the member list of the Discord server.

The previous instructions should be followed to create the Conversational Bot and as many as desired Reaction Monitors.

The Discord tokens and Oauth URLs are required for the next steps as DISCORD_TOKEN and MONITOR_LINK respectively.

Step 3: Build the project

Inside this repository there are two packages, which will be configured in the next tutorial steps:

  • Conversational Bot: contains the logic for Aragon’s discord bot.
  • Reaction Monitors: act as a middleware to read message reactions from the Discord API, and then publish the results through a public REST API.

After ensuring that the previously mentioned requirements, access to a Witnet and Ethereum node, are fulfilled, follow these steps:

  1. Clone the discord-bot-integration repository from GitHub
$ git clone https://github.com/stampery-labs/aragon-govern-discord-integration
  1. Enter the directory, install all dependencies and build the project:
$ cd aragon-govern-discord-integration
$ yarn
$ yarn bootstrap

Step 4: Start the Conversational Bot

The Conversational Bot is configured via environment variables. The easiest to configure the bot is by using the .env file located under aragon-govern-discord-integration/packages/bot.

The main configuration parameters are:

  • DISCORD_TOKEN: the token available at Step 2 (3.b) of the conversational bot.
  • MONITOR_NAME_0: reaction monitor name shown after !setup message.
  • MONITOR_LINK_0: generated OAuth2 URL at Step 2 (4.c).
  • MONITOR_RETRIEVE_URL_0: host and port of the monitor to be queried by Witnet nodes (should be accessible externally).
  • WEB3_ACCOUNT: Ethereum account from which transactions are sent.
  • WEB3_PROVIDER: host and port of the web3 provider.
  • WITNET_NODE_HOST: Witnet node host.
  • WITNET_NODE_PORT: Witnet node port.

Example .env file:

ENVIRONMENT = development
DISCORD_TOKEN = <COPY DISCORD TOKEN HERE>
# The minimum period a proposal has to be active in seconds
MINIMUM_PROPOSAL_DEADLINE = 120
# Subgraph server
SUBGRAPH_ENDPOINT = https://api.thegraph.com/subgraphs/name/aragon/aragon-govern-rinkeby
# List of Reaction Monitors
MONITOR_NAME_0 = "Reactions Monitor 1"
MONITOR_LINK_0 = <COPY OATH2 URL HERE>
MONITOR_RETRIEVE_URL_0 = <CHANGE ME! http://mydomain1:3000>
MONITOR_NAME_1 = "Reactions Monitor 2"
MONITOR_LINK_1 = <COPY OATH2 URL HERE>
MONITOR_RETRIEVE_URL_1 = <CHANGE ME! http://mydomain2:3000>
# Web3 provider
WEB3_ACCOUNT = <COPY WEB3 ACCOUT HERE>
WEB3_PROVIDER = http://localhost:8544
# Witnet
WITNET_NODE_HOST = "localhost"
WITNET_NODE_PORT = 22338

From the aragon-govern-discord-integration folder, start the conversational bot as:

$ yarn bot[BOT]: Connected to Witnet node
Connected to database
[BOT]: Listening discord server
[BOT]: looking for active proposals
[BOT]: active proposals found []

Step 5: Start the Reaction Monitors

Reaction Monitors are configured in a similar but simpler way to the Conversational Bot. It only contains 2 parameters:

  • DISCORD_TOKEN: the token available at Step 2 (3.b) of the reaction monitor bot.
  • PORT: port to listen to HTTP GET requests, used by Witnet nodes to query the proposal results.

Example .env file:

DISCORD_TOKEN = <COPY DISCORD TOKEN HERE>
PORT = 3000

From the aragon-govern-discord-integration folder, each Reaction Monitor is started as:

$ yarn server[Server] Listening on PORT 3000
Connected to database

Ideally, Reaction Monitors should run in different machines and they should be independently operated. However, if they run on the same machine (e.g. for testing purposes), the ports should be different for each one of them.

The PORT environment variable can also be defined inline as:

$ PORT=3001 yarn server[Server] Listening on PORT 3001
Connected to database

Step 6: Use it from Discord

We are almost done, the last step is all about the happy path and about checking that all configured components are working properly:

1. First, if you didn’t do it already, add the bot to a Discord server by using the OATH2 URL as described in Step 2 (4d). Once you have added the bot to your server it should appear online in the member list.

2. Configure your Aragon Govern DAO by using the !setup command within the channel and specify the DAO’s name and which role is allowed to send proposals.

!setup <daoName> <role>

3. Only authorized users (with a configured role) are allowed to create proposals by using the !proposal command as:

!proposal <deadline> <description> to:<address> value:<ETH> data?:<data>

Example:

!proposal 2021/03/26 15:07:00 do you want to give a grant to ENTITY? to:0x199eA5114D1612e40E3457Eaf9DF2779340EAD12 value:0.01

4. After a proposal is received by the bot, the voting period starts and it will read 👍 and 👎 reactions from all Discord users.

5. When the proposal deadline is reached, users can’t continue voting. Then, the bot will create a Witnet data request to retrieve the voting results and it will deliver the data to the Aragon DAO in form of a schedule transaction.

6. After the dispute period is over, the bot will trigger the execution of the proposal as a execute transaction. This will also execute the specified action. In this case, transferring ETH to the given address.

What to do next?

If you made it this far, thank you very much for your patience! 🎆

We know the integration has many moving parts and it is not easy to make it work on the first attempt. Please take into consideration that this integration is a work-in-progress and there are still missing features to be added!

The integration source code is open-source and available at our Github repository aragon-govern-discord-integration. New collaborators and new feature requests are always welcomed! 💪

About Witnet

Witnet is a decentralized oracle that is true to the censorship resistant nature of blockchains. The Witnet protocol leverages state-of-the-art cryptographic and economic techniques to provide smart contracts with secure data input.

Website | Discord | Telegram | Twitter | Reddit | Youtube

About Aragon

Aragon is the leading platform for enabling online communities, companies and collectives of all types to run Decentralized Autonomous Organizations (DAOs) on Ethereum.

Website | Discord | Forum | Twitter | Reddit | YouTube

About Discord

Discord is a voice, video and text communication service used by over a hundred million people to hang out and talk with their friends and communities.

Website | Twitter | Instagram | Facebook | YouTube

--

--