Type Id is a digest of a unique type script.
The unique type script consists of three parts:
code_hash: type id contract code hash
The uniqueness of the generated type script is guaranteed by the
type id contract and
hash(this_transaction.input) | output_index_of_this_cell since
No man ever steps in the same river twice, for it’s not the same river and he’s not the same man.
type id contract checks if the
unique_type_script.args matches the
deployment_transaction.inputs. Once it’s deployed on the chain successfully, the
deployment_transaction.inputs cannot be used to deploy the same
unique type script again since it’s comsumed, like the water gone, i.e. the
unique_type_script.args cannot be used to deploy again and the uniqueness of the
unique type script is promised.
The contract cell, i.e. the cell dep referenced in a transaction, is upgradable when it’s located via its type script. By deploying a new cell with new contract code but having the same type script as the deprecated one, it can be indexed by the same
[code_hash, hash_type] conditions.
graph LR id1[code_hash: hash_a, hash_type: type]-->|OutPoint of Deprecated Cell|id2[Deprecated Contract] id1[code_hash: hash_a, hash_type: type]-->|OutPoint of Latest Deployed Cell|id3[Latest Deploayed Contract]
By this way, an attacker can deploy a malicious contract with the same type script of the targeted contract to bypass script validation and confuse users.
graph LR id1[code_hash: hash_a, hash_type: type]-->|OutPoint of Deprecated Cell|id2[Deprecated Contract] id1[code_hash: hash_a, hash_type: type]-->|OutPoint of Latest Deployed Cell|id3[Latest Deploayed Contract] id1[code_hash: hash_a, hash_type: type]-->|OutPoint of Malicious Cell|id3[Malicious Contract]
An exclusive type script is necessary in this mode.
There are 4 rules to deploy an unique type script(with unique
Count how many output cells use current type script, if there’re more than one cell with current type script, throw an error since an attacker is trying to create more than one cells with the same type script, which is not expected.
Count how many input cells use current type script, if there’s only one input cell with the current type script, return success.
Use CKB Syscall to read the first input’s OutPoint in the current transaction and if it matches the
argsfield of the type script, return success.
- Since the first input can only be comsumed once, its unique OutPoint guarantees the uniqueness of the type script.
- An attacker cannot use the same
argsto deploy the type script since the unique cell has been consumed.
Otherwise throw an error.
Simply hash the type script
hash([codeHash, hashType, args]) | output_index
Since Type Script is used, the contract depends on it has
hash type = type.
In this case, the ckb vm loops all cell deps and try to find a dep whose type script has the corresponding
Once a cell dep meeting the condition is found, it’s used as the dependency of the contract.
type id contract can be implemented in CKB VM, but now it exists in CKB node as a system script and can be referenced by a special code hash, ascii code in hex of the text