Class: TonSdkRuby::Slice

Inherits:
Object
  • Object
show all
Extended by:
TonSdkRuby
Includes:
TonSdkRuby
Defined in:
lib/ton-sdk-ruby/boc/slice.rb

Constant Summary

Constants included from TonSdkRuby

DEPTH_BITS, FLAG_BOUNCEABLE, FLAG_NON_BOUNCEABLE, FLAG_TEST_ONLY, HASH_BITS, INT32_MAX, INT32_MIN, LEAN_BOC_MAGIC_PREFIX, LEAN_BOC_MAGIC_PREFIX_CRC, REACH_BOC_MAGIC_PREFIX, VERSION

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TonSdkRuby

augment, base64_to_bytes, bits_to_big_int, bits_to_big_uint, bits_to_bytes, bits_to_hex, bits_to_int_uint, breadth_first_sort, bytes_compare, bytes_needed_for_words_bip39, bytes_to_base64, bytes_to_bits, bytes_to_data_string, bytes_to_hex, bytes_to_string, bytes_to_uint, crc16, crc16_bytes_be, crc32c, crc32c_bytes_le, depth_first_sort, deserialize, deserialize_cell, deserialize_fift, deserialize_header, generate_words_bip39, get_mapper, hex_to_bits, hex_to_bytes, hex_to_data_string, read_json_from_link, read_post_json_from_link, require_type, rollback, serialize, serialize_cell, sha256, sha512, sign_cell, slice_into_chunks, string_to_bytes, uint_to_hex, validate_library_reference, validate_merkle_proof, validate_merkle_update, validate_ordinary, validate_pruned_branch

Constructor Details

#initialize(bits, refs) ⇒ Slice

Returns a new instance of Slice.



7
8
9
10
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 7

def initialize(bits, refs)
  @bits = bits
  @refs = refs
end

Class Method Details

.parse(cell) ⇒ Object



335
336
337
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 335

def self.parse(cell)
  Slice.new(cell.bits.dup, cell.refs.dup)
end

Instance Method Details

#bitsObject



12
13
14
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 12

def bits
  Array.new(@bits)
end

#load_addressObject



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 241

def load_address
  flag_address_no = [0, 0]
  flag_address = [1, 0]
  flag = preload_bits(2)

  if flag == flag_address_no
    skip(2)
    Address::NONE
  elsif flag == flag_address
    # 2 bits flag, 1 bit anycast, 8 bits workchain, 256 bits address hash
    size = 2 + 1 + 8 + 256
    # Slice 2 because we don't need flag bits
    loaded_bits = load_bits(size)
    bits = loaded_bits[2..-1]

    # Anycast is currently unused
    _anycast = bits.shift
    workchain = bits_to_int_uint(bits.shift(8), type: 'int')

    hash = bits_to_hex(bits.shift(256))
    raw = "#{workchain}:#{hash}"

    Address.new(raw)
  else
    raise 'Slice: bad address flag bits.'
  end
end

#load_big_int(size) ⇒ Object



109
110
111
112
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 109

def load_big_int(size)
  bits = load_bits(size)
  bits_to_big_int(bits)[:value]
end

#load_big_uint(size) ⇒ Object



130
131
132
133
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 130

def load_big_uint(size)
  bits = load_bits(size)
  bits_to_big_uint(bits)[:value]
end

#load_bitObject



69
70
71
72
73
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 69

def load_bit
  raise 'Slice: bits overflow.' if @bits.empty?

  @bits.shift
end

#load_bits(size) ⇒ Object



87
88
89
90
91
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 87

def load_bits(size)
  raise 'Slice: bits overflow.' if size < 0 || @bits.length < size

  @bits.shift(size)
end

#load_bytes(size) ⇒ Object



221
222
223
224
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 221

def load_bytes(size)
  bits = load_bits(size * 8)
  bits_to_bytes(bits)
end

#load_coins(decimals = 9) ⇒ Object



295
296
297
298
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 295

def load_coins(decimals = 9)
  coins = load_var_big_uint(16)
  Coins.new(coins, is_nano: true, decimals: decimals)
end

#load_dict(key_size, options = {}) ⇒ Object



305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 305

