Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blob tx and instructions #592

Merged
merged 15 commits into from
Jul 31, 2024
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- [Transaction Pointer](./tx-format/tx-pointer.md)
- [Computing Identifiers](./identifiers/index.md)
- [Asset ID](./identifiers/asset.md)
- [Blob ID](./identifiers/blob-id.md)
- [Contract ID](./identifiers/contract-id.md)
- [Predicate ID](./identifiers/predicate-id.md)
- [Transaction ID](./identifiers/transaction-id.md)
Expand Down
68 changes: 58 additions & 10 deletions src/fuel-vm/instruction-set.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
- [`CCP`: Code copy](#ccp-code-copy)
- [`CROO`: Code Merkle root](#croo-code-merkle-root)
- [`CSIZ`: Code size](#csiz-code-size)
- [`LDC`: Load code from an external contract](#ldc-load-code-from-an-external-contract)
- [`LDC`: Load code from an external contract](#ldc-load-code-from-an-external-contract-or-blob)
- [`LOG`: Log event](#log-log-event)
- [`LOGD`: Log data event](#logd-log-data-event)
- [`MINT`: Mint new coins](#mint-mint-new-coins)
Expand All @@ -106,6 +106,9 @@
- [`TIME`: Timestamp at height](#time-timestamp-at-height)
- [`TR`: Transfer coins to contract](#tr-transfer-coins-to-contract)
- [`TRO`: Transfer coins to output](#tro-transfer-coins-to-output)
- [Blob Instructions](#blob-instructions)
- [`BSIZ`: Blob size](#bsiz-blob-size)
- [`BLDD`: Load data from a blob](#bldd-load-data-from-a-blob)
- [Cryptographic Instructions](#cryptographic-instructions)
- [`ECK1`: Secp251k1 signature recovery](#eck1-secp256k1-signature-recovery)
- [`ECR1`: Secp256r1 signature recovery](#ecr1-secp256r1-signature-recovery)
Expand Down Expand Up @@ -1749,7 +1752,7 @@ Panic if:
| Notes | If `$rD` is greater than the code size, zero bytes are filled in. |

This is used only for reading and inspecting code of other contracts.
Use [`LDC`](#ldc-load-code-from-an-external-contract) to load code for executing.
Use [`LDC`](#ldc-load-code-from-an-external-contract-or-blob) to load code for executing.

Panic if:

Expand Down Expand Up @@ -1793,27 +1796,37 @@ Panic if:
- `$rB + 32` overflows or `> VM_MAX_RAM`
- Contract with ID `MEM[$rB, 32]` is not in `tx.inputs`

### `LDC`: Load code from an external contract
### `LDC`: Load code from an external contract or blob

| | |
|-------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| Description | Copy `$rC` bytes of code starting at `$rB` for contract with ID equal to the 32 bytes in memory starting at `$rA` into memory starting at `$ssp`. |
| Operation | ```MEM[$ssp, $rC] = code($rA, $rB, $rC);``` |
| Syntax | `ldc $rA, $rB, $rC` |
| Encoding | `0x00 rA rB rC -` |
| Description | Copy `$rC` bytes of code at offset `$rB` from object with 32 byte id starting at `$rA` into memory starting at `$ssp`. Object type is in `imm`. |
| Operation | `id = mem[$rA,32]; code = match imm { 0 => contract_code($id), 1 => blob_payload($id) }; MEM[$ssp, $rC] = code[$rB, $rC];` |
| Syntax | `ldc $rA, $rB, $rC, imm` |
| Encoding | `0x00 rA rB rC imm` |
| Notes | If `$rC` is greater than the code size, zero bytes are filled in. |

Object type from `imm` determined the source for loading as follows:

| `imm` | Object type |
|-------|---------------|
| `0` | Contract code |
| `1` | Blob payload |
| other | _reserved_ |

Panic if:

- `$ssp + $rC` overflows or `> VM_MAX_RAM`
- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$ssp + $rC >= $hp`
- `$rC > CONTRACT_MAX_SIZE`
- Contract with ID `MEM[$rA, 32]` is not in `tx.inputs`
- `imm == 0` and `$rC > CONTRACT_MAX_SIZE`
- `imm == 0` and contract with ID `MEM[$rA, 32]` is not in `tx.inputs`
- `imm == 1` and contract with ID `MEM[$rA, 32]` is not found in the chain state
- `imm >= 2` (reserved value)

Increment `$fp->codesize`, `$ssp` by `$rC` padded to word alignment. Then set `$sp` to `$ssp`.

This instruction can be used to concatenate the code of multiple contracts together. It can only be used when the stack area of the call frame is zero-sized.
This instruction can be used to concatenate the code of multiple contracts or blobs together. It can only be used when the stack area of the call frame is zero-sized.

### `LOG`: Log event

Expand Down Expand Up @@ -2217,6 +2230,41 @@ In an external context, decrease `MEM[balanceOfStart(MEM[$rD, 32]), 8]` by `$rC`

This modifies the `balanceRoot` field of the appropriate output(s).

## Blob Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

### `BSIZ`: Blob size

| | |
|-------------|-----------------------------------------------------------------------------------------------------------|
| Description | Set `$rA` to the size of the blob with ID equal to the 32 bytes in memory starting at `$rB`. |
| Operation | `$rA = len(blob(MEM[$rB, 32]));` |
| Syntax | `bsiz $rA, $rB` |
| Encoding | `0x00 rA rB - -` |
| Notes | |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- Blob ID `MEM[$rB, 32]` is not found

### `BLDD`: Load data from a blob

|-------------|-------------------------------------------------------------------------------------------------------------|
| Description | Load 32-byte blob id at `$rB`, and copy `$rD` bytes starting from `$rC` into `$sA`. |
| Operation | `MEM[$rA, $rD] = blob(MEM[$rB, 32])[$rC, $rD];` |
| Syntax | `bldd $rA, $rB, rC, $rD` |
| Encoding | `0x00 rA rB rC rD` |
| Notes | If `$rC >` blob size, zero bytes are filled in. |

Panic if:

- `$rA + $rD` overflows or `> VM_MAX_RAM` or `> $hp`
- `$rB + 32` overflows or `> VM_MAX_RAM`
- Blob ID `MEM[$rB, 32]` is not found

## Cryptographic Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.
Expand Down
10 changes: 10 additions & 0 deletions src/identifiers/blob-id.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Blob ID

The _blob ID_ (also called _blob hash_) of a transaction is computed as
the [hash](../protocol/cryptographic-primitives.md#hashing) of the blob data.

Blob ID calculation doesn't vary between chains.

```python
sha256(blob_data)
```
1 change: 1 addition & 0 deletions src/identifiers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
This chapter defines how to compute unique identifiers.

- [Asset ID](./asset.md)
- [Blob ID](./blob-id.md)
- [Contract ID](./contract-id.md)
- [Predicate ID](./predicate-id.md)
- [Transaction ID](./transaction-id.md)
Expand Down
3 changes: 3 additions & 0 deletions src/tx-format/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ The Fuel Transaction Format.
- [`TransactionScript`](./transaction.md#transactionscript)
- [`TransactionCreate`](./transaction.md#transactioncreate)
- [`TransactionMint`](./transaction.md#transactionmint)
- [`TransactionUpgrade`](./transaction.md#transactionupgrade)
- [`TransactionUpload`](./transaction.md#transactionupload)
- [`TransactionBlob`](./transaction.md#transactionblob)
- [Input](./input.md)
- [`InputCoin`](./input.md#inputcoin)
- [`InputContract`](./input.md#inputcontract)
Expand Down
29 changes: 29 additions & 0 deletions src/tx-format/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ enum TransactionType : uint8 {
Mint = 2,
Upgrade = 3,
Upload = 4,
Blob = 5,
}
```

Expand Down Expand Up @@ -232,3 +233,31 @@ Transaction is invalid if:
- `subsectionIndex` >= `subsectionsNumber`
- `subsectionsNumber > MAX_BYTECODE_SUBSECTIONS`
- The [Binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) root calculated from `(witnesses[witnessIndex], subsectionIndex, subsectionsNumber, proofSet)` is not equal to the `root`. Root calculation is affected by all fields, so modification of one of them invalidates the proof.

## `TransactionBlob`

The `Blob` inserts a simple binary blob in the chain. It's raw immutable data that can be cheaply loaded by the VM and used as instructions or just data. Unlike `Create`, it doesn't hold any state or balances.

`Blob`s are content-addressed, i.e. the they are uniquely identified by hash of the data field. Programs running on the VM can load an already-posted blob just by the hash, without having to specify it in contract inputs.

| name | type | description |
|---------------------|-----------------------------|----------------------------------|
| `id` | `byte[32]` | Blob id, i.e. hash of the data. |
| `witnessIndex` | `uint16` | The witness index of the data. |
| `policyTypes` | `uint32` | Bitfield of used policy types. |
| `inputsCount` | `uint16` | Number of inputs. |
| `outputsCount` | `uint16` | Number of outputs. |
| `witnessesCount` | `uint16` | Number of witnesses. |
| `policies` | [Policy](./policy.md)`[]` | List of policies. |
| `inputs` | [Input](./input.md)`[]` | List of inputs. |
| `outputs` | [Output](./output.md)`[]` | List of outputs. |
| `witnesses` | [Witness](./witness.md)`[]` | List of witnesses. |

Transaction is invalid if:

- Any input is of type `InputType.Contract` or `InputType.Message` where `input.dataLength > 0`
- Any input uses non-base asset.
- Any output is of type `OutputType.Contract` or `OutputType.Variable` or `OutputType.Message` or `OutputType.ContractCreated`
- Any output is of type `OutputType.Change` with non-base `asset_id`
- `witnessIndex >= tx.witnessesCount`
- `sha256(witnesses[witnessIndex]) != id`
Loading