Skip to content

Commit

Permalink
Granular Asset Minting (#491)
Browse files Browse the repository at this point in the history
### Abstract

This PR introduces granular asset minting which would enable sub
identifiers to be included at asset creation. These sub identifiers can
include important metadata and be used to enable native level NFTs.

**This adds:**
- A new asset ID construction (which incorporates the contract ID and
the sub asset ID).
- New receipt logs for minting and burning which are helpful for
indexing.
- Changes to the MINT and BURN opcodes.

### Cons

- This removes the nice feature that asset IDs are the contract ID.

### Pros

- Native level UTXO based NFTs.
- Single contract multi-asset pools (useful for common AMM designs).

Implementation tickets/PRs:

- FuelLabs/fuel-vm#496
- FuelLabs/fuels-ts#1067
- FuelLabs/fuel-indexer#1012
- FuelLabs/sway#4651

---------

Co-authored-by: Brandon Kite <brandonkite92@gmail.com>
Co-authored-by: Green Baneling <XgreenX9999@gmail.com>
  • Loading branch information
3 people authored Aug 7, 2023
1 parent 1176515 commit b241dc9
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 20 deletions.
42 changes: 42 additions & 0 deletions src/abi/receipts.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ All receipts will have a `type` property:
- [Panic](#panic-receipt)
- [Revert](#revert-receipt)
- [Log](#log-receipt)
- [Mint](#mint-receipt)
- [Burn](#burn-receipt)
- [LogData](#logdata-receipt)
- [Transfer](#transfer-receipt)
- [TransferOut](#transferout-receipt)
Expand Down Expand Up @@ -124,6 +126,46 @@ _Important note:_ For the JSON representation of receipts, we represent 64-bit u
}
```

## Mint Receipt

- `type`: `Mint`.
- `sub_id`: Hexadecimal string representation of the 256-bit (32-byte) asset sub identifier ID; derived from register `$rB`.
- `contract_id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context.
- `val`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
"type": "Mint",
"sub_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
"contract_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
"val": "18446744073709551613",
"pc": "0xffffffffffffffff",
"is": "0xfffffffffffffffe"
}
```

## Burn Receipt

- `type`: `Burn`.
- `sub_id`: Hexadecimal string representation of the 256-bit (32-byte) asset sub identifier ID; derived from register `$rB`.
- `contract_id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context.
- `val`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
"type": "Burn",
"sub_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
"contract_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
"val": "18446744073709551613",
"pc": "0xffffffffffffffff",
"is": "0xfffffffffffffffe"
}
```

## LogData Receipt

- `type`: `LogData`.
Expand Down
66 changes: 47 additions & 19 deletions src/fuel-vm/instruction-set.md
Original file line number Diff line number Diff line change
Expand Up @@ -1626,23 +1626,37 @@ Block header hashes for blocks with height greater than or equal to current bloc

### BURN: Burn existing coins

| | |
|-------------|------------------------------------------------------|
| Description | Burn `$rA` coins of the current contract's asset ID. |
| Operation | ```burn($rA);``` |
| Syntax | `burn $rA` |
| Encoding | `0x00 rA - - -` |
| Notes | |
| | |
|-------------|-------------------------------------------------------------|
| Description | Burn `$rA` coins of the `$rB` ID from the current contract. |
| Operation | ```burn($rA, $rB);``` |
| Syntax | `burn $rA $rB` |
| Encoding | `0x00 rA rB - -` |
| Notes | `$rB` is a pointer to a 32 byte ID in memory. |

The asset ID is constructed using the asset ID construction method.

Panic if:

- Balance of asset ID `MEM[$fp, 32]` of output with contract ID `MEM[$fp, 32]` minus `$rA` underflows
- `$rB + 32 > VM_MAX_RAM`
- Balance of asset ID from `constructAssetID(MEM[$fp, 32], MEM[$rB, 32])` of output with contract ID `MEM[$fp, 32]` minus `$rA` underflows
- `$fp == 0` (in the script context)

For output with contract ID `MEM[$fp, 32]`, decrease balance of asset ID `MEM[$fp, 32]` by `$rA`.
For output with contract ID `MEM[$fp, 32]`, decrease balance of asset ID `constructAssetID(MEM[$fp, 32], MEM[$rB, 32])` by `$rA`.

This modifies the `balanceRoot` field of the appropriate output.

Append a receipt to the list of receipts, modifying tx.receiptsRoot:

| name | type | description |
|----------|---------------|---------------------------------------------------------------------------|
| `type` | `ReceiptType` | `ReceiptType.Burn` |
| `sub_id` | `byte[32]` | Asset sub identifier `MEM[$rB, $rB + 32]`. |
| `contract_id` | `byte[32]` | Contract ID of the current context. |
| `val` | `uint64` | Value of register `$rA`. |
| `pc` | `uint64` | Value of register `$pc`. |
| `is` | `uint64` | Value of register `$is`. |

### CALL: Call contract

| | |
Expand Down Expand Up @@ -1854,27 +1868,41 @@ Logs the memory range `MEM[$rC, $rD]`.
Panics if:

- `$rC + $rD` overflows
- `$rA + $rD > VM_MAX_RAN`
- `$rA + $rD > VM_MAX_RAM`

### MINT: Mint new coins

| | |
|-------------|------------------------------------------------------|
| Description | Mint `$rA` coins of the current contract's asset ID. |
| Operation | ```mint($rA);``` |
| Syntax | `mint $rA` |
| Encoding | `0x00 rA - - -` |
| Notes | |
| | |
|-------------|-------------------------------------------------------------|
| Description | Mint `$rA` coins of the `$rB` ID from the current contract. |
| Operation | ```mint($rA, $rB);``` |
| Syntax | `mint $rA $rB` |
| Encoding | `0x00 rA rB - -` |
| Notes | `$rB` is a pointer to a 32 byte ID in memory |

The asset ID will be constructed using the asset ID construction method.

Panic if:

- Balance of asset ID `MEM[$fp, 32]` of output with contract ID `MEM[$fp, 32]` plus `$rA` overflows
- `$rB + 32 > VM_MAX_RAM`
- Balance of asset ID `constructAssetID(MEM[$fp, 32], MEM[$rB])` of output with contract ID `MEM[$fp, 32]` plus `$rA` overflows
- `$fp == 0` (in the script context)

For output with contract ID `MEM[$fp, 32]`, increase balance of asset ID `MEM[$fp, 32]` by `$rA`.
For output with contract ID `MEM[$fp, 32]`, increase balance of asset ID `constructAssetID(MEM[$fp, 32], MEM[$rB])` by `$rA`.

This modifies the `balanceRoot` field of the appropriate output.

Append a receipt to the list of receipts, modifying tx.receiptsRoot:

| name | type | description |
|----------|---------------|---------------------------------------------------------------------------|
| `type` | `ReceiptType` | `ReceiptType.Mint` |
| `sub_id` | `byte[32]` | Asset sub identifier `MEM[$rB, $rB + 32]`. |
| `contract_id` | `byte[32]` | Contract ID of the current context. |
| `val` | `uint64` | Value of register `$rA`. |
| `pc` | `uint64` | Value of register `$pc`. |
| `is` | `uint64` | Value of register `$is`. |

### RETD: Return from context with data

| | |
Expand Down
8 changes: 8 additions & 0 deletions src/identifiers/asset.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Asset ID

The _asset ID_ (also called _asset hash_) of a asset is computed as
the [hash](../protocol/cryptographic-primitives.md#hashing) of the `CONTRACT_ID` and a 256-bit `SUB_IDENTIFIER`.

```python
sha256(CONTRACT_ID ++ SUB_IDENTIFIER)
```
3 changes: 2 additions & 1 deletion src/identifiers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

This chapter defines how to compute unique identifiers.

- [Transaction ID](./transaction-id.md)
- [Asset ID](./asset.md)
- [Contract ID](./contract-id.md)
- [Predicate ID](./predicate-id.md)
- [Transaction ID](./transaction-id.md)
- [UTXO ID](./utxo-id.md)
- [Coin ID](./utxo-id.md#coin-id)
- [Message ID](./utxo-id.md#message-id)
Expand Down
2 changes: 2 additions & 0 deletions src/tx-format/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ enum ReceiptType : uint8 {
TransferOut = 8,
ScriptResult = 9,
MessageOut = 10,
Mint = 11
Burn = 12
}
```

Expand Down

0 comments on commit b241dc9

Please sign in to comment.