scale.rb 0.2.14 → 0.2.15
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 +2007 -11
- data/Cargo.toml +9 -2
- data/Gemfile.lock +15 -9
- data/exe/scale +9 -0
- data/lib/helper.rb +126 -0
- data/lib/metadata/metadata.rb +14 -0
- data/lib/scale.rb +25 -9
- data/lib/scale/base.rb +5 -8
- data/lib/scale/block.rb +11 -25
- data/lib/scale/types.rb +18 -0
- data/lib/scale/version.rb +1 -1
- data/lib/substrate_client.rb +159 -0
- data/lib/type_registry/{crab-28.json → crab.json} +394 -127
- data/lib/type_registry/darwinia.json +701 -136
- data/scale.gemspec +3 -2
- data/scripts/block_events.rb +2 -3
- data/src/lib.rs +42 -1
- data/src/storage_key.rs +41 -0
- metadata +30 -15
- data/.DS_Store +0 -0
- data/lib/type_registry/darwinia-8.json +0 -662
data/Cargo.toml
CHANGED
@@ -2,10 +2,17 @@
|
|
2
2
|
name = "SCALE-testing-interface"
|
3
3
|
version = "0.1.0"
|
4
4
|
authors = ["Robert Hambrock <robert@web3.foundation>"]
|
5
|
+
edition = "2018"
|
5
6
|
|
6
7
|
[dependencies]
|
7
|
-
parity-scale-codec = { version = "1.
|
8
|
+
parity-scale-codec = { version = "1.3.6" }
|
9
|
+
sp-core = { version = "2.0.0", git = "https://github.com/paritytech/substrate.git", features = ["full_crypto"]}
|
10
|
+
frame-support = { version = "2.0.0", git = "https://github.com/paritytech/substrate.git" }
|
8
11
|
|
9
12
|
[lib]
|
10
13
|
name = "scale_ffi"
|
11
|
-
crate-type = ["dylib"]
|
14
|
+
crate-type = ["dylib"]
|
15
|
+
|
16
|
+
[[bin]]
|
17
|
+
name = "storage_key"
|
18
|
+
path = "src/storage_key.rs"
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
scale.rb (0.2.
|
5
|
-
activesupport (
|
4
|
+
scale.rb (0.2.15)
|
5
|
+
activesupport (~> 6.0.0)
|
6
6
|
json (~> 2.3.0)
|
7
|
-
|
7
|
+
kontena-websocket-client (~> 0.1.1)
|
8
|
+
substrate_common.rb (~> 0.1.10)
|
8
9
|
thor (~> 0.19.0)
|
9
10
|
|
10
11
|
GEM
|
@@ -19,14 +20,16 @@ GEM
|
|
19
20
|
base58 (0.2.3)
|
20
21
|
blake2b (0.10.0)
|
21
22
|
coderay (1.1.2)
|
22
|
-
concurrent-ruby (1.1.
|
23
|
+
concurrent-ruby (1.1.8)
|
23
24
|
diff-lcs (1.3)
|
24
25
|
ffi (1.12.2)
|
25
|
-
i18n (1.8.
|
26
|
+
i18n (1.8.8)
|
26
27
|
concurrent-ruby (~> 1.0)
|
27
28
|
json (2.3.1)
|
29
|
+
kontena-websocket-client (0.1.1)
|
30
|
+
websocket-driver (~> 0.6.5)
|
28
31
|
method_source (0.9.2)
|
29
|
-
minitest (5.14.
|
32
|
+
minitest (5.14.3)
|
30
33
|
pry (0.12.2)
|
31
34
|
coderay (~> 1.1.0)
|
32
35
|
method_source (~> 0.9.0)
|
@@ -44,16 +47,19 @@ GEM
|
|
44
47
|
diff-lcs (>= 1.2.0, < 2.0)
|
45
48
|
rspec-support (~> 3.9.0)
|
46
49
|
rspec-support (3.9.0)
|
47
|
-
substrate_common.rb (0.1.
|
50
|
+
substrate_common.rb (0.1.10)
|
48
51
|
base58
|
49
52
|
blake2b
|
50
53
|
xxhash
|
51
54
|
thor (0.19.4)
|
52
55
|
thread_safe (0.3.6)
|
53
|
-
tzinfo (1.2.
|
56
|
+
tzinfo (1.2.9)
|
54
57
|
thread_safe (~> 0.1)
|
58
|
+
websocket-driver (0.6.5)
|
59
|
+
websocket-extensions (>= 0.1.0)
|
60
|
+
websocket-extensions (0.1.5)
|
55
61
|
xxhash (0.4.0)
|
56
|
-
zeitwerk (2.4.
|
62
|
+
zeitwerk (2.4.2)
|
57
63
|
|
58
64
|
PLATFORMS
|
59
65
|
ruby
|
data/exe/scale
CHANGED
@@ -75,6 +75,15 @@ class ScaleCli < Thor
|
|
75
75
|
type = Scale::Types.get(type_name)
|
76
76
|
p "0x" + type.new(value.to_i).encode
|
77
77
|
end
|
78
|
+
|
79
|
+
desc "check_read_proof ROOT PROOF STORAGE_KEY", "check read proof and output leaf's value"
|
80
|
+
def check_read_proof(root, proof, storage_key)
|
81
|
+
Scale::TypeRegistry.instance.load
|
82
|
+
proof = proof.split(",").map(&:strip)
|
83
|
+
|
84
|
+
value = Scale::Types::TrieNode::check(root, proof, storage_key)
|
85
|
+
p value
|
86
|
+
end
|
78
87
|
end
|
79
88
|
|
80
89
|
ScaleCli.start(ARGV)
|
data/lib/helper.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
|
2
|
+
class SubstrateClient::Helper
|
3
|
+
class << self
|
4
|
+
def generate_storage_key_from_metadata(metadata, module_name, storage_name, params = nil)
|
5
|
+
# find the storage item from metadata
|
6
|
+
metadata_modules = metadata.value.value[:metadata][:modules]
|
7
|
+
metadata_module = metadata_modules.detect { |mm| mm[:name] == module_name }
|
8
|
+
raise "Module '#{module_name}' not exist" unless metadata_module
|
9
|
+
storage_item = metadata_module[:storage][:items].detect { |item| item[:name] == storage_name }
|
10
|
+
raise "Storage item '#{storage_name}' not exist. \n#{metadata_module.inspect}" unless storage_item
|
11
|
+
|
12
|
+
if storage_item[:type][:Plain]
|
13
|
+
return_type = storage_item[:type][:Plain]
|
14
|
+
elsif map = storage_item[:type][:Map]
|
15
|
+
raise "Storage call of type \"Map\" requires 1 parameter" if params.nil? || params.length != 1
|
16
|
+
|
17
|
+
hasher = map[:hasher]
|
18
|
+
return_type = map[:value]
|
19
|
+
# TODO: decode to account id if param is address
|
20
|
+
# params[0] = decode(params[0]) if map[:key] == "AccountId"
|
21
|
+
type = Scale::Types.get(map[:key])
|
22
|
+
params[0] = type.new(params[0]).encode
|
23
|
+
elsif map = storage_item[:type][:DoubleMap]
|
24
|
+
raise "Storage call of type \"DoubleMapType\" requires 2 parameters" if params.nil? || params.length != 2
|
25
|
+
|
26
|
+
hasher = map[:hasher]
|
27
|
+
hasher2 = map[:key2Hasher]
|
28
|
+
return_type = map[:value]
|
29
|
+
params[0] = Scale::Types.get(map[:key1]).new(params[0]).encode
|
30
|
+
params[1] = Scale::Types.get(map[:key2]).new(params[1]).encode
|
31
|
+
else
|
32
|
+
raise NotImplementedError
|
33
|
+
end
|
34
|
+
|
35
|
+
storage_prefix = metadata_module[:storage][:prefix]
|
36
|
+
storage_key = generate_storage_key(
|
37
|
+
storage_prefix.nil? ? module_name : storage_prefix,
|
38
|
+
storage_name,
|
39
|
+
params,
|
40
|
+
hasher,
|
41
|
+
hasher2,
|
42
|
+
metadata.value.value[:metadata][:version]
|
43
|
+
)
|
44
|
+
[storage_key, return_type]
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_storage_key(module_name, storage_name, params = nil, hasher = nil, hasher2 = nil, metadata_version = nil)
|
48
|
+
metadata_version = 12 if metadata_version.nil?
|
49
|
+
if metadata_version and metadata_version >= 9
|
50
|
+
storage_key = Crypto.twox128(module_name) + Crypto.twox128(storage_name)
|
51
|
+
|
52
|
+
params&.each_with_index do |param, index|
|
53
|
+
if index == 0
|
54
|
+
param_hasher = hasher
|
55
|
+
elsif index == 1
|
56
|
+
param_hasher = hasher2
|
57
|
+
else
|
58
|
+
raise "Unexpected third parameter for storage call"
|
59
|
+
end
|
60
|
+
|
61
|
+
param_key = if param.class == String && param.start_with?("0x")
|
62
|
+
param.hex_to_bytes
|
63
|
+
else
|
64
|
+
param.encode().hex_to_bytes
|
65
|
+
end
|
66
|
+
param_hasher = "Twox128" if param_hasher.nil?
|
67
|
+
storage_key += Crypto.send(param_hasher.underscore, param_key)
|
68
|
+
end
|
69
|
+
|
70
|
+
"0x#{storage_key}"
|
71
|
+
else
|
72
|
+
# TODO: add test
|
73
|
+
storage_key = module_name + " " + storage_name
|
74
|
+
|
75
|
+
unless params.nil?
|
76
|
+
params = [params] if params.class != ::Array
|
77
|
+
params_key = params.join("")
|
78
|
+
hasher = "Twox128" if hasher.nil?
|
79
|
+
storage_key += params_key.hex_to_bytes.bytes_to_utf8
|
80
|
+
end
|
81
|
+
|
82
|
+
"0x#{Crypto.send( hasher.underscore, storage_key )}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def compose_call_from_metadata(metadata, module_name, call_name, params)
|
87
|
+
call = metadata.get_module_call(module_name, call_name)
|
88
|
+
|
89
|
+
value = {
|
90
|
+
call_index: call[:lookup],
|
91
|
+
module_name: module_name,
|
92
|
+
call_name: call_name,
|
93
|
+
params: []
|
94
|
+
}
|
95
|
+
|
96
|
+
params.keys.each_with_index do |call_param_name, i|
|
97
|
+
param_value = params[call_param_name]
|
98
|
+
value[:params] << {
|
99
|
+
name: call_param_name.to_s,
|
100
|
+
type: call[:args][i][:type],
|
101
|
+
value: param_value
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
Scale::Types::Extrinsic.new(value).encode
|
106
|
+
end
|
107
|
+
|
108
|
+
def decode_block(block)
|
109
|
+
block["block"]["header"]["number"] = block["block"]["header"]["number"].to_i(16)
|
110
|
+
|
111
|
+
block["block"]["extrinsics"].each_with_index do |hex, i|
|
112
|
+
scale_bytes = Scale::Bytes.new(hex)
|
113
|
+
block["block"]["extrinsics"][i] = Scale::Types::Extrinsic.decode(scale_bytes).to_human
|
114
|
+
end
|
115
|
+
|
116
|
+
block['block']['header']["digest"]["logs"].each_with_index do |hex, i|
|
117
|
+
scale_bytes = Scale::Bytes.new(hex)
|
118
|
+
log = Scale::Types::LogDigest.decode(scale_bytes).to_human
|
119
|
+
block['block']['header']["digest"]["logs"][i] = log
|
120
|
+
end
|
121
|
+
|
122
|
+
block
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
data/lib/metadata/metadata.rb
CHANGED
@@ -35,6 +35,16 @@ module Scale
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
+
|
39
|
+
def get_module_storage(module_name, storage_name)
|
40
|
+
the_module = get_module(module_name)
|
41
|
+
if the_module[:storage].class == Array
|
42
|
+
storages = the_module[:storage]
|
43
|
+
else
|
44
|
+
storages = the_module[:storage][:items]
|
45
|
+
end
|
46
|
+
storages.find {|storage| storage[:name] == storage_name}
|
47
|
+
end
|
38
48
|
end
|
39
49
|
|
40
50
|
class MetadataModule
|
@@ -68,6 +78,10 @@ module Scale
|
|
68
78
|
|
69
79
|
MetadataModule.new(result)
|
70
80
|
end
|
81
|
+
|
82
|
+
def get_storage(storage_name)
|
83
|
+
self.value[:storage].find { |storage| storage[:name].downcase == storage_name.downcase }
|
84
|
+
end
|
71
85
|
end
|
72
86
|
|
73
87
|
class MetadataModuleStorage
|
data/lib/scale.rb
CHANGED
@@ -26,13 +26,23 @@ require "metadata/metadata_v10"
|
|
26
26
|
require "metadata/metadata_v11"
|
27
27
|
require "metadata/metadata_v12"
|
28
28
|
|
29
|
+
require "substrate_client"
|
30
|
+
require "logger"
|
31
|
+
require "helper"
|
32
|
+
require 'kontena-websocket-client'
|
33
|
+
|
29
34
|
module Scale
|
30
35
|
class Error < StandardError; end
|
31
36
|
|
32
37
|
class TypeRegistry
|
33
38
|
include Singleton
|
34
|
-
|
35
|
-
|
39
|
+
|
40
|
+
# init by load, and will not change
|
41
|
+
attr_reader :spec_name, :types
|
42
|
+
attr_reader :versioning, :custom_types # optional
|
43
|
+
|
44
|
+
# will change by different spec version
|
45
|
+
attr_accessor :spec_version # optional
|
36
46
|
attr_accessor :metadata
|
37
47
|
|
38
48
|
def load(spec_name: nil, custom_types: nil)
|
@@ -43,13 +53,18 @@ module Scale
|
|
43
53
|
|
44
54
|
default_types, _, _ = load_chain_spec_types("default")
|
45
55
|
|
46
|
-
if spec_name
|
56
|
+
if spec_name
|
57
|
+
begin
|
58
|
+
@spec_name = spec_name
|
59
|
+
spec_types, @versioning, @spec_version = load_chain_spec_types(spec_name)
|
60
|
+
@types = default_types.merge(spec_types)
|
61
|
+
rescue => ex
|
62
|
+
puts "There is no types json file named #{spec_name}"
|
63
|
+
@types = default_types
|
64
|
+
end
|
65
|
+
else
|
47
66
|
@spec_name = "default"
|
48
67
|
@types = default_types
|
49
|
-
else
|
50
|
-
@spec_name = spec_name
|
51
|
-
spec_types, @versioning, @spec_version = load_chain_spec_types(spec_name)
|
52
|
-
@types = default_types.merge(spec_types)
|
53
68
|
end
|
54
69
|
|
55
70
|
self.custom_types = custom_types
|
@@ -63,7 +78,8 @@ module Scale
|
|
63
78
|
|
64
79
|
if @spec_version && @versioning
|
65
80
|
@versioning.each do |item|
|
66
|
-
if @spec_version >= item["runtime_range"][0] &&
|
81
|
+
if @spec_version >= item["runtime_range"][0] &&
|
82
|
+
( item["runtime_range"][1].nil? || @spec_version <= item["runtime_range"][1] )
|
67
83
|
all_types.merge!(item["types"])
|
68
84
|
end
|
69
85
|
end
|
@@ -342,7 +358,7 @@ def rename(type)
|
|
342
358
|
return "AccountData" if type == "AccountData<Balance>"
|
343
359
|
|
344
360
|
if type =~ /\[U\d+; \d+\]/
|
345
|
-
byte_length = type.scan(/\[U\d+; (\d+)\]/).first.first
|
361
|
+
byte_length = type.scan(/\[U\d+; (\d+)\]/).first.first.to_i
|
346
362
|
return "VecU8Length#{byte_length}"
|
347
363
|
end
|
348
364
|
|
data/lib/scale/base.rb
CHANGED
@@ -349,9 +349,8 @@ module Scale
|
|
349
349
|
|
350
350
|
module ClassMethods
|
351
351
|
def decode(scale_bytes)
|
352
|
-
byte_length =
|
353
|
-
raise "length is wrong: #{byte_length}" unless %w[2 3 4 8 16 20 32 64].include?(byte_length)
|
354
|
-
byte_length = byte_length.to_i
|
352
|
+
byte_length = self::BYTE_LENGTH
|
353
|
+
raise "#{self.name} byte length is wrong: #{byte_length}" unless %w[2 3 4 8 16 20 32 64 128 256].include?(byte_length.to_s)
|
355
354
|
|
356
355
|
bytes = scale_bytes.get_next_bytes(byte_length)
|
357
356
|
str = bytes.pack("C*").force_encoding("utf-8")
|
@@ -368,12 +367,10 @@ module Scale
|
|
368
367
|
end
|
369
368
|
|
370
369
|
def encode
|
371
|
-
|
372
|
-
length
|
373
|
-
raise "length is wrong: #{length}" unless %w[2 3 4 8 16 20 32 64].include?(length)
|
374
|
-
length = length.to_i
|
370
|
+
byte_length = self.class::BYTE_LENGTH
|
371
|
+
raise "#{self.class.name}'s byte length is wrong: #{byte_length}" unless %w[2 3 4 8 16 20 32 64 128 256].include?(byte_length.to_s)
|
375
372
|
|
376
|
-
if value.start_with?("0x") && value.length == (
|
373
|
+
if value.start_with?("0x") && value.length == (byte_length * 2 + 2)
|
377
374
|
value[2..]
|
378
375
|
else
|
379
376
|
bytes = value.unpack("C*")
|
data/lib/scale/block.rb
CHANGED
@@ -10,7 +10,7 @@ module Scale
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.decode(scale_bytes)
|
13
|
-
metadata = Scale::TypeRegistry.instance.metadata
|
13
|
+
metadata = Scale::TypeRegistry.instance.metadata.value
|
14
14
|
result = {}
|
15
15
|
|
16
16
|
extrinsic_length = Compact.decode(scale_bytes).value
|
@@ -24,9 +24,6 @@ module Scale
|
|
24
24
|
if contains_transaction
|
25
25
|
address = Scale::Types.get("Address").decode(scale_bytes)
|
26
26
|
result[:address] = address.value
|
27
|
-
result[:account_length] = address.account_length
|
28
|
-
result[:account_id] = address.account_id
|
29
|
-
result[:account_index] = address.account_index
|
30
27
|
result[:signature] = Scale::Types.get("Signature").decode(scale_bytes).value
|
31
28
|
result[:nonce] = Scale::Types.get("Compact").decode(scale_bytes).value
|
32
29
|
result[:era] = Scale::Types.get("Era").decode(scale_bytes).value
|
@@ -39,9 +36,6 @@ module Scale
|
|
39
36
|
if contains_transaction
|
40
37
|
address = Scale::Types.get("Address").decode(scale_bytes)
|
41
38
|
result[:address] = address.value
|
42
|
-
result[:account_length] = address.account_length
|
43
|
-
result[:account_id] = address.account_id
|
44
|
-
result[:account_index] = address.account_index
|
45
39
|
result[:signature] = Scale::Types.get("Signature").decode(scale_bytes).value
|
46
40
|
result[:era] = Scale::Types.get("Era").decode(scale_bytes).value
|
47
41
|
result[:nonce] = Scale::Types.get("Compact").decode(scale_bytes).value
|
@@ -55,9 +49,6 @@ module Scale
|
|
55
49
|
if contains_transaction
|
56
50
|
address = Scale::Types.get("Address").decode(scale_bytes)
|
57
51
|
result[:address] = address.value
|
58
|
-
result[:account_length] = address.account_length
|
59
|
-
result[:account_id] = address.account_id
|
60
|
-
result[:account_index] = address.account_index
|
61
52
|
result[:signature] = Scale::Types.get("Signature").decode(scale_bytes).value
|
62
53
|
result[:era] = Scale::Types.get("Era").decode(scale_bytes).value
|
63
54
|
result[:nonce] = Scale::Types.get("Compact").decode(scale_bytes).value
|
@@ -69,16 +60,11 @@ module Scale
|
|
69
60
|
elsif version_info == "0x04" || version_info == "0x84"
|
70
61
|
|
71
62
|
if contains_transaction
|
72
|
-
address = Scale::Types.get("Address").decode(scale_bytes)
|
73
|
-
result[:
|
74
|
-
result[:
|
75
|
-
result[:
|
76
|
-
result[:
|
77
|
-
result[:signature_version] = Scale::Types.get("U8").decode(scale_bytes).value
|
78
|
-
result[:signature] = Scale::Types.get("Signature").decode(scale_bytes).value
|
79
|
-
result[:era] = Scale::Types.get("Era").decode(scale_bytes).value
|
80
|
-
result[:nonce] = Scale::Types.get("Compact").decode(scale_bytes).value
|
81
|
-
result[:tip] = Scale::Types.get("Compact").decode(scale_bytes).value
|
63
|
+
result[:address] = Scale::Types.get("Address").decode(scale_bytes).value
|
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
|
82
68
|
result[:extrinsic_hash] = generate_hash(scale_bytes.bytes)
|
83
69
|
end
|
84
70
|
result[:call_index] = scale_bytes.get_next_bytes(2).bytes_to_hex[2..]
|
@@ -146,7 +132,7 @@ module Scale
|
|
146
132
|
include SingleValue
|
147
133
|
|
148
134
|
def self.decode(scale_bytes)
|
149
|
-
metadata = Scale::TypeRegistry.instance.metadata
|
135
|
+
metadata = Scale::TypeRegistry.instance.metadata.value
|
150
136
|
|
151
137
|
result = {}
|
152
138
|
phase = scale_bytes.get_next_bytes(1).first
|
@@ -175,18 +161,18 @@ module Scale
|
|
175
161
|
end
|
176
162
|
end
|
177
163
|
|
178
|
-
# log
|
179
|
-
class Other < Bytes; end
|
180
|
-
|
181
164
|
class AuthoritiesChange
|
182
165
|
include Vec
|
183
166
|
inner_type "AccountId"
|
184
167
|
end
|
185
168
|
|
186
|
-
class
|
169
|
+
class GenericConsensusEngineId < VecU8Length4; end
|
187
170
|
|
188
171
|
class ChangesTrieRoot < Bytes; end
|
189
172
|
|
173
|
+
# log
|
174
|
+
class Other < Bytes; end
|
175
|
+
|
190
176
|
class SealV0
|
191
177
|
include Struct
|
192
178
|
items(
|
data/lib/scale/types.rb
CHANGED
@@ -570,34 +570,52 @@ module Scale
|
|
570
570
|
|
571
571
|
class VecU8Length2
|
572
572
|
include VecU8FixedLength
|
573
|
+
BYTE_LENGTH = 2
|
573
574
|
end
|
574
575
|
|
575
576
|
class VecU8Length3
|
576
577
|
include VecU8FixedLength
|
578
|
+
BYTE_LENGTH = 3
|
577
579
|
end
|
578
580
|
|
579
581
|
class VecU8Length4
|
580
582
|
include VecU8FixedLength
|
583
|
+
BYTE_LENGTH = 4
|
581
584
|
end
|
582
585
|
|
583
586
|
class VecU8Length8
|
584
587
|
include VecU8FixedLength
|
588
|
+
BYTE_LENGTH = 8
|
585
589
|
end
|
586
590
|
|
587
591
|
class VecU8Length16
|
588
592
|
include VecU8FixedLength
|
593
|
+
BYTE_LENGTH = 16
|
589
594
|
end
|
590
595
|
|
591
596
|
class VecU8Length20
|
592
597
|
include VecU8FixedLength
|
598
|
+
BYTE_LENGTH = 20
|
593
599
|
end
|
594
600
|
|
595
601
|
class VecU8Length32
|
596
602
|
include VecU8FixedLength
|
603
|
+
BYTE_LENGTH = 32
|
597
604
|
end
|
598
605
|
|
599
606
|
class VecU8Length64
|
600
607
|
include VecU8FixedLength
|
608
|
+
BYTE_LENGTH = 64
|
609
|
+
end
|
610
|
+
|
611
|
+
class VecU8Length128
|
612
|
+
include VecU8FixedLength
|
613
|
+
BYTE_LENGTH = 128
|
614
|
+
end
|
615
|
+
|
616
|
+
class VecU8Length256
|
617
|
+
include VecU8FixedLength
|
618
|
+
BYTE_LENGTH = 256
|
601
619
|
end
|
602
620
|
|
603
621
|
class BalanceLock
|