zold 0.26.7 → 0.26.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e21eb76334ee1e9a8e7b80dbc6c43b62ad8381a1ee99e8ac780b937c14d0f418
4
- data.tar.gz: 7b0a0e5c66a8cfcb7ca34a139be4223b5c42e32d10df6e6a79bc71a116d86d71
3
+ metadata.gz: 6ac37397e5ff256409bed9549fa390687d9948ece326adb44df42e4e56663341
4
+ data.tar.gz: 7783a1cb0a6ca7c98262f233980de0ecf77d2b5fb97a8f5f187c7a62f7be559e
5
5
  SHA512:
6
- metadata.gz: a2a009ad5725c759219f5a94085eefbe82868237db58ccc52d66e6ff488fb5f10df27a48b32f832409d8371242cfe17e7b61b53519f766e97abee7dea784b667
7
- data.tar.gz: ae6f4c9677dd2367f72582c5e663316755fe7710f44c6af177952a07739c1260ddfbbf644656141f4dac91f990756cfee130a5195f2746768c4cf0ed049816ba
6
+ metadata.gz: 34f7840aca58aa3f88b851df2da34de671d47028168e5bf3b2999fefc0c0cf8136d449ea93861f1e95444cb91a8d465a1c3708522395f1014037640d266b59c3
7
+ data.tar.gz: a3a6af3bb00938418bacb448f0de1a7e8ab91574a93779608ce57640947174a474ee4f4fef9fa999eb891e72ca61df1b76bc1ca8340f4632599455821121aa3b
@@ -0,0 +1,6 @@
1
+ test
2
+ 1
3
+ 0000000000000000
4
+ MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnppnkzrCreiKaHF09XKS6bO+2274+wSGo+F8KHvVrNbqear/e09r9PB/P6bFdLoMh4Xc7p/7+NSEZLeu2Eg/dBkQLEb8M/zgkT4gBDGyETW/zusYHIznX/lgf0f8qleIQIIB/3Y7QpDztkamWYTKWlnmlrcQvCVB0uRRPm4ZMcMJouKR9n7E2DpL9eolKyOwr/JY08iJOuK3HuW6tRdvE+0x7I+wDprM65OH/PoArlfO5qnIGbeXwsEGRXt0w6a/ubPpeadFjPXotE7cT1SA4YSD1tWTIVm1ZWppOE967XoDIum6tzt5KfzDNRfs9GbCfO0BL235HxbO8I9rTlVLTKcNAiEe0CWolY9HR5pMaosOgZ6PB54InJEZJs4L2b10c+IlVUX1RSnwfFYg0vy5oqrYyqt7gnipl/06YW4PKIYc7TljogsEHf9Cz/kpEKzqDtsH2LrmjMNsbWiousvNHM+MPgcuMg8ZnwLKwDy9NWdI4XLTpg6hVRJNH9erZdfAO5tg/3ub3JLeJbyNo4Bd5f/Bnr5YN/9ahZ87kSpI7v0Qk94dR4hDPjstEcghyZ9RVUoN52+h1g83cd3cIqksJd0kifMCoBmObD013RSPQqNwr9GGU2JaJEm25Vq35dy2DHAkOQpUZVT8GNg9IM4qUDV0yagTN3bZyvuLWIgufb0CAwEAAQ==
5
+
6
+ 0001;2018-06-22T07:38:23Z;fffffe0000000000;g6hVRJNH;0123456789abcdef;To help you;IFQvo0PN3JkpkuZRjPyQ6BywuM9aSRFI6GdNOevSQxWJMwSesYp6b25KIi78TcIV9b84f0Qr96d8TgvkTjLqczvZZzyYIJ+e2w8qQhbxSiCgFxfThm6U8NnrXNprMBRHg4amV40dAjgW2lfVDDRk+RtCYEUEZDX5xPhiCHC8lhtoJm/atgJfgOIAfeLTy6ZWwC+teMtHUt6/uHH9z9giYnWHLBpYFyjYSSlrf4K/0e86Kzy/8Bwmk9Q/I6Yvo7IWL7TNN5vCGiz74R2wUTHVfmlY/YdXD15JnPmmZGjoR+BCjxbpjPqYWGm2bTxSuDHCFg0oTKAHIPqC57hKzGQUNzmoSqMHxTBDTvdLHjf0Uo9oaWhdT+BTpnGzFJxgz7d9oJOsIFqrLzPZ6VjOqKtl+ptbFkrjpq9ZdfpbzzBxHhLU8quxmBihodxBZAI6f2rpDGgnwS/D2v+Ncdcmqpdin1GkU0lAeAzWhenKBqu2t9C5UeZbjw6diiKyrGPHWLS9X9BGX9j6STMyI93f81Y6+j798gqv+XZtsohxL/sHDNJK0m81S6QWnAD//bZbNqW85y8ZMFwHmn3GXsSDupaQGpe6wpvFknWxho4vM8A/nAk20rWur5PF1S4RpFwpOr/4RmBA06yWnPxdB6x9lonPKmYC5Pck0fwxXDOEcjMTdWo=
@@ -0,0 +1,6 @@
1
+ test
2
+ 1
3
+ 0123456789abcdef
4
+ MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnppnkzrCreiKaHF09XKS6bO+2274+wSGo+F8KHvVrNbqear/e09r9PB/P6bFdLoMh4Xc7p/7+NSEZLeu2Eg/dBkQLEb8M/zgkT4gBDGyETW/zusYHIznX/lgf0f8qleIQIIB/3Y7QpDztkamWYTKWlnmlrcQvCVB0uRRPm4ZMcMJouKR9n7E2DpL9eolKyOwr/JY08iJOuK3HuW6tRdvE+0x7I+wDprM65OH/PoArlfO5qnIGbeXwsEGRXt0w6a/ubPpeadFjPXotE7cT1SA4YSD1tWTIVm1ZWppOE967XoDIum6tzt5KfzDNRfs9GbCfO0BL235HxbO8I9rTlVLTKcNAiEe0CWolY9HR5pMaosOgZ6PB54InJEZJs4L2b10c+IlVUX1RSnwfFYg0vy5oqrYyqt7gnipl/06YW4PKIYc7TljogsEHf9Cz/kpEKzqDtsH2LrmjMNsbWiousvNHM+MPgcuMg8ZnwLKwDy9NWdI4XLTpg6hVRJNH9erZdfAO5tg/3ub3JLeJbyNo4Bd5f/Bnr5YN/9ahZ87kSpI7v0Qk94dR4hDPjstEcghyZ9RVUoN52+h1g83cd3cIqksJd0kifMCoBmObD013RSPQqNwr9GGU2JaJEm25Vq35dy2DHAkOQpUZVT8GNg9IM4qUDV0yagTN3bZyvuLWIgufb0CAwEAAQ==
5
+
6
+
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2018-2019 Zerocracy, Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require_relative 'asserts.rb'
24
+ wallet = Zold::Wallet.new('0123456789abcdef.z')
25
+ assert_equal(Zold::Amount.new(zld: 496.0), wallet.balance)
@@ -0,0 +1,8 @@
1
+ test
2
+ 1
3
+ 0123456789abcdef
4
+ MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnppnkzrCreiKaHF09XKS6bO+2274+wSGo+F8KHvVrNbqear/e09r9PB/P6bFdLoMh4Xc7p/7+NSEZLeu2Eg/dBkQLEb8M/zgkT4gBDGyETW/zusYHIznX/lgf0f8qleIQIIB/3Y7QpDztkamWYTKWlnmlrcQvCVB0uRRPm4ZMcMJouKR9n7E2DpL9eolKyOwr/JY08iJOuK3HuW6tRdvE+0x7I+wDprM65OH/PoArlfO5qnIGbeXwsEGRXt0w6a/ubPpeadFjPXotE7cT1SA4YSD1tWTIVm1ZWppOE967XoDIum6tzt5KfzDNRfs9GbCfO0BL235HxbO8I9rTlVLTKcNAiEe0CWolY9HR5pMaosOgZ6PB54InJEZJs4L2b10c+IlVUX1RSnwfFYg0vy5oqrYyqt7gnipl/06YW4PKIYc7TljogsEHf9Cz/kpEKzqDtsH2LrmjMNsbWiousvNHM+MPgcuMg8ZnwLKwDy9NWdI4XLTpg6hVRJNH9erZdfAO5tg/3ub3JLeJbyNo4Bd5f/Bnr5YN/9ahZ87kSpI7v0Qk94dR4hDPjstEcghyZ9RVUoN52+h1g83cd3cIqksJd0kifMCoBmObD013RSPQqNwr9GGU2JaJEm25Vq35dy2DHAkOQpUZVT8GNg9IM4qUDV0yagTN3bZyvuLWIgufb0CAwEAAQ==
5
+
6
+ 0001;2018-06-22T07:38:23Z;0000020000000000;g6hVRJNH;0000000000000000;To help you;
7
+ 0001;2018-06-22T07:38:23Z;0000020000000000;g6hVRJNH;0000000000000001;From a missing wallet;
8
+ 0001;2018-06-22T08:26:19Z;fffffff000000000;TESTPREFIX;ffffffffffffffff;For pizza;L1MFiKqM8O6Eg/v54TD7M48gI/oq7iYYmjM7cKgUpMUk7dx48K+9DRQ2as+d2SrMMH/TKdJ/It8v8DJN6RV3kVtpdZo7CsUrUisive5rpJduO68+nJFr3TB3vQrCPm8N3Cz9vfmM68WrmskPHOABETyIC9cSQrSIvaCWhchwru7sO0625y2aYiMVoW2jmKFTtflGr6M9n7rqTkaYG/EftrNMrJS7PaG19T1HOQupAcKQ4DzBujEnbm3KQQc9Rp5GR8cb49Y38IAr9lENkDB1zmMaVJeZNEyX0ne6S1ZB7Ys9L0jUIJA+SRzNHDEdWC6lcOifcCuanU4kBPFtOiuAjghJX09l8Ue1pyE478+Sy8BgApqKu1l4+p+qUSXOTx7yKwT9ahZaA9DgVHEinz6MqhiozDddw24fXRK956pQ+jUPzNJXVeH4UrDcUDAaCIX8jCaaqGQUqhJXH2KF0Z1PtWBfHYB7OxXEpiVVtScMQ+68iB40p71f7j4YrVW50G89NrCJbOamdai+3dmwiIZzSOsSahB8kXrkaF+lrDZiwNPfL2ixs3F2xW34aKHvA/UCCo7PVfUVDLC8VHiDtAKTSyoqhPP4ocomszfRaRGxSjDIh3ceCrPH9BIW2zfUzkU63+dJ5adS+XSXzO3L3gfwiLM6XPr2jlJbPy1OSMkDK7s=
@@ -0,0 +1 @@
1
+ 1,0.0.0.0,4096,10,NOW,M
@@ -0,0 +1 @@
1
+ --verbose
@@ -109,7 +109,10 @@ Available options:"
109
109
  private
