Skip to content

Commit

Permalink
Merge pull request #365 from Chia-Network/new-hinting-section
Browse files Browse the repository at this point in the history
New hinting section in conditions page
  • Loading branch information
Rigidity committed Aug 16, 2023
2 parents 2857df0 + 2323883 commit 13d7a41
Showing 1 changed file with 55 additions and 32 deletions.
87 changes: 55 additions & 32 deletions docs/coin-set-model/conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,34 @@ However, it is still best practice to only use this condition in a coin's soluti

This is an extensive list of each condition allowed on the Chia blockchain.

| Condition | Format | Description |
| ------------------------------ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| REMARK | `(1)` | Always a valid condition. |
| AGG_SIG_UNSAFE | `(49 public_key message)` | Verifies a signature by its `public_key` and `message`. Usually `AGG_SIG_ME` is safer. |
| AGG_SIG_ME | `(50 public_key message)` | Like `AGG_SIG_UNSAFE`, but including the coin id and genesis id to prevent replay attacks. |
| CREATE_COIN | `(51 puzzle_hash amount (memos))` | Creates a coin with a given `puzzle_hash`, `amount`, and optional `memo` (first is a hint). |
| RESERVE_FEE | `(52 amount)` | Requires a given `amount` to be remaining in the transaction as a fee. |
| CREATE_COIN_ANNOUNCEMENT | `(60 message)` | Creates an announcement with a given `message`, tied to this coin. |
| ASSERT_COIN_ANNOUNCEMENT | `(61 announcement_id)` | Asserts a coin announcement was created within this transaction by its `announcement_id`. |
| CREATE_PUZZLE_ANNOUNCEMENT | `(62 message)` | Creates an announcement with a given `message`, tied to this puzzle. |
| ASSERT_PUZZLE_ANNOUNCEMENT | `(63 announcement_id)` | Asserts a puzzle announcement was created within this transaction by its `announcement_id`. |
| ASSERT_CONCURRENT_SPEND | `(64 coin_id)` | Asserts that this coin is spent in the same block as a given `coin_id`. |
| ASSERT_CONCURRENT_PUZZLE | `(65 puzzle_hash)` | Asserts that this coin is spent in the same block as a coin with a given `puzzle_hash`. |
| ASSERT_MY_COIN_ID | `(70 coin_id)` | Asserts that the coin's id matches the given `coin_id`. |
| ASSERT_MY_PARENT_ID | `(71 parent_id)` | Asserts that the coin's parent id matches the given `parent_id`. |
| ASSERT_MY_PUZZLEHASH | `(72 puzzle_hash)` | Asserts that the coin's puzzle hash matches the given `puzzle_hash`. |
| ASSERT_MY_AMOUNT | `(73 amount)` | Asserts that the coin's amount matches the given `amount`. |
| ASSERT_MY_BIRTH_SECONDS | `(74 seconds)` | Asserts that the coin was created with a timestamp of `seconds`. |
| ASSERT_MY_BIRTH_HEIGHT | `(75 block_height)` | Asserts that the coin was created on a given `block_height`. |
| ASSERT_EPHEMERAL | `(76)` | Asserts that the coin was both created and spent on the current block. |
| ASSERT_SECONDS_RELATIVE | `(80 seconds_passed)` | Asserts that the previous transaction block's timestamp was at least `seconds_passed` seconds after coin creation. |
| ASSERT_SECONDS_ABSOLUTE | `(81 seconds)` | Asserts that the previous transaction block's timestamp was at least `seconds`. |
| ASSERT_HEIGHT_RELATIVE | `(82 block_height_passed)` | Asserts that the previous transaction block's height was at least `block_height_passed` after coin creation. |
| ASSERT_HEIGHT_ABSOLUTE | `(83 block_height)` | Asserts that the previous transaction block's height was at least `block_height`. |
| ASSERT_BEFORE_SECONDS_RELATIVE | `(84 seconds_passed)` | Asserts that the previous transaction block's timestamp was less than `seconds_passed` seconds after coin creation. |
| ASSERT_BEFORE_SECONDS_ABSOLUTE | `(85 seconds)` | Asserts that the previous transaction block's timestamp was less than `seconds`. |
| ASSERT_BEFORE_HEIGHT_RELATIVE | `(86 block_height_passed)` | Asserts that the previous transaction block's height was less than `seconds_passed` after coin creation. |
| ASSERT_BEFORE_HEIGHT_ABSOLUTE | `(87 block_height)` | Asserts that the previous transaction block's height was less than `block_height`. |
| Condition | Format | Description |
| ------------------------------ | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| REMARK | `(1)` | Always a valid condition. |
| AGG_SIG_UNSAFE | `(49 public_key message)` | Verifies a signature by its `public_key` and `message`. Usually `AGG_SIG_ME` is safer. |
| AGG_SIG_ME | `(50 public_key message)` | Like `AGG_SIG_UNSAFE`, but including the coin id and genesis id to prevent replay attacks. |
| CREATE_COIN | `(51 puzzle_hash amount (...memos))` | Creates a coin with a given `puzzle_hash`, `amount`, and an optional [memos](#memos) parameter. |
| RESERVE_FEE | `(52 amount)` | Requires a given `amount` to be remaining in the transaction as a fee. |
| CREATE_COIN_ANNOUNCEMENT | `(60 message)` | Creates an announcement with a given `message`, tied to this coin. |
| ASSERT_COIN_ANNOUNCEMENT | `(61 announcement_id)` | Asserts a coin announcement was created within this transaction by its `announcement_id`. |
| CREATE_PUZZLE_ANNOUNCEMENT | `(62 message)` | Creates an announcement with a given `message`, tied to this puzzle. |
| ASSERT_PUZZLE_ANNOUNCEMENT | `(63 announcement_id)` | Asserts a puzzle announcement was created within this transaction by its `announcement_id`. |
| ASSERT_CONCURRENT_SPEND | `(64 coin_id)` | Asserts that this coin is spent in the same block as a given `coin_id`. |
| ASSERT_CONCURRENT_PUZZLE | `(65 puzzle_hash)` | Asserts that this coin is spent in the same block as a coin with a given `puzzle_hash`. |
| ASSERT_MY_COIN_ID | `(70 coin_id)` | Asserts that the coin's id matches the given `coin_id`. |
| ASSERT_MY_PARENT_ID | `(71 parent_id)` | Asserts that the coin's parent id matches the given `parent_id`. |
| ASSERT_MY_PUZZLEHASH | `(72 puzzle_hash)` | Asserts that the coin's puzzle hash matches the given `puzzle_hash`. |
| ASSERT_MY_AMOUNT | `(73 amount)` | Asserts that the coin's amount matches the given `amount`. |
| ASSERT_MY_BIRTH_SECONDS | `(74 seconds)` | Asserts that the coin was created with a timestamp of `seconds`. |
| ASSERT_MY_BIRTH_HEIGHT | `(75 block_height)` | Asserts that the coin was created on a given `block_height`. |
| ASSERT_EPHEMERAL | `(76)` | Asserts that the coin was both created and spent on the current block. |
| ASSERT_SECONDS_RELATIVE | `(80 seconds_passed)` | Asserts that the previous transaction block's timestamp was at least `seconds_passed` seconds after coin creation. |
| ASSERT_SECONDS_ABSOLUTE | `(81 seconds)` | Asserts that the previous transaction block's timestamp was at least `seconds`. |
| ASSERT_HEIGHT_RELATIVE | `(82 block_height_passed)` | Asserts that the previous transaction block's height was at least `block_height_passed` after coin creation. |
| ASSERT_HEIGHT_ABSOLUTE | `(83 block_height)` | Asserts that the previous transaction block's height was at least `block_height`. |
| ASSERT_BEFORE_SECONDS_RELATIVE | `(84 seconds_passed)` | Asserts that the previous transaction block's timestamp was less than `seconds_passed` seconds after coin creation. |
| ASSERT_BEFORE_SECONDS_ABSOLUTE | `(85 seconds)` | Asserts that the previous transaction block's timestamp was less than `seconds`. |
| ASSERT_BEFORE_HEIGHT_RELATIVE | `(86 block_height_passed)` | Asserts that the previous transaction block's height was less than `seconds_passed` after coin creation. |
| ASSERT_BEFORE_HEIGHT_ABSOLUTE | `(87 block_height)` | Asserts that the previous transaction block's height was less than `block_height`. |

## Condition Costs {#costs}

Expand All @@ -75,13 +75,36 @@ Conditions not listed here do not have a cost associated with them.
| AGG_SIG_UNSAFE | 1200000 |
| AGG_SIG_ME | 1200000 |

## Hinting
## Memos and Hinting {#memos}

When creating a coin, there is an optional `memos` parameter in addition to the `puzzle_hash` and `amount`. Wallets use the first memo parameter to discover assets (by hinting the corresponding `puzzle_hash` of the address it was sent to). This hint value is then stored in the blockchain database for easy lookup.
When a coin uses one or more outer puzzles that change their puzzle hash, it's challenging for wallets to know which coins they have the ability to spend. The memos field allows you to hint the inner puzzle hash of created coins, which consequently lets the wallet know that the coin belongs to it. Coins can be looked up by the inner puzzle hash rather than the outer puzzle hash.

A wallet will typically look up each of its addresses by hint to get a record for every coin. It can then find the puzzle reveal from its parent coin's spend, which is then used to identify and validate the coin. This info can then be used to spend the coin later on.
The `CREATE_COIN` condition is defined as a list containing the opcode `51` and the following arguments:

Without hinting, a wallet would have to either look at millions of coins to figure out which of them it owns. Hints are a powerful and flexible way to optimize this lookup.
```chialisp
; The third parameter is optional.
(51 puzzle_hash amount (...memos))
```

The `memos` parameter is an optional list, which must be null terminated.

If `memos` is present, and the first memo is exactly 32 bytes long, it's used as the hint and the rest of the list are memos. Otherwise, values in the entire list are memos.

As an example, the following inner solution for the [standard transaction](https://chialisp.com/standard-transactions) would create an unhinted coin:

```chialisp
(() (q . ((51 target_puzzle_hash amount))) ())
```

The following solution would instead create a coin with the hint matching the inner puzzle hash:

```chialisp
(() (q . ((51 target_puzzle_hash amount (target_puzzle_hash)))) ())
```

This `CREATE_COIN` condition creates the same coin as before, but now it specifies the hint with which the receiving wallet can look up to find this coin.

Hints are only necessary for outer puzzles, of which the inner puzzle hash matches the hint. For example, coins using the standard transaction itself with no outer puzzle do not need a hint.

## Announcements

Expand Down

0 comments on commit 13d7a41

Please sign in to comment.