# Welcome to OpenStamp

Features SRC20 & Stamps Marketplace, Minting Service, Launchpad, and an Explorer for SRC20 & Stamps asset tracking.

STAMPS IMPRINTING ETERNITY ON BITCOIN,\
ONE TRANSACTION AT A TIME.
--------------------------

## Official Links

{% content-ref url="/pages/ffyZB6e97Auq8o2J2YGL" %}
[OpenStamp Official Links](/official-links/openstamp-official-links)
{% endcontent-ref %}

## Design

{% content-ref url="/pages/8cIRCHGrfaAO9yNoH3ql" %}
[SRC20 Marketplace](/product-design/src20-marketplace)
{% endcontent-ref %}

{% content-ref url="/pages/nEjNK1mpXnEVBmxYPLZE" %}
[Small UTXO](/product-design/small-utxo)
{% endcontent-ref %}

## Marketplace

{% content-ref url="/pages/jAAJQ3pku8DFNKSQS5WG" %}
[Buy SRC20 Tokens](/product-guides/buy-src20-tokens)
{% endcontent-ref %}

{% content-ref url="/pages/0nrvvdXuM0b9jHvLtHJq" %}
[List SRC20 Tokens](/product-guides/list-src20-tokens)
{% endcontent-ref %}

## Mint

{% content-ref url="/pages/GeNW4GrLRTNAZWQSuDKA" %}
[Mint SRC20 Tokens](/product-guides/mint-src20-tokens)
{% endcontent-ref %}

{% content-ref url="/pages/KB0bqnn2AyzZyNb0QUry" %}
[Mint Stamps](/product-guides/mint-stamps)
{% endcontent-ref %}


# BTC STAMPS

BTC Stamps protocol specification