110
110
 
111
111
  def fetch(id, cps, opts)
112
- raise "There are no remote nodes, run 'zold remote reset'" if @remotes.all.empty?
112
+ if @remotes.all.empty?
113
+ return if opts['quiet-if-absent']
114
+ raise "There are no remote nodes, run 'zold remote reset'"
115
+ end
113
116
  start = Time.now
114
117
  total = Concurrent::AtomicFixnum.new
115
118
  nodes = Concurrent::AtomicFixnum.new
@@ -190,7 +193,7 @@ as copy ##{copy}/#{cps.all.count} in #{Age.new(start, limit: 4)}: \
190
193
  begin
191
194
  uri = "/wallet/#{id}"
192
195
  head = r.http(uri).get
193
- raise "The wallet #{id} doesn't exist at #{r}" if head.status == 404
196
+ raise Fetch::Error, "The wallet #{id} doesn't exist at #{r}" if head.status == 404
194
197
  r.assert_code(200, head)
195
198
  json = JsonPage.new(head.body, uri).to_hash
196
199
  score = Score.parse_json(json['score'])
@@ -198,7 +201,7 @@ as copy ##{copy}/#{cps.all.count} in #{Age.new(start, limit: 4)}: \
198
201
  rescue JsonPage::CantParse, Score::CantParse, RemoteNode::CantAssert => e
