JS: Vote on a Query

Cast a vote by submitting a unique set of option indices and staking collateral in the governance token. The oracle aggregates weight by identical answer-hash (keccak256 of the encoded uint8).

Requirements:

  • ERC‑20 allowance to the oracle that covers your collateral
  • Voting window open: block.number in startBlock, currentEndBlock
  • One vote per address per query
  • selectedOptions must be unique, each < totalOptions

Browser signer example

import { BrowserProvider, Contract } from 'ethers'
import OracleArtifact from '../../../artifacts/contracts/FarmTruth.sol/DecentralizedOracle.json'

const browser = new BrowserProvider((globalThis as any).ethereum)
const signer = await browser.getSigner()

const ORACLE_ADDRESS = '0xFA4595F636887CA28FCA3260486e44fdcc8c8A71'
const oracle = new Contract(ORACLE_ADDRESS, (OracleArtifact as any).abi, signer)

const queryId = 0n
const selectedOptions = [1]       // Use unique indices
const collateral = 10n * 10n ** 18n // 10 tokens (assuming 18 decimals)

const tx = await oracle.voteOnQuery(queryId, selectedOptions, collateral)
await tx.wait()

Server signer example

import { Wallet, JsonRpcProvider, Contract } from 'ethers'
import OracleArtifact from '../../../artifacts/contracts/FarmTruth.sol/DecentralizedOracle.json'

const provider = new JsonRpcProvider(process.env.RPC!)
const wallet = new Wallet(process.env.PRIVATE_KEY!, provider)

const ORACLE_ADDRESS = '0xFA4595F636887CA28FCA3260486e44fdcc8c8A71'
const oracle = new Contract(ORACLE_ADDRESS, (OracleArtifact as any).abi, wallet)

const queryId = 1n
const selectedOptions = [0, 2]    // multi-select allowed, must be unique and valid
const collateral = 25n * 10n ** 18n

const tx = await oracle.voteOnQuery(queryId, selectedOptions, collateral)
await tx.wait()

Validating inputs

  • Unique indices: duplicates revert
  • Index bounds: 0 <= option < totalOptions
  • Positive collateral: collateral > 0

Optional pre-checks:

// Check you haven’t voted yet
const [opts, amount, claimed] = await oracle.getUserVote(queryId, await signer.getAddress())
// amount > 0n means you already voted

// Ensure allowance is sufficient (see JS Setup for approve flow)

Reading distribution

Use getQueryAnswers to inspect current answers and weights:

const [hashes, decodedAnswers, weights] = await oracle.getQueryAnswers(queryId, 0, 100n)
decodedAnswers.forEach((opts, i) => {
  console.log('Answer', i, 'options:', opts.map(v => v.toString()), 'weight:', weights[i].toString())
})

Common pitfalls

  • Missing allowance: approve the oracle for at least your collateral amount
  • Voting too early/late: must be within the active window startBlock, currentEndBlock
  • Double voting: only one vote per address per query
  • Duplicated options: pass each option index once

Navigate next:

  • Resolve a query → ./resolve
  • Claim rewards → ./claim
  • Ties, extensions, slashing → ./ties-slashing
  • Pagination and listing → ./pagination

Back to: