Nervos Blockchain

https://docs.nervos.org/docs/basics/concepts/nervos-blockchain

How does a transaction occur in Nervos?

https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0002-ckb/0002-ckb.md#3-consensus

  1. Provide input cells and output cells.

  2. Lock scripts (of the referenced cells) are executed when the cell is referenced by a transaction input. It ensures the user has appropriate permissions to update / transfer the cell.

  3. type scripts contained in input / output cells are ran to validate the input / output cells, to make sure it’s valid.

How do lock scripts verify if a user has appropriate permissions?

https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md

  • An input cell with public key in the args.

  • Signature contained in witnesses field. This signature is usually of the whole transaction.

  • NOTE: Also the script code can read ANY part of a transaction.

  • Via proofs - how are these proofs supplied?

How do type scripts validate a cell’s state?

  • Establish contracts on the cells.
  • Example: User defined token (UDT)
  • Runs on both input and outputs.
  • Ensures that cell passes verification when it is produced and consumed.
  • type script must run on output for UDT, to ensure token issuance is authorized.
  • type script must also run on inputs, to ensure that a user consuming cells does not do things like produce new outputs without type scripts. (Recall it can do so because it has access to the entire transaction).

What happens when hash_type inside a code cell is type?

TODO: See https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md#type-id

Will having both a lock script and type script cause conflicts?

Some contracts, e.g. SUDT from Nervos only have type script.

Why is transaction hash unique?

https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md

Computed from all tx fields, less witness.

TODO: See appendix A.

How to reference a cell?

Tx hash is unique -> reference a cell by tx + the output cell idx.

Wait… but what about root cells, do these have txs too?

How is code stored?

Via a code cell - in its data field.

How is code referenced?

In each cell, there are script, which contain code_hash, hash_type and args.

In each transaction, there’s CellDep which points to the cell with code.

  1. hash_type is data.
  2. code_hash match the hash of the binary (i.e. the compiled risc binary of the script code).

What are addresses in CKB?

How do these relate to scripts and the rest of things?

They are a way to refer to specific lock scripts.

There are 3 types of encodings:

  1. Popular code_hash
  2. Data hash_types.
  3. Type hash_types.

How are scripts deployed?

What’s the process?

Once we compile and build the binary, what happens next?

Do we have a tx hash as well?

How does it make it into the blockchain?

What’s the exact transaction we have to construct?

What happens if it’s a root cell, i.e. newly minted.

How are cells created on the blockchain?

Do we have to mint these cells?

What is the difference between hash_types?

Hashtype=data means that your codehash refers to a hash of actual script code, which is contained in a dep cell.

Hashtype=type means that your codehash refers to a typescript instead, which is contained in a dep cell. a typescript. This is an instance of the script code, with specific arguments attached.

What’s the point of distinguishing between these two?

We have different types of natures of script types.

  1. Suppose we have a secp256k1 script code for verifying public keys. When referencing the script code, we would of course then use a hash_type=data However, if we wanted to lock a cell using a specific public key, we would want a specific instance which validates against this public key. Hence we would use a hash_type=type.

  2. Suppose we have a script code which provides implementation for SUDT. We could also want to have different args for different types of tokens. In this case, we would want our script to have hash_type=type, referencing a specific type of token.

Are celldeps required for only code? Or any input cell referenced requires a celldep as well?

Nope, celldeps are read-only. Hence, they should only be used to reference data / code.

See the table in: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0019-data-structures/0019-data-structures.md#Transaction The section for cell_deps indicates this property.

How do we reference input cells again?

We use { previous_output: [OutPoint] } to reference them.

Where OutPoint is a product of tx_hash and index, used to index the exact cell in the transaction generating the input cell.

See: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md#part-i-core-features

How are arguments structured in Nervos RPC?

Passed in via an array, deserialized to function arguments, this is implemented using a macro from rpc-derive.

What is the transaction validation lifecycle?

See: https://docs.nervos.org/docs/essays/lifecycle

What happens when a transaction gets sent over JSON_RPC?

transaction := normalTx | malleableTx
transaction = {
  <original fields>
  rebase_script: Option<...>
  cell_indices: Option<...>
}
  1. Client constructs the tx
  2. sends the tx over the JSON_RPC to the ckb node send_transaction -> We do a check to see if it’s a malleable tx. -> We put it in a separate pool to avoid the validation part.
  3. Runs the validation logic within the node.
  1. resolve inputs
  2. verification checks like capacity, duplicate deps, etc… validate script (lock and type scripts).
  1. Your transaction has passed validation. So it gets passed on the txpool.
  2. The miner at this point can query get_block_template, get_malleable_txs. So inside the response body you would also have the resolved transactions. And then after solving the puzzle, you would be able to also commit these txs.

Scenarios:

  1. Validation succeeds, consumed before miner commits the block.
  • Node regularly tell the miner which inputs were consumed.
  • Just let the miner produce a block which is invalid.
  • PoC: it’s fine, it can just do whatever it does not.
  • Production: We want to shortcircuit, and deal with this properly.
  • How do we trigger the rebase here?
  • Someone needs to keep track of inputs -> malleable txs.
  • When these inputs are updated -> malleable txs need to be rebased.
  • There is someway that information flows into the ckbnode. (Blocks which can indicate inputs are consumed.)
  • When the node receives a malleable tx, it should store a map between input hashes to txs.
  • The miner has to do the rebasing then.
  • And then the miner would resubmit the tx (note that we should preserve the malleability property?).
    • Remember to remove it from the map.
  • NOTE: The ckb node is the one which does the rebasing, also it has the execution environment for the rebase script.
  1. Validation fails.