199
202
  attempt += 1
200
203
  if attempt < opts['retry']
201
- @log.error("#{r} failed to fetch #{id}, trying again (attempt no.#{attempt}): #{e.message}")
204
+ @log.debug("#{r} failed to fetch #{id}, trying again (attempt no.#{attempt}): #{e.message}")
202
205
  retry
203
206
  end
204
207
  raise e
@@ -59,6 +59,9 @@ Available options:"
59
59
  o.bool '--skip-legacy',
60
60
  'Don\'t make legacy transactions (older than 24 hours) immutable',
61
61
  default: false
62
+ o.bool '--quiet-if-absent',
63
+ 'Don\'t fail if the wallet is absent',
64
+ default: false
62
65
  o.bool '--shallow',
63
66
  'Don\'t try to pull other wallets if their confirmations are required',
64
67
  default: false
@@ -116,7 +119,10 @@ Available options:"
116
119
  @log.debug("Local copy of #{id} is absent, nothing to merge")
117
120
  end
118
121
  end
119
- raise "There are no copies of #{id}, nothing to merge" if patch.empty?
122
+ if patch.empty?
123
+ return if opts['quiet-if-absent']
124
+ raise "There are no copies of #{id}, nothing to merge"
125
+ end
120
126
  modified = @wallets.acq(id, exclusive: true) { |w| patch.save(w.path, overwrite: true) }
