zold 0.0.8 → 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +12 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +11 -0
  4. data/.rubocop.yml +9 -1
  5. data/.simplecov +2 -2
  6. data/.travis.yml +1 -1
  7. data/Gemfile +1 -1
  8. data/LICENSE.txt +1 -1
  9. data/Procfile +1 -1
  10. data/README.md +208 -101
  11. data/Rakefile +2 -1
  12. data/bin/zold +135 -54
  13. data/features/cli.feature +1 -1
  14. data/features/step_definitions/steps.rb +1 -1
  15. data/features/support/env.rb +1 -1
  16. data/fixtures/scripts/push-and-pull.sh +35 -0
  17. data/lib/zold.rb +2 -2
  18. data/lib/zold/amount.rb +10 -2
  19. data/lib/zold/commands/{send.rb → clean.rb} +16 -16
  20. data/lib/zold/commands/create.rb +7 -5
  21. data/lib/zold/commands/diff.rb +59 -0
  22. data/lib/zold/commands/fetch.rb +74 -0
  23. data/lib/zold/commands/{pull.rb → list.rb} +11 -17
  24. data/lib/zold/commands/merge.rb +50 -0
  25. data/lib/zold/commands/node.rb +94 -0
  26. data/lib/zold/commands/pay.rb +58 -0
  27. data/lib/zold/commands/{check.rb → propagate.rb} +19 -20
  28. data/lib/zold/commands/push.rb +12 -12
  29. data/lib/zold/commands/remote.rb +115 -0
  30. data/lib/zold/commands/{balance.rb → show.rb} +11 -7
  31. data/lib/zold/copies.rb +126 -0
  32. data/lib/zold/http.rb +70 -0
  33. data/lib/zold/id.rb +8 -3
  34. data/lib/zold/key.rb +2 -2
  35. data/lib/zold/log.rb +51 -2
  36. data/lib/zold/node/farm.rb +81 -0
  37. data/lib/zold/node/front.rb +94 -46
  38. data/lib/zold/patch.rb +58 -0
  39. data/lib/zold/remotes.rb +106 -0
  40. data/lib/zold/score.rb +101 -0
  41. data/lib/zold/signature.rb +48 -0
  42. data/lib/zold/version.rb +3 -3
  43. data/lib/zold/wallet.rb +87 -55
  44. data/lib/zold/wallets.rb +13 -6
  45. data/resources/remotes +1 -0
  46. data/test/commands/test_clean.rb +41 -0
  47. data/test/commands/test_create.rb +2 -2
  48. data/test/commands/test_diff.rb +61 -0
  49. data/test/commands/test_fetch.rb +65 -0
  50. data/test/commands/test_list.rb +42 -0
  51. data/test/commands/test_merge.rb +62 -0
  52. data/test/commands/test_node.rb +56 -0
  53. data/test/commands/{test_send.rb → test_pay.rb} +10 -11
  54. data/test/commands/test_remote.rb +60 -0
  55. data/test/commands/{test_balance.rb → test_show.rb} +6 -8
  56. data/test/node/fake_node.rb +73 -0
  57. data/test/node/test_farm.rb +34 -0
  58. data/test/node/test_front.rb +26 -57
  59. data/test/test__helper.rb +1 -1
  60. data/test/test_amount.rb +10 -2
  61. data/test/test_copies.rb +73 -0
  62. data/test/test_http.rb +42 -0
  63. data/test/test_id.rb +2 -2
  64. data/test/test_key.rb +10 -10
  65. data/test/test_patch.rb +59 -0
  66. data/test/test_remotes.rb +72 -0
  67. data/test/test_score.rb +79 -0
  68. data/test/test_signature.rb +45 -0
  69. data/test/test_wallet.rb +18 -35
  70. data/test/test_wallets.rb +14 -3
  71. data/test/test_zold.rb +52 -5
  72. data/zold.gemspec +5 -3
  73. metadata +92 -21
  74. data/CONTRIBUTING.md +0 -19
  75. data/views/index.haml +0 -6
  76. data/views/layout.haml +0 -26
  77. data/views/not_found.haml +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5306e5717fd5e9e5e42148d1e46446895b24b48d
