Skip to content

Commit b83e5ae

Browse files
committed
doc: revamping UDT docs
1 parent f7b3c4b commit b83e5ae

File tree

4 files changed

+229
-263
lines changed

4 files changed

+229
-263
lines changed

guides/quickstart_udt.md

Lines changed: 0 additions & 131 deletions
This file was deleted.

packages/docs/docs/udt.md

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
---
2+
sidebar-position: 5
3+
title: UDT
4+
description: UDT(User Defined Tokens) is the customized token created with properties defined by user.
5+
---
6+
7+
## Fungible Tokens
8+
9+
Unlike [ERC20(Ethereum)](https://eips.ethereum.org/EIPS/eip-20) and [BRC20(Bitcoin)](https://www.brc-20.io/), CKB uses a unique way to build custom tokens based on its UTXO-like Cell Model.
10+
11+
In CKB, custom tokens are called User-Defined Tokens (UDTs). s(Simple)UDT is the standard that defines the most basic implementation of a UDT fungible token on CKB, and CKB's core team has also proposed a minimal but also extensible standard for UDT called xUDT(extensible UDT).
12+
13+
Steps to Issue a Custom Token with sUDT/xUDT:
14+
15+
1. Create a Special Cell: When you issue tokens, you create a special Cell representing a balance of your custom token, similar to how physical cash represents a balance of currency.
16+
17+
2. Configure the Cell's Data: This Cell’s data field will store the token amount, while its Type Script will be the sUDT/xUDT Script. The script’s args field will contain the Lock Script Hash of the issuer.
18+
19+
3. Establish a Unique Token ID: The issuer’s Lock Script hash serves as the unique identifier for each custom token. Different Lock Script hashes represent different tokens, enabling secure and distinct transactions for each token type.
20+
21+
## SSRI-Compliant `UDT` (Advanced)
22+
23+
SSRI-Compliant UDT is an enhanced and the latest version of UDT that implements the SSRI (Script-Sourced Rich Information) protocol. By implementing the public traits `UDT`, SSRI allows UDT scripts to provide rich metadata and additional functionality directly from the script code, such as token name, symbol, icon, and other custom properties, making them more interoperable and user-friendly across different applications and wallets.
24+
25+
On a more abstract level, any Script can be a UDT if it implements the public traits `UDT` as SSRI provides unlimited extensibility.
26+
27+
## `@ckb-ccc/udt`: All-in-one SDK for interactions with `UDT`
28+
29+
@ckb-ccc/udt is a comprehensive SDK that provides a unified interface for interacting seamlessly with both SSRI-compliant UDTs and legacy sUDT and xUDT tokens on CKB. It offers a rich set of features including:
30+
31+
- Querying token metadata (name, symbol, icon, etc.)
32+
- Checking token balances
33+
- Transferring tokens
34+
35+
For detailed API documentation and usage examples, please refer to the [API Reference](https://api.ckbccc.com/).
36+
37+
## Tutorial: Interact UDT Script with `@ckb-ccc/udt`
38+
39+
>The following guide uses UDT and Pausable UDT as example and assume you're using the playground environment which provides the signer. Your signer would be different based on your project setup.
40+
41+
### Example 1: Prepare and Setup a `UDT` instance
42+
43+
1. Create or setup your project with CCC (see guide [here](https://docs.ckbccc.com/index.html#md:quick-start-with-create-ccc-app-recommended))
44+
45+
2. `(Only for SSRI-Compliant Token)` Start up your local SSRI server through docker:
46+
47+
```shell
48+
docker run -p 9090:9090 hanssen0/ckb-ssri-server
49+
```
50+
51+
Note: You can also choose to use the WASM implementation of SSRI Executor instead if you're developing browser based dApps, so you don't need to provide the service yourself.
52+
53+
3. `(Only for SSRI-Compliant Token)` Prepare the `OutPoint` of your SSRI-compliant UDT script. It's recommended to deploy your UDT script with Type ID, and the following way would allow you to get the `OutPoint` programmatically even if the script gets upgraded:
54+
55+
```ts
56+
import { ccc } from "@ckb-ccc/ccc";
57+
import { signer } from "@ckb-ccc/playground";
58+
// Note: Your signer would be different based on your project setup.
59+
60+
const pudtScriptCell = await signer.client.findSingletonCellByType({
61+
codeHash:"0x00000000000000000000000000000000000000000000000000545950455f4944",
62+
hashType: "type",
63+
args: "0xf0bad0541211603bf14946e09ceac920dd7ed4f862f0ffd53d0d477d6e1d0f0b",
64+
});
65+
if (!scriptCell) {
66+
throw new Error("pudt script cell not found");
67+
}
68+
```
69+
70+
4. Prepare the type `Script` object of your UDT. You can provide the code hash yourself by copying from the explorer, or get it programmatically from the `OutPoint` of your UDT script.
71+
For sUDT, you can get the type `Script` object like this:
72+
73+
```ts
74+
const mySudtType = ccc.Script.from({
75+
codeHash: "0x5e7a36a77e68eecc013dfa2fe6a23f3b6c344b04005808694ae6dd45eea4cfd5",
76+
hashType: "type",
77+
args: "0xabcd..." // The args of your sUDT
78+
});
79+
```
80+
81+
For xUDT, you can get it more programmatically:
82+
83+
```ts
84+
const xudtInfo = await signer.client.getKnownScript(ccc.KnownScript.XUdt);
85+
const myXudtType = ccc.Script.from({
86+
codeHash: xudtInfo.codeHash,
87+
hashType: xudtInfo.hashType,
88+
args: "0xabcd..." // The args of your xUDT
89+
})
90+
```
91+
92+
For SSRI-Compliant UDT, you can get it this way even if the Script code gets updated:
93+
94+
```ts
95+
const pudtCodeHash = pudtScriptCell.cellOutput.type?.hash();
96+
if (!pudtCodeHash) {
97+
throw new Error("PUDT code hash not found");
98+
}
99+
const pudtType = {
100+
codeHash: pudtCodeHash,
101+
hashType: "type",
102+
args: "0x02c93173368ec56f72ec023f63148461b80e7698eddd62cbd9dbe31a13f2b330", // This is just for playground, you should replace it with the args with your SSRI-Compliant UDT
103+
};
104+
```
105+
106+
5. You have everything ready, now you can create an instance of your UDT and interact with it.
107+
108+
For sUDT and xUDT, you will create the instance like this, but you can only call with `UDT.transfer` and `UDT.mint`. See how to call them with in the next example.
109+
110+
```ts
111+
const sudtOutPoint = ccc.OutPoint.from({
112+
txHash: "0xc7813f6a415144643970c2e88e0bb6ca6a8edc5dd7c1022746f628284a9936d5",
113+
index: 0
114+
});
115+
const mySudt = new ccc.udt.Udt(sudtOutPoint, mySudtType);
116+
```
117+
118+
For SSRI-Compliant UDT, you will need to provide the Executor and create your instance like this:
119+
120+
```ts
121+
const executor = new ccc.ssri.ExecutorJsonRpc("http://localhost:9090");
122+
const pudt = new ccc.udt.Udt(pudtScriptCell.outPoint, pudtType, {
123+
executor,
124+
});
125+
```
126+
127+
And then you can interact with your SSRI-Compliant UDT like this:
128+
129+
```ts
130+
const pudtName = await pudt.name();
131+
const pudtIcon = await pudt.icon();
132+
console.log(pudtName);
133+
// {"res":"pudt Token","cellDeps":[]}
134+
console.log(pudtIcon);
135+
// {"res":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMjQiIGN5PSIyNCIgcj0iMjQ ......
136+
```
137+
138+
The same script might have implemented multiple SSRI traits or sub-traits at the same time, but you can instantiate the same script arbitrarily with different traits as long as the script implemented the traits you want.
139+
140+
```ts
141+
const pudt = new ccc.udt.UdtPausable(pudtScriptCell.outPoint, pudtType, {
142+
executor,
143+
});
144+
const pudtEnumeratePaused = await pudt.enumeratePaused();
145+
console.log(pudtEnumeratePaused);
146+
// {"res":["0xb5202efa0f2d250af66f0f571e4b8be8b272572663707a052907f8760112fe35","0xa320a09489791af2e5e1fe84927eda84f71afcbd2c7a65cb419464fe46e75085"],"cellDeps":[{"txHash":"0x98c37eabc1672c4a0a30c0bb284ed49308f0cb58b0d8791f44cca168c973e7da","index":"0"}]}
147+
```
148+
149+
### Example 2: Generate and Send a Transaction through @ckb-ccc/udt
150+
151+
1. Some of the methods allows you to generate a transaction object directly while taking care of most of the details for you. You just need to follow the guidance of the docs provided via your IDE.
152+
153+
For all UDT including the legacy sUDT, xUDT, and SSRI-Compliant UDT, you can `transfer` and `mint` like this:
154+
155+
```ts
156+
const receiverA =
157+
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq2jk6pyw9vlnfakx7vp4t5lxg0lzvvsp3c5adflu";
158+
159+
const { script: lockA } = await ccc.Address.fromString(
160+
receiverA,
161+
signer.client
162+
);
163+
164+
const sudtTransferTx = (
165+
await mySudt.transfer(signer, [
166+
{
167+
to: lockA,
168+
amount: 10000,
169+
},
170+
])
171+
).res;
172+
173+
const xudtTransferTx = (
174+
await myXudt.transfer(signer, [
175+
{
176+
to: lockA,
177+
amount: 10000,
178+
},
179+
])
180+
).res;
181+
182+
const pudtTransferTx = (
183+
await pudt.transfer(signer, [
184+
{
185+
to: lockA,
186+
amount: 10000,
187+
},
188+
])
189+
).res;
190+
```
191+
192+
Many of these methods also allow you to pass in a previous `ccc.TransactionLike` object as the second argument, which allows you for example to transfer multiple UDT cells in a single transaction.
193+
194+
```ts
195+
const receiverB =
196+
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqflz4emgssc6nqj4yv3nfv2sca7g9dzhscgmg28x";
197+
const { script: lockB } = await ccc.Address.fromString(
198+
receiverB,
199+
signer.client
200+
);
201+
let combinedTransferTx = (
202+
await pudt.transfer(
203+
signer,
204+
[
205+
{
206+
to: lockB,
207+
amount: 20000,
208+
},
209+
],
210+
pudtTransferTx
211+
)
212+
).res;
213+
```
214+
215+
2. You only need to complete the inputs of the transaction just like processing any other transactions with CCC.
216+
217+
```ts
218+
// Note: You need to connect your wallet for the following parts. You also need to have enough balance of pudt in your wallet.
219+
combinedTransferTx = await pudt.completeBy(combinedTransferTx, signer);
220+
await combinedTransferTx.completeFeeBy(signer);
221+
await render(combinedTransferTx);
222+
const combinedTransferTxHash = await signer.sendTransaction(combinedTransferTx);
223+
224+
console.log(combinedTransferTxHash);
225+
```

packages/ssri/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
## Additional Note
4949

5050
- Currently `ExecutorJsonRpc` is the only supported `Executor`. There will be more in the future and legacy support for `xUDT` will be added through `ckb-asset-indexer`.
51-
- A public SSRI Executor JSON RPC Point is being scheduled, and efforts are being made to make to provide in-browser SSRI execution with WASM.
51+
- A public SSRI Executor JSON RPC Point is being scheduled, and efforts to make to provide in-browser SSRI execution with WASM are under review at the moment.
5252

5353
## Related Projects
5454

0 commit comments

Comments
 (0)