Skip to content

Commit b47cd2c

Browse files
committed
docs: add a draft of kuai proposal
Add a draft of kuai proposal to elaborate on the motivation, design and schedule.
1 parent 331278d commit b47cd2c

File tree

1 file changed

+321
-0
lines changed

1 file changed

+321
-0
lines changed

README.md

Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
## Problems to solve
2+
3+
There are three obvious obstables hindering the development of DApps on CKB.
4+
5+
### First: separate runtimes
6+
7+
CKB adopts Cell model which is a generalization of UTXO model so only a **function of state verification** is running on-chain, that's the core of a DApp and theoretically that's all of a DApp.
8+
9+
But a real-word DApp is for users who are not good at mathematics or programming so the logic of the DApp will be exposed by a graphical interface and a set of prescribed actions. The team of a DApp has to
10+
11+
1. re-implement **function of state verification on-chain** off-chain for testing;
12+
2. define a **state transition equation** following the **function of state verification** for prescribed actions;
13+
3. define algorithms to get ideal parameters for the **state transition equation**, namely `input cells` from CKB, and implement a server to map kv data into relational data for graphical interface.
14+
15+
A mass of off-chain works are introduced because runtimes of on-chain and off-chain are separate and follow exclusive paradigms.
16+
17+
**function of state verification on-chain** is totally a pure function which returns code_0 for success and code_other for failure, all its arguments are determined so the result is predictable.
18+
19+
**function of state verification off-chain** is a rehearsal or replay of **function of state verification off-chain**, they share the same logic but the one off-chain may be re-implemented because the one on-chain is based on rust which is hard for most programmers.
20+
21+
**state transition equation** is reversed from the **function of state verification**, this is easy to understand and used in ethereum contract,
22+
23+
```
24+
// let's define the function of state verification and expect it be be 0
25+
fn(action)(current_state, new_state) = 0
26+
27+
// then the state transition equation will be deduced
28+
new_state = fn'(actions)(current_state)
29+
30+
// and we get the state transition function
31+
const fn_transition = fn'(actions)
32+
```
33+
34+
What's even crazy is that **state verification** is **functional** while **state transition** might be of **object-oriented** style because `actions` in `fn'(actions)` is from a set of pre-defined actions on graphical interface and could be pipelined.
35+
36+
Besides, the **function of state transition** has only one parameter `current_state`, which is determined by algorithms of gathering cells on-chain, the algorithms will be realized by complex mechanism due to consideration of engineering and concurrency issues caused by cell model.
37+
38+
These concepts are too obscure and leading to a steep learning curve for DApp developers.
39+
40+
### Second: Lack of development paradigm
41+
42+
There's no clear and unified paradigm for development, every DApp project could have various assumptions, project structure, workflow, and APIs. By the variety, each DApp grows into an insulated island because it takes too much to understand the design, implementation of a DApp. It's also hard to interoperate another DApp because its APIs are unpredictable.
43+
44+
### Third: Fragmented devtools
45+
46+
Now there're many devtools for specific goal or domain but it takes too much to master them all.
47+
48+
#### Contract development
49+
- Capsule: https://github.com/nervosnetwork/capsule, a development framework for creating smart contract scripts in Rust for Nervos' CKB layer 1 blockchain. Capsule is designed to provide an out-of-the-box solution that helps Nervos developers accomplish common tasks quickly and painlessly.
50+
- CKB standalone debugger: https://github.com/nervosnetwork/ckb-standalone-debugger, a standalone debugger enabling off-chain contract development.
51+
52+
#### Local network
53+
- Tippy: https://github.com/nervosnetwork/tippy, tippy is a sandbox development environment available to Nervos CKB developers. Throughout the development cycle, developers can use Tippy, which allows them to develop, deploy and test DApps in a secure and deterministic environment.
54+
55+
#### Aggregation service
56+
- CKB Indexer: https://github.com/nervosnetwork/ckb-indexer,a standalone service for creating cell and transaction indexes as an alternate solution.
57+
- Lumos: https://github.com/ckb-js/lumos, lumos is a full-featured JavaScript/TypeScript based DApp framework for Nervos CKB.
58+
- Mercury: https://github.com/nervosnetwork/mercury, building on top of ckb-indexer, Mercury provides handy integration features for Nervos CKB.
59+
60+
61+
What's worse, some DApp teams found the devtools are not enough for them so they have to develop tools for themselves, leading to more fragmented.
62+
63+
## How other ecologies are solving these problems
64+
65+
For the separate runtimes issue introduced by UTXO model, there's a framework named `run`(https://run.network/) aiming at propagating a token protocol for universal DApps.
66+
67+
A data model named `Jig` is brought in as the most basic unit of an interactive object to build a skyscraper from bricks. Imagine we are building a toy vehicle with lego blocks, every two blocks can be easily connected even they are in various shapes because they share a unified interface.
68+
69+
![](https://www.lego.com/cdn/product-assets/element.img.lod5photo.192x192/6037890.jpg)
70+
71+
And all advanced data models are derived from `Jig`, like `Code`, `Token`, work for specific functions, can be connected to each other because they share the most basic interfaces.
72+
73+
![](https://www.lego.com/cdn/product-assets/element.img.lod5photo.192x192/6276858.jpg)
74+
![](https://www.lego.com/cdn/product-assets/element.img.lod5photo.192x192/6345886.jpg)
75+
76+
In terms of development paradigm and devtools, ethereum community has given a good enough answer. The most popular development framework in ethereum community is `hardhat`(https://hardhat.org/), which names itself as **professional development environment** and is super similar to a mature build system.
77+
78+
It takes care of building/debugging/testing/deployment and is extensible by plugins and tasks so developers could finish their work within a framework.
79+
80+
By the support of hardhat, projects will follow the same convention and generate a contract-specific SDK for outside users.
81+
82+
83+
## Kuai Project
84+
85+
`Kuai` project is a framework to solve problems mentioned above, inspired by [actor model](https://www.wikiwand.com/en/Actor_model), [run](https://run.network/), [hardhat](https://hardhat.org/) and other tools popular in the community.
86+
87+
`Kuai` includes a unified paradigm for development, a set of conventions, fine-grind all-in-one devtools with SDKs and a general aggregation service.
88+
89+
### Unified paradigm for development
90+
91+
Two abstractions will be promoted in `Kuai`: `Data storage` and `Data manipulation`
92+
93+
#### Abstraction of data storage
94+
95+
There'll be three basic data models used in `Kuai` based DApps: `Data`, `Code`, `MultiCoin Token`
96+
97+
##### Data
98+
99+
The basic function of cells in CKB is storing data. But data are meaningless without schema, so the first basic model introduced by `Kuai` is named `Data` which is used to transform plain data into a structured data with schema.
100+
101+
Note that a `Data` model could be a group of cells matching the same pattern and working as an entity so it could be regarded as a virutal DApp. Say we have 2 DApps in `School Roster Data` models, each of them consists of many `Student Data` models. And we are going to build a `Sports Meeting` DApp, a new `Sports Meeting Data` model could be created and consists of partial `Student Data` from School A and B respectively, it should work as same as a `School Roster` DApp.
102+
103+
##### Code
104+
105+
`Code` model is extended from `Data` model and used for scripts. A `Code` model has not only attributes, but also methods. In other words, it's not only read-/writable, but also executable. `Code` model's data/state could be updated by some rules rather than a simple `set` method inherited from the `Data` model.
106+
107+
##### MultiCoin Token
108+
109+
Token is a general use case that should have ability of transferring between DApps, so the third model to introduce is `MultiCoin Token`, which is specialized from `Code` model with specific attributes and methods.
110+
111+
#### Abstraction of data manipulation
112+
113+
DApps can read states from each other freely because data/states are arranged uniformly by the abstraction of data storage.
114+
115+
DApps can also communicate with each other freely if data manipulation has been abstracted.
116+
117+
##### Data
118+
119+
A `Data` model should have 7 basic interfaces
120+
121+
- New(pattern): create an `Data` model binding to specified cells, as a DApp located by the pattern, ps: it's a virtual DApp rather than an explicit DApp, but because cells are following the same rule, they can work together as an entity.
122+
- Destroy(): remove state and turn the cells into empty
123+
- Duplicate(): create a `Data` model from a instance
124+
- Sync(blockNumber?): will load and update data from the chain at latest(or specific block) global state
125+
- Get(path): will read value of specified path
126+
- Set(path, value): will set given value at specified path
127+
- Delete: (path): remove key/value at specified path
128+
129+
##### Code
130+
131+
A `Code` model should have 5 more interfaces than `Data` model
132+
133+
- Deploy(): deploy the script on the chain
134+
- Extend(code): extends from an existing `Code` model for overriding
135+
- Upgrade(): upgrade the script on the chain
136+
- Run(method: string, params: Array<any>): call a method of the script to update its state
137+
- Link(abi: Array<object>): instantiate a script SDK from ABI
138+
139+
##### MultiCoin Token
140+
141+
A generally used token must have some methods based on `Code`
142+
143+
- Metadata(tokenId, metadata?): a setter/getter to the metadata of a specific token id including `name`, `symbol`, `tokenURI`, `totalSupply`)
144+
- Mint(tokenId, amount): Mint a token
145+
- Send(from, to, tokenId, amount): Send a token
146+
- Stake(address, dapp, tokenId, amount, locktime?): stake into a dapp and get staking tokens
147+
- Redeem(address, dapp, tokenId, amount): unstake from a dapp and burn a staking token
148+
- Lock(address, amount, tokenId, locktime): lock tokens, for cases like pre-sale, bounty of a team
149+
- Unlock(address, tokenId, amount): unlock tokens
150+
- Combine(token): combine two `MultiCoin Token` models into one
151+
- GetBalance(address, tokenId): get token balance of a given address
152+
153+
154+
Notice, all actions will be grouped and finalized together, viz. `mint`/`send` multiple token id will be finalized with a single transaction
155+
156+
#### Reactive Lazy Evaluation
157+
158+
As mentioned above
159+
160+
> Notice, all actions will be grouped and finalized together, viz. `mint`/`send` multiple token id will be finalized with a single transaction
161+
162+
All actions/manipulations adopted on a model will be cached and evaluated at the end of the pipeline.
163+
164+
```
165+
const model = new Data()
166+
model.action_1()
167+
model.action_2()
168+
// ...
169+
modeol.action_n()
170+
171+
/**
172+
* get a structure with initial state and actions
173+
*
174+
* {
175+
* state,
176+
* actions: [action_1, action_2, action_3, ..., action_n]
177+
* }
178+
*
179+
* and calling the finalize() to evaluate new state
180+
*/
181+
182+
model.finalize()
183+
184+
/**
185+
*
186+
* {
187+
* state: new_state,
188+
* actions: [],
189+
* }
190+
*
191+
*/
192+
193+
```
194+
195+
Lazy evaluation is beneficial to the following points:
196+
197+
1. state of the model could be traversed for debugging
198+
2. actions could be revoked easily to find the best path of state transition.
199+
3. inspector(or other dependencies) could be injected to enhance development
200+
201+
#### Model Tree
202+
203+
There would be multiple levels of `Data` models constructing a model tree.
204+
205+
Every cell on CKB could be treated as a DApp because every cell has its own state and script while a group of cells using the same script should also be treated as a DApp because they adopt the same logic on a broader state.
206+
207+
Besides, if a DApp_A wants to interact with another DApp_B, stateof DApp_B would be a part of DApp_A's state so the models would be like
208+
209+
```mermaid
210+
flowchart BT
211+
212+
cell_a_0_model --> dapp_a_sub_model
213+
cell_a_1_model --> dapp_a_sub_model
214+
cell_a_n_model --> dapp_a_sub_model
215+
dapp_a_sub_model --> dapp_a_model
216+
217+
cell_b_0_model --> dapp_b_model
218+
cell_b_1_model --> dapp_b_model
219+
cell_b_n_model --> dapp_b_model
220+
dapp_b_model --> dapp_a_model
221+
```
222+
223+
### Conventions
224+
225+
`Kuai-convention` is a set of conventions for the implementation reference of `Kuai-runtime` and the usage guide of `Kuai-runtime`, such as:
226+
227+
- serialization - cell state layout to prevent conflict between different contract interactions
228+
- ABI - Application Binary Interface for cell model
229+
- structure - project structure
230+
- sequencer - define how to sort (aggregate) user requests
231+
- storage - A series of schemes on how to persist data, such as serialization schemes, etc.
232+
233+
### Fine-grind devtools
234+
235+
The paradigm and conventions will be instructed by `Kuai` with a fine-grind devtool named `Kuai-runtime`, similar to nx(https://nx.dev/) which provides basic features of a build system and extensible for tasks and plugins.
236+
237+
Basic features delivered by `Kuai` build system:
238+
- Clear project structure
239+
- Compile
240+
- Debug
241+
- Release
242+
- Debug
243+
- Break point
244+
- Console
245+
- Inspector
246+
- Test
247+
- Run specific cases
248+
- Generate a mock transaction
249+
- Helpers as clear state, rollback
250+
- Deployment
251+
- Configuration management
252+
- Multiple network
253+
- Hd wallet
254+
- Base contracts/scripts
255+
256+
Possibly included tasks/plugins are as follow:
257+
- cycle reporter
258+
- script sizer
259+
- test-coverage
260+
- document
261+
- debugger remover
262+
- typechain: https://github.com/dethcrypto/TypeChain/
263+
- storage layout: https://www.npmjs.com/package/hardhat-storage-layout, when to use on-chain/off-chain data
264+
265+
`Kuai-runtime` covers on-chain and off-chain parts of a project, implements the interface defined by `Kuai-convention`, shielding implementation details and provides easy-to-use APIs.
266+
267+
`Kuai-runtime` also provides friendly libraries/modules for building, sending, and managing transactions, which will be elaborated on in section `General aggregation service`.
268+
269+
### General aggregation service
270+
271+
Now there are two classic types of DApp running on CKB
272+
1. based on the general cell model: e.g. Force Bridge, Portal Wallet...
273+
2. based on the SMT(sparse merkle tree, https://github.com/nervosnetwork/sparse-merkle-tree) half-rollup like: e.g. CoTA NFT, dotbit, sub-accounting...
274+
275+
`Kuai`'s aggregation service would cover these two cases for general usages and has following components:
276+
277+
- Merkle X Storage - Generate proof which stored in on-chain. And persist data in off-chain.
278+
- Sequencer - Combine multiple requests into one to avoid [concurrency issue](https://iohk.io/en/blog/posts/2021/09/10/concurrency-and-all-that-cardano-smart-contracts-and-the-eutxo-model/).
279+
- Transaction Builder Factory (OnChainStateUpdator) - Build transactions that update on-chain state.
280+
- CkbNodeClient - Interact with chains, such as query transaction status, etc.
281+
- Client-side SDK - Common wallet integration, e.g MetaMask(sign via EIP712 if possible), TronLink, CardanoWallet…
282+
- Scheduler - Scheduling various sub-services, such as Sequencer and Merkle X Storage.
283+
284+
![runtime-level drawio (2) (1)](https://user-images.githubusercontent.com/107106858/190947666-bfbdd975-1f04-4fc4-841c-37b357e31e75.png)
285+
286+
The aggregation service would run as a sub module in DApp's server
287+
288+
![kuai-runtime drawio (2) (1)](https://user-images.githubusercontent.com/107106858/190947648-4a8f401b-955c-4e90-b84e-b6f6e802dad5.png)
289+
290+
291+
## Website
292+
293+
Last but not least, as an open source project, `Kuai` would be introduced to developers with good documentation and rich examples, including:
294+
- Tutorials
295+
- Developer Documentation
296+
- API documentation
297+
298+
## Roadmap
299+
- M1 ~ M2
300+
- Construct a build system similar to https://nx.dev/, only for project structure, basic tasks, and plugins
301+
- Design storage paradigm
302+
- Design action paradigm
303+
- Design workflow with base contracts/scripts
304+
- M3 ~ M4
305+
- Implements SDK following the designed paradigm and workflow with base contracts/scripts
306+
- Design generally used tasks and plugins
307+
- Cycle reporter
308+
- Script sizer
309+
- Test-coverage
310+
- Document
311+
- Debugger remover
312+
- Typechain: https://github.com/dethcrypto/TypeChain/
313+
- Storage layout: https://www.npmjs.com/package/hardhat-storage-layout, when to use on-chain/off-chain data
314+
- Design local network debug/test/deploy tools
315+
- M5
316+
- Implement tasks/plugins
317+
- Implement local network
318+
- Implement debug/test/deploy tools
319+
- M6
320+
- Use the project to deliver a simple .bit dapp
321+

0 commit comments

Comments
 (0)