Skip to content

Commit db791f4

Browse files
committed
docs: update draft of kuai proposal
1. rename models to `Store`, `Contract` and `Token` 2. complement details added in #5 3. add some promising features
1 parent 3dbad76 commit db791f4

File tree

1 file changed

+90
-33
lines changed

1 file changed

+90
-33
lines changed

README.md

Lines changed: 90 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -90,53 +90,57 @@ Two abstractions will be promoted in `Kuai`: `Data storage` and `Data manipulati
9090

9191
#### Abstraction of data storage
9292

93-
There'll be three basic data models used in `Kuai` based DApps: `Data`, `Code`, `MultiCoin Token`
93+
There'll be three basic data models used in `Kuai` based DApps: `Store`, `Contract`, `Token`
9494

95-
##### Data
95+
##### Store
9696

97-
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.
97+
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 `Store` which is used to transform plain data into a structured data with schema, similar to [ORM](https://www.wikiwand.com/en/Object-relational_mapping)
9898

99-
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.
99+
Note that a `Store` 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 Store` models, each of them consists of many `Student Store` models. And we are going to build a `Sports Meeting` DApp, a new `Sports Meeting Store` model could be created and consists of partial `Student Store` from School A and B respectively, it should work as same as a `School Roster` DApp.
100100

101-
##### Code
101+
<sub>Sidenote:
102+
For JavaScript developers, the `Repository` concept in [TypeORM](https://github.com/typeorm/typeorm/blob/master/docs/working-with-repository.md) is quite similar, or to say, `Store` is a simplified `Repository` in TypeORM. `Store` has its own schema and accepts a pattern to load data from CKB, just as `Repository` accepts an `Entity` and builds a query string to load data from database.
103+
<sub>
102104

103-
`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.
105+
##### Contract
104106

105-
##### MultiCoin Token
107+
`Contract` model is extended from `Store` model and used for scripts. A `Contract` model has not only attributes, but also methods. In other words, it's not only read-/writable, but also executable. `Contract` model's data/state could be updated by some rules rather than a simple `set` method inherited from the `Store` model.
106108

107-
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.
109+
##### Token
110+
111+
Token is a general use case that should have ability of transferring between DApps, so the third model to introduce is `Token`, which is specialized from `Contract` model with specific attributes and methods. Especially, a `Token` model is a collection of tokens, similar to [ERC 1155](https://eips.ethereum.org/EIPS/eip-1155) that represents multiple token types in one model.
108112

109113
#### Abstraction of data manipulation
110114

111115
DApps can read states from each other freely because data/states are arranged uniformly by the abstraction of data storage.
112116

113117
DApps can also communicate with each other freely if data manipulation has been abstracted.
114118

115-
##### Data
119+
##### Store
116120

117-
A `Data` model should have 7 basic interfaces
121+
A `Store` model should have 7 basic interfaces
118122

119-
- 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.
123+
- New(pattern): create an `Store` 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.
120124
- Destroy(): remove state and turn the cells into empty
121-
- Duplicate(): create a `Data` model from a instance
125+
- Duplicate(): create a `Store` model from an instance
122126
- Sync(blockNumber?): will load and update data from the chain at latest(or specific block) global state
123127
- Get(path): will read value of specified path
124128
- Set(path, value): will set given value at specified path
125129
- Delete: (path): remove key/value at specified path
126130

127-
##### Code
131+
##### Contract
128132

129-
A `Code` model should have 5 more interfaces than `Data` model
133+
A `Contract` model should have 5 more interfaces than `Store` model
130134

131-
- Deploy(): deploy the script on the chain
132-
- Extend(code): extends from an existing `Code` model for overriding
133-
- Upgrade(): upgrade the script on the chain
134-
- Run(method: string, params: Array<any>): call a method of the script to update its state
135-
- Link(abi: Array<object>): instantiate a script SDK from ABI
135+
- Deploy(): deploy the contract on the chain
136+
- Extend(contract): extends from an existing `Contract` model for overriding
137+
- Upgrade(): upgrade the contract on the chain
138+
- Run(method: string, params: Array<any>): call a method of the contract to update its state
139+
- Link(interfaces: Array<object>): instantiate a contract SDK from interfaces. mainly used to encode a human-readable method call into a message transferred between `Contract` models.
136140

137-
##### MultiCoin Token
141+
##### Token
138142

139-
A generally used token must have some methods based on `Code`
143+
A generally used token must have some methods based on `Contract`
140144

141145
- Metadata(tokenId, metadata?): a setter/getter to the metadata of a specific token id including `name`, `symbol`, `tokenURI`, `totalSupply`)
142146
- Mint(tokenId, amount): Mint a token
@@ -145,12 +149,19 @@ A generally used token must have some methods based on `Code`
145149
- Redeem(address, dapp, tokenId, amount): unstake from a dapp and burn a staking token
146150
- Lock(address, amount, tokenId, locktime): lock tokens, for cases like pre-sale, bounty of a team
147151
- Unlock(address, tokenId, amount): unlock tokens
148-
- Combine(token): combine two `MultiCoin Token` models into one
152+
- Combine(token): combine two `Token` models into one
149153
- GetBalance(address, tokenId): get token balance of a given address
150154

151155

152156
Notice, all actions will be grouped and finalized together, viz. `mint`/`send` multiple token id will be finalized with a single transaction
153157

158+
<sub>Sidenote:
159+
The relations between `Store`, `Contract` and `Token` could be analogized to JavaScript Built-in Objects [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), [Reflect](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect) and [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
160+
`Store` is similar to `Map` in JavaScript which is an iterable collection of key-value pairs and has basic methods such sa `get`, `has`, `set`, `forEach`, `keys`, `values`, `entries`. Its only usage is to store structured data.
161+
`Contract` extends `Store` to have the ability to retrieve/alter its internal data by specific interfaces rather than simple `get/set` methods. For interoperability, `Contract` exposes a uniform approach to update its state, named `run(methodSignature, argumentList)` which is similar to `Reflect.apply(fn, thisArg, argumentList)` so the trigger could be broadcasted via message in the model tree, we will talk about it later.
162+
`Token` is specialized from `Contract` and can be thought of as `Date` in JavaScript which has its own specific attributes and methods `now`, `setHour`. `Token` would have methods like `mint`, `burn`, `transfer`, etc. `Date` and `Token` are used so widely that they have their own seats in Built-in Objects. More advanced models will be added along with the evolving ecosystem.
163+
</sub>
164+
154165
#### Reactive Lazy Evaluation
155166

156167
As mentioned above
@@ -160,11 +171,11 @@ As mentioned above
160171
All actions/manipulations adopted on a model will be cached and evaluated at the end of the pipeline.
161172

162173
```javascript
163-
const model = new Data()
174+
const model = new Store()
164175
model.action_1()
165176
model.action_2()
166177
// ...
167-
modeol.action_n()
178+
model.action_n()
168179

169180
/**
170181
* get a structure with initial state and actions
@@ -192,17 +203,29 @@ model.finalize()
192203

193204
Lazy evaluation is beneficial to the following points:
194205

195-
1. state of the model could be traversed for debugging
196-
2. actions could be revoked easily to find the best path of state transition.
197-
3. inspector(or other dependencies) could be injected to enhance development
206+
1. State of the model could be traversed for debugging
207+
2. Actions could be revoked easily to find the best path of state transition.
208+
3. Inspector(or other dependencies) could be injected to enhance development
198209

199210
#### Model Tree
200211

201-
There would be multiple levels of `Data` models constructing a model tree.
212+
The keyword **model tree** was mentioned in the sidenote above of analogizing `Contract` to `Reflect`.
202213

203-
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.
214+
Every cell of CKB could be treated as a minimal DApp because every cell has its own state and script, but usually a group of cells using the same script will work together as a real DApp because it adopts the same logic on a broader state. Thus a DApp running on CKB could be represented as a 2-level tree which has cells as leaves and shared scripts as nodes.
215+
216+
```mermaid
217+
flowchart BT
218+
cell_0 --> script_a
219+
cell_1 --> script_a
220+
cell_2 --> script_a
221+
cell_3 --> script_b
222+
cell_4 --> script_b
223+
cell_5 --> script_b
224+
script_a --> DApp
225+
script_b --> DApp
226+
```
204227

205-
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
228+
Similarly, a DApp could be destructed into a multi-level **model tree**. And if a **DApp_A** wants to interact with another **DApp_B**, state of **DApp_B** would be a part of **DApp_A**'s so the **model tree** of **DApp_A** would be like
206229

207230
```mermaid
208231
flowchart BT
@@ -212,12 +235,42 @@ cell_a_1_model --> dapp_a_sub_model
212235
cell_a_n_model --> dapp_a_sub_model
213236
dapp_a_sub_model --> dapp_a_model
214237
215-
cell_b_0_model --> dapp_b_model
216-
cell_b_1_model --> dapp_b_model
217-
cell_b_n_model --> dapp_b_model
238+
dapp_b_0_sub_model --> dapp_b_model
239+
dapp_b_1_sub_model --> dapp_b_model
240+
dapp_b_n_sub_model --> dapp_b_model
218241
dapp_b_model --> dapp_a_model
219242
```
220243

244+
With a set of standardized interfaces, the detail of DApp_B's model tree could be obscure to DApp_A.
245+
246+
This idea is from [actor model](https://www.oreilly.com/library/view/applied-akka-patterns/9781491934876/ch01.html) so the structure of an application is similar
247+
248+
![actor model](https://camo.githubusercontent.com/0aec56b15a4dcccf39723b43503b32e3b3a3a364ef0c3f760c9fc6a0e0ae77f3/68747470733a2f2f7777772e7a61727469732e636f6d2f77702d636f6e74656e742f75706c6f6164732f323032312f30352f696d6167652d31332d373638783237352e706e672e77656270)
249+
250+
Actor model is a programming paradigm for concurrent computation, states will not be stored in a single point, but distributed to various actors so computation could be performed in many actors.
251+
252+
Actor model follows several fundamental rules
253+
- All computation is performed within an actor
254+
- Actors can communicate only through messages
255+
- In response to a message, an actor can:
256+
- Change its state or behavior
257+
- Send messages to other actors
258+
- Create a finite number of child actors
259+
260+
From the perspective of the model tree and CKB's cell model, states/cells will not be stored in a single `Store` model, but distributed to a bulk of `Store` models and can be updated in parallel via messages. If a model handles a message, it would
261+
- Update model's state
262+
- Proxy the message to another model
263+
- Create a new model to fetch more state/cells and handle the message
264+
265+
States/cells are arranged isolatedly into different pieces and can only be changed by messages, the updates are sequenced and data conflicts are avoided naturally.
266+
267+
One more interesting point is that model tree could be server-agnostic. As mentioned above, if **DApp_A** relies on **DApp_B**, e.g. **Swap DApp** relies on **Token DApp**, model tree of **DApp_B** will be a part of **DApp_A**'s model tree, illustrated in the diagram above, and **DApp_A** have to rebuild the model tree of **DApp_B** to interact with it. In actor model, **DApp_B**'s model tree could be rebuilt locally or remotely because the interactions are transferred by messages, thus **DApp_A** could request the server of **DApp_B** to output `Store` by a specific `action`.
268+
269+
Take a concrete example, there's a **Swap DApp** to swap **Token A** and **Token B**. Now **user** wants to swap **X token a** with **Y token b** from **Swap DApp**
270+
1. **Swap DApp** requests **Token A DApp** to take an action **transfer X from swap_pool to user** and return a `Store of Token A`
271+
2. **Swap DApp** requests **Token B DApp** to take an action **transfer Y from user to swap_pool** and return a `Store of Token B`.
272+
3. **Swap DApp** combines `Store of Token A` and `Store of Token B` to generate a transaction for user to confirm the swap.
273+
221274
### Conventions
222275

223276
`Kuai-convention` is a set of conventions for the implementation reference of `Kuai-runtime` and the usage guide of `Kuai-runtime`, such as:
@@ -317,3 +370,7 @@ Last but not least, as an open source project, `Kuai` would be introduced to dev
317370
- M6
318371
- Use the project to deliver a simple .bit dapp
319372

373+
## Promising Features
374+
- Working with contracts purely by JavaScript/TypeScript instead of Rust/C;
375+
- Supporting [open transactions](https://en.bitcoin.it/wiki/Open_Transactions) for further use cases;
376+
- Adding [DSL](https://www.wikiwand.com/en/Domain-specific_language) for facilication of development.

0 commit comments

Comments
 (0)