DMC 安全指南

該指南旨在幫助業務方瞭解在對接 DMC 時需要注意的安全問題,以及如何防範這些安全問題。

交易所充提接入方案

基本邏輯

充值:用戶需要向交易所的賬戶充值,為此,交易所會生成一個在平臺內唯一可識別的標識。當用戶充值到交易所賬戶時,需要在轉賬操作的”memo”字段中填入交易所為該用戶生成的唯一標識。

提現:用戶在進行提現時,需要填寫自己的 DMC 賬戶。交易所通過轉賬方式將用戶提現的 DMC 數量轉給用戶填寫的賬戶名,從而完成提幣操作。在此過程中,”memo”字段可能也有必要的,因為用戶有可能從一個交易所提現至另一個交易所。

注意事項

DMC 支持兩種轉賬方式,分別是 transferextransfer

其區別在於,transfer 操作只能轉移官方發行的通證,即 contract@datamall 的通證,而 extransfer 則可以轉移任意通證。

目前,DMC 中官方發行的通證有 DMC@datamallPST@datamall,僅支持 DMC@datamall 進行轉賬操作

DMC@datamall 是四位精度,最小單位為 0.0001 DMC

示例

extransfer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
account: 'dmc.token',
name: 'extransfer',
authorization: [{
actor: account,
permission: 'active',
}],
data: {
from: account,
to: to,
quantity: {
quantity: `${amount} DMC`,
contract: 'datamall'
}
memo: memo
}
}

鏈上返回結果:

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
{
"transaction_id": "2b0e27e0b9c9d6c6ada6b09be5c267c7e2ce1926e6fa4bc7d3fae369d22175ca",
"processed": {
"id": "2b0e27e0b9c9d6c6ada6b09be5c267c7e2ce1926e6fa4bc7d3fae369d22175ca",
"block_num": 13111072,
"block_time": "2023-06-19T04:20:50.500",
"producer_block_id": null,
"receipt": {
"status": "executed",
"cpu_usage_us": 421,
"net_usage_words": 18
},
"elapsed": 421,
"net_usage": 144,
"scheduled": false,
"action_traces": [
{
"action_ordinal": 1,
"creator_action_ordinal": 0,
"closest_unnotified_ancestor_action_ordinal": 0,
"receipt": {
"receiver": "dmc.token",
"act_digest": "b238dc7fc3dd05f45fde4ecc48bb66fad2c1669f1f81af51fd3384866e881c6f",
"global_sequence": 13486942,
"recv_sequence": 390918,
"auth_sequence": [
[
"speakfool123",
211
]
],
"code_sequence": 37,
"abi_sequence": 37
},
"receiver": "dmc.token",
"act": {
"account": "dmc.token",
"name": "extransfer",
"authorization": [
{
"actor": "speakfool123",
"permission": "active"
}
],
"data": {
"from": "speakfool123",
"to": "asdasdqwdqwd",
"quantity": {
"quantity": "0.0001 DMC",
"contract": "datamall"
},
"memo": "test"
},
"hex_data": "304488942e6854c590b84ddc266c1236010000000000000004444d4300000000000000311a69b2490474657374"
},
"context_free": false,
"elapsed": 131,
"console": "",
"trx_id": "2b0e27e0b9c9d6c6ada6b09be5c267c7e2ce1926e6fa4bc7d3fae369d22175ca",
"block_num": 13111072,
"block_time": "2023-06-19T04:20:50.500",
"producer_block_id": null,
"account_ram_deltas": [],
"except": null,
"error_code": null,
"return_value_hex_data": "",
"inline_traces": []
}
],
"account_ram_delta": null,
"except": null,
"error_code": null
}
}

transfer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"account": "dmc.token",
"name": 'transfer',
"authorization": [{
actor: from,
permission: 'active',
}],
"data": {
"from": from,
"to": to,
"quantity": `${amount} DMC`,
"memo": memo
}
}

