scale.rb 0.1.0
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.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +10 -0
- data/Dockerfile +18 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +49 -0
- data/LICENSE.txt +21 -0
- data/README.md +149 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/grants_badge.png +0 -0
- data/lib/metadata/metadata.rb +127 -0
- data/lib/metadata/metadata_v10.rb +22 -0
- data/lib/metadata/metadata_v3.rb +22 -0
- data/lib/metadata/metadata_v7.rb +123 -0
- data/lib/metadata/metadata_v8.rb +69 -0
- data/lib/metadata/metadata_v9.rb +22 -0
- data/lib/scale/base.rb +322 -0
- data/lib/scale/types.rb +561 -0
- data/lib/scale/version.rb +3 -0
- data/lib/scale.rb +187 -0
- data/scale.gemspec +43 -0
- metadata +137 -0
data/lib/scale/types.rb
ADDED
@@ -0,0 +1,561 @@
|
|
1
|
+
module Scale
|
2
|
+
module Types
|
3
|
+
|
4
|
+
class Bool
|
5
|
+
include SingleValue
|
6
|
+
BYTES_LENGTH = 1
|
7
|
+
|
8
|
+
def self.decode(scale_bytes)
|
9
|
+
bytes = scale_bytes.get_next_bytes(self::BYTES_LENGTH)
|
10
|
+
if bytes == [0]
|
11
|
+
Bool.new(false)
|
12
|
+
elsif bytes == [1]
|
13
|
+
Bool.new(true)
|
14
|
+
else
|
15
|
+
raise "Bad data"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def encode
|
20
|
+
self.value === true ? "01" : "00"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class U8
|
25
|
+
include FixedWidthUInt
|
26
|
+
BYTES_LENGTH = 1
|
27
|
+
end
|
28
|
+
|
29
|
+
class U16
|
30
|
+
include FixedWidthUInt
|
31
|
+
BYTES_LENGTH = 2
|
32
|
+
end
|
33
|
+
|
34
|
+
class U32
|
35
|
+
include FixedWidthUInt
|
36
|
+
BYTES_LENGTH = 4
|
37
|
+
end
|
38
|
+
|
39
|
+
class U64
|
40
|
+
include FixedWidthUInt
|
41
|
+
BYTES_LENGTH = 8
|
42
|
+
end
|
43
|
+
|
44
|
+
class U128
|
45
|
+
include FixedWidthUInt
|
46
|
+
BYTES_LENGTH = 16
|
47
|
+
end
|
48
|
+
|
49
|
+
class Compact
|
50
|
+
include SingleValue
|
51
|
+
|
52
|
+
def self.decode(scale_bytes)
|
53
|
+
first_byte = scale_bytes.get_next_bytes(1)[0]
|
54
|
+
first_byte_in_bin = first_byte.to_s(2).rjust(8, '0')
|
55
|
+
|
56
|
+
mode = first_byte_in_bin[6..7]
|
57
|
+
value =
|
58
|
+
if mode == '00'
|
59
|
+
first_byte >> 2
|
60
|
+
elsif mode == '01'
|
61
|
+
second_byte = scale_bytes.get_next_bytes(1)[0]
|
62
|
+
[first_byte, second_byte]
|
63
|
+
.reverse
|
64
|
+
.map { |b| b.to_s(16).rjust(2, '0') }
|
65
|
+
.join
|
66
|
+
.to_i(16) >> 2
|
67
|
+
elsif mode == '10'
|
68
|
+
remaining_bytes = scale_bytes.get_next_bytes(3)
|
69
|
+
([first_byte] + remaining_bytes)
|
70
|
+
.reverse
|
71
|
+
.map { |b| b.to_s(16).rjust(2, '0') }
|
72
|
+
.join
|
73
|
+
.to_i(16) >> 2
|
74
|
+
# or like this:
|
75
|
+
# ['02093d00'].pack('H*').unpack('l').first / 4
|
76
|
+
elsif mode == '11'
|
77
|
+
remaining_length = 4 + (first_byte >> 2)
|
78
|
+
remaining_bytes = scale_bytes.get_next_bytes(remaining_length)
|
79
|
+
remaining_bytes
|
80
|
+
.reverse
|
81
|
+
.map { |b| b.to_s(16).rjust(2, '0') }
|
82
|
+
.join
|
83
|
+
.to_i(16)
|
84
|
+
end
|
85
|
+
|
86
|
+
Compact.new(value)
|
87
|
+
end
|
88
|
+
|
89
|
+
def encode
|
90
|
+
if self.value >= 0 and self.value <= 63
|
91
|
+
(value << 2).to_s(16).rjust(2, '0')
|
92
|
+
elsif self.value > 63 and self.value <= (2**14 - 1)
|
93
|
+
((value << 2) + 1).to_s(16).rjust(4, '0').scan(/.{2}/).reverse.join
|
94
|
+
elsif self.value > (2**14 - 1) and self.value <= (2**30 - 1)
|
95
|
+
((value << 2) + 2).to_s(16).rjust(8, '0').scan(/.{2}/).reverse.join
|
96
|
+
elsif self.value > (2**30 - 1)
|
97
|
+
value_in_hex = self.value.to_s(16)
|
98
|
+
length = if value_in_hex.length % 2 == 1
|
99
|
+
value_in_hex.length + 1
|
100
|
+
else
|
101
|
+
value_in_hex.length
|
102
|
+
end
|
103
|
+
|
104
|
+
hex = value_in_hex.rjust(length, '0').scan(/.{2}/).reverse.join
|
105
|
+
(((length/2 - 4) << 2) + 3).to_s(16).rjust(2, '0') + hex
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Bytes
|
111
|
+
include SingleValue
|
112
|
+
|
113
|
+
def self.decode(scale_bytes)
|
114
|
+
length = Scale::Types::Compact.decode(scale_bytes).value
|
115
|
+
bytes = scale_bytes.get_next_bytes(length)
|
116
|
+
|
117
|
+
# [67, 97, 102, 195, 169].pack('C*').force_encoding('utf-8')
|
118
|
+
# => "Café"
|
119
|
+
str = bytes.pack("C*").force_encoding("utf-8")
|
120
|
+
if str.valid_encoding?
|
121
|
+
Bytes.new str
|
122
|
+
else
|
123
|
+
Bytes.new bytes.bytes_to_hex
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def encode
|
128
|
+
if self.value.start_with?("0x")
|
129
|
+
length = Compact.new((self.value.length - 2)/2).encode
|
130
|
+
"#{length}#{self.value[2..]}"
|
131
|
+
else
|
132
|
+
bytes = self.value.unpack("C*")
|
133
|
+
hex_string = bytes.bytes_to_hex[2..]
|
134
|
+
length = Compact.new(bytes.length).encode
|
135
|
+
"#{length}#{hex_string}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class Hex
|
141
|
+
include SingleValue
|
142
|
+
|
143
|
+
def self.decode(scale_bytes)
|
144
|
+
length = Scale::Types::Compact.decode(scale_bytes).value
|
145
|
+
hex_string = scale_bytes.get_next_bytes(length).bytes_to_hex
|
146
|
+
Hex.new(hex_string)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class String
|
151
|
+
include SingleValue
|
152
|
+
def self.decode(scale_bytes)
|
153
|
+
length = Scale::Types::Compact.decode(scale_bytes).value
|
154
|
+
bytes = scale_bytes.get_next_bytes(length)
|
155
|
+
String.new bytes.pack("C*").force_encoding("utf-8")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
class H160
|
160
|
+
include SingleValue
|
161
|
+
def self.decode(scale_bytes)
|
162
|
+
bytes = scale_bytes.get_next_bytes(20)
|
163
|
+
H160.new(bytes.bytes_to_hex)
|
164
|
+
end
|
165
|
+
|
166
|
+
def encode
|
167
|
+
raise "Format error" if not self.value.start_with?("0x") || self.value.length != 42
|
168
|
+
ScaleBytes.new self.value
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
class H256
|
173
|
+
include SingleValue
|
174
|
+
def self.decode(scale_bytes)
|
175
|
+
bytes = scale_bytes.get_next_bytes(32)
|
176
|
+
H256.new(bytes.bytes_to_hex)
|
177
|
+
end
|
178
|
+
|
179
|
+
def encode
|
180
|
+
raise "Format error" if not self.value.start_with?("0x") || self.value.length != 66
|
181
|
+
ScaleBytes.new self.value
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class H512
|
186
|
+
include SingleValue
|
187
|
+
def self.decode(scale_bytes)
|
188
|
+
bytes = scale_bytes.get_next_bytes(64)
|
189
|
+
H512.new(bytes.bytes_to_hex)
|
190
|
+
end
|
191
|
+
|
192
|
+
def encode
|
193
|
+
raise "Format error" if not self.value.start_with?("0x") || self.value.length != 130
|
194
|
+
ScaleBytes.new self.value
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
class Address
|
199
|
+
include SingleValue
|
200
|
+
def self.decode(scale_bytes)
|
201
|
+
prefix = scale_bytes.get_next_bytes(1).first
|
202
|
+
if prefix == 0xff
|
203
|
+
value = scale_bytes.get_next_bytes(32).bytes_to_hex
|
204
|
+
elsif prefix == 0xfc
|
205
|
+
value = scale_bytes.get_next_bytes(2).bytes_to_hex
|
206
|
+
elsif prefix == 0xfd
|
207
|
+
value = scale_bytes.get_next_bytes(4).bytes_to_hex
|
208
|
+
elsif prefix == 0xfe
|
209
|
+
value = scale_bytes.get_next_bytes(8).bytes_to_hex
|
210
|
+
else
|
211
|
+
value = [prefix].bytes_to_hex
|
212
|
+
end
|
213
|
+
|
214
|
+
Address.new(value)
|
215
|
+
end
|
216
|
+
|
217
|
+
def encode(ss58=false, addr_type=42)
|
218
|
+
if self.value.start_with?("0x")
|
219
|
+
if ss58 === true
|
220
|
+
::Address.encode(self.value, addr_type)
|
221
|
+
else
|
222
|
+
prefix = if self.value.length == 66
|
223
|
+
"ff"
|
224
|
+
elsif self.value.length == 6
|
225
|
+
"fc"
|
226
|
+
elsif self.value.length == 10
|
227
|
+
"fd"
|
228
|
+
elsif self.value.length == 18
|
229
|
+
"fe"
|
230
|
+
else
|
231
|
+
""
|
232
|
+
end
|
233
|
+
"#{prefix}#{self.value[2..]}"
|
234
|
+
end
|
235
|
+
else
|
236
|
+
raise "Format error"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
class AccountId < H256; end
|
242
|
+
|
243
|
+
class Balance < U128; end
|
244
|
+
|
245
|
+
class BalanceOf < Balance; end
|
246
|
+
|
247
|
+
class BlockNumber < U32; end
|
248
|
+
|
249
|
+
class AccountIndex < U32; end
|
250
|
+
|
251
|
+
class Era
|
252
|
+
include SingleValue
|
253
|
+
def self.decode(scale_bytes)
|
254
|
+
byte = scale_bytes.get_next_bytes(1).bytes_to_hex
|
255
|
+
if byte == "0x00"
|
256
|
+
Era.new byte
|
257
|
+
else
|
258
|
+
Era.new byte + scale_bytes.get_next_bytes(1).bytes_to_hex()[2..]
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
class EraIndex < U32; end
|
264
|
+
|
265
|
+
class Moment < U64; end
|
266
|
+
|
267
|
+
class CompactMoment
|
268
|
+
include SingleValue
|
269
|
+
def self.decode(scale_bytes)
|
270
|
+
value = Compact.decode(scale_bytes).value
|
271
|
+
if value > 10000000000
|
272
|
+
value = value / 1000
|
273
|
+
end
|
274
|
+
|
275
|
+
CompactMoment.new Time.at(seconds_since_epoch_integer).to_datetime
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
class ProposalPreimage
|
280
|
+
include Struct
|
281
|
+
items(
|
282
|
+
proposal: "Hex",
|
283
|
+
registredBy: "AccountId",
|
284
|
+
deposit: "BalanceOf",
|
285
|
+
blockNumber: "BlockNumber"
|
286
|
+
)
|
287
|
+
end
|
288
|
+
|
289
|
+
class RewardDestination
|
290
|
+
include Enum
|
291
|
+
values "Staked", "Stash", "Controller"
|
292
|
+
end
|
293
|
+
|
294
|
+
class WithdrawReasons
|
295
|
+
include Set
|
296
|
+
values(
|
297
|
+
{
|
298
|
+
"TransactionPayment" => 1,
|
299
|
+
"Transfer" => 2,
|
300
|
+
"Reserve" => 4,
|
301
|
+
"Fee" => 8,
|
302
|
+
"Tip" => 16
|
303
|
+
}, 1
|
304
|
+
)
|
305
|
+
end
|
306
|
+
|
307
|
+
class ReferendumIndex < U32; end
|
308
|
+
|
309
|
+
class PropIndex < U32; end
|
310
|
+
|
311
|
+
class Vote < U32; end
|
312
|
+
|
313
|
+
class SessionKey < H256; end
|
314
|
+
|
315
|
+
class SessionIndex < U32; end
|
316
|
+
|
317
|
+
class ParaId < U32; end
|
318
|
+
|
319
|
+
class KeyValue
|
320
|
+
include Struct
|
321
|
+
items key: "Vec<U8>", value: "Vec<U8>"
|
322
|
+
end
|
323
|
+
|
324
|
+
class NewAccountOutcome < Compact; end
|
325
|
+
|
326
|
+
class StakingLedger
|
327
|
+
include Struct
|
328
|
+
items(
|
329
|
+
stash: "AccountId",
|
330
|
+
total: "Compact",
|
331
|
+
active: "Compact",
|
332
|
+
unlocking: "Vec<UnlockChunk>"
|
333
|
+
)
|
334
|
+
end
|
335
|
+
|
336
|
+
class UnlockChunk
|
337
|
+
include Struct
|
338
|
+
items(
|
339
|
+
value: "Compact",
|
340
|
+
era: "Compact"
|
341
|
+
)
|
342
|
+
end
|
343
|
+
|
344
|
+
class Exposure
|
345
|
+
include Struct
|
346
|
+
items(
|
347
|
+
total: "Compact",
|
348
|
+
own: "Compact",
|
349
|
+
others: "Vec<IndividualExposure>"
|
350
|
+
)
|
351
|
+
end
|
352
|
+
|
353
|
+
class IndividualExposure
|
354
|
+
include Struct
|
355
|
+
items(
|
356
|
+
who: "AccountId",
|
357
|
+
value: "Compact"
|
358
|
+
)
|
359
|
+
end
|
360
|
+
|
361
|
+
class BabeAuthorityWeight < U64; end
|
362
|
+
|
363
|
+
class Points < U32; end
|
364
|
+
|
365
|
+
class EraPoints
|
366
|
+
include Struct
|
367
|
+
items(
|
368
|
+
total: "Points",
|
369
|
+
individual: "Vec<Points>"
|
370
|
+
)
|
371
|
+
end
|
372
|
+
|
373
|
+
class VoteThreshold
|
374
|
+
include Enum
|
375
|
+
values 'SuperMajorityApprove', 'SuperMajorityAgainst', 'SimpleMajority'
|
376
|
+
end
|
377
|
+
|
378
|
+
class Null
|
379
|
+
include SingleValue
|
380
|
+
def self.decode(scale_bytes)
|
381
|
+
Null.new nil
|
382
|
+
end
|
383
|
+
|
384
|
+
def encode
|
385
|
+
""
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
class InherentOfflineReport < Null; end
|
390
|
+
|
391
|
+
class LockPeriods < U8; end
|
392
|
+
|
393
|
+
class Hash < H256; end
|
394
|
+
|
395
|
+
class VoteIndex < U32; end
|
396
|
+
|
397
|
+
class ProposalIndex < U32; end
|
398
|
+
|
399
|
+
class Permill < U32; end
|
400
|
+
|
401
|
+
class Perbill < U32; end
|
402
|
+
|
403
|
+
class ApprovalFlag < U32; end
|
404
|
+
|
405
|
+
class SetIndex < U32; end
|
406
|
+
|
407
|
+
class AuthorityId < AccountId; end
|
408
|
+
|
409
|
+
class ValidatorId < AccountId; end
|
410
|
+
|
411
|
+
class AuthorityWeight < U64; end
|
412
|
+
|
413
|
+
class StoredPendingChange
|
414
|
+
include Struct
|
415
|
+
items(
|
416
|
+
scheduled_at: "U32",
|
417
|
+
forced: "U32"
|
418
|
+
)
|
419
|
+
end
|
420
|
+
|
421
|
+
class ReportIdOf < Hash; end
|
422
|
+
|
423
|
+
class StorageHasher
|
424
|
+
include Enum
|
425
|
+
values 'Blake2_128', 'Blake2_256', 'Blake2_128Concat', 'Twox128', 'Twox256', 'Twox64Concat'
|
426
|
+
end
|
427
|
+
|
428
|
+
class VoterInfo
|
429
|
+
include Struct
|
430
|
+
items(
|
431
|
+
last_active: "VoteIndex",
|
432
|
+
last_win: "VoteIndex",
|
433
|
+
pot: "Balance",
|
434
|
+
stake: "Balance"
|
435
|
+
)
|
436
|
+
end
|
437
|
+
|
438
|
+
class Gas < U64; end
|
439
|
+
|
440
|
+
class CodeHash < Hash; end
|
441
|
+
|
442
|
+
class PrefabWasmModule
|
443
|
+
include Struct
|
444
|
+
items(
|
445
|
+
scheduleVersion: "Compact",
|
446
|
+
initial: "Compact",
|
447
|
+
maximum: "Compact",
|
448
|
+
_reserved: "Option<Null>",
|
449
|
+
code: "Bytes"
|
450
|
+
)
|
451
|
+
end
|
452
|
+
|
453
|
+
class OpaqueNetworkState
|
454
|
+
include Struct
|
455
|
+
items(
|
456
|
+
peerId: "OpaquePeerId",
|
457
|
+
externalAddresses: "Vec<OpaqueMultiaddr>"
|
458
|
+
)
|
459
|
+
end
|
460
|
+
|
461
|
+
class OpaquePeerId < Bytes; end
|
462
|
+
|
463
|
+
class OpaqueMultiaddr < Bytes; end
|
464
|
+
|
465
|
+
class SessionKeysSubstrate
|
466
|
+
include Struct
|
467
|
+
items(
|
468
|
+
grandpa: "AccountId",
|
469
|
+
babe: "AccountId",
|
470
|
+
im_online: "AccountId"
|
471
|
+
)
|
472
|
+
end
|
473
|
+
|
474
|
+
class LegacyKeys
|
475
|
+
include Struct
|
476
|
+
items(
|
477
|
+
grandpa: "AccountId",
|
478
|
+
babe: "AccountId"
|
479
|
+
)
|
480
|
+
end
|
481
|
+
|
482
|
+
class EdgewareKeys
|
483
|
+
include Struct
|
484
|
+
items(
|
485
|
+
grandpa: "AccountId"
|
486
|
+
)
|
487
|
+
end
|
488
|
+
|
489
|
+
class QueuedKeys
|
490
|
+
include Struct
|
491
|
+
items(
|
492
|
+
validator: "ValidatorId",
|
493
|
+
keys: "Keys"
|
494
|
+
)
|
495
|
+
end
|
496
|
+
|
497
|
+
class LegacyQueuedKeys
|
498
|
+
include Struct
|
499
|
+
items(
|
500
|
+
validator: "ValidatorId",
|
501
|
+
keys: "LegacyKeys"
|
502
|
+
)
|
503
|
+
end
|
504
|
+
|
505
|
+
class EdgewareQueuedKeys
|
506
|
+
include Struct
|
507
|
+
items(
|
508
|
+
validator: "ValidatorId",
|
509
|
+
keys: "EdgewareKeys"
|
510
|
+
)
|
511
|
+
end
|
512
|
+
|
513
|
+
class VecQueuedKeys
|
514
|
+
include Vec
|
515
|
+
inner_type "QueuedKeys"
|
516
|
+
end
|
517
|
+
|
518
|
+
class VecU8Length2
|
519
|
+
include VecU8FixedLength
|
520
|
+
end
|
521
|
+
|
522
|
+
class VecU8Length3
|
523
|
+
include VecU8FixedLength
|
524
|
+
end
|
525
|
+
|
526
|
+
class VecU8Length4
|
527
|
+
include VecU8FixedLength
|
528
|
+
end
|
529
|
+
|
530
|
+
class VecU8Length8
|
531
|
+
include VecU8FixedLength
|
532
|
+
end
|
533
|
+
|
534
|
+
class VecU8Length16
|
535
|
+
include VecU8FixedLength
|
536
|
+
end
|
537
|
+
|
538
|
+
class VecU8Length20
|
539
|
+
include VecU8FixedLength
|
540
|
+
end
|
541
|
+
|
542
|
+
class VecU8Length32
|
543
|
+
include VecU8FixedLength
|
544
|
+
end
|
545
|
+
|
546
|
+
class VecU8Length64
|
547
|
+
include VecU8FixedLength
|
548
|
+
end
|
549
|
+
|
550
|
+
class BalanceLock
|
551
|
+
include Struct
|
552
|
+
items(
|
553
|
+
id: "VecU8Length8",
|
554
|
+
amount: "Balance",
|
555
|
+
until: "U32",
|
556
|
+
reasons: "WithdrawReasons"
|
557
|
+
)
|
558
|
+
end
|
559
|
+
|
560
|
+
end
|
561
|
+
end
|