4
- data.tar.gz: a47d42f9786ed85e65a35026ccca2f0f292bd9e3
3
+ metadata.gz: 7e97c8ea80595de8fb52f2e1171802cde078b02f
4
+ data.tar.gz: 599819edb711070c723db98fdc8de0c2a506fce1
5
5
  SHA512:
6
- metadata.gz: 2c93b3dd2db0fb07b521c0920112f743dff5574219ac6c19f9ebc5ec73126b3f671bb9ca71a53a9128c43455e558c6e4293e3c507efeb468202765783935e1e6
7
- data.tar.gz: 89a74ea62a573ba9f3eff0481083780a41fe212e5c2cea9b325a3d343168df4b264f8152600290fdcca70e76129653b19c80a7dffaf1255efcc8809e32e8fbed
6
+ metadata.gz: 22998fc542734a47363547652c21b2f2ca9226e74a0839008c039629c539e02dda14d7f5b5fc2bb6d17873b6df290cfb80ba24bba106a25866a1457a6b95d2cf
7
+ data.tar.gz: ec7c957625795210afa0e1d458c1104c6015a0dac3d0b0b7fed6df7aea5b05414af7718362939c696e535a1420c7f281b91cd7d9407b8ed94d749c94c18e9d65
@@ -0,0 +1,12 @@
1
+ Make sure the title of the issue explains the problem you are having. Also, the description of the issue must clearly explain what is broken, not what you want us to implement. Go through this checklist and make sure you answer "YES" to all points:
2
+
3
+ - You have all pre-requisites listed in README.md installed
4
+ - You are sure that you are not reporting a duplicate (search all issues)
5
+ - You say "is broken" or "doesn't work" in the title
6
+ - You tell us what you are trying to do
7
+ - You explain the results you are getting
8
+ - You suggest an alternative result you would like to see
9
+
10
+ This article will help you understand what we are looking for: http://www.yegor256.com/2014/11/24/principles-of-bug-tracking.html
11
+
12
+ Thank you for your contribution!
@@ -0,0 +1,11 @@
1
+ Many thanks for your contribution, we truly appreciate it. We will appreciate it even more, if you make sure that you can say "YES" to each point in this short checklist:
2
+
3
+ - You made a small amount of changes (less than 100 lines, less than 10 files)
4
+ - You made changes related to only one bug (create separate PRs for separate problems)
5
+ - You are ready to defend your changes (there will be a code review)
6
+ - You don't touch what you don't understand
7
+ - You ran the build locally and it passed
8
+
9
+ This article will help you understand what we are looking for: http://www.yegor256.com/2015/02/09/serious-code-reviewer.html
10
+
11
+ Thank you for your contribution!
@@ -6,7 +6,7 @@ AllCops:
6
6
  TargetRubyVersion: 2.2
7
7
 
8
8
  Metrics/CyclomaticComplexity:
9
- Max: 10
9
+ Max: 15
10
10
  Metrics/MethodLength:
11
11
  Enabled: false
12
12
  Layout/MultilineMethodCallIndentation:
@@ -17,3 +17,11 @@ Metrics/BlockLength:
17
17
  Max: 50
18
18
  Metrics/ClassLength:
19
19
  Max: 200
20
+ Style/EndOfLine:
21
+ EnforcedStyle: lf
22
+ Metrics/ParameterLists:
23
+ Max: 10
24
+ Layout/AlignParameters:
25
+ Enabled: false
26
+ Metrics/PerceivedComplexity:
27
+ Max: 12
data/.simplecov CHANGED
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # Copyright (c) 2018 Zerocracy, Inc.
3
+ # Copyright (c) 2018 Yegor Bugayenko
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the 'Software'), to deal
@@ -35,6 +35,6 @@ else
35
35
  SimpleCov.start do