121
127
  if modified
122
128
  @log.info("#{cps.count} copies with the total score of #{score} successfully merged \
@@ -138,7 +144,7 @@ into #{@wallets.acq(id, &:mnemo)} in #{Age.new(start, limit: 0.1 + cps.count * 0
138
144
  else
139
145
  patch.join(wallet, ledger: opts['ledger']) do |txn|
140
146
  Pull.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @log).run(
141
- ['pull', txn.bnf.to_s, "--network=#{opts['network']}", '--shallow']
147
+ ['pull', txn.bnf.to_s, "--network=#{opts['network']}", '--shallow', '--quiet-if-absent']
142
148
  )
143
149
  true
144
150
  end
@@ -66,6 +66,9 @@ Available options:"
66
66
  o.string '--time',
67
67
  "Time of transaction (default: #{Time.now.utc.iso8601})",
68
68
  default: Time.now.utc.iso8601
69
+ o.string '--keygap',
70
+ 'Keygap, if the private RSA key is not complete',
71
+ default: ''
69
72
  o.bool '--tolerate-edges',
70
73
  'Don\'t fail if only "edge" (not "master" ones) nodes have the wallet',
71
74
  default: false
@@ -120,7 +123,7 @@ Available options:"
120
123
  return unless debt
121
124
  require_relative 'taxes'
122
125
  Taxes.new(wallets: @wallets, remotes: @remotes, log: @log).run(
123
- ['taxes', 'pay', "--private-key=#{opts['private-key']}", id.to_s]
126
+ ['taxes', 'pay', "--private-key=#{opts['private-key']}", id.to_s, "--keygap=#{opts['keygap']}"]
124
127
  )
