vLotto Ledger Integration Guide (Third‑Party)

How to read ledger.vlotto@ data, enumerate tickets, score, verify authenticity, and present drawing parameters.

This guide assumes no prior knowledge of vLotto. It shows both JSON‑RPC (remote API) and CLI command examples. You can mirror this end‑to‑end to independently score and verify a drawing using only on‑chain data.

1. Overview

vLotto publishes public, machine‑readable status and results into the contentmultimap of the identity ledger.vlotto@. Third parties can:

2. Prerequisites

3. Getting the Ledger

3.0 VDXF Keys (Where to look)

vLotto uses VDXF keys to store structured data inside identities:

PurposeURIVDXF IDWhere
Ledger Data vlotto.ledger.data iFVPmjN213NmfaiBhAkxAJWWGtcDEoXJcU ledger.vlotto@ contentmultimap (latest entry)
Primary Ticket Finalized Data vlotto.ticket.finalizeddata iMzWvy5j4ciiMSBsEEVzfy66awLQ85b4GN each ticket’s contentmultimap (latest entry)
Data Descriptor data.type.object.datadescriptor i4GC1YGEVD21afWudGoFJVdnfjJ5XWnCQv descriptor key nested inside entries to label object types
When reading contentmultimap, iterate its primary keys and inspect the nested VDXF key to match your desired object type. The examples below simply take the latest entry across keys and extract its objectdata.message.

3.1 JSON‑RPC (remote)

{"jsonrpc":"1.0","id":"vlotto","method":"getidentity","params":["ledger.vlotto@"]}

Example with curl:

curl -sS -H 'content-type: text/plain' --data-binary '{"jsonrpc":"1.0","id":"vlotto","method":"getidentity","params":["ledger.vlotto@"]}' https://api.verustest.net | jq '.result.identity'

3.2 CLI (local node)

./verus -chain=VRSCTEST getidentity ledger.vlotto@

3.3 What to extract

The ledger stores a JSON message in the contentmultimap. Extract it from the latest entry:

jq -r '.contentmultimap | to_entries[] | .value[0] | to_entries[] | .value.objectdata.message'

The message contains (field names may appear in snake_case or legacy PascalCase):

PathDescription
.currentPhaseHuman‑readable phase marker.
.phaseStatus.*Completion booleans and timestamps for phases.
.drawingResults.drawingHashFinal 64‑hex drawing hash used for scoring.
.drawingResults.topWinningTicketPublisher’s top ticket info for convenience.
.drawingParameters.*Inputs used to derive ticket names and scoring rules (e.g., mainVerusID, drawingBlock, requiredMatches, rAddressForTickets).
.ticketSummary.*Planned/generated/registered counts for enumeration bounds.

4. Enumerating Tickets

Tickets are named deterministically as: <drawingBlock>_<idx>of<planned>.<mainID-trimmed>@.

Indexing or naming hiccups may occur if publishers adjust naming conventions. If a lookup fails, try trimming trailing digits from the main ID base and retry (fallback strategy).

4.1 Fetching ticket content

Use getidentitycontent on each candidate ticket name. Query the latest content entry and extract the message object.

JSON‑RPC

{"jsonrpc":"1.0","id":"vlotto","method":"getidentitycontent","params":["<ticket_name>"]}

CLI

./verus -chain=VRSCTEST getidentitycontent <ticket_name>

From the message, read:

5. Determining Ticket “Sold” vs “Unsold”

Fetch the current identity state of the ticket:

./verus -chain=VRSCTEST getidentity <ticket_name>

A ticket is considered sold if its current primaryaddresses[0] is different from the published .drawingParameters.rAddressForTickets. Otherwise it is unsold (or graveyarded).

6. Scoring Rules

  1. Obtain drawingHash from ledger message.
  2. Ignore any leading zeros in the drawing hash when scoring.
  3. For each position after the first non‑zero nibble: if ticket nibble equals drawing nibble, increment matches and add the hex value to score.

Rank tickets by: matches desc, then score desc, then ticket index asc. Apply your winner policy (e.g., requires .drawingParameters.requiredMatches and sold=yes).

7. Verifying Authenticity

Given ticket name T, values sig1, hash1, sig2, hash2, and regtx from the ticket message:

