加入節點網絡

上一章中,我們介紹了 DMC 的節點網絡。這一章中,我們將加入其中,成為一個節點,親身體會區塊鏈網絡的魅力。

dmc-nodes

dmc-nodes 是由 DMC 社區提供的一款快速啟動 DMC 主網節點的腳本工具,他能幫助開發者快速啟動三種不同類型的節點。

項目地址:https://github.com/datamallchain/dmc-nodes

安裝

1
2
git clone git@github.com:datamallchain/dmc-nodes.git
cd dmc-nodes

啟動

1
2
3
dmc seed.js // 快速啟動一個同步節點

dmc bp.js // 快速啟動一個 BP 節點

默認數據,配置存儲位置 /data

主網全節點數據同步

全節點區塊數據同步耗時長,DMC 社區提供最新鏡像啟動服務,極大縮短區塊同步時間。

服務地址:http://backups.dmctech.io:2748/

使用方法

  1. 下載數據:

    訪問 http://backups.dmctech.io:2748/ 選擇想要同步的數據包文件,直接點擊下載

    或者獲取文件URL,使用 wget 命令進行下載

    1
    wget http://backups.dmctech.io:2748/data_21395806.tar.gz
  2. 解壓文件:

    1
    tar -zxvSf data_21395806.tar.gz
  3. 修改快速啟動腳本配置文件 config.json :

    將 data_dir 參數指向剛剛數據文件解壓的 data 目錄即可。

    1
    "data_dir": "data",
  4. 啟動全節點

    1
    dmc seed.js

手動加入 DMC 節點網絡

如果你不使用 dmc-nodes 這個工具進行節點啟動的話,你也可以自行編寫啟動腳本,加入到節點網絡中來。

加入 DMC 網絡配置需要涉及幾個關鍵信息:

獲得節點網絡的 chainId

TestNet:

1
chainId: 'c102a8115bef9e4a4e751559aac2cdc2859417e6476f8cb6054cd3f7dffe1ce4'

DMC 主網:

1
chainId: '4d1fb981dd562d2827447dafa89645622bdcd4e29185d60eeb45539f25d2d85d'

提供 P2P 監聽的地址以及端口

1
'p2p-listen-endpoint' : '0.0.0.0:9870'

區塊數據同步的目標節點信息

區塊數據同步必須先從已經在運行的超級節點中同步數據。
TestNet:

1
2
3
4
5
6
7
8
{
"p2p-peer-address": [
"154.31.0.101:9870",
"154.31.0.101:9901",
"154.31.0.72:5701",
"154.31.0.72:5702"
]
}

DMC 主網:
DMC 主網的超級節點已全部被社區節點取代,具體的節點信息,請訪問 https://github.com/datamallchain/p2p-address/blob/main/p2p_address.json

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
{
"p2p-peer-address": [
"206.2.131.160:8871",
"206.2.131.160:8872",
"206.2.131.160:8873",
"154.216.191.129:8872",
"154.216.191.127:8872",
"154.216.191.128:8872",
"154.39.157.175:8872",
"154.39.157.179:8872",
"154.39.157.176:8872",
"154.39.157.177:8872",
"154.216.191.198:8872",
"154.31.50.146:8872",
"154.31.50.161:8872",
"154.31.50.141:8872",
"154.31.50.142:8872",
"154.39.157.178:8872",
"154.31.50.104:8872",
"154.216.191.199:8872",
"154.216.191.200:8872",
"154.31.50.88:8872",
"154.39.150.161:8872"
]
}

注意:示例中給出的 DMC 主網 BP P2P 地址,會發生變動,請時刻關注。

genesis.json 文件

TestNet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"initial_timestamp": "2023-06-06T00:00:00.000",
"initial_key": "DM6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"initial_configuration": {
"max_block_net_usage": 1048576,
"target_block_net_usage_pct": 1000,
"max_transaction_net_usage": 524288,
"base_per_transaction_net_usage": 12,
"net_usage_leeway": 500,
"context_free_discount_net_usage_num": 20,
"context_free_discount_net_usage_den": 100,
"max_block_cpu_usage": 200000,
"target_block_cpu_usage_pct": 1000,
"max_transaction_cpu_usage": 150000,
"min_transaction_cpu_usage": 100,
"max_transaction_lifetime": 3600,
"deferred_trx_expiration_window": 600,
"max_transaction_delay": 3888000,
"max_inline_action_size": 4096,
"max_inline_action_depth": 4,
"max_authority_depth": 6
}
}

