This article was first published on the Nervos Chinese community public account.

I'm a Linus fan. He created an open source operating system that is everywhere, co-authored a book that I absolutely love, and built a distributed version control system that nearly every developer uses every day.

I started using Git the moment I saw it and was attracted by its speed and elegance. Developers use version control systems [1] to manage source code, so they can keep track of code updates, share changes with friends and colleagues, roll back to previous bug-free versions when new errors occur, and more. Git makes life more fun, and I hope CKB can do the same.

Image

CKB is Git

Our process of creating CKB and Cell models was inspired by Git. Git emerged out of Linus' desire to make Linux kernel development easy, and it could be used whenever people wanted to organize something, from comments to blog posts to images. It is a knowledge base supported by excellent history tracking capabilities.

The Git repository is called a "repository" and internally maintains an immutable append-only object database (remember that?). The basic storage unit in Git is a Blob (binary large object), which is an object containing the data that people store in the repository, just like a Cell in CKB. Git creates a blob object for each version of each file. Whenever a new file is created, a new blob is created. Whenever an existing file is modified, a blob is created with new content without modifying the old blob (sound familiar?). Each blob is hashed, and the blob hash is used as an identifier to reference the blob. After working for a few hours, you create some new files and modify some existing files, commit all your changes to the repository, sync the new commits to your colleagues, and call it a day.

A commit is the basic history point in Git, and a repository history consists of a sequence of commits from the origin of the repository to the most recent update. A commit is a version of the repository at a specific time and includes version metadata such as author, timestamp, previous commit, and reference to the blob tree. Just like the block header holds metadata for every update to the blockchain by writing down the miner address, timestamp, parent block hash, and the root of the transaction merkle tree. You and your colleagues get paid by extending the history of your git repository, just like miners get block rewards by extending the history of blocks.

Git repositories can also have Forks. People work on different branches, but which branch is "correct" is decided by the repository maintainers, not by consensus. Git is a distributed system without consensus that relies on special peer-to-peer communication (such as ssh or email) for data exchange.

There are similarities between Git and blockchain, which also means that we should be more cautious about incorporating Git ideas into blockchain, and should not introduce conflicting design choices into blockchain. Blockchain or smart contract developers can enjoy some of Git's proven advantages. This is what CKB is really like on the inside: the only large-scale Git repository with a true p2p network, global consensus, and enhanced blobs, constantly updated by a group of anonymous people.

Image


This is not a blockchain

Name the Cell how you like

The core of Git and CKB are data objects (blob/cell) and hash references. A hash reference is the inherent name of an object, a magic wand you can wave to extract the value of the data. If you know the name of an object, you can reference it and thereby gain access to its power. On CKB, the code of smart contracts and user data are separated, so hash references allow you to directly name a piece of code or user data, making them first-level objects in the system [2]. This fine granularity creates a flexible and powerful programming model. Here are some examples.

Reuse code/data

Because cells are referenceable storage units, reusing code/data on CKB is easy. Suppose there is some shared code/data stored in cell 0xbee#1(output 1 of transaction 0xbeef), to reuse it, first you need to load cell 0xbee#1as transaction dependency (cell_deps) and then read from it using ckb_load_cell_data system call Get the data as shown in the default lock script. Once the data in cell 0xbee#1is loaded into VM memory, it can be used as code or data, depending on your needs [3]. In this way, CKB acts like a shared library of code and data for use by smart contracts running on it. Wouldn’t it be cool if we could build a smart contract [4] by combining existing secure LEGO bricks? Instead of copying code from somewhere on GitHub and deploying the same code again and again, which wastes time and space on the chain. An analysis of Ethereum contracts [5][6] shows that 95% to 99% of contracts are duplicates.

Image


No fear of dependency deletion

In the code/data reuse example above, you don't need to worry about someone modifying the code/data stored in the dependent cell because the cell is immutable, that is, no one has a way to modify it. But what if the owner of the dependent cell directly deletes it from CKB? Will that make my smart contract unusable?

This is indeed the case on Ethereum. If you’ve been in this space long enough, you might be aware of the 2017 incident involving a $280 million incident [7]. The entire tragedy was triggered by the accidental deletion of a smart contract on Ethereum that was used by many other smart contracts. This deletion caused all smart contracts that relied on it to become dysfunctional and all assets stored in these smart contracts were frozen.

On CKB, such an accident will have no impact, because anyone who saves a copy of the code (such as those running a full node or a complex light client) can deploy the same code again on the chain, and the code hash The quote is still valid. We just need to construct the transaction using the new dependency cell. No one will suffer and everything will still work as normal.

Image

In fact, we can even intentionally use this to achieve "use first and then deploy" the code. Let's say you want to use a new custom locking script (smart contract) to protect your cells. Unlike the usual deploy-then-use process, you can use it without deploying. You only need to put the code hash of the new lock script (code implementation) into the cell lock (code usage), and then these cells will be protected by the new lock and take effect immediately.

