@@ -3,3 +3,217 @@ sidebar_position: 4
3
3
---
4
4
5
5
# 使用SDK构建FT交易
6
+
7
+ 本文档介绍如何使用FT SDK发行token,转账token,销毁token,查询token等操作。
8
+
9
+ > 使用之前请确保已经完成环境配置和测试币领取,请参考[ 搭建一个MVC项目] ( ../enviroment/setup-project ) 。
10
+
11
+ 本文基于上述已经配置好的环境和密钥进行操作。
12
+
13
+ ## 代码示例
14
+
15
+ 将` src/index.ts ` 文件替换为以下内容:
16
+
17
+ ``` typescript
18
+ import {Address , Mnemonic } from " meta-contract/dist/mvc" ;
19
+ import {promises as fs } from ' fs' ;
20
+ import {API_NET , API_TARGET , FtManager , Wallet } from " meta-contract" ;
21
+ import {BURN_ADDRESS } from " meta-contract/dist/mcp02/constants" ;
22
+
23
+ const FILE_PATH = ' mnemonic-seed.txt'
24
+ const WALLET_PATH = " m/44'/10001'/0'/0/0"
25
+ let seed = ' ' ;
26
+ const generateMnemonic = async (): Promise <string > => {
27
+ console .log (" Generating random mnemonic seed: <%s>, use your own if you already have it" , Mnemonic .fromRandom ().toString ())
28
+ const mnemonic = Mnemonic .fromRandom ().toString ();
29
+ await fs .writeFile (FILE_PATH , mnemonic , ' utf8' );
30
+ return mnemonic ;
31
+ };
32
+
33
+ const readMnemonic = async (): Promise <string > => {
34
+ return await fs .readFile (FILE_PATH , ' utf8' );
35
+ };
36
+
37
+ // Detect if the mnomonic seed file exists, if not, generate a new one
38
+ // Then create a wallet with the seed with path WALLET_PATH
39
+ const setupMyWalletAndOperateFt = async (): Promise <void > => {
40
+ try {
41
+ await fs .access (FILE_PATH );
42
+ const mnemonic = await readMnemonic ();
43
+ console .log (' Mnemonic seed exists: <%s>, will use this one.' , mnemonic );
44
+ seed = mnemonic ;
45
+ } catch (error ) {
46
+ const mnemonic = await generateMnemonic ();
47
+ console .log (' Mnemonic seed not detected, generating new one. <%s> , please keep it safe for future use.' , mnemonic );
48
+ seed = mnemonic ;
49
+ }
50
+ console .log (' Creating wallet with seed: <%s> and path <%s>' , seed , WALLET_PATH );
51
+ let mnemonicParsed = Mnemonic .fromString (seed );
52
+ let privateKey = mnemonicParsed .toHDPrivateKey (" " , API_NET .TEST ).deriveChild (WALLET_PATH );
53
+ let wallet = new Wallet (privateKey .privateKey .toWIF (), API_NET .TEST , 1 );
54
+ console .log (" Your private key %s" , privateKey .privateKey .toWIF ());
55
+ console .log (" Your address %s" , privateKey .privateKey .toAddress (API_NET .TEST ).toString ());
56
+ console .log (" Your balance %s satoshis" , await wallet .getBalance ());
57
+
58
+ // create a FtManager instance and generate a new token
59
+ // codehash, genesis, sensibleId, genesisTxId are the results of the genesis operation
60
+ let ftManager = new FtManager ({
61
+ network: API_NET .TEST ,
62
+ apiTarget: API_TARGET .MVC ,
63
+ purse: privateKey .privateKey .toWIF (),
64
+ feeb: 1 ,
65
+ debug: true ,
66
+ })
67
+ let codehash: string
68
+ let genesis: string
69
+ let sensibleId: string
70
+ let genesisTxId: string
71
+
72
+
73
+ // use time as token name so that it's unique
74
+ // you can change it to any name you like
75
+ const currentDate = new Date ().getHours () + ' :' + new Date ().getMinutes ()
76
+ const tokenName = ' MintTest - ' + currentDate
77
+ const tokenSymbol = ' MVCTest'
78
+ const decimalNum = 8
79
+ const receiverAddress = wallet .address
80
+
81
+ // create a new token(Genesis)
82
+ console .log (" Creating token with name: <%s>, symbol: <%s>, decimal: <%s>" , tokenName , tokenSymbol , decimalNum );
83
+ const genesisResult = await ftManager .genesis ({
84
+ tokenName: tokenName ,
85
+ tokenSymbol: tokenSymbol ,
86
+ decimalNum: decimalNum ,
87
+ genesisWif: privateKey .privateKey .toWIF (),
88
+ })
89
+ codehash = genesisResult .codehash
90
+ genesis = genesisResult .genesis
91
+ genesisTxId = genesisResult .txid
92
+ sensibleId = genesisResult .sensibleId
93
+ console .log (" Token created with codehash: <%s>, genesis: <%s>, genesisTxId: <%s>, sensibleId: <%s>" , codehash , genesis , genesisTxId , sensibleId );
94
+
95
+ // sleep for 1 seconds to wait for the token to be created
96
+ await new Promise (resolve => setTimeout (resolve , 1000 ));
97
+
98
+ // split utxo for fee preparation
99
+ const receivers = []
100
+ for (let i = 0 ; i < 4 ; i ++ ) {
101
+ receivers .push ({
102
+ amount: 10000 ,
103
+ address: wallet .address .toString (),
104
+ })
105
+ }
106
+ const feeTxid = (await wallet .sendArray (receivers )).txId
107
+ console .log (' Created fee providing txid ' , feeTxid )
108
+
109
+ // sleep for 1 seconds to wait for the fee tx to be created
110
+ await new Promise (resolve => setTimeout (resolve , 1000 ));
111
+
112
+ // mint some token to burn
113
+ let {txid} = await ftManager .mint ({
114
+ sensibleId ,
115
+ genesisWif: privateKey .privateKey .toWIF (),
116
+ receiverAddress ,
117
+ tokenAmount: ' 10000000000' ,
118
+ })
119
+ console .log (' Minted %d %s tokens by txid %s ' , 10000000000 , tokenSymbol , txid )
120
+
121
+
122
+ // sleep for 1 seconds to wait for the token to be minted
123
+ await new Promise (resolve => setTimeout (resolve , 1000 ));
124
+
125
+ // transfer and burn token
126
+ const burnTokenAmount = " 100000"
127
+ // transfer to zero address in order to burn, you can use this method to transfer to any address
128
+ let transfer = await ftManager .transfer ({
129
+ genesis: genesis ,
130
+ codehash: codehash ,
131
+ receivers: [
132
+ {
133
+ amount: burnTokenAmount ,
134
+ address: Address .fromPublicKeyHash (BURN_ADDRESS , API_NET .TEST ).toString (),
135
+ },
136
+ ],
137
+ senderWif: privateKey .privateKey .toWIF ()
138
+
139
+ })
140
+ console .log (' Sent %s %s tokens to zero address by txid %s' , burnTokenAmount , tokenSymbol , transfer .txid )
141
+
142
+ await new Promise (resolve => setTimeout (resolve , 1000 ));
143
+
144
+ // transfer to zero address in order to burn
145
+ let transfer2 = await ftManager .transfer ({
146
+ genesis ,
147
+ codehash ,
148
+ receivers: [
149
+ {
150
+ amount: burnTokenAmount ,
151
+ address: Address .fromPublicKeyHash (BURN_ADDRESS , API_NET .TEST ).toString (),
152
+ },
153
+ ],
154
+ senderWif: privateKey .privateKey .toWIF ()
155
+ })
156
+ console .log (' Sent %s %s tokens again to zero address by txid2 %s' , burnTokenAmount , tokenSymbol , transfer .txid )
157
+ await new Promise (resolve => setTimeout (resolve , 1000 ));
158
+
159
+ // burn the tokens
160
+ const ftUtxos = [
161
+ {
162
+ txId: transfer .txid ,
163
+ outputIndex: 0 ,
164
+ tokenAddress: Address .fromPublicKeyHash (BURN_ADDRESS , API_NET .TEST ).toString (),
165
+ tokenAmount: burnTokenAmount ,
166
+ },
167
+ {
168
+ txId: transfer2 .txid ,
169
+ outputIndex: 0 ,
170
+ tokenAddress: Address .fromPublicKeyHash (BURN_ADDRESS , API_NET .TEST ).toString (),
171
+ tokenAmount: burnTokenAmount ,
172
+ },
173
+ ]
174
+ // burn
175
+ const burnResult = await ftManager .burn ({
176
+ genesis: genesis ,
177
+ codehash: codehash ,
178
+ ftUtxos: ftUtxos ,
179
+ })
180
+ console .log (' Burned %s tokens by txid %s' , tokenSymbol , burnResult .txid )
181
+
182
+ // check token balance
183
+ console .log (' Your token balance is %s %s tokens' , await ftManager .getBalance ({
184
+ codehash: codehash ,
185
+ genesis: genesis ,
186
+ address: receiverAddress .toString ()
187
+ }), tokenSymbol )
188
+
189
+
190
+ };
191
+
192
+
193
+ setupMyWalletAndOperateFt ().catch (console .error );
194
+ ```
195
+
196
+ 上面的示例代码展示了如何创建一个新的token,然后转账token(到0地址),销毁token,查询token余额等操作。期间的等待操作是为了防止访问频率过高indexer尚未正确索引导致程序异常。
197
+
198
+ 程序的功能介绍:
199
+
200
+ 1 . 初始化钱包并打印出地址和余额。
201
+ 2 . 创建FtManager实例并创造(Genesis)一个新的token,token名称可以任意指定。生成token的过程中会返回codehash, genesis, sensibleId, genesisTxId等信息。
202
+ 3 . 等待1秒,等待token创建完成。
203
+ 4 . 准备一些utxo用于支付后续手续费。
204
+ 5 . 铸造(Mint)一些token用于销毁。
205
+ 6 . 等待1秒,等待token铸造完成。
206
+ 7 . 分两次转账token到0地址,用于销毁。
207
+ 8 . 等待1秒,等待token转账完成。
208
+ 9 . 销毁token。
209
+ 10 . 查询token余额。确认token销毁成功。
210
+
211
+
212
+ ## 运行程序
213
+
214
+ 运行以下命令,执行程序:
215
+
216
+ ``` bash
217
+ npx tsc
218
+ node src/index.js
219
+ ```
0 commit comments