DMC 主網:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"initial_timestamp": "2023-01-10T00:00:00.000",
"initial_key": "DM6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"initial_configuration": {
"max_block_net_usage": 1048576,
"target_block_net_usage_pct": 1000,
"max_transaction_net_usage": 524288,
"base_per_transaction_net_usage": 12,
"net_usage_leeway": 500,
"context_free_discount_net_usage_num": 20,
"context_free_discount_net_usage_den": 100,
"max_block_cpu_usage": 200000,
"target_block_cpu_usage_pct": 1000,
"max_transaction_cpu_usage": 150000,
"min_transaction_cpu_usage": 100,
"max_transaction_lifetime": 3600,
"deferred_trx_expiration_window": 600,
"max_transaction_delay": 3888000,
"max_inline_action_size": 4096,
"max_inline_action_depth": 4,
"max_authority_depth": 6
}
}

如何成為一個同步節點

如果節點僅僅作為同步 DMC 區塊數據,非常簡單。以下代碼保存至 sync_node.js:

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
var chain = require('chain');
var bp_dir = "./data"

chain.config_dir = bp_dir;
chain.data_dir = bp_dir;
chain.pubkey_prefix = "DM";
chain.name = "dmc";

console.notice("config_dir:", chain.config_dir);
console.notice("data_dir:", chain.data_dir);

chain.load("http", {
"http-server-address": "0.0.0.0:8870",
"access-control-allow-origin": "*",
"http-validate-host": false,
"verbose-http-errors": true //打開報錯
});

chain.load("net", {
"p2p-peer-address": ["206.2.131.160:8871", "206.2.131.160:8872"], // 根據節點信息修改
"max-clients": 100,
"p2p-listen-endpoint": "0.0.0.0:9870"
});

chain.load("producer", {
'max-transaction-time': 3000,
});


chain.load("chain", {
"contracts-console": true,
"genesis-json": "genesis.json",
"enable-account-queries": true
});

chain.load("chain_api");
chain.load("trace_api", {
"trace-no-abis": "true"
});
chain.start();

上述代碼中,net 模塊中的 p2p-peer-address 是一個可變值,請注意修改。

運行同步節點:

1
dmc sync_node.js

如何成為一個 BP 節點

(* BP 區塊生產者)

重要提示:使用 Producer 身份發起註冊申請,最好 producer key 不要和 active key 一樣!

如果節點需要申請註冊成為 DMC 主網的區塊生產者,需要涉及到 3 個方面:

配置 Producer 信息啟動 DMC 節點服務

只有持有的 PST@datamall 數量達到一定的值,DMC 節點才會真正的成為 Producer,擁有生產區塊的權限,其他情況僅僅作為同步區塊數據的身份存在。

以下代碼實現了配置一個 Producer,保存代碼至 producer_node.js:

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
const dmc = require('chain');
const config = require("./config.json")
console.notice("start dmc producer node");
const DMC = require('dmc.js')
let keys = "";
while (true) {
keys = console.readLine("input the producer-name:private-key! oooo:xxxx\n");
if (keys) break;
}
let public_key = "";
let private_key = "";
let producername = "";
keys = keys.split(":");
producername = keys[0];
private_key = keys[1];

public_key = DMC.ecc.privateToPublic(private_key);
dmc.config_dir = config.config_dir;
dmc.data_dir = config.data_dir;
dmc.pubkey_prefix = "DM";
dmc.name = "dmc";

let chain_config = {
"contracts-console": true,
'chain-state-db-size-mb': 1024 * 1024,
"genesis-json": "genesis.json"
};

console.notice("config_dir:", dmc.config_dir);
console.notice("data_dir:", dmc.data_dir);

dmc.load("http", {
"http-server-address": `0.0.0.0:${config.http_port}`,
"access-control-allow-origin": "*",
"http-validate-host": false,
"verbose-http-errors": true
});

dmc.load("net", {
"max-clients": 100,
"p2p-peer-address": config.p2p_peer_address,
"p2p-listen-endpoint": `0.0.0.0:${config.p2p_port}`
});

dmc.load("producer", {
'producer-name': producername,
'private-key': JSON.stringify([public_key, private_key])
});

dmc.load("chain", chain_config);
dmc.load("chain_api");
dmc.load("producer_api");

dmc.start()

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

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

其中 config.json 的內容為

1
2
3
4
5
6
7
8
9
10
11
12
{
"chainId": "97f1c8a5826da6959a893a1bb66c9efe74c9a52d60fda4c3eac0af0d021f8256",
"httpEndpoint": "http://154.22.123.188:8870",
"url": "explorer.dmctech.io",
"location": 702,
"config_dir": "./data",
"data_dir": "./data",
"http_port": 8781,
"p2p_port": 8681,
"p2p_peer_address": [
]
}

