Skip to content

Commit

Permalink
docs(yp): Spec how bytecode is encoded in class registerer (#5471)
Browse files Browse the repository at this point in the history
Adds a section to the contract classes page in the yellow paper about
how bytecode is encoded for passing into each function and emitting as
event.
  • Loading branch information
spalladino authored Mar 27, 2024
1 parent 2292214 commit e3bced2
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions yellow-paper/docs/contract-deployment/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,23 @@ assert computed_artifact_hash == contract_class.artifact_hash

It is strongly recommended for developers registering new classes to broadcast the code for `compute_hash_and_nullifier`, so any private message recipients have the code available to process their incoming notes. However, the `ContractClassRegisterer` contract does not enforce this during registration, since it is difficult to check the multiple signatures for `compute_hash_and_nullifier` as they may evolve over time to account for new note sizes.

### Encoding Bytecode

The `register`, `broadcast_unconstrained_function`, and `broadcast_private_function` functions all receive and emit variable-length bytecode in unencrypted events. In every function, bytecode is encoded in a fixed-length array of field elements, which sets a maximum length for each:

- `MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS`: 15000 field elements, used for a contract's public bytecode in the `register` function.
- `MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS`: 3000 field elements, used for the ACIR and Brillig bytecode of a broadcasted private function in `broadcast_private_function`.
- `MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS`: 3000 field elements, used for the Brillig bytecode of a broadcasted unconstrained function in `broadcast_unconstrained_function`.

To encode the bytecode into a fixed-length array of Fields, the bytecode is first split into 31-byte chunks, and each chunk interpreted big-endian as a field element. The total length in bytes is then prepended as an initial element, and then right-padded with zeroes.

```
chunks = chunk bytecode into 31 bytes elements, last element right-padded with zeroes
fields = right-align each chunk into 32 bytes and cast to a field element
padding = repeat a zero-value field MAX_SIZE - fields.count - 1 times
encoded = [bytecode.length as field, ...fields, ...padding]
```

## Discarded Approaches

### Bundling private function information into a single tree
Expand Down

0 comments on commit e3bced2

Please sign in to comment.