def load_dict(key_size, options = {})
  dict_constructor = load_bit
  is_empty = dict_constructor.zero?

  if !is_empty
    HashmapE.parse(
      key_size,
      Slice.new([dict_constructor], [load_ref]),
      options
    )
  else
    HashmapE.new(key_size, options)
  end
end

#load_int(size) ⇒ Object



99
100
101
102
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 99

def load_int(size)
  bits = load_bits(size)
  bits_to_int_uint(bits, { type: :int })
end

#load_maybe_refObject



61
62
63
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 61

def load_maybe_ref
  load_bit == 1 ? load_ref : nil
end

#load_refObject



49
50
51
52
53
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 49

def load_ref
  raise 'Slice: refs overflow.' if @refs.empty?

  @refs.shift
end

#load_string(size = nil) ⇒ Object



231
232
233
234
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 231

def load_string(size = nil)
  bytes = size.nil? ? load_bytes(@bits.length / 8) : load_bytes(size)
  bytes_to_string(bytes)
end

#load_uint(size) ⇒ Object



119
120
121
122
123
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 119

def load_uint(size)
  bits = load_bits(size)

  bits_to_int_uint(bits, { type: :uint })
end

#load_var_big_int(length) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 161

def load_var_big_int(length)
  size = Math.log2(length).ceil

  size_bytes = preload_uint(size)
  size_bits = size_bytes * 8

  raise 'Slice: can\'t perform loadVarBigInt – not enough bits' if @bits.length < size_bits + size

  bits = load_bits(size_bits)
  bits_to_big_int(bits)[:value]
end

#load_var_big_uint(length) ⇒ Object



202
203
204
205
206
207
208
209
210
211
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 202

def load_var_big_uint(length)
  size = Math.log2(length).ceil
  size_bytes = preload_uint(size)
  size_bits = size_bytes * 8

  raise 'Slice: can\'t perform loadVarBigUint – not enough bits' if @bits.length < size_bits + size

  bits = skip(size).load_bits(size_bits)
  bits_to_big_uint(bits)[:value]
end

#load_var_int(length) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 140

def load_var_int(length)
  size = Math.log2(length).ceil

  size_bytes = preload_uint(size)
  size_bits = size_bytes * 8

  raise 'Slice: can\'t perform loadVarInt – not enough bits' if @bits.length < size_bits + size

  skip(size)
  load_int(size_bits)
end

#load_var_uint(length) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 181

def load_var_uint(length)
  size = Math.log2(length).ceil

  size_bytes = preload_uint(size)
  size_bits = size_bytes * 8

  raise 'Slice: can\'t perform loadVarUint – not enough bits' if @bits.length < size_bits + size

  skip(size)
  load_uint(size_bits)
end

#preload_addressObject



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 269

def preload_address
  flag_address_no = [0, 0]
  flag_address = [1, 0]
  flag = preload_bits(2)

  if flag == flag_address_no
    Address::NONE
  elsif flag == flag_address
    # 2 bits flag, 1 bit anycast, 8 bits workchain, 256 bits address hash
    size = 2 + 1 + 8 + 256
    bits = preload_bits(size)[2..-1]
    # Splice 2 because we don't need flag bits

    # Anycast is currently unused
    _anycast = bits.shift

    workchain = bits_to_int_uint(bits.shift(8), { type: 'int' })
    hash = bits_to_hex(bits.shift(256))
    raw = "#{workchain}:#{hash}"

    Address.new(raw)
  else
    raise 'Slice: bad address flag bits.'
  end
end

#preload_big_int(size) ⇒ Object



114
115
116
117
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 114

def preload_big_int(size)
  bits = preload_bits(size)
  bits_to_big_int(bits)[:value]
end

#preload_big_uint(size) ⇒ Object



135
136
137
138
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 135

def preload_big_uint(size)
  bits = preload_bits(size)
  bits_to_big_uint(bits)[:value]
end

#preload_bitObject



75
76
77
78
79
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 75

def preload_bit
  raise 'Slice: bits overflow.' if @bits.empty?

  @bits[0]
end

#preload_bits(size) ⇒ Object



93
94
95
96
97
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 93