參數說明

配置項 說明 備註
chainId DMC 區塊鏈網絡 ID 不可更改
httpEndpoint 我們提供的 RPC 接口 不可更改
url 註冊 BP 的 url 信息 按需更改
location 註冊 BP 的 地址 按需更改
config_dir 本地區塊鏈配置保存位置 不推薦更改
data_dir 本地區塊鏈數據保存位置 不推薦更改
http_port 本地區塊鏈監聽的 RPC 端口,對外提供訪問服務 按需更改
p2p_port 本地區塊鏈監聽的 p2p 端口,用於其他節點連接 按需更改
p2p_peer_address 需要連接的其他節點 P2P 地址 按需更改

安裝依賴

1
dmc --install dmc.js

運行 Producer 節點:

1
dmc producer_node.js

根據要求輸入私鑰和出塊者名稱,具體格式為

producer-name:private-key

出塊者名稱:私鑰,以英文:為分隔。

以testnetbppa4為例,輸入:

testnetbppa4:5K7NFbDfjxV7khfKdRvPEUt5Ny***cdfiR83p1t3npPEavAegc3

注意保持該進程不會被關閉

使用 Producer 身份發起註冊申請

以下代碼保存至 register_bp.js :

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
var DMC = require('dmc.js');
var config = require("./config.json")
let keys = "";
while (true) {
keys = console.readLine("input the producer-name:private-key! oooo:xxxx\n");
if (keys) break;
}

let public_key = "";
let private_key = "";
let producername = "";
keys = keys.split(":");
producername = keys[0];
private_key = keys[1];
public_key = DMC.ecc.privateToPublic(private_key);

//初始化客戶端
let dmc = DMC({
chainId: config.chainId,
keyProvider: private_key,
httpEndpoint: config.httpEndpoint,
logger: {
log: null,
error: null
}
});

dmc.transact_sync({
actions: [
{
account: 'dmc',
name: 'regproducer',
authorization: [{
actor: producername,
permission: 'active',
}],
data: {
producer: producername,
producer_key: public_key,
url: config.url,
location: config.location
}
}]
}, {
blocksBehind: 3,
expireSeconds: 30,
});

let c = dmc.rpc.get_table_rows_sync({
json: true,
code: "dmc",
scope: "dmc",
table: "producers",
lower_bound: producername,
upper_bound: producername,
limit: 1000
});
console.warn(c);

執行代碼

1
dmc register_bp.js

輸入內容同上

鑄造(mint) PST@datamall 成為 Producer

只有持有足量的 PST@datamall 才有可能成為 Produer,其中鑄造 PST 數量和鑄造合約有關,公式為$PST = \frac{DMC}{m’\times p} $

以下代碼保存至mint.js

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
var DMC = require('dmc.js');
var config = require("./config.json")
let keys = "";
let quantity = "";
while (true) {
keys = console.readLine("input the producer-name:private-key! oooo:xxxx\n");
if (keys) break;
}

while (true) {
quantity = console.readLine("input the quantity of PST be minted: e.g. 20 PST\n");
if (quantity) break;
}

let producername = "";
keys = keys.split(":");
producername = keys[0];
let private_key = keys[1];

//初始化客戶端
let dmc = DMC({
chainId: config.chainId,
keyProvider: private_key,
httpEndpoint: config.httpEndpoint,
logger: {
log: null,
error: null
}
});

dmc.transact_sync({
actions: [
{
account: 'dmc.token',
name: 'mint',
authorization: [{
actor: producername,
permission: 'active',
}],
data: {
"owner": producername,
"asset": {
"quantity": quantity,
"contract": "datamall"
}
}
}]
}, {
blocksBehind: 3,
expireSeconds: 30,
});

let c = dmc.rpc.get_table_rows_sync({
json: true,
code: "dmc.token",
scope: "dmc.token",
table: "pststats",
lower_bound: producername,
upper_bound: producername,
limit: 10,
}).rows;
console.warn(c);

執行代碼

1
$ dmc mint.js
1
2
3
4
input the producer-name:private-key! oooo:xxxx
> testlfdlzz1t:5KUCoizhwKCmrq4FofXbzbzaBjmH28WZ7nFY4VogM6d7LfYWewf
input the quantity of PST be minted: e.g. 20 PST
> 20 PST

上例會鑄造 20 PST@datamall

硬件推薦配置

名稱 配置
CPU 8 核心
內存 16GB RAM
儲存空間 500GB 硬盤