viz-js-lib 0.11.0 → 0.12.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.qoder/docs/spec/viz-dns-nameserver-spec.md +982 -0
- package/.qoder/docs/viz-cpp-node-docs/data-types.md +322 -0
- package/.qoder/docs/viz-cpp-node-docs/index.md +160 -0
- package/.qoder/docs/viz-cpp-node-docs/op-account-market.md +236 -0
- package/.qoder/docs/viz-cpp-node-docs/op-account.md +199 -0
- package/.qoder/docs/viz-cpp-node-docs/op-award.md +162 -0
- package/.qoder/docs/viz-cpp-node-docs/op-committee.md +193 -0
- package/.qoder/docs/viz-cpp-node-docs/op-content.md +157 -0
- package/.qoder/docs/viz-cpp-node-docs/op-escrow.md +224 -0
- package/.qoder/docs/viz-cpp-node-docs/op-invite.md +219 -0
- package/.qoder/docs/viz-cpp-node-docs/op-proposal.md +229 -0
- package/.qoder/docs/viz-cpp-node-docs/op-recovery.md +188 -0
- package/.qoder/docs/viz-cpp-node-docs/op-subscription.md +146 -0
- package/.qoder/docs/viz-cpp-node-docs/op-transfer-vesting.md +224 -0
- package/.qoder/docs/viz-cpp-node-docs/op-witness.md +252 -0
- package/.qoder/docs/viz-cpp-node-docs/plugins.md +887 -0
- package/.qoder/docs/viz-cpp-node-docs/virtual-operations.md +513 -0
- package/.qoder/repowiki/en/content/API Reference/API Reference.md +724 -0
- package/.qoder/repowiki/en/content/API Reference/Configuration Options.md +410 -0
- package/.qoder/repowiki/en/content/API Reference/Core API Methods.md +547 -0
- package/.qoder/repowiki/en/content/API Reference/Streaming APIs.md +380 -0
- package/.qoder/repowiki/en/content/API Reference/Transport Layer.md +341 -0
- package/.qoder/repowiki/en/content/API Reference/VIZ Blockchain Operations Coverage Status.md +427 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Authentication & Cryptography.md +430 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Digital Signatures.md +462 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Key Management.md +456 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Memo Encryption.md +331 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Security Practices.md +488 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Broadcast Transactions.md +432 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Network Broadcasting.md +418 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Operation Construction.md +352 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Transaction Preparation.md +353 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Transaction Signing.md +404 -0
- package/.qoder/repowiki/en/content/Data Serialization/Data Serialization.md +540 -0
- package/.qoder/repowiki/en/content/Data Serialization/Encoding & Decoding.md +463 -0
- package/.qoder/repowiki/en/content/Data Serialization/Object Templates.md +413 -0
- package/.qoder/repowiki/en/content/Data Serialization/Type System.md +514 -0
- package/.qoder/repowiki/en/content/Data Serialization/Validation Rules.md +439 -0
- package/.qoder/repowiki/en/content/Examples & Tutorials.md +485 -0
- package/.qoder/repowiki/en/content/Getting Started.md +345 -0
- package/.qoder/repowiki/en/content/Testing & Development.md +637 -0
- package/.qoder/repowiki/en/content/Utilities & Helpers.md +557 -0
- package/.qoder/repowiki/en/meta/repowiki-metadata.json +1 -0
- package/VIZ-JS-LIB-COVERAGE-STATUS.md +356 -0
- package/config.json +3 -1
- package/dist/statistics.html +1 -1
- package/dist/viz-tests.min.js +32 -42
- package/dist/viz-tests.min.js.gz +0 -0
- package/dist/viz.min.js +8 -18
- package/dist/viz.min.js.gz +0 -0
- package/lib/api/methods.js +24 -0
- package/lib/auth/serializer/src/ChainTypes.js +2 -1
- package/lib/auth/serializer/src/operations.js +35 -2
- package/lib/broadcast/index.js +29 -15
- package/lib/broadcast/operations.js +4 -0
- package/lib/dns.js +658 -0
- package/lib/index.js +3 -1
- package/package.json +3 -2
- package/test/dns.test.js +395 -0
- package/webpack/makeConfig.js +3 -0
|
@@ -0,0 +1,982 @@
|
|
|
1
|
+
# VIZ DNS Nameserver Specification
|
|
2
|
+
|
|
3
|
+
A simple tool for configuring A records and TXT (SSL) records in account metadata on the VIZ blockchain.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
VIZ DNS is a decentralized domain name system that stores NS records directly in the VIZ blockchain. This enables:
|
|
8
|
+
- **Decentralized DNS**: No reliance on traditional DNS providers
|
|
9
|
+
- **Self-signed SSL verification**: Certificate public key hashes stored on-chain for validation
|
|
10
|
+
- **Censorship resistance**: Domain records cannot be seized or modified by third parties
|
|
11
|
+
- **Account-based domains**: VIZ account names serve as domain names
|
|
12
|
+
|
|
13
|
+
## Data Format Specification
|
|
14
|
+
|
|
15
|
+
### JSON Metadata Structure
|
|
16
|
+
|
|
17
|
+
NS data is stored in the `json_metadata` field of a VIZ account using the following JSON format:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"ns": [
|
|
22
|
+
["A", "188.120.231.153"],
|
|
23
|
+
["TXT", "ssl=4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2"]
|
|
24
|
+
],
|
|
25
|
+
"ttl": 28800
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Field Definitions
|
|
30
|
+
|
|
31
|
+
| Field | Type | Description |
|
|
32
|
+
|-------|------|-------------|
|
|
33
|
+
| `ns` | Array | Array of DNS record tuples |
|
|
34
|
+
| `ns[n][0]` | String | Record type: `"A"` or `"TXT"` |
|
|
35
|
+
| `ns[n][1]` | String | Record value (IPv4 address or TXT content) |
|
|
36
|
+
| `ttl` | Integer | Time-to-live in seconds (default: 28800 = 8 hours) |
|
|
37
|
+
|
|
38
|
+
### Supported Record Types
|
|
39
|
+
|
|
40
|
+
#### A Record
|
|
41
|
+
- **Purpose**: Maps domain to IPv4 address
|
|
42
|
+
- **Format**: `["A", "<IPv4_ADDRESS>"]`
|
|
43
|
+
- **Example**: `["A", "188.120.231.153"]`
|
|
44
|
+
- **Multiple A records**: Supported for Round Robin DNS
|
|
45
|
+
|
|
46
|
+
#### TXT Record (SSL)
|
|
47
|
+
- **Purpose**: Stores SHA256 hash of SSL certificate public key
|
|
48
|
+
- **Format**: `["TXT", "ssl=<SHA256_HASH>"]`
|
|
49
|
+
- **Example**: `["TXT", "ssl=4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2"]`
|
|
50
|
+
- **Max length**: 256 characters (per NS standard)
|
|
51
|
+
|
|
52
|
+
### Round Robin DNS Support
|
|
53
|
+
|
|
54
|
+
Multiple A records can be specified for load balancing:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"ns": [
|
|
59
|
+
["A", "188.120.231.153"],
|
|
60
|
+
["A", "192.168.1.100"],
|
|
61
|
+
["A", "10.0.0.50"],
|
|
62
|
+
["TXT", "ssl=4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2"]
|
|
63
|
+
],
|
|
64
|
+
"ttl": 28800
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Blockchain Operations
|
|
71
|
+
|
|
72
|
+
### Operation: account_metadata
|
|
73
|
+
|
|
74
|
+
The `account_metadata` operation is used to set or update NS records in an account's metadata.
|
|
75
|
+
|
|
76
|
+
#### Operation Structure
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
["account_metadata", {
|
|
80
|
+
"account": "<ACCOUNT_NAME>",
|
|
81
|
+
"json_metadata": "<ESCAPED_JSON_STRING>"
|
|
82
|
+
}]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Parameters
|
|
86
|
+
|
|
87
|
+
| Parameter | Type | Required | Description |
|
|
88
|
+
|-----------|------|----------|-------------|
|
|
89
|
+
| `account` | String | Yes | VIZ account name (also serves as domain name) |
|
|
90
|
+
| `json_metadata` | String | Yes | JSON-encoded metadata containing NS records |
|
|
91
|
+
|
|
92
|
+
#### Required Authority
|
|
93
|
+
|
|
94
|
+
- **Regular key** is sufficient to update account metadata
|
|
95
|
+
|
|
96
|
+
#### JavaScript Example (viz-js-lib)
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
const viz = require('viz-js-lib');
|
|
100
|
+
|
|
101
|
+
// Set NS records using helpers
|
|
102
|
+
viz.api.getAccounts(['myaccount'], function(err, accounts) {
|
|
103
|
+
if (!err && accounts.length > 0) {
|
|
104
|
+
const account = accounts[0];
|
|
105
|
+
|
|
106
|
+
// Create NS metadata
|
|
107
|
+
const nsData = viz.dns.createNsMetadata({
|
|
108
|
+
aRecords: ['188.120.231.153'],
|
|
109
|
+
sslHash: '4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2',
|
|
110
|
+
ttl: 28800
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Merge with existing metadata (preserves other fields like profile)
|
|
114
|
+
const updatedMetadata = viz.dns.mergeNsMetadata(account.json_metadata, nsData);
|
|
115
|
+
|
|
116
|
+
// Broadcast transaction
|
|
117
|
+
viz.broadcast.accountMetadata(
|
|
118
|
+
regularKey,
|
|
119
|
+
'myaccount',
|
|
120
|
+
JSON.stringify(updatedMetadata),
|
|
121
|
+
function(err, result) {
|
|
122
|
+
if (!err) {
|
|
123
|
+
console.log('NS records updated successfully');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### JavaScript Example (Manual - viz-world-js style)
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
// Set NS records
|
|
135
|
+
gate.api.getAccount('myaccount', '', function(err, response) {
|
|
136
|
+
if (!err) {
|
|
137
|
+
let metadata = {};
|
|
138
|
+
try {
|
|
139
|
+
metadata = JSON.parse(response.json_metadata);
|
|
140
|
+
} catch (e) {
|
|
141
|
+
metadata = {};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Remove existing NS data
|
|
145
|
+
if (typeof metadata.ns !== 'undefined') delete metadata.ns;
|
|
146
|
+
if (typeof metadata.ttl !== 'undefined') delete metadata.ttl;
|
|
147
|
+
|
|
148
|
+
// Set new NS records
|
|
149
|
+
metadata.ns = [];
|
|
150
|
+
metadata.ns.push(['A', '188.120.231.153']);
|
|
151
|
+
metadata.ns.push(['TXT', 'ssl=4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2']);
|
|
152
|
+
metadata.ttl = 28800;
|
|
153
|
+
|
|
154
|
+
// Broadcast transaction
|
|
155
|
+
gate.broadcast.accountMetadata(
|
|
156
|
+
users[current_user].regular_key,
|
|
157
|
+
current_user,
|
|
158
|
+
JSON.stringify(metadata),
|
|
159
|
+
function(err, result) {
|
|
160
|
+
if (!err) {
|
|
161
|
+
console.log('NS records updated successfully');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### PHP Example
|
|
170
|
+
|
|
171
|
+
```php
|
|
172
|
+
$tx = new Transaction($chain_id);
|
|
173
|
+
|
|
174
|
+
// Build operation
|
|
175
|
+
list($json, $raw) = $tx->build_account_metadata(
|
|
176
|
+
'myaccount',
|
|
177
|
+
addslashes(json_encode([
|
|
178
|
+
'ns' => [
|
|
179
|
+
['A', '188.120.231.153'],
|
|
180
|
+
['TXT', 'ssl=4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2']
|
|
181
|
+
],
|
|
182
|
+
'ttl' => 28800
|
|
183
|
+
]))
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
// Sign and broadcast
|
|
187
|
+
$signed = $tx->sign($regular_private_key, $ref_block_num, $ref_block_prefix, $expiration, $json, $raw);
|
|
188
|
+
$api->execute_method('broadcast_transaction', [$signed]);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Operation: Remove NS Records
|
|
192
|
+
|
|
193
|
+
To remove NS records, update metadata without the `ns` and `ttl` fields:
|
|
194
|
+
|
|
195
|
+
```javascript
|
|
196
|
+
// Using viz-js-lib helpers
|
|
197
|
+
const cleanedMetadata = viz.dns.removeNsMetadata(account.json_metadata);
|
|
198
|
+
viz.broadcast.accountMetadata(
|
|
199
|
+
regularKey,
|
|
200
|
+
'myaccount',
|
|
201
|
+
JSON.stringify(cleanedMetadata),
|
|
202
|
+
callback
|
|
203
|
+
);
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
```javascript
|
|
207
|
+
// Manual approach
|
|
208
|
+
delete metadata.ns;
|
|
209
|
+
delete metadata.ttl;
|
|
210
|
+
gate.broadcast.accountMetadata(
|
|
211
|
+
users[current_user].regular_key,
|
|
212
|
+
current_user,
|
|
213
|
+
JSON.stringify(metadata),
|
|
214
|
+
callback
|
|
215
|
+
);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## API Reference
|
|
221
|
+
|
|
222
|
+
### Get Account NS Data
|
|
223
|
+
|
|
224
|
+
Use the `get_account` or `get_accounts` API methods to retrieve account metadata containing NS records.
|
|
225
|
+
|
|
226
|
+
#### Method: get_accounts
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"jsonrpc": "2.0",
|
|
231
|
+
"method": "call",
|
|
232
|
+
"params": ["database_api", "get_accounts", [["account_name"]]],
|
|
233
|
+
"id": 1
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
#### Response Example
|
|
238
|
+
|
|
239
|
+
```json
|
|
240
|
+
{
|
|
241
|
+
"id": 1,
|
|
242
|
+
"result": [{
|
|
243
|
+
"name": "on1x",
|
|
244
|
+
"json_metadata": "{\"ns\":[[\"A\",\"188.120.231.153\"],[\"TXT\",\"ssl=4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2\"]],\"ttl\":28800}",
|
|
245
|
+
...
|
|
246
|
+
}]
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
#### Method: get_account (custom_protocol_api)
|
|
251
|
+
|
|
252
|
+
```json
|
|
253
|
+
{
|
|
254
|
+
"jsonrpc": "2.0",
|
|
255
|
+
"method": "call",
|
|
256
|
+
"params": ["custom_protocol_api", "get_account", ["account_name", ""]],
|
|
257
|
+
"id": 1
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Parse NS Data (JavaScript) - Using viz-js-lib Helpers
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
const viz = require('viz-js-lib');
|
|
265
|
+
|
|
266
|
+
viz.api.getAccounts(['on1x'], function(err, accounts) {
|
|
267
|
+
if (!err && accounts.length > 0) {
|
|
268
|
+
const account = accounts[0];
|
|
269
|
+
|
|
270
|
+
// Get complete NS summary in one call
|
|
271
|
+
const summary = viz.dns.getNsSummary(account.json_metadata);
|
|
272
|
+
|
|
273
|
+
console.log('IPv4 Addresses:', summary.aRecords); // ['188.120.231.153']
|
|
274
|
+
console.log('SSL Hash:', summary.sslHash); // '4a4613daef37...'
|
|
275
|
+
console.log('TTL:', summary.ttl); // 28800
|
|
276
|
+
|
|
277
|
+
// Or extract individual components
|
|
278
|
+
const ipAddresses = viz.dns.extractARecords(account.json_metadata);
|
|
279
|
+
const sslHash = viz.dns.extractSslHash(account.json_metadata);
|
|
280
|
+
const ttl = viz.dns.extractTtl(account.json_metadata);
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Parse NS Data (JavaScript) - Manual Parsing
|
|
286
|
+
|
|
287
|
+
```javascript
|
|
288
|
+
gate.api.getAccount('on1x', '', function(err, response) {
|
|
289
|
+
if (!err) {
|
|
290
|
+
let metadata = {};
|
|
291
|
+
try {
|
|
292
|
+
metadata = JSON.parse(response.json_metadata);
|
|
293
|
+
} catch (e) {
|
|
294
|
+
metadata = {};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (typeof metadata.ns !== 'undefined') {
|
|
298
|
+
for (let i in metadata.ns) {
|
|
299
|
+
if (metadata.ns[i][0] === 'A') {
|
|
300
|
+
console.log('IPv4:', metadata.ns[i][1]);
|
|
301
|
+
}
|
|
302
|
+
if (metadata.ns[i][0] === 'TXT') {
|
|
303
|
+
let txt_arr = metadata.ns[i][1].split('=');
|
|
304
|
+
if (txt_arr[0] === 'ssl') {
|
|
305
|
+
console.log('SSL Hash:', txt_arr[1]);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (typeof metadata.ttl !== 'undefined') {
|
|
312
|
+
console.log('TTL:', metadata.ttl);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Parse NS Data (PHP)
|
|
319
|
+
|
|
320
|
+
```php
|
|
321
|
+
$api = new JsonRPC($endpoint);
|
|
322
|
+
$accounts = $api->execute_method('get_accounts', [['on1x']]);
|
|
323
|
+
|
|
324
|
+
if ($accounts && count($accounts) > 0) {
|
|
325
|
+
$metadata = json_decode($accounts[0]['json_metadata'], true);
|
|
326
|
+
|
|
327
|
+
if (isset($metadata['ns'])) {
|
|
328
|
+
foreach ($metadata['ns'] as $record) {
|
|
329
|
+
if ($record[0] === 'A') {
|
|
330
|
+
echo "IPv4: " . $record[1] . PHP_EOL;
|
|
331
|
+
}
|
|
332
|
+
if ($record[0] === 'TXT') {
|
|
333
|
+
$txt = explode('=', $record[1]);
|
|
334
|
+
if ($txt[0] === 'ssl') {
|
|
335
|
+
echo "SSL Hash: " . $txt[1] . PHP_EOL;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (isset($metadata['ttl'])) {
|
|
342
|
+
echo "TTL: " . $metadata['ttl'] . PHP_EOL;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## viz-js-lib DNS Helpers Module
|
|
350
|
+
|
|
351
|
+
The `viz-js-lib` library provides a dedicated `dns` module with helper functions for working with VIZ DNS NS records.
|
|
352
|
+
|
|
353
|
+
### Installation
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
npm install viz-js-lib
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Import
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
const viz = require('viz-js-lib');
|
|
363
|
+
// Access via viz.dns.*
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Constants
|
|
367
|
+
|
|
368
|
+
| Constant | Value | Description |
|
|
369
|
+
|----------|-------|-------------|
|
|
370
|
+
| `viz.dns.DEFAULT_TTL` | `28800` | Default TTL in seconds (8 hours) |
|
|
371
|
+
| `viz.dns.MAX_TXT_LENGTH` | `256` | Maximum TXT record length |
|
|
372
|
+
| `viz.dns.SHA256_HEX_LENGTH` | `64` | SHA256 hash length in hex characters |
|
|
373
|
+
|
|
374
|
+
### Validation Functions
|
|
375
|
+
|
|
376
|
+
#### `isValidIPv4(ipv4)`
|
|
377
|
+
Validates an IPv4 address string.
|
|
378
|
+
|
|
379
|
+
```javascript
|
|
380
|
+
viz.dns.isValidIPv4('188.120.231.153'); // true
|
|
381
|
+
viz.dns.isValidIPv4('256.0.0.1'); // false
|
|
382
|
+
viz.dns.isValidIPv4('invalid'); // false
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
#### `isValidSHA256Hash(hash)`
|
|
386
|
+
Validates a SHA256 hash string (64 hex characters).
|
|
387
|
+
|
|
388
|
+
```javascript
|
|
389
|
+
viz.dns.isValidSHA256Hash('4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2'); // true
|
|
390
|
+
viz.dns.isValidSHA256Hash('invalid'); // false
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
#### `isValidTTL(ttl)`
|
|
394
|
+
Validates a TTL value (must be positive integer).
|
|
395
|
+
|
|
396
|
+
```javascript
|
|
397
|
+
viz.dns.isValidTTL(28800); // true
|
|
398
|
+
viz.dns.isValidTTL(-1); // false
|
|
399
|
+
viz.dns.isValidTTL(1.5); // false
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
#### `isValidSslTxtRecord(txt)`
|
|
403
|
+
Validates an SSL TXT record format (`ssl=<hash>`).
|
|
404
|
+
|
|
405
|
+
```javascript
|
|
406
|
+
viz.dns.isValidSslTxtRecord('ssl=4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2'); // true
|
|
407
|
+
viz.dns.isValidSslTxtRecord('ssl=invalid'); // false
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
#### `validateNsMetadata(nsData)`
|
|
411
|
+
Performs complete validation of NS metadata structure.
|
|
412
|
+
|
|
413
|
+
```javascript
|
|
414
|
+
const result = viz.dns.validateNsMetadata({
|
|
415
|
+
ns: [['A', '188.120.231.153'], ['TXT', 'ssl=...']],
|
|
416
|
+
ttl: 28800
|
|
417
|
+
});
|
|
418
|
+
console.log(result.isValid); // true
|
|
419
|
+
console.log(result.errors); // []
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Record Creation Functions
|
|
423
|
+
|
|
424
|
+
#### `createARecord(ipv4)`
|
|
425
|
+
Creates an A record tuple.
|
|
426
|
+
|
|
427
|
+
```javascript
|
|
428
|
+
viz.dns.createARecord('188.120.231.153');
|
|
429
|
+
// Returns: ['A', '188.120.231.153']
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
#### `createSslTxtRecord(hash)`
|
|
433
|
+
Creates an SSL TXT record tuple from a SHA256 hash.
|
|
434
|
+
|
|
435
|
+
```javascript
|
|
436
|
+
viz.dns.createSslTxtRecord('4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2');
|
|
437
|
+
// Returns: ['TXT', 'ssl=4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2']
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
#### `createTxtRecord(value)`
|
|
441
|
+
Creates a generic TXT record tuple.
|
|
442
|
+
|
|
443
|
+
```javascript
|
|
444
|
+
viz.dns.createTxtRecord('custom=value');
|
|
445
|
+
// Returns: ['TXT', 'custom=value']
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
#### `createNsMetadata(options)`
|
|
449
|
+
Creates a complete NS metadata object.
|
|
450
|
+
|
|
451
|
+
```javascript
|
|
452
|
+
const nsData = viz.dns.createNsMetadata({
|
|
453
|
+
aRecords: ['188.120.231.153', '192.168.1.100'],
|
|
454
|
+
sslHash: '4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2',
|
|
455
|
+
ttl: 28800 // optional, defaults to 28800
|
|
456
|
+
});
|
|
457
|
+
// Returns:
|
|
458
|
+
// {
|
|
459
|
+
// ns: [
|
|
460
|
+
// ['A', '188.120.231.153'],
|
|
461
|
+
// ['A', '192.168.1.100'],
|
|
462
|
+
// ['TXT', 'ssl=4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2']
|
|
463
|
+
// ],
|
|
464
|
+
// ttl: 28800
|
|
465
|
+
// }
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### Parsing Functions
|
|
469
|
+
|
|
470
|
+
#### `parseNsMetadata(jsonMetadata)`
|
|
471
|
+
Parses NS metadata from account `json_metadata` (string or object).
|
|
472
|
+
|
|
473
|
+
```javascript
|
|
474
|
+
const nsData = viz.dns.parseNsMetadata(account.json_metadata);
|
|
475
|
+
// Returns: { ns: [...], ttl: 28800 } or null if not found
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
#### `extractARecords(jsonMetadata)`
|
|
479
|
+
Extracts all IPv4 addresses from A records.
|
|
480
|
+
|
|
481
|
+
```javascript
|
|
482
|
+
const ips = viz.dns.extractARecords(account.json_metadata);
|
|
483
|
+
// Returns: ['188.120.231.153', '192.168.1.100']
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
#### `extractSslHash(jsonMetadata)`
|
|
487
|
+
Extracts the SSL certificate hash from TXT records.
|
|
488
|
+
|
|
489
|
+
```javascript
|
|
490
|
+
const hash = viz.dns.extractSslHash(account.json_metadata);
|
|
491
|
+
// Returns: '4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2' or null
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
#### `extractTxtRecords(jsonMetadata)`
|
|
495
|
+
Extracts all TXT record values.
|
|
496
|
+
|
|
497
|
+
```javascript
|
|
498
|
+
const txtRecords = viz.dns.extractTxtRecords(account.json_metadata);
|
|
499
|
+
// Returns: ['ssl=4a4613...', 'other=value']
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
#### `extractTtl(jsonMetadata)`
|
|
503
|
+
Extracts the TTL value (returns default if not set).
|
|
504
|
+
|
|
505
|
+
```javascript
|
|
506
|
+
const ttl = viz.dns.extractTtl(account.json_metadata);
|
|
507
|
+
// Returns: 28800
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
#### `getNsSummary(jsonMetadata)`
|
|
511
|
+
Returns a complete summary of all NS data.
|
|
512
|
+
|
|
513
|
+
```javascript
|
|
514
|
+
const summary = viz.dns.getNsSummary(account.json_metadata);
|
|
515
|
+
// Returns:
|
|
516
|
+
// {
|
|
517
|
+
// aRecords: ['188.120.231.153'],
|
|
518
|
+
// sslHash: '4a4613daef37...',
|
|
519
|
+
// txtRecords: ['ssl=4a4613daef37...'],
|
|
520
|
+
// ttl: 28800
|
|
521
|
+
// }
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
#### `hasNsRecords(jsonMetadata)`
|
|
525
|
+
Checks if NS records exist in the metadata.
|
|
526
|
+
|
|
527
|
+
```javascript
|
|
528
|
+
if (viz.dns.hasNsRecords(account.json_metadata)) {
|
|
529
|
+
console.log('Account has NS records configured');
|
|
530
|
+
}
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
### Metadata Manipulation Functions
|
|
534
|
+
|
|
535
|
+
#### `mergeNsMetadata(existingMetadata, nsData)`
|
|
536
|
+
Merges NS data into existing account metadata (preserves other fields).
|
|
537
|
+
|
|
538
|
+
```javascript
|
|
539
|
+
const existingMetadata = { profile: { name: 'My Site' } };
|
|
540
|
+
const nsData = viz.dns.createNsMetadata({ aRecords: ['188.120.231.153'] });
|
|
541
|
+
const merged = viz.dns.mergeNsMetadata(existingMetadata, nsData);
|
|
542
|
+
// Returns:
|
|
543
|
+
// {
|
|
544
|
+
// profile: { name: 'My Site' },
|
|
545
|
+
// ns: [['A', '188.120.231.153']],
|
|
546
|
+
// ttl: 28800
|
|
547
|
+
// }
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
#### `removeNsMetadata(existingMetadata)`
|
|
551
|
+
Removes NS data from metadata (preserves other fields).
|
|
552
|
+
|
|
553
|
+
```javascript
|
|
554
|
+
const cleaned = viz.dns.removeNsMetadata(account.json_metadata);
|
|
555
|
+
// Returns metadata without ns and ttl fields
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
#### `addARecord(jsonMetadata, ipv4)`
|
|
559
|
+
Adds an A record to existing metadata.
|
|
560
|
+
|
|
561
|
+
```javascript
|
|
562
|
+
const updated = viz.dns.addARecord(account.json_metadata, '192.168.1.100');
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
#### `removeARecord(jsonMetadata, ipv4)`
|
|
566
|
+
Removes a specific A record from metadata.
|
|
567
|
+
|
|
568
|
+
```javascript
|
|
569
|
+
const updated = viz.dns.removeARecord(account.json_metadata, '192.168.1.100');
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
#### `setSslHash(jsonMetadata, hash)`
|
|
573
|
+
Sets or updates the SSL hash (replaces existing if present).
|
|
574
|
+
|
|
575
|
+
```javascript
|
|
576
|
+
const updated = viz.dns.setSslHash(account.json_metadata, 'new_hash_here...');
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
#### `removeSslHash(jsonMetadata)`
|
|
580
|
+
Removes the SSL hash TXT record.
|
|
581
|
+
|
|
582
|
+
```javascript
|
|
583
|
+
const updated = viz.dns.removeSslHash(account.json_metadata);
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
#### `setTtl(jsonMetadata, ttl)`
|
|
587
|
+
Sets the TTL value.
|
|
588
|
+
|
|
589
|
+
```javascript
|
|
590
|
+
const updated = viz.dns.setTtl(account.json_metadata, 3600); // 1 hour
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Complete Usage Examples
|
|
594
|
+
|
|
595
|
+
#### Setting NS Records with viz-js-lib
|
|
596
|
+
|
|
597
|
+
```javascript
|
|
598
|
+
const viz = require('viz-js-lib');
|
|
599
|
+
|
|
600
|
+
// Get current account metadata
|
|
601
|
+
viz.api.getAccounts(['myaccount'], function(err, accounts) {
|
|
602
|
+
if (err) return console.error(err);
|
|
603
|
+
|
|
604
|
+
const account = accounts[0];
|
|
605
|
+
|
|
606
|
+
// Create NS data
|
|
607
|
+
const nsData = viz.dns.createNsMetadata({
|
|
608
|
+
aRecords: ['188.120.231.153'],
|
|
609
|
+
sslHash: '4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2',
|
|
610
|
+
ttl: 28800
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
// Merge with existing metadata
|
|
614
|
+
const updatedMetadata = viz.dns.mergeNsMetadata(account.json_metadata, nsData);
|
|
615
|
+
|
|
616
|
+
// Broadcast update
|
|
617
|
+
viz.broadcast.accountMetadata(
|
|
618
|
+
regularKey,
|
|
619
|
+
'myaccount',
|
|
620
|
+
JSON.stringify(updatedMetadata),
|
|
621
|
+
function(err, result) {
|
|
622
|
+
if (!err) {
|
|
623
|
+
console.log('NS records updated successfully');
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
);
|
|
627
|
+
});
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
#### Adding Round Robin A Records
|
|
631
|
+
|
|
632
|
+
```javascript
|
|
633
|
+
let metadata = viz.dns.addARecord(account.json_metadata, '188.120.231.153');
|
|
634
|
+
metadata = viz.dns.addARecord(metadata, '192.168.1.100');
|
|
635
|
+
metadata = viz.dns.addARecord(metadata, '10.0.0.50');
|
|
636
|
+
metadata = viz.dns.setSslHash(metadata, 'your_ssl_hash_here');
|
|
637
|
+
|
|
638
|
+
// Broadcast the update...
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
#### Removing NS Configuration
|
|
642
|
+
|
|
643
|
+
```javascript
|
|
644
|
+
const cleanedMetadata = viz.dns.removeNsMetadata(account.json_metadata);
|
|
645
|
+
|
|
646
|
+
viz.broadcast.accountMetadata(
|
|
647
|
+
regularKey,
|
|
648
|
+
'myaccount',
|
|
649
|
+
JSON.stringify(cleanedMetadata),
|
|
650
|
+
callback
|
|
651
|
+
);
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
#### Validating NS Configuration Before Broadcast
|
|
655
|
+
|
|
656
|
+
```javascript
|
|
657
|
+
const nsData = viz.dns.createNsMetadata({
|
|
658
|
+
aRecords: ['188.120.231.153'],
|
|
659
|
+
sslHash: 'your_hash_here'
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
const validation = viz.dns.validateNsMetadata(nsData);
|
|
663
|
+
if (!validation.isValid) {
|
|
664
|
+
console.error('Invalid NS configuration:', validation.errors);
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// Proceed with broadcast...
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
673
|
+
## SSL Certificate Verification
|
|
674
|
+
|
|
675
|
+
### Concept
|
|
676
|
+
|
|
677
|
+
VIZ DNS uses a self-signed certificate verification system where:
|
|
678
|
+
1. The **SHA256 hash of the public key** is stored in the TXT record
|
|
679
|
+
2. Clients connect to the server and extract the certificate's public key
|
|
680
|
+
3. The hash is compared to verify authenticity
|
|
681
|
+
|
|
682
|
+
This approach works with:
|
|
683
|
+
- Self-signed certificates
|
|
684
|
+
- Let's Encrypt certificates
|
|
685
|
+
- Any CA-signed certificates
|
|
686
|
+
|
|
687
|
+
### Generating SSL Hash
|
|
688
|
+
|
|
689
|
+
#### From Private Key (Server Side)
|
|
690
|
+
|
|
691
|
+
```bash
|
|
692
|
+
# Get public key hash from private key
|
|
693
|
+
openssl rsa -in /etc/letsencrypt/live/example.com/privkey.pem -pubout | sha256sum
|
|
694
|
+
|
|
695
|
+
# Output: 4a4613daef37cbc5c4a5156cd7b24ea2e6ee2e5f1e7461262a2df2b63cbf17e2
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
#### From Certificate (Server Side)
|
|
699
|
+
|
|
700
|
+
```bash
|
|
701
|
+
# Get public key hash from certificate chain
|
|
702
|
+
openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -pubkey -nocert | sha256sum
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
#### From Remote Server
|
|
706
|
+
|
|
707
|
+
```bash
|
|
708
|
+
# Get certificate info from remote server
|
|
709
|
+
echo | openssl s_client -servername example.com -connect 188.120.231.153:443 | \
|
|
710
|
+
openssl x509 -noout -pubkey -dates
|
|
711
|
+
|
|
712
|
+
# Get just the public key hash
|
|
713
|
+
echo | openssl s_client -servername example.com -connect 188.120.231.153:443 2>/dev/null | \
|
|
714
|
+
openssl x509 -pubkey -nocert | sha256sum
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### PHP Implementation for SSL Verification
|
|
718
|
+
|
|
719
|
+
```php
|
|
720
|
+
/**
|
|
721
|
+
* Extract SSL public key hash from a domain
|
|
722
|
+
*
|
|
723
|
+
* @param string $domain Domain name or IP address
|
|
724
|
+
* @param string|null $ipv4 Optional IP address override
|
|
725
|
+
* @return array ['error' => bool, 'result' => [ipv4, hash]]
|
|
726
|
+
*/
|
|
727
|
+
function get_ssl_hash($domain, $ipv4 = null) {
|
|
728
|
+
// Resolve IP if not provided
|
|
729
|
+
if ($ipv4 === null) {
|
|
730
|
+
$ipv4 = gethostbyname($domain);
|
|
731
|
+
if ($ipv4 === $domain) {
|
|
732
|
+
return ['error' => 'dns_resolution_failed'];
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// Create SSL context
|
|
737
|
+
$streamContext = stream_context_create([
|
|
738
|
+
'ssl' => [
|
|
739
|
+
'peer_name' => $domain,
|
|
740
|
+
'verify_peer' => false,
|
|
741
|
+
'verify_peer_name' => false,
|
|
742
|
+
'capture_peer_cert' => true,
|
|
743
|
+
],
|
|
744
|
+
]);
|
|
745
|
+
|
|
746
|
+
// Connect to server
|
|
747
|
+
$client = stream_socket_client(
|
|
748
|
+
'ssl://' . $ipv4 . ':443',
|
|
749
|
+
$errorNumber,
|
|
750
|
+
$errorDescription,
|
|
751
|
+
3,
|
|
752
|
+
STREAM_CLIENT_CONNECT,
|
|
753
|
+
$streamContext
|
|
754
|
+
);
|
|
755
|
+
|
|
756
|
+
if ($errorNumber !== 0) {
|
|
757
|
+
return ['error' => 'connection_failed: ' . $errorDescription];
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
$response = stream_context_get_params($client);
|
|
761
|
+
|
|
762
|
+
// Extract public key and compute hash
|
|
763
|
+
$public_key = openssl_pkey_get_public(
|
|
764
|
+
$response['options']['ssl']['peer_certificate']
|
|
765
|
+
);
|
|
766
|
+
$public_key_data = openssl_pkey_get_details($public_key);
|
|
767
|
+
|
|
768
|
+
// Hash the full PEM-encoded public key (including headers)
|
|
769
|
+
$hash = hash('sha256', $public_key_data['key'], false);
|
|
770
|
+
|
|
771
|
+
fclose($client);
|
|
772
|
+
|
|
773
|
+
return ['error' => false, 'result' => [$ipv4, $hash]];
|
|
774
|
+
}
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
### Complete SSL Verification Process
|
|
778
|
+
|
|
779
|
+
```php
|
|
780
|
+
/**
|
|
781
|
+
* Verify SSL certificate against VIZ blockchain records
|
|
782
|
+
*
|
|
783
|
+
* @param string $account VIZ account name (domain)
|
|
784
|
+
* @param string $ipv4 Server IP address
|
|
785
|
+
* @return bool True if certificate is valid
|
|
786
|
+
*/
|
|
787
|
+
function verify_viz_ssl($account, $ipv4) {
|
|
788
|
+
global $api;
|
|
789
|
+
|
|
790
|
+
// 1. Get account metadata from blockchain
|
|
791
|
+
$accounts = $api->execute_method('get_accounts', [[$account]]);
|
|
792
|
+
if (!$accounts || count($accounts) === 0) {
|
|
793
|
+
return false;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
$metadata = json_decode($accounts[0]['json_metadata'], true);
|
|
797
|
+
if (!isset($metadata['ns'])) {
|
|
798
|
+
return false;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// 2. Extract expected SSL hash from TXT record
|
|
802
|
+
$expected_hash = null;
|
|
803
|
+
foreach ($metadata['ns'] as $record) {
|
|
804
|
+
if ($record[0] === 'TXT') {
|
|
805
|
+
$txt = explode('=', $record[1]);
|
|
806
|
+
if ($txt[0] === 'ssl') {
|
|
807
|
+
$expected_hash = $txt[1];
|
|
808
|
+
break;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
if ($expected_hash === null) {
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// 3. Get actual SSL hash from server
|
|
818
|
+
$ssl_result = get_ssl_hash($account, $ipv4);
|
|
819
|
+
if ($ssl_result['error'] !== false) {
|
|
820
|
+
return false;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
$actual_hash = $ssl_result['result'][1];
|
|
824
|
+
|
|
825
|
+
// 4. Compare hashes
|
|
826
|
+
return hash_equals($expected_hash, $actual_hash);
|
|
827
|
+
}
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
---
|
|
831
|
+
|
|
832
|
+
## Building a VIZ DNS System
|
|
833
|
+
|
|
834
|
+
### Architecture Recommendations
|
|
835
|
+
|
|
836
|
+
#### 1. DNS Resolver Component
|
|
837
|
+
|
|
838
|
+
Build a custom DNS resolver that:
|
|
839
|
+
- Intercepts DNS queries for `.viz` domains (or custom TLD)
|
|
840
|
+
- Queries VIZ blockchain for account metadata
|
|
841
|
+
- Returns A records from the `ns` array
|
|
842
|
+
- Implements TTL caching based on the `ttl` field
|
|
843
|
+
|
|
844
|
+
```
|
|
845
|
+
Client Request → VIZ DNS Resolver → VIZ Blockchain
|
|
846
|
+
↓
|
|
847
|
+
Local DNS Cache (TTL-based)
|
|
848
|
+
↓
|
|
849
|
+
DNS Response
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
#### 2. SSL/TLS Proxy
|
|
853
|
+
|
|
854
|
+
Implement a reverse proxy that:
|
|
855
|
+
- Terminates TLS connections
|
|
856
|
+
- Validates certificate public key hash against blockchain records
|
|
857
|
+
- Forwards requests to the actual server
|
|
858
|
+
|
|
859
|
+
#### 3. Web Server Configuration (nginx)
|
|
860
|
+
|
|
861
|
+
Configure nginx to serve multiple domains from the same server:
|
|
862
|
+
|
|
863
|
+
```nginx
|
|
864
|
+
server {
|
|
865
|
+
listen 443 ssl;
|
|
866
|
+
server_name example.com www.example.com example; # Include VIZ domain name
|
|
867
|
+
|
|
868
|
+
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
|
|
869
|
+
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
|
|
870
|
+
|
|
871
|
+
# ... rest of config
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
server {
|
|
875
|
+
listen 80;
|
|
876
|
+
server_name example.com www.example.com example;
|
|
877
|
+
|
|
878
|
+
# Redirect to HTTPS
|
|
879
|
+
return 301 https://$host$request_uri;
|
|
880
|
+
}
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
### Implementation Steps
|
|
884
|
+
|
|
885
|
+
#### Step 1: Register VIZ Account
|
|
886
|
+
|
|
887
|
+
The account name serves as the domain name:
|
|
888
|
+
- `on1x` → resolves to `on1x` domain
|
|
889
|
+
- `mysite` → resolves to `mysite` domain
|
|
890
|
+
|
|
891
|
+
#### Step 2: Configure Web Server
|
|
892
|
+
|
|
893
|
+
1. Generate or obtain SSL certificate
|
|
894
|
+
2. Configure nginx to accept connections for the VIZ domain name
|
|
895
|
+
3. Restart nginx: `service nginx restart`
|
|
896
|
+
|
|
897
|
+
#### Step 3: Calculate SSL Hash
|
|
898
|
+
|
|
899
|
+
```bash
|
|
900
|
+
# Calculate hash from your certificate
|
|
901
|
+
openssl x509 -in /etc/letsencrypt/live/yourdomain.com/fullchain.pem -pubkey -nocert | sha256sum
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
#### Step 4: Set NS Records on Blockchain
|
|
905
|
+
|
|
906
|
+
Use the VIZ.World Control Panel (`/tools/ns/`) or programmatically:
|
|
907
|
+
|
|
908
|
+
```javascript
|
|
909
|
+
// Via Control Panel UI or API
|
|
910
|
+
metadata.ns = [
|
|
911
|
+
['A', 'YOUR_SERVER_IP'],
|
|
912
|
+
['TXT', 'ssl=YOUR_CALCULATED_HASH']
|
|
913
|
+
];
|
|
914
|
+
metadata.ttl = 28800;
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
#### Step 5: Implement Client Verification
|
|
918
|
+
|
|
919
|
+
Clients should:
|
|
920
|
+
1. Query VIZ blockchain for account metadata
|
|
921
|
+
2. Extract IP from A record
|
|
922
|
+
3. Connect to server via HTTPS
|
|
923
|
+
4. Extract server's public key
|
|
924
|
+
5. Hash and compare with TXT record
|
|
925
|
+
6. If match, connection is trusted
|
|
926
|
+
|
|
927
|
+
### Security Considerations
|
|
928
|
+
|
|
929
|
+
1. **Hash Algorithm**: SHA256 is recommended for public key hashing
|
|
930
|
+
2. **TTL Management**: Use appropriate TTL values (28800 seconds = 8 hours is default)
|
|
931
|
+
3. **Certificate Rotation**: Update TXT record when certificates are renewed
|
|
932
|
+
4. **Multiple A Records**: Ensure all servers share the same certificate (for Round Robin)
|
|
933
|
+
|
|
934
|
+
### Verification Commands
|
|
935
|
+
|
|
936
|
+
```bash
|
|
937
|
+
# Verify certificate from server
|
|
938
|
+
echo | openssl s_client -servername on1x -connect 188.120.231.153:443 | \
|
|
939
|
+
openssl x509 -noout -pubkey -dates
|
|
940
|
+
|
|
941
|
+
# Get certificate dates
|
|
942
|
+
openssl x509 -in /etc/letsencrypt/live/on1x.com/fullchain.pem -noout -startdate -enddate
|
|
943
|
+
# notBefore=Aug 26 11:17:39 2023 GMT
|
|
944
|
+
# notAfter=Nov 24 11:17:38 2023 GMT
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
---
|
|
948
|
+
|
|
949
|
+
## Existing Implementation Reference
|
|
950
|
+
|
|
951
|
+
### viz-js-lib DNS Module
|
|
952
|
+
- **JavaScript**: [src/dns.js](file:///d:/Work/viz-js-lib/src/dns.js) - DNS helpers module
|
|
953
|
+
- **Tests**: [test/dns.test.js](file:///d:/Work/viz-js-lib/test/dns.test.js) - Test suite
|
|
954
|
+
- **Export**: [src/index.js](file:///d:/Work/viz-js-lib/src/index.js) - Module export as `viz.dns`
|
|
955
|
+
|
|
956
|
+
### VIZ.World Control Panel
|
|
957
|
+
|
|
958
|
+
#### UI Component Location
|
|
959
|
+
- **PHP**: [module/tools.php](file:///d:/Work/viz.world/backup-16-11-2024/control.viz.world/module/tools.php#L25-L34) - `/tools/ns/` route
|
|
960
|
+
- **JavaScript**: [js/app.js](file:///d:/Work/viz.world/backup-16-11-2024/control.viz.world/js/app.js#L2072-L2249) - `ns_control()` function
|
|
961
|
+
|
|
962
|
+
#### AJAX Handler
|
|
963
|
+
- **PHP**: [module/ajax.php](file:///d:/Work/viz.world/backup-16-11-2024/control.viz.world/module/ajax.php#L4-L79) - `/ajax/ns/` endpoint
|
|
964
|
+
|
|
965
|
+
#### Transaction Builder
|
|
966
|
+
- **PHP**: [class/VIZ/Transaction.php](file:///d:/Work/viz.world/backup-16-11-2024/control.viz.world/class/VIZ/Transaction.php#L665-L675) - `build_account_metadata()` method
|
|
967
|
+
|
|
968
|
+
---
|
|
969
|
+
|
|
970
|
+
## Summary
|
|
971
|
+
|
|
972
|
+
| Component | Description |
|
|
973
|
+
|-----------|-------------|
|
|
974
|
+
| **Data Storage** | Account `json_metadata` field |
|
|
975
|
+
| **Record Types** | A (IPv4), TXT (SSL hash) |
|
|
976
|
+
| **Operation** | `account_metadata` |
|
|
977
|
+
| **Authority** | Regular key |
|
|
978
|
+
| **Hash Algorithm** | SHA256 of PEM-encoded public key |
|
|
979
|
+
| **Default TTL** | 28800 seconds (8 hours) |
|
|
980
|
+
| **JavaScript Library** | `viz-js-lib` - `viz.dns.*` module |
|
|
981
|
+
|
|
982
|
+
This system provides a decentralized, blockchain-based alternative to traditional DNS with built-in SSL certificate verification capabilities.
|