Cell Model Changes Preview in v0.19.0

The latest post is here


:bangbang: Since the post was published, the structure design has evolved several versions. I’ll post a new article soon, this post is already outdated.

This version has changed Cell Model a lot.

  1. Modified transaction structure
  2. Added new feature Dep Group, which references multiple cells as deps using only one out point.
  3. Allowed script to match deps by type hash.

Transaction Structure

Input Structure

In input, the field previous_output now can only point to a cell. If the script needs to know which block the cell is in, the cell has to appear in deps as well, with dep type cell_with_header.

Here is a sample input.

{
    "previous_output": {
        "index": "0",
        "tx_hash": "0x04e427..."
    },
    "since": "0"
}

Output Structure

In the output, data and scripts are no longer embedded. Instead, the output only contains the blake256 hash of the content.

  • data is replaced by data_hash.
  • lock is replaced by lock_hash.
  • If the cell has a type, it is replaced by type_hash.

The data content is stored in the new transaction field outputs_data. It is not a parallel array of outputs, but matched by the data_hash.

The lock scripts of all inputs, and the type scripts of all inputs and outputs must appear in the transaction field scripts. The relationship is also via the hash.

Following is a sample output without a type.

{
    "capacity": "100000000000",
    "data_hash": "0x0000000...",
    "lock_hash": "0x28e83a1...",
    "type_hash": null
}

Dep Structure

The dep has four different types now:

  • cell points to a previous transaction output.
  • cell_with_header points to a previous transaction output, as well as the block the transaction is committed.
  • dep_group points to a previous transaction output, which data is a list of deps of type cell. See details in the chapter about Dep Group later.
  • header points to a block in the canonical chain.

Example cell dep:

{
  "type": "cell_with_header",
  "previous_output": {
    "index": "0",
    "tx_hash": "0x04e427..."
  }
}

Example cell_with_header dep:

{
  "type": "cell",
  "previous_output": {
    "index": "0",
    "tx_hash": "0x04e427..."
  },
  "header_hash": "0xabcdef..."
}

Example dep_group dep:

{
  "type": "dep_group",
  "previous_output": {
    "index": "0",
    "tx_hash": "0x04e427..."
  }
}

Example header dep:

{
  "type": "header",
  "header_hash": "0xabcdef..."
}

Output Data Structure

The outputs data in the transaction is just an array of bytes.

Script Structure

The field scripts in the transaction is an array of scripts.

The script has added a new field hash_type.

  • code_hash: When hash_type is “Data”, it references a cell in the deps which data hash equals this value. When hash_type is “Type”, it references a cell in the deps which type script hash equals this value.
  • hash_type: available values are “Data” and “Type”
  • args: an array of bytes passed to script.

Dep Group

Dep Group references a bundle of cells as deps using only one dep slot. It solves two problems:

  • We want to reduce the block size, but the default secp256k1 is too large to fit in a block.
  • If we split the secp256k1 into multiple deps, every transaction that unlocks a secp256k1 locked cell must add all the deps, which wastes a lot of spaces.

A Dep Group is a normal cell, which data is the serialized list of out points (a pointer to a cell via transaction hash plus output index).

The dep group is added into a transaction as a dep of type dep_group. For script, the transaction is identical by replacing the dep group with its member cells as deps.

Which is considered identical to expand the members in place:

Type ID

In original design, script matches a dep cell by data hash. When the script code has to update, the data hash changes, leaving existing cell still using the old code.

The new cell model allow a script matches dep via type hash. See the changes in script structure above.

Instead of creating cell which uses frozen code as lock and type scripts, we can now reference to upgradable code.

Since it is easy to forge a cell with identical type script with existing live cell, we add a special contract to guarantees the uniqueness.

The contract uses a special code hash, let’s assume that it is H. We call the hash of the type script which code hash is H, and hash type is “Type” to be the type id of the cell.

  • It’s impossible to create two cells with the identical type id in the same transaction.
  • It is impossible to create a cell with a type ID which equals to an existing live cell, except that cell is in the transaction inputs.

Type ID Creation

A transaction can only create one cell with a new type ID. The “new” means the type ID never appears in dead and live cells.

The new cell type ID must be:

  • code hash is H
  • hash type is “Type”
  • args contains a single H256, which equals to the blake256 hash of all inputs of the transaction.

Type ID Inheritance

Cell with type ID can update the data and keep the type ID. A transaction can contains multiple type ID inheritances.

4 Likes

不觉明历 只能 :+1: