In the previous article, we have introduced a new programming perspective on CKB, which is energize-data. And in the last chapter, a question was raised: how data of different applications(or protocols) can interact, similar to contract interaction on Ethereum?
Before proceeding with this article, it is recommended that you read the previous article first.
This article will answer the question, and show how to write more complex programs using the new idea.
Energize Data
When developing an applicaton or protocol, we will encounter two situations:
- Protocol has no dependency on others, just like UDT-20 or ERC-20 protocol
- Protocol is built on other existed protocols, such as Uniswap (built on ERC-20 protocol)
The previous article has solved the first case, simply put:
- Define the data of protocol, and classify them into cells of corresponding type
- Define the life cycles for each type, which are data-generation, data-transformation and data-vanishment
In the second case, if we are writing contract on Ethereum, we just call interface of other contracts, which is supported by Ethereum transaction. Whereas CKB is a newly designed blockchain, and transaction of CKB is constructed to update cells, not to call some targets. So it may not be appropriate to copy Ethereum pattern to CKB.
As discussed in the previous article, we think data is a first-class citizen, and programming on CKB is to make data meaningful and valuable through consensus. When we want to develop a protocol depending on other protocols, all we need to do is to associate data-change of our protocol with that of other protocols.
That is to say, in life-cycle (data-change) of our protocol, we should verify if there are life-cycles of other protocols we depend on truely happened.
// Input cells should not contain cell of this type, but output cells should
fn generate() -> bool {
// verify data-change of other protocol we depend on
// verfiy data-change of our protocol
}
// Both input and output cells should contain cell of this type
fn transform() -> bool {
// verify data-change of other protocol we depend on
// verfiy data-change of our protocol
}
// Input cells should contain cell of this type, but output cells should not
fn vanish() -> bool {
// verify data-change of other protocol we depend on
// verfiy data-change of our protocol
}
Next, we take Uniswap protocol as an example to illustrate the interaction with other protocols.
For Instance
Uniswap is a protocol for automated token exchange, so it will interact with UDT-20 protocol, which we have discussed in previous article.
To make it simple, uniswap here only has three features:
- Deposit liquidity
- Swap token and ckb (ignore fees to simplify)
- Withdraw liquidity
First of all, let’s define the data of uniswap protocol:
- LT(Liquidity Token), consists of
token_id
,token_name
,token_symbol
,token_supply
,- id of cell controlled by protocol to lock tokens and ckb,
- LT balances of users
And that’s all, then we classify them into cells:
LT Code Life Cycle
LT code is immutable, the same as UDT20-Code, so let’s just skip this one.
LT Info Life Cycle
The difference from UDT20-Info is that the supply of LT can be mutated. The transformation of LT info is associated with the generation or vanishment of LT balance, as shown below:
// Both input and output cells should contain cell of this type
fn transform() -> bool {
// Verify the data-change of LT balance
// If transaciton contains generation of LT balance,
// then supply in output LT info cell == supply in input LT info cell + balance in output LT balance cell
// Else transaction has to contain vanishment of LT balance,
// then supply in output LT info cell == supply in input LT info cell - balance in input LT balance cell
}
LT Balance Life Cycle
If someone deposited liquidity, LT balance data should be generated. The generation of LT balance is associated with the transformation of UDT20 balance and ckb.
// Input cells should not contain cell of this type, but output cells should
fn generate() -> bool {
// Verify the transformation of UDT20 balance and ckb
// UDT20 balance and ckb locked by uniswap was proportional increased
// Verfiy the transformation of LT info
// Check supply amount
// Check LT balance amount
}
Transformation of LT balance is the same as UDT20 balance.
// Both input and output cells should contain cell of this type
fn transform() -> bool {
// Accumulated balance of input cells equal to that of output cells
}
If someone withdrawed liquidity, LT balance data should be vanished. The vanishment of LT balance is associated with the transformation of UDT20 balance and ckb.
// Input cells should contain cell of this type, but output cells should not
fn vanish() -> bool {
// Verify the transformation of UDT20 balance and ckb
// UDT20 balance and ckb locked by uniswap was proportional decreased
// Verfiy the transformation of LT info
// Check supply amount
// Check LT balance amount
}
Now, we only have one feature left: swap token and ckb. But it has nothing to do with LT data, so it’s accomplished by uniswap lock script of UDT20 balance cell, which defines the rules of swapping.
At Last
Associating data-change of your protocol with others is the way to interact with other protocols. And the process of energize-data is the same as explained in previous article. The extra thing to do is, in life cycles of protocol data, to verify the life cycles of others.