Skip to content

Commit e3b0791

Browse files
committed
Merge remote-tracking branch 'upstream/develop'
2 parents fd36dc6 + d1ac258 commit e3b0791

File tree

14 files changed

+377
-122
lines changed

14 files changed

+377
-122
lines changed

Protocol-cn.md

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# XDAG加密货币协议
2+
#### Version 0.3.1 Apirl 6, 2018
3+
4+
## 1.名词解释
5+
6+
**区快地址** - 区块hash截取后的base64编码.
7+
8+
**金额** - XDAG的数量,以Cheato为单位,类似比特币的Santoshi.
9+
10+
**区块** - Dagger的基本结构, 每个区块定长512字节, 结构定义在第二部分介绍.
11+
12+
**** - 一个块的序列,其中每个块被前一个块引用.
13+
14+
**Cheato** - 一个XDAG包括2^32个Cheato.
15+
16+
**Dagger元年** - Unix格式:0x5A500000 ,也就是2018年1月5日.
17+
18+
**区块难度** - (2^128-1)/(hash_little / 2^160), hash_little = 小端字节序(hash(block)), hash_little大小为256 bits(32 bytes).
19+
20+
**链难度** - 链上区块的难度之和.
21+
22+
**Hash** - 采用双sha256哈希算法, hash(block) = sha256(sha256(block)).
23+
24+
**主块** - 主链上的任何区块.
25+
26+
**主链** - 难度最大的链称为主链.
27+
28+
**链接** - 如果A具有类型2或3的字段,其中包含块B的截断散列,请参第二章.
29+
30+
**引用** - 如果从区块A到区块B是一段连续的区块组成,则称区块B被区块A引用.
31+
32+
**i-引用** - 如果区块A的第i个域连接到区块C,并且区块C引用区块B,则称区块B是区块A的i-引用.
33+
34+
**分离链** - 链上的区块属于不同的时间片.
35+
36+
**最短链** - 一个从区块A到区块B的链,每个区块都是i-引用B。i越小,链越短.
37+
38+
**时间片** - 每64秒一个时间片,时间为Unix格式,低6bits等于0.
39+
40+
**区块时间** - 区块时间记录在区块头信息里,从1970年1月1号开始,单位是1/1024秒.
41+
42+
**交易** - 交易即区块.
43+
44+
**hash截断** - hash小端字节序表示,取最低24个字节.
45+
46+
47+
## 2.区块
48+
49+
一个区块有16个字段,每个字段32个字节,每个字段type可能为0到15,一般区块,第0个字段type必须是1;伪块,第0个字段必须是类型0。有关传输用的伪块,详看第5章
50+
51+
字段的类型0-15:
52+
53+
0 随机数, 32字节.
54+
55+
1 区块头. 结构如下:
56+
- 64-bit 传输层头, 在计算区块散列的时候,这个头信息要全部设置为0;
57+
- 64-bit 小端字节序, 包括字段类型0..15. 每个类型4 bits. 字段0的类型编码为低4位.
58+
- 64-bit 小端字节序, 区块的时间.
59+
- 64-bit 小端字节序, 交易的手续费.
60+
61+
2 交易的输入. 连接到另外一个区块B.
62+
结构如下:
63+
- 192-bit 区块B的hash截断.
64+
- 64-bit 小端字节序, 区块被应用后的金额.
65+
66+
67+
3 交易的输出. 连接到其他区块.
68+
结构如下:
69+
- 192-bit 区块B的hash截断.
70+
- 64-bit 小端字节序, 区块被应用后的金额.
71+
72+
4 输入签名的一半. 输入签名由两个type为4的字段组成.
73+
第一个字段是r,第二个字段是s,这两个值都是从ECDSA的签名算法获得.
74+
通过以下摘要得出的ECDSA签名, 并通过相应的私钥进行签名.
75+
摘要是:
76+
hash(modified_block # key_prefix_byte # public_key)
77+
78+
其中:
79+
- # 是连接符号
80+
- modified_block 是去除块中的输入签名与输出签名字段,由零填充.
81+
- key_prefix_byte 如果公钥是偶数,0x02, 如果公钥是奇数,0x03.
82+
- public_key - 公钥, 32 bytes.
83+
84+
5 输出签名的一半. 结构与输入签名一样. 参考第3章 . 输入与输出签名的区别.
85+
86+
6 偶数公钥. 该字段包含ECDSA的编号x公共密钥,如果数字y是偶数.
87+
88+
7 奇数公钥. 该字段包含ECDSA的编号x公共密钥,如果数字y是奇数.
89+
90+
8 - 15 留给未来的使用.
91+
92+
93+
## 3.算法
94+
95+
每一个区块都是一个交易. 一个交易个可能有多个输入、输出、公钥、 输入和输出的签名, 还有手续费. 如果满足以下条件,则区块是有效的:
96+
97+
- 区块的产生时间不小于Dagger元年(2018-01-06 22:45:20);
98+
- 区块的输入、输出时间小于区块A的产生时间;
99+
- 区块的每个输入或者输出必须是合法的区块;
100+
- 区块的所有输入金额之和必须小于2的64次方;
101+
- 区块的所有输出金额加上手续费必须小于2的64次方;
102+
- 如果至少有一个输入大于所有输入的和,则必须不少于所有输出之和加上手续费;否则,所有输出的和必须为零;
103+
- 对于区块A的每个输入B,在块A中有公钥K和输入或输出签名S,在块B中有输出签名T,使得使用密钥K,从块A获得签名S,使用相同密钥K,从块B获得签名T(非正式描述:只有块B的所有者才能从它提取资金)
104+
- 输出签名字段的数目必须是偶数,而输入签名字段的数目可能是奇数;在这种情况下,最后一个输入签名字段可以被用作随机数,可以在不重新签名的情况下修改该字段.
105+
106+
任何时刻,只有一个主链 (看 [1.名词解释](#1.名词解释)). 主链上的区块称为主块. 每个主块属于不同的时间片. 也就是说,在一个时间片内,有1个或0个主块. 每个主块被挖出来时,会奖被奖励. 在第一个四年,奖励1024个XDAG。第二个四年,奖励512个XDAG, 之后每四年,奖励减半,XDAG的产出总量大约40亿
107+
108+
区块按照下面的规则排序:
109+
110+
1. 如果区块A被某个主块M引用,但是区块B没被主块M引用,则区块A优先区块B.
111+
2. 如果区块A和区块B相等,并且区块M是最小的被引用区块,并且区块C是M到A或者M到B的最小链上的公共块,如果A是C的i-引用,B是C的j-引用,并且i小于j的话,区块A优先区块B.
112+
3. 如果区块A和区块B在条件1/2下都相等,并且区块A被区块B引用,区块A优先区块B,交易使用上述规则进行。如果上述规则无法适用,该交易无效.
113+
114+
交易使用上述规则进行, 如果上述规则无法适用,该交易无效.
115+
每个区块拥有自己的XDAG金额.一开始的情况下是0, 但是在如下情况下,金额会变化:
116+
117+
1. 如果区块A是被挖出的区块, 区块A的金额会加上主块奖励.
118+
2. 如果区块A作为区块B的输入,区块A的金额会减去区块B的相应的输出金额.
119+
3. 如果区块A作为区块B的输出, 在这种情况下区块A的金额会增加区块B的相应的输入金额
120+
4. 如果区块A是区块B连接中的最小的区块(按照上述规则),则区块A的金额会增加区块B的手续费.
121+
5. 如果区块A的输入总和大于输出总额以及费用,则区块A的金额是两者的差额.
122+
123+
一个交易能合法验证,必须满足以下条件:
124+
125+
1. 对于区块A中的所有输入,要小于对于区块金额.
126+
2. 区块A中所有输入加区块A本身的金额的大小必须大于所有输出以及手续费之和.
127+
128+
因为每个区块有金额,所以本身也就是一个账户.用户如果拥有区块A中的输出的签名的私钥,则该用户拥有该区块A的账户.用户可以通过地址访问他的账户.区块地址是针对区块截断散列的base64编码。地址是32字节的字符串,包括字符:A-Z, a-z, 0-9, /, +.用户可以在系统中从他自己的账户中提取金额并且转账给一个有效的区块.
129+
130+
## 4.加密与安全
131+
132+
签名算法,使用openssl实现中的标准ECDSA签名.椭圆曲线是Secp256k1.私钥长度为32个字节,公钥的长度为32字节(椭圆曲线上的点的x坐标)加上(椭圆曲线上的点的y坐标).签名是64个字节,由两个字段组成.这两个字段别是ECDSA签名算法中的r和s.
133+
私钥存在wallet.dat文件中,这个文件和xdag可执行程序在同一目录.每个私钥长度32个字节, 公钥不保存,因为公钥可以从私钥计算得出.当用户第一次启动xdag程序时,要求用户提供一串随机字符.这些字符会作为随机生成器的种子.这些字符存在dnet_key.dat文件中.每次xdaga启动时,这些字符会参与随机数生成, 所有的私钥用这些字符生成。
134+
135+
## 5.传输层
136+
137+
Dagger节点利用传输协议进行区块的交换.区块的前8个字节会用做传输协议特定的信息. 需要提到的是,这个字段在计算区块散列的时候要清零.xdag程序默认使用dnet作为网络传输层.传输过程中的区块信息是加密的.使用作者的半对称算法和临时密钥对每个传输的块进行编码,并使用相同的密钥对另一侧进行解码.临时密钥由发送方生成,然后使用存储在文件dnet_key.dat中的发送方的私钥进行编码,然后使用发送方的公钥将其解码. 加密算法为长度为8192bits的RSA算法.
138+
139+
节点间不仅能传输区块,还能传输伪区块.伪区块是一些需要对方答复的请求.对于伪区块,字段0的类型必须是0,字段1的类型必须是消息类型.
140+
141+
伪区块的消息类型如下:
142+
143+
0 请求某个时间段内的所有区块信息.起始时间在区块头的时间字段中,结束时间在区块头的金额字段中.
144+
1 对消息类型0的回复.这个回复必须在所有请求的区块之后.
145+
2 请求某个时间段内的所有区块的汇总信息.起始时间在区块头的时间字段中,结束时间在区块头的金额字段中.
146+
3 对消息类型2的回复.回复是一个区块,其中的后256个字节是由16个汇总结构组成.每个汇总将总的时间段划分成16等份.
147+
每个汇总信息包括两个内容:
148+
- 第一个64-bit(小端字节序),是该子区间中所有块的所有64-bit之和
149+
- 第二个64-bit(小端字节序),是从这个子区间开始的所有块的长度之和.
150+
151+
每个请求在字段1里有自己的ID.每个回复必须在字段1里拥有相同的ID.每个伪区块消息在字段2,字段3以及字段4的开头存放统计结构
152+
153+
统计结构如下:
154+
155+
- 发送方的主链难度, 16个字节;
156+
- 网络主链上已知的主链最大难度, 16字节;
157+
- 发送方的有效区块个数, 8个字节;
158+
- 网络中的最大的有效区块个数, 8个字节;
159+
- 发送方的主块个数, 8个字节;
160+
- 网络中的最大的主块个数, 8个字节;
161+
- 发送方已知的节点个数, 4个字节;
162+
- 网络中已知的节点个数, 4个字节;
163+
164+
伪区块中的其他字段填写发送方的节点地址信息.节点地址信息是6个字节,IP(4 字节, 大端字节序)和 端口(小端字节序)
165+
166+
## 翻译
167+
本白皮书由reymondtu翻译并校对.([email protected],XDAG:+09AAQmaOlLswDbHjHlJ+MFScwG+wfMB)

README.md

+14
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,20 @@ Then run below command
120120

121121
xdag> xfer [amount] [address]
122122

123+
Build (Mac Os):
124+
-----------------------
125+
- Install dependencies:
126+
127+
$ brew install openssl
128+
$ ln -s /usr/local/opt/openssl/include/openssl /usr/local/include
129+
$ ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
130+
131+
- Make
132+
133+
$ cd xdag/client
134+
$ make
135+
136+
123137
Main chain idea:
124138
---------------
125139

client/Makefile

+20-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ dfslib = $(dfstools)/dfslib
77
dar = ../dus/programs/dar/source
88
ldusinc = ../ldus/source/include/ldus
99
utils = ./utils
10+
OS := $(shell uname)
11+
12+
ifeq ($(OS), Darwin)
13+
asm_src = \
14+
sha256-mb-x86_64-mac.s \
15+
x86_64cpuid-mac.s
16+
else
17+
asm_src = \
18+
sha256-mb-x86_64.s \
19+
x86_64cpuid.s
20+
endif
1021

1122
sources = \
1223
address.c \
@@ -21,14 +32,12 @@ sources = \
2132
miner.c \
2233
mining_common.c \
2334
sha256.c \
24-
sha256-mb-x86_64.s \
2535
storage.c \
2636
sync.c \
2737
transport.c \
2838
wallet.c \
2939
commands.c \
3040
terminal.c \
31-
x86_64cpuid.s \
3241
$(dnet)/dnet_crypt.c \
3342
$(dnet)/dnet_database.c \
3443
$(dnet)/dnet_main.c \
@@ -103,13 +112,20 @@ headers = \
103112
./json-rpc/rpc_wrapper.h \
104113

105114

106-
flags = -std=gnu11 -O3 -DDFSTOOLS -DCHEATCOIN -DNDEBUG -g -lpthread -lcrypto -lssl -lm -Wall -Wmissing-prototypes -Wno-unused-result -Wl,--export-dynamic
115+
116+
ifeq ($(OS), Darwin)
117+
118+
flags = -std=gnu11 -O3 -DDFSTOOLS -DCHEATCOIN -DNDEBUG -g -lpthread -lcrypto -lssl -lm -Wall -Wmissing-prototypes -Wno-unused-result
119+
else
120+
flags = -std=gnu11 -O3 -DDFSTOOLS -DCHEATCOIN -DNDEBUG -g -lpthread -lcrypto -lssl -lm -Wall -Wmissing-prototypes -Wno-unused-result -Wl,--export-dynamic
121+
122+
endif
107123

108124

109125
all: xdag
110126

111127
xdag: $(sources) $(headers) Makefile
112-
gcc -o xdag $(sources) -DSHA256_USE_OPENSSL_TXFM -DSHA256_OPENSSL_MBLOCK -I$(SRCROOT) -I$(utils) $(flags)
128+
gcc -o xdag $(sources) $(asm_src) -DSHA256_USE_OPENSSL_TXFM -DSHA256_OPENSSL_MBLOCK -I$(SRCROOT) -I$(utils) $(flags)
113129

114130
clean:
115131
rm xdag

client/address.c

+7-13
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ int xdag_address_init(void)
2525
int xdag_address2hash(const char *address, xdag_hash_t hash)
2626
{
2727
uint8_t *fld = (uint8_t*)hash;
28-
int i, c, d, e, n;
28+
int i, c, d, n;
2929

30-
for (e = n = i = 0; i < 32; ++i) {
30+
for (int e = n = i = 0; i < 32; ++i) {
3131
do {
3232
if (!(c = (uint8_t)*address++))
3333
return -1;
@@ -51,25 +51,19 @@ int xdag_address2hash(const char *address, xdag_hash_t hash)
5151
}
5252

5353
// converts hash to address
54-
const char *xdag_hash2address(const xdag_hash_t hash)
54+
void xdag_hash2address(const xdag_hash_t hash, char *address)
5555
{
56-
static char bufs[4][33];
57-
static int k = 0;
58-
char *buf = &bufs[k++ & 3][0], *ptr = buf;
59-
int i, c, d;
56+
int c, d;
6057
const uint8_t *fld = (const uint8_t*)hash;
6158

62-
for (i = c = d = 0; i < 32; ++i) {
59+
for (int i = c = d = 0; i < 32; ++i) {
6360
if (d < 6) {
6461
d += 8;
6562
c <<= 8;
6663
c |= *fld++;
6764
}
6865
d -= 6;
69-
*ptr++ = bits2mime[c >> d & 0x3F];
66+
*address++ = bits2mime[c >> d & 0x3F];
7067
}
71-
72-
*ptr = 0;
73-
74-
return buf;
68+
*address = 0;
7569
}

client/address.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ extern int xdag_address_init(void);
1212
extern int xdag_address2hash(const char *address, xdag_hash_t hash);
1313

1414
/* converts hash to address */
15-
extern const char *xdag_hash2address(const xdag_hash_t hash);
15+
extern void xdag_hash2address(const xdag_hash_t hash, char *address);
1616

1717
#endif

client/block.c

+19-8
Original file line numberDiff line numberDiff line change
@@ -1359,6 +1359,7 @@ int xdag_print_block_info(xdag_hash_t hash, FILE *out)
13591359
{
13601360
struct tm tm;
13611361
char tbuf[64];
1362+
char address[33];
13621363
int i;
13631364

13641365
pthread_mutex_lock(&block_mutex);
@@ -1381,17 +1382,25 @@ int xdag_print_block_info(xdag_hash_t hash, FILE *out)
13811382
fprintf(out, " hash: %016llx%016llx%016llx%016llx\n",
13821383
(unsigned long long)h[3], (unsigned long long)h[2], (unsigned long long)h[1], (unsigned long long)h[0]);
13831384
fprintf(out, "difficulty: %llx%016llx\n", xdag_diff_args(bi->difficulty));
1384-
fprintf(out, " balance: %s %10u.%09u\n", xdag_hash2address(h), pramount(bi->amount));
1385+
xdag_hash2address(h, address);
1386+
fprintf(out, " balance: %s %10u.%09u\n", address, pramount(bi->amount));
13851387
fprintf(out, "-------------------------------------------------------------------------------------------\n");
13861388
fprintf(out, " block as transaction: details\n");
13871389
fprintf(out, " direction address amount\n");
13881390
fprintf(out, "-------------------------------------------------------------------------------------------\n");
1389-
fprintf(out, " fee: %s %10u.%09u\n", (bi->ref ? xdag_hash2address(bi->ref->hash) : "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
1391+
if(bi->ref) {
1392+
xdag_hash2address(bi->ref->hash, address);
1393+
}
1394+
else {
1395+
strcpy(address, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
1396+
}
1397+
fprintf(out, " fee: %s %10u.%09u\n", address,
13901398
pramount(bi->fee));
13911399

13921400
for (i = 0; i < bi->nlinks; ++i) {
1401+
xdag_hash2address(bi->link[i]->hash, address);
13931402
fprintf(out, " %6s: %s %10u.%09u\n", (1 << i & bi->in_mask ? " input" : "output"),
1394-
xdag_hash2address(bi->link[i]->hash), pramount(bi->linkamount[i]));
1403+
address, pramount(bi->linkamount[i]));
13951404
}
13961405

13971406
fprintf(out, "-------------------------------------------------------------------------------------------\n");
@@ -1400,7 +1409,8 @@ int xdag_print_block_info(xdag_hash_t hash, FILE *out)
14001409
fprintf(out, "-------------------------------------------------------------------------------------------\n");
14011410

14021411
if (bi->flags & BI_MAIN) {
1403-
fprintf(out, " earning: %s %10u.%09u %s.%03d\n", xdag_hash2address(h),
1412+
xdag_hash2address(h, address);
1413+
fprintf(out, " earning: %s %10u.%09u %s.%03d\n", address,
14041414
pramount(MAIN_START_AMOUNT >> ((MAIN_TIME(bi->time) - MAIN_TIME(XDAG_ERA)) >> MAIN_BIG_PERIOD_LOG)),
14051415
tbuf, (int)((bi->time & 0x3ff) * 1000) >> 10);
14061416
}
@@ -1445,13 +1455,14 @@ int xdag_print_block_info(xdag_hash_t hash, FILE *out)
14451455
struct block_internal *ri = ba[i];
14461456
if (ri->flags & BI_APPLIED) {
14471457
for (int j = 0; j < ri->nlinks; j++) {
1448-
if (ri->link[j] == bi && ri->linkamount[j]) {
1458+
if(ri->link[j] == bi && ri->linkamount[j]) {
14491459
t = ri->time >> 10;
14501460
localtime_r(&t, &tm);
14511461
strftime(tbuf, 64, "%Y-%m-%d %H:%M:%S", &tm);
1462+
xdag_hash2address(ri->hash, address);
14521463
fprintf(out, " %6s: %s %10u.%09u %s.%03d\n",
1453-
(1 << j & ri->in_mask ? "output" : " input"), xdag_hash2address(ri->hash),
1454-
pramount(ri->linkamount[j]), tbuf, (int)((ri->time & 0x3ff) * 1000) >> 10);
1464+
(1 << j & ri->in_mask ? "output" : " input"), address,
1465+
pramount(ri->linkamount[j]), tbuf, (int)((ri->time & 0x3ff) * 1000) >> 10);
14551466
}
14561467
}
14571468
}
@@ -1469,7 +1480,7 @@ int xdagGetLastMainBlocks(int count, char** addressArray)
14691480
int i = 0;
14701481
for (struct block_internal *b = top_main_chain; b && i < count; b = b->link[b->max_diff_link]) {
14711482
if (b->flags & BI_MAIN) {
1472-
strcpy(addressArray[i], xdag_hash2address(b->hash));
1483+
xdag_hash2address(b->hash, addressArray[i]);
14731484
++i;
14741485
}
14751486
}

0 commit comments

Comments
 (0)