125
128
  end
126
129
 
@@ -133,7 +136,12 @@ Available options:"
133
136
  the difference is #{(amount - from.balance).to_i} zents"
134
137
  end
135
138
  end
136
- key = Zold::Key.new(file: opts['private-key'])
139
+ pem = IO.read(opts['private-key'])
140
+ unless opts['keygap'].empty?
141
+ pem = pem.sub('*' * opts['keygap'].length, opts['keygap'])
142
+ @log.debug("Keygap \"#{'*' * opts['keygap'].length}\" injected into the RSA private key")
143
+ end
144
+ key = Zold::Key.new(text: pem)
137
145
  txn = from.sub(amount, invoice, key, details, time: Txn.parse_time(opts['time']))
138
146
  @log.debug("#{amount} sent from #{from} to #{txn.bnf}: #{details}")
139
147
  @log.debug("Don't forget to do 'zold push #{from}'")
@@ -78,6 +78,9 @@ Available options:"
78
78
  o.bool '--ignore-score-weakness',
79
79
  'Don\'t complain when their score is too weak',
80
80
  default: false
81
+ o.string '--keygap',
82
+ 'Keygap, if the private RSA key is not complete',
83
+ default: ''
81
84
  o.bool '--ignore-nodes-absence',
82
85
  'Don\'t complain if there are not enough nodes in the network to pay taxes',
83
86
  default: false
@@ -145,7 +148,12 @@ the balance is #{wallet.balance}: #{tax.to_text}")
145
148
  @log.debug("The score has already been taxed: #{best}")
146
149
  next
147
150
  end
148
- txn = tax.pay(Zold::Key.new(file: opts['private-key']), best)
151
+ pem = IO.read(opts['private-key'])
152
+ unless opts['keygap'].empty?
153
+ pem = pem.sub('*' * opts['keygap'].length, opts['keygap'])
154
+ @log.debug("Keygap \"#{'*' * opts['keygap'].length}\" injected into the RSA private key")
155
+ end
156
+ txn = tax.pay(Zold::Key.new(text: pem), best)
149
157
  debt += txn.amount
150
158
  paid += 1
