> For the complete documentation index, see [llms.txt](https://bsv.brc.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bsv.brc.dev/tokens/0159.md).

# 1Sat Ordinals — Single-Satoshi Tokens and Origin Tracking

Open Protocol Labs (<info@opl.dev>)

**Authors:** David Case (<dcase@opl.dev>), Luke Rohenaz (<luke@opl.dev>)

**Contributors:** Kurt Wuckert Jr. (<kurt@opl.dev>), Michael Boyd (<root@opl.dev>), Dan Wagner (<dan@opl.dev>)

## Abstract

**1Sat Ordinals** treats a **1-satoshi output** as a non-fungible token and tracks it through the chain.

Each token has a stable id — its **origin** — the outpoint where the 1-satoshi chain started. Spending that sat into a new 1-satoshi output under sat ordering moves the token; the origin does not change.

## Motivation

Bitcoin SV allows outputs of exactly one satoshi. A single satoshi is already discrete and transferable; 1Sat Ordinals just names it and tracks it.

This document standardizes four ideas:

1. A **token** is a chain of 1-satoshi outputs.
2. **Origin** is the permanent name of that chain (an outpoint).
3. The token's **current outpoint** is whichever 1-satoshi output in the chain is still unspent.
4. A **transfer** is a spend that puts that satoshi into a new 1-satoshi output under sat ordering.

Everything else — inscriptions, metadata, names, wallet baskets, marketplaces — can build on this.

## Ordinal Theory

1Sat uses the sat-assignment rule from **Ordinal Theory**: satoshis move from inputs to outputs in order (inputs in order, sats within each input; outputs in order, sats within each output). The *n*th satoshi spent is the *n*th satoshi created.

1Sat does **not** use global sat serial numbers from coinbase. Identity is the **origin** of a 1-satoshi chain. Background: <https://docs.ordinals.com/>.

## Specification

### Outpoints

An **outpoint** is transaction id + output index.

String forms in common use:

* **underscore** — `txid_vout` (common in 1Sat indexers and OrdFS-style paths)
* **dot** — `txid.vout` (common in BRC-100 / overlay APIs; see [BRC-36](/outpoints/0036.md) practice)

Both denote the same outpoint when `txid` is 64 hex characters and `vout` is a non-negative decimal integer. Implementations that accept external references MUST treat the two forms as equal after normalization.

### Token

A **1Sat token** is a chain of **1-satoshi outputs** linked by transfers.

* Only outputs with exactly **1** satoshi are part of a chain.
* Any locking script is fine. This BRC does not care how the coin is locked.
* Script data (inscriptions, metadata) is optional; it does not create or name the token.

While held, exactly one output in the chain is unspent — the token's current location.

### Origin

The **origin** is the outpoint of the first 1-satoshi output in the chain. It is the stable id for APIs, indexes, and UIs. Transfers never change it.

Every 1-satoshi output is either the next link after a transfer, or a **new origin**.

### Sat ordering and transfer

Satoshis flow input→output in order. Counts matter, not input/output indexes: a 1-sat input at any index can land at any 1-sat output if the running totals align.

**Forward (spend):** For a 1-satoshi input, let `S_in` = (sum of earlier input values) + 1. Find the output where the running output total first reaches `S_in`.

* That output value is **1** → **transfer** (new location; origin unchanged).
* That output value is **> 1** → **no transfer** (chain ends; a fresh 1-sat output that did not receive a transferred sat is a new origin).
* No output reaches `S_in` → **burn** (paid as fee).

### Finding origin from an outpoint

Start at any 1-satoshi outpoint in a chain and walk **backward**. When the walk cannot continue as a 1→1 hop, **the current outpoint is the origin**.

```
function proveOrigin(outpoint, txs):
    current = outpoint

    loop:
        tx = load current's transaction from txs
        if missing: fail

        if tx.outputs[current.vout].satoshis != 1: fail

        outAcc = 0
        for j in 0 .. current.vout-1:
            outAcc += tx.outputs[j].satoshis

        inAcc = 0
        for each input of tx:
            sourceTx = load input's source transaction from txs
            if missing: fail
            inSats = sourceTx.outputs[input.vout].satoshis

            // Input entirely before our sat — skip.
            if inAcc + inSats <= outAcc:
                inAcc += inSats
                continue

            // This input covers our sat.
            if inSats == 1 and inAcc == outAcc:
                current = input's source outpoint
                continue outer loop

            break   // not a 1→1 hop

        // Stopped walking — this outpoint is the origin.
        return origin = current
```

### Examples

**Simple transfer** (token input first):

```
inputs:
  i0  1-sat token      1 sat     ← global sat #1
  i1  funding     10_000 sats     ← sats #2 … #10001

outputs:
  o0  1-sat token      1 sat     ← sat #1          origin unchanged
  o1  payment      4_000 sats     ← sats #2 … #4001
  o2  change       5_998 sats     ← sats #4002 … #10001
```

**Counts, not indexes** — funding can come *before* the token on both sides:

```
inputs:
  i0  funding A    3_000 sats     ← sats #1 … #3000
  i1  1-sat token      1 sat     ← sat  #3001        (input index 1, not 0)
  i2  funding B    5_000 sats     ← sats #3002 … #8001

outputs:
  o0  payment      2_000 sats     ← sats #1 … #2000
  o1  payment      1_000 sats     ← sats #2001 … #3000
  o2  1-sat token      1 sat     ← sat  #3001        origin unchanged
  o3  change       4_999 sats     ← sats #3002 … #8001
```

Sats before the token input = `3000` → global sat `#3001`. Sats before `o2` = `3000`, `o2` value 1 → transfer. If `#3001` landed inside a larger output, the chain would not continue.

**Two tokens in one transaction:**

```
inputs:
  i0  token A          1 sat     ← sat #1
  i1  token B          1 sat     ← sat #2
  i2  funding     10_000 sats     ← sats #3 …

outputs:
  o0  token A          1 sat     ← sat #1   origin A unchanged
  o1  token B          1 sat     ← sat #2   origin B unchanged
  o2  change       9_998 sats     ← from funding
```

### What this document does not cover

* Inscription envelopes — [BRC-160](/tokens/0160.md)
* Metadata, wallets, baskets, tags
* Offline or wire proof packages
* Content delivery and application rules (collectables, names, markets, locks, …)

## Security considerations

* **Coin selection** — Do not spend 1Sat token outputs in ordinary payments unless a transfer is intended.
* **Output order** — Builders must place each token satoshi in the intended 1-satoshi output.
* **Claimed origins** — A string `origin: …` is not proof.
* **Proof packages** — Offline tip→origin proofs, bundle size, and send hot paths are specified in [BRC-150](/tokens/0150.md) (and optionally [BRC-158](/transactions/0158.md)). Sat ordering itself is O(inputs+outputs) per hop and is not the scalability bottleneck.

## Implementations

* [docs.1satordinals.com](https://docs.1satordinals.com)
* [b-open-io/1sat-stack](https://github.com/b-open-io/1sat-stack)
* [b-open-io/1sat-sdk](https://github.com/b-open-io/1sat-sdk)

## References

1. 1Sat Ordinals — <https://docs.1satordinals.com>
2. Ordinal Theory — <https://docs.ordinals.com/>
3. [BRC-36](/outpoints/0036.md) — Format for Bitcoin Outpoints
4. [BRC-45](/tokens/0045.md) — Definition of UTXOs as Bitcoin Tokens
5. [BRC-160](/tokens/0160.md) — 1Sat Ordinals — Inscription Envelopes
6. [BRC-150](/tokens/0150.md) — 1Sat Provenance Remittance for Basket `1sat`
7. [BRC-158](/transactions/0158.md) — Outpoint BEEF


---

# 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://bsv.brc.dev/tokens/0159.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.