鏈上返回結果:

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
{
"transaction_id": "eeaa563d937e26dafa39cbe306faf47fa7a55d75ea558aa34148d206eecd0a86",
"processed": {
"id": "eeaa563d937e26dafa39cbe306faf47fa7a55d75ea558aa34148d206eecd0a86",
"block_num": 13110171,
"block_time": "2023-06-19T04:13:20.000",
"producer_block_id": null,
"receipt": {
"status": "executed",
"cpu_usage_us": 356,
"net_usage_words": 17
},
"elapsed": 356,
"net_usage": 136,
"scheduled": false,
"action_traces": [
{
"action_ordinal": 1,
"creator_action_ordinal": 0,
"closest_unnotified_ancestor_action_ordinal": 0,
"receipt": {
"receiver": "dmc.token",
"act_digest": "75efa22efa51fc67e8379ca04d92b2dbdc4fef20652ad21995e4cd34226d2a36",
"global_sequence": 13486018,
"recv_sequence": 390897,
"auth_sequence": [
[
"speakfool123",
208
]
],
"code_sequence": 37,
"abi_sequence": 37
},
"receiver": "dmc.token",
"act": {
"account": "dmc.token",
"name": "transfer",
"authorization": [
{
"actor": "speakfool123",
"permission": "active"
}
],
"data": {
"from": "speakfool123",
"to": "asdasdqwdqwd",
"quantity": "0.0001 DMC",
"memo": "test"
},
"hex_data": "304488942e6854c590b84ddc266c1236010000000000000004444d43000000000474657374"
},
"context_free": false,
"elapsed": 152,
"console": "",
"trx_id": "eeaa563d937e26dafa39cbe306faf47fa7a55d75ea558aa34148d206eecd0a86",
"block_num": 13110171,
"block_time": "2023-06-19T04:13:20.000",
"producer_block_id": null,
"account_ram_deltas": [],
"except": null,
"error_code": null,
"return_value_hex_data": "",
"inline_traces": []
}
],
"account_ram_delta": null,
"except": null,
"error_code": null
}
}

參數說明詳見 接口文檔

“假幣”充值

需要甄別,僅支持接受 DMC@datamall 的轉賬,其他通證的轉賬均視為無效交易。

對於transfer,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"act": {
"account": "dmc.token",
"name": "transfer",
"authorization": [
{
"actor": "speakfool123",
"permission": "active"
}
],
"data": {
"from": "speakfool123",
"to": "asdasdqwdqwd",
"quantity": "0.0001 DMC",
"memo": "test"
},
"hex_data": "304488942e6854c590b84ddc266c1236010000000000000004444d43000000000474657374"
}

需要注意:

對於extransfer,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"act": {
"account": "dmc.token",
"name": "extransfer",
"authorization": [
{
"actor": "speakfool123",
"permission": "active"
}
],
"data": {
"from": "speakfool123",
"to": "asdasdqwdqwd",
"quantity": {
"quantity": "0.0001 DMC",
"contract": "datamall"
},
"memo": "test"
},
"hex_data": "304488942e6854c590b84ddc266c1236010000000000000004444d4300000000000000311a69b2490474657374"
}

需要注意:

交易狀態確認

不可逆高度判斷

由於 DMC 使用了 PoSS的共識機制,在判斷一筆交易時,需要確保該交易已經被確認幷包含在不可逆的區塊中。不可逆高度是指在當前 DMC 節點網絡中已經達到共識的高度,低於這個高度的區塊不可被回滾。這意味著該高度以內的交易已經得到足夠的確認,不會被篡改或逆轉。

對於 DMC 網絡,如果一筆交易所在的區塊高度大於不可逆高度,那麼該交易仍處於可逆狀態,可能會受到區塊鏈的重組或其他攻擊的影響。但如果一筆交易所在的區塊高度小於或等於不可逆高度,我們可以確定該交易已經被足 夠多的 BP 節點確認,進入了不可逆狀態,不會再被回滾。

Hard - failed 狀態攻擊

DMC 鏈上交易的執行狀態存在多種,其中有一種狀態為 hard-failed,處於這種狀態下的交易的特點是,沒有被成功執行,但是依舊在鏈上留下了記錄,攻擊者可以利用 DMC 的這一交易特性對業務方造成威脅,從而進行無效交易。對這一安全威脅的防範辦法是,在不可逆高度的基礎上,對交易的狀態進行判斷,如果發現交易的狀態是 hard-failed 則認定為是非法交易。