151
159
  @log.info("#{txn.amount * -1} of taxes paid from #{wallet.id} to #{txn.bnf} \
data/lib/zold/patch.rb CHANGED
@@ -83,8 +83,11 @@ module Zold
83
83
  @log.error("Wallet ID mismatch, ours is #{@id}, theirs is #{wallet.id}")
84
84
  return
85
85
  end
86
+ seen = 0
87
+ added = 0
86
88
  wallet.txns.each do |txn|
87
89
  next if @txns.find { |t| t == txn }
90
+ seen += 1
88
91
  if txn.amount.negative?
89
92
  dup = @txns.find { |t| t.id == txn.id && t.amount.negative? }
90
93
  if dup
@@ -129,6 +132,7 @@ doesn't have this transaction: \"#{txn.to_text}\"")
129
132
  end
130
133
  end
131
134
  @txns << txn
135
+ added += 1
132
136
  if txn.amount.negative?
133
137
  File.open(ledger, 'a') do |f|
134
138
  f.puts(
@@ -147,6 +151,7 @@ doesn't have this transaction: \"#{txn.to_text}\"")
147
151
  end
148
152
  @log.debug("Merged on top, balance is #{@txns.map(&:amount).inject(&:+)}: #{txn.to_text}")
149
153
  end
154
+ @log.debug("#{seen} new txns arrived from #{wallet.mnemo}, #{added} of them added to the patch")
150
155
  end
151
156
 
152
157
  def empty?
data/lib/zold/remotes.rb CHANGED
@@ -215,8 +215,12 @@ at #{response.headers['X-Zold-Path']}"
215
215
  unerror(r[:host], r[:port]) if node.touched
216
216
  rescue StandardError => e
217
217
  error(r[:host], r[:port])
218
- log.info("#{Rainbow(node).red}: \"#{e.message.strip}\" in #{Age.new(start)}")
219
- log.debug(Backtrace.new(e).to_s)
218
+ if e.is_a?(RemoteNode::CantAssert) || e.is_a?(Fetch::Error)
219
+ log.debug("#{Rainbow(node).red}: \"#{e.message.strip}\" in #{Age.new(start)}")
220
+ else
221
+ log.info("#{Rainbow(node).red}: \"#{e.message.strip}\" in #{Age.new(start)}")
222
+ log.debug(Backtrace.new(e).to_s)
223
+ end
220
224
  remove(r[:host], r[:port]) if r[:errors] > TOLERANCE
221
225
  end
222
226
  end
data/lib/zold/version.rb CHANGED
@@ -25,7 +25,7 @@
25
25
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Zold
28
- VERSION = '0.26.7'
28
+ VERSION = '0.26.8'
29
29
  PROTOCOL = 2
30
30
  REPO = 'zold-io/zold'
31
31
  end
@@ -82,6 +82,25 @@ class TestPay < Zold::Test
82
82
  end
83
83
  end
84
84
 
85
+ def test_pay_with_keygap
86
+ FakeHome.new(log: test_log).run do |home|
87
+ wallet = home.create_wallet
88
+ amount = Zold::Amount.new(zld: 2.0)
89
+ Tempfile.open do |f|
90
+ pem = IO.read('fixtures/id_rsa')
91
+ keygap = pem[100..120]
92
+ IO.write(f, pem.gsub(keygap, '*' * keygap.length))
93
+ Zold::Pay.new(wallets: home.wallets, copies: home.dir, remotes: home.remotes, log: test_log).run(
94
+ [
95
+ 'pay', '--force', "--private-key=#{f.path}", "--keygap=#{keygap}",
96
+ wallet.id.to_s, 'NOPREFIX@dddd0000dddd0000', amount.to_zld, '-'
97
+ ]
98
+ )
99
+ end
100
+ assert_equal(amount * -1, wallet.balance)
101
+ end
102
+ end
103
+
85
104
  def test_pay_in_many_threads
86
105
  FakeHome.new(log: test_log).run do |home|
87
106
  wallet = home.create_wallet
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zold
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.7
4
+ version: 0.26.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-07 00:00:00.000000000 Z
11
+ date: 2019-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -580,6 +580,12 @@ files:
580
580
  - fixtures/merge/legacy_negatives_stay/copies/0123456789abcdef/1.zc
581
581
  - fixtures/merge/legacy_negatives_stay/copies/0123456789abcdef/scores.zc
582
582
  - fixtures/merge/legacy_negatives_stay/opts
583
+ - fixtures/merge/missed_wallets/0000000000000000.z
584
+ - fixtures/merge/missed_wallets/0123456789abcdef.z
585
+ - fixtures/merge/missed_wallets/assert.rb
586
+ - fixtures/merge/missed_wallets/copies/0123456789abcdef/1.zc
587
+ - fixtures/merge/missed_wallets/copies/0123456789abcdef/scores.zc
588
+ - fixtures/merge/missed_wallets/opts
583
589
  - fixtures/merge/random_expenses/0000000000000000.z
584
590
  - fixtures/merge/random_expenses/0123456789abcdef.z
585
591
  - fixtures/merge/random_expenses/assert.rb
@@ -764,7 +770,7 @@ licenses:
764
770
  - MIT
765
771
  metadata: {}
766
772
  post_install_message: |-
767
- Thanks for installing Zold 0.26.7!
773
+ Thanks for installing Zold 0.26.8!
768
774
  Study our White Paper: https://papers.zold.io/wp.pdf
769
775
  Read our blog posts: https://blog.zold.io
770
776
  Try ZLD online wallet at: https://wts.zold.io