scale.rb 0.2.16 → 0.3.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 +4 -4
- data/.gitignore +1 -0
- data/Cargo.lock +8 -4
- data/Cargo.toml +2 -3
- data/Dockerfile +4 -1
- data/Gemfile.lock +43 -35
- data/README.md +44 -1
- data/Rakefile +6 -0
- data/exe/scale +39 -79
- data/lib/address.rb +3 -0
- data/lib/common.rb +163 -0
- data/lib/helper.rb +25 -8
- data/lib/metadata/metadata.rb +28 -18
- data/lib/metadata/metadata_v0.rb +24 -20
- data/lib/metadata/metadata_v1.rb +13 -9
- data/lib/metadata/metadata_v10.rb +2 -2
- data/lib/metadata/metadata_v11.rb +2 -2
- data/lib/metadata/metadata_v12.rb +9 -8
- data/lib/metadata/metadata_v13.rb +161 -0
- data/lib/metadata/metadata_v2.rb +2 -2
- data/lib/metadata/metadata_v3.rb +2 -2
- data/lib/metadata/metadata_v4.rb +21 -11
- data/lib/metadata/metadata_v5.rb +21 -11
- data/lib/metadata/metadata_v6.rb +9 -9
- data/lib/metadata/metadata_v7.rb +26 -15
- data/lib/metadata/metadata_v8.rb +9 -9
- data/lib/metadata/metadata_v9.rb +2 -2
- data/lib/scale.rb +41 -341
- data/lib/scale/base.rb +177 -95
- data/lib/scale/block.rb +17 -13
- data/lib/scale/trie.rb +1 -1
- data/lib/scale/types.rb +139 -40
- data/lib/scale/version.rb +1 -1
- data/lib/scale_bytes.rb +63 -0
- data/lib/substrate_client.rb +31 -17
- data/lib/type_builder.rb +279 -0
- data/lib/type_registry.rb +91 -0
- data/lib/type_registry/crab.json +676 -595
- data/lib/type_registry/darwinia.json +730 -554
- data/lib/type_registry/default.json +3 -2
- data/lib/type_registry/pangolin.json +771 -0
- data/scale.gemspec +7 -5
- data/scripts/mmr_root_to_sign.rb +10 -0
- data/src/lib.rs +80 -25
- metadata +59 -30
- data/lib/type_registry/edgeware.json +0 -124
- data/lib/type_registry/joystream.json +0 -49
- data/lib/type_registry/kulupu.json +0 -15
- data/lib/type_registry/plasm.json +0 -89
- data/lib/type_registry/robonomics.json +0 -39
- data/lib/type_registry/westend.json +0 -63
- data/src/storage_key.rs +0 -41
data/lib/scale/block.rb
CHANGED
@@ -2,11 +2,11 @@ module Scale
|
|
2
2
|
module Types
|
3
3
|
|
4
4
|
class Extrinsic
|
5
|
-
include
|
5
|
+
include Base
|
6
6
|
# attr_accessor :address, :signature, :nonce, :era, :extrinsic_hash, :call_index, :params_raw, :params
|
7
7
|
|
8
|
-
def self.generate_hash(
|
9
|
-
|
8
|
+
def self.generate_hash(bytes)
|
9
|
+
Crypto.blake2_256 bytes
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.decode(scale_bytes)
|
@@ -61,10 +61,10 @@ module Scale
|
|
61
61
|
|
62
62
|
if contains_transaction
|
63
63
|
result[:address] = Scale::Types.get("Address").decode(scale_bytes).value
|
64
|
-
result[:signature] =
|
65
|
-
result[:era] =
|
66
|
-
result[:nonce] =
|
67
|
-
result[:tip] =
|
64
|
+
result[:signature] = Scale::Types.get("MultiSignature").decode(scale_bytes).value
|
65
|
+
result[:era] = Scale::Types.get("Era").decode(scale_bytes).value
|
66
|
+
result[:nonce] = Scale::Types.get("Compact").decode(scale_bytes).value
|
67
|
+
result[:tip] = Scale::Types.get("Compact").decode(scale_bytes).value
|
68
68
|
result[:extrinsic_hash] = generate_hash(scale_bytes.bytes)
|
69
69
|
end
|
70
70
|
result[:call_index] = scale_bytes.get_next_bytes(2).bytes_to_hex[2..]
|
@@ -116,7 +116,7 @@ module Scale
|
|
116
116
|
end
|
117
117
|
|
118
118
|
class EventRecords
|
119
|
-
include
|
119
|
+
include Base
|
120
120
|
|
121
121
|
def self.decode(scale_bytes)
|
122
122
|
|
@@ -129,7 +129,7 @@ module Scale
|
|
129
129
|
end
|
130
130
|
|
131
131
|
class EventRecord
|
132
|
-
include
|
132
|
+
include Base
|
133
133
|
|
134
134
|
def self.decode(scale_bytes)
|
135
135
|
metadata = Scale::TypeRegistry.instance.metadata.value
|
@@ -141,9 +141,13 @@ module Scale
|
|
141
141
|
result[:extrinsic_idx] = U32.decode(scale_bytes).value
|
142
142
|
end
|
143
143
|
|
144
|
-
|
145
|
-
event = metadata.event_index[
|
146
|
-
|
144
|
+
index = scale_bytes.get_next_bytes(2).bytes_to_hex[2..]
|
145
|
+
event = metadata.event_index[index][1]
|
146
|
+
the_module = metadata.event_index[index][0]
|
147
|
+
|
148
|
+
result[:event_index] = index
|
149
|
+
result[:event_metadata] = event
|
150
|
+
result[:module_metadata] = the_module
|
147
151
|
|
148
152
|
result[:params] = []
|
149
153
|
event[:args].each do |arg_type|
|
@@ -207,7 +211,7 @@ module Scale
|
|
207
211
|
|
208
212
|
class LogDigest
|
209
213
|
include Enum
|
210
|
-
|
214
|
+
inner_types *%w[Other AuthoritiesChange ChangesTrieRoot SealV0 Consensus Seal PreRuntime]
|
211
215
|
end
|
212
216
|
|
213
217
|
end
|
data/lib/scale/trie.rb
CHANGED
data/lib/scale/types.rb
CHANGED
@@ -2,15 +2,18 @@ module Scale
|
|
2
2
|
module Types
|
3
3
|
|
4
4
|
class Bool
|
5
|
-
include
|
5
|
+
include Base
|
6
6
|
BYTES_LENGTH = 1
|
7
7
|
|
8
8
|
def self.decode(scale_bytes)
|
9
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
9
10
|
bytes = scale_bytes.get_next_bytes(self::BYTES_LENGTH)
|
10
11
|
if bytes == [0]
|
11
|
-
|
12
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
13
|
+
new(false)
|
12
14
|
elsif bytes == [1]
|
13
|
-
|
15
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
16
|
+
new(true)
|
14
17
|
else
|
15
18
|
raise "Bad data"
|
16
19
|
end
|
@@ -21,6 +24,35 @@ module Scale
|
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
27
|
+
class OptionBool
|
28
|
+
include Base
|
29
|
+
def self.decode(scale_bytes)
|
30
|
+
byte = scale_bytes.get_next_bytes(1)[0]
|
31
|
+
value = if byte == 0x00
|
32
|
+
nil
|
33
|
+
elsif byte == 0x01
|
34
|
+
true
|
35
|
+
elsif byte == 0x02
|
36
|
+
false
|
37
|
+
else
|
38
|
+
raise BadDataError.new("Bad scale data for OptionBool #{byte.to_s(16)}")
|
39
|
+
end
|
40
|
+
new(value)
|
41
|
+
end
|
42
|
+
|
43
|
+
def encode
|
44
|
+
if value.nil?
|
45
|
+
"00"
|
46
|
+
elsif value === true
|
47
|
+
"01"
|
48
|
+
elsif value === false
|
49
|
+
"02"
|
50
|
+
else
|
51
|
+
raise WrongValueError.new("OptionBool can not have value other than `nil`, `true`, `false`")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
24
56
|
class U8
|
25
57
|
include FixedWidthUInt
|
26
58
|
BYTE_LENGTH = 1
|
@@ -51,6 +83,11 @@ module Scale
|
|
51
83
|
BYTE_LENGTH = 32
|
52
84
|
end
|
53
85
|
|
86
|
+
class U512
|
87
|
+
include FixedWidthUInt
|
88
|
+
BYTE_LENGTH = 64
|
89
|
+
end
|
90
|
+
|
54
91
|
class I8
|
55
92
|
include FixedWidthInt
|
56
93
|
BYTE_LENGTH = 1
|
@@ -77,9 +114,10 @@ module Scale
|
|
77
114
|
end
|
78
115
|
|
79
116
|
class Compact
|
80
|
-
include
|
117
|
+
include Base
|
81
118
|
|
82
119
|
def self.decode(scale_bytes)
|
120
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
83
121
|
first_byte = scale_bytes.get_next_bytes(1)[0]
|
84
122
|
first_byte_in_bin = first_byte.to_s(2).rjust(8, "0")
|
85
123
|
|
@@ -113,7 +151,8 @@ module Scale
|
|
113
151
|
.to_i(16)
|
114
152
|
end
|
115
153
|
|
116
|
-
|
154
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
155
|
+
new(value)
|
117
156
|
end
|
118
157
|
|
119
158
|
def encode
|
@@ -138,9 +177,10 @@ module Scale
|
|
138
177
|
end
|
139
178
|
|
140
179
|
class Bytes
|
141
|
-
include
|
180
|
+
include Base
|
142
181
|
|
143
182
|
def self.decode(scale_bytes)
|
183
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
144
184
|
length = Scale::Types::Compact.decode(scale_bytes).value
|
145
185
|
bytes = scale_bytes.get_next_bytes(length)
|
146
186
|
|
@@ -148,9 +188,11 @@ module Scale
|
|
148
188
|
# => "Café"
|
149
189
|
str = bytes.pack("C*").force_encoding("utf-8")
|
150
190
|
if str.valid_encoding?
|
151
|
-
|
191
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
192
|
+
new str
|
152
193
|
else
|
153
|
-
|
194
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
195
|
+
new bytes.bytes_to_hex
|
154
196
|
end
|
155
197
|
end
|
156
198
|
|
@@ -168,29 +210,40 @@ module Scale
|
|
168
210
|
end
|
169
211
|
|
170
212
|
class Hex
|
171
|
-
include
|
213
|
+
include Base
|
172
214
|
|
173
215
|
def self.decode(scale_bytes)
|
216
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
174
217
|
length = Scale::Types::Compact.decode(scale_bytes).value
|
175
218
|
hex_string = scale_bytes.get_next_bytes(length).bytes_to_hex
|
176
|
-
|
219
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
220
|
+
new(hex_string)
|
221
|
+
end
|
222
|
+
|
223
|
+
def encode
|
224
|
+
length = Compact.new((value.length - 2)/2).encode
|
225
|
+
"#{length}#{value[2..]}"
|
177
226
|
end
|
178
227
|
end
|
179
228
|
|
180
229
|
class String
|
181
|
-
include
|
230
|
+
include Base
|
182
231
|
def self.decode(scale_bytes)
|
232
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
183
233
|
length = Scale::Types::Compact.decode(scale_bytes).value
|
184
234
|
bytes = scale_bytes.get_next_bytes(length)
|
185
|
-
|
235
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
236
|
+
new bytes.pack("C*").force_encoding("utf-8")
|
186
237
|
end
|
187
238
|
end
|
188
239
|
|
189
240
|
class H160
|
190
|
-
include
|
241
|
+
include Base
|
191
242
|
def self.decode(scale_bytes)
|
243
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
192
244
|
bytes = scale_bytes.get_next_bytes(20)
|
193
|
-
|
245
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
246
|
+
new(bytes.bytes_to_hex)
|
194
247
|
end
|
195
248
|
|
196
249
|
def encode
|
@@ -200,10 +253,12 @@ module Scale
|
|
200
253
|
end
|
201
254
|
|
202
255
|
class H256
|
203
|
-
include
|
256
|
+
include Base
|
204
257
|
def self.decode(scale_bytes)
|
258
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
205
259
|
bytes = scale_bytes.get_next_bytes(32)
|
206
|
-
|
260
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
261
|
+
new(bytes.bytes_to_hex)
|
207
262
|
end
|
208
263
|
|
209
264
|
def encode
|
@@ -213,10 +268,12 @@ module Scale
|
|
213
268
|
end
|
214
269
|
|
215
270
|
class H512
|
216
|
-
include
|
271
|
+
include Base
|
217
272
|
def self.decode(scale_bytes)
|
273
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
218
274
|
bytes = scale_bytes.get_next_bytes(64)
|
219
|
-
|
275
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
276
|
+
new(bytes.bytes_to_hex)
|
220
277
|
end
|
221
278
|
|
222
279
|
def encode
|
@@ -226,7 +283,7 @@ module Scale
|
|
226
283
|
end
|
227
284
|
|
228
285
|
class GenericAddress
|
229
|
-
include
|
286
|
+
include Base
|
230
287
|
|
231
288
|
# https://github.com/paritytech/substrate/wiki/External-Address-Format-(SS58)
|
232
289
|
# base58encode ( concat ( <address-type>, <address>, <checksum> ) )
|
@@ -234,13 +291,15 @@ module Scale
|
|
234
291
|
# the <address> is 32 byte account id or 1, 2, 4, 8 byte account index
|
235
292
|
# scale_bytes: account length byte + <address>'s bytes
|
236
293
|
def self.decode(scale_bytes)
|
294
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
237
295
|
account_length = scale_bytes.get_next_bytes(1).first
|
238
296
|
|
239
297
|
if account_length == 0xff # 32 bytes address(Public key)
|
240
298
|
account_id = scale_bytes.get_next_bytes(32).bytes_to_hex
|
241
299
|
account_length = [account_length].bytes_to_hex
|
242
300
|
|
243
|
-
|
301
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
302
|
+
new({
|
244
303
|
account_id: account_id,
|
245
304
|
account_length: account_length
|
246
305
|
})
|
@@ -258,7 +317,8 @@ module Scale
|
|
258
317
|
# TODO: add account_idx
|
259
318
|
account_length = [account_length].bytes_to_hex
|
260
319
|
|
261
|
-
|
320
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
321
|
+
new({
|
262
322
|
account_index: account_index,
|
263
323
|
account_length: account_length
|
264
324
|
})
|
@@ -280,10 +340,14 @@ module Scale
|
|
280
340
|
|
281
341
|
class AccountIdAddress < GenericAddress
|
282
342
|
def self.decode(scale_bytes)
|
283
|
-
|
343
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
344
|
+
result = new({
|
284
345
|
account_id: AccountId.decode(scale_bytes).value,
|
285
346
|
account_length: "0xff"
|
286
347
|
})
|
348
|
+
|
349
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
350
|
+
result
|
287
351
|
end
|
288
352
|
|
289
353
|
def encode
|
@@ -291,6 +355,17 @@ module Scale
|
|
291
355
|
end
|
292
356
|
end
|
293
357
|
|
358
|
+
class GenericMultiAddress
|
359
|
+
include Enum
|
360
|
+
items(
|
361
|
+
Id: "AccountId",
|
362
|
+
Index: "Compact",
|
363
|
+
Raw: "Hex",
|
364
|
+
Address32: "H256",
|
365
|
+
Address20: "H160"
|
366
|
+
)
|
367
|
+
end
|
368
|
+
|
294
369
|
class AccountId < H256; end
|
295
370
|
|
296
371
|
class Balance < U128; end
|
@@ -302,14 +377,17 @@ module Scale
|
|
302
377
|
class AccountIndex < U32; end
|
303
378
|
|
304
379
|
class Era
|
305
|
-
include
|
380
|
+
include Base
|
306
381
|
def self.decode(scale_bytes)
|
382
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
307
383
|
byte = scale_bytes.get_next_bytes(1).bytes_to_hex
|
308
|
-
if byte == "0x00"
|
309
|
-
|
384
|
+
result = if byte == "0x00"
|
385
|
+
new byte
|
310
386
|
else
|
311
|
-
|
387
|
+
new byte + scale_bytes.get_next_bytes(1).bytes_to_hex()[2..]
|
312
388
|
end
|
389
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
390
|
+
result
|
313
391
|
end
|
314
392
|
end
|
315
393
|
|
@@ -318,14 +396,16 @@ module Scale
|
|
318
396
|
class Moment < U64; end
|
319
397
|
|
320
398
|
class CompactMoment
|
321
|
-
include
|
399
|
+
include Base
|
322
400
|
def self.decode(scale_bytes)
|
401
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
323
402
|
value = Compact.decode(scale_bytes).value
|
324
403
|
if value > 10000000000
|
325
404
|
value /= 1000
|
326
405
|
end
|
327
406
|
|
328
|
-
|
407
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
408
|
+
new Time.at(value).strftime("%F %T")
|
329
409
|
end
|
330
410
|
end
|
331
411
|
|
@@ -429,9 +509,9 @@ module Scale
|
|
429
509
|
end
|
430
510
|
|
431
511
|
class Null
|
432
|
-
include
|
512
|
+
include Base
|
433
513
|
def self.decode(scale_bytes)
|
434
|
-
|
514
|
+
new nil
|
435
515
|
end
|
436
516
|
|
437
517
|
def encode
|
@@ -622,18 +702,20 @@ module Scale
|
|
622
702
|
include Struct
|
623
703
|
items(
|
624
704
|
id: "VecU8Length8",
|
625
|
-
amount: "Balance",
|
705
|
+
amount: "Scale::Types::Balance",
|
626
706
|
until: "U32",
|
627
|
-
reasons: "WithdrawReasons"
|
707
|
+
reasons: "Scale::Types::WithdrawReasons"
|
628
708
|
)
|
629
709
|
end
|
630
710
|
|
631
711
|
class EthereumAddress
|
632
|
-
include
|
712
|
+
include Base
|
633
713
|
|
634
714
|
def self.decode(scale_bytes)
|
715
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
635
716
|
bytes = scale_bytes.get_next_bytes(20)
|
636
|
-
|
717
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
718
|
+
new(bytes.bytes_to_hex)
|
637
719
|
end
|
638
720
|
|
639
721
|
def encode
|
@@ -646,11 +728,13 @@ module Scale
|
|
646
728
|
end
|
647
729
|
|
648
730
|
class EcdsaSignature
|
649
|
-
include
|
731
|
+
include Base
|
650
732
|
|
651
733
|
def self.decode(scale_bytes)
|
734
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
652
735
|
bytes = scale_bytes.get_next_bytes(65)
|
653
|
-
|
736
|
+
new(bytes.bytes_to_hex)
|
737
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
654
738
|
end
|
655
739
|
|
656
740
|
def encode
|
@@ -756,9 +840,13 @@ module Scale
|
|
756
840
|
end
|
757
841
|
|
758
842
|
class VoteOutcome
|
759
|
-
include
|
843
|
+
include Base
|
760
844
|
def self.decode(scale_bytes)
|
761
|
-
|
845
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
846
|
+
result = new(scale_bytes.get_next_bytes(32))
|
847
|
+
|
848
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
849
|
+
result
|
762
850
|
end
|
763
851
|
end
|
764
852
|
|
@@ -796,9 +884,10 @@ module Scale
|
|
796
884
|
end
|
797
885
|
|
798
886
|
class BoxProposal
|
799
|
-
include
|
887
|
+
include Base
|
800
888
|
|
801
889
|
def self.decode(scale_bytes, metadata, chain_spec)
|
890
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
802
891
|
call_index = scale_bytes.get_next_bytes(2).bytes_to_hex[2..]
|
803
892
|
call_module, call = metadata.value.call_index[call_index]
|
804
893
|
|
@@ -807,6 +896,7 @@ module Scale
|
|
807
896
|
{name: arg[:name], type: arg[:type], value: arg_obj.encode, value_raw: arg_obj.value}
|
808
897
|
end
|
809
898
|
|
899
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
810
900
|
self.new({
|
811
901
|
call_index: call_index,
|
812
902
|
call_function: call[:name],
|
@@ -832,7 +922,7 @@ module Scale
|
|
832
922
|
end
|
833
923
|
|
834
924
|
class VecH512Length2
|
835
|
-
include
|
925
|
+
include Base
|
836
926
|
|
837
927
|
def self.decode(scale_bytes)
|
838
928
|
end
|
@@ -844,6 +934,15 @@ module Scale
|
|
844
934
|
end
|
845
935
|
end
|
846
936
|
|
937
|
+
class GenericBlock
|
938
|
+
include Base
|
939
|
+
|
940
|
+
def self.decode(scale_bytes)
|
941
|
+
end
|
942
|
+
|
943
|
+
def encode
|
944
|
+
end
|
945
|
+
end
|
847
946
|
|
848
947
|
end
|
849
948
|
end
|