> Source: [https://github.com/mikeinspace/stamps#readme ](<https://github.com/mikeinspace/stamps#readme >)

## STAMPS: A Protocol for Storing Images On-Chain in Transaction Outputs Immutably on Bitcoin

Storing "Art on the Blockchain" as a method of achieving permanence is often a misnomer in the NFT world. Most NFTs are merely image pointers to centralized hosting or stored on-chain in prunable witness data. We propose a method of embedding base64-formatted image data using transaction outputs in a novel fashion.

The means by which this is achieved is encoding an image's binary content to a base64 string, placing this string as a suffix to `STAMP:` in a transaction's description key, and then broadcasting it using the Counterparty protocol onto the Bitcoin ledger. The length of the string means that Counterparty defaults to bare multisig, thereby chunking the data into outputs rather than using the limited (and prunable) OP\_RETURN. By doing so, the data is preserved in such a manner that is impossible to prune from a fullnode, preserving the data immutably forever.

Given the cost of preserving data in this manner, we suggest the following guidance: 24x24 pixel, 8-colour-depth PNG or GIF. The constraints of this "canvas" are ideal for pixel art. In particular, the CryptoPunks use a native resolution of 24x24 pixels.

STAMPS will be numbered based on the transaction timestamp. This is to ensure that the STAMPS directory is ordered chronologically. The first STAMP will be the first transaction to include the `STAMP:` string with a valid base64 string appended in the description key, and so on. A transaction with an invalid or indecipherable base64 string will not be considered a STAMP. The STAMP number will begin at zero and continue indefinitely.

### What Makes a STAMP? <a href="#user-content-what-makes-a-stamp" id="user-content-what-makes-a-stamp"></a>

A STAMP is a Counterparty transaction which contains a valid `STAMP:base64` string in the description key. STAMPS can be decoded directly from the original Bitcoin transaction. In order for speed of processing and to eliminate needs for indexing, we are utilizing Counterparty API to decode the original Bitcoin transactions. Once the decoding is complete, we upload the images to stampchain.io for consumption via web applications as a convenience. It is intended that anyone may decode these transactions and interpret the underlying image data for rendering on any application.

### STAMPS abide by the following rules: <a href="#user-content-stamps-abide-by-the-following-rules" id="user-content-stamps-abide-by-the-following-rules"></a>

* The image data must be in either jpg, png, gif or webP format and encoded in base64.

**Recommended Format:**

* `STAMP:<base64 data>`

Example:

* `STAMP:iVBORw0KGgoAAAANSU...`

### Potential Future State formatting: <a href="#user-content-potential-future-state-formatting" id="user-content-potential-future-state-formatting"></a>

Warning: Do not try this until its actually approved. Doing so may result in an invalid STAMP as plans may change.

* `STAMP:data:image/png;base64,iVBORw0KGgoAAAANSU...`

### Decoding a STAMP <a href="#user-content-decoding-a-stamp" id="user-content-decoding-a-stamp"></a>

A raw bitcoin transaction may be decoded using tools such as:

<https://jpja.github.io/Electrum-Counterparty/decode_tx.htm>

This will reveal the description field of the STAMP transaction. The description field will contain the base64 string. This string can be decoded using any base64 decoder.

### Absence of MIME-type and encoding <a href="#user-content-absence-of-mime-type-and-encoding" id="user-content-absence-of-mime-type-and-encoding"></a>

Our rationale for excluding both the MIME-type and encoding goes as follows:

* The fewer the bytes the better.
* Given the limited scope of acceptable file formats, we are confident that decoding them accurately based on the base64 string alone is trivial.
* We are only interested in decoding base64, so if the string does not conform to valid base64 it is rejected. Therefore, specification of the encoding is unnecessary.

This all pertains to current state. The future-state proposal would require a MIME-type like 'text/plain' for the auxilary content to be decoded.

### XCHAIN-specific markup <a href="#user-content-xchain-specific-markup" id="user-content-xchain-specific-markup"></a>

While no specific markup should be required, STAMPS are purposely designed to be very small in the range of 24x24 pixels. While they can be presented at this size or even scaled-up using the traditional method, the user experience would be sub-optimal. Using a few simple CSS rules will optimize the rendering. Eg: image-rendering: pixelated;

Visual example of pixel art scaling without image degradation: <https://i.imgur.com/CGLqw11.jpg>

### Trading <a href="#user-content-trading" id="user-content-trading"></a>

Users are able to trade the token on the Counterparty DEX, Dispensers or OTC or any other method as traditional Counterparty assets.


# OLGA(Octet Linked Graphics & Artifacts)

Bitcoin Stamps Improvement Proposal: Octet Linked Graphics & Artifacts (OLGA)

> Source: <https://github.com/mikeinspace/stamps/blob/main/OLGA.md>

Based on "File Storage in P2WSH Outputs" by JP Janssen\
<https://github.com/CounterpartyXCP/cips/blob/master/cip-0033.md>

## Abstract

Encode a supported Bitcoin Stamp, which is stored in the form of binary octets, in the transaction outputs of non-obvious burn-addresses, along with a Counterparty issuance transaction.

## Supported File-types

Image formats such as PNG, JPG, GIF, and SVG are the focus of the protocol for images and art. Currently, the excluded file formats for Bitcoin Stamps include \['plain', 'octet-stream', 'js', 'css', 'x-empty', 'json'].

## Motivation

Store files immutably on Bitcoin and link them to tokens in a manner that is cheaper than storing them in multisig Bitcoin transactions, as done with Classic Bitcoin Stamps.

## Rationale

The Classic Bitcoin Stamp method stores files as Base64 strings, achieving an efficiency of 6 bits per byte. Base64 encoding converts binary data into an ASCII string format by representing it with 64 different ASCII characters, including A-Z, a-z, 0-9, '+', and '/'. In this encoding, 24 bits (or 3 bytes) of binary data are encoded into 4 Base64 characters, which amounts to 32 bits. Consequently, the total size of 24 bits of binary data, when encoded in Base64, becomes 4 bytes. Since 24 bits of original data are represented by 32 bits (4 bytes), the efficiency is 24/32, which simplifies to 6/8, or 6 bits per original byte. Therefore, in the context of Bitcoin transactions, 3 bytes of binary data consume 4 bytes. Additionally, the Classic Bitcoin Stamp method employs multisig transaction encoding, where only two out of three outputs are utilized for storage.

This Bitcoin Stamps Improvement Proposal (BSIP) introduces a method for storing a file in conjunction with a Counterparty issuance transaction. This is achieved by dividing the file into chunks, which then constitute multiple P2WSH outputs. This approach creates (effectively) permanent UTXOs, wherein a small amount of bitcoin dust is burnt.

Comparing the encoding methods for files of about the same size; a [Stamp of 2853 bytes](https://stampchain.io/asset.html?tx_hash=e6ed0accb29285858217826b2116609ae297e8eaea71fdffd9b87a7934a948b0) and a [OLGA of 2474 bytes](https://jpja.github.io/Electrum-Counterparty/decode_tx?tx=549a5cc4bc189c800f0f9ea01068e8a7fd987c7dadb40c0b6a224d489ed070cc):

| Encoding      | File | Tx   | Tx x | Dust   | SATS/Byte |
| ------------- | ---- | ---- | ---- | ------ | --------- |
| Classic Stamp | 2853 | 8579 | 3.0  | 73,000 | 26        |
| OLGA Stamp    | 2474 | 3613 | 1.5  | 27,306 | 11        |

In a Classic Bitcoin Stamp, the Bitcoin transaction is three times larger than the file, and for each byte of the file, 26 satoshis are burnt. With the OLGA Stamp method, the transaction is only 50% larger than the OLGA-encoded file, and just 11 satoshis are burnt per byte. This makes the OLGA Stamp method more than 50% cheaper than Classic Bitcoin Stamps.

## Definitions

* `STAMP:` - Case insensitive prefix of the Counterparty `asset description` signaling that a file is encoded in the transaction.
* `P2WSH output` - 32 byte script data of a Pay-To-Witness-Script-Hash address output.

## Specification

### File Encoding

* Prepend the file's blob with a two-byte integer signaling the file size.
* Split the blob into 32 byte chunks.
* Append empty bytes to last chunk to make it exactly 32 bytes.
* Convert these to P2WSH addresses and add these as tx outputs.

### Link Token to OLGA-encoded file via Counterparty Issuance

* In the same transaction, insert a valid `op_return` or `multisig` Counterparty issuance transaction.
* Asset description must begin with `STAMP:` (case insensitive).
* Characters after `STAMP:` are currently ignored (reserved for future use).
* To avoid conflict with Classic Stamps, any base64 data following STAMP: may invalidate the transaction for inclusion in Bitcoin Stamps.
* Asset must be numeric not named or sub-asset of named.

### Block Height Activation

OLGA-encoded Bitcoin Stamps will be considered valid only on, or after, Bitcoin block height 833,000.

### Limitations

Since a standard node accepts a maximum of 200 outputs, and one is used for an op\_return and another for change, the file must fit within 198 P2WSH outputs. This implies a maximum file size of 198 \* 32 - 2 = 6334 bytes. The theoretical maximum file size, which can be mined by a node ignoring standard rules, is 256^2 - 2 = 65,536 bytes, limited only by the two-byte size prefix.

## Implementation

Live on block 833000

With the "Counterparty Decoder" you can look up OLGA Stamps and Counterparty CIP33 transactions on [mainnet](https://jpja.github.io/Electrum-Counterparty/decode_tx?tx=549a5cc4bc189c800f0f9ea01068e8a7fd987c7dadb40c0b6a224d489ed070cc) and [testnet](https://jpja.github.io/Electrum-Counterparty/decode_tx?tx=83fc87b4fffd78c8ffd55469206f0f90c0dbbb620b32e8d4adfb7d46148a07f5\&network=testnet).

## Copyright

This document is placed in the public domain.


# Key Burn

Key Burn is a new technique introduced to address concerns with the spendable outputs that encode the art of a Bitcoin Stamps.

> Source: <https://github.com/mikeinspace/stamps/blob/main/Key-Burn.md>

## Bitcoin Stamps: Introduction to 'Key Burn'

Key Burn is a new technique introduced to address concerns with the spendable outputs that encode the art of a Bitcoin Stamp.

While spending outputs is currently a non-trivial process, tooling is likely to emerge in the near future making the process easy enough. Combined with the large amount of sats embedded in older Stamps' outputs (7800), we recognize the incentive to spend the outputs once tooling makes it easy to do so. That being said, spent outputs would only mean that the art would no longer exist within the UTXO set, but continue to live in the transaction data of the blockchain held by all full nodes.

Key Burn is the first step in addressing this potential issue. We are also working on a redemption method paired with Key Burn that would allow artists to redeem up to 90% of the trapped sats from the outputs before 'burning' the multisig key. We believe this approach should be incentive-compatible for artists and collectors alike.

## The Approach

Based on 'NFiniTy' by B0B Smith, Key Burn assigns the spending key of the 'fake multisig' to a burn address when a Bitcoin Stamp is minted, making the spendable outputs, effectively, unspendable.

Presently, the STAMPCHAIN.IO minting service does this by default by cycling through a series of known burn addresses which can easily be scrutinized to validate that no private key can practically exist. In the future, this library of burn addresses may grow to address adversarial action.

The very first example of the Key Burn method in use (coined 'NFiniTy') is here: <https://xchain.io/asset/SPENDME>. By analyzing its scriptPubKey, you will notice that the spendable multisig key address is: '`022222222222222222222222222222222222222222222222222222222222222222`' which does not have a known Private Key based on the highly improbable pattern.

The second example of the Key Burn method in use (a valid #Bitcoin Stamp) is here: <https://xchain.io/asset/A808022222222222222>. Once again, you can examine the scriptPubKey here: <https://blockstream.info/tx/f2ac4cf5230e3033968c25d0a4e3f05ea7ba36429dec7e560ae770a732fd7ae8?expand> to verify that the spendable multisig key address is: '`022222222222222222222222222222222222222222222222222222222222222222`'

## Library of current Key Burn addresses:

If you're unfamiliar with how a burn address works, essentially, a completely improbable pattern is chosen which proves that no private key is held. This is because the public key is derived from the private key, so the odds of coming up with a pre-determined pattern of great length is infinitesimally small to the point where a computer would need to grind away at keys for billions of years in order to do produce a valid private key.

Here are the key addresses chosen for the initial launch of Key Burn.

`022222222222222222222222222222222222222222222222222222222222222222` `033333333333333333333333333333333333333333333333333333333333333333` `020202020202020202020202020202020202020202020202020202020202020202` `030303030303030303030303030303030303030303030303030303030303030303`

We strongly advise other minting services looking to implement Key Burn to use one of the addresses above or work closely with the STAMP protocol developers to ensure that a consolidated list of burn addresses is maintained as we will be badging Bitcoin Stamps in a future update of STAMPCHAIN.IO as well as the webservice API.

## Badging

In a future release, Bitcoin Stamps will have 1 of 3 designations based on the state of the spendable outputs and key availability:

* Spent Outputs (Art will likely be blacked-out or faded but numbering will remain intact)
* Unspent Outputs; Key Available
* Unspent Outputs; Key Burned

## Acknowledgements

Special Thanks to B0B Smith, Regan and RΞINAMORA for devising and coding this solution.


# SRC20 Protocol

{% content-ref url="/pages/3JjGqng50NUPh6TI1Eho" %}
[SRC20 on Bitcoin](/introduction/src20-protocol/src20-on-bitcoin)
{% endcontent-ref %}

{% content-ref url="/pages/lAiFNm3NV6IPQDBKfT4j" %}
[SRC20 on Fractal](/introduction/src20-protocol/src20-on-fractal)
{% endcontent-ref %}


# SRC20 on Bitcoin

BTC Stamp fungible token protocol - SRC20 specification

> Source: <https://github.com/hydren-crypto/stampchain/blob/main/docs/src20.md>

## SRC-20 Tokens

SRC-20 Specifications have changed protocol specifications as of block 796,000. SRC-20 transactions are now created directly on BTC and are no-longer supported as Counterparty transactions. SRC-20 mints, deploys, and transfers are all free from an service fees with the exception of the BTC miners fee when done from a supported wallet.

SRC-20 is a bleeding edge specification modeled after BRC-20. Prior specifications of SRC-20 in its initial state were built on top of Counterparty transactions with specific requirements for an issuance transaction. The current specification as of block 796,000 encodes the SRC-20 transaction directly onto BTC and does not use Counterparty. Any SRC-20 transactions created on Counterparty after block 796,000 will be invalid. Counterparty was used as a proof of concept as we designed a direct to BTC method which optimizes the transaction size and reduces cost of SRC-20 transactions.

## Specifications

SRC-20 Tokens must conform to these **required** fields or a Bitcoin Stamp Number will not be created, the transaction will not be considered a valid SRC-20 transaction, and they will not appear in the Bitcoin Stamps Protocol index / API.

SRC-20 transaction must be signed and broadcast onto BTC by the address that holds the SRC-20 token balance as it acts as a means to authenticate ownership. Both the source and destination addresses are embedded into the BTC transaction which is created by the users wallet. The SRC-20 reference wallet will ensure you are creating the proper transaction until support can be integrated into more broadly distributed wallets such as Hiro. Please use extreme caution if signing transactions created by a third party.

#### DEPLOY

```JSON
{
    "p": "src-20", 
    "op": "deploy", 
    "tick": "STAMP",
    "max": "100000", 
    "lim": "100",
    "dec": "18" // [optional]
}
```

#### MINT

```JSON
{
    "p": "src-20", 
    "op": "mint", 
    "tick": "STAMP", 
    "amt": "100"
}
```

#### TRANSFER

```JSON
{
    "p": "src-20", 
    "op": "transfer", 
    "tick": "STAMP", 
    "amt": "100"
}
```

If the amount specified to be transferred exceeds the balance held (which would be determined by the latest state of an Indexer), then the transfer will be deemed invalid.

## SRC-20 Token Requirements

1. Tokens must be 1-5 characters in length.
2. Allowed characters: a. Any word character (alphanumeric characters and underscores) b. Special characters: \~!@#$%^&\*()\_+=<>? c. Most printable emojis in U+1F300 to U+1F5FF
3. Disallowed characters: a. Non-printable Unicode characters b. Quotation marks: " \` ' outside of regular json delimiters c. Special characters not present in (2b, 2c) including , in numeric fields
4. Only numeric values are allowed in the "max", "amt", "lim" fields
5. Other Qualifications:
   * The third multisig pubkeys must be to a valid Keyburn address
   * not case sensitive DOGE=doge
   * max mint/transfer/lim amount: uint64\_max 18,446,744,073,709,551,615 (**commas not allowed**, here for readability only)
   * max decimals: 18 (default - no need to specify unless a lower precision is desired)
   * json strings are not order sensitive
   * json strings are not case sensitive
   * MAX, LIM fields are integers only
   * AMT field is a decimal up to uint64 max with 18 decimals
   * Must be a valid CP transaction for transactions prior to block 796,000 have 0 assets issued, locked, and not divisible
   * Must be a valid BASE64 as decoded by Python 3.9 base64.b64decode(base64\_string prior to block 796,000
6. Balance Calculations
   * Mints over the limit are capped - user will receive the limit amount if the token has not exceeded the max value
   * Deploys to the same tick which are previously deployed are invalid
   * Negative mints and transfers are invalid
   * If a mint is within the limit, but not within the max it is capped at the max value
   * Any mint where max has already been exceeded is invalid (overmint)
   * Any transfer over the users balance at the time of transfer is considered invalid and will not impact either users balance
     * if wallet *x* has 1 KEVIN token and attempts to transfer 10000 KEVIN tokens to address *y* the entire transaction is invalid

## SRC-20 Token Example JSON Strings

```
🔺🔺 Invalid Examples: 🚫🚫

{"p": "src-20", "op": "mint", "tick": "🙂APL", "amt": "18446744073709551616"} ## over uint64_max
{"p": "src-20", "op": "mint", "tick": "🙂@PL", "amt": "18,446"}     ## commas not allowed in amt
{"p": "src-20", "op": "mint", "tick": "🙂"PL", "amt": "100"}        ## double quotes not allowed in tick
{'p': 'src-20', 'op': 'mint', 'tick': ' rare', 'amt': '1000'}       ## invalid space in tick
```

```
👍👌 Valid Examples: 👌👍

{"p": "src-20", "tick": "🙂APL", "op": "mint", "amt": "100"}
{"p": "src-20", "op": "mint", "tick": "STAMP", "amt": "18446744073709551615"}
{"p": "src-20", "op": "mint", "tick": "🙂P`L", "amt": "100"}
{"p": "src-20", "op": "mint", "tick": "🙂PL?", "amt": "100"}
{"p": "src-20", "op": "mint", "tick": "🙂PL?", "amt": "100"}
{"p": "src-20", "op": "mint", "tick": "🙂PL", "amt": "100"}
{"p": "src-20", "op": "mint", "tick": "PIZZA", "amt": "11111", "random": "test"}  
{
 "p": "src-20",
 "op": "deploy",
 "tick": "KEVN",
 "max": "2844674409551615",
 "lim": "1000"
}
```

**INVALID** tokens will not be created in the Bitcoin Stamps Protocol index or API, and the transaction will not be considered a valid SRC-20 transaction. Any further modifications to the standard must be designed around backwards compatibility.

### Allowed Unicode Chars for Tick Field

Emoji\_Presentation: This property includes all characters that are defined as emojis and have a distinct emoji-style appearance. These characters are intended to be displayed as colorful pictographs, rather than black-and-white text symbols. Examples include face emojis (😀, 😂, 😊), objects (🚗, 🌍, 🍕), and symbols (❤️, 🚫, ⏰).

Emoji\_Modifier\_Base: This property consists of characters that can be modified by emoji modifiers, such as skin tone modifiers. These characters usually represent human-like figures (e.g., 👩, 👨, 🤳) and can be combined with emoji modifiers to represent variations in skin tone or other attributes.

Emoji\_Modifier: This property contains characters that can be used to modify the appearance of other emojis, particularly the ones classified as Emoji\_Modifier\_Base. The most common example is the skin tone modifiers (🏻, 🏼, 🏽, 🏾, 🏿) that can be applied to human-like emojis to represent different skin tones.

### Excluded Unicode Chars for Tick Field

These chars are excluded from the allowed chars list because they are not printable, and are not allowed in the tick field. Tokens with these chars will not be created in Bitcoin Stamps Protocol index or API, and the transaction will not be considered a valid SRC-20 transaction.

Emoji\_Component: Characters that are used to create more complex emojis, such as skin tone modifiers and hair components. These characters are not emojis on their own but can be used with other emojis.

Extended\_Pictographic: This includes additional pictographic characters not covered by Emoji\_Presentation but can still be considered emojis.

to apply an emoji modifier it would take up 2 chars, and be added directly after the emoji from emoji\_presentation. I suspect the web browser interprets that. kind of cool, didn't know how those worked.

an ASCII character takes up only one byte, while an emoji can take up to four bytes.

## SRC-20 BTC Transaction Specifications

```BASH
 # bitcoin-cli getrawtransaction 50aeb77245a9483a5b077e4e7506c331dc2f628c22046e7d2b4c6ad6c6236ae1 true
```

```JSON

{
  "txid": "50aeb77245a9483a5b077e4e7506c331dc2f628c22046e7d2b4c6ad6c6236ae1",
  "hash": "d045be2dc4647d92c1327fbd5572e6c7024f00f1e991b833f38cbdfb1a19577c",
  "version": 2,
  "size": 451,
  "vsize": 369,
  "weight": 1474,
  "locktime": 0,
  "vin": [
    {
      "txid": "6005ee8cc02e528e20c8e5ff71191723b0260391020862a03587a985f813dabe",
      "vout": 2,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "txinwitness": [
        "3045022100bd8c27473a5a82cc9085af4fd530ffbcb8642fda04689ac27ecefa01287f54e5022040af2daafaa1bedd6f80ee9d751cc88c12de8f8e65b33222c432d066c8cecbd801",
        "0314beffca49f214014cccdc0e1f7259aa1a5eeaaa34da1a4fd807e16fea3a86b0"
      ],
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.00000555,
      "n": 0,
      "scriptPubKey": {
        "asm": "0 afdcc32a2778ebd36c4859c7301bb4c32cb59f93",
        "desc": "addr(bc1q4lwvx2380r4axmzgt8rnqxa5cvktt8unqlnka6)#3yzckyj0",
        "hex": "0014afdcc32a2778ebd36c4859c7301bb4c32cb59f93",
        "address": "bc1q4lwvx2380r4axmzgt8rnqxa5cvktt8unqlnka6",
        "type": "witness_v0_keyhash"
      }
    },
    {
      "value": 0.00000888,
      "n": 1,
      "scriptPubKey": {
        "asm": "1 03c46b73fe2ff939bea5d0a577950dc8876e863bed11c887d681417dfd70533e51 039036c8182c70770f8f6bd702a25c7179bfff1ccb3a844297a717226b88b976cc 020202020202020202020202020202020202020202020202020202020202020202 3 OP_CHECKMULTISIG",
        "desc": "multi(1,03c46b73fe2ff939bea5d0a577950dc8876e863bed11c887d681417dfd70533e51,039036c8182c70770f8f6bd702a25c7179bfff1ccb3a844297a717226b88b976cc,020202020202020202020202020202020202020202020202020202020202020202)#jjleg3k0",
        "hex": "512103c46b73fe2ff939bea5d0a577950dc8876e863bed11c887d681417dfd70533e5121039036c8182c70770f8f6bd702a25c7179bfff1ccb3a844297a717226b88b976cc2102020202020202020202020202020202020202020202020202020202020202020253ae",
        "type": "multisig"
      }
    },
    {
      "value": 0.00000888,
      "n": 2,
      "scriptPubKey": {
        "asm": "1 02dc054e58b755f233295d2a8759a3e4cbf678619d8e75379e7989046dbce16be3 02932b35a45d21395ac8bb54b8f9dae3fd2dbc309c24e550cf2211fe6aa897e5ca 020202020202020202020202020202020202020202020202020202020202020202 3 OP_CHECKMULTISIG",
        "desc": "multi(1,02dc054e58b755f233295d2a8759a3e4cbf678619d8e75379e7989046dbce16be3,02932b35a45d21395ac8bb54b8f9dae3fd2dbc309c24e550cf2211fe6aa897e5ca,020202020202020202020202020202020202020202020202020202020202020202)#x8agrm2s",
        "hex": "512102dc054e58b755f233295d2a8759a3e4cbf678619d8e75379e7989046dbce16be32102932b35a45d21395ac8bb54b8f9dae3fd2dbc309c24e550cf2211fe6aa897e5ca2102020202020202020202020202020202020202020202020202020202020202020253ae",
        "type": "multisig"
      }
    },
    {
      "value": 0.00345194,
      "n": 3,
      "scriptPubKey": {
        "asm": "0 cc1d6448d6879b3e260829d9a31717beb772186e",
        "desc": "addr(bc1qeswkgjxks7dnufsg98v6x9chh6mhyxrwrvdktf)#km4m4l32",
        "hex": "0014cc1d6448d6879b3e260829d9a31717beb772186e",
        "address": "bc1qeswkgjxks7dnufsg98v6x9chh6mhyxrwrvdktf",
        "type": "witness_v0_keyhash"
      }
    }
  ],
  "hex": "02000000000101beda13f885a98735a0620802910326b023171971ffe5c8208e522ec08cee05600200000000ffffffff042b02000000000000160014afdcc32a2778ebd36c4859c7301bb4c32cb59f93780300000000000069512103c46b73fe2ff939bea5d0a577950dc8876e863bed11c887d681417dfd70533e5121039036c8182c70770f8f6bd702a25c7179bfff1ccb3a844297a717226b88b976cc2102020202020202020202020202020202020202020202020202020202020202020253ae780300000000000069512102dc054e58b755f233295d2a8759a3e4cbf678619d8e75379e7989046dbce16be32102932b35a45d21395ac8bb54b8f9dae3fd2dbc309c24e550cf2211fe6aa897e5ca2102020202020202020202020202020202020202020202020202020202020202020253ae6a44050000000000160014cc1d6448d6879b3e260829d9a31717beb772186e02483045022100bd8c27473a5a82cc9085af4fd530ffbcb8642fda04689ac27ecefa01287f54e5022040af2daafaa1bedd6f80ee9d751cc88c12de8f8e65b33222c432d066c8cecbd801210314beffca49f214014cccdc0e1f7259aa1a5eeaaa34da1a4fd807e16fea3a86b000000000",
  "blockhash": "00000000000000000005304641c363ce12d8a2a3b98c81d6b8b721cb37f66dfa",
  "confirmations": 1999,
  "time": 1686278106,
  "blocktime": 1686278106
}
```

The owner of the first input is considered the owner / source of the transaction | `vin[0].prevout.hash[::-1]`

The first `vout` output `0` is the destination address for a transfer `"address": "bc1q4lwvx2380r4axmzgt8rnqxa5cvktt8unqlnka6"`

For mint and deploys `vout-0` is the minter/deployer address

The components of the multisig `ScriptPubKeys` are:

* `1`: This is the number of required signatures for the transaction to be valid. Always 1 (of 3) for SRC-20 (1 sigop)
* `03c46b73fe2ff939bea5d0a577950dc8876e863bed11c887d681417dfd70533e51`: This is the SRC-20 encoded data
* `039036c8182c70770f8f6bd702a25c7179bfff1ccb3a844297a717226b88b976cc`: This is the SRC-20 encoded data
* `020202020202020202020202020202020202020202020202020202020202020202`: This is the hash that must be to a valid keyburn address.
* `3`: This is the total number of public keys in the multisig script. Always (1 of) 3 for SRC-20
* `OP_CHECKMULTISIG`: opcode

We will also use an additional mulisig script in the decoding example below. Additional multisig scripts may be added depending on the length of the JSON string.

## Decoding the SRC-20 Bitcoin Transaction

Take the first two pubkeys from all present multisig scripts. In this example there are a total of 4 hex strings in the two scripts.

```
03c46b73fe2ff939bea5d0a577950dc8876e863bed11c887d681417dfd70533e51 039036c8182c70770f8f6bd702a25c7179bfff1ccb3a844297a717226b88b976cc
02dc054e58b755f233295d2a8759a3e4cbf678619d8e75379e7989046dbce16be3 02932b35a45d21395ac8bb54b8f9dae3fd2dbc309c24e550cf2211fe6aa897e5ca
```

First we strip the sign and nonce bytes (first and last bytes from each string) which leaves.

```
c46b73fe2ff939bea5d0a577950dc8876e863bed11c887d681417dfd70533e 9036c8182c70770f8f6bd702a25c7179bfff1ccb3a844297a717226b88b976
dc054e58b755f233295d2a8759a3e4cbf678619d8e75379e7989046dbce16b 932b35a45d21395ac8bb54b8f9dae3fd2dbc309c24e550cf2211fe6aa897e5
```

The strings are then concatenated and decoded using ARC4 decoding, which uses the `vin[0].prevout.hash[::-1]` as the signing key.

The output after ARC4 decoding is:

```
00457374616d703a7b2270223a227372632d3230222c226f70223a227472616e73666572222c227469636b223a225354455645222c22616d74223a22313030303030303030227d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
```

The first two bytes - in this example `0045` is the expected length of the decoded data in hex (less any trailing zeros) for data validation. This is required in order for the transaction to successfully parse and be indexed. Transactions without this value or a value that does not match the string length are considered invalid.

The next `7374616d703a` is the hexadecimal representation of `stamp:` in lowercase - this is required for a valid stamp SRC-20 transaction

The remaining string is the SRC-20 JSON data.

```
7b2270223a227372632d3230222c226f70223a227472616e73666572222c227469636b223a225354455645222c22616d74223a22313030303030303030227d
```

Which UTF-8 decodes to:

`{"p":"src-20","op":"transfer","tick":"STEVE","amt":"100000000"}`

In order to minimize the transaction size spaces are not used in the serialized JSON string which is constructed by the SRC-20 reference wallet.

## Compression

Compression and data serialization is supported in SRC-20 transactions. Previously SRC-20 was a JSON Strings encoded in BASE64 inside of a Counterparty issuance transaction. In some cases the json string was serialized and compression was utilized to minimize the size of the corresponding transaction. This is an important factor when indexing and validating prior SRC-20 transactions within Counterparty transactions, and will continue to be supported in current version SRC-20 transactions. However given the construction of the JSON string without spaces, and the fact that we are no longer encoding in BASE64 the transactißon size benefits are minimal. This must be taken into consideration when parsing for transactions on chain.

An example of the serialization and compression:

```PY

# Note this string has line breaks and spaces so serialization and compression is worthwhile especially given that it was encoded in BASE64 which is 2x the size. 
data = {
    "p": "src-20",
    "op": "mint",
    "tick": "STAMP",
    "amt": "100000"
}

# Serialize the JSON String
serialized_data = msgpack.packb(data)

# Compress the serialized data using zlib
compressed_data = zlib.compress(serialized_data)

```

## Indexing for SRC-20 Transactions

SRC-20 transactions may be indexed directly from BTC for validation. Prior to block 796,000 this can be accomplihed using Counterparty API's to pull transaction details from valid issuances with a numeric asset with a valid json string encoded in base64 with the multisig scripts to a valid keyburn address. All transacitons on and after block 796,000 must be parsed directly from a BTC node. The specifications above must be followed including valid json strings and a valid Bitcoin Stamp transaction prefixed by 'stamp:'

### Tick Length

Python sees the text length differently than Node.JS. In the following example we determine the char length using the python method.

Node: 'BULL🐂'.length = 6

Python: len('BULL🐂') = 5

## Base64 and other Decoding Anomolies

Python and Node.JS handle base64 decoding differently. Prior to block 796,000 for CP based transactions which were base64 encoded this can have an impact on valid/invalid transactions. After block 796,000 for direct to BTC transactions which are ARC4 encoded this does not have an impact.

For example:

Transaction: `c129cc8f13760fce63a42257dbe5dcdd0aad798f858f6b08968c7834c7a1bcc7`

With base64 string: `eyJwIjogInNyYy0yMCIsICJvcCI6ICJtaW50IiwgInRpY2siOiAiUElaWkEiLCAiYW10IjogIjExMTExIn0`

This string is considered invalid in Python using `base64.b64decode(base64_string)` and `pybase64.b64decode(base64_string)` and in bash `printf "%s" "{base64_string}" | base64 -d` because it is missing the end of line `=` for padding / newline. The original indexer was written in python with these 3 checks so it is deemed invalid even though Node.JS interprets this string properly. Padding was attempted in prior iterations to attempt to include improperly formatted base64 strings into BTC Stamps protocol however since it is not possible to properly determine the location for padding in all cases these were simply deemed invalid to remove malformed data.

Also, Transaction `f3a8df9f71bd195b43186c669666732fa86623e2d2f9633cf663b32e5e417b69` at the time of block 796000 was parsing as an SRC-20 transaction when pulled directly off Bitcoin. However on 3 Counterparty nodes the transaction parsed as shown below. Due to the requirements of SRC-20 Transactions being a valid counterparty transaction prior to the specified block this transaction was deemed invalid. This may be a bug in Counterparty which was unable to be addressed for final validation so this was excluded. This is documented for future indexing validation. The original transaction was a Bitcoin Stamp, however the same Counterparty asset name was used for the second transacion was intended to be a JSON string for a SRC-20 token. This is against protocol specifications where a previously existing stamp on the asset cannot be changed.

```
9575037|791071|insert|issuances|{"asset": "A5428699716173256069", "asset_longname": null, "block_index": 791071, "call_date": 0, "call_price": 0.0, "callable": false, "description": "STAMP:iVBORw0KGgoAAAANSUhEUgAAACgAAAA4BAMAAAB9BqfFAAAAJ1BMVEVIZZcqRnYNERg8Qj4gJSEiLEojOFsAAAD7AQkeGx7///+SoYxUaWqIxi3EAAABTklEQVQ4y73PsU7DMBQF0FSiA6MHilg7lA8IEhmRcCR+wIq8MpQvQE8xYxrFaVkzpBuVoAM7/B7XcRrH1EJMvapk++jd1zaaB3I6XD6GEDFOO+Uj+JqIdr0tgF0o3+bb+cI+otkB63yN0yKz5xPqyiEDA/O2/XCIYAW9aK03Xw6RS9p/a20XsNmAij439MaW5tUjM1gB2QgvMqL3I2wyJSrFfBRCNCX7jTKAEqN1CN1kNDHHlUDfIQIHCg8RU5ejnTbTbnLiY3SOpSX2eDiVmOxuYxQS6AXYiADiv/8XQ3UZ3BlGeYyNDKBoQ3X5B55xh2nTfxHng/LU/CTeB+87VHjalKIe0B6YzJ5LvuIPHmZ7oD+5SjOlfESAVKJsMY7jG3OpFK144tBwfLumIsFlwASfRBWFjgt+Dwf2KbR+Lez1gKhqjYaHWABy6NhhID/iStgdKGHcpQAAAABJRU5ErkJggg==", "divisible": false, "fee_paid": 0, "issuer": "1WweVUK8kLmSNt6yKKqwVxch3Z7Lw5HAY", "locked": true, "quantity": 100, "reset": false, "source": "1WweVUK8kLmSNt6yKKqwVxch3Z7Lw5HAY", "status": "valid", "transfer": false, "tx_hash": "934dc31e690d0237d8d0d6a69355a7448920dbd12ff21abf694af48cfb30d715", "tx_index": 2387617}|1684859820

9581330|791180|insert|issuances|{"asset": "A5428699716173256069", "asset_longname": null, "block_index": 791180, "call_date": 0, "call_price": 0.0, "callable": false, "description": "STAMP:iVBORw0KGgoAAAANSUhEUgAAACgAAAA4BAMAAAB9BqfFAAAAJ1BMVEVIZZcqRnYNERg8Qj4gJSEiLEojOFsAAAD7AQkeGx7///+SoYxUaWqIxi3EAAABTklEQVQ4y73PsU7DMBQF0FSiA6MHilg7lA8IEhmRcCR+wIq8MpQvQE8xYxrFaVkzpBuVoAM7/B7XcRrH1EJMvapk++jd1zaaB3I6XD6GEDFOO+Uj+JqIdr0tgF0o3+bb+cI+otkB63yN0yKz5xPqyiEDA/O2/XCIYAW9aK03Xw6RS9p/a20XsNmAij439MaW5tUjM1gB2QgvMqL3I2wyJSrFfBRCNCX7jTKAEqN1CN1kNDHHlUDfIQIHCg8RU5ejnTbTbnLiY3SOpSX2eDiVmOxuYxQS6AXYiADiv/8XQ3UZ3BlGeYyNDKBoQ3X5B55xh2nTfxHng/LU/CTeB+87VHjalKIe0B6YzJ5LvuIPHmZ7oD+5SjOlfESAVKJsMY7jG3OpFK144tBwfLumIsFlwASfRBWFjgt+Dwf2KbR+Lez1gKhqjYaHWABy6NhhID/iStgdKGHcpQAAAABJRU5ErkJggg==", "divisible": false, "fee_paid": 0, "issuer": "1NwCmg8gZW7KykrA7mX16zugNZZuckPg5o", "locked": true, "quantity": 0, "reset": false, "source": "1WweVUK8kLmSNt6yKKqwVxch3Z7Lw5HAY", "status": "valid", "transfer": true, "tx_hash": "f3a8df9f71bd195b43186c669666732fa86623e2d2f9633cf663b32e5e417b69", "tx_index": 2390355}|1684931053
```

## Example SRC-20 JSON Validation

If the JSON string is not valid including it will be rejected from the index. This is a sample of the validation script. Any SRC-20 transactions that do not pass this validation are considered invalid transactions and will not impact user balances. This is the current method used for the indexer validation of JSON strings. Anything that does not pass this check will not get a valid BTC Stamp number and will not be indexed as part of SRC-20.

```PY

tick_pattern_list = {
    regex.compile(r'((\p{Emoji_Presentation})|(\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?))|[\p{Punctuation}\p{Symbol}\w~!@#$%^&*()_=<>?]')
}

def matches_any_pattern(text, pattern_list):
    matched = True
    for char in text:
        char_matched = any(pattern.fullmatch(char) for pattern in pattern_list)
        if not char_matched:
            matched = False
            break
    return matched

def sort_keys(key):
    priority_keys = ["p", "op", "tick"]
    if key in priority_keys:
        return priority_keys.index(key)
    return len(priority_keys)

def check_format(src_input_json, block_index):
    try:
        input_dict = json.loads(src_input_json)
        print("checking format", input_dict)

        if input_dict.get("p") == "src-20" and block_index < src20blockend:
            tick_value = input_dict.get("tick")
            if not tick_value or not matches_any_pattern(tick_value, tick_pattern_list) or len(tick_value) > 5:
                print("EXCLUSION: did not match tick pattern", input_dict)
                return False

            deploy_keys = {"op", "tick", "max", "lim"}
            transfer_keys = {"op", "tick", "amt"}
            mint_keys = {"op", "tick", "amt"}

            input_keys = set(input_dict.keys())

            uint64_max = Decimal(2 ** 64 - 1)
            key_sets = [deploy_keys, transfer_keys, mint_keys]
            key_to_check = {"deploy_keys": ["max", "lim"], "transfer_keys": ["amt"], "mint_keys": ["amt"]}

            for i, key_set in enumerate(key_sets):
                if input_keys >= key_set:
                    for key in key_to_check[list(key_to_check.keys())[i]]:
                        value = input_dict.get(key)
                        if value is None:
                            print(src_input_json)
                            print(f"EXCLUSION: Missing or invalid value for {key}", input_dict)
                            return False

                        if isinstance(value, str):
                            try:
                                value = Decimal(''.join(c for c in value if c.isdigit() or c == '.')) if value else Decimal(0)
                            except ValueError:
                                print(src_input_json)
                                print(f"EXCLUSION: {key} not a valid decimal", input_dict)
                                return False
                        elif isinstance(value, int):
                            value = Decimal(value)
                        else:
                            print(src_input_json)
                            print(f"EXCLUSION: {key} not a string or integer", input_dict)
                            return False

                        if not (0 <= value <= uint64_max):
                            print(src_input_json)
                            print(f"EXCLUSION: {key} not in range", input_dict)
                            return False
            return True

    except json.JSONDecodeError:
        return False
```


# SRC20 on Fractal

SRC20 protocol on Fractal

## Fractal Bitcoin

[**Fractal Bitcoin**](https://www.fractalbitcoin.io/), the Bitcoin-native scaling solution designed to extend the power and potential of Bitcoin without compromising its core principles. By maintaining consistency with the Bitcoin mainnet and providing new tools for developers and miners, Fractal creates a robust environment for innovation that stays true to Bitcoin’s ethos of decentralization, security, and transparency.

The Fractal network has activated the `OP_CAT` opcode, unlocking significant potential for programmability across the entire network. The recently introduced [CAT20](https://catprotocol.org/cat20/) protocol takes full advantage of this feature, creatively developing a fungible token protocol validated by POW miners. This protocol not only serves as a practical smart contract use case within the Fractal ecosystem but also provides valuable insights for both Fractal and Bitcoin regarding the potential of `OP_CAT`.

## Extending SRC20 Protocol onto Fractal

Currently, the most prominent fungible token protocols on Bitcoin include BRC20, SRC20, ARC20, and RUNES. Notably, BRC20 was activated at block height 21,000 on the Fractal mainnet, and RUNES is set to activate at height 84,000. To further increase the impact of the SRC20 protocol and explore how `OP_CAT` can unlock new possibilities for its development, it is both logical and advantageous to extend the SRC20 protocol to the Fractal network.

## **SRC20 on Fractal**

The protocol specifications for SRC20 on Fractal are identical to those on Bitcoin, except for the ticker name length. For native SRC20 protocol details, please refer to: [SRC20 Specifications](https://github.com/stampchain-io/stamps_sdk/blob/main/docs/src20specs.md).

To prevent conflicts with existing assets on the Bitcoin mainnet, the SRC20 ticker naming rule on Fractal has been customized.

🔸 **SRC20 ticker names on Fractal must be between 6 and 12 characters. Tickers with fewer than 6 characters are not allowed, as they are already in use on Bitcoin's mainnet.**

**🔸 In addition to the rule mentioned above, SRC20 rules on Fractal are consistent with the** [**rules**](https://github.com/stampchain-io/stamps_sdk/blob/main/docs/src20specs.md) **on Bitcoin mainnet.**

## UTXO Model (under development)

Currently, SRC20 uses a pure account-based model. Compared to the UTXO model, the account model eliminates the risk of unintended asset transfers but does not benefit from the advantages offered by the UTXO model, such as a fully non-custodial P2P trade mode.

To retain the benefits of the account model while also taking advantage of the UTXO model’s convenience and exploring future possibilities on the Fractal network, we are researching how to extend the SRC20 protocol to the UTXO model on Fractal. The protocol will introduce the `attach` and `detach` operators, with the initial design described as follows:

1. **attach**
   * Bind a specified amount of tokens to a UTXO.
   * Example:

     ```json
     {
       "p": "src-20",
       "op": "attach",
       "tick": "STAMP",
       "amt": "100"
     }
     ```
2. **detach**
   * Unbind all assets from the transaction inputs and credit them to the account model.
   * Example:

     ```json
     {
       "p": "src-20",
       "op": "detach"
     }
     ```
3. **Account model transfer (same as the current SRC20 protocol on Bitcoin)**
   * Example:

     ```json
     {
       "p": "src-20",
       "op": "transfer",
       "tick": "STAMP",
       "amt": "100"
     }
     ```
4. **UTXO model transfer**
   * Transfer all bound assets from the transaction inputs to the first non-OP\_RETURN output UTXO.

**Pros and cons of the SRC20 protocol coexisting with both account and UTXO models:**

1. The SRC20 account model avoids unintended asset transfers.
2. The SRC20 UTXO model benefits from the network’s native validation and further potential with OP\_CAT activated networks.
3. Coexistence of account and UTXO models increases protocol complexity.
4. The UTXO model requires wallet support, or there is a risk of easily losing assets.

***


# SRC721 Protocol

SRC 721 Specification Designed by Derp & OpenStamp

> Source: <https://github.com/DerpHerpenstein/src-721>

## SRC-721 NFT Collection Specification

### Introduction

Stamps are very expensive and there needs to be an inexpensive way for users to mint higher resolution composable NFTs (like 10k pfp projects). SRC-721 specifies how to store all the art for a given collection as layers using the STAMPS protocol and have the user mint a small JSON file referencing data that was already stored on chain, in order to create an NFT composed from the aformentioned layers. By storing the layers individually it is possible to significantly reduce file size by using techniques like indexed color pallets for each layer. By stacking the images up it is possible to create a high quality visually appealing final product. By ensuring the user has to store less than 100 bytes on chain, the mint cost for this higher resolution NFT is significantly reduced.

Since the Stamps protocol is under active development and changes will occur causing reindexing of Stamp ID's this specification uses counterparty asset ID's to ensure that inevitable changes to the Stamps protocol do not impact asset references of deployed SRC-721 collections.

### Operations

SRC-721 transactions must conform to these **required** fields or the transaction will not be considered a valid SRC-721 transaction. Fields labeled optional can be omitted when not used.

#### DEPLOY

```
{
        "p": "src-721",
        "v": "2",
        "op": "deploy",
        "name": "Collection Name",      // The display name of the collection
        "symbol": "SYM",                // the symbol for the collection
        "price":"10000",                // price in sats, must be paid to the owner of the collection for a mint to be valid [optiona] 
        "description": "Description",
        "max": "2500",                   // maximum number of mints
        "lim": "1",                      // limit per mint [optional, default=1]
        "num": "1",                      // the maximum number of stamp with the same traits [optional, default=1]
        "wl": "1",                       // public(0)or whitelist(1) mint phase [optional, default=0]
        "mode": "1",                     //  traits allocation mode, random allocation(0) or authorized allocation(1) [optional, default=0]
        "operators": ["1ABC...321"],         // bitcoin addresses of the operators for whitelist mint [optional]
        "price": "200000",               // mint fee in satoshis [optional, default=0]
        "recipient": "1ABC...321",       // recipient address of mint fee. must exist and valid address if the price is not 0. 
        "type": "data:image/png;base64", // mime type of the images used in traits t0-tx
        "image-rendering":"pixelated",   // css property to ensure images are displayed properly [optional]
        "viewbox": "0 0 160 160",        // viewbox to properly see  traits t0-tx
        "icon": "A16308540544056654000", // CP asset for a collection icon [optional]
        // All t0-tx are optional if the reveal op is planned to be used
        "t0": ["A12430899936789156000", "A9676658320305385000"],    // up to x layers of stamp traits (references by CP asset#) containing
        "t1": ["A17140023175661332000", "A6689685157378600000"],    // transparency can be stacked on top of eachother to form a final image
        ...
        "tx": ["A12240402677681132000", "A4332886198473102000"]
}
```

#### REVEAL

```
{
    "p": "src-721",
    "v": "1",
    "op": "reveal",
    "symbol": "SYM",        // symbol [optional]
    "c":"A123456789",       // a pointer to the deploy collection json cp asset
    "sig": "a1b2...e8d9",   // signed hash of data object containing references to traits [optional] only needed if the sender is not the collection owner
    "data":{
       "s": ["seed0", "seed1", ... "seedx"]                         // seed used for the deterministic generation of traits [optional]
        "t0": ["A12430899936789156000", "A9676658320305385000"],    // up to x layers of stamp traits (references by CP asset#) containing
        "c0": ["1000", "10000"],                                    // coefficients used to select t0 traits per tokenId [optional]    
        "t1": ["A17140023175661332000", "A6689685157378600000"],    // transparency can be stacked on top of eachother to form a final image
        "c1": ["4000", "10000"],                                    // coefficients used to select t1 traits per tokenId [optional]     
        ...
        "tx": ["A12240402677681132000", "A4332886198473102000"],
        "cx": ["7000", "10000"],                                    // coefficients used to select tx traits per tokenId [optional]     
    }
}
```

#### MINT

```
{
    "p": "src-721",
    "op": "mint",
    "symbol": "SYM",      // symbol [optional]
    "c":"A123456789",     // a pointer to the deploy collection json cp asset
    "sig": "1234...abcd", // used for a permissioned mint signed(sha256(num+JSON.stingify(ts)+userAddress)) [optional]

    "ts":[0,1,...,y]    // an array with x length wherein each item
                        // represents the index of the trait to use
                        // from the deploy mechanism
}
```

#### UPDATE - updates mutable properties of deploy

```
{
    "p": "src-721",
    "op": "update",
    "operators": ["1ABC...321"], // the bitcoin address of the new operators [optional]
    "price":"10000",             // the price for the mint in satoshis [optional]
    "recipient": "1ABC...321",   // mint fee recipient address [optional]
    "wl": "1",                   // public(0) or whitelist(1) mint phase [optional]
    "mode": "1",                 //  traits allocation mode, random allocation(0), authorized allocation(1),user allocation(2) [optional]
}
```

#### MINT a single item (not part of a collection)

It may be desireable to mint a single NFT (that is not part of a collection) based on various on chain assets. This can be done by omitting the symbol field and using counterparty asset IDs instead of index's

```
{
    "p": "src-721",
    "op": "mint",
    "ts":["A12430899936789156000", .., "A17140023175661332000"]    
                        // an array with x length wherein each item
                        // represents the CP asset ID 
}
```

#### TRANSFER and USE

SRC-721 transactions are valid counterparty assets and can be use as such.

### Design Philosophy

#### Target

1. Uniform Indexer: Develop a comprehensive, standardized SRC721 indexing algorithm.
2. Flexible Mint Mode: Offer an array of versatile minting modes that are both combinable and interchangeable.
3. Real-time Validation: Ascertain the validity of a mint transaction immediately upon its confirmation.

#### Roles

1. Owner: The address that holds the collection deployment stamp. The owner changes as the stamp is transferred.
2. Operator: The address executes delegated mint through providing signature or directly mint. The primary function is for the owner to delegate the mint service to handle project issuance.

#### Authority Operations

1. Change Parameters: The owner has the ability to initiate a protocol operation to modify the operator, mint price, recipient, mint phase, and mint mode.
2. Generate Reveal Signature: The owner signs the hash(traits data objects) to obtain a signature. If the first input of the transaction is the owner, no signature is required.
3. Generate Mint Signature: The operator signs the sha256(JSON.stingify(ts)+userAddress) to obtain a signature. sha256 should be a hex string. For random mints: sign sha256(userAddress). If two or more wl mints for an address exist, sign the hashes of the address accordingly sha256(sha256(userAddress)).

#### Sale Mode

1. Public Sale: Any address can participate in minting.
2. Whitelist Sale: Only authorized addresses are allowed to mint.

#### Traits Allocation Mode

There are two main mint modes for traits allocation,

1. Authorized allocation: A mint transaction, which is either initiated by the operator or containing the operator's signature, incorporates the relevant traits. ts must be present, 3 or more UTXOs
2. Random allocation: the reveal function outlines the traits distribution. ts is ignoted, 2 or more UTXOs
3. User allocation: A mint transaction initiated by the user that incorporates the relevant traits. ts must be present, 3 or more UTXOs

#### Additional Notes

1. Token ID: If a Token ID is required, it is assigned in the order of valid minting. However, if a Token ID is added in the mint JSON, it would be difficult to effectively implement the combination and switching of mint modes. So it is not a good design to contain the Token ID in the mint json.
2. NUM: The maximum number of stamp with the same traits. In order to allow for the existence of Images with the same traits within a collection and prevent multiple mints with the same signature from a single address, we have introduced a variable called "num" to represent the maximum quantity of Images with the same traits. Additionally, the signature data needs to include an indication of which numbered Image with the same traits it corresponds to. If the value of "num" in the deploy JSON is N, then the range of "num" in the signature data is \[0, N-1].

### Mint Modes Combination

Based on the Sale Mode and Traits Allocation Mode, 4 minting modes can be combined, and these 4 modes can be switched interchangeably.

**Note: Signatures can be omitted when a dust input from the owner or operator is present.**

#### Whitelist Sale with Authorized Traits Allocation

```
{
    "p": "src-721",
    "op": "mint",
    "c": "A123456789",   
    "ts": [0,1,...,y],
    "d":["d0","d1".."dy"],// [optional, used to attach data to this nft]
    "sig": "1234...abcd"  // signed(sha256(JSON.stingify(ts)+userAddress)). The signature field is not required if the sender is the operator. 
} 
```

MultiSig UTXO Amount: at least 3

#### Whitelist Sale with Random Traits Allocation

```
{
    "p": "src-721",
    "op": "mint",
    "c": "A123456789",   
    "d":["d0","d1".."dy"],// [optional, used to attach data to this nft]
    "sig": "1234...abcd" // signed(sha256(userAddress)). The signature field is not required if the sender is the operator
}  
```

MultiSig UTXO Amount: at least 2

#### Public Sale with Authorized Traits Allocation

```
{
    "p": "src-721",
    "op": "mint",
    "c": "A123456789",   
    "ts": [0,1,...,y],
    "d":["d0","d1".."dy"],// [optional, used to attach data to this nft]
    "sig": "1234...abcd"  // signed(sha256(JSON.stingify(ts)+userAddress)). The signature field is not required if the sender is the operator
} 
```

MultiSig UTXO Amount: at least 3

#### Public Sale with Random Traits Allocation

```
{
    "p": "src-721",
    "op": "mint",
    "c": "A123456789",
    "amt": "1"          // [optional, default=1]
    "d":["d0","d1".."dy"],// [optional, used to attach data to this nft]
} 
```

MultiSig UTXO Amount: at least 2

### Indexer

#### How indexer validates a valid mint?

1. The "c" field must point to a valid SRC721 Collection.
2. The collection is not fully minted yet.
3. If the price is not 0, the mint transaction should include an output whose amount is equal to or greater than the price to the recipient.
4. If mode=1 or wl=1(Whitelist Sale or Authorized Traits Allocation), the signature (sig) in the mint json must be unique, or signature can be omitted with a dust input from the owner/operator
5. If mode=1(Authorized Traits Allocation), then the sender needs to either be the operator or the mint json has a correctly signature signed(sha256(JSON.stringify(ts)+userAddress)).
6. If mode=0 and wl=1(Whitelist Sale with Random Traits Allocation), then the sender needs to either be the operator or the mint json has a correctly signature signed(sha256(userAddress)).

### SRC-721 Token Requirements

1. Tokens must be 1-10 characters in length.
2. Allowed characters: a. Any word character (alphanumeric characters and underscores) b. Special characters: \~!@#$%^&\*()\_+=<>? c. Most printable emojis in U+1F300 to U+1F5FF
3. Disallowed characters: a. Non-printable Unicode characters b. Quotation marks: " \` ' c. Special characters not present in 2c
4. Only numeric values are allowed in the "max", "lim" fields
5. Other Qualifications:
   * CP Asset must be locked, and multisig dust assigned to qualified burn address For more details on "KeyBurn" see: <https://github.com/mikeinspace/stamps/blob/main/Key-Burn.md>
   * CP Asset for deploy must be value 1, nondivisible
   * CP Asset value for mint must be less than or equal to lim
   * not case sensitive DOGE=doge
   * max lim amount: uint64\_max 18,446,744,073,709,551,615 (**commaas not allowed**, here for readability only)
   * json strings are not order sensitive
   * json strings are not case sensitive

**INVALID** tokens will not be created in the Bitcoin Stamps Protocol index or API, and the transaction will not be considered a valid SRC-721 transaction. Any further modifications to the standard must be designed around backwards compatibility.

### Allowed Unicode Chars

Emoji\_Presentation: This property includes all characters that are defined as emojis and have a distinct emoji-style appearance. These characters are intended to be displayed as colorful pictographs, rather than black-and-white text symbols. Examples include face emojis (😀, 😂, 😊), objects (🚗, 🌍, 🍕), and symbols (❤️, 🚫, ⏰).

Emoji\_Modifier\_Base: This property consists of characters that can be modified by emoji modifiers, such as skin tone modifiers. These characters usually represent human-like figures (e.g., 👩, 👨, 🤳) and can be combined with emoji modifiers to represent variations in skin tone or other attributes.

Emoji\_Modifier: This property contains characters that can be used to modify the appearance of other emojis, particularly the ones classified as Emoji\_Modifier\_Base. The most common example is the skin tone modifiers (🏻, 🏼, 🏽, 🏾, 🏿) that can be applied to human-like emojis to represent different skin tones.

### Excluded Unicode Chars

These chars are excluded from the allowed chars list because they are not printable, and are not allowed in any field. Tokens with these chars will not be created in Bitcoin Stamps Protocol index or API, and the transaction will not be considered a valid SRC-721 transaction.

Emoji\_Component: Characters that are used to create more complex emojis, such as skin tone modifiers and hair components. These characters are not emojis on their own but can be used with other emojis.

Extended\_Pictographic: This includes additional pictographic characters not covered by Emoji\_Presentation but can still be considered emojis.


# RGB++ Protocol

RGB++ Protocol

{% content-ref url="/pages/zxTaH4lteI7AED1yyIJk" %}
[RGB++ Light Paper(EN)](/introduction/rgb++-protocol/rgb++-light-paper-en)
{% endcontent-ref %}

{% content-ref url="/pages/NlHZLq88OGS4KqBCtos5" %}
[RGB++ Light Paper(CN)](/introduction/rgb++-protocol/rgb++-light-paper-cn)
{% endcontent-ref %}

{% content-ref url="/pages/tuMVXQwwlgQhrQ0ewVuY" %}
[RGB++ Specification(CN)](/introduction/rgb++-protocol/rgb++-specification-cn)
{% endcontent-ref %}


# RGB++ Light Paper(EN)

RGB++ Protocol Light Paper (EN)

> Source: <https://github.com/ckb-cell/RGBPlusPlus-design/blob/main/docs/light-paper-en.md>

## **Introduction**

RGB++ is an extended RGB protocol by using single-use seals and client-side validation techniques to manage state changes and transaction verification. It maps the UTXO set of Bitcoin to the Cell of Nervos CKB via isomorphic bindings, and leverages scripting constraints on both CKB and Bitcoin chains to ensure the correctness of the state computations and the validity of the change ownership.

Addressing technical challenges encountered in the implementation of the original RGB protocol, RGB++ brings a wide array of new possibilities including client-side validation, transaction folding, shared state across contracts, non-interactive transfers, and more. It introduces Turing-complete smart contract scalability and performance to Bitcoin without the need for cross-chain transactions and without compromising security.

#### **Single-Use Seals**

The concept of **single-use seals** was [first introduced by Peter Todd in July, 2016](https://petertodd.org/2016/state-machine-consensus-building-blocks). It allows for a lock of an electronic seal on a message, ensuring that the message can only be used once. Specifically, Bitcoin’s Unspent Transaction Outputs (UTXOs) can server as seals for messages, and the Bitcoin system’s consensus mechanism ensures that these UTXOs can only be spent once, meaning that these seals can only be opened once.

The RGB protocol uses single-use seals, which is based on Bitcoin UTXOs, to map RGB state changes to Bitcoin UTXOs ownership. This allows the Bitcoin system to guarantee ownership of the RGB state, as well as traceability of all state changes through the UTXO history. With single-use seals, the RGB protocol inherits Bitcoin's double spending protection and transaction traceability, both enforced by Bitcoin's consensus mechanism.

#### **Client-side Validation**

The RGB protocol contains user state that cannot be directly verified by the Bitcoin consensus. This requires users to utilize off-chain computation to validate that RGB state changes meet expectations. Client-side validation enables users to only validate the relevant UTXO branch history, rather than irrelevant ones. RGB ‘s state security is provided through client-side validation without reliance on any centralized third party.

#### **Problems with the RGB Protocol**

While the RGB protocol has many advantages, especially in providing Bitcoin with virtually uncompromising contract extensions, there are several technical and product issues in practice.

**DA Issues**

**DA(Decentralized Authentication)** refers to whether the average user can generate or obtain proof of transaction history. When using a simple client-side product, average users lack the ability or resources to store full historical transaction data, making it difficult to provide cryptographic proof of transactions to counterparties.

**P2P Network Issues**

As an extension of Bitcoin, RGB transactions rely on a P2P network for propagation. Users also need to interact with each other when transferring money, for example, recipients need to provide receipts. This introduces dependencies on a P2P network that is independent of the Bitcoin network.

**Virtual Machines and Contract Languages Immaturity**

The RGB protocol currently uses AluVM as its primary virtual machine. As a new model, AluVM lacks mature development tools and code examples for practice.

**Problems of Shared States and Unhosted Contracts**

The RGB protocol presently lacks sophisticated solution for the interaction of unhosted contracts, which limits multi-party interactions to realize.

#### **RGB++ isomorphic bindings**

<figure><img src="/files/6SykdSE5thaIds7d39dm" alt=""><figcaption></figcaption></figure>

RGB++ uses isomorphic bindings to solve the problems encountered by the RGB protocol and unlock more possibilities. In RGB, the two most important components are UTXOs, determining ownership, while commitments manage state and single-use seals. In contrast, RGB++ leverages isomorphic bindings to map Bitcoin UTXOs to Nervos' Cell, ensuring ownership synchronization through the utilization of Bitcoin's UTXO locking scripts. Meanwhile, the state maintenance is managed by the data and type fields of Nervos Cells.

#### **Blockchain Enhanced Client-side Validation**

All RGB++ transactions undergo synchronization, resulting in one transaction on both the BTC and CKB chains. The former is compatible with RGB protocol transactions, while the latter serves to replace the client-side validation process. Users only need to check the corresponding transaction on CKB to verify whether the state of the RGB++ transaction is correct.

Also, users also have the option not to use the transactions on the CKB chain as the basis for verifications. By utilizing the local historical transaction information of UTXO, users can independently verify the RGB++ transaction from the CKB chain (note: some functions, such as transaction folding, still need to rely on the block header hash of CKB for anti-double-spending verification).

## **RGB++ Transaction Process**

<figure><img src="/files/Wbw71ley80iwtoA0KfkQ" alt=""><figcaption></figcaption></figure>

#### **Off-chain Computation**&#x20;

* Select the next **Single-Use Seals to be used**, e.g. btc\_utxo#2;
* Perform off-chain computation to generate an RGB++ transaction (**`CKB_TX_B`**) that will be sent to the CKB;
* Get off-chain calculation: **`commitment = hash(CKB_TX_B | btc_utxo#1 | btc_utxo#2)`**.

#### **BTC Transaction Submission**

Generate and broadcast a Bitcoin transaction (**`Bitcoin_TX_A`**), input **`btc_utxo#1`** for consumption, outputting the above commitment via OP\_RETURN.

#### CKB Transaction Submission

* Broadcast the CKB transaction (**`CKB_TX_B`**) mentioned above;
* The user's latest state is maintained by **`CKB_TX_B.output.data`**;
* The next state change requires the use of **`btc_utxo#2`** and **`CKB_TX_B.output`**;

#### **On-chain Validation**

* UTXOs related to Bitcoin validations can only be spent once by a given user;
* A lightweight client on CKB validates the presence of relevant Bitcoin transactions on the Bitcoin chain;
* Bitcoin's related transactions are submitted as witnesses in the CKB transaction for verification;
* CKB then verifies that the BTC transaction spent the correct UTXO;
* CKB further verifies that the BTC transaction commits to the correct commitment;
* CKB verifies that the on-chain state transition complies with the predefined contract rules.

### **RGB++ Client**

In contrast to the RGB protocol, all RGB++ transactions are on CKB and are validated by CKB script constraints. Therefore, RGB++ doesn't require a standalone client; users only need to access Bitcoin and CKB light client to verify all transactions. The CKB light client employs he PoW algorithm to verify all historical transactions and states with just a few recent block headers, which in turn facilitates the use of isomorphic bindings for verifying all RGB++ transactions.

## **Transaction Folding**

The RGB++ protocol uses isomorphic bindings between Bitcoin UTXOs and CKB Cell, enabling the implementation of Turing-complete Bitcoin UTXO transactions validated by CKB Cell. Specifically, by further leveraging the programmable capabilities of CKB Cells, multiple CKB transactions can be corresponded with a single Bitcoin RGB++ transaction. This approach allows the low speed, low throughput Bitcoin chain to benefit from higher scalability with the high performance CKB chain.

<figure><img src="/files/d5CbVGd5ViVklahcR5qL" alt=""><figcaption></figcaption></figure>

## **Shared State and Unhosted Contracts**

### Mediocre Implementation of Shared State

Shared state has always been a challenge in UTXO systems. Here, we will first discuss a mediocre implementation that does not consider simultaneous updates to the shared state by multiple parties. Then, we will delve into a more practical solution that allows multiple parties to operate on the shared state simultaneously.

Consider a global state cell on the CKB that manages the state shared by multiple users. Typically, it could be a staking contract for an algorithmic stablecoin, where users deposit volatile assets and receive a deposit proof. The global state is managed by an unhosted contract, meaning anyone can make changes to the state without requiring specific digital signatures from designated signatories. The implementation of an unhosted contract plays a crucial role in the decentralization and censorship resistance of the protocol.

A mediocre implementation in this context means that there is a risk that the Global state Cell is occupied by another user, causing CKB TX fail because the specified Global state utxo does not exist. As the Bitcoin TX needs to be sent out and computed into the commitment before the CKB TX, subsequent validation becomes impossible.

### **The Issue of State Contentions in Shared States and Solutions**

To address the above problem, we introduce the Intent Cell as an intermediary. Users can deterministically write down actions they wish to execute into the Intent Cell, which can interact with the global state Cell through the collaboration of a third-party aggregator, batch processing multiple parties’ intent and merging the results of the interaction into a standard shadow cell.

## **Non-Interactive Transfers**

One issue with the RGB protocol is receivers needs to provide a live UTXO as an invoice to initiate a transfer. This requires recipients stay online to complete a transaction, which increases the complexity for both user understanding and products. Instead, RGB++ leverages the Turing-complete environment by placing the interaction behavior in a CKB environment, and providing a two-step approach of send-receive to implement non-interactive transfer.

### **Send**

When user A sends assets to user B, user A only needs to know user B's address - transferring funds to that address in the RGB++ transaction without requiring user B to provide any UTXOs or invoices.

<figure><img src="/files/MnY1tY2wEAS0ZkQ4xxPM" alt=""><figcaption></figcaption></figure>

### **Receive**

<figure><img src="/files/dTp9j3kRKcazpUfCNfr5" alt=""><figcaption></figcaption></figure>

The CKB lock contract has the ability to validate the digital signature of the BTC address. Therefore, the receiver can formulate a Tx C on CKB to unlock the corresponding CKB Cell and transfer the assets to their own utxo#2. This finalizes the non-interactive collection process.

## Coins

Issuing fungible assets on RGB++ requires corresponding data structure standards and consistency verification standards. We can adopt the [xUDT standard on CKB](https://talk.nervos.org/t/rfc-extensible-udt/5337) as the isomorphic binding protocol.

### **Issuance**

There are many ways to issue fungible assets on RGB++, including but not limited to centralized distribution, airdrops, and subscriptions. The total supply of tokens can be either uncapped or pre-capped. For pre-capped tokens, a state sharing scheme can be employed during each issuance to validate that the total issued amount remains less than or equal to the preset cap.

### **Transfer**

Transferring RGB++ coins is a straightforward process, involving mapping the recipient and remaining UTXO balances to the shadow cell of CKB. Also, transferring coins can be streamlined exclusively on CKB through transaction foldings. After multiple transactions are completed, the final results will be committed to BTC.

<figure><img src="/files/YMGBbtBOi04kasanAzP0" alt=""><figcaption></figcaption></figure>

### Privacy

The xUDT protocol is a transparent token protocol. To enhance the privacy-preserving features of RGB++ coins, we can explore token protocols that offer both amount privacy and flow privacy. For instance, the bulletproof algorithm can be employed to transform the content in data into a blinded amount, with a zero-knowledge proof demonstrating the consistency and non-negativity of the amount in each transfer transaction. This ensures that only the parties involved in a transaction possess knowledge of the specific amount in the transaction, preventing third-party observers from accessing the date of amount.

Additionally, ring signatures can be used torealize the blinding of the transfer flow. The user's coins are transferred to the ring signature obfuscator on CKB and then redirected back to the address managed by the Bitcoin UTXO. This strategy hides the historical trace of capital flow, thereby achieving enhanced privacy protection for the address.

## NFTs

### Issuance

Issuing NFT assest on RGB++ can also utilize existing CKB NFT standards, including but not limited to the [Spore Protocol](https://spore.pro/), mNFT, and [CoTA protocol](https://talk.nervos.org/t/rfc-cota-a-compact-token-aggregator-standard-for-extremely-low-cost-nfts-and-fts/6338). Taking Spore Protocol as an example, it stores all metadata on-chain, achieving 100% security in data availability. The CoTA protocol, on the other hand, is a compact token aggregator standard which compresses NFT information and holds data in 32-byte SMTs, providing ultimate cost advantages.

### **Transfer**

The transfer of NFTs in RGB++ is also very simple, similar to a coins transfer with no change.

## **Lightning Network Connectivity**

RGB, functioning as a client-side authentication protocol, inherently supports state channels and the Lightning Network. However, due to Bitcoin's scripting limitations, it is very challenging to run non-BTC Lightning networks on the Bitcoin blockchain. By adopting the RGB++ protocol, we can leverage CKB's Turing-complete scripting system to implement state channels and Lightning networks specifically for RGB++ assets. Such technology holds significant commercial potential. For example, a stablecoin payment system built on the Lightning Network can deliver cost and performance advantages that surpass those offered by centralized systems while guaranteeing decentralization and censorship resistance.

## **Examples of Applications**

### Airdrop

Given a list of addresses and corresponding amounts, we can implement a complete airdrop application using RGB++. Assuming that both the pending airdrop data and the claimed address list are stored in cell data as SMT, users can easily collect airdrops from their own addresses.

### DEX & AMM

RGB++ optimizes the UTXO structure, facilitating seamless support for UTXO-based asset exchange protocols without the need for intermediaries. Additionally, RGB++ adopts a grid trading design to enhance its Automated Market Maker (AMM) model. In comparison to Uniswap's AMM model, the grid trading model offers enhanced customization and suitability for trading UTXO-based assets.

<figure><img src="/files/UX5Tk0xlw2WcxOltNn2d" alt=""><figcaption></figcaption></figure>

The example above illustrates a scenario where a buyer is executing a purchase using $BTC in response to a seller's pending order for RGB++ xudt. As the transaction structure involves the buyer's utxo, containing sufficient amount of $BTC and a PBST signature, the buyer can creates a CKB transaction that meets the seller’s requirements. Afterwards, the buyer sends this signed CKB transaction to the seller. The seller then submits the BTC transaction and CKB transaction on-chain, one after the other, to complete the trade.

## **Summary**

RGB++ inherits the core idea of the RGB protocol while adopting a different virtual machine and validation scheme. Users can independently validate transactions by accessing Bitcoin and CKB light nodes, without needing a separate RGB++ client. In general, RGB++ brings Turing-complete contract scalability and achieves over ten times [performance scaling](https://www.ibm.com/docs/en/zos/2.1.0?topic=storage-tape-capacity-performance-scaling) to Bitcoin. Notably, instead of using cross-chain bridges, RGB++ implements native client-side validation for enhanced security and censorship resistance.


# RGB++ Light Paper(CN)

RGB++ Protocol 白皮书

> Source: <https://github.com/ckb-cell/RGBPlusPlus-design/blob/main/docs/light-paper-cn.md>

## 简介

RGB++ 是一个基于 RGB 的扩展协议，利用一次性密封条和客户端验证技术来管理状态变更和交易验证。它通过同构绑定将比特币 UTXO 映射到 Nervos CKB 的 Cell 上，并利用 CKB 链和 Bitcoin 链上的脚本约束来验证状态计算的正确性和变更所有权的有效性。RGB++ 解决了原 RGB 协议在实际落地中的技术问题，并提供了更多的可能性，如区块链增强的客户端验证、交易折叠、共享状态与无主合约、非交互式转账等。它比特币带来了无须跨链、不损失安全性的图灵完备合约扩展和性能扩展。

#### 一次性密封

一次性密密封的概念最早由 [Peter Todd 在 2016 年](https://petertodd.org/2016/state-machine-consensus-building-blocks)提出，它允许你对一条消息锁上一个电子密封条，确保这条消息只能被使用一次。具体来说，我们可以使用比特币的未花费的交易输出（UTXO）作为消息的密封条，比特币系统的共识机制可以确保这些 UTXO 仅能被消费一次，也即这些密封条仅能被打开一次。

RGB 协议利用这种基于比特币 UTXO 的一次性密封条，将 RGB 状态变更与比特币 UTXO 的所有权对应。因此比特币系统确保了 RGB 的状态所有权，以及可以通过 UTXO 历史来追溯所有的状态变更。一次性密封为 RGB 协议提供了由 Bitcoin 共识保障的防双花安全和交易分支追溯功能。

#### 客户端验证

RGB 协议包含的用户状态无法由比特币共识直接验证，用户必须通过链外计算确保 RGB 的状态变更符合预期。客户端验证技术允许用户只需要验证与自己有关的 UTXO 分支历史，而无需关心与自己无关的交易历史。RGB 的状态安全性通过客户端验证方式保障，不依赖任何中心化第三方。

#### RGB 协议的问题

尽管 RGB 协议有非常多的优势，尤其它可以为 Bitcoin 提供几乎不妥协的合约扩展，但在实际应用中依然存在多个技术和产品问题。

**DA 问题**

普通用户如何生成或获取交易历史的证明。普通用户使用简单的客户端产品时，并没有能力或资源保存所有的历史交易，也因此难以向交易对手方提供交易证明。

**P2P 网络问题**

RGB 交易作为 Bitcoin 的扩展交易，需要依赖一个 P2P 网络进行传播。用户之间在进行转账交易时，也需要进行交互式操作，接收方需要提供收条。这些都依赖一个独立于 Bitcoin 网络的 P2P 网络。

**虚拟机与合约语言**

RGB 协议的虚拟机目前主要是采用了 AluVM，作为新的虚拟机，目前缺乏完善的开发工具和实践代码。

**无主合约问题**

RGB 协议目前尚无完善的无主合约（公共合约）的交互方案。这导致多方交互难以实现。

#### RGB++ 同构绑定

<figure><img src="/files/19pqctnVFH0HgGKmkII6" alt=""><figcaption></figcaption></figure>

RGB++ 通过同构绑定技术解决了 RGB 协议遇到的问题，并赋予了 RGB 更多的可能性。在 RGB 协议中，最重要的两个组件是用来做所有权认定的 UTXO 和用来做状态管理与一次性密封的 commitment。RGB++ 的同构绑定将其中的 Bitcoin UTXO 一一映射到 CKB 的 Cell 上、使用 bitcoin utxo lock 来实现所有权同步，并使用 cell 的 data 和 type 来实现状态的维护。

#### 区块链增强客户端验证

所有的 RGB++ 交易都会在 BTC 和 CKB 链上同步各出现一笔交易。前者与 RGB 协议的交易兼容，后者则取代了客户端验证的流程，用户只需要检查 CKB 上的相关交易即可验证这笔 RGB++ 交易的状态计算是否正确。但用户也可以不使用 CKB 链上的交易作为验证依据，利用 UTXO 的局部历史交易信息，用户可以脱离 CKB 链独立地对 RGB++ 交易进行验证（交易折叠等部分功能仍然需要依赖 CKB 的块头哈希做防双花验证）。

## RGB++ 交易流程

<figure><img src="/files/A4Uc3I1x592VYkvd5DeK" alt=""><figcaption></figcaption></figure>

#### 链外计算

* 选中下一次要使用的一次性密封条，例如 btc\_utxo#2
* 链外计算并生成一笔将要发送到 CKB 上的 RGB++ 交易: CKB\_TX\_B
* 链外计算 `commitment = hash(CKB_TX_B | btc_utxo#1 | btc_utxo#2)`

#### BTC 交易提交

* 生成并发送一笔比特币交易 Bitcoin\_TX\_A, 输入消耗 `btc_utxo#1`，输出通过 OP\_RETURN 加入上面的 commitment

#### CKB 交易提交

* 发送上述 CKB 交易 CKB\_TX\_B
* 用户的最新状态由 `CKB_TX_B.output.data` 维护
* 下一次变更状态需要使用 `btc_utxo#2`、`CKB_TX_B.output`

#### 链上验证

* Bitcoin 验证相关的 utxo 只能被指定用户花费一次
* CKB 上存在 Bitcoin 的轻客户端，它可以验证 Bitcoin 上的相关交易存在 Bitcoin 链上
  * Bitcoin 的相关交易作为 ckb 交易的 witness 被提交上来，协助验证
* CKB 进一步验证该 btc 交易花费了正确的 utxo
* CKB 进一步验证该 btc 交易承诺了正确的 commitment
* CKB 验证 CKB 上的状态转移符合预订的合约规则

### RGB++ 客户端

不同于 RGB 协议，RGB++ 的所有交易都在 CKB 上并由 CKB 脚本约束验证，因此 RGB++ 无须独立客户端，用户只需要访问 Bitcoin 和 CKB 轻客户端即可验证所有交易。其中 CKB 轻客户端同样使用 PoW 算法可以实现最近的若干个块头即可验证所有历史交易和状态，进而利用同构绑定验证 RGB++ 的所有交易。

## 交易折叠

RGB++ 协议将 Bitcoin UTXO 与 CKB Cell 进行同构绑定，实现了 CKB Cell 验证支持的图灵完备 Bitcoin UTXO 交易。如果我们进一步利用 CKB Cell 的可编程能力，那么我们可以将多笔 CKB 交易与一笔 Bitcoin RGB++ 交易对应，这样就可以将低速低吞吐量的 Bitcoin 链使用高性能的 CKB 链进行扩容。

<figure><img src="/files/EjAuLwiqBOqQmFeb8jNh" alt=""><figcaption></figcaption></figure>

## 共享状态与无主合约

### 共享状态的平庸实现

共享状态一直是 UTXO 系统的难题，这里先讨论一种不考虑多人同时更新共享状态的平庸实现，再进一步讨论实际会采用的允许多人同时操作共享状态的解决方案。

考虑 CKB 上存在一个全局状态的 Cell，用来管理多用户共享的状态。典型地，它可以是一个算法稳定币的质押合约，用户将波动资产存入，并获得一个存款证明。全局状态由无主合约管理，所谓无主合约指的是任何人在满足合约的约束前提下都可以对状态进行变更，而不要求指定的数字签名提供方进行变更。无主合约的实现对协议的去中心化和抗审查有决定性的作用。

这里的平庸实现指的是 Global-state cell 有被其他用户占用的风险，这样 CKB TX 就会因为指定的 Global state utxo 不存在而无法成立。而 Bitcoin TX 需要先于 CKB TX 发送出来、并将其计算到 commitment 中，因此也无法进行后续的验证。

### 共享状态的状态争抢问题与解决方案

为了解决上述问题，我们引入了 Intent Cell 作为中介。用户将自己希望执行的动作确定性地写入 Intent Cell，后者则可以通过第三方聚合器的协作与全局状态 Cell 交互，批量将多方的 intent 进行计算，并将交互结果合并到标准的 shadow cell 上。

## 非交互式转账

原始 RGB 协议的一个问题是收款方需要提供一个自己的 live utxo 作为 invoice 才能实施转账，这种方式要求收款方必须在线才能完成一笔普通的交易，增加了用户理解难度和产品复杂度。RGB++ 可以利用图灵完备环境的优势，将交互行为放置在 ckb 环境里面，采用发送-领取两步操作来实现非交互式转账逻辑。

### 发送

用户 A 向用户 B 发送资产时，只需要获知 B 的地址，并在 RGB++ 交易中向该地址转账，而不需要收款人提供 utxo 或 invoice。

<figure><img src="/files/mJInsNZfX2W4Kzdrzwmq" alt=""><figcaption></figcaption></figure>

### 领取

<figure><img src="/files/2CX56YSN8nYj9pnDaoaQ" alt=""><figcaption></figcaption></figure>

CKB 的 lock 合约有能力验证 btc 地址对应的数字签名，因此接收方可以在 CKB 上构造 Tx C 来解锁对应的 CKB Cell，并将资产转移到自己的 utxo#2 上。从而完成了非交互式收款。

## Coins

RGB++ 上的 fungible 资产发行需要对应的数据结构标准和一致性验证标准。我们可以使用 ckb 的 xudt 标准作为它的同构绑定协议。

### 发行

RGB++ coins 的发行有很多种方式，包括并不限于中心化分发、空投、认购等方式。代币的总量也可以选择不设上限和预设上限两种。对于预设上限的代币，可以使用状态共享方案在每次发行时验证已发行总量小于等于预设上限。

### 转移

RGB++ coins 的转移非常简单，只需要将收款方和找零 utxo 分别对应到 ckb 的 shadow cell 即可。coins 的转移也可以通过交易折叠的方式只发生在 CKB 上，多笔交易后再将最后结果 commit 到 BTC 上。

### 隐私

xudt 是一个透明的代币协议，我们也可以采用支持金额隐私和流向隐私的代币协议来强化 RGB++ coins 的隐私保护特性。例如，我们可以使用 bulletproof 算法，将 data 中的内容变成盲化金额，并在每次转让的交易中提供金额一致且非负的零知识证明。这样，只有交易当事人知道当前交易的具体金额信息，第三方观察者无法获知金额数据。

此外，我们还可以使用环签名实现转账流向的盲化。用户的 coin 在 CKB 上转账给环签名混淆器，然后再回流到由 bitcoin utxo 管理的地址上。通过这种方式切断资金流的历史轨迹，从而完成地址的隐私保护。

## NFTs

### 发行

RGB++ 的 NFT 资产发行也可以利用到 ckb 上现有的 NFT 协议，包括不限于 Spore、mNFT 和 CoTA 协议。以 Spore 为例，它将所有的元数据均保留的链上，实现了数据可用性的 100% 安全。而 CoTA 协议则是利用状态压缩技术，将 NFT 信息和持有数据压缩在 32 字节的的 SMT 中，提供了极致的成本优势。

### 转移

RGB++ 中 NFT 的转让也非常简单，类似无须找零的 coins 转账。

<figure><img src="/files/n5RLAzo6wnnmUV0chXeH" alt=""><figcaption></figcaption></figure>

## 闪电网络联通

RGB 作为客户端验证协议天然支持状态通道和闪电网络，但受限于 Bitcoin 的脚本计算能力，在 Bitcoin 上实现非 btc 的闪电网络非常困难。通过 RGB++ 协议的包裹，我们可以基于 CKB 的图灵完备脚本系统实现 RGB++ 资产的状态通道以及闪电网络。这项技术有着巨大的商业前景，例如基于闪电网络的稳定币支付系统可以提供低于中心化系统的成本和性能优势，同时保障了去中心化和抗审查特性。

## 应用举例

### Airdrop

给定一个地址列表和金额列表，我们可以使用 RGB++ 实现完整的 airdrop 应用。我们假设待领空投数据和已领地址列表均以 SMT 的信息保存在 cell data 中。用户即可通过自己的地址领取空投。

### DEX & AMM

RGB++ 利用 UTXO 结构可以直接支持基于 UTXO 的资产交换协议，无须引入中介方。同时利用网格订单簿设计可以实现自动化做市商模式，有别于 Uniswap 的价格曲线做市商模式，**网格做市商模式**可定制化更强，更适合 UTXO 结构的资产交易。

<figure><img src="/files/cHGymUADvLiZa6lkJxvs" alt=""><figcaption></figcaption></figure>

上面的例子是卖家挂单 RGB++ xudt，买家使用 Bitcoin 购买。交易结构为买家提供包含了足够数量 Bitcoin 的 buyer’s utxo 并提供 PBST 签名，买家则构造 CKB 上的交易来符合卖家的要求，最终买家将构造好的 CKB 交易发送给卖家，卖家将 BTC 交易和 CKB 交易先后上链完成交易。

## 总结

RGB++ 继承了 RGB 协议的核心思想，采用了不同的虚拟机和验证方案，用户无须独立的 RGB++ 客户端，只需要访问 Bitcoin 和 CKB 轻节点即可独立完成所有的验证。RGB++ 为 Bitcoin 带来了图灵完备合约扩展和数十倍的性能扩展。它没有使用任何跨链桥，而是使用了原生的客户端验证方案，确保了安全性和抗审查性。


# RGB++ Specification(CN)

RGB++合约规范

> Source: <https://github.com/ckb-cell/RGBPlusPlus-design/blob/main/docs/locscript-design-prd-cn.md>

## 概述

### 关于同构绑定的要求和限制

同构绑定本质上要求 RGB++ 相关的每一个 BTC UTXO 和 CKB CELL 对应。鉴于交易的流程是先构造一个 CKB raw tx，然后把它的部分信息作为 commitment 放到 BTC TX 中，最后再将 CKB TX 上链。这里面的一些约束条件有：

* CKB Cell 的 lock 需要有完整的 BTC UTXO 信息（btc\_tx + index）
* ckb\_tx 的计算依赖所有的 cell 信息，后者依赖 btc\_tx，如果 btc\_tx.commitment 包含 ckb\_tx，这就死锁了，因此，**commitment 只能包含 ckb tx 的部分信息**
  * 为了方便 ckb tx 更新手续费重发，commitment 中不应该包含 output\[].capacity
* Cell 的一个额外问题是，创建 cell 时，lock 脚本并不执行，因此如果没有额外的限制或约束，任何人都可以创建多个使用相同 btc\_utxo 作为 lockargs 的 cell，形式上与同一个 btc utxo 绑定
  * 但似乎多个 cell 于一个 btc\_utxo 对应不会引入安全问题，因此我们允许这种情况出现

## 合约需求

需要如下合约，

* RGB\_lock 用来处理与 BTC TX 的同构映射的 CELL 的解锁
* BTC\_TIME\_lock，用来当资产从 L1 jump 到 L2 时进行锁定一定区块数再允许用户操作

### 合约的 Config Cell

RGB\_lock / BTC\_TIME\_lock 合约需要读取轻节点 cells，因此我们必须保存相关合约的 type\_hash。由于不希望引入硬编码的合约依赖，我们引入 Config Cell 的概念来解决此类配置问题。

部署合约时要求合约输出以及 config cell 输出都在同一笔交易内完成部署。

```yaml
# BTC_TIME_lock
inputs: any cells
outputs:
  BTC_TIME_lock code cell
  time_lock_config cell
...

# RGB_lock
inputs: any cells
outputs:
  RGB_lock code cell
  rgb_lock_config cell
...
```

合约通过以下方式找到 config cell

```yaml
1. load_script 找到目前的 合约的 type_hash
2. 通过 type_hash 找到 cell dep 符合且 out_point.index == 1 的 cell deps 的 index
3. load 这个 cell dep 的 data 即得到全局配置

全局配置
```

```rust
struct RGBPPConfig {
  # Type hash of bitcoin light client
  bitcoin_lc_type_hash: Byte32,
  # Type hash of bitcoin time lock contract
  bitcoin_time_lock_type_hash: Byte32,
}
```

每次更新合约都必须和 config cell 一起更新，并且遵守更新规则。

### 合约数据结构

#### RGB\_lock

```yaml
RGB_lock:
  code_hash: 
    RGB_lock
  args:
    out_index | %bitcoin_tx%
```

* RGB\_lock:
  * out\_index：指定一个可消费自己的 utxo 中的 index
  * bitcoin\_tx: 指定一个可消费自己的 utxo 中的 btc\_txid，该数值不包含在计算 commitment 内

#### BTC\_TIME\_lock

```yaml
BTC_TIME_lock:
  args: lock_script | after | %new_bitcoin_tx%
```

* BTC Time lock:
  * lock\_script 为目标 lockscript
  * after 要求 new\_bitcoin\_tx 已经超过 after 个确认
  * 解锁后的 cell 持有人的 lock 符合 lock\_script

### RGB\_Lock 解锁逻辑

💡 该 Lock 放在每一个 RGB++ 资产在 CKB 的映射 Cell 上，用于 L1 地址(btc\_utxo)持有 RGB++ 资产

**Cell 解锁验证流程**

<figure><img src="/files/mpgtAYFR9dKFQuC5buNH" alt=""><figcaption></figcaption></figure>

* 存在一个与当前 CKB TX 对应的 `btc_tx`，它满足：
  * 包含在 CKB 上的 BTC 轻客户端中
  * inputs 中包含一个与要解锁的 cell.lock 对应的 btc utxo input，即 `btc_tx.inputs[i] == previous_bitcoin_tx | out_index`
  * outputs 中有且仅有一个 OP\_RETURN，包含 `commitment`
  * `self.lockargs.%new_bitcoin_tx% = btc_tx`
* 该 `commitment`为一下内容的 hash，算法为 `double sha256(”RGB++” | messages)`
  * `version: u16`，必须为 0
  * `inputs_len:u8`
    * 表示 commitments 包含前 n 个 inputs
    * 必须 >= 1
    * 所有 type 不为空的 input cell 必须被包含在 inputs\_len 中
  * `outputs_len:u8`
    * 表示 commitments 包含前 n 个 outputs
    * 必须 >= 1
    * 所有 type 不为空的 output cell 必须被包含在 outputs\_len 中
  * `CKB_TX.inputs[:inputs_len]`
  * `CKB_TX.outputs_sub[:outputs_len]`, 包含全部数据，除了
    * 不包含 `lockargs.%new_bitcoin_tx% = btc_tx`
* 验证 L1 的资产仍然被 RGB++ 逻辑保护，即所有 outputs 中 type 不为空的 cells 必须使用以下两种 lock 之一
  * RGB\_lock
  * BTC\_TIME\_lock
    * 要求 `lockargs.after ≥ 6`
    * 要求 `lockargs.new_bitcoin_tx == btc_tx`

**tips**

* 由最后一个有 type 的 input / output cell 的位置就可以计算出 inputs\_len / outputs\_len 值
* 如果所有 inputs / outputs 都没有 type 则至少填 `1`，commitment 至少包含一个 input out point
* SDK 增加手续费时可以在 commitment 之外的 cells 里增加，这样即使提交不成功也可以修改这个 cell。

### BTC\_TIME\_lock 解锁逻辑

```yaml
lock.args: lock_hash | after | %new_bitcoin_tx%
```

* lock\_script 为解锁后需要释放到的目标接受者
  * 解锁交易中每个 BTC\_TIME\_lock input 必须在相同 index 对应一个 output
  * output 的 lock 为 lock\_script 其余字段 type, data, capacity 需要和 input 一致
* after 要求 new\_bitcoin\_tx 已经超过 after 个确认
* 解锁后的 cell 持有人的 lock 符合 lock\_script

## 交易逻辑

### L1 转账/操作

**定义：CKB 上输入输出的资产 cell（定义：type ≠ null） 均为 RGB\_lock**

```yaml
# BTC_TX
input:
  btc_utxo_1  # =(previous_btc_tx | out_index)
  ...
output:
  OP_RETURN: commitment
  btc_utxo_3  # =(new_bitcoin_tx | out_index)
  btc_utxo_4  # =(new_bitcoin_tx | out_index)

# CKB_TX
input:
  rgb-xudt:
    type:
      code: xudt
      args: <asset-id>
    lock:
      code: RGB_lock
      args: btc_utxo_1 = (out_index | previous_btc_tx)

output:
  xudt:
    type: xudt
    lock:
      code: RGB_lock
      args: out_index = 1 | %new_bitcoin_tx%

  xudt:
    type: xudt
    lock:
      code: RGB_lock
      args: out_index = 2 | %new_bitcoin_tx%
```

### L1 → L2 Jump 操作

**定义：CKB 上输入的资产 cell 的 lock 均为 RGB lock，输出的资产 cell 的 lock 至少一个或全部为 BTC\_TIME\_lock，其余为 RGB\_lock**

这里需要在 CKB 上引入一种新的时间锁 Lock: **BTC\_TIME\_lock**

```yaml
# BTC_TX
input:
  btc_utxo_1
  ...
output:
  OP_RETURN: commitment
  btc_utxo_3

# CKB_TX
input:
  rgb_xudt:
    type: xudt
    lock:
      code: RGB_lock
      args: out_index | source_tx

output:
  rgb_xudt:
    type: xudt
    lock：
      code: BTC_TIME_lock
      args: lock_script | after | %new_bitcoin_tx%

  rgb_xudt:
    type: xudt
    lock:
      code: RGB_lock
      args: out_index=1 | %new_bitcoin_tx%
```

等到足够多的 BTC 区块确认后，可以解锁 BTC\_TIME\_lock 的 cell

```yaml
# CKB_TX
input:
  rgb_xudt:
    type: xudt
    lock:
      code: BTC_TIME_lock
      args: lock_script | 6 | btc_tx

output:
  rgb_xudt:
    type: xudt
    lock:
      lock_script

witness:
  # proof of 6 confirmations after #btx_tx
```

### L2 → L1 Jump 操作

**定义：输入侧没有 RGB\_lock，输出侧有 RGB\_lock**

```yaml
# CKB TX
input:
  xudt:
    type: xudt
    lock:
      ckb_address1

output:
  xudt:
    type: xudt
    lock:
      ckb_address2

  rgb_xudt:
    type: xudt
    lock:    
      args: btc_utxo
```

**注意，这里不需要同构绑定**

双花问题：

* 建议应用方或用户在 CKB 交易 24 块确认后再执行后续的 RGB++ L1 交易
* 否则可能因为 CKB TX 双花，导致上面 rgb\_xudt(#btc\_utxo) 被替换成其他输出
  * 因此 dapp 设计上，L2→L1 的资产需要等 24 个 ckb 区块才能操作，不过仅限于前端限制

## RGB++ 资产发行

### 纯 L1 方式发行 RGB++ 资产

使用 L1 方式发行 RGB++ 要求发行人使用 bitcoin 上的交易，utxo 或其他 id 作为身份标识符来发行资产，这样才可以做到无须 L2 辅助即可完全实现 CSV。具体发行方案有多种，我们这里列出两种简单方案。

#### 直接发行

用户需要首先构造一个使用特定 utxo 做 lock 的 cell，作为发行人。该步骤无须经过同构绑定，后即可用这个 cell 进行一次性发行

```yaml
# BTC TX
input:
  btc_utxo#0
  ...
output:
  commitment
  btc_utxo#1
  ...

# CKB TX
input:
  issue_cell:
    RGB_lock:
    args: btc_utxo#0
      
output:
  xudt_cell:
    data: amount
    type: 
      code: xudt
      args: hash(RGB_lock|btc_utxo#0)
    lock:
      code: RGB_lock
      args: btc_utxo#1
```

#### 区块区间发行

区块区间发行需要将 xudt 的发行模式从 lock 发行改为 type 发行，即创建一种新的 xudt，或插件，使得发行的 xudt 的 type.args，即资产 id 不是 lockhash，而是某些 btc 链的参数即可

```yaml
# BTC TX
input:
  btc_utxo#0
  ...
output:
  commitment
  btc_utxo#1
  ...
  
# CKB TX
input:
  issue_cell:
    RGB_lock:
      args: btc_utxo#0

output:
  xudt_cell:
    data: amount
    type: 
      code: xudt_modified
      args: 
        hash_of:
          start_block,
          end_block,
          max_per_tx,
          token_name
    lock:
      code: RGB_lock
      args: btc_utxo#1
```

上面的例子中，在\[start\_block, end\_block] 区间发起的交易，任何人都可以在 BTC L1 上实现公平发射发行，以平等的机会获得代币。

### L2 发行后跳转到 L1

比较简单，也更灵活，不再赘述。


# LeapX

Support for assets on the BTC mainnet to swiftly transition into RGB++, BTC L2 and other protocol & network assets.

## What is LeapX, and what can it do?

LeapX is an all-protocol asset leap tool; it enables all ecosystem protocol assets on the Bitcoin mainnet to leap bi-directionally into RGB++ assets, granting them the capability to seamlessly and trustlessly navigate between L1 and L2.

## Why make the leap?

The ultimate fate of L1 assets should not be merely MEMEs but core assets like Bitcoin itself. LeapX is designed to break down the barriers between protocols, allowing all L1 assets to engage more natively in the yield-generating and application possibilities of L2, transforming them into genuine core assets.

## What can be done after leaping?

By leveraging the RGB++ protocol's ability to leap freely between networks within the UTXO model, all assets will eventually be usable across similar networks, such as CKB, ContinentX, and all UTXO Stack chains. This will form a vast ecosystem containing DEXs, stablecoins, lending protocols, and other foundational infrastructure and DeFi applications.


# FairPool(SRC-20)

FairPool is a new mint model for SRC20 tokens proposed by OpenStamp.

## What is FairPool and why we need it?

As the SRC20 ecosystem develops, more users have noticed some issues during the SRC20 mint process. Recently, we have also received many complaints from users about the drawbacks of the traditional mint mode. Users hope that OpenStamp can provide a corresponding solution to avoid these problems. Therefore, we propose the concept of the FairPool. OpenStamp's SRC20 FairPool has the following advantages:

### 1. Saving bulk mint transaction fees

In the traditional mint method, each mint requires a transaction, and users have to bear the miner fee for each mint transaction.&#x20;

In the Fair Pool, users only need to pay one miner fee for multiple mints. With the traditional mint mode, if you mint 10 times and each transaction costs $10 in miner fees, it would total $100. By minting through FairPool, you only need one transaction fee, reducing the cost by $90.

### 2. Avoiding losses from invalid mint transactions

In the traditional mint method, invalid mint transactions often occur due to tokens being minted out, especially during the mint of hot tokens. Users pay the miner fee but cannot receive the corresponding tokens.&#x20;

However, the Fair Pool's mint can accurately control mint transactions without causing invalid transactions, avoiding unnecessary losses for users.

### 3. Allocation Reserved

In the traditional mint mode, transactions with higher fee rates get included in blocks before those with lower fees. If a mint transaction with a low fee rate is sent and the fee rate increases quickly, the mint transaction might fail, resulting in financial loss.&#x20;

However, in the FairPool, minting is allocation reserved, meaning it won't fail due to a fee rate spike. There's no need to worry about not receiving tokens after sending a transaction, reducing the risk of user losses.

### 4. Ensuring fair token mint

For a specific token, the Fair Pool limits the maximum number of mints per address and sets a minimum total mint count, ensuring that tokens are not minted out by a few addresses at once, allowing more people to participate in the fair mint.

### 5. Setting royalty to incentivize deployers

To better promote the SRC20 ecosystem and enhance community activity, we provide an optional royalty for token deployers. Deployers can set a corresponding royalty fee when issuing tokens in the Fair Pool. This way, deployers can earn some income during minting, promoting the token further.

### 6. Ensuring consistent token costs

Tokens minted through the Fair Pool have consistent costs, avoiding arbitrage by snipers and protecting the interests of all users.

### 7. Eliminating the Bitcoin native too-long-chain limitation

Bitcoin has a transaction chain limit, where an unconfirmed transaction chain can have a maximum of 25 transactions. In the traditional mint process, mint more than 25 times in one order requires at least two blocks to complete all mints.&#x20;

With Fair Pool mint, no matter how many times you mint, only one block confirmation is needed, requiring only one miner fee. This significantly reduces costs and improves efficiency.


# SRC20 Marketplace

OpenStamp's SRC20 marketplace design philosophy

After a period of diligent development, we are thrilled to announce the launch of our SRC20 [Marketplace](https://openstamp.io/). Your unwavering support along the way has been truly appreciated.

Since the SRC20 is not directly linked to SAT, achieving a DEX through simple SAT exchanges is out of the question. The design philosophy of our marketplace revolves around minimizing trust and thwarting Maximum Extractable Value (MEV) to foster a secure and robust trading environment.

In order to help users better understand the trading processes on our SRC20 Marketplace and to address potential questions, this article offers a concise overview of various facets associated with trading. This includes the selection of indexer and wallets, the interpretation of different order statuses, and key considerations for both buyers and sellers. If you have additional questions, feel free to join our [Telegram ](https://t.me/btcopenstamp)community.

## Design Philosophy

1. **Assets safety comes first.**&#x20;
2. **No transaction needed when list or cancel orders.**
3. **Trading process has to be transparent to users.**
4. **Easy to use.**

## Wallet Selection <a href="#ba59" id="ba59"></a>

In the initial stages, we will use the UniSat Wallet, as it provides a comprehensive and easily integratable range of features such as message signing and PSBT transaction signatures. Future support for the Hiro and StampWallet will be considered based on the practical needs of our users and the wallet supported functions.

If your SRC20 tokens are stored in a non-UniSat wallet, such as Hiro, StampWallet, or FreeWallet, we recommend that you import your address into the UniSat Wallet. Please refer to this [guide ](https://medium.com/@btcopenstamp/import-private-key-into-unisat-wallet-15eea401a548)for detailed steps.

## Order Status Explanation <a href="#id-1155" id="id-1155"></a>

**1. Pending Payment:** The order is pending a match, waiting for the buyer to place an order.\
**2. Locked:** To prevent duplicate purchases, orders are locked once a buyer places an order. If the buyer does not pay within 1 minute, the order will be unlocked within the following 2–3 minutes.\
**3. Paid:** The order has been paid for, awaiting the matching transaction.\
**4. Expired:** The payment has timed out.\
**5. Matching:** The buyer has paid, and the matching transaction has been sent, awaiting block confirmation.\
**6. Verifying Match:** After 2–3 block confirmations of the matching transaction, the transaction’s success is verified.\
**7. Matched:** The matching transaction verification is successful.\
**8. Exchanging Assets:** The asset transfer transaction has been sent, awaiting block confirmation.\
**9. Finished:** The asset transfer was successful.\
**10. Refunding:** The order is abnormal, refund in progress.\
**11. Refunded:** The refund has been processed.\
**12. Cancelled:** The order has been cancelled.\
**13. Invalid:** The order is invalid.

## **Notes for Sellers** <a href="#a8e6" id="a8e6"></a>

1\. Posting and cancelling sell orders do not require transaction sending. After the order is cancelled, the platform will delete the signed transaction for the sell order.\
2\. Each sell order will occupy a UTXO with small amount. [Small UTXO](/product-design/small-utxo)\
3\. The amount held in the UTXO used for the sell order will be transferred back to the seller in the matching transaction.\
4\. If the UTXO used for the sell order is moved before the matching transaction, the sell order will become invalid.\
5\. If your account does not have a UTXO with small amount, you can create some using the [UTXO Split Tool](https://openstamp.io/tools) in our website.\
6\. If you need to move your SRC20 Token, please cancel your orders first.\
7\. If you maliciously move the SRC20 Token resulting in a failed matching transaction, all your related addresses will be permanently added to the blacklist.\
8\. **Avoid using an inscription or BRC20 wallet concurrently, as this could potentially result in the loss of your inscription.**\
9\. To alleviate unnecessary concerns, we recommend using a dedicated wallet for Marketplace trading.\
10\. If you have any doubts, do not proceed. Feel free to seek advice by joining our [Telegram](https://t.me/btcopenstamp).

## Notes for Buyers <a href="#id-10b0" id="id-10b0"></a>

1\. Only one unpaid order can exist at a time.\
2\. Please complete the order payment within 1 minute. If you do not pay within 1 minute, you will have to wait for 2–3 minutes to place the order again.\
3\. Strictly adhere to our provided payment process. Do not use other payment methods. Any losses incurred from such actions will be borne by the user.\
4\. If you frequently place orders without making payments, all your related addresses will be permanently added to the blacklist.\
5\. If you have any doubts, do not proceed. Feel free to seek advice by joining our [Telegram](https://t.me/btcopenstamp).

Your continued support for OpenStamp is greatly appreciated. We remain committed to contributing to the Stamp, SRC20, and SRC721 ecosystems. Happy trading!


# Small UTXO

Everything you need to know about small UTXO

## What is Small UTXO? <a href="#a5d9" id="a5d9"></a>

We classify a UTXO containing a small amount of SATs as a small UTXO. We strongly advise not to receive SRC20 tokens on addresses holding inscriptions or BRC20.&#x20;

## Why do we need small UTXO to list sell order? <a href="#id-0077" id="id-0077"></a>

**The small UTXO creation function is designed specifically for sellers.** When a seller lists on our platform, they need to sign a transaction authorizing the transfer of SRC20, which includes the authorized quantity (i.e., the order quantity). Moreover, the first input of a legitimate SRC20 transfer transaction must be the seller’s address. If the referenced UTXO is spent by the seller after the listing, the authorization transaction will become invalid. In addition, the authorization transaction will only be sent to the network when the buyer’s payment is received.

**To ensure that the seller’s wallet can be used normally after authorization and to maintain the validity of the authorization transaction**, we need users to create some small UTXO. This way, users can use their wallets normally without affecting the authorized listing orders.

**Each sell order listing requires referencing a UTXO, so if you want have multiple listings at the same time, you’ll need multiple UTXOs**. But don’t worry, **once your order is fulfilled, the transaction process will generate another UTXO of the same amount for you, thus maintaining the quantity of your UTXOs, and the funds will also be returned to you**. If you cancel an order, the UTXO occupied by this order will be released and can be reused. Simultaneously, we will delete the authorization transaction related to the cancelled order.

## How to create small UTXOs

{% content-ref url="/pages/yY7eJm62SJJbncYKKjDv" %}
[Create Small UTXOs](/product-guides/create-small-utxos)
{% endcontent-ref %}


# Order Status

SRC20 Marketplace Order Status Explanation

## Order Status Explanation <a href="#id-1155" id="id-1155"></a>

**1. Pending:** The order is pending on a payment, waiting for the buyer to pay.\
**2. Locked:** To prevent duplicate purchases, orders are locked once a buyer places an order. If the buyer does not pay within 1 minute, the order will be unlocked within the following 2–3 minutes.\
**3. Paid:** The order has been paid for, awaiting the matching transaction.\
**4. Expired:** The payment has timed out.\
**5. Matching:** The buyer has paid, and the matching transaction has been sent, awaiting block confirmation.\
**6. Verifying:** After 2–3 block confirmations of the matching transaction, the transaction’s success is verified.\
**7. Matched:** The matching transaction verification is successful.\
**8. Sending:** The asset transfer transaction has been sent, awaiting block confirmation.\
**9. Finished:** The asset transfer was successful.\
**10. Refunding:** The order is abnormal, refund in progress.\
**11. Refunded:** The refund has been processed.\
**12. Cancelled:** The order has been cancelled.\
**13. Invalid:** The order is invalid.


# OS Loyalty Points

OS Loyalty Points represent the level of support a user has for OpenStamp.

At OpenStamp, we are committed to elevating user experiences and giving back to our community. With this vision in mind, we are proud to introduce the "OS Loyalty Points" program – a Loyalty Points accumulation system designed specifically for our active users on the platform.

## **What are OS Loyalty Points?**

{% hint style="danger" %}
OS Loyalty Points represent the level of support a user has for OpenStamp. However, it's important to note that these **OS Points do not guarantee any rights or privileges. We encourage users to earn OS Points rationally, understanding that they are just a measure of engagement rather than entitlement.**
{% endhint %}

## How to Earn OS Loyalty Points?

By participating in various activities on our platform, users can earn OS points. Here are the various ways you can accumulate points:

**1. Buy or Sell SRC20 Tokens or STAMPS**

Every trade conducted on OpenStamp’s marketplace, including trades of SRC20 Tokens and STAMPS, earns you points.&#x20;

Points are awarded based on the order amount (unit price \* quantity). The conversion rate is **1 BTC = 400 OS Points**. For instance, if an order with amounts to 0.0025 BTC, both the buyer and seller earn 1 OS Point each.&#x20;

**2. Mint SRC20 Tokens or STAMPS**

Each mint transaction will currently earn **5 OS points**, and we reserve the right to change this ratio.

**3. Participate in OpenStamp's Launchpad**

Our Launchpad is yet to be launched, and the specific rules for earning points through participation are still being finalized.

**4. Leap on LeapX**

Each successful Leap operation will earn **1 OS point** reward.

**5. Engage in OpenStamp's Community Events**

To reward community members for their involvement in OpenStamp activities, we will offer different point rewards for different events. The specific rules will be announced alongside the activities.

**6. Report Bugs or Suggest Product Improvements**

For the first user who reports a relatively serious bug on the OpenStamp platform, if we confirm it as a bug and worth a OS points reward, we will award a certain number of OS points.&#x20;

We also welcome product improvement suggestions sent to <support@openstamp.io>. If your suggestion is adopted, we will also award you with a certain number of OS points.

{% hint style="info" %}
**Points less than 1 OS Point are accumulated until they reach 1.**
{% endhint %}

## Penalty OS Points Situations

At OpenStamp, we are committed to maintaining a fair and secure platform. Therefore, we have a penalty points system in place for malicious activities aimed at exploiting or harming our platform. ***Serious offenses may lead to account suspension***. These activities include, but are not limited to:

1. **Frequent Order Locking without Payment**: Repeatedly locking orders without actual payment is considered a malicious activity.
2. **Maliciously Transferring SRC20 Tokens or STAMPS**: Maliciously transferring SRC20 Tokens or STAMPS, leading to a failed trade, is a serious violation.
3. **Attempted Attacks on Our Platform**: Any attempts to attack or compromise the integrity of the OpenStamp platform will be met with strict penalties.

## **View Your OS Points**

You can easily view your points through your OpenStamp account dashboard.&#x20;

<figure><img src="/files/w251qanHwZQbUN3J5gaQ" alt="" width="267"><figcaption></figcaption></figure>

## **Join Us and Start Accumulating Your OS Points**

We invite all OpenStamp users to join this exciting program and start earning and using OS Loyalty Points. It’s our way of saying thank you to our loyal users and a motivation to drive more active participation in our community.


# Order Limit

Related order limit explanation

## Order Amount Limit

The current limit for maximum pending payment orders for SRC20 and Stamps on OpenStamp is set as follows:

<table><thead><tr><th width="221">Asset\Limit</th><th width="209" align="center">MIN(BTC)</th><th align="center">MAX(BTC)</th></tr></thead><tbody><tr><td>SRC20</td><td align="center">0.0005</td><td align="center">2</td></tr><tr><td>Stamps</td><td align="center">0.0003</td><td align="center">2</td></tr></tbody></table>

We adjust the limit on order amounts based on changes in the network fee rate and token prices. For instance, when the fee rate is high, we will increase the minimum order amount. This is to prevent sellers from having to use a high proportion of the order amount to pay for miner's fees. **However, please note that these adjustments will only apply to new orders and will not affect orders that have already been listed.**

{% hint style="danger" %}

NOTE: Sellers will bear a portion of the transaction fees for asset transfers during the trade, and these fees are closely tied to the Bitcoin network fee rate at the time of the transaction.&#x20;

The approximate formula to calculate the consumed BTC as miner's fee is: Consumed Miner's Fee(BTC) = 800 \* Current Network Fee Rate / Math.pow(10,8). For example, when the network fee rate is 120 sat/vB, it will approximately consume 0.00096 BTC as a miner's fee.

If you are concerned about the cost of these fees, we recommend not listing orders when the network fee rate is high or listing with large order amount. If you have any open orders that have not yet been executed, it may be wise to cancel them and wait until the network fee rate stabilizes or decreases before listing again.
{% endhint %}

## Maximum Pending Payment Order Limit

The current limit for maximum pending payment orders on OpenStamp is set as follows:

<table><thead><tr><th width="237" align="center">OS Points</th><th align="center">Max Pending Payment Order(SRC20&#x26;Stamps)</th></tr></thead><tbody><tr><td align="center">&#x3C; 50</td><td align="center">3</td></tr><tr><td align="center">>= 50</td><td align="center">10</td></tr></tbody></table>

To minimize the possibility of malicious users deliberately locking orders without payment, we currently limit the maximum number of unpaid orders a user can have at one time, based on the number of OS points in their account. If we detect any users engaging in this malicious practice of locking orders without payment, we will blacklist their account, and their OS points will also be frozen.


# XCP FairMinter

## What is FairMinter?

FairMinter is a  decentralized minting mechanism allowing users to create tokens without directly benefiting the deployer on [Counterparty](https://www.counterparty.io/). Inspired by Counterparty's Proof-of-Burn and adapted by token standards like BRC-20 and SRC-20, FairMinter enables "fair minting," where users pay only a miner fee to mint tokens. This ensures a transparent distribution of tokens without enrichment of the minting system creator. Please check more on [FairMinter](https://docs.counterparty.io/docs/advanced/specifications/fairminter/)

## Mint FairMinter Tokens on OpenStamp

To maintain consistency with Bitcoin protocols like BRC20 and SRC20, OpenStamp currently only supports FairMinter that meet all of the following conditions:

1. Named Asset
2. On Open state
3. Not require XCP commission

Since minting operations currently only credit tokens to the source address, to simplify the user experience and improve minting efficiency, allowing users to submit multiple mints in a single order, we will issue a single Transfer transaction after all mint transactions are confirmed to transfer the minted assets to the user in one batch. Therefore, you will see the following status on the order history page:

* **Pending**: Mint transaction on processing
* **Confirming**: Mint transaction pending confirmation
* **Confirmed**: Mint transaction confirmed (Note: since tokens may be minted out, confirmation does not guarantee mint success)
* **Transferring**: Transfer transaction has been sent
* **Finished**: Order completed

**Note**: Since the transfer to the user’s address occurs only after all mint transactions are confirmed, please be patient. If there is a sudden increase in network fee rates causing delays in transaction confirmation, you can use our Accelerator to speed up the mint transactions.

Additionally, while mint transactions will be sent to the Bitcoin network as long as tokens have not been minted out, this does not guarantee mint success. The final outcome depends on when the mint transactions are included in a block. Please use the mint function with caution if you are unable to accept this potential loss.

## Trade FairMinter Tokens on OpenStamp

To ensure the security of assets for both buyers and sellers, we currently follow the same trading model as SRC20 and Image Stamps.&#x20;

Recently, the Counterparty protocol introduced an upgrade with UTXO binding, which will greatly benefit the entire Counterparty asset trading model. However, considering that this UTXO binding feature has only recently been deployed on the mainnet, to ensure user asset safety, we have chosen not to support UTXO-based trading at this time.&#x20;

We are currently reviewing the relevant Counterparty source code to ensure the UTXO model operates as expected, and we will provide UTXO model trading as soon as possible. Please stay tuned.


# Accelerator

The transaction accelerator uses CPFP (Child Pays for Parent) to increase the Effective Fee Rate of a transaction, thus facilitating faster confirmation.

## Common Usage

You can go to [mempool](https://mempool.space/) by searching your address to get the transaction ID you would like to accelerate.  Then navigate to the [OpenStamp Accelerator](https://openstamp.io/tools?type=ACCELERATOR) and enter the TXID into the 'TXID to Accelerate' field. This will display the current effective fee rate.&#x20;

By clicking on 'view', you can see the current network fee rate. You then have the option to customize the target effective fee rate yourself, or simply use the default value provided.

Click 'Submit' button to send the acceleration transaction.

<figure><img src="/files/WEQVARlA9x8F3JUvHIgD" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
To guarantee the effectiveness of the acceleration process, we exclusively select confirmed BTC transactions for sending the acceleration transaction.

In most cases, a transaction can only be accelerated once. If a fee rate spike occurs after the transaction is sent, you will need to provide the TXID of the previous acceleration transaction for a second acceleration.
{% endhint %}

## Accelerate Matching Status Order by Seller

The seller has the option to expedite the trading process when the order is in a matching status(please refer to the [order status explanation](/product-design/order-status)),  and the related transaction is not confirmed yet(click the Matching status to check). In the order history, you will find a 'speed up' icon. For more details, please see the screenshot provided below.

By clicking on this icon, the seller will be directed to the Accelerator page. There, the seller can enter the desired target effective fee rate to initiate the acceleration transaction.

<figure><img src="/files/MM6cJ0aSpnsK4vr5hinq" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
The seller is limited to using the acceleration feature only once from the order history. Should the network fee rate experience another spike after the initial acceleration transaction is dispatched, the seller must locate the acceleration TXID from [mempool.space](https://mempool.space/). Following this, they should proceed according to the standard usage guidelines of the Accelerator.
{% endhint %}

## Accelerate Sending Status Order by Buyer or Seller

The buyer/seller has the option to expedite the trading process when the order is in a sending status (please refer to the [order status explanation](/product-design/order-status)) and the related transaction is not confirmed yet(click the Sending status to check). In the order history, you will find a 'speed up' icon. For more details, please see the screenshot provided below.

By clicking on this icon, the buyer/seller will be directed to the Accelerator page. There, the buyer/seller can enter the desired target effective fee rate to initiate the acceleration transaction.

<figure><img src="/files/ut0b7rM3e9g7lEV2lFeZ" alt=""><figcaption><p>Buyer Perspective</p></figcaption></figure>

<figure><img src="/files/kmSMfmwasUmXVO99TaaK" alt=""><figcaption><p>Seller Perspective</p></figcaption></figure>

{% hint style="info" %}

The buyer/seller is limited to using the acceleration feature only once from the order history. Should the network fee rate experience another spike after the initial acceleration transaction is dispatched, the buyer/seller must locate the acceleration TXID from [mempool.space](https://mempool.space/). Following this, they should proceed according to the standard usage guidelines of the Accelerator.
{% endhint %}


# LeapX Tutorial

OpenStamp LeapX Tutorial

<figure><img src="/files/O9B0RzHxunoRwOTUl2zM" alt=""><figcaption></figcaption></figure>


# LeapX 教程

OpenStamp LeapX 教程

<div data-full-width="false"><figure><img src="/files/lxDUBmBHKLBGU09cbpra" alt=""><figcaption></figcaption></figure></div>


# Buy SRC20 Tokens

How to buy SRC20 tokens on OpenStamp.io

## Step 1 - Login OpenStamp with UniSat/Leather Wallet

Once your UniSat/Leather wallet([Install Guide](/wallets-guides/install-unisat-wallet)) is ready, open [OpenStamp](https://openstamp.io/market), click ‘Connect’ in the top right corner, then click ‘Sign’ to log in.

<figure><img src="/files/NlonQGap4hBniy66gUbM" alt="" width="375"><figcaption></figcaption></figure>

## Step 2 - Buy SRC20 Tokens <a href="#id-3209" id="id-3209"></a>

Go to the ‘[Marketplace](https://openstamp.io/market)’, select SRC20 from the Marketplace menu:

<figure><img src="/files/3fFo4wmHwFoRkWGRqRtf" alt=""><figcaption></figcaption></figure>

And select the token you want to Buy, for example, ‘STAMP’,

<figure><img src="/files/KbqE0Nf5ps5bCyCBOpw4" alt=""><figcaption></figcaption></figure>

Choose the order you want to buy, click ‘Buy Now’

<figure><img src="/files/5AjEAzuWYZlUK6PfebEm" alt=""><figcaption></figcaption></figure>

Or use the sweep mode to place more orders at the same time:

<figure><img src="/files/HryTSw6F3UrT7TQKHmqW" alt=""><figcaption></figcaption></figure>

Click the 'Confirm button' and  click ‘Sign & Pay’ within 1 minute, otherwise, the order will expire.

<figure><img src="/files/mUQUAZEy9Vq6JqlDABU7" alt="" width="375"><figcaption></figcaption></figure>

## Step 3 - Order History

To view your order history, click on the address in the upper right corner and select ‘Orders’.&#x20;

You can click the order Status to check the ongoing or finished transactions.&#x20;

{% hint style="info" %}
**Normally, it will need 3-4 block confirmations before you received the bought tokens. Please be patient.**<br>
{% endhint %}

<figure><img src="/files/BDWCNNtUNpNJZyljUFIg" alt=""><figcaption></figcaption></figure>


# Create Small UTXOs

How to create small UTXOs on OpenStamp.io

## Small UTXO Design Philosophy <a href="#id-325a" id="id-325a"></a>

{% content-ref url="/pages/nEjNK1mpXnEVBmxYPLZE" %}
[Small UTXO](/product-design/small-utxo)
{% endcontent-ref %}

## How to create small UTXO? <a href="#id-325a" id="id-325a"></a>

Go to the small UTXO generation tool at <https://openstamp.io/tools>

<figure><img src="/files/qEZDpAdq9MjNCpPiuhi5" alt=""><figcaption></figcaption></figure>

You can view your BTC balance along with the quantity of your confirmed and total small UTXOs through 'Small UTXO Quantity'(e.g 9 small utxos and 8 of them were confirmed).

If you need to generate additional small UTXOs, simply **enter the desired number into the ‘New UTXO Quantity’ field, leave the ‘Each UTXO Amount’ and ‘Fee Rate’ values at their default settings**, then click submit. This will initiate a transaction to create multiple small UTXOs.

Once the **transaction is confirmed**, you will be able to utilize the newly created small UTXOs to create sell orders.

&#x20;**If you want to list N orders at the same time, you are gonna need N small confirmed UTXOs.** The consumed small UTXOs will be recreated and sent to you once order fulfilled and you can reuse the new small UTXOs to list orders.&#x20;

{% hint style="danger" %}
**WARNING**\
Please do not mix the stamp assets with addresses used for other BTC protocols, as it may result in the loss of other assets.
{% endhint %}


# List SRC20 Tokens

How to list SRC20 tokens on OpenStamp.io

## Step 1 - Login OpenStamp with UniSat/Leather Wallet

Once your UniSat/Leather wallet([Install Guide](/wallets-guides/install-unisat-wallet)) is ready, open [OpenStamp](https://openstamp.io/market), click ‘Connect’ in the top right corner, then click ‘Sign’ to log in.

<figure><img src="/files/ahkcctncgQudVf1wYn7Z" alt="" width="375"><figcaption></figcaption></figure>

## Step 2 - List Sell Order

After logging in, click on the address in the top right corner, then select ‘Assets’,

<figure><img src="/files/1kaD42ecBE1WiErt4Kjn" alt="" width="306"><figcaption></figcaption></figure>

Then you can see the SRC20 tokens you hold. Click the ‘List’ button on the right side.

<figure><img src="/files/VIrMTFsxWhsuoZwOMhKV" alt=""><figcaption></figcaption></figure>

Then a ‘List Review’ box will pop up. Enter the quantity of Tokens you want to sell and the unit price, read the warning information and check the box to acknowledge the risks, then click ‘Confirm’.

<figure><img src="/files/T0ytMPK3MQPmoW5PUK4O" alt="" width="375"><figcaption></figcaption></figure>

You should cancel orders before transferring listed SRC20 Tokens, or risk being blacklisted due to Matching Transaction failure.

You will need to click the ‘Sign’ button to authorize this Sell Order, which will only be posted to the network after the buyer pays. **You do not need to pay any listing fee and there will be no BTC loss.**

<figure><img src="/files/KEvwvZOlnMuipmnCTHlJ" alt="" width="375"><figcaption></figcaption></figure>

If you encounter the prompt “No suitable low-value UTXO found. Create more in Tools”, please first go to ‘Tools’ to create some small amount UTXOs([Guide](/product-guides/create-small-utxos)).

<figure><img src="/files/zmo8hj6KTiYmULnCjW6J" alt=""><figcaption></figcaption></figure>

Each Sell order requires the use of one confirmed small UTXO. Input the number of small UTXOs you need to create, for example, 3, then click ‘Submit’ to submit the transaction. After the transaction is confirmed, you can use the created UTXOs for listing orders. For more details, please refer to [Small UTXO Design](/product-design/small-utxo).

## Step 3 - List Order History

After logging in, click on the address in the top right corner, then select ‘Orders’. You can see your list order history.

You can also click the order Status to check the related tx and usually **needs 3-4 block confirmations after user paid the payment.**

<figure><img src="/files/3xap8lqp5cFAzD5nwtrX" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
**WARNING**

Please do not mix the stamp assets with addresses used for other BTC protocols, as it may result in the loss of other assets.
{% endhint %}


# Delist SRC20 Order

How to delist SRC20 sell order on OpenStamp.io

To view listing orders or cancel orders, click on the address in the upper right corner and select ‘Orders’. You’ll be able to see the sell orders you just are listing.&#x20;

Click on the ‘Delist’ button on the right to delist sell order, **with no fees required**.

<figure><img src="/files/SBFq94XG4xTZxdhuwoCr" alt=""><figcaption></figcaption></figure>

###


# Deploy SRC20 Tokens

How to deploy SRC20 tokens on OpenStamp.io

## Step 1 - Enter the Deploy Info <a href="#id-38d7" id="id-38d7"></a>

Go to SRC20 deploy page <https://openstamp.io/mint?tab=src20&type=deploy> Provide the following info,

<figure><img src="/files/E2FbXJjpX9RqoDrglUh3" alt="" width="375"><figcaption></figcaption></figure>

**Tick(Case Insensitive):** The token name you want to deploy.

**Total Supply:** The total supply of the token

**Mint All:** Mint the entire supply to your address at once with an extra mint transaction. Note that this may not be 100% successful, as there is still a risk of being preemptively minted.

**Limit Per Mint:** Max mint amount each time.&#x20;

**Fee Rate:** The fee rate for the deployment transaction. The deployment transaction with higher fee rate get confirmed faster.

**Receive:** The address will be named as the Tick issuer.

## Step 2 - Submit Order <a href="#id-3dff" id="id-3dff"></a>

After you enter the above info, click the ‘Deploy’ button, then you can see the order review based on the info you provided.

<figure><img src="/files/fGhEhhUctRPL8myrgbdd" alt="" width="375"><figcaption></figcaption></figure>

Then click the ‘Pay with Wallet’ button to send the payment transaction with login address or choose 'Pay with BTC' to pay from other sources.

## Step 3(Optional) - Wait the Deploy Transaction Get Confirmed <a href="#id-2c14" id="id-2c14"></a>

You can check your deploy transaction at <https://mempool.space/> . Just search your recipient address and you will see the deploy transaction.&#x20;

## Step 4(Optional) - Accelerate deploy transaction <a href="#id-2c14" id="id-2c14"></a>

If the deploy transaction experiences a fee rate spike, you can use our accelerator to speed it up.

{% content-ref url="/pages/RswGDQFkOSYwQ7GBvxvV" %}
[Accelerator](/product-guides/accelerator)
{% endcontent-ref %}

## Step 5(Optional) - Mint the Deployed Token <a href="#id-2c14" id="id-2c14"></a>

Once the deploy transaction get confirmed. You can mint the token by following:<br>

{% content-ref url="/pages/GeNW4GrLRTNAZWQSuDKA" %}
[Mint SRC20 Tokens](/product-guides/mint-src20-tokens)
{% endcontent-ref %}


# Deploy FairPool(SRC20) Tokens

How to deploy FairPool(SRC20) tokens on OpenStamp.io

## Step 1 - Enter the Deploy Info <a href="#id-38d7" id="id-38d7"></a>

Go to SRC20 FairPool deploy page <http://openstamp.io/mint?tab=fair&fair-type=deploy> Provide the following info,

<figure><img src="/files/y8powbBdHZKuKDU2EvW8" alt=""><figcaption></figcaption></figure>

**Tick(Case Insensitive):** The token name you want to deploy.

**Total Supply:** The total supply of the token

**Max Mints(at least 1000):** The maximum mint times

**Limit Per Mint:** Max mint amount each time.&#x20;

**Max Mints Per Address:** Maximum mint times per address.&#x20;

**Deployer & Royalty Address:** Token issuer and royalty recipient address.

**Royalty:** Royalty amount per mint, in sats.

**Fee Rate:** The fee rate for the deployment transaction. The deployment transaction with higher fee rate get confirmed faster.

## Step 2 - Submit Order <a href="#id-3dff" id="id-3dff"></a>

After you enter the above info, click the ‘Deploy’ button, then you can see the order review based on the info you provided.

<figure><img src="/files/yGSmshp3aj6gZT2NnkDk" alt="" width="375"><figcaption></figcaption></figure>

Then click the ‘Pay with Wallet’ button to send the payment transaction with login address.

## Step 3(Optional) - Wait the Deploy Transaction Get Confirmed <a href="#id-2c14" id="id-2c14"></a>

You can check your deploy transaction at <https://mempool.space/> . Just search your recipient address and you will see the deploy transaction.&#x20;

## Step 4(Optional) - Accelerate deploy transaction <a href="#id-2c14" id="id-2c14"></a>

If the deploy transaction experiences a fee rate spike, you can use our accelerator to speed it up.

{% content-ref url="/pages/RswGDQFkOSYwQ7GBvxvV" %}
[Accelerator](/product-guides/accelerator)
{% endcontent-ref %}

## Step 5(Optional) - Mint the Deployed Token <a href="#id-2c14" id="id-2c14"></a>

Once the deploy transaction get confirmed. You can mint the token by following:<br>

{% content-ref url="/pages/gB2Len6GuMK9Em8Uzgn2" %}
[Mint FairPool(SRC20) Tokens](/product-guides/mint-fairpool-src20-tokens)
{% endcontent-ref %}


# Mint SRC20 Tokens

How to mint SRC20 tokens on OpenStamp.io

## Step 1 - Check Token Deploy Status <a href="#id-38d7" id="id-38d7"></a>

Make sure the token is deployed before mint(You can check at <https://openstamp.io/explorer> by searching the token name), otherwise you need to deploy the token before minting by following:&#x20;

{% content-ref url="/pages/2Ww1Yzi1FF933HGRurt6" %}
[Deploy SRC20 Tokens](/product-guides/deploy-src20-tokens)
{% endcontent-ref %}

## Step 2 - Enter the Mint Info <a href="#id-38d7" id="id-38d7"></a>

Go to SRC20 mint page <https://openstamp.io/mint?tab=src20>

<figure><img src="/files/PrvYh8wShXtLuABPm7T5" alt="" width="375"><figcaption></figcaption></figure>

Provide the following info,

**Tick(Case Insensitive):** The token you want to mint.

**Amount:** Mint amount each time(Will be loaded after inputing a deployed Tick).

**Repeat mint:** How many times do you want to mint?

**Effective Fee Rate:** The effective fee rate for the minting transaction. Minting transaction with higher fee rate get confirmed faster.&#x20;

**Receive:** The address to receive SRC20 tokens.

## Step 3 - Submit Order <a href="#id-3dff" id="id-3dff"></a>

After you enter the above info, click the ‘Mint’ button, then you can see the order review based on the info you provided.

<figure><img src="/files/XYFsFm0qtA9gtnX9F9V1" alt="" width="375"><figcaption></figcaption></figure>

Then click the ‘Pay with Wallet’ button to send the payment transaction with login address or choose 'Pay with BTC' to pay from other sources.

## Step 4 - Check the Minted Tokens <a href="#id-2c14" id="id-2c14"></a>

You can check your minting transactions at <https://mempool.space/> . Just search your receive address and you will see the minting transactions. After the minting transactions have **at least 1 block confirmations**. You can see your minted tokens after login [OpenStamp](https://openstamp.io/) or go to <https://openstamp.io/explorer> by searching your address.


# Mint FairPool(SRC20) Tokens

How to mint FairPool(SRC20) tokens on OpenStamp.io

## Step 1 - Check Token Deploy Status <a href="#id-38d7" id="id-38d7"></a>

Make sure the token is deployed before mint(You can check at <https://openstamp.io/explorer> by searching the token name), otherwise you need to deploy the token before minting by following:&#x20;

{% content-ref url="/pages/zmEPEPtLiuxFQHIP4gqQ" %}
[Deploy FairPool(SRC20) Tokens](/product-guides/deploy-fairpool-src20-tokens)
{% endcontent-ref %}

## Step 2 - Enter the Mint Info <a href="#id-38d7" id="id-38d7"></a>

Go to FairPool(SRC20) mint page <http://openstamp.io/mint?tab=fair>

<figure><img src="/files/KLFIyneBSENdIwZvbIsp" alt=""><figcaption></figcaption></figure>

Provide the following info,

**Tick(Case Insensitive):** The token you want to mint.

**Limit Per Mint:** Token amount each mint(Will be loaded after inputing a deployed Tick).

**Repeat Mint:** Mint times you are gonna have.

**Receive Amount:** The token amount and ratio you are gonna receive.

**Receive:** The address to receive SRC20 tokens.

**Effective Fee Rate:** The effective fee rate for the minting transaction. Minting transaction with higher fee rate get confirmed faster.&#x20;

## Step 3 - Submit Order <a href="#id-3dff" id="id-3dff"></a>

After you enter the above info, click the ‘Mint’ button, then you can see the order review based on the info you provided.

<figure><img src="/files/U9YmC3koFFbDoyfmk5YI" alt="" width="375"><figcaption></figcaption></figure>

Then click the ‘Pay with Wallet’ button to send the payment transaction with login address.

## Step 4(Optional) - Check the Minted Tokens <a href="#id-2c14" id="id-2c14"></a>

You can check your minting transactions at <https://mempool.space/> . Just search your receive address and you will see the minting transactions. After the minting transactions have **at least 1 block confirmations**. You can see your minted tokens after login [OpenStamp](https://openstamp.io/) or go to <https://openstamp.io/explorer> by searching your address.

## Step 5(Optional) - Accelerate transaction <a href="#id-2c14" id="id-2c14"></a>

If the mint transaction experiences a fee rate spike, you can use our accelerator to speed it up.

{% content-ref url="/pages/RswGDQFkOSYwQ7GBvxvV" %}
[Accelerator](/product-guides/accelerator)
{% endcontent-ref %}


# Mint Stamps

How to mint stamps on OpenStamp.io

## Step 1 - Enter the Mint Info <a href="#beed" id="beed"></a>

Go to stamps mint page <https://openstamp.io/mint> and choose STAMPS

<figure><img src="/files/xqFexkK82ceNsUTY3y3V" alt=""><figcaption></figcaption></figure>

Provide the following info,

**Data Type**: Choose File/SRC721 JSON/Base64

**Encode Type:** Data encode type. [OLGA(P2WSH)](/introduction/olga-octet-linked-graphics-and-artifacts) or Legacy(Bare Multi-Sig)

{% hint style="info" %}
We highly recommend using the OLGA encoding type as it can save over 70% on transaction fees.
{% endhint %}

**File**: Upload the file you want to stamp. Supports

```python
text/html
```

&#x20;and the following image types:&#x20;

```dart
jpg,jpeg,png,gif,svg,tif,jfif,jpe,pbm,pgm,ppm,pnm,apng,bmp,webp,heif,
heic,avif,ico,tiff,svgz,wmf,emf,pcx,djvu,djv
```

**Supply:** The initial supply of the stamp.

**Receive:** The address to receive the stamp.

**Lock Asset:** Locked asset cannot raise up the supply once minted.

**Effective Fee Rate:** The effective fee rate for the minting transaction. Minting transactions with higher fee rate get confirmed faster.&#x20;

## Step 2 - Submit Order <a href="#id-09e7" id="id-09e7"></a>

After you enter the above info, click the ‘Mint’ button, then you can see the order review based on the info you provided.

<figure><img src="/files/Llf7clXo3hbJ5CIun3HN" alt="" width="375"><figcaption></figcaption></figure>

&#x20;Then click the ‘Pay with Wallet’ button to send the payment transaction within 5 minutes

## Step 3 - Check the Minted Stamp <a href="#eae7" id="eae7"></a>

You can check your minting transactions at <https://mempool.space/> . Just search your recipient address and you will see the minting transactions. After the minting transactions have 1 block confirmations. You can see your minted stamp at <https://openstamp.io/explorer> by searching your address.


# Transfer SRC20 Tokens

How to transfer SRC20 tokens on OpenStamp.io

## Step 1 - Find the token your want to transfer <a href="#id-38d7" id="id-38d7"></a>

Go to 'Assets' page and click the three dots after each token, then click the 'Transfer' button

<figure><img src="/files/avxoRaezjYgtKN4l6v9r" alt=""><figcaption></figcaption></figure>

## Step 2 - Enter the transfer Info <a href="#id-38d7" id="id-38d7"></a>

<figure><img src="/files/BjWufgn1CiCww3TGGk9R" alt="" width="375"><figcaption></figcaption></figure>

Provide the following info,

**Amount:** Transfer amount. Must equals or less than the available amount.

**Receive(BTC Address):** The address to receive SRC20 tokens.

**Fee Rate:** The fee rate for the transfer transaction.

## Step 3 - Confirm <a href="#id-38d7" id="id-38d7"></a>

Once you have verified the information you entered, please click the 'Confirm' button to send the transation.


# Supported Wallets

Supported wallets on OpenStamp

<table><thead><tr><th width="216">Wallet\Operation</th><th width="159" data-type="checkbox">Buy Assets</th><th width="206" data-type="checkbox">SRC20 (List &#x26; Transfer)</th><th data-type="checkbox">Stamps &#x26; RGB++  (List &#x26; Transfer)</th></tr></thead><tbody><tr><td><a href="https://unisat.io/">UniSat</a></td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://leather.io/">Leather(Hiro)</a></td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://www.okx.com/web3">OKXWallet</a></td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://joy.id/">JoyID</a></td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://wallet.magiceden.io/">MagicEden</a></td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://web3.bitget.com/">Bitget Wallet</a></td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://www.gate.io/web3">Gate Wallet</a></td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://www.xverse.app/">Xverse</a></td><td>true</td><td>true</td><td>true</td></tr><tr><td><a href="https://phantom.app/">Phantom</a></td><td>true</td><td>false</td><td>false</td></tr></tbody></table>

{% hint style="info" %}
Assets includes SRC20, Stamps and RGB++ .
{% endhint %}


# Grand Celebration Offer

OpenStamp’s Grand Celebration Offer

## For OG Pass Holders

### 1. Achievement Badge OAT

Design unique achievement badges.

### 2. Participate in Decision Voting

OG PASS HOLDERS can participate in decision-making processes on the OpenStamp platform, such as the design of new features, UI optimization, or recommending new projects to join the launchpad, enhancing their sense of involvement.

### 3. Limited-time Trading Discount: This limited-time offer ends on 02.28.2024

OG PASS HOLDERS enjoy a 50% rebate on platform trading fees.

## For Regular Existing Users

### 1. Points Reward System

The higher your points, the greater the trading discounts. With points exceeding 200, during the limited-time offer (ending on 02.28.2024), a 30% rebate on platform trading fees is provided.

### 2. Social Media Sharing

Regular users can earn extra points by sharing transaction screenshots on the OpenStamp platform. With over 20 likes, you get 10 points; over 40 likes, you get 20 points; over 100 likes, you get 60 points. This activity is limited to once per user.

## For New Users (Initially for BRC20 and BRC420 Users Only)

### First Minting or Trading Points Reward

New users conducting their first minting or trading on the OpenStamp platform receive a reward of 20 points.

## For Projects Joining the Launchpad——Mayflower

### 1. Enhanced Brand Exposure

OpenStamp will provide launchpad projects with broader brand exposure, attracting more attention from the crypto community.

### 2. Shared Ecosystem Resources

OpenStamp will introduce launchpad projects to other projects within the same ecosystem, creating opportunities for collaboration and resource sharing.

### 3. Community Support

OpenStamp will establish exclusive Discord channels for launchpad projects, offering community support to channel members.

### 4. KOL Support

Launchpad projects will have access to shared Key Opinion Leaders (KOLs) within the ecosystem, boosting project visibility.

### 5. Media Support

OpenStamp will provide media support for launchpad projects.

### 6. Consultation/Incubation Support

The OpenStamp team can offer comprehensive advice and introductions to optimize the launch of a project, ensuring its quality.

### 7. Limited-time Points Reward for Project Minting

All users participating in the launchpad mint will receive an additional 10 points during the minting period.<br>

<mark style="color:red;">\*The final interpretation of this marketing plan belongs to the OpenStamp.io.</mark>


# SRC20 Explorer

SRC20 explorer by OpenStamp.

## Check the mint trending

<figure><img src="/files/oNFRadlzkB8XJhsS7EoD" alt=""><figcaption></figcaption></figure>

## Search address assets

<figure><img src="/files/yDqPVUy6NOnEmBRDeIPJ" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/lQL9Un1xW75xZCrzwXjG" alt=""><figcaption></figcaption></figure>

## Check token details

<figure><img src="/files/oxAmjwyxpKAttoOipFUz" alt=""><figcaption></figcaption></figure>


# Install UniSat Wallet

## Step 1 - Download UniSat Wallet&#x20;

Official Website: <https://unisat.io/download>

Chrome Store: <https://chrome.google.com/webstore/detail/unisat/ppbibelpcjmhbdihakflkdcoccbgbkpo>

Github: <https://github.com/unisat-wallet/extension/releases/latest>

## Step 2 - Create a new wallet&#x20;

![](/files/B6d4n71DGJoM440jxIzd)![](/files/BGA69X78y9qDhTgvUSOk)![](/files/yF4nl5hecfeEComAwHwD)![](/files/tHVrvLVk36JWrYo4KyAK)![](/files/rETPJkyNcEYSiVfrTCSw)


# Import Private Key into UniSat

Import Private Key into Unisat wallet

## Step 1 - Install UniSat Wallet(Optional)

{% content-ref url="/pages/Nqbm6eCORyBL8JRYRtbY" %}
[Install UniSat Wallet](/wallets-guides/install-unisat-wallet)
{% endcontent-ref %}

## Step 2 - Get Your Private Key

Export your private key from other wallets, like StampWallet or FreeWallet etc.

{% content-ref url="/pages/9ESgUQQlXNypHSYueC4R" %}
[Export StampWallet Private Key](/wallets-guides/export-stampwallet-private-key)
{% endcontent-ref %}

{% content-ref url="/pages/PDV8I918g0A5z137zjA8" %}
[Export FreeWallet Private Key](/wallets-guides/export-freewallet-private-key)
{% endcontent-ref %}

## Step 3 - Import Private Key Into Unisat&#x20;

&#x20;![](/files/pdWAzHGzndC4X0lfJUMS)![](/files/YqaXOygE1zE7RODK50KF)![](/files/kzaurauVfxlyz0HQjbzN)![](/files/6DlXNZKeY2Alav5Q2MMw)


# Import Mnemonic/Seed Phrase Into UniSat

Import Mnemonic/Seed Phrase Into UniSat

## Step 1 - Get Your Mnemonic/Seed Phrase <a href="#dcd1" id="dcd1"></a>

E.g:&#x20;

{% content-ref url="/pages/0sL2xiVmKx0xlN4YAUxX" %}
[Import Seed Phrase From Leather(Hiro) Into UniSat](/wallets-guides/import-seed-phrase-from-leather-hiro-into-unisat)
{% endcontent-ref %}

{% content-ref url="/pages/DRNa75pZCuHIfZeaR0PZ" %}
[Export Seed Phrase From StampWallet](/wallets-guides/export-seed-phrase-from-stampwallet)
{% endcontent-ref %}

{% content-ref url="/pages/n60HqMHuRsBQ7xXIxjpO" %}
[Export Mnemonic From Trust Wallet](/wallets-guides/export-mnemonic-from-trust-wallet)
{% endcontent-ref %}

## Step 2 - Choose import method <a href="#id-9657" id="id-9657"></a>

### Case 1: Haven't installed UniSat

{% content-ref url="/pages/Nqbm6eCORyBL8JRYRtbY" %}
[Install UniSat Wallet](/wallets-guides/install-unisat-wallet)
{% endcontent-ref %}

After install UniSat wallet, choose I already have a wallet,

<figure><img src="/files/PgDPm19LspQvnGaRhyng" alt="" width="316"><figcaption></figcaption></figure>

### Case 2: UniSat already installed&#x20;

![](/files/MgtmVULW6DnsIITKrDay)![](/files/JYpsUeFxW2wM1QlY6m1M)

![](/files/y8EgvSSfRdGuLAI3G0mf)

## Step 3 - Import Mnemonic into UniSat <a href="#id-9657" id="id-9657"></a>

Choose the corresponding wallet or ‘Other Wallet’,

<figure><img src="/files/8f01iuP1JFimISXu3yfv" alt="" width="371"><figcaption></figcaption></figure>

Choose the length of your Mnemonic, paste your Mnemonic and continue.

<figure><img src="/files/gNYrL4DKhYO7KSY4rXJT" alt="" width="371"><figcaption></figcaption></figure>

Choose the corresponding address type(the same address with the account you want to import):

<figure><img src="/files/wwZAShOQH1Y8YBkxVSrJ" alt="" width="371"><figcaption></figcaption></figure>

Congratulations!


# Import Seed Phrase From Leather(Hiro) Into UniSat

Import Seed Phrase From Leather(Hiro) Into UniSat

## Step 1 - Export Secret Key from Leather <a href="#dcd1" id="dcd1"></a>

Click the three dots and then View Secret Key,

![](/files/xhueXiECbu8YUFmpbIvu)

After input your password, you can see the following info, click Copy to clipboard to copy your Mnemonic.

![](/files/FWed8qFj2Ja9FVLHIoVS)

## Step 2 - Import Hiro Accounts into UniSat <a href="#id-9657" id="id-9657"></a>

### Case 1: Haven't installed UniSat

{% content-ref url="/pages/Nqbm6eCORyBL8JRYRtbY" %}
[Install UniSat Wallet](/wallets-guides/install-unisat-wallet)
{% endcontent-ref %}

After install UniSat wallet, choose I already have a wallet,

![](/files/lfzgmxrP18JbLoJ9BNdc)

### Case 2: UniSat already installed&#x20;

![](/files/MgtmVULW6DnsIITKrDay)![](/files/JYpsUeFxW2wM1QlY6m1M)

![](/files/y8EgvSSfRdGuLAI3G0mf)

Click ‘Other Wallet’,

![](/files/rkWKuthMboUjLa5jb6GR)

Choose the length of your Mnemonic, paste your Mnemonic and continue.![](/files/pcKS0clzhJl9SXXXCxsw)

**a. Choose Native Segwit address type.**

**b. Set Custom HDPath**

m/84'/0'/**0'**/0 will import the first account, this is default value of UniSat. So you do not need to change the HDPath if you want to import the first Leather account.

If you want to **import the second Leather account, set the HdPath to m/84'/0'/1'/0.**&#x20;

And set to m/84'/0'/**2'**/0 to import the third account, etc.

Then click continue and your Hiro account should be imported.

![](/files/ZGdD4TYjdJtZT91ugJG8)

Congratulations!


# Import Account From Ledger Into UniSat

Import Account From Ledger Into UniSat

## Step 1 - Find the HD derive path for your Ledger account <a href="#dcd1" id="dcd1"></a>

Click the 'Edit Account' button on the account page.

<figure><img src="/files/euyMIerKiehRR0Uhrxuo" alt=""><figcaption></figcaption></figure>

Find the derive path by **ADVANCED** -> **freshAddressPath** (E.g 84'/0'/0'/0/0).

<figure><img src="/files/K0YPdjQHy8eNc5SZs02B" alt=""><figcaption></figcaption></figure>

## Step 2 - Import Account into UniSat <a href="#id-9657" id="id-9657"></a>

### Case 1: Haven't installed UniSat

{% content-ref url="/pages/Nqbm6eCORyBL8JRYRtbY" %}
[Install UniSat Wallet](/wallets-guides/install-unisat-wallet)
{% endcontent-ref %}

After install UniSat wallet, choose I already have a wallet,

![](/files/lfzgmxrP18JbLoJ9BNdc)

### Case 2: UniSat already installed&#x20;

![](/files/MgtmVULW6DnsIITKrDay)![](/files/JYpsUeFxW2wM1QlY6m1M)

![](/files/y8EgvSSfRdGuLAI3G0mf)

Click ‘Other Wallet’,

![](/files/rkWKuthMboUjLa5jb6GR)

Choose the length of your Mnemonic, paste your Ledger Mnemonic and continue.![](/files/pcKS0clzhJl9SXXXCxsw)

**a. Choose Native Segwit or Taproot address type according to your account type.**

**b. Set Custom HDPath to your Legder account derive path which you can get from 'Account Page ->Edit account** -> **ADVANCED** -> **freshAddressPath' on Step 1 (E.g** m/84'/0'/0/0)

**c. Click 'Continue' to finish the process**

![](/files/ZGdD4TYjdJtZT91ugJG8)

Congratulations!


# Export Seed Phrase From StampWallet

Export Seed Phrase From StampWallet

## Export Seed Phrase from StampWallet <a href="#dcd1" id="dcd1"></a>

![](/files/B5g64XTnI3CvcMHIgFWV)![](/files/NbfqBYDhTxkxc9BxV6ka)

![](/files/AsBIrncQxlj6XVULT3VQ)![](/files/PJ9SoIySlnJTxCXhU4Ni)

If you want to import your accounts into UniSat, please check:

{% content-ref url="/pages/ll7N3JC3hwZ2g9Pgb2yH" %}
[Import Mnemonic/Seed Phrase Into UniSat](/wallets-guides/import-mnemonic-seed-phrase-into-unisat)
{% endcontent-ref %}


# Export Mnemonic From Trust Wallet

Export Mnemonic From StampWallet Into UniSat

## Export Mnemonic from Trust Wallet <a href="#dcd1" id="dcd1"></a>

![](/files/e6WEWMyUM4FOrUBeyJEW)![](/files/xyx3XihYMzLlD9rQiVJS)

![](/files/7b7Fox32Pf22q7nmIC8x)![](/files/nENUHr9kzZj2X2gkruU4)

If you want to import your accounts into UniSat, please check:

{% content-ref url="/pages/ll7N3JC3hwZ2g9Pgb2yH" %}
[Import Mnemonic/Seed Phrase Into UniSat](/wallets-guides/import-mnemonic-seed-phrase-into-unisat)
{% endcontent-ref %}


# Export FreeWallet Private Key

Export Private Key From FreeWallet

<figure><img src="/files/6hKDIdKspmeJ5XmNC6ew" alt=""><figcaption></figcaption></figure>

**Copy the private key after "p2wpkh:" for native segwit address which starts with 'bc1q'**

<figure><img src="/files/kuaWyitiTDv9ycUSbcgN" alt=""><figcaption></figcaption></figure>

**Or just copy the private key for legacy address which starts with '1'**

<figure><img src="/files/upa9D7yVQBAFiwbsHL8x" alt=""><figcaption></figcaption></figure>


# Export StampWallet Private Key

Export Private Key From StampWallet

## Follow the steps below:

![](/files/wBRhzEydNkfMRVGfBTO5)![](/files/FZaCbijNI6iOb1d46a4W)![](/files/bzmyjU7nTbT2z0IP5BDP)![](/files/7r0tH4zQvqksKtLE9emL)


# Browser Plugin Wallet Upgrade

Browser Plugin Wallet Upgrade Guide

## Step 1 - Go to chrome://extensions/

<figure><img src="/files/SXWWv2Psii01QGJ8Zqmz" alt=""><figcaption></figcaption></figure>

## Step 2 - Open Developer mode

<figure><img src="/files/AVy9SQvq0DazrIFFRBF9" alt=""><figcaption></figcaption></figure>

## Step 3 - Click the Update button to upgrade

<figure><img src="/files/l0Vd5zuk2IeR8UXoyuER" alt=""><figcaption></figcaption></figure>

##


# Set OKX Wallet Address Default Type

How to set OKX wallet address default type?

## Step1 - Click 'My Asset' on the bottom(Just for Mobile app, skip this step for browser plugin)

<figure><img src="/files/VCSAlWWFb6yRE5Jrjjvq" alt="" width="375"><figcaption></figcaption></figure>

## Step 2 - Click the 'BTC' under Crypto tab

<figure><img src="/files/uiJSTDLXw2Cw5tBfDzb0" alt="" width="374"><figcaption></figcaption></figure>

## **Step 3 - Click 'set default address format' logo on the upper right corner**

<figure><img src="/files/u1pwTbrfB8qaQb2PYMTP" alt="" width="374"><figcaption></figcaption></figure>

## Step 4 - Choose the address type you want to use

<figure><img src="/files/IpduUmO1tBOxVI3kIQAE" alt="" width="374"><figcaption></figcaption></figure>


# OpenStamp Official Links

Website: <https://openstamp.io/>

Explorer: <https://openstamp.io/explorer>

Telegram: <https://t.me/btcopenstamp>

Discord: <https://discord.com/invite/openstamp>

X(Twitter): <https://twitter.com/btcopenstamp>

Medium: <https://medium.com/@btcopenstamp>

GitHub: <https://github.com/btcopenstamp>

Docs: <https://docs.openstamp.io/>


