Cover photo a Frame for verifiable polls is the first secure, censorship-resistant and verifiable polling system for Farcaster.

Vocdoni is changing the game in digital governance by blending easy-to-use Web2 interfaces with the security of Web3. Thanks to the Farcaster Frames interface, we're making voting not just secure but also incredibly user-friendly. This means voting with just one click while backed by blockchain tech.

This article provides a technical explanation of how Vocdoni built a Farcaster Frame for reliable governance 🚀🗳.

This article is written by @p4u, follow him on Farcaster for more technical updates on

Simplifying voting in Web3

At Vocdoni, our mission is to enhance the accessibility and security of voting systems using open-source technology. Our approach merges the simplicity of Web2 interfaces with the robust decentralization of Web3 backends, exemplified in our latest integration with the Farcaster network.

This article provides a concise overview of how Vocdoni leverages the Farcaster frame to simplify voting in the digital age, ensuring it is understandable even for those not deeply versed in blockchain technology.

Bridging Web2 and Web3 Voting

Vocdoni is dedicated to creating open-source and decentralized voting protocols. Our systems are designed to be as user-friendly as Web2 applications, while harnessing the security and transparency of Web3 technologies. This blend has allowed us to deploy our voting infrastructure across various sectors, from sports clubs like Barcelona Football Club to political parties and municipal referendums.

Furthering our commitment to the crypto space, we've collaborated with the Aragon Project and launched advanced web3 applications, including and our new Farcaster-compatible voting application available at

Vocdoni's core technology: the Vochain

At the heart of Vocdoni's products lies the Vochain, a cometBFT blockchain optimized for voting verification. Capable of processing approximately 800 transactions per second (TPS), the Vochain supports various cryptographic proofs, ensuring fast and secure vote verification without imposing gas fees on voters. This approach makes voting accessible and cost-effective. All activity in the Vochain can be observed through the block explorer.

The Farcaster frame integration

Let's unpack the technical intricacies involved in verifying votes on the Vocdoni blockchain through the Farcaster frame interface.

Verifying votes on Vocdoni Blockchain

The Farcaster frame interface is very basic, it only allows the backend to respond with static images and the user to interact with 4 buttons and 1 input text.

Then, on each interaction with the backend, the Frame user will send a JSON object like this:

  "untrustedData": {
    "fid": 2,
    "url": "",
    "messageHash": "0xd2b1ddc6c88e865a33cb1a565e0058d757042974",
    "timestamp": 1706243218,
    "network": 1,
    "buttonIndex": 2,
    "inputText": "hello world",
    "castId": {
      "fid": 226,
      "hash": "0xa48dd46161d8e57725f5e26e34ec19c13ff7f3b9"
  "trustedData": {
    "messageBytes": "d2b1ddc6c88e865a33cb1a565e0058d757042974..."

Let's focus on the trustedData, the crucial component for constructing a voting frame. This element is a Protobuf serialized message that encapsulates the untrustedData along with some additional information.

The signature on this data comes from the appkey, which is an ed25519 EDDSA public key managed by the Farcaster client (such as warpcast, among others).

It's important to underline that this key differs from an Ethereum address, rendering it incompatible with conventional web3 signers.

Let's dive into the fields we use for building the vote transaction:

  • Button Index (1 to 4): This indicates the voter's choice. Each number corresponds to a specific voting option, allowing the system to understand the voter's decision.

  • Farcaster ID (fid): A unique identifier for the Farcaster user, crucial for ensuring the vote's authenticity and preventing double voting.

  • Public Key: Used to verify the signature of the vote, ensuring that the vote is indeed from the user it claims to be from.

  • URL of the Frame: This contextualizes the vote within a specific polling instance, we use it to check and verify the unique poll identifier (processID) and avoid using votes from one process into another.

1. Constructing the Vote Package

The button index directly translates into a “vote package”—an array of numbers representing the voter's choice, as per our ballot protocol. This package is the digital equivalent of marking a ballot in traditional voting systems.

2. Building the Census Proof

The legitimacy of a vote on the blockchain is confirmed through a census proof. The proof validation must be deterministic, reproducible, and self-contained, so any node on the blockchain can verify it at any moment, without requiring external input.

For the Farcaster voting proof, we have two essential components:

  1. Frame Signed TrustedData: This includes the user's public key, extracted directly from the frame backend. It's part of the trusted data signed by the user, ensuring the authenticity of the vote.

  2. Merkle Proof from a Merkle-Tree of Farcaster Public Keys: Utilizing our Web3 EVM scanner, census3, we scan all event logs from the Farcaster registry-key smart contract. This process identifies registered public keys, builds a merkle tree, and publishes it to IPFS, establishing a verifiable and deterministic census. This merkle proof confirms that the voter is part of the eligible voting population.

When initiating a new voting poll on the Vocdoni blockchain, we specify the merkle tree root and its IPFS URI, cementing the census data and enabling nodes across the network to download, verify, and utilize it for merkle-proofs.

Here you can find the Farcaster proof verification implementation code.

3. Preventing Double Voting: The Nullifier

A unique challenge in digital voting is ensuring a single vote per user. Farcaster's protocol allows a user to possess multiple ed25519 public keys, with the Farcaster ID (fid) serving as the unchanging identifier. To counteract double voting, we make use of a nullifier—a hash combining the Farcaster ID and the unique poll identifier (processID). This creates a unique hash for each voting attempt, nullifier = hash(FID,ProcessID), effectively blocking multiple votes by the same user across different keys.

This nullifier is crucial for maintaining the integrity of the voting process. Upon casting a vote, the nullifier is computed and stored in the blockchain state. Any subsequent voting attempts using the same Farcaster ID for the same poll are automatically detected and rejected.

🗳 Use it!

By putting the Farcaster Protocol and the Vocdoni Protocol together, we believe Farcaster has the potential to become the go-to platform for building digital communities of all kinds, including DAOs and Network States.

We spent two fun and productive weeks developing the first version of but now is your turn to have bun by creating your first poll!

More updates, like token-gated polls, are coming soon 👀
Follow @vocdoni on Farcaster and don't miss any update!

Collect this post to permanently own it.
Vocdoni logo
Subscribe to Vocdoni and never miss a post.
#digital voting#web3#farcaster#frames
  • Loading comments...