CheckRPCPurpose
Ticket signed the registration txid verifymessage(T, sig1, regtx) Confirms a ticket signature over its registration.
Ticket signed hash1 verifyhash(T, sig1, hash1) Confirms ticket’s signature over its own content hash.
Proofguard signed sig1 verifymessage(proofguard.<mainID>@, sig2, sig1) Confirms a second signer acknowledged the ticket signature.
Proofguard signed hash2 verifyhash(proofguard.<mainID>@, sig2, hash2) Confirms second signer’s hash binding.
Optional consistency playing_number == hash2 Additional integrity check used by vLotto’s public script.

7.1 JSON‑RPC examples

{"jsonrpc":"1.0","id":"vlotto","method":"verifymessage","params":["<ticket_name>","<sig1>","<registration_txid>"]}
{"jsonrpc":"1.0","id":"vlotto","method":"verifyhash","params":["<ticket_name>","<sig1>","<hash1>"]}
{"jsonrpc":"1.0","id":"vlotto","method":"verifymessage","params":["proofguard.<mainID>@","<sig2>","<sig1>"]}
{"jsonrpc":"1.0","id":"vlotto","method":"verifyhash","params":["proofguard.<mainID>@","<sig2>","<hash2>"]}

8. Putting It All Together (Workflow)

  1. Fetch ledger from ledger.vlotto@ and parse message JSON.
  2. Read parameters: mainVerusID, drawingBlock, requiredMatches, rAddressForTickets, planned.
  3. Enumerate tickets for i = 1..planned<drawingBlock>_<i>of<planned>.<main>@.
  4. For each ticket:
    • Fetch latest getidentitycontent and parse the message.
    • Check current getidentity to determine sold (primary address != rAddressForTickets).
    • Compute matches and score against drawingHash (ignore hash leading zeros).
  5. Rank tickets by matches, score, index. Determine winner using your policy (usually: sold AND matches ≥ required).
  6. Verify authenticity for top candidates using the four checks in Section 7.
  7. Present results (phase status, parameters, top tickets, verification summary).

9. Remote vs Local Calls

All examples have a JSON‑RPC form suitable for remote APIs and a CLI form for local nodes.

ActionJSON‑RPCCLI (VRSCTEST)
Ledgergetidentity("ledger.vlotto@")./verus -chain=VRSCTEST getidentity ledger.vlotto@
Ticket messagegetidentitycontent("T")./verus -chain=VRSCTEST getidentitycontent T
Ticket stategetidentity("T")./verus -chain=VRSCTEST getidentity T
Verify 1verifymessage(T, sig1, regtx)same via CLI
Verify 2verifyhash(T, sig1, hash1)same via CLI
Verify 3verifymessage(proofguard.main@, sig2, sig1)same via CLI
Verify 4verifyhash(proofguard.main@, sig2, hash2)same via CLI

10. Edge Cases & Tips

11. Minimal Scoring Pseudocode

// Inputs: ledgerMsg, api (rpc), network
main = trimAt(ledgerMsg.drawingParameters.mainVerusID)
N = ledgerMsg.ticketSummary.planned
block = ledgerMsg.drawingParameters.drawingBlock
draw = ledgerMsg.drawingResults.drawingHash
start = index of first non-zero in draw
for i in 1..N:
  name = sprintf("%d_%dof%d.%s@", block, i, N, main)
  msg = latestMessage(getidentitycontent(name))
  if !msg: try fallback base (trim digits)
  cur = getidentity(name)
  sold = cur.primaryaddresses[0] != ledgerMsg.drawingParameters.rAddressForTickets
  matches=0; score=0
  for k from start..63:
    if msg.playing_number[k] == draw[k]:
      matches++
      score += hex2int(draw[k])
  record(matches, score, i, name, sold, msg)
rank by (matches desc, score desc, index asc)
verify top candidates via 4 checks
present results
    

12. Utilities & Basket

The ledger also publishes a utilities section summarizing utility IDs and basket composition. From the ledger message JSON:

Example (remote API):

# Fetch ledger
curl -sS -H 'content-type: text/plain' --data-binary '{"jsonrpc":"1.0","id":"vlotto","method":"getidentity","params":["ledger.vlotto@"]}' https://api.verustest.net \
 | jq -r '.result.identity.contentmultimap | to_entries[] | .value[0] | to_entries[] | .value.objectdata.message' > ledger.json

jq '.utilities.utilityIds' ledger.json
jq '.utilities.basketInfo' ledger.json
jq '.utilities.totalBasket' ledger.json
jq '.utilities.basketHeight' ledger.json

To display current balances for a listed utility ID on your own node, use:

