You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+90-33Lines changed: 90 additions & 33 deletions
Original file line number
Diff line number
Diff line change
@@ -90,53 +90,57 @@ Two abstractions will be promoted in `Kuai`: `Data storage` and `Data manipulati
90
90
91
91
#### Abstraction of data storage
92
92
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`
94
94
95
-
##### Data
95
+
##### Store
96
96
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)
98
98
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.
100
100
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>
102
104
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
104
106
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.
106
108
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.
108
112
109
113
#### Abstraction of data manipulation
110
114
111
115
DApps can read states from each other freely because data/states are arranged uniformly by the abstraction of data storage.
112
116
113
117
DApps can also communicate with each other freely if data manipulation has been abstracted.
114
118
115
-
##### Data
119
+
##### Store
116
120
117
-
A `Data` model should have 7 basic interfaces
121
+
A `Store` model should have 7 basic interfaces
118
122
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.
120
124
- 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
122
126
- Sync(blockNumber?): will load and update data from the chain at latest(or specific block) global state
123
127
- Get(path): will read value of specified path
124
128
- Set(path, value): will set given value at specified path
125
129
- Delete: (path): remove key/value at specified path
126
130
127
-
##### Code
131
+
##### Contract
128
132
129
-
A `Code` model should have 5 more interfaces than `Data` model
133
+
A `Contract` model should have 5 more interfaces than `Store` model
130
134
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.
136
140
137
-
##### MultiCoin Token
141
+
##### Token
138
142
139
-
A generally used token must have some methods based on `Code`
143
+
A generally used token must have some methods based on `Contract`
140
144
141
145
- Metadata(tokenId, metadata?): a setter/getter to the metadata of a specific token id including `name`, `symbol`, `tokenURI`, `totalSupply`)
142
146
- Mint(tokenId, amount): Mint a token
@@ -145,12 +149,19 @@ A generally used token must have some methods based on `Code`
145
149
- Redeem(address, dapp, tokenId, amount): unstake from a dapp and burn a staking token
146
150
- Lock(address, amount, tokenId, locktime): lock tokens, for cases like pre-sale, bounty of a team
147
151
- 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
149
153
- GetBalance(address, tokenId): get token balance of a given address
150
154
151
155
152
156
Notice, all actions will be grouped and finalized together, viz. `mint`/`send` multiple token id will be finalized with a single transaction
153
157
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
+
154
165
#### Reactive Lazy Evaluation
155
166
156
167
As mentioned above
@@ -160,11 +171,11 @@ As mentioned above
160
171
All actions/manipulations adopted on a model will be cached and evaluated at the end of the pipeline.
161
172
162
173
```javascript
163
-
constmodel=newData()
174
+
constmodel=newStore()
164
175
model.action_1()
165
176
model.action_2()
166
177
// ...
167
-
modeol.action_n()
178
+
model.action_n()
168
179
169
180
/**
170
181
* get a structure with initial state and actions
@@ -192,17 +203,29 @@ model.finalize()
192
203
193
204
Lazy evaluation is beneficial to the following points:
194
205
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
198
209
199
210
#### Model Tree
200
211
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`.
202
213
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
+
```
204
227
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
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
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
+
221
274
### Conventions
222
275
223
276
`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
317
370
- M6
318
371
- Use the project to deliver a simple .bit dapp
319
372
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