chain/get_transaction_status

以下操作需要對應請求節點已經配置了transaction-finality-status-max-storage-size-gb的配置項,如果涉及資金問題,推薦維護自有同步節點。

1
2
3
4
5
curl --location '${RPC_ENDPOINT}/v1/chain/get_transaction_status' \
--header 'Content-Type: application/json' \
--data '{
"id": "TRX_ID"
}'

如果請求正確,會返回以下結果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"state": "IRREVERSIBLE",
"block_number": 14899444,
"block_id": "00e358f4f8906b140aff2db43ed991aea50255223eb0660e87e6c84861c2dbbc",
"block_timestamp": "2023-07-06T09:27:05.000",
"expiration": "2023-07-06T09:27:29.000",
"head_number": 14899540,
"head_id": "00e3595421070003362eb53f66808cfc9a1dd84e66c6fd63f23faa35493b8b31",
"head_timestamp": "2023-07-06T09:27:53.000",
"irreversible_number": 14899493,
"irreversible_id": "00e35925187869c08d4fba75234066fd4e203ada79b0d923adab4ecfcd116806",
"irreversible_timestamp": "2023-07-06T09:27:29.500",
"earliest_tracked_block_id": "00e35341164012efb8685db89045bd88164adf21d8a7386c399437b8d644cd26",
"earliest_tracked_block_number": 14897985
}

注意事項:

  1. state 為 IRREVERSIBLE 表示該交易已經被不可逆區塊確認,不會被回滾。
  2. 記錄默認保留 3 分鐘,超過時間則變為 UNKNOWN 狀態,如果有額外需要可以修改參數項 transaction-finality-status-success-duration-sec,默認值為 180 秒。

trace_api/get_block

以下操作需要對應請求節點已經加載了trace_api_plugin,如果涉及資金問題,推薦維護自有同步節點。

1
2
3
4
5
curl --location '${RPC_ENDPOINT}/v1/trace_api/get_block' \
--header 'Content-Type: application/json' \
--data '{
"block_num": ${block_num}
}'

如果請求正確,會返回以下結果

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
{
"id": "00f433cc28f34dc4a80e0bcfb6d935d0bf06f1d57210c76485bef6126b6de87e",
"number": 16004044,
"previous_id": "00f433cb0997beac31ea8977415b62fd0ac565aa4eba8a1959fbf7bd7e897e98",
"status": "irreversible",
"timestamp": "2023-05-17T02:47:36.000Z",
"producer": "dmcrc1bppa11",
"transaction_mroot": "0000000000000000000000000000000000000000000000000000000000000000",
"action_mroot": "ea58ff5ff979f865869ebc38606017291950aeb9d67181e884e6722d048cce04",
"schedule_version": 4,
"transactions": [
{
"id": "a2d14ce284e5b3ad6ac708a5744cc8a771a643a0d69cbbf96d4223e40a879a39",
"block_num": 16004044,
"block_time": "2023-05-17T02:47:36.000",
"producer_block_id": "00f433cc28f34dc4a80e0bcfb6d935d0bf06f1d57210c76485bef6126b6de87e",
"actions": [
..
],
"status": "executed",
"cpu_usage_us": 100,
"net_usage_words": 0,
"signatures": [],
"transaction_header": {
"expiration": "2023-05-17T02:47:36",
"ref_block_num": 13259,
"ref_block_prefix": 2005527089,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0
}
}
]
}

注意事項:

  1. 確認 statusirreversible,證明該區塊已經不可逆
  2. 遍歷transactions[],確認所檢索交易在該區塊內
  3. 確認transactions[i].statusexecuted狀態

節點安全

對於交易所自己的 API 節點建議禁用外網 RPC,如果節點需要 RPC 訪問,建議使用內網 HTTP,對應配置示例代碼如下:

1
2
3
chain.load("http", {
"http-server-address": "127.0.0.1:8870",
});