def preload_bits(size)
  raise 'Slice: bits overflow.' if size < 0 || @bits.length < size

  @bits[0, size]
end

#preload_bytes(size) ⇒ Object



226
227
228
229
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 226

def preload_bytes(size)
  bits = preload_bits(size * 8)
  bits_to_bytes(bits)
end

#preload_coins(decimals = 9) ⇒ Object



300
301
302
303
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 300

def preload_coins(decimals = 9)
  coins = preload_var_big_uint(16)
  Coins.new(coins, is_nano: true, decimals: decimals)
end

#preload_dict(key_size, options = {}) ⇒ Object



320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 320

def preload_dict(key_size, options = {})
  dict_constructor = preload_bit
  is_empty = dict_constructor.zero?

  if !is_empty
    HashmapE.parse(
      key_size,
      Slice.new([dict_constructor], [preload_ref]),
      options
    )
  else
    HashmapE.new(key_size, options)
  end
end

#preload_int(size) ⇒ Object



104
105
106
107
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 104

def preload_int(size)
  bits = preload_bits(size)
  bits_to_int_uint(bits, { type: :int })
end

#preload_maybe_refObject



65
66
67
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 65

def preload_maybe_ref
  preload_bit == 1 ? preload_ref : nil
end

#preload_refObject



55
56
57
58
59
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 55

def preload_ref
  raise 'Slice: refs overflow.' if @refs.empty?

  @refs[0]
end

#preload_string(size = nil) ⇒ Object



236
237
238
239
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 236

def preload_string(size = nil)
  bytes = size.nil? ? preload_bytes(@bits.length / 8) : preload_bytes(size)
  bytes_to_string(bytes)
end

#preload_uint(size) ⇒ Object



125
126
127
128
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 125

def preload_uint(size)
  bits = preload_bits(size)
  bits_to_int_uint(bits, { type: :uint })
end

#preload_var_big_int(length) ⇒ Object



173
174
175
176
177
178
179
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 173

def preload_var_big_int(length)
  size = Math.log2(length).ceil
  size_bytes = preload_uint(size)
  size_bits = size_bytes * 8
  bits = preload_bits(size + size_bits)[size..-1]
  bits_to_big_int(bits)[:value]
end

#preload_var_big_uint(length) ⇒ Object



213
214
215
216
217
218
219
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 213

def preload_var_big_uint(length)
  size = Math.log2(length).ceil
  size_bytes = preload_uint(size)
  size_bits = size_bytes * 8
  bits = preload_bits(size + size_bits)[size..-1]
  bits_to_big_uint(bits)[:value]
end

#preload_var_int(length) ⇒ Object



152
153
154
155
156
157
158
159
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 152

def preload_var_int(length)
  size = Math.log2(length).ceil
  size_bytes = preload_uint(size)
  size_bits = size_bytes * 8
  bits = preload_bits(size + size_bits)[size..-1]

  bits_to_int_uint(bits, { type: :int })
end

#preload_var_uint(length) ⇒ Object



193
194
195
196
197
198
199
200
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 193

def preload_var_uint(length)
  size = Math.log2(length).ceil
  size_bytes = preload_uint(size)
  size_bits = size_bytes * 8
  bits = preload_bits(size + size_bits)[size..-1]

  bits_to_int_uint(bits, { type: :uint })
end

#refsObject



16
17
18
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 16

def refs
  Array.new(@refs)
end

#skip(size) ⇒ Object



20
21
22
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 20

def skip(size)
  skip_bits(size)
end

#skip_bits(size) ⇒ Object



24
25
26
27
28
29
30
31
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 24

def skip_bits(size)
  if @bits.length < size
    raise 'Slice: bits overflow.'
  end

  @bits.shift(size)
  self
end

#skip_dictObject



42
43
44
45
46
47
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 42

def skip_dict
  is_empty = load_bit == 0
  return skip_refs(1) unless is_empty

  self
end

#skip_refs(size) ⇒ Object



33
34
35
36
37
38
39
40
# File 'lib/ton-sdk-ruby/boc/slice.rb', line 33

def skip_refs(size)
  if @refs.length < size
    raise 'Slice: refs overflow.'
  end

  @refs.shift(size)
  self
end