The latest post is here
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.
- Modified transaction structure
- Added new feature Dep Group, which references multiple cells as deps using only one out point.
- 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 bydata_hash
.lock
is replaced bylock_hash
.- If the cell has a
type
, it is replaced bytype_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 typecell
. 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
: Whenhash_type
is “Data”, it references a cell in the deps which data hash equals this value. Whenhash_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.