Read and cast votes on the protocol

Bloom's protocol uses community voting to make important protocol decisions. Anyone can create a Poll in the Bloom network by interacting with the VotingCenter contract.

Votes are associated with BloomIDs. If a user has multiple addresses associated with their BloomID, their total BLT balance across all addresses will be used to tally their influence.

Contract name Network Address
VotingCenter Mainnet 0xfdA09EBC868cbCDC5d4838E86581B91079d262eb
VotingCenter Rinkeby 0x9881f0B197fc30D12dADbae103a9008a16132Ef3

If Alice wanted to create a very simple poll within the Bloom network, it might look like this:

// This module exists in the repo!
const ipfsUtils = require(./src/ipfs”);

// Related contracts
accountRegistry ="[address of registry contract]")
signingLogic ="[address of signing logic contract"])

// Create a connection to IFPS
const IPFS = require(“ipfs-mini”);
const ipfs = new IPFS({
  host: “”,
  port: 5001,
  protocol: “https”

// Poll data we want to store
const poll = {
  title: “What kind of ice cream should I buy?,
  description:I am hosting a party soon and I need to decide!,
  choices: [“Vanilla”, “Chocolate”, “Strawberry”]

// Write the data to IPFS
ipfs.addJSON(poll, (err, ipfsMultihash) => {
  if (err) throw err;

  // On success, create the poll via the voting center
    'Bloom Poll',
    1, // chainId: mainnet
    +new Date() / 1000 + 60 * 5, // start in 5 minutes
    +new Date() / 1000 + 60 * 60 * 24 * 7 // end the poll in 1 week,

Delegated Voting


A 3rd party can submit votes on behalf of users in order to pay the transaction costs. A user signs a one-time-use signature with the vote information and sends it to the 3rd party to vote on their behalf. A nonce is included in the signature to make each vote unique. The voter accepts the risk of their vote being censored by a biased 3rd party. They always have the option to submit the vote transaction directly.

mapping (bytes32 => bool) public usedSignatures;

function voteFor(uint16 _choice, address _voter, bytes32 _nonce, bytes _delegationSig) external;
Signing Logic
bytes32 constant VOTE_FOR_TYPEHASH = keccak256(
  "VoteFor(uint16 choice,address voter,bytes32 nonce,address poll)"

struct VoteFor {
    uint16 choice;
    address voter;
    bytes32 nonce;
    address poll;

function hash(VoteFor request) internal pure returns (bytes32) {
  return keccak256(abi.encode(

function generateVoteForDelegationSchemaHash(
  uint16 _choice,
  address _voter,
  bytes32 _nonce,
  address _poll
) external view returns (bytes32) {
  return keccak256(