./verus -chain=VRSCTEST getcurrency <utility_id>
./verus -chain=VRSCTEST getaddressbalance <address_or_id>
The “Basket” is the currency associated with the main drawing ID. You can show its composition from .utilities.basketInfo or query per‑currency balances via the CLI.

13. Graveyard Addresses (Unsold Ticket Reassignment)

After sales close and verification, vLotto does not revoke unsold tickets. Instead, it performs an updateidentity to reassign control of each unsold ticket to a designated graveyard R‑address. This preserves the ticket’s on‑chain record and its contentmultimap (chain‑of‑custody data) while removing it from the operator’s wallet.

NetworkGraveyard R‑Address
VRSCTEST (testnet)RMzd5vMptsxxz1tWH2FeSdUgRSNgS4G52w
VRSC (mainnet)RAXCjm9Z4RJWEmsNgo83B8JevTcJRt6Tj5
These addresses are static and produced by a separate, external process. They are not expected to change. The ledger message may also include a convenience field under .utilities.graveyard.rAddress for display.

13.1 Detecting Graveyarded Tickets

During scoring you classify a ticket as “sold” when its current primary address differs from .drawingParameters.rAddressForTickets. After cleanup, unsold tickets will have primary address = graveyard address.

# Current state of a ticket
./verus -chain=VRSCTEST getidentity <ticket_name>
# Expectation after cleanup (unsold):
#   identity.primaryaddresses[0] == RMzd5vMptsxxz1tWH2FeSdUgRSNgS4G52w (testnet)
#   identity.primaryaddresses[0] == RAXCjm9Z4RJWEmsNgo83B8JevTcJRt6Tj5 (mainnet)

Third‑party UIs should reflect this by labeling such tickets as unsold/retired to graveyard. The contentmultimap remains intact and should still be parsed for chain‑of‑custody data.

13.2 Why Graveyard Instead of Revocation?

14. License & Attribution

This document accompanies the vLotto project and is intended for public integration. Please retain attribution when redistributing.

15. Utility IDs – Roles and Expectations

vLotto organizes operational identities as Utility IDs. Third parties can display their presence, balances and basic status by resolving each sub‑ID under the main drawing ID (e.g., jackpot.<main>@). Below is a high‑level description of each utility and what you should expect to find on‑chain.

15.1 jackpot.<main>@

15.2 payout.<main>@

15.3 operations.<main>@

15.4 ledger.<main>@ (a.k.a. ledger.vlotto@)

Content Multimap Entries (message fields)

PathDescription
.currentPhaseHuman‑readable marker of the most recently completed phase.
.lastUpdatedUTC timestamp for the latest ledger write.
.phaseStatus.phase1_initialization..phase10_distributionPer‑phase completion booleans and timestamps.
.drawingParametersImmutable inputs used to derive tickets/scoring (mainVerusID, drawingBlock, ticketPrice, requiredMatches, rAddressForTickets, distribution percents, etc.).
.ticketSummaryPlanned/generated/registered counts and tallies for data updates, marketplace, sold/unsold (graveyarded), verified/fraudulent.
.drawingResults.drawingHashFinal 64‑hex hash used for scoring (ignore leading zeros when scoring).
.drawingResults.topWinningTicketDisplay convenience for the highest scoring candidate or final winner.
.drawingResults.verificationStatusStatus of verifying the top candidate/winner (e.g., completed).
.drawingResults.topTicketMatches/.topTicketScoreMatch count and score for the top ticket (for display).
.drawingResults.winnerStatusOne of winner, no_winner, or pending.
.securityMetricsAggregates from public validation (fraud checks, counts, rates).
.timelockStatusTimelock application indicators for the cycle (may be simulated depending on deployment).
.utilities.utilityIdsDetected utility identity list (e.g., jackpot, payout, operations, ledger, proofguard, reserves, cashier).
.utilities.basketInfo/.totalBasket/.basketHeightCurrency basket composition snapshot and the block height it was computed at (if main ID is a currency).
.payoutSummarySummaries of buyback offers and payout amounts after Phase 9 (if applicable).
.distributionSummaryPhase 10 distribution totals and per‑destination amounts.
.financialSummaryRunning financial aggregates such as current/final jackpot, revenue totals, and distribution amounts.
.operationalMetricsOptional operational telemetry (phase processing times, retry counts) to help readers estimate performance.

15.5 proofguard.<main>@

15.6 reserves.<main>@

15.7 cashier.<main>@

15.8 basket (currency)

15.9 <main>@ (Main ID)