Solidity: Vote on a Query
Stake collateral on a unique set of option indices. The oracle aggregates weight by identical answer-hash (keccak256 of the encoded uint8[]). This page focuses on on-chain integration (no deployment, governance, or meta info).
Requirements:
- Your contract holds governance tokens and has approved the oracle to pull
collateralviatransferFrom(see ./approvals). - Voting window is open:
block.numberin[startBlock, currentEndBlock]. - One vote per address per query.
selectedOptionsmust be non-empty, contain unique indices, and each index< totalOptions.collateral > 0.
Minimal interface
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IOracleVote {
function voteOnQuery(
uint256 queryId,
uint8[] calldata selectedOptions,
uint256 collateral
) external;
}
Vote single option
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IOracleVote {
function voteOnQuery(uint256, uint8[] calldata, uint256) external;
}
contract OracleVoteSingle {
IOracleVote public immutable oracle;
constructor(address oracle_) {
oracle = IOracleVote(oracle_);
}
/// @notice Vote for a single option with collateral.
/// @dev Assumes allowance to the oracle covers `collateral` and voting window is open.
function voteSingle(uint256 queryId, uint8 option, uint256 collateral) external {
uint8[] memory opts = new uint8[](1);
opts[0] = option;
oracle.voteOnQuery(queryId, opts, collateral);
}
}
Vote multiple options
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IOracleVote {
function voteOnQuery(uint256, uint8[] calldata, uint256) external;
}
contract OracleVoteMulti {
IOracleVote public immutable oracle;
constructor(address oracle_) {
oracle = IOracleVote(oracle_);
}
/// @notice Vote for multiple unique options.
/// @dev Reverts if options are duplicated or out of bounds; ensure `collateral > 0`.
function voteMulti(uint256 queryId, uint8[] calldata options, uint256 collateral) external {
oracle.voteOnQuery(queryId, options, collateral);
}
}
Rules recap:
- Unique options only; duplicates revert.
- Each option must be
< totalOptions. - One vote per address per query (re-voting reverts).
- Collateral must be positive and allowance must be sufficient.
Reading user vote and distribution (view)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IOracleRead {
function getUserVote(uint256, address) external view returns (uint8[] memory, uint256, bool);
function getQueryAnswers(uint256, uint256, uint256) external view returns (
bytes32[] memory answerHashes,
uint8[][] memory decodedAnswers,
uint256[] memory weights
);
}
contract OracleVoteViews {
IOracleRead public immutable oracle;
constructor(address oracle_) {
oracle = IOracleRead(oracle_);
}
function myVote(uint256 queryId) external view returns (uint8[] memory options, uint256 collateral, bool claimed) {
return oracle.getUserVote(queryId, msg.sender);
}
function pageAnswers(uint256 queryId, uint256 offset, uint256 limit)
external
view
returns (bytes32[] memory hashes, uint8[][] memory decoded, uint256[] memory weights)
{
return oracle.getQueryAnswers(queryId, offset, limit);
}
}
Common pitfalls
- Missing allowance: approve the oracle for at least
collateralbefore calling. - Voting too early/late: must be within the active window
[startBlock, currentEndBlock]. - Duplicate options: ensure each index appears only once.
- Out-of-range option: each index must be
< totalOptions.
Related pages
Back to: