scale.rb 0.2.4 → 0.2.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8538580b5cc0d84add3684e3af10bbbba86bc741abb66bc5d38594c7de17894
4
- data.tar.gz: a652f2dd8b436840f8b4e004fdf3fe81c699200fb68a11ea2ca52ae4a3e64062
3
+ metadata.gz: b6c01e31f2e50407197c68df2d81da349d5471d52ddcb1b17c1a30fcd5706eae
4
+ data.tar.gz: 5618f3aa22bcf94dc40a12bb15508cbe6dff74441879ffccdd8f2d6f626de992
5
5
  SHA512:
6
- metadata.gz: a5a71617b20e22dc876b71414c6bdf78cfdc23b94444f010d902eb382bb8f26d92e06de9eedca805aca9ba408035a981a106fa1d944081a3426864d6351b6b58
7
- data.tar.gz: 8a65c9e78531472b74f93eb48da5c0e54c7b05430342467afa03ead952643cc41901a4a8f6b908ba6e3e8721b9aa26e6e426d6664ffb8ab93390e7c0febfd74c
6
+ metadata.gz: c00a8b437a13ea3a795ac1dbdc4bbeda4442400cb0a8153ab0bc07e980f5c921091b54afffe28392646aa3fede9c7b8b96d1d74d1e4fb3a9e3cf5de0419c1bca
7
+ data.tar.gz: c449932d536db154cd4b6e3bbb9163bb6083494d69066e52b3e3fb856bdcc44944e9d102835f1c702c024667a32ae8c1baa0719fc1d6e0815fc90dbbbf92b956
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- scale.rb (0.2.4)
4
+ scale.rb (0.2.5)
5
5
  activesupport (>= 4.0.0)
6
6
  json (~> 2.3.0)
7
7
  substrate_common.rb (~> 0.1.8)
data/README.md CHANGED
@@ -79,10 +79,13 @@ examples in `exec/scale`
79
79
  rspec
80
80
  ```
81
81
 
82
- To run only low level format tests, call
82
+ To run single test file:
83
83
 
84
- ```
85
- rspec spec/low_level_spec.rb
84
+ ```bash
85
+ rspec spec/types_spec.rb
86
+ rspec spec/extrinsic_spec.rb
87
+ rspec spec/metadata_spec.rb
88
+ rspec spec/types_ffi_spec.rb
86
89
  ```
87
90
 
88
91
 
@@ -5,21 +5,8 @@ module Scale
5
5
  attr_accessor :version
6
6
  def self.decode(scale_bytes)
7
7
  bytes = scale_bytes.get_next_bytes(4)
8
- if bytes.bytes_to_utf8 == 'meta'
9
- metadata_version = Scale::Types.type_of('Enum', [
10
- 'MetadataV0',
11
- 'MetadataV1',
12
- 'MetadataV2',
13
- 'MetadataV3',
14
- 'MetadataV4',
15
- 'MetadataV5',
16
- 'MetadataV6',
17
- 'MetadataV7',
18
- 'MetadataV8',
19
- 'MetadataV9',
20
- 'MetadataV10',
21
- 'MetadataV11'
22
- ]).decode(scale_bytes).value
8
+ if bytes.bytes_to_utf8 == "meta"
9
+ metadata_version = Scale::Types.type_of("Enum", %w[MetadataV0 MetadataV1 MetadataV2 MetadataV3 MetadataV4 MetadataV5 MetadataV6 MetadataV7 MetadataV8 MetadataV9 MetadataV10 MetadataV11]).decode(scale_bytes).value
23
10
  metadata = Metadata.new "Scale::Types::#{metadata_version}".constantize.decode(scale_bytes)
24
11
  metadata.version = metadata_version[9..].to_i
25
12
  else
@@ -30,6 +17,24 @@ module Scale
30
17
  end
31
18
  metadata
32
19
  end
20
+
21
+ def get_module(module_name)
22
+ modules = self.value.value[:metadata][:modules]
23
+ modules.each do |m|
24
+ if m[:name].downcase == module_name.downcase
25
+ return m
26
+ end
27
+ end
28
+ end
29
+
30
+ def get_module_call(module_name, call_name)
31
+ the_module = get_module(module_name)
32
+ the_module[:calls].each do |call|
33
+ if call[:name].downcase == call_name.downcase
34
+ return call
35
+ end
36
+ end
37
+ end
33
38
  end
34
39
 
35
40
  class MetadataModule
@@ -45,19 +50,19 @@ module Scale
45
50
 
46
51
  has_storage = Bool.decode(scale_bytes).value
47
52
  if has_storage
48
- storages = Scale::Types.type_of('Vec<MetadataModuleStorage>').decode(scale_bytes).value
53
+ storages = Scale::Types.type_of("Vec<MetadataModuleStorage>").decode(scale_bytes).value
49
54
  result[:storage] = storages.map(&:value)
50
55
  end
51
56
 
52
57
  has_calls = Bool.decode(scale_bytes).value
53
58
  if has_calls
54
- calls = Scale::Types.type_of('Vec<MetadataModuleCall>').decode(scale_bytes).value
59
+ calls = Scale::Types.type_of("Vec<MetadataModuleCall>").decode(scale_bytes).value
55
60
  result[:calls] = calls.map(&:value)
56
61
  end
57
62
 
58
63
  has_events = Bool.decode(scale_bytes).value
59
64
  if has_events
60
- events = Scale::Types.type_of('Vec<MetadataModuleEvent>').decode(scale_bytes).value
65
+ events = Scale::Types.type_of("Vec<MetadataModuleEvent>").decode(scale_bytes).value
61
66
  result[:events] = events.map(&:value)
62
67
  end
63
68
 
@@ -70,26 +75,26 @@ module Scale
70
75
  def self.decode(scale_bytes)
71
76
  result = {
72
77
  name: String.decode(scale_bytes).value,
73
- modifier: Scale::Types.type_of('Enum', %w[Optional Default]).decode(scale_bytes).value
78
+ modifier: Scale::Types.type_of("Enum", %w[Optional Default]).decode(scale_bytes).value
74
79
  }
75
80
 
76
81
  is_key_value = Bool.decode(scale_bytes).value
77
82
  result[:type] = if is_key_value
78
83
  {
79
84
  Map: {
80
- key: adjust(String.decode(scale_bytes).value),
81
- value: adjust(String.decode(scale_bytes).value),
85
+ key: rename(String.decode(scale_bytes).value),
86
+ value: rename(String.decode(scale_bytes).value),
82
87
  linked: Bool.decode(scale_bytes).value
83
88
  }
84
89
  }
85
90
  else
86
91
  {
87
- Plain: adjust(String.decode(scale_bytes).value)
92
+ Plain: rename(String.decode(scale_bytes).value)
88
93
  }
89
94
  end
90
95
 
91
96
  result[:fallback] = Hex.decode(scale_bytes).value
92
- result[:documentation] = Scale::Types.type_of('Vec<String>').decode(scale_bytes).value.map(&:value)
97
+ result[:documentation] = Scale::Types.type_of("Vec<String>").decode(scale_bytes).value.map(&:value)
93
98
 
94
99
  MetadataModuleStorage.new(result)
95
100
  end
@@ -100,8 +105,8 @@ module Scale
100
105
  def self.decode(scale_bytes)
101
106
  result = {}
102
107
  result[:name] = String.decode(scale_bytes).value
103
- result[:args] = Scale::Types.type_of('Vec<MetadataModuleCallArgument>').decode(scale_bytes).value.map(&:value)
104
- result[:documentation] = Scale::Types.type_of('Vec<String>').decode(scale_bytes).value.map(&:value)
108
+ result[:args] = Scale::Types.type_of("Vec<MetadataModuleCallArgument>").decode(scale_bytes).value.map(&:value)
109
+ result[:documentation] = Scale::Types.type_of("Vec<String>").decode(scale_bytes).value.map(&:value)
105
110
  MetadataModuleCall.new(result)
106
111
  end
107
112
  end
@@ -111,7 +116,7 @@ module Scale
111
116
  def self.decode(scale_bytes)
112
117
  result = {}
113
118
  result[:name] = String.decode(scale_bytes).value
114
- result[:type] = adjust(String.decode(scale_bytes).value)
119
+ result[:type] = rename(String.decode(scale_bytes).value)
115
120
 
116
121
  MetadataModuleCallArgument.new(result)
117
122
  end
@@ -122,8 +127,8 @@ module Scale
122
127
  def self.decode(scale_bytes)
123
128
  result = {}
124
129
  result[:name] = String.decode(scale_bytes).value
125
- result[:args] = Scale::Types.type_of('Vec<String>').decode(scale_bytes).value.map(&:value)
126
- result[:documentation] = Scale::Types.type_of('Vec<String>').decode(scale_bytes).value.map(&:value)
130
+ result[:args] = Scale::Types.type_of("Vec<String>").decode(scale_bytes).value.map(&:value)
131
+ result[:documentation] = Scale::Types.type_of("Vec<String>").decode(scale_bytes).value.map(&:value)
127
132
 
128
133
  MetadataModuleEvent.new(result)
129
134
  end
@@ -93,13 +93,13 @@ module Scale
93
93
  if is_key_value
94
94
  type = {
95
95
  MapType: {
96
- key: adjust(Bytes.decode(scale_bytes).value),
97
- value: adjust(Bytes.decode(scale_bytes).value)
96
+ key: rename(Bytes.decode(scale_bytes).value),
97
+ value: rename(Bytes.decode(scale_bytes).value)
98
98
  }
99
99
  }
100
100
  else
101
101
  type = {
102
- PlainType: adjust(Bytes.decode(scale_bytes).value)
102
+ PlainType: rename(Bytes.decode(scale_bytes).value)
103
103
  }
104
104
  end
105
105
 
@@ -92,14 +92,14 @@ module Scale
92
92
  storage_function_type = Scale::Types.type_of("Enum", %w[Plain Map DoubleMap]).decode(scale_bytes).value
93
93
  if storage_function_type == "Plain"
94
94
  result[:type] = {
95
- Plain: adjust(String.decode(scale_bytes).value)
95
+ Plain: rename(String.decode(scale_bytes).value)
96
96
  }
97
97
  elsif storage_function_type == "Map"
98
98
  result[:type] = {
99
99
  Map: {
100
100
  hasher: StorageHasher.decode(scale_bytes).value,
101
- key: adjust(String.decode(scale_bytes).value),
102
- value: adjust(String.decode(scale_bytes).value),
101
+ key: rename(String.decode(scale_bytes).value),
102
+ value: rename(String.decode(scale_bytes).value),
103
103
  linked: Bool.decode(scale_bytes).value
104
104
  }
105
105
  }
@@ -107,9 +107,9 @@ module Scale
107
107
  result[:type] = {
108
108
  DoubleMap: {
109
109
  hasher: StorageHasher.decode(scale_bytes).value,
110
- key1: adjust(String.decode(scale_bytes).value),
111
- key2: adjust(String.decode(scale_bytes).value),
112
- value: adjust(String.decode(scale_bytes).value),
110
+ key1: rename(String.decode(scale_bytes).value),
111
+ key2: rename(String.decode(scale_bytes).value),
112
+ value: rename(String.decode(scale_bytes).value),
113
113
  key2Hasher: StorageHasher.decode(scale_bytes).value
114
114
  }
115
115
  }
@@ -92,14 +92,14 @@ module Scale
92
92
  storage_function_type = Scale::Types.type_of("Enum", %w[Plain Map DoubleMap]).decode(scale_bytes).value
93
93
  if storage_function_type == "Plain"
94
94
  result[:type] = {
95
- Plain: adjust(String.decode(scale_bytes).value)
95
+ Plain: rename(String.decode(scale_bytes).value)
96
96
  }
97
97
  elsif storage_function_type == "Map"
98
98
  result[:type] = {
99
99
  Map: {
100
100
  hasher: StorageHasher.decode(scale_bytes).value,
101
- key: adjust(String.decode(scale_bytes).value),
102
- value: adjust(String.decode(scale_bytes).value),
101
+ key: rename(String.decode(scale_bytes).value),
102
+ value: rename(String.decode(scale_bytes).value),
103
103
  linked: Bool.decode(scale_bytes).value
104
104
  }
105
105
  }
@@ -107,9 +107,9 @@ module Scale
107
107
  result[:type] = {
108
108
  DoubleMap: {
109
109
  hasher: StorageHasher.decode(scale_bytes).value,
110
- key1: adjust(String.decode(scale_bytes).value),
111
- key2: adjust(String.decode(scale_bytes).value),
112
- value: adjust(String.decode(scale_bytes).value),
110
+ key1: rename(String.decode(scale_bytes).value),
111
+ key2: rename(String.decode(scale_bytes).value),
112
+ value: rename(String.decode(scale_bytes).value),
113
113
  key2Hasher: StorageHasher.decode(scale_bytes).value
114
114
  }
115
115
  }
@@ -106,14 +106,14 @@ module Scale
106
106
  storage_function_type = Scale::Types.type_of("Enum", %w[Plain Map DoubleMap]).decode(scale_bytes).value
107
107
  if storage_function_type == "Plain"
108
108
  result[:type] = {
109
- Plain: adjust(String.decode(scale_bytes).value)
109
+ Plain: rename(String.decode(scale_bytes).value)
110
110
  }
111
111
  elsif storage_function_type == "Map"
112
112
  result[:type] = {
113
113
  Map: {
114
114
  hasher: StorageHasher.decode(scale_bytes).value,
115
- key: adjust(String.decode(scale_bytes).value),
116
- value: adjust(String.decode(scale_bytes).value),
115
+ key: rename(String.decode(scale_bytes).value),
116
+ value: rename(String.decode(scale_bytes).value),
117
117
  linked: Bool.decode(scale_bytes).value
118
118
  }
119
119
  }
@@ -121,9 +121,9 @@ module Scale
121
121
  result[:type] = {
122
122
  DoubleMap: {
123
123
  hasher: StorageHasher.decode(scale_bytes).value,
124
- key1: adjust(String.decode(scale_bytes).value),
125
- key2: adjust(String.decode(scale_bytes).value),
126
- value: adjust(String.decode(scale_bytes).value),
124
+ key1: rename(String.decode(scale_bytes).value),
125
+ key2: rename(String.decode(scale_bytes).value),
126
+ value: rename(String.decode(scale_bytes).value),
127
127
  key2Hasher: StorageHasher.decode(scale_bytes).value
128
128
  }
129
129
  }
data/lib/scale/base.rb CHANGED
@@ -11,6 +11,28 @@ module Scale
11
11
  def ==(other)
12
12
  value == other.value
13
13
  end
14
+
15
+ def to_human
16
+ if @value.class == ::Hash
17
+ @value.transform_values do |v|
18
+ if v.class.included_modules.include?(SingleValue)
19
+ v.to_human
20
+ else
21
+ v
22
+ end
23
+ end
24
+ elsif @value.class == ::Array
25
+ @value.map do |v|
26
+ if v.class.included_modules.include?(SingleValue)
27
+ v.to_human
28
+ else
29
+ v
30
+ end
31
+ end
32
+ else
33
+ @value
34
+ end
35
+ end
14
36
  end
15
37
 
16
38
  # value: one of nil, false, true, scale object
@@ -67,9 +89,8 @@ module Scale
67
89
 
68
90
  module ClassMethods
69
91
  def decode(scale_bytes)
70
- bit_length = to_s[15..].to_i
71
- byte_length = bit_length / 8
72
- bytes = scale_bytes.get_next_bytes byte_length
92
+ bytes = scale_bytes.get_next_bytes self::BYTE_LENGTH
93
+ bit_length = bytes.length.to_i * 8
73
94
  value = bytes.reverse.bytes_to_hex.to_i(16).to_signed(bit_length)
74
95
  new(value)
75
96
  end
@@ -83,7 +104,7 @@ module Scale
83
104
  if value.class != ::Integer
84
105
  raise "#{self.class}'s value must be integer"
85
106
  end
86
- bit_length = self.class.name[15..].to_i
107
+ bit_length = self.class::BYTE_LENGTH * 8
87
108
  hex = value.to_unsigned(bit_length).to_s(16).hex_to_bytes.reverse.bytes_to_hex
88
109
  hex[2..]
89
110
  end
@@ -111,19 +132,20 @@ module Scale
111
132
  if value.class != ::Integer
112
133
  raise "#{self.class}'s value must be integer"
113
134
  end
114
- bytes = value.to_s(16).rjust(self.class::BYTE_LENGTH * 2, "0").scan(/.{2}/).reverse.map {|hex| hex.to_i(16) }
135
+ byte_length = self.class::BYTE_LENGTH
136
+ bytes = value.to_s(16).rjust(byte_length * 2, "0").scan(/.{2}/).reverse.map {|hex| hex.to_i(16) }
115
137
  bytes.bytes_to_hex[2..]
116
138
  end
117
139
  end
118
140
 
119
-
120
141
  module Struct
121
142
  include SingleValue
122
143
  # new(1.to_u32, U32(69))
123
144
  module ClassMethods
124
145
  def decode(scale_bytes)
125
146
  item_values = self::ITEM_TYPE_STRS.map do |item_type_str|
126
- Scale::Types.get(item_type_str).decode(scale_bytes)
147
+ type = Scale::TypeRegistry.instance.get(item_type_str)
148
+ type.decode(scale_bytes)
127
149
  end
128
150
 
129
151
  value = {}
@@ -197,7 +219,7 @@ module Scale
197
219
  module ClassMethods
198
220
  def decode(scale_bytes)
199
221
  index = scale_bytes.get_next_bytes(1)[0]
200
- if const_defined? "ITEM_NAMES"
222
+ if const_defined? "ITEM_TYPE_STRS"
201
223
  item_type_str = self::ITEM_TYPE_STRS[index]
202
224
  raise "There is no such member with index #{index} for enum #{self}" if item_type_str.nil?
203
225
  value = Scale::Types.get(item_type_str).decode(scale_bytes)
@@ -208,16 +230,20 @@ module Scale
208
230
  end
209
231
 
210
232
  def items(items)
211
- attr_names = []
212
- attr_type_strs = []
233
+ if items.class == ::Hash
234
+ attr_names = []
235
+ attr_type_strs = []
213
236
 
214
- items.each_pair do |attr_name, attr_type_str|
215
- attr_names << attr_name
216
- attr_type_strs << attr_type_str
217
- end
237
+ items.each_pair do |attr_name, attr_type_str|
238
+ attr_names << attr_name
239
+ attr_type_strs << attr_type_str
240
+ end
218
241
 
219
- const_set(:ITEM_NAMES, attr_names)
220
- const_set(:ITEM_TYPE_STRS, attr_type_strs)
242
+ const_set(:ITEM_NAMES, attr_names)
243
+ const_set(:ITEM_TYPE_STRS, attr_type_strs)
244
+ elsif items.class == ::Array
245
+ const_set(:ITEM_TYPE_STRS, items)
246
+ end
221
247
  end
222
248
 
223
249
  def values(*values)
@@ -238,6 +264,14 @@ module Scale
238
264
  self.class::VALUES.index(value).to_s(16).rjust(2, "0")
239
265
  end
240
266
  end
267
+
268
+ def to_human
269
+ if self.class.const_defined? "ITEM_TYPE_STRS"
270
+ @value.to_human
271
+ else
272
+ @value
273
+ end
274
+ end
241
275
  end
242
276
 
243
277
  module Vec
@@ -248,7 +282,8 @@ module Scale
248
282
  number = Scale::Types::Compact.decode(scale_bytes).value
249
283
  items = []
250
284
  number.times do
251
- item = Scale::Types.get(self::INNER_TYPE_STR).decode(scale_bytes)
285
+ type = Scale::Types.get(self::INNER_TYPE_STR)
286
+ item = type.decode(scale_bytes)
252
287
  items << item
253
288
  end
254
289
  raw ? items : new(items)
@@ -278,7 +313,7 @@ module Scale
278
313
 
279
314
  module ClassMethods
280
315
  def decode(scale_bytes)
281
- value = "Scale::Types::U#{self::BYTES_LENGTH * 8}".constantize.decode(scale_bytes).value
316
+ value = "Scale::Types::U#{self::BYTE_LENGTH * 8}".constantize.decode(scale_bytes).value
282
317
  return new [] unless value || value <= 0
283
318
 
284
319
  result = self::ITEMS.select { |_, mask| value & mask > 0 }.keys
@@ -295,7 +330,7 @@ module Scale
295
330
  def items(items, bytes_length = 1)
296
331
  raise "byte length is wrong: #{bytes_length}" unless [1, 2, 4, 8, 16].include?(bytes_length)
297
332
  const_set(:ITEMS, items)
298
- const_set(:BYTES_LENGTH, bytes_length)
333
+ const_set(:BYTE_LENGTH, bytes_length)
299
334
  end
300
335
  end
301
336
 
@@ -305,7 +340,7 @@ module Scale
305
340
 
306
341
  def encode
307
342
  value = self.class::ITEMS.select { |key, _| self.value.include?(key) }.values.sum
308
- "Scale::Types::U#{self.class::BYTES_LENGTH * 8}".constantize.new(value).encode
343
+ "Scale::Types::U#{self.class::BYTE_LENGTH * 8}".constantize.new(value).encode
309
344
  end
310
345
  end
311
346
 
data/lib/scale/block.rb CHANGED
@@ -9,7 +9,8 @@ module Scale
9
9
  Blake2b.hex data, Blake2b::Key.none, 32
10
10
  end
11
11
 
12
- def self.decode(scale_bytes, metadata)
12
+ def self.decode(scale_bytes)
13
+ metadata = Scale::TypeRegistry.instance.metadata
13
14
  result = {}
14
15
 
15
16
  extrinsic_length = Compact.decode(scale_bytes).value
@@ -83,11 +84,11 @@ module Scale
83
84
  result[:call_index] = scale_bytes.get_next_bytes(2).bytes_to_hex[2..]
84
85
 
85
86
  else
86
- raise "Extrinsics version #{version_info} is not implemented"
87
+ raise "Extrinsic version #{version_info} is not implemented"
87
88
  end
88
89
 
89
90
  if result[:call_index]
90
- call_module, call = metadata.value.call_index[result[:call_index]]
91
+ call_module, call = metadata.call_index[result[:call_index]]
91
92
 
92
93
  result[:call_function] = call[:name].downcase
93
94
  result[:call_module] = call_module[:name].downcase
@@ -97,7 +98,7 @@ module Scale
97
98
  result[:params] = call[:args].map do |arg|
98
99
  type = Scale::Types.get(arg[:type])
99
100
  arg_obj = type.decode(scale_bytes)
100
- {name: arg[:name], type: type.name, value: arg_obj.value, value_raw: "0x#{arg_obj.encode}" }
101
+ {name: arg[:name], type: arg[:type], scale_type: type, value: arg_obj.value }
101
102
  end
102
103
  end
103
104
 
@@ -107,24 +108,24 @@ module Scale
107
108
  Extrinsic.new result
108
109
  end
109
110
 
110
- def encode(metadata)
111
- puts metadata.value.value["modules"]
111
+ def encode
112
112
  result = "04" + self.value[:call_index]
113
113
 
114
- result = result +
115
- self.value[:params].map do |param|
116
- param[:type].constantize.new(param[:value]).encode
117
- end.join
114
+ result += self.value[:params].map do |param|
115
+ Scale::Types.get(param[:type]).new(param[:value]).encode
116
+ end.join
118
117
 
119
- result = "0x" + Compact.new(result.length / 2).encode + result
120
- return result
118
+ "0x" + Compact.new(result.length / 2).encode + result
119
+ end
120
+
121
+ def to_human
122
+ @value
121
123
  end
122
124
  end
123
125
 
124
126
  class EventRecord
125
127
  include SingleValue
126
128
 
127
- # 0x0c000000000000001027000001010000010000000400be07e2c28688db5368445c33d32b3c7bcad15dab1ec802ba8cccc1c22b86574f6992da89ff412eaf9bafac4024
128
129
  def self.decode(scale_bytes)
129
130
  metadata = Scale::TypeRegistry.instance.metadata
130
131
 
@@ -137,22 +138,72 @@ module Scale
137
138
 
138
139
  type = scale_bytes.get_next_bytes(2).bytes_to_hex[2..]
139
140
  event = metadata.event_index[type][1]
140
- mod = metadata.event_index[type][0]
141
+ # mod = metadata.event_index[type][0]
141
142
 
142
143
  result[:params] = []
143
144
  event[:args].each do |arg_type|
144
- value = Scale::Types.get(arg_type).decode(scale_bytes).value
145
+ value = Scale::Types.get(arg_type).decode(scale_bytes).to_human
145
146
  result[:params] << {
147
+ name: event[:name],
146
148
  type: arg_type,
147
149
  value: value
148
150
  }
149
151
  end
150
152
 
151
- result[:topics] = Scale::Types.get('Vec<Hash>').decode(scale_bytes).value.map(&:value)
153
+ result[:topics] = Scale::Types.get("Vec<Hash>").decode(scale_bytes).value.map(&:value)
152
154
 
153
155
  EventRecord.new(result)
154
156
  end
155
157
  end
156
158
 
159
+ # log
160
+ class Other < Bytes; end
161
+
162
+ class AuthoritiesChange
163
+ include Vec
164
+ inner_type "AccountId"
165
+ end
166
+
167
+ class ConsensusEngineId < VecU8Length4; end
168
+
169
+ class ChangesTrieRoot < Bytes; end
170
+
171
+ class SealV0
172
+ include Struct
173
+ items(
174
+ slot: "U64",
175
+ signature: "Signature"
176
+ )
177
+ end
178
+
179
+ class Consensus
180
+ include Struct
181
+ items(
182
+ engine: "ConsensusEngineId",
183
+ data: "Hex"
184
+ )
185
+ end
186
+
187
+ class Seal
188
+ include Struct
189
+ items(
190
+ engine: "ConsensusEngineId",
191
+ data: "Hex"
192
+ )
193
+ end
194
+
195
+ class PreRuntime
196
+ include Struct
197
+ items(
198
+ engine: "ConsensusEngineId",
199
+ data: "Hex"
200
+ )
201
+ end
202
+
203
+ class LogDigest
204
+ include Enum
205
+ items %w[Other AuthoritiesChange ChangesTrieRoot SealV0 Consensus Seal PreRuntime]
206
+ end
207
+
157
208
  end
158
209
  end
data/lib/scale/types.rb CHANGED
@@ -46,24 +46,34 @@ module Scale
46
46
  BYTE_LENGTH = 16
47
47
  end
48
48
 
49
+ class U256
50
+ include FixedWidthUInt
51
+ BYTE_LENGTH = 32
52
+ end
53
+
49
54
  class I8
50
55
  include FixedWidthInt
56
+ BYTE_LENGTH = 1
51
57
  end
52
58
 
53
59
  class I16
54
60
  include FixedWidthInt
61
+ BYTE_LENGTH = 2
55
62
  end
56
63
 
57
64
  class I32
58
65
  include FixedWidthInt
66
+ BYTE_LENGTH = 4
59
67
  end
60
68
 
61
69
  class I64
62
70
  include FixedWidthInt
71
+ BYTE_LENGTH = 8
63
72
  end
64
73
 
65
74
  class I128
66
75
  include FixedWidthInt
76
+ BYTE_LENGTH = 16
67
77
  end
68
78
 
69
79
  class Compact
@@ -303,7 +313,7 @@ module Scale
303
313
  value /= 1000
304
314
  end
305
315
 
306
- CompactMoment.new Time.at(seconds_since_epoch_integer).to_datetime
316
+ CompactMoment.new Time.at(value).to_datetime.strftime("%F %T")
307
317
  end
308
318
  end
309
319
 
@@ -791,5 +801,19 @@ module Scale
791
801
  )
792
802
  end
793
803
 
804
+ class VecH512Length2
805
+ include SingleValue
806
+
807
+ def self.decode(scale_bytes)
808
+ end
809
+
810
+ def encode
811
+ "0x" + self.value.map do |item|
812
+ item[2..]
813
+ end.join
814
+ end
815
+ end
816
+
817
+
794
818
  end
795
819
  end
data/lib/scale/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Scale
2
- VERSION = "0.2.4".freeze
2
+ VERSION = "0.2.5".freeze
3
3
  end
data/lib/scale.rb CHANGED
@@ -29,89 +29,65 @@ module Scale
29
29
 
30
30
  class TypeRegistry
31
31
  include Singleton
32
- attr_accessor :types, :metadata
32
+ attr_accessor :types, :versioning
33
+ attr_accessor :spec_version, :metadata
34
+ attr_accessor :custom_types
33
35
 
34
- def load(spec_name = nil, spec_version = nil)
35
- @spec_name = spec_name
36
- @spec_version = spec_version
37
- @types = load_types(spec_name, spec_version.nil? ? nil : spec_version.to_i)
36
+ def load(spec_name = nil, custom_types = nil)
37
+ default_types, _ = load_chain_spec_types("default")
38
38
 
39
+ if spec_name.nil? || spec_name == "default"
40
+ @types = default_types
41
+ else
42
+ spec_types, @versioning = load_chain_spec_types(spec_name)
43
+ @types = default_types.merge(spec_types)
44
+ end
45
+
46
+ @custom_types = custom_types.stringify_keys if custom_types.nil? && custom_types.class.name == "Hash"
39
47
  true
40
48
  end
41
49
 
42
50
  def get(type_name)
43
- type = @types[type_name]
44
- return Scale::Types.type_of(type_name) if type.nil?
45
- type
46
- end
51
+ raise "Types not loaded" if @types.nil?
47
52
 
48
- private
49
- def load_types(spec_name, spec_version)
50
- # hard coded types
51
- coded_types = Scale::Types
52
- .constants
53
- .select { |c| Scale::Types.const_get(c).is_a? Class }
54
- .map { |type_name| [type_name.to_s, type_name.to_s] }
55
- .to_h
56
- .transform_values {|type| Scale::Types.constantize(type) }
57
-
58
- return coded_types if spec_name.nil?
59
-
60
- # default spec types
61
- default_types = load_chain_spec_types("default", spec_version).transform_values do |type|
62
- Scale::Types.type_convert(type, coded_types)
63
- end
64
- default_types = coded_types.merge(default_types)
53
+ all_types = {}.merge(@types)
65
54
 
66
- # chain spec types
67
- if spec_name != "default"
68
- spec_types = load_chain_spec_types(spec_name, spec_version)
69
- spec_types.transform_values do |type|
70
- Scale::Types.type_convert(type, default_types)
55
+ if @spec_version && @versioning
56
+ @versioning.each do |item|
57
+ if @spec_version >= item["runtime_range"][0] && @spec_version <= (item["runtime_range"][1] || 1073741823)
58
+ all_types.merge!(item["types"])
59
+ end
71
60
  end
72
- default_types.merge(spec_types)
73
- else
74
- default_types
75
61
  end
62
+
63
+ all_types.merge!(@custom_types) if @custom_types
64
+
65
+ type = type_traverse(type_name, all_types)
66
+
67
+ Scale::Types.constantize(type)
76
68
  end
77
69
 
78
- def load_chain_spec_types(spec_name, spec_version)
70
+ def load_chain_spec_types(spec_name)
79
71
  file = File.join File.expand_path("../..", __FILE__), "lib", "type_registry", "#{spec_name}.json"
80
72
  json_string = File.open(file).read
81
73
  json = JSON.parse(json_string)
82
74
 
83
- types = {}
84
75
  runtime_id = json["runtime_id"]
85
- versioning = json["versioning"] || []
86
-
87
- if runtime_id.nil? || (spec_version && spec_version >= runtime_id)
88
- types = json["types"]
89
- end
90
76
 
91
- if spec_version
92
- versioning.each do |item|
93
- if spec_version >= item["runtime_range"][0] && spec_version <= (item["runtime_range"][1] || 1073741823)
94
- types.merge!(item["types"])
95
- end
96
- end
97
- end
77
+ [json["types"], json["versioning"]]
78
+ end
98
79
 
99
- types.transform_values! do |type|
100
- if type.class != ::String
101
- Scale::Types.constantize(type)
80
+ def type_traverse(type, types)
81
+ if types.has_key?(type)
82
+ type_traverse(types[type], types)
83
+ else
84
+ if type.class == ::String
85
+ rename(type)
102
86
  else
103
- t = Scale::Types.type_convert(type, types)
104
- if t.class == ::String
105
- Scale::Types.constantize(t)
106
- else
107
- t
108
- end
87
+ type
109
88
  end
110
89
  end
111
-
112
- types
113
90
  end
114
-
115
91
  end
116
92
 
117
93
  # TODO: == implement
@@ -227,7 +203,6 @@ module Scale
227
203
  end
228
204
 
229
205
  def self.get(type_name)
230
- type_name = adjust(type_name)
231
206
  TypeRegistry.instance.get(type_name)
232
207
  end
233
208
 
@@ -247,19 +222,6 @@ module Scale
247
222
  end
248
223
  end
249
224
 
250
- def self.type_convert(type, types)
251
- return type if type.class != ::String
252
-
253
- if type =~ /\[u\d+; \d+\]/
254
- byte_length = type.scan(/\[u\d+; (\d+)\]/).first.first
255
- "VecU8Length#{byte_length}"
256
- elsif types.has_key?(type) && types[type] != type
257
- type_convert(types[type], types)
258
- else
259
- adjust(type)
260
- end
261
- end
262
-
263
225
  def self.type_of(type_string, values = nil)
264
226
  if type_string.end_with?(">")
265
227
  type_strs = type_string.scan(/^([^<]*)<(.+)>$/).first
@@ -274,7 +236,7 @@ module Scale
274
236
  name = "#{type_str}_Of_#{inner_type_str.camelize}_#{klass.object_id}"
275
237
  Scale::Types.const_set fix(name), klass
276
238
  else
277
- raise "#{type_str} not support inner type"
239
+ raise "#{type_str} not support inner type: #{type_string}"
278
240
  end
279
241
  elsif type_string.start_with?("(") && type_string.end_with?(")") # tuple
280
242
  # TODO: add nested tuple support
@@ -345,13 +307,14 @@ def fix(name)
345
307
  .gsub(":", "։")
346
308
  end
347
309
 
348
- def adjust(type)
310
+ def rename(type)
349
311
  type = type.gsub("T::", "")
350
312
  .gsub("<T>", "")
351
313
  .gsub("<T as Trait>::", "")
352
314
  .delete("\n")
353
315
  .gsub("EventRecord<Event, Hash>", "EventRecord")
354
316
  .gsub(/(u)(\d+)/, 'U\2')
317
+ return "Bool" if type == "bool"
355
318
  return "Null" if type == "()"
356
319
  return "String" if type == "Vec<u8>"
357
320
  return "Compact" if type == "Compact<u32>" || type == "Compact<U32>"
@@ -361,8 +324,15 @@ def adjust(type)
361
324
  return "Compact" if type == "<BlockNumber as HasCompact>::Type"
362
325
  return "Compact" if type == "Compact<Balance>"
363
326
  return "CompactMoment" if type == "<Moment as HasCompact>::Type"
327
+ return "CompactMoment" if type == "Compact<Moment>"
364
328
  return "InherentOfflineReport" if type == "<InherentOfflineReport as InherentOfflineReport>::Inherent"
365
329
  return "AccountData" if type == "AccountData<Balance>"
330
+
331
+ if type =~ /\[U\d+; \d+\]/
332
+ byte_length = type.scan(/\[U\d+; (\d+)\]/).first.first
333
+ return "VecU8Length#{byte_length}"
334
+ end
335
+
366
336
  type
367
337
  end
368
338
 
@@ -395,3 +365,19 @@ class Integer
395
365
  self
396
366
  end
397
367
  end
368
+
369
+ class ::Hash
370
+ # via https://stackoverflow.com/a/25835016/2257038
371
+ def stringify_keys
372
+ h = self.map do |k,v|
373
+ v_str = if v.instance_of? Hash
374
+ v.stringify_keys
375
+ else
376
+ v
377
+ end
378
+
379
+ [k.to_s, v_str]
380
+ end
381
+ Hash[h]
382
+ end
383
+ end
@@ -107,6 +107,13 @@
107
107
  ["ktoner", "TokenBalance"],
108
108
  ["lottery", "TokenBalance"]
109
109
  ]
110
+ },
111
+ "DoubleNodeWithMerkleProof": {
112
+ "type": "struct",
113
+ "type_mapping": [
114
+ ["dag_nodes", "VecH512Length2"],
115
+ ["proof", "Vec<H128>"]
116
+ ]
110
117
  }
111
118
  }
112
119
  }
@@ -35,13 +35,6 @@
35
35
  ["balance", "Balance"]
36
36
  ]
37
37
  },
38
- "ReferendumInfo<BlockNumber, Hash, Balance>": {
39
- "type": "enum",
40
- "type_mapping": [
41
- ["Ongoing", "ReferendumStatus"],
42
- ["Finished", "ReferendumInfoFinished"]
43
- ]
44
- },
45
38
  "ReferendumInfoFinished": {
46
39
  "type": "struct",
47
40
  "type_mapping": [
@@ -67,6 +60,13 @@
67
60
  ["tally", "Tally"]
68
61
  ]
69
62
  },
63
+ "ReferendumInfo": {
64
+ "type": "enum",
65
+ "type_mapping": [
66
+ ["Ongoing", "ReferendumStatus"],
67
+ ["Finished", "ReferendumInfoFinished"]
68
+ ]
69
+ },
70
70
  "VotingDirectVote": {
71
71
  "type": "struct",
72
72
  "type_mapping": [
@@ -247,7 +247,8 @@
247
247
  "type": "enum",
248
248
  "value_list": [
249
249
  "Normal",
250
- "Operational"
250
+ "Operational",
251
+ "Mandatory"
251
252
  ]
252
253
  },
253
254
  "DispatchInfo": {
@@ -338,6 +339,7 @@
338
339
  "MomentOf": "Moment",
339
340
  "MoreAttestations": "Null",
340
341
  "Multiplier": "u64",
342
+ "CallHash": "H256",
341
343
  "Timepoint": {
342
344
  "type": "struct",
343
345
  "type_mapping": [
@@ -364,7 +366,7 @@
364
366
  "PhantomData": "Null",
365
367
  "sp_std::marker::PhantomData<(AccountId, Event)>": "PhantomData",
366
368
  "Reporter": "AccountId",
367
- "OffenceDetails<AccountId, IdentificationTuple>": {
369
+ "OffenceDetails": {
368
370
  "type": "struct",
369
371
  "type_mapping": [
370
372
  ["offender", "Offender"],
@@ -543,17 +545,6 @@
543
545
  ]
544
546
  },
545
547
  "WinningData": "Vec<WinningDataEntry>",
546
- "WithdrawReasons": {
547
- "type": "set",
548
- "value_type": "u64",
549
- "value_list": {
550
- "TransactionPayment": 1,
551
- "Transfer": 2,
552
- "Reserve": 4,
553
- "Fee": 8,
554
- "Tip": 16
555
- }
556
- },
557
548
  "Index": "U32",
558
549
  "Kind": "[u8; 16]",
559
550
  "Nominations": {
@@ -583,7 +574,8 @@
583
574
  ["blockNumber", "BlockNumber"],
584
575
  ["networkState", "OpaqueNetworkState"],
585
576
  ["sessionIndex", "SessionIndex"],
586
- ["authorityIndex", "AuthIndex"]
577
+ ["authorityIndex", "AuthIndex"],
578
+ ["validatorsLen", "u32"]
587
579
  ]
588
580
  },
589
581
  "RewardDestination": {
@@ -837,6 +829,164 @@
837
829
  ["perBlock", "Balance"],
838
830
  ["startingBlock", "BlockNumber"]
839
831
  ]
832
+ },
833
+ "NominatorIndex": "u32",
834
+ "ValidatorIndex": "u16",
835
+ "PerU16": "u16",
836
+ "OffchainAccuracy": "PerU16",
837
+ "CompactScore": {
838
+ "type": "struct",
839
+ "type_mapping": [
840
+ ["validatorIndex", "ValidatorIndex"],
841
+ ["offchainAccuracy", "OffchainAccuracy"]
842
+ ]
843
+ },
844
+ "CompactAssignments": {
845
+ "type": "struct",
846
+ "type_mapping": [
847
+ ["votes1", "Vec<(NominatorIndex, ValidatorIndex)>"],
848
+ ["votes2", "Vec<(NominatorIndex, [CompactScore; 1], ValidatorIndex)>"],
849
+ ["votes3", "Vec<(NominatorIndex, [CompactScore; 2], ValidatorIndex)>"],
850
+ ["votes4", "Vec<(NominatorIndex, [CompactScore; 3], ValidatorIndex)>"],
851
+ ["votes5", "Vec<(NominatorIndex, [CompactScore; 4], ValidatorIndex)>"],
852
+ ["votes6", "Vec<(NominatorIndex, [CompactScore; 5], ValidatorIndex)>"],
853
+ ["votes7", "Vec<(NominatorIndex, [CompactScore; 6], ValidatorIndex)>"],
854
+ ["votes8", "Vec<(NominatorIndex, [CompactScore; 7], ValidatorIndex)>"],
855
+ ["votes9", "Vec<(NominatorIndex, [CompactScore; 8], ValidatorIndex)>"],
856
+ ["votes10", "Vec<(NominatorIndex, [CompactScore; 9], ValidatorIndex)>"],
857
+ ["votes11", "Vec<(NominatorIndex, [CompactScore; 10], ValidatorIndex)>"],
858
+ ["votes12", "Vec<(NominatorIndex, [CompactScore; 11], ValidatorIndex)>"],
859
+ ["votes13", "Vec<(NominatorIndex, [CompactScore; 12], ValidatorIndex)>"],
860
+ ["votes14", "Vec<(NominatorIndex, [CompactScore; 13], ValidatorIndex)>"],
861
+ ["votes15", "Vec<(NominatorIndex, [CompactScore; 14], ValidatorIndex)>"],
862
+ ["votes16", "Vec<(NominatorIndex, [CompactScore; 15], ValidatorIndex)>"]
863
+ ]
864
+ },
865
+ "DeferredOffenceOf": {
866
+ "type": "struct",
867
+ "type_mapping": [
868
+ ["offences", "Vec<OffenceDetails>"],
869
+ ["perc", "Vec<Perbill>"],
870
+ ["session", "SessionIndex"]
871
+ ]
872
+ },
873
+ "Statement": {
874
+ "type": "enum",
875
+ "type_mapping": [
876
+ ["Never", "Null"],
877
+ ["Candidate", "Hash"],
878
+ ["Valid", "Hash"],
879
+ ["Invalid", "Hash"]
880
+ ]
881
+ },
882
+ "ValidatorSignature": "Signature",
883
+ "DoubleVoteReportStatement": {
884
+ "type": "struct",
885
+ "type_mapping": [
886
+ ["statement", "Statement"],
887
+ ["signature", "ValidatorSignature"]
888
+ ]
889
+ },
890
+ "DoubleVoteReportProof": {
891
+ "type": "struct",
892
+ "type_mapping": [
893
+ ["session", "SessionIndex"],
894
+ ["trieNodes", "Vec<Bytes>"]
895
+ ]
896
+ },
897
+ "SigningContext": {
898
+ "type": "struct",
899
+ "type_mapping": [
900
+ ["sessionIndex", "SessionIndex"],
901
+ ["parentHash", "Hash"]
902
+ ]
903
+ },
904
+ "DoubleVoteReport": {
905
+ "type": "struct",
906
+ "type_mapping": [
907
+ ["identity", "ValidatorId"],
908
+ ["first", "DoubleVoteReportStatement"],
909
+ ["second", "DoubleVoteReportStatement"],
910
+ ["proof", "DoubleVoteReportProof"],
911
+ ["signingContext", "SigningContext"]
912
+ ]
913
+ },
914
+ "ElectionCompute": {
915
+ "type": "enum",
916
+ "value_list": [
917
+ "OnChain",
918
+ "Signed",
919
+ "Authority"
920
+ ]
921
+ },
922
+ "ElectionResult": {
923
+ "type": "struct",
924
+ "type_mapping": [
925
+ ["compute", "ElectionCompute"],
926
+ ["slotStake", "Balance"],
927
+ ["electedStashes", "Vec<AccountId>"],
928
+ ["exposures", "Vec<(AccountId, Exposure)>"]
929
+ ]
930
+ },
931
+ "ElectionStatus": {
932
+ "type": "enum",
933
+ "type_mapping": [
934
+ ["Close", "Null"],
935
+ ["Open", "BlockNumber"]
936
+ ]
937
+ },
938
+ "Phase": {
939
+ "type": "enum",
940
+ "type_mapping": [
941
+ ["ApplyExtrinsic", "u32"],
942
+ ["Finalization", "Null"],
943
+ ["Initialization", "Null"]
944
+ ]
945
+ },
946
+ "PhragmenScore": "[u128; 3]",
947
+ "PreimageStatusAvailable": {
948
+ "type": "struct",
949
+ "type_mapping": [
950
+ ["data", "Bytes"],
951
+ ["provider", "AccountId"],
952
+ ["deposit", "Balance"],
953
+ ["since", "BlockNumber"],
954
+ ["expiry", "Option<BlockNumber>"]
955
+ ]
956
+ },
957
+ "PreimageStatus": {
958
+ "type": "enum",
959
+ "type_mapping": [
960
+ ["Missing", "BlockNumber"],
961
+ ["Available", "PreimageStatusAvailable"]
962
+ ]
963
+ },
964
+ "Randomness": "Hash",
965
+ "MaybeRandomness": "Option<Randomness>",
966
+ "schnorrkel::Randomness": "Hash",
967
+ "schnorrkel::RawVRFOutput": "[u8; 32]",
968
+ "TaskAddress": {
969
+ "type": "struct",
970
+ "type_mapping": [
971
+ ["blockNumber", "BlockNumber"],
972
+ ["index", "u32"]
973
+ ]
974
+ },
975
+ "ValidationCode": "Bytes",
976
+ "ParaPastCodeMeta": {
977
+ "type": "struct",
978
+ "type_mapping": [
979
+ ["upgrade_times", "Vec<BlockNumber>"],
980
+ ["last_pruned", "Option<BlockNumber>"]
981
+ ]
982
+ },
983
+ "ModuleId": "LockIdentifier",
984
+ "RuntimeDbWeight": {
985
+ "type": "struct",
986
+ "type_mapping": [
987
+ ["read", "Weight"],
988
+ ["write", "Weight"]
989
+ ]
840
990
  }
841
991
  }
842
992
  }
@@ -1,6 +1,6 @@
1
1
  {
2
- "runtime_id": 2,
2
+ "runtime_id": 3,
3
3
  "types": {
4
- "Weight": "u16"
4
+ "Weight": "u64"
5
5
  }
6
6
  }
@@ -1,9 +1,10 @@
1
1
  {
2
- "runtime_id": 1054,
2
+ "runtime_id": 1062,
3
3
  "types": {
4
4
  "Address": "AccountIdAddress",
5
5
  "BlockNumber": "U32",
6
6
  "LeasePeriod": "BlockNumber",
7
+ "Weight": "u64",
7
8
  "SessionKeysPolkadot": {
8
9
  "type": "struct",
9
10
  "type_mapping": [
@@ -180,7 +181,47 @@
180
181
  ]
181
182
  }
182
183
  }
184
+ },
185
+ {
186
+ "runtime_range": [1019, 1056],
187
+ "types": {
188
+ "Weight": "u32"
189
+ }
190
+ },
191
+ {
192
+ "runtime_range": [1057, null],
193
+ "types": {
194
+ "Weight": "u64"
195
+ }
196
+ },
197
+ {
198
+ "runtime_range": [1019, 1058],
199
+ "types": {
200
+ "Heartbeat": {
201
+ "type": "struct",
202
+ "type_mapping": [
203
+ ["blockNumber", "BlockNumber"],
204
+ ["networkState", "OpaqueNetworkState"],
205
+ ["sessionIndex", "SessionIndex"],
206
+ ["authorityIndex", "AuthIndex"]
207
+ ]
208
+ }
209
+ }
210
+ },
211
+ {
212
+ "runtime_range": [1062, null],
213
+ "types": {
214
+ "Heartbeat": {
215
+ "type": "struct",
216
+ "type_mapping": [
217
+ ["blockNumber", "BlockNumber"],
218
+ ["networkState", "OpaqueNetworkState"],
219
+ ["sessionIndex", "SessionIndex"],
220
+ ["authorityIndex", "AuthIndex"],
221
+ ["validatorsLen", "u32"]
222
+ ]
223
+ }
224
+ }
183
225
  }
184
-
185
226
  ]
