-
Notifications
You must be signed in to change notification settings - Fork 53
/
BTS交易所对接指南(单节点版).txt
693 lines (459 loc) · 34.1 KB
/
BTS交易所对接指南(单节点版).txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
BTS 交易所对接指南(单节点版)
此文目的是协助第三方交易所上线 BTS 交易。
此文所述方案为单节点方案。相对于此前另一篇文档描述的双节点方案来说,单节点方案可以节省内存、硬盘和同步时间。
1. 基本概念
1.1 共识
BTS 使用 DPOS 共识机制,由持有 BTS 的人投票产生区块锻造人,标准区块间隔时间是 3 秒。
1.2 账户
1) BTS里,资金是存在账户里的,不像比特币是存在地址里。对交易所来说,需要公开一个账号供用户充值。
可以使用网页钱包或者轻钱包注册新账号。
* 网页钱包地址 https://wallet.bitshares.org/
开发版 https://develop.bitshares.org/ , 网页钱包可能存在 BUG 导致一些功能无法使用,可尝试使用开发版
* 轻钱包下载地址 https://github.com/bitshares/bitshares-ui/releases
轻钱包是网页钱包的下载版。下面的描述中,提到网页钱包的时候,一般都适用于轻钱包。
注意:对于交易所来说,注册账号请使用钱包模式,而不是账号+密码模式(简称账户模式),因为交易所要用到一些高级功能,在账户模式下会存在问题。
(如果是官方网页钱包或轻钱包 2.0.171102 或以上版本,第一次注册时默认是账户模式,可点击“钱包模式(advanced form)”进入钱包模式)。
不是所有账号都可以免费注册,一般带横杠的或者数字的账号可以免费注册,比如 my-exchange ,或者 myexchange2017 。
为了资金安全,交易所可以用一个账号负责充值,另用一个账号负责提现。
注:每个账号在 BTS 系统里有一个内置ID,格式为 "1.2.xxxxx" ,下面会用到。
可以到区块链浏览器 https://blocksights.info/ 输入账号名获取账户 ID ,
也可以自建节点同步完成后在钱包里通过命令获取 ID ,获取命令参考“提现目的账号名检查”章节。
2) 用户充值,就是从其他账号转账到交易所的公开的账号。
账号名就是收款地址。
每笔转账可以带一个备注(Memo),交易所通过这个备注(Memo)来区分是哪个用户的充值。
具体备注(Memo)与交易所用户关联关系,请交易所自行设定。
备注(Memo)是加密的,只有拥有发送者或者接收者的备注密钥(memo key)才可以解密。
3) 用户提现,就是从交易所账号转账到用户账号,目的账号名由用户提供。
由于有用户需要把资金直接从一个交易所转到另一个交易所,而另一个交易所是根据备注(Memo)入账,所以提现功能最好可以带备注(Memo)。
4) 使用网页钱包注册的账号是基本账号。可付费升级为终身会员账号,升级后,后续交易手续费节省 80% (先支付后返款,返款需主动提取)。
终身会员可以创建新账号。
当前手续费费率标准可以在钱包内查看,从界面依次点击 浏览(Explore)-费率表(Fee Schedule) 进入。
5) 每个账号默认有 3 对密钥,可以在网页钱包点击右上角“三”状图标,然后点击“进阶功能(Advanced)”-“权限(Permissions)”,出现的页面里,
三对密钥分别为:资金权限(Active Permissions 或 Active Key)、账户权限(Owner Permissions 或 Owner Key)、备注密钥(Memo key)。
其中,资金权限密钥用于转账等日常操作;账户权限密钥用于修改密钥;备注密钥用来加密和解密转账备注。
使用钱包模式注册的账户,默认情况下,资金权限密钥与备注密钥相同,但可以修改为不同。
以上 3 对密钥都可以修改。其中,账户权限为最高权限,可以修改所有密钥;使用资金权限密钥不能修改账户权限密钥,但可以修改其他两个密钥。
注:
* 链上操作都是通过密钥来进行验证。“钱包模式”和“账户模式”是 UI 概念,对应不同的密钥生成机制。
* 钱包模式下,存在一个钱包文件,钱包文件包含一个种子(brain key,由一组单词组成),其他自动生成的密钥都是从种子衍生而来,如果密钥丢失,可以通过种子恢复。
钱包密码是用来在本地设备上加密钱包文件的,修改钱包密码不会影响链上密钥。
钱包文件需要备份。
* 账户模式下,账号的密钥是从账号名和密码经过哈希运算得出的,只要记住账户名和密码,则可以在任何支持该模式的设备上使用。
账户模式下不需要备份文件,但必须同时记住账户名和密码。
账户模式下,修改密码操作是上链的,会导致密钥发生变化。
1.3 资产
1) BTS 系统里有多种资产,其中,核心资产是 BTS 。交易所上线 BTS 系统内其他资产的方法,与上线核心资产(BTS)的方式类似。
2) 每个账户可以同时拥有多种资产。
1.4 块链结构
每个块有个 ID,即 block_id,该 ID 是块内容的 hash 值;
每个块包含前一块的 ID,存放在 "previous" 字段,因此形成一个链;
每个块里包含多个交易,存放在 "transactions" 字段,按顺序存放;
使用 API 获取块信息时,会同时返回 "transaction_ids" 字段,即交易 ID 清单,是交易(不包含签名)序列化后的 hash 值
每个交易可包含多个操作,存放在 "operations" 字段,按顺序存放;
每个操作也有一个 ID ,是一个全局数字编号,是程序运行中内部产生的,不是 hash 值
2. 基础软硬件需求
独立服务器或者VPS,双核即可
推荐 16G 内存或以上,至少需要 8G 内存
推荐 150G 硬盘或以上,需要至少 100G 硬盘
推荐 64 位 Ubuntu 20.04 LTS 。也可以使用其他主要发行版,或者 Windows Server 。
3. 程序准备
要对接 BTS 系统,需要运行这几个程序:普通节点 witness_node 、命令行钱包 cli_wallet 。
3.1 架构说明
witness_node 通过 P2P 方式连接到 BTS 网络,从网络接收最新区块,向网络广播本地签署的交易包;
witness_node 通过 websocket + http rpc 的方式提供 API 供其他程序调用(以下称为节点 API)。
cli_wallet 通过 websocket 方式连接到 witness_node 。
cli_wallet 管理钱包文件,钱包文件里包含经过加密的用户私钥,一个钱包文件可以包含多个私钥。
可以同时运行多个 cli_wallet 进程,同时连到 witness_node ,用来管理多个钱包文件。
cli_wallet 提供交易签名功能,签名后通过 witness_node 向外广播。
cli_wallet 通过 http rpc 的方式提供 API 供其他程序调用(以下称为钱包 API)。
推荐交易所使用一个 cli_wallet 来监测用户充值,使用另一个 cli_wallet 来处理用户提现请求。
3.2 Windows
Github 上提供编译好的 Windows 可执行文件下载,下载页面在 https://github.com/bitshares/bitshares-core/releases/latest ,
文件为 bitshares-core-x.y.z-win64-bin.zip ,解开即可,里面包含 witness_node.exe 和 cli_wallet.exe 两个可执行文件。
如果自行编译,参考教程 https://github.com/bitshares/bitshares-core/wiki/BUILD_WIN32
3.3 Linux
Github 上提供编译好的 Linux 可执行文件下载,下载页面在 https://github.com/bitshares/bitshares-core/releases/latest ,
文件为 bitshares-core-x.y.z-linux-amd64-bin.tar.bz2 ,解开即可,里面包含 witness_node 和 cli_wallet 两个可执行文件。
如果自行编译,推荐使用 Ubuntu 20.04 LTS ,编译步骤如下:
sudo apt-get update
sudo apt-get install autoconf cmake git libboost-all-dev libssl-dev doxygen g++ libcurl4-openssl-dev
git clone https://github.com/bitshares/bitshares-core.git
cd bitshares-core
git checkout <LATEST_RELEASE_TAG>
git submodule update --init --recursive
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j witness_node cli_wallet
注:上述步骤中,请将 <LATEST_RELEASE_TAG> 替换成最新发布版本号。
(在 https://github.com/bitshares/bitshares-core/releases 可以查到最新版本,比如 6.0.0 )
如果因为内存不足导致编译失败,比如出现 Killed 字样,请尝试去掉 -j 参数重新编译。
编译完成后,得到两个可执行程序分别是:
* build/programs/witness_node/witness_node
* build/programs/cli_wallet/cli_wallet
上述程序可以拷贝到其他目录或者其他服务器执行。以下默认认为程序在当前目录。
注:拷贝到其他服务器执行时,如果服务器操作系统或其他软硬件环境有差异,则可能不能使用。
使用其他 Linux 发行版也可以编译,不在本文说明范围。
4. 环境准备
要保证系统正常运行,需要保证服务器系统时间正确。时间不正确会导致块链无法同步、资金发送失败等各种问题。
Ubuntu 系统推荐安装 NTP 服务端,方法是
sudo timedatectl set-ntp false
sudo apt-get install ntp
根据部署环境不同,可能需要修改默认的 ntp 服务器地址,请参阅相关文档。
如果是 Windows 系统,请设置好系统时间同步。
5. 同步数据
由于需要同时运行多个程序, Ubuntu 下推荐在 screen 或者 tmux 里启动程序。
以下描述主要针对 Ubuntu ,所以命令前都带 ./ 。对于 Windows ,在命令行界面 cd 到程序目录之后,执行时不需要 ./ 。
5.1 witness_node
可使用 ./witness_node --help 来查看命令参数。
5.1.1 初次执行:
./witness_node -d witness_node_data_dir
然后按 Ctrl+C 结束它。
这样会在当前目录生成一个数据目录 witness_node_data_dir ,里面包含 blockchain 目录是数据存储,以及 config.ini 和 logging.ini 配置文件。
注:如果数据目录是较老版本的 witness_node 生成的,则没有 logging.ini 文件,相关的配置内容在 config.ini 文件里。
对于这种情况,建议在一个新的目录运行 witness_node ,生成一份新的配置文件,然后对照老版本进行修改
对于交易所,推荐对配置文件作一些修改。
1) 以下参数会减少运行需要的内存,原理是不保存交易所用不到的数据。
plugins = account_history
ignore-api-helper-indexes-warning = true
注:
* 如果 config.ini 里没找到上述配置项,比如从老版本升级上来时不会更新已有配置文件,建议另外找个空目录生成一个 config.ini 文件再拷过来修改。
* 默认的 plugins 配置有多项,这里实际是去掉其他项,只保留 account_history
* 如果只修改 plugins 会导致程序无法启动,需要同时修改 ignore-api-helper-indexes-warning
* 默认 ignore-api-helper-indexes-warning 前面有“#”符号,需要删除
2) 以下参数会大量减少运行需要的内存,原理是不保存与交易所账户无关的历史数据索引。
track-account = "1.2.12345"
请将 12345 替换成你的账户数字 ID 。数字前的 "1.2." 表示类型是账户。
如果需要监控多个账户,则使用多个 track-account 配置,如:
track-account = "1.2.12345"
track-account = "1.2.12346"
注:
* config.ini 里默认 track-account 前面有个“#”符号,需要删除。
* 参数首尾双引号需要保留
* 如果需要增加、修改、删除追踪账号,修改后,需要重建索引才能生效。
* 也可以在启动 witness_node 的时候,在命令行后面添加 --track-account 参数,比如:
./witness_node --track-account "\"1.2.12345\"" --track-account "\"1.2.12346\""
注:
* 参数首尾双引号需要保留,所以使用 \ 进行转义。 Linux 下可以使用双引号外加一层单引号的方式,则不需要转义。
* 如果需要增加、修改、删除追踪账号,修改后,需要重建索引才能生效。
方法是按 Ctrl + C 结束程序,然后加 --replay-blockchain 参数重新启动,如:
./witness_node -d witness_node_data_dir --track-account "\"1.2.12345\"" --track-account "\"1.2.12346\"" --replay-blockchain
3) 以下参数表示每账号保留多少条历史记录供查询,默认值是 100 。
对交易所来说,如果充值、提现记录较多,可考虑设置成一个较大的值,比如
max-ops-per-account = 100
修改为
max-ops-per-account = 1000000
则会保留一百万条数据。更早的数据会从内存中被删除而无法快速查询(但仍然记录在链上)。
4) 也可以考虑使用下述参数组合来设置追踪账号,而不使用 track-account 和 max-ops-per-account 的参数组合,
这样的话,符合条件的账号会保留 extended-max-ops-per-account 条历史记录,其他账号会保留 max-ops-per-account 条记录。
# Maximum number of operations to keep for accounts for which extended history is kept
# extended-max-ops-per-account =
# Track longer history for these accounts (may specify multiple times)
# extended-history-by-account =
# Track longer history for accounts with this registrar (may specify multiple times)
# extended-history-by-registrar =
5.1.2 重新执行
再次启动 witness_node ,开始同步数据。根据网络条件、服务器硬件条件不同,初次同步可能需要花几个小时到几天时间。
./witness_node -d witness_node_data_dir --rpc-endpoint 127.0.0.1:8090 --track-account "\"1.2.12345\"" --track-account "\"1.2.12346\"" --max-ops-per-account 1000000 --replay-blockchain
上述命令中,使用 --rpc-endpoint 开启节点 API 服务,这样就可以使用 cli_wallet 和其他程序连接使用
注:以后再需要重新启动 witness_node 时,一般不要加 --replay-blockchain 参数,否则启动会很慢
5.2 运行一个 cli_wallet 用于处理提现
./cli_wallet -w wallet_for_withdrawal.json -s ws://127.0.0.1:8090 -H 127.0.0.1:8091
上述命令使用 -w 参数指定钱包文件, -s 参数连接到 witness_node , -H 参数开启钱包 API 服务,监听端口 8091
注:
* 可使用 ./cli_wallet --help 来查看命令参数。
* cli_wallet 与 witness_node 间通信的数据不包含私密数据,一般不需加密,也不需要对节点 RPC 端口作刻意保护(加一层保护也未尝不可)。
但 cli_wallet 与充提程序间的通信是明文,可能需要包含密码,如果部署为多机架构,需要注意加密,可采用 SSH 隧道的方式。
并且, cli_wallet 处于解锁状态时,通过 RPC 端口可以转移钱包内账户资金,需要注意防止非授权访问,强烈不建议钱包 RPC 直接开放公网访问。
为 cli_wallet 的 RPC 配置证书或者密码的做法,本人没有研究过,故此不作描述。
执行成功会显示:
new >>>
首先需要为钱包文件设置一个密码,输入 set_password 然后按回车键:
new >>> set_password [回车]
按提示输入密码,密码不会显示。
执行成功会显示:
locked >>>
然后解锁钱包
locked >>> unlock [回车]
按提示输入密码,密码不会显示。
解锁成功会显示:
unlocked >>>
注:如果是 Windows ,不能直接按回车再输密码,而是必须把密码直接写在命令后,如:
new >>> set_password my_password_123
locked >>> unlock my_password_123
unlocked >>>
使用 info 命令可以查看当前同步情况
unlocked >>> info
info
{
"head_block_num": 17249870,
"head_block_id": "0107364e2bf1c4ed1331ece4ad7824271e563fbb",
"head_block_age": "23 seconds old",
"next_maintenance_time": "31 minutes in the future",
"chain_id": "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8",
"participation": "96.87500000000000000",
...
}
5.3 运行另一个 cli_wallet 用于处理充值
./cli_wallet -w wallet_for_deposit.json -s ws://127.0.0.1:8090 -H 127.0.0.1:8093
这个 cli_wallet 也开启钱包 API 服务,监听端口 8093
请参考前面的章节设置密码及解锁。
6. 账户设置
考虑到安全性,可以使用两个账号分别处理充值和提现,这里假设 deposit-account 用于充值,withdrawal-account 用于提现。
6.1 修改充值账户的备注密钥(Memo key)
注:如果账户的 active key 和 memo key 不同,比如是用账户模式创建的账户,可跳过这一步。
在上述任何一个 cli_wallet 中执行 suggest_brain_key ,会得到一对密钥,示例如下:
unlocked >>> suggest_brain_key
suggest_brain_key
{
"brain_priv_key": ".....",
"wif_priv_key": "5JxyJx2KyDmAx5kpkMthWEpqGjzpwtGtEJigSMz5XE1AtrQaZXu",
"pub_key": "BTS69uKRvM8dAPn8En4SCi2nMTHKXt1rWrohFbwaPwv2rAbT3XFzf"
}
在网页钱包里,账户权限页面,将备注密钥修改为上述结果中的 pub_key ,步骤为:
* 右上角“三”菜单-进阶功能(Advanced)-权限(Permissions)-备注密钥(Memo key)标签,输入上述新密钥,保存
注:
1. 修改过后请注意备份,否则网页钱包里可能无法解密修改前的备注。
2. 这个方法也可以用来修改账户的资金权限密钥和账户权限密钥,有需要时可以使用。
3. 修改过后,如果仍需要使用网页钱包进行带备注的转账、或者读取新的转入/转出转账备注,
则需要将上述 wif_priv_key 导入到网页钱包,导入步骤为:
* 右上角“三”菜单-设置(Settings)-左边“通用设置(General)”-页面最下面“登录模式(Login Mode)”确定为“本地钱包模式(Local Wallet Login)”
* 左边“本地钱包(Local Wallet)”-“当前使用的钱包(Active Local Wallet)”确认非空,如果为空则需点击“新建本地钱包(New Local Wallet)”
* 左边“恢复/导入(Restore/Import)”-下拉框选“导入私钥(Import a private key)”-输入私钥-确认
* 如果因为 BUG 无法在 https://wallet.bitshares.org/ 或者轻钱包完成上述步骤,请尝试 https://develop.bitshares.org/
参考如下教程中的第二步: http://btsabc.org/article-761-1.html 。
导入后可以做个新的备份。
6.2 将充值账户的备注密钥(Memo key)导入到负责充值的 cli_wallet
如果钱包已锁定,需要先用 unlock 命令解锁。
这里需用到上述 suggest_brain_key 结果中的 wif_priv_key :
unlocked >>> import_key deposit-account 5JxyJx2KyDmAx5kpkMthWEpqGjzpwtGtEJigSMz5XE1AtrQaZXu
注:
* 如果在 witness_node 同步完成前导入,可能失败。请同步完成后再尝试。
* 如果跳过了 6.1 步骤,需要从网页钱包取得备注密钥(Memo key)私钥进行导入。获取步骤为
* 右上角“三”菜单-进阶功能(Advanced)-权限(Permissions)-备注密钥(Memo key)标签,复制以 BTS 开头的一串备注公钥(Memo Public Key)
* 再点击“资金权限(Active Permissions)”标签,在第一个输入框“账户名或公钥(Account Name or Public Key)”里粘贴上述复制内容,
第二个输入框“权重(Weight)”填 1 ,点“添加(Add)”,下面列表中即会出现该公钥并可点击,在出现的页面里显示私钥并复制。不要点击“保存(Save)”。
* 如果因为 BUG 无法在 https://wallet.bitshares.org/ 或者轻钱包完成上述步骤,请尝试 https://develop.bitshares.org/
导入时 cli_wallet 会自动生成一个或者两个备份文件,可删除。
这时可按 Ctrl + D 或者 Ctrl + C 退出钱包,对钱包文件 wallet_for_deposit.json 进行备份,然后重新启动 cli_wallet 。
退出时如果报错,可以忽略。
由于没有导入资金权限密钥(Active key),负责处理充值的 cli_wallet 无法动用充值账户的资金,只能查看历史记录。
6.3 从网页钱包中取得提现账户的资金权限密钥(Active key)
获取步骤为
* 右上角“三”菜单-进阶功能(Advanced)-权限(Permissions)-“资金权限(Active Permissions)”标签
* 点击下面列表中 BTS 开头的一串公钥,在出现的页面里显示私钥并复制。
参考 http://btsabc.org/article-761-1.html
6.4 将提现账户的资金权限密钥(Active key)导入到负责提现的 cli_wallet
unlocked >>> import_key withdrawal-account 5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
同样可以对钱包文件作个备份。
注:检查一下提现账户的资金权限密钥(Active key)和备注密钥(Memo key)是否一样,如果不一样,则需要将备注密钥也导入,否则无法处理带备注的提现。导入命令仍然是:
unlocked >>> import_key withdrawal-account 5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
备注密钥获取方式参考 6.2 节内注解。
7. 钱包命令
cli_wallet 里,
* 使用 help 命令可以列出命令清单及参数
* Linux 和 macOS 下可以按 TAB 键补全命令,可以按上下箭头浏览历史命令
* 如果编译时有 doxygen ,使用 gethelp 命令可以获取具体命令的参数说明及示例,如
unlocked >>> gethelp get_account
8. 钱包 API
钱包开启了 http rpc 方式的 API 服务时,可以通过 http rpc 方式调用**所有的**钱包命令,效果与在钱包里输入命令相同。
示例:
curl -d '{"jsonrpc": "2.0", "method": "get_block", "params": [1], "id": 1}' http://127.0.0.1:8093/
curl -d '{"jsonrpc": "2.0", "method": "unlock", "params": ["my_password_123"], "id": 2}' http://127.0.0.1:8093/
即:method 传入命令名,params 数组传入参数清单。
返回:
{"id":1,"result":{"previous":"0000000000000000000000000000000000000000","timestamp":"2015-10-13T14:12:24","witness":"1.6.8","transaction_merkle_root":"0000000000000000000000000000000000000000","extensions":[],"witness_signature":"1f53542bb60f1f7a653bac70d6b1613e73b9adc952031e30e591e601dd60d493ba5c9a832e155ff0c40ea1dd53512e9f93bf65a8191497ea67d701bc2502f93af7","transactions":[],"block_id":"00000001b656820f72f6b28cda811778632d4998","signing_key":"BTS6ZQEFsPmG6jWspNDdZHkehNmPpG7gkSHkphmRZQWaJ2LrcaVSi","transaction_ids":[]}}
如果执行成功,结果会有 result ,否则会有 error 。
注意:
在钱包里输入命令,返回结果是经过美化的;使用 http rpc 请求时,返回的是 json 格式的原始数据。关于原始数据,需要注意的有:
* 金额是 {"amount":467116432,"asset_id":"1.3.0"} 格式,其中
* asset_id 可以通过 get_asset 命令查到具体名称, BTS 的 asset_id 是 1.3.0 ,其他资产有其他 id
* amount 是数量去掉小数点之后的值,比如 BTS 是 5 位小数,上面例子中实际是 4671.16432 BTS
* 账户是 1.2.xxxxx 的格式,可以通过 get_account 获取账户信息
* 操作类型(op)是数值格式,比如 0 表示转账操作
9. 处理充值
9.1 获取当前的“无法回退区块”块号
与比特币等采用确认数来从概率上降低交易回退的可能性有所不同, BTS 里可采用“无法回退区块”块号来判断交易是否可能回退。
“无法回退”区块及更早区块里面的交易,可以保证不会发生回退。
在 cli_wallet 里使用命令 get_dynamic_global_properties 来获取无法回退的块号。如:
get_dynamic_global_properties
{
"id": "2.1.0",
"head_block_number": 21955727,
...
"last_irreversible_block_num": 21955709
}
其中, head_block_number 为最新区块号, last_irreversible_block_num 为无法回退区块号。
9.2 查询充值账户历史
使用 get_relative_account_history 命令来查询充值账户历史,检测是否有新的充值。如:
unlocked >>> get_relative_account_history deposit-account 1 100 100
unlocked >>> get_relative_account_history deposit-account 101 100 200
curl -d '{"jsonrpc": "2.0", "method": "get_relative_account_history", "params": ["deposit-account",1,100,100], "id": 1}' http://127.0.0.1:8093/
四个参数分别为:账户名,最小编号,最大返回数量,最大编号。编号从 1 开始。
注:
某个版本的 cli_wallet 最大返回数量超过 100 时有个bug,导致结果不准,使用时请避免 limit 超过 100 。
返回结果是一个数组,按时间倒序排序,即最新的记录排在最前面。
* 如果没有新充值,则数组长度为 0 。
* 如果有新的记录,其中第N条数据为 result[N],格式可能为:
{
"memo":"",
"description":"Transfer 1 BTS from a to b -- Unlock wallet to see memo. (Fee: 0.22941 BTS)",
"op":{
"id":"1.11.1234567",
"op":[
0,
{
"fee":{
"amount":22941,
"asset_id":"1.3.0"
},
"from":"1.2.12345",
"to":"1.2.45678",
"amount":{
"amount":100000,
"asset_id":"1.3.0"
},
"memo":{
"from":"BTS7NLcZJzqq3mvKfcqoN52ainajDckyMp5SYRgzicfbHD6u587ib",
"to":"BTS7SakKqZ8HamkTr7FdPn9qYxYmtSh2QzFNn49CiFAkdFAvQVMg6",
"nonce":"5333758904325274680",
"message":"0b809fa8169453422343434366514a153981ea"
},
"extensions":[
]
}
],
"result":[
0,
{
}
],
"block_num":1234567,
"trx_in_block":7,
"op_in_trx":0,
"virtual_op":1234
}
}
可见,结果中并没有显式包含每条记录的编号,需要程序自行推算、记录。一般将该数组顺序颠倒,然后逐一处理比较合适。
首先要判断该交易所在区块是否已经无法回退。
取 result[N]["op"]["block_num"] 与 last_irreversible_block_num 作比较,如果不可回退则继续处理,可以回退则先跳过不处理。
注意:交易没有进块时,仍然可能在 get_relative_account_history 中出现,并且所在块号会一直改变,难以判断状态。
所以请使用 last_irreversible_block_num 来判断。
result[N]["op"]["op"] 是数组格式,取数组里第一个元素 result[N]["op"]["op"][0] ,如果是 0 ,则表示转账;
则可以取第二个元素中 "to" 字段,即 result[N]["op"]["op"][1]["to"] ,判断它是否与 deposit-account 的 ID 相同,来判断是否转入;
如果是,则取第二个字段中 "amount" 字段里 "asset_id" 字段 result[N]["op"]["op"][1]["amount"]["asset_id"] 判断是否正确资产类型,
然后取 "amount" 里面的 "amount" ,即 result[N]["op"]["op"][1]["amount"]["amount"] ,加上小数点位数,得出充值金额;
取最外层的 "memo" 字段,即 result[N]["memo"] ,得出用户在交易所的 ID ,进行入账。
result[N]["op"]["id"] 是这笔转账的唯一 ID ,可以记录备查。
同时,推荐将结果中 block_num, trx_in_block, op_in_trx 几个数据也记录下来,含义分别是 块号、块中第几个交易、交易中第几个操作。
另外,由于他方转账时,可能只记录交易ID (哈希值),或者交易签名,而不记录操作ID或者块号,
为了方便检查问题,建议在充值检测时,记录操作对应的交易 ID 和交易签名,方法如下:
根据上述 block_num ,调用 get_block 命令获取块内容,如
unlocked >>> get_block 16000000
curl -d '{"jsonrpc": "2.0", "method": "get_block", "params": [160000], "id": 1}' http://127.0.0.1:8093/
设结果中块内容为 result ,根据上述 trx_in_block ,
取 result["transaction_ids"][trx_in_block] ,即为对应的交易 ID;
取 result["transactions"][trx_in_block]["signatures"] ,即为交易签名,是个数组,因为多重签名账户转账可能包含多个签名
注:
1) 钱包必须先解锁才能解密备注。
2) 如果检测到有充值的备注不正确,或者资产类型不正确,注意不要简单退回,因为可能是从其他交易所转来的,退回后对方处理起来也会很麻烦。
3) 一个块里很可能有多笔充值,结果的 block_num 相同,甚至可能 trx_in_block 和 op_in_trx 也相同,但 virtual_op 不同,需注意处理。
可以肯定 blocknum + trx_in_block + op_in_trx + vitrual_op 的组合是唯一的。
4) 由于存在“提议”功能,可以延期执行,用 get_block 然后用 trx_in_block 定位时可能取不到对应交易,或者取到的交易与充值操作不对应。
延期执行功能目前很少有人用,但理论上存在,请注意错误处理。
10. 处理提现
10.1 网络状态检查
为了安全起见,只有当 witness_node 网络正常时,才处理提现。
在负责提现的 cli_wallet 中使用 info 命令检查网络状态。
unlocked >>> info
info
{
"head_block_num": 17249870,
"head_block_id": "0107364e2bf1c4ed1331ece4ad7824271e563fbb",
"head_block_age": "23 seconds old",
"next_maintenance_time": "31 minutes in the future",
"chain_id": "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8",
"participation": "96.87500000000000000",
...
}
需检查的字段有:
* head_block_age 最好是在 1 分钟以内
* participation 最好在 80 以上,表示 witness_node 所连网络有 80% 的出块节点正常工作
另外,网络正常时, last_irreversible_block_num 与 head_block_num 之间的差值不会太大(一般 30 以内);
这个可以作为参考。
10.2 提现账户余额检查
使用 list_account_balances 命令检查提现账户余额是否足够(注意资产类型、并且算上手续费)
unlocked >>> list_account_balances withdrawal-account
注:
1) 注意资产类型
2) 注意加上手续费。因为备注是按长度收费,所以带备注时手续费会比不带备注时高一些。
10.3 提现目的账号名检查
使用 get_account_id 命令可以检查客户输入的提现目的账号是否有效
locked >>> get_account_id test-123
get_account_id test-123
"1.2.96698"
locked >>> get_account_id test-124
get_account_id test-124
10 assert_exception: Assert Exception
rec && rec->name == account_name_or_id:
{}
th_a wallet.cpp:597 get_account
10.4 发送提现
使用 transfer2 命令发送提现交易。如:
unlocked >>> transfer2 withdrawal-account to-account 100 BTS "some memo"
参数分别是:源账户名,目的账户名,金额,币种,备注
该命令会签名并广播交易,然后返回一个数组,第一个元素是交易 id ,第二个元素是详细交易内容
注:
1) 如果币种是 BTS ,金额小数位数最多 5 位。如果是其他资产,通过 get_asset 命令可以查看资产的小数位数,"precision"字段。
2) 也可以使用 transfer 命令,但是这样不会直接返回交易 ID ,而是需要调用其他 API 来计算出来,所以不推荐。
3) 备注通常用 UTF-8 编码
4) 建议记录相关数据备查,比如交易 id 、 json 格式的详细交易内容等
10.5 提现结果检查
使用 get_relative_account_history 命令获取 withdrawal-account 的提现历史,参照充值处理章节,如果发现有新的记录,
并且交易所在块号早于 last_irreversible_block_num ,则表示交易已经进块并且不可回退;
注意:交易没有进块时,仍然可能在 get_relative_account_history 中出现,并且所在块号会一直改变,难以判断状态。
所以请使用 last_irreversible_block_num 来判断。
根据该条记录的 block_num 字段,使用 get_block 命令查询详情
unlocked >>> get_block 12345
返回结果中, transaction_ids 字段数据里应该包含前面的交易 id 。
建议记录上述 get_relative_account_history 结果中的 id (1.11.x), block_num, trx_in_block 备查。
10.6 关于失败重发
在有些情况下可能交易发送后,没有及时被打包进入区块。
与比特币不同, BTS 的交易里面有个超时时间字段(expiration),
使用 cli_wallet 签名广播交易时,该字段值默认是本机系统时间加 2 分钟。
本机交易特别多的时候,超时时间会加长。
如果在网络时间到达该超时时间之后,交易仍然没有被打包进块,则该交易会被所有网络节点丢弃,不再有可能被打包。
因此,如果出现交易广播了但没有在账户历史中出现,先检查本机系统时间是否滞后。
* 如果 last_irreversible_block_num 对应的块时间已经过了交易的超时时间,那么重发是安全的。
* 如果交易已经在历史中出现,则检查交易所在块号是否已经固定,而不是一直随着最新块号更新
* 如果交易所在块号一直更新,表示交易还没被打包进块,需继续耐心等待被打包或超时
* 如果块号已固定,随着时间推移,网络正常时, last_irreversible_block_num 很快就会超过该块号
* 如果 head_block_num 一直增长,而 last_irreversible_block_num 不增长,
则很可能 witness_node 进入了一个较短分叉链,或者网络出现问题,导致交易无法完全确认。
这种情况下,请检查 witness_node 是否有新版本需要升级,或联系开发团队
* 如果重发仍然无法被打包,则可能遇到网络异常或者拥堵,这种情况比较少见,请联系开发团队
11. 其他
* cli_wallet 有个参数 --daemon ,使用此参数启动后,会在后台运行
* 需要关闭 witness_node 时,按一次 Ctrl C,然后等待程序自己退出。
* 正常退出后,重新启动时,不需重建索引,启动会比较快
* 正常退出后,可以对数据目录 witness_node_data_dir 打包备份,需要时可直接恢复使用
* 如果异常退出,则重新启动时,很可能需要重建索引,启动比较慢
* 如果 witness_node 出现异常,一般先尝试重启,如果不行则可尝试带 --replay-blockchain 参数重启,即手工触发重建索引
* 如果没有解决,则使用备份恢复
* 如果没有备份,则重新同步,可能耗时较长
* 多重签名: BTS 原生支持账户级多重签名,并且有提案-批准的机制,可以在线发起多签请求,然后确认完成多签交易,具体参考相关教程
* 硬件钱包:
* Ledger Nano S : https://github.com/bitshares/ledger-app-bitshares
* Keybox : https://keybox.magicw.net/
* 冷存储: 可以实现,步骤有些复杂,示例:
* 在离线机器,使用 cli_wallet --suggest_brain_key 命令离线生成密钥对;
* 然后用轻钱包将账户密钥修改为上述密钥,则账户进入冷存状态
* 需要动用冷存账户时,
* 可以用暂时变热的方式,即将私钥导入轻钱包使用,用完后再换成新密钥
* 纯冷模式也可实现,但当前 cli_wallet 支持不好,有需要的请单独联系
12. 相关资料
* 图文教程 http://jc.btsabc.org/
* 自建节点教程 http://btsabc.org/article-477-1.html
* 获取账户私钥 http://btsabc.org/article-761-1.html
* 英文对接文档 https://dev.bitshares.works/en/master/bts_guide/tutorials/exchange_single_node.html
* 英文 API 文档 https://dev.bitshares.works/en/master/api/index_api.html