36
36
  add_filter "/test/"
37
37
  add_filter "/features/"
38
- minimum_coverage 60
38
+ minimum_coverage 100
39
39
  end
40
40
  end
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.2
3
+ - 2.3.3
4
4
  cache: bundler
5
5
  branches:
6
6
  only:
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2018 Zerocracy, Inc.
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2018 Zerocracy, Inc.
3
+ Copyright (c) 2018 Yegor Bugayenko
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the 'Software'), to deal
data/Procfile CHANGED
@@ -1 +1 @@
1
- web: LC_ALL=UTF-8 ./bin/zold node $PORT
1
+ web: LC_ALL=UTF-8 ./bin/zold --no-colors --verbose --trace node --bind-port=$PORT --port=80 --host=b1.zold.io --threads=0
data/README.md CHANGED
@@ -1,11 +1,12 @@
1
1
  <img src="http://www.zold.io/logo.svg" width="64px" height="64px"/>
2
2
 
3
- [![Managed by Zerocracy](http://www.0crat.com/badge/C91QJT4CF.svg)](http://www.0crat.com/p/C91QJT4CF)
3
+ [![EO principles respected here](http://www.elegantobjects.org/badge.svg)](http://www.elegantobjects.org)
4
+ [![Managed by Zerocracy](https://www.0crat.com/badge/C91QJT4CF.svg)](https://www.0crat.com/p/C91QJT4CF)
4
5
  [![DevOps By Rultor.com](http://www.rultor.com/b/yegor256/Zold)](http://www.rultor.com/p/yegor256/Zold)
5
- [![We recommend RubyMine](http://img.teamed.io/rubymine-recommend.svg)](https://www.jetbrains.com/ruby/)
6
+ [![We recommend RubyMine](http://www.elegantobjects.org/rubymine.svg)](https://www.jetbrains.com/ruby/)
6
7
 
7
8
  [![Build Status](https://travis-ci.org/zerocracy/zold.svg)](https://travis-ci.org/zerocracy/zold)
8
- [![Build status](https://ci.appveyor.com/api/projects/status/orvfo2qgmd1d7a2i?svg=true)](https://ci.appveyor.com/project/zerocracy/zold)
9
+ [![Build status](https://ci.appveyor.com/api/projects/status/ypctxm5ohrtp2kr4?svg=true)](https://ci.appveyor.com/project/yegor256/zold)
9
10
  [![PDD status](http://www.0pdd.com/svg?name=zerocracy/zold)](http://www.0pdd.com/p?name=zerocracy/zold)
10
11
  [![Gem Version](https://badge.fury.io/rb/zold.svg)](http://badge.fury.io/rb/zold)
11
12
  [![Test Coverage](https://img.shields.io/codecov/c/github/zerocracy/zold.svg)](https://codecov.io/github/zerocracy/zold?branch=master)
@@ -16,31 +17,20 @@
16
17
  **NOTICE**: It's an experiment and a very early draft! Please, feel free to
17
18
  submit your ideas or pull requests.
18
19
 
19
- ZOLD is a crypto currency.
20
-
21
- ZOLD is going to solve these problems:
22
-
23
- * Blockchain is slow and [doesn't scale](https://en.wikipedia.org/wiki/Bitcoin_scalability_problem)
24
- * Crypto mining makes irrelevant strangers rich
25
- * High volatility makes cryptos suitable mostly for the black market
26
-
27
- ZOLD is:
28
-
29
- * Fast
30
- * Scalable
31
- * Anonymous
32
-
33
20
  ZOLD principles include:
34
21
 
35
- * The entire code base is open source
36
- * There is no mining; the only way to get ZOLD is to receive it from someone else
37
- * Only 2<sup>63</sup> numerals (no fractions) can technically be issued
38
- * The first wallet belongs to the issuer and may have a negative balance
39
- * A wallet is an plain text file
40
- * There is no central ledger, each wallet has its own personal ledger
41
- * Each transaction in the ledger is confirmed by [RSA](https://simple.wikipedia.org/wiki/RSA_%28algorithm%29) encryption
42
- * The network of communicating nodes maintains wallets of users
43
- * Anyone can add a node to the network
22
+ * The entire code base is open source;
23
+ * There is no mining, the only way to get ZOLD is to receive it from someone else;
24
+ * Only 2<sup>63</sup> numerals (no fractions) can technically be issued;
25
+ * The first wallet belongs to the issuer and may have a negative balance;
26
+ * A wallet is a plain text file;
27
+ * There is no central ledger, each wallet has its own personal ledger;
28
+ * Each transaction in the ledger is confirmed by [RSA](https://simple.wikipedia.org/wiki/RSA_%28algorithm%29) encryption;
29
+ * The network of communicating nodes maintains wallets of users;
30
+ * Anyone can add a node to the network.
31
+
32
+ 1 ZLD by convention equals to 2<sup>24</sup> (16,777,216) _zents_.
33
+ Thus, the technical capacity of the currency is 549,755,813,888 ZLD (half a trillion).
44
34
 
45
35
  ## How to Use
46
36
 
@@ -58,11 +48,14 @@ $ zold start
58
48
 
59
49
  Or do one of the following:
60
50
 
61
- * `zold init` creates a new wallet (you have to provide PGP keys)
62
- * `zold pull` pulls a wallet from the network
63
- * `zold balance` checks the balance of a wallet
64
- * `zold send` creates a new transaction
65
- * `zold push` pushes a wallet to the network
51
+ * `zold remote` manipulates the list off remote nodes;
52
+ * `zold create` creates a new wallet (you have to provide PGP keys);
53
+ * `zold fetch` downloads all copies of the wallet from the network;
54
+ * `zold merge` merges all copies of the wallet into the local one;
55
+ * `zold pull` first `fetch`, then `merge`;
56
+ * `zold show` prints out all known details of a wallet (incl. its balance);
57
+ * `zold pay` creates a new transaction;
58
+ * `zold push` pushes a wallet to the network.
66
59
 
67
60
  For more options and commands just run:
68
61
 
@@ -72,108 +65,222 @@ $ zold --help
72
65
 
73
66
  ## Glossary
74
67
 
75
- A **node** is an HTTP server with a RESTful API, a maintainer of wallets.
68
+ **Node** is an HTTP server with a RESTful API, a maintainer of wallets
69
+ and a command line Ruby gem [`zold`](https://rubygems.org/gems/zold).
70
+
71
+ **Network** is a set of all nodes available online.
72
+
73
+ **Score** is the amount of "hash sufficies" a node has at any given moment of time.
74
+
75
+ **Wallet** is a text file with a ledger of all transactions inside.
76
+
77
+ **Transaction** is a money transferring operation between two wallets.
78
+
79
+ **MSS** (minimum summary score) is a summary of all scores required to trust a wallet.
80
+
81
+ ## Score
82
+
83
+ Each node calculates its own score. First, it takes the current timestamp
84
+ in UTC [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601),
85
+ for example `2017-07-19T21:24:51Z ` (with a trailing space). Then, it appends
86
+ its own host name or IP address to it, space, TCP port number, and a space.
87
+ Then, it attempts to append any
88
+ arbitrary text (has to match `[a-zA-Z0-9]+`) to the end of it and to calculate SHA-256 of the text
89
+ in the hexadecimal format, for example:
90
+
91
+ ```
92
+ Input: "2017-07-19T21:24:51Z b1.zold.io 80 the-suffix"
93
+ SHA-256: "eba36e52e1ee674d198f486e07c8496853ffc8879e7fe25329523177646a96a0"
94
+ ```
95
+
96
+ The node attempts to try different sufficies until one of them produces
97
+ SHA-256 hash that ends with `00000000` (eight zeros). For example, this
98
+ suffix `11edb424c` works (it took 212 minutes to find it on 2.3GHz Intel Core i7):
99
+
100
+ ```
101
+ Input: "2017-07-19T21:24:51Z b1.zold.io 80 11edb424c"
102
+ SHA-256: "34f48e0eee1ed12ad74cb39418f2f6e7442a776a7b6182697957650e00000000"
103
+ ```
104
+
105
+ When the first suffix is found, the score of the node is 1. Then, to
106
+ increase the score by one, the node has to find the next suffix, which
107
+ can be added to the first 20 characters of the previous hash
108
+ in order to obtain a new hash with trailing zeros, for example:
109
+
110
+ ```
111
+ Input: "34f48e0eee1ed12ad74c "
112
+ SHA-256: "..."
113
+ ```
114
+
115
+ And so on.
116
+
117
+ The score is valid only when the starting time point is earlier than
118
+ current time, but not earlier than 24 hours ago.
119
+
120
+ ## Operations
121
+
122
+ ### Remote
123
+
124
+ Each node maintains a list of visible "remote" nodes.
125
+ The gem is shipped together with a hard-coded list of a few of them.
76
126
 
77
- A **client** is a command line Ruby gem [`zold`](https://rubygems.org/gems/zold).
127
+ * `remote update` goes through the list of all remote nodes,
128
+ checks their availability, and either removes them from the list or
129
+ adds new nodes to the list.
78
130
 
79
- A **wallet** is an XML file with a ledger of all transactions inside.
131
+ * `remote add <IP>` adds a new remote node to the list.
80
132
 
81
- A **transaction** is a money transferring operation between two wallets.
133
+ * `remote remove <IP>` removes a remote node.
82
134
 
83
- ## Data
135
+ * `remote show` prints the entire list of remote nodes.
84
136
 
85
- A wallet may look like this:
137
+ The node always tries to make sure the summary of all scores in the
138
+ list of remote nodes is right above the MSS, but not more.
139
+
140
+ ### Fetch
141
+
142
+ The node attempts to pull the wallet from the first remote.
143
+ The remote returns the wallet, if it exists. Otherwise, rejects the request
144
+ and returns the list of all remotes known to it.
145
+
146
+ The node stores the content of the wallet and the score of the remote
147
+ to the local storage.
148
+ The local storage doesn't keep all remote copies, but only their unique
149
+ versions and summary scores for each version.
150
+
151
+ Fetching stops when:
152
+
153
+ * Total score is above MSS _or_
154
+ * There is only one version and the total score is above ½ MSS.
155
+
156
+ If not, the node attempts the next remote in the list.
157
+
158
+ ### Merge
159
+
160
+ The remote copy is accepted "as is" without verifications if:
161
+
162
+ * All remote copies are identical _and_
163
+ * Their summary score is above the MSS.
164
+
165
+ Otherwise, the node goes through the entire list of transactions visible in all
166
+ remote copies and merges them one by one into the "head" copy.
167
+ The decision is made per each transaction.
168
+
169
+ If a transaction exists in the head, it remains there.
170
+
171
+ Otherwise, if it's a positive transaction that increases the balance of the head copy,
172
+ the signature is validated (in the paying wallet, which is pulled first)
173
+ and it goes into the head. The transaction gets a new ID.
174
+
175
+ If it's a negative transaction, the decision is made between all copies.
176
+ The one with the largest score goes first, if the balance of the wallet
177
+ is big enough. Then, the next one in the line and so on. The transactions
178
+ that negate the balance are rejected.
179
+
180
+ ### Pay
181
+
182
+ The node pulls both wallets. Then, say, the user makes a payment
183
+ from the wallet `0123456789abcdef` to the wallet `4567456745674567`:
184
+
185
+ ```bash
186
+ zold send 0123456789abcdef 4567456745674567 5
187
+ ```
188
+
189
+ The content of both files get changed. An outgoing transaction with a negative
190
+ amount gets added to the end of the paying wallet `0123456789abcdef`:
86
191
 
87
192
  ```text
88
- 12345678abcdef
89
- AAAAB3NzaC1yc2EAAAADAQABAAABAQCuLuVr4Tl2sXoN5Zb7b6SKMPrVjLxb...
193
+ 500;2017-07-19T22:18:43Z;-83886080;4567456745674567;-;b6SKMPrVjLx...
194
+ ```
90
195
 
91
- 35;2017-07-19T21:24:51.136Z;98bb82c81735c4ee;-560;SKMPrVjLxbM5oDm0IhniQQy3shF...
196
+ The incoming transaction gets appended to the end of the receiving wallet
197
+ `4567456745674567`:
198
+
199
+ ```text
200
+ 500;2017-07-19T22:18:43Z;83886080;0123456789abcdef;-
92
201
  ```
93
202
 
94
- Lines are separated by either CR or CRLF, doesn't matter.
203
+ ### Push
95
204
 
96
- The fist line is wallet ID, a 64-bit unsigned integer.
205
+ The node sends a package of a few wallets to the biggest remote available
206
+ (with the highest score).
207
+ The package must also include a fee to the wallet that belongs to the
208
+ remote.
97
209
 
98
- The second line is a public RSA key of the wallet owner.
210
+ The remote stores them as remote copies and performs _pull_.
99
211
 
100
- The third line is empty.
212
+ The remote sends "pull requests" to all available nodes.
213
+ They must pull from the node for free, if their scores are lower or equal
214
+ to the score of the node.
101
215
 
102
- Each next line is a transaction and it has four or five fields separated by a semi-colon.
216
+ ## RESTful API
103
217
 
104
- The first field is transaction ID, an unsigned 16-bit integer.
218
+ The full list of RESTful resources:
105
219
 
106
- The second field is its date, in ISO 8601 format.
220
+ * `/` (GET): status page of the node, in JSON
107
221
 
108
- The third field is the wallet ID of the beneficiary.
222
+ * `/remotes` (GET): load all known remotes in JSON
109
223
 
110
- The forth field is the amount.
224
+ * `/wallet/<ID>` (GET): fetch wallet in JSON
111
225
 
112
- The fifth field is an RSA signature of "ID;beneficiary;amount" text.
226
+ * `/wallet/<ID>` (PUT): push wallet
113
227
 
114
- 1ZLD by convention equals to 2<sup>24</sup> (16,777,216).
115
- Thus, the technical capacity of the currency is
116
- 549,755,813,888 (half a trillion).
228
+ Each HTTP response contains `Content-type` header.
117
229
 
118
- ## Architecture
230
+ ## Files
119
231
 
120
- **Pull**.
121
- The client connects to a random closest node and pulls a wallet. If the node
122
- doesn't have the wallet, it tries to find it in the network.
123
- Then, it calculates and prints the balance to the user.
232
+ Each wallet is a text file with the name equal to the wallet ID, for example:
124
233
 
125
- **Commit**.
126
- The user provides the amount and the destination wallet name.
127
- The client pulls the destination wallet and adds
128
- a new XML element `<txn/>` to both wallets.
234
+ ```text
235
+ 12345678abcdef
236
+ AAAAB3NzaC1yc2EAAAADAQABAAABAQCuLuVr4Tl2sXoN5Zb7b6SKMPrVjLxb...
237
+
238
+ 34;2017-07-19T21:24:51Z;-560700;98bb82c81735c4ee;for services;SKMPrVjLxbM5oDm0IhniQQy3shF...
239
+ 35;2017-07-19T21:25:07Z;-56990;98bb82c81735c4ee;;QCuLuVr4Tl2sXoN5Zb7b6SKMPrVjLxb...
240
+ 134;2017-07-19T21:29:11Z;647388;18bb82dd1735b6e9;;
241
+ 36;2017-07-19T22:18:43Z;-884733;38ab8fc8e735c4fc;for fun;2sXoN5Zb7b6SKMPrVjLxb7b6SKMPrVjLx...
242
+ ```
129
243
 
130
- **Push**.
131
- The client sends two wallets to a random closest node, which checks
132
- the validity of the deduction and propagates
133
- both wallets to _all_ other nodes in a [2PC](https://en.wikipedia.org/wiki/Two-phase_commit_protocol)
134
- manner: acknowledgment first, commit next.
135
- If a node receives a wallet that contains transactions that are younger
136
- than transactions in its local copy, a merge operation is
137
- performed. If the balance after the merge is negative, the push is rejected.
244
+ Lines are separated by either CR or CRLF, doesn't matter. There is a
245
+ header and a ledger, separated by an empty line.
246
+ The header includes two lines:
138
247
 
139
- **Init**.
140
- The client creates an empty wallet XML and assigns a random `id` for it.
248
+ * Wallet ID, a 64-bit unsigned integer;
249
+ * Public RSA key of the wallet owner.
141
250
 
142
- **Start**.
143
- The node manifests itself to one of the backbone nodes, which
144
- propagates the manifestation to other nodes, they propagate further.
145
- When any node goes down, the node that detected such a situation,
146
- notifies other nodes and they exlude the failed node from the list.
251
+ The ledger includes transactions, one per line. Each transaction line
252
+ contains fields separated by a semi-colon:
147
253
 
148
- ## Corner Cases
254
+ * Transaction ID, an unsigned 16-bit integer;
255
+ * Date and time, in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601);
256
+ * Amount (integer);
257
+ * Wallet ID of the beneficiary;
258
+ * Details: `/[a-zA-Z0-9 -.]{1,128}/`;
259
+ * RSA signature of the sender of "ID;amount;beneficiary;details" text.
149
260
 
150
- **Too long wallet**.
151
- If a wallet has too many transactions, its validation will take too long, since
152
- will require many cross-wallet checks. How to solve this?
261
+ Transactions with positive amount don't
262
+ have RSA signatures. Their IDs point to ID fields of corresponding
263
+ beneficiaries' wallets.
153
264
 
154
- **DDoS**.
155
- We may have too many simultaneous `push` operations to the network,
156
- which may/will cause troubles. What to do?
265
+ The combination "ID+Beneficiary" is unique in the entire wallet.
157
266
 
158
- ## License (MIT)
267
+ The directory `.zold` is automatically created and contains system data.
159
268
 
160
- Copyright (c) 2018 Zerocracy, Inc.
269
+ `.zold/remotes` is a comma-separated file with a list of remote nodes with
270
+ these columns:
161
271
 
162
- Permission is hereby granted, free of charge, to any person obtaining a copy
163
- of this software and associated documentation files (the 'Software'), to deal
164
- in the Software without restriction, including without limitation the rights
165
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
166
- copies of the Software, and to permit persons to whom the Software is
167
- furnished to do so, subject to the following conditions:
272
+ * Address or IP;
273
+ * TPC port (usually 80);
274
+ * Score (positive integer);
275
+ * Time of score update, ISO 8601.
168
276
 
169
- The above copyright notice and this permission notice shall be included in all
170
- copies or substantial portions of the Software.
277
+ `.zold/copies` is a directory of directories, named after wallet IDs,
278
+ each of which contains copies of wallets, named like `1`, `2`, `3`, etc. Also,
279
+ each sub-directory contains a comma-separated file `scores` with these columns:
171
280
 
172
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
173
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
174
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
175
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
176
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
177
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
178
- SOFTWARE.
281
+ * The name of the copy, e.g. `1`;
282
+ * The address of the remote (host name or IP);
283
+ * The TCP port number of the remote;
284
+ * The score (positive integer);
285
+ * The time of fetching, in ISO 8601.
179
286