186
227
  }
@@ -1,6 +1,7 @@
1
1
  {
2
- "runtime_id": 1000,
2
+ "runtime_id": 1006,
3
3
  "types": {
4
+ "Address": "AccountIdAddress",
4
5
  "BlockNumber": "U32",
5
6
  "LeasePeriod": "BlockNumber",
6
7
  "SessionKeysPolkadot": {
@@ -0,0 +1,34 @@
1
+ require "scale"
2
+
3
+
4
+ client = SubstrateClient.new("ws://127.0.0.1:9944/")
5
+ client.init
6
+ metadata = client.get_metadata nil
7
+
8
+ the_module = metadata.get_module("CertificateModule")
9
+ puts ""
10
+ puts "CertificateModule calls:"
11
+ puts "---------------------------------------"
12
+ puts the_module[:calls]
13
+
14
+ the_call = metadata.get_module_call("CertificateModule", "create_entity")
15
+ puts ""
16
+ puts "create_entity call:"
17
+ puts "---------------------------------------"
18
+ puts the_call
19
+
20
+
21
+ puts ""
22
+ puts "CertificateModule storages:"
23
+ puts "---------------------------------------"
24
+ puts the_module[:storage][:items]
25
+
26
+ # Scale::TypeRegistry.instance.metadata = metadata.value
27
+ # puts metadata.value.event_index["0400"][1]
28
+ # puts metadata.value.event_index["0401"][1]
29
+ # puts metadata.value.event_index["0402"][1]
30
+ # hex_events = "0x0c000000000000001027000001010000010000000400be07e2c28688db5368445c33d32b3c7bcad15dab1ec802ba8cccc1c22b86574f6992da89ff412eaf9bafac4024ca23eea8c988a437fc96a1c6445148a8ebb4d2000001000000000010270000000100"
31
+ # scale_bytes = Scale::Bytes.new(hex_events)
32
+ # Scale::Types.get("Vec<EventRecord>").decode(scale_bytes).value.each do |er|
33
+ # puts er.value
34
+ # end
@@ -0,0 +1,4 @@
1
+ require "scale"
2
+
3
+ client = SubstrateClient.new("wss://kusama-rpc.polkadot.io/")
4
+ client.init
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scale.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wu Minzhe
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-15 00:00:00.000000000 Z
11
+ date: 2020-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: substrate_common.rb
@@ -189,6 +189,8 @@ files:
189
189
  - lib/type_registry/test.json
190
190
  - lib/type_registry/westend.json
191
191
  - scale.gemspec
192
+ - scripts/block_events.rb
193
+ - scripts/example.rb
192
194
  - src/lib.rs
193
195
  homepage: https://github.com/itering/scale.rb
194
196
  licenses: