Background
Centralized exchanges provide great user experience and high performance. Users need to deposit their tokens to exchanges’ addresses before trading. It is simple for Bitcoin and Ethereum to generate huge number of addresses for deposit. However, every UTXO on CKB occupies 61 bytes at least, which maybe a heavy burden for exchanges if they have to take the responsibility to provide deposit cells for user experience.
Let’s say a exchange with 1M users, and every user has 9 types of UDT on average. It will spend the exchange at least 61 * 10 * 1M = 610 M
CKB, which not includes UDT’s data overhead. This is too much for exchanges.
A good exchange deposit solution should have the following features:
- Low cost, average cost of one user is the lower the better
- Take UDT into consideration
- User convenience, easy to understand and easy to operate
- Privacy, user can choose new addresses for every deposit
- Easy to integrate for exchanges / wallets
- Security, users wouldn’t lose tokens if they deposit to obsolete addresses
Dummy Solution
A dummy solution is always feasible, simple to integrate, and easy to understand. Which is,
- Generate new deposit addresses for users
- User transfers CKB/UDT to the address
- User needs to provide the receiving cell’s capacity
This solution is great except the last feature. In the long run, the price of CKByte may increase, which will also increase user’s cost of deposit because UDT deposit will occupy their own CKBytes for a while.
But it is not a problem we are facing in the near future, I suggest the exchange use this simple solution in the first several years.
A Better Solution
A Special Lock That Anyone Can Occupy to Deposit
Prepare a new lock script, which accept one pkhash
as arg. The lock script’s logic is,
- A signature match
pkhash
can arbitrarily spend the cell - Without signature matches
pkhash
, a TX can still spend the cell as long as the TX includes an output cell that follows the rules:- Its type equals the spent cell’s type
- Its lock equals the spent cell’s lock
- Its capacity equals or great than the spent cell’s capacity
- Its data’s number of UDT amount equals or great than that of the spent cell, if their type is UDT type.
We name the special lock Lock_Deposit
. With this lock, one can occupy (spend, actualy) such cell for space to hold his/her deposit. Exchanges provide such cells to their users.
In this demostration above, green cells are controlled by exchange, blue ones are controlled by user. User deposit C1 CKBytes, without extra cell capacity cost. Exchange provides the receiving capacity.
UDT Deposit
To support UDT deposit, we need to make two modifications to the Lock_Deposit design.
- The Lock_Deposit script should be aware of UDT balance data structure, and UDT identity.
- The Lock_Deposit’s logic should cover CKB balance consistency, and UDT balance consistency, which means the Lock_Deposit enabled cell must guard more CKB or more UDTs after the transaction.
Repectively, if the UDT type script support multi-assets in one cell, it would be very storage efficient.
User Journey
1. User requests a deposit address from exchange
- User select “deposit CKB / CKB-UDT” function on exchange
- The exchange generate a new deposit cell specially for this user
- Genereate private key, and a corresponding public key
- Calculate the hash of this public key, compose a new deposit cell with Lock_Deposit, and its arg is this pkhash
- Put this cell on chain
- The deposit address is a wrap of Lock_Deposit with this pkhash.
2. User transfer CKB / UDT to the deposit address
- Routines
- The wallet application collects live cells according to the deposit address
- Generate deposit TX, spend the deposit cell, broadcast the TX
- After the TX confirmed by blockchain, the deposit cell is replaced by a new one, with user’s depoist
- What if the user transfer more than one types of UDT to the deposit address in a short period ?
- If the wallet found that the deposit cell has been filled with some UDT balances deposited previous, the wallet should update the UDT balance list in the cell’s data field, so that it can accept multi-assets simultaneously.
- What if the user transfer CKB / UDT to an obsolete address ?
- If the wallet cannot find any live cell according to the deposit address, it means that the cell has been recycled by exchange
- User can still deposit to the obsolete address if they offer the deposit cell capacity (fall back to dummy solution). This action should be supported by application level wallet automatically.
3. Exchange takes the deposit
- Exchanges can spend the deposit cell any time
- By check the on-chain TX records, and the balance in the deposit cell, exchange can add corresponding balance to user’s virtual account
- [optional] Recycle obsolete deposit cells
4. Withdraw from Exchange
It’s much easier than deposit, because exchange can charge withdraw fee for output cell’s capacity.
Summary
- Cost
- One extra cell capacity for one user at most, no matter how many types of UDT token they deposit.
- User experience
- the same as transfer CKB/UDT
- Privacy
- support deposit address alteration
- Integration with exchanges / wallets
- guess it’s not too difficult
- Security
- support deposit to obsolete addresses
What we need ?
A New Format of Address
Short / compressed address is always user friendly. Besides, we’d better define a new address format/sub-type so that the wallet can recognize the deposit cell replacement rules and generate right transactions.
Coding
- Lock_Deposit
- Update UDT Design Pattern
- support multi-assets in one cell
- Integration with exchange
- Integration with wallet