Deployment of the actual locking script code can be delayed until you want to unlock those cells. If you want to unlock, you first need to deploy script code on the chain, and then send another transaction to unlock these cells as usual. After the cell is unlocked, you can delete the deployed code and claim back the occupied CKBytes to reduce unnecessary storage costs. The added benefit of using it first and then deploying it is better privacy: no one knows what the logic of this new lock is until you unlock it.

Evolved CKB

After understanding the similarities and advantages between CKB and Git, let's explore a more interesting question: If CKB is a git library, can we use CKB to manage CKB's code?

Yes! This is why some CKB core functions, such as transaction signature verification [8] and Nervos DAO [9], are implemented in the form of smart contracts. Take transaction signature verification as an example - this is a core feature of almost all blockchains and is hard-coded in native languages ​​(e.g. C in Bitcoin, Go in go-ethereum).

In order to upgrade a blockchain, one must distribute and deploy a new software version (soft/hard fork) on a majority of nodes, which requires a lot of coordination. For CKB, transaction signature verification can be upgraded like other smart contracts by deploying a new version on the chain. This gives CKB the long-term scalability proposed by Tezos [10].


We can do better. On CKB, each user owns his or her own data, so a contract is more like a two-party agreement between the user and CKB, and individuals can make independent choices. If you use a contract via a code hash[11], it means "I agree to this specific version of the contract." You don't have to worry that one day developers will upgrade the contract code, because the code hash of the new contract is different, and your lock/type will still refer to the old contract instead of the new one. After the new version is deployed, it will coexist with the old version in the system. If you use the system contract through its code hash, the new version will not affect you and you can decide whether to upgrade. If the answer is yes, then you can update all cells to use the new version. If no, nothing needs to be done and you continue to use the old version.

This is a friendly guarantee for holders who may not be online often, as they can guarantee that the contract attached to their cell at creation time will not be changed. People's assets will always be locked the way they specified when they were locked. This is the ultimate guarantee for SoV users and is what makes CKB assets different from other assets on the blockchain. This is the same as Bitcoin providing protection to holders by "only following soft forks". The only drawback is that you run the risk of being "too late" when it comes to security upgrades. Therefore, for the sake of convenience, some people may still like to always use the latest version because they trust the development team and do not need to worry about reviewing contracts and manual upgrades. In this case, they will use type id[12] to reference the contract . Roughly speaking, type id is similar to HEAD in Git, an updatable reference always points to the current version. By providing these two options (referenced via code hash and referenced by type id) we give the power back to the user to choose the appropriate upgrade strategy. It's always good to have options. We can have different choices and no one will be forced to upgrade.

Image

In the long run, CKB will become increasingly abstract and modular, and more core functions will be extracted and implemented in on-chain smart contracts. In its complete form, we should be able to upgrade CKB without going through a soft/hard fork. The missing link is, how do we, the community, decide whether to upgrade the system contract or not, or what is the governance model of CKB? More precisely, it is how we decide to upgrade the type id of a system contract.

Today, CKB uses the same off-chain governance model as Bitcoin, and we still rely on soft/hard forks. In order for anyone using its type id reference to enable a new version of system scripts, a hard fork is required to update the type id reference to point to the latest version, because the code cell is locked by an unlockable lock (https://explorer.nervos. org/address/ckb1qgqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqhzeqga, check its code hash). Not using multi-signature locks controlled by the core team is an intentional choice, as upgrades to system scripts should follow governance decisions made by the community.

As we said in our positioning white paper, while there are many interesting proposals, we have yet to see a practical governance model. Once we find a suitable governance model, we can use "governance locks" to replace non-unlockable locks, allowing system smart contracts to be upgraded with community consent, such as the results of voting. Until then, we will stick to the imperfect off-chain governance model for the time being, but#CKB The backbone of governance and evolution already exists. $CKB ≠≠

Ref:

[1]:https://en.wikipedia.org/wiki/Version_control

[2]:https://talk.nervos.org/t/first-class-asset/405

[3]:https://github.com/nervosnetwork/ckb-system-scripts/blob/master/c/secp256k1_helper.h#L40-L66

[4]:https://talk.nervos.org/t/rfc-swappable-signature-verification-protocol-spec/4802

[5]:https://www.researchgate.net/publication/332799463_Characterizing_Code_Clones_in_the_Ethereum_Smart_Contract_Ecosystem

[6]:https://security.cse.iitk.ac.in/sites/default/files/17111011.pdf

[7]:https://medium.com/hackernoon/what-caused-the-latest-100-million-ethereum-bug-and-a-detection-tool-for-similar-bugs-7b80f8ab7279

[8]:https://github.com/nervosnetwork/ckb-system-scripts/blob/master/c/secp256k1_blake160_sighash_all.c

[9]:https://github.com/nervosnetwork/ckb-system-scripts/blob/master/c/dao.c

[10]:https://tezos.com/ 

[11]:https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md#upgradable-script

[12]:https://docs.ckb.dev/blog/ckbscript-06