> For the complete documentation index, see [llms.txt](https://hashly.gitbook.io/hashly-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hashly.gitbook.io/hashly-docs/technical/hcs-voting.md).

# On-Chain Records (HCS)

Hashly records the actions anyone should be able to check on the **Hedera Consensus Service (HCS)**: votes, event check-ins, Ember grants and claims, and raffle entries and draws. This page lists every topic, what goes into it and how to read it yourself.

***

## 🔍 What Is HCS?

The Hedera Consensus Service is a public, ordered log. Every message sent to a topic gets a consensus timestamp and a sequence number from the network, and once written it can't be changed or removed. **Anyone** can read a topic's messages to verify the data on their own.

***

## 📋 Hashly's Topics (Mainnet)

| Topic                   | ID                                                               | What it records                                                |
| ----------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------- |
| 🗳️ **Event Votes**     | [`0.0.10279947`](https://hashscan.io/mainnet/topic/0.0.10279947) | Stars on mints, meetups, X Spaces, hackathons and other events |
| 💰 **Asset Votes**      | [`0.0.10279948`](https://hashscan.io/mainnet/topic/0.0.10279948) | Stars on tokens, NFT collections and ecosystem projects        |
| 📍 **Event Attendance** | [`0.0.10300837`](https://hashscan.io/mainnet/topic/0.0.10300837) | Check-ins at events with an attendance badge                   |
| 🎁 **Raffles**          | [`0.0.10855136`](https://hashscan.io/mainnet/topic/0.0.10855136) | Raffles opening, ticket purchases and draws                    |
| 🔥 **Embers**           | [`0.0.10855219`](https://hashscan.io/mainnet/topic/0.0.10855219) | Embers granted by an admin and Embers claimed from staking     |

All five topics have **no admin key**, so their settings can never be changed, and the same **submit key** (held by Hashly's account `0.0.10279885`) is the only one allowed to write to them. That keeps spam out while anyone can still read everything.

> ⚠️ Records are permanent. Each one includes your Hedera account ID and a timestamp, and nobody, Hashly included, can edit or delete it. See [Privacy & Terms](/hashly-docs/technical/privacy-terms.md).

***

## 🗳️ Event Votes

Written when someone stars an event:

```json
{
  "type": "event_vote",
  "version": 1,
  "wallet": "0.0.1057510",
  "event_id": "cmtxj8nzj0001hxvytc9pql73",
  "event_type": "meetup",
  "vote": "up",
  "timestamp": 1789300499650
}
```

| Field        | Meaning                                                                                                                    |
| ------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `wallet`     | Account that starred                                                                                                       |
| `event_id`   | Hashly's ID for the event (`hash-ly.com/events/<event_id>`)                                                                |
| `event_type` | `nft` for mints, `meetup` for meetups and X Spaces, `hackathon` for hackathons. Events of type Other are recorded as `nft` |
| `vote`       | Always `up`: events are voted with stars                                                                                   |
| `timestamp`  | When Hashly sent the message, in milliseconds                                                                              |

Event votes don't include voting power. The weight a star added is calculated from the wallet's Dragon and El Santuario holdings when it was cast; see [Voting System](/hashly-docs/discover/voting-system.md).

***

## 💰 Asset Votes

Written when someone stars a token, an NFT collection or an ecosystem project:

```json
{
  "type": "asset_vote",
  "version": 1,
  "wallet": "0.0.8182572",
  "target_id": "0.0.456858",
  "target_type": "token",
  "vote": "up",
  "voting_power": 29,
  "holdings": {
    "el_santuario": 0,
    "santuario_hedera": 28
  },
  "timestamp": 1789284593000
}
```

| Field                       | Meaning                                                                                       |
| --------------------------- | --------------------------------------------------------------------------------------------- |
| `target_id`                 | The token ID for tokens and collections, or `ecosystem:<project slug>` for ecosystem projects |
| `target_type`               | `token` for tokens, `nft` for NFT collections and for ecosystem projects                      |
| `vote`                      | Always `up`                                                                                   |
| `voting_power`              | Weight of the star: 1 + 1 per Dragon + 5 if the wallet holds El Santuario                     |
| `holdings.el_santuario`     | `1` if the wallet held at least one El Santuario, otherwise `0`                               |
| `holdings.santuario_hedera` | Number of Santuario Hedera Dragons held                                                       |

***

## 📍 Event Attendance

Written for every check-in, whether it came from the QR code, the attendance link or the host adding a wallet by hand:

```json
{
  "type": "event_checkin",
  "version": 2,
  "wallet": "0.0.1120388",
  "event_id": "cmq54c3j20001qhisqu6spu6r",
  "event_name": "HHWS #12 - Protocolos Lending",
  "event_type": "ECOSYSTEM_MEETUP",
  "timestamp": 1780945331505
}
```

`event_name` is the event's title at check-in time, and `event_type` is Hashly's internal type name. See [Attendance Badges for Hosts](/hashly-docs/for-event-organizers/host-badges.md).

***

## 🎁 Raffles

A raffle leaves three kinds of message, so its terms, its entries and its result can all be checked.

**Raffle opened** — written when the raffle is published, before anyone can buy a ticket:

```json
{
  "type": "raffle_opened",
  "version": 1,
  "raffle": "test",
  "title": "Test",
  "ticket_cost": 5,
  "winners": 1,
  "ends_at": "2026-09-11T19:00:00.000Z",
  "requires": "1x 0.0.7235629",
  "timestamp": 1789150727523
}
```

`ticket_cost` is in Embers, `winners` is how many will be drawn, and `requires` is the holding needed to enter (`<count>x <token ID>`), or `null` when there's none.

**Entry** — written each time someone buys tickets:

```json
{
  "type": "raffle_entry",
  "version": 1,
  "raffle": "test",
  "wallet": "0.0.961733",
  "tickets": 2,
  "total_tickets": 2,
  "timestamp": 1789151910940
}
```

`tickets` is how many were bought in that purchase, and `total_tickets` is the raffle's running total across everyone.

**Draw** — written when the winners are drawn:

```json
{
  "type": "raffle_drawn",
  "version": 1,
  "raffle": "mapache-mafia-287",
  "tickets": 56,
  "winners": [
    { "place": 1, "wallet": "0.0.4596910", "roll": 10, "prng_tx": "0.0.10279885@1789298771.151616903" }
  ],
  "prng_tx": "0.0.10279885@1789298771.151616903",
  "timestamp": 1789298778899
}
```

| Field               | Meaning                                                                                     |
| ------------------- | ------------------------------------------------------------------------------------------- |
| `raffle`            | The raffle's slug                                                                           |
| `tickets`           | Tickets held by entrants who still met the requirement at the draw                          |
| `winners[].place`   | 1 for the first winner, 2 for the second, and so on                                         |
| `winners[].roll`    | The random number that picked that winner                                                   |
| `winners[].prng_tx` | Transaction ID of the Hedera random number transaction that picked that winner              |
| `prng_tx`           | Transaction ID of the last roll, kept for draws recorded before each winner carried its own |

### 🎲 How Winners Are Drawn

1. 🔍 At the draw, every entrant's holding is checked again on the mirror node. Wallets that no longer meet the requirement are left out.
2. 🎟️ Each remaining ticket is one possible number, so a wallet with 10 tickets covers 10 numbers.
3. 🎲 For each winner, Hashly asks the network for a random number with a **Hedera PRNG transaction**. The number is generated by the consensus nodes and stored in the transaction record, so anyone can look it up on HashScan.
4. 👤 The number lands on a ticket and that ticket's wallet wins. The wallet is taken out before the next roll, so nobody wins twice.
5. 🚫 If Hedera's randomness isn't available, nothing is drawn. Hashly never falls back to a random number of its own.

Ember balances themselves are kept in Hashly's database. What goes on-chain is the raffle's terms, every entry and the random numbers that chose the winners.

***

## 🔥 Embers

**Grant** — Embers an admin gives to a wallet:

```json
{
  "type": "ember_grant",
  "version": 1,
  "from": "0.0.xxxxx",
  "to": "0.0.yyyyy",
  "amount": 1,
  "reason": "Why the Embers were given",
  "timestamp": 1789151164178
}
```

`from` is the admin account that gave the Embers, `to` is the wallet that received them, and `reason` says why. A grant is written to the topic **before** anything is credited. If the message can't be written, the Embers aren't given.

**Claim** — Embers a staker moves into their balance:

```json
{
  "type": "ember_claim",
  "version": 1,
  "wallet": "0.0.9956345",
  "amount": 10.497639,
  "dragons": 21,
  "rate_per_day": 27.625,
  "hours": 0.5419622222222222,
  "timestamp": 1789297058898
}
```

| Field          | Meaning                                                                |
| -------------- | ---------------------------------------------------------------------- |
| `amount`       | Embers claimed                                                         |
| `dragons`      | Dragons that qualified at the moment of the claim                      |
| `rate_per_day` | Embers per day those Dragons were earning                              |
| `hours`        | Time since the wallet's last check, settled at the moment of the claim |

A claim is recorded **after** the Embers are credited, because they were already earned. See [Staking](https://hash-ly.com/staking).

> 💡 Embers have no monetary value and only work inside Hashly. Being recorded on HCS doesn't make them an asset. See [Privacy & Terms](/hashly-docs/technical/privacy-terms.md).

***

## 🔎 Verify It Yourself

* 🔍 **HashScan** — open a topic from the table above to browse its messages.
* 🌐 **Mirror node API** — read the messages directly (they're base64-encoded JSON): `https://mainnet.mirrornode.hedera.com/api/v1/topics/{topicId}/messages`
* 🎲 **Raffle rolls** — look up the `prng_tx` transaction on HashScan to see the number Hedera generated.

***

## 💡 Tips

* 🗳️ **Find your own votes** by searching a topic's messages for your account ID.
* ⏱️ **Allow a few seconds.** Votes and claims are sent to Hedera just after Hashly saves them.
* 🧾 **Use the consensus timestamp** on HashScan as the network's time for a record; `timestamp` inside the message is when Hashly sent it.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://hashly.gitbook.io/hashly-docs/technical/hcs-voting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
