platon 0.2.7
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/.github/workflows/main.yml +18 -0
- data/.gitignore +15 -0
- data/.rspec +3 -0
- data/.rubocop.yml +10 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +69 -0
- data/LICENSE.txt +21 -0
- data/README.md +216 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/doc/zh-cn.md +1762 -0
- data/lib/bech32.rb +82 -0
- data/lib/platon.rb +77 -0
- data/lib/platon/abi.rb +32 -0
- data/lib/platon/address.rb +62 -0
- data/lib/platon/client.rb +175 -0
- data/lib/platon/contract.rb +351 -0
- data/lib/platon/contract_event.rb +24 -0
- data/lib/platon/contract_initializer.rb +54 -0
- data/lib/platon/decoder.rb +99 -0
- data/lib/platon/deployment.rb +49 -0
- data/lib/platon/encoder.rb +120 -0
- data/lib/platon/explorer_url_helper.rb +0 -0
- data/lib/platon/formatter.rb +142 -0
- data/lib/platon/function.rb +36 -0
- data/lib/platon/function_input.rb +13 -0
- data/lib/platon/function_output.rb +14 -0
- data/lib/platon/gas.rb +9 -0
- data/lib/platon/http_client.rb +55 -0
- data/lib/platon/initializer.rb +0 -0
- data/lib/platon/ipc_client.rb +45 -0
- data/lib/platon/key.rb +105 -0
- data/lib/platon/key/decrypter.rb +113 -0
- data/lib/platon/key/encrypter.rb +128 -0
- data/lib/platon/open_ssl.rb +267 -0
- data/lib/platon/ppos.rb +344 -0
- data/lib/platon/railtie.rb +0 -0
- data/lib/platon/secp256k1.rb +7 -0
- data/lib/platon/sedes.rb +40 -0
- data/lib/platon/segwit_addr.rb +66 -0
- data/lib/platon/singleton.rb +39 -0
- data/lib/platon/solidity.rb +40 -0
- data/lib/platon/transaction.rb +41 -0
- data/lib/platon/tx.rb +201 -0
- data/lib/platon/utils.rb +180 -0
- data/lib/platon/version.rb +5 -0
- data/lib/tasks/platon_contract.rake +27 -0
- data/platon-ruby-logo.png +0 -0
- data/platon.gemspec +50 -0
- metadata +235 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module Platon
|
2
|
+
class ContractEvent
|
3
|
+
|
4
|
+
attr_accessor :name, :signature, :input_types, :inputs, :event_string, :address, :client
|
5
|
+
|
6
|
+
def initialize(data)
|
7
|
+
@name = data["name"]
|
8
|
+
@input_types = data["inputs"].collect {|x| x["type"]}
|
9
|
+
@inputs = data["inputs"].collect {|x| x["name"]}
|
10
|
+
@event_string = "#{@name}(#{@input_types.join(",")})"
|
11
|
+
@signature = Digest::SHA3.hexdigest(@event_string, 256)
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_address(address)
|
15
|
+
@address = address
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_client(client)
|
19
|
+
@client = client
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Platon
|
2
|
+
|
3
|
+
class ContractInitializer
|
4
|
+
|
5
|
+
attr_accessor :abi, :binary, :name, :libraries, :needs_linking, :project_initializer, :contract
|
6
|
+
|
7
|
+
def initialize(contract_name, contract, project_initializer)
|
8
|
+
@abi = JSON.parse(contract["abi"]) unless contract.nil?
|
9
|
+
@binary = contract["bin"] unless contract.nil?
|
10
|
+
@name = contract_name
|
11
|
+
@project_initializer = project_initializer
|
12
|
+
matchdata = @binary.scan(/_+[a-zA-Z]+_+/).uniq
|
13
|
+
@needs_linking = matchdata.present?
|
14
|
+
if @needs_linking
|
15
|
+
@libraries = matchdata.collect do |libname|
|
16
|
+
{name: libname.gsub(/_+/,''), sigil: libname}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def link_libraries
|
22
|
+
if @needs_linking
|
23
|
+
@libraries.each do |library|
|
24
|
+
name = library[:name]
|
25
|
+
if @project_initializer.libraries[name].nil?
|
26
|
+
ENV['ETHEREUM_DEPLOYER_WAIT_TIME'] ||= "120"
|
27
|
+
wait_time = ENV['ETHEREUM_DEPLOYER_WAIT_TIME'].to_i
|
28
|
+
library_instance = library[:name].constantize.new
|
29
|
+
puts "Deploying library #{name}"
|
30
|
+
library_instance.deploy_and_wait(wait_time)
|
31
|
+
puts "Library deployed at #{library_instance.address}"
|
32
|
+
@project_initializer.libraries[name] = library_instance.address
|
33
|
+
@binary.gsub!(library[:sigil], library_instance.address.gsub(/^0x/,''))
|
34
|
+
else
|
35
|
+
address = @project_initializer.libraries[name]
|
36
|
+
@binary.gsub!(library[:sigil], address.gsub(/^0x/,''))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def build(connection)
|
43
|
+
@contract = Platon::Contract.new(@name, @binary, @abi, client)
|
44
|
+
@contract.build(connection)
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_javascripts(path)
|
48
|
+
data = {name: @name, abi: @abi, binary: @binary}
|
49
|
+
File.open(File.join(path, "#{@name}.json"), 'w') {|f| f.puts data.to_json}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Platon
|
2
|
+
class Decoder
|
3
|
+
|
4
|
+
def decode(type, value, start = 0)
|
5
|
+
is_array, arity, array_subtype = Abi::parse_array_type(type)
|
6
|
+
if is_array && arity
|
7
|
+
decode_static_array(arity, array_subtype, value, start)
|
8
|
+
elsif is_array
|
9
|
+
decode_dynamic_array(array_subtype, value, start)
|
10
|
+
else
|
11
|
+
value = value.gsub(/^0x/,'')
|
12
|
+
core, subtype = Abi::parse_type(type)
|
13
|
+
method_name = "decode_#{core}".to_sym
|
14
|
+
self.send(method_name, value, subtype, start)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def decode_static_array(arity, array_subtype, value, start)
|
19
|
+
(0..arity-1).map { |i| decode(array_subtype, value, start + i * 64) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def decode_dynamic_array(array_subtype, value, start)
|
23
|
+
location = decode_uint(value[start..(start+63)]) * 2
|
24
|
+
size = decode_uint(value[location..location+63])
|
25
|
+
(0..size-1).map { |i| decode(array_subtype, value, location + (i+1) * 64) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def decode_fixed(value, subtype = "128x128", start = 0)
|
29
|
+
decode_int(trim(value, start, fixed_bitsize(subtype))).to_f / 2**exponent(subtype)
|
30
|
+
end
|
31
|
+
|
32
|
+
def decode_uint(value, subtype = "256", start = 0)
|
33
|
+
trim(value, start, bitsize(subtype)).hex
|
34
|
+
end
|
35
|
+
|
36
|
+
def decode_int(value, subtype = "256", start = 0)
|
37
|
+
raise ArgumentError if value.nil?
|
38
|
+
size = bitsize(subtype)
|
39
|
+
value = trim(value, start, size)
|
40
|
+
(value[0..1] == "ff") ? (value.hex - (2 ** size)) : value.hex
|
41
|
+
end
|
42
|
+
|
43
|
+
def decode_bool(value, _, start)
|
44
|
+
value = trim(value, start, 4)
|
45
|
+
return true if value == "1"
|
46
|
+
return false if value == "0"
|
47
|
+
raise ArgumentError
|
48
|
+
end
|
49
|
+
|
50
|
+
def decode_address(value, _ = nil, start)
|
51
|
+
raise ArgumentError if value.size-start < 64
|
52
|
+
value[start+24..start+63]
|
53
|
+
end
|
54
|
+
|
55
|
+
def decode_bytes(value, subtype, start)
|
56
|
+
subtype.present? ? decode_static_bytes(value, subtype, start) : decode_dynamic_bytes(value, start)
|
57
|
+
end
|
58
|
+
|
59
|
+
def decode_static_bytes(value, subtype = nil, start = 0)
|
60
|
+
trim(value, start, subtype.to_i*8).scan(/.{2}/).collect {|x| x.hex}.pack('C*').strip
|
61
|
+
end
|
62
|
+
|
63
|
+
def decode_dynamic_bytes(value, start = 0)
|
64
|
+
location = decode_uint(value[start..(start+63)]) * 2
|
65
|
+
size = decode_uint(value[location..location+63]) * 2
|
66
|
+
value[location+64..location+63+size].scan(/.{2}/).collect {|x| x.hex}.pack('C*')
|
67
|
+
end
|
68
|
+
|
69
|
+
def decode_string(value, _ = nil, start = 0)
|
70
|
+
decode_dynamic_bytes(value, start).force_encoding('utf-8')
|
71
|
+
end
|
72
|
+
|
73
|
+
def decode_arguments(arguments, data)
|
74
|
+
data = data.gsub(/^0x/,'')
|
75
|
+
types = arguments.map { |o| o.type }
|
76
|
+
types.each.with_index.map { |t , i| decode(t, data, i*64) }
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
def trim(value, start, bitsize = 256)
|
81
|
+
value[start+63-(bitsize/4-1)..start+63]
|
82
|
+
end
|
83
|
+
|
84
|
+
def bitsize(subtype, default = 256)
|
85
|
+
subtype.present? ? subtype.to_i : default
|
86
|
+
end
|
87
|
+
|
88
|
+
def fixed_bitsize(subtype = nil)
|
89
|
+
subtype ||= "128x128"
|
90
|
+
_, x, n = /(\d+)x(\d+)/.match(subtype).to_a
|
91
|
+
x.to_i + n.to_i
|
92
|
+
end
|
93
|
+
|
94
|
+
def exponent(subtype, default = 128)
|
95
|
+
subtype.nil? ? default : /(\d+)x(\d+)/.match(subtype)[2].to_i
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Platon
|
2
|
+
|
3
|
+
class Deployment
|
4
|
+
|
5
|
+
DEFAULT_TIMEOUT = 300.seconds
|
6
|
+
DEFAULT_STEP = 5.seconds
|
7
|
+
|
8
|
+
attr_accessor :id, :contract_address, :connection, :deployed, :mined
|
9
|
+
attr_reader :valid_deployment
|
10
|
+
|
11
|
+
def initialize(txid, connection)
|
12
|
+
@id = txid
|
13
|
+
@connection = connection
|
14
|
+
@deployed = false
|
15
|
+
@contract_address = nil
|
16
|
+
@valid_deployment = false
|
17
|
+
end
|
18
|
+
|
19
|
+
def mined?
|
20
|
+
return true if @mined
|
21
|
+
@mined = @connection.platon_get_transaction_by_hash(@id)["result"]["blockNumber"].present?
|
22
|
+
@mined ||= false
|
23
|
+
end
|
24
|
+
|
25
|
+
def check_deployed
|
26
|
+
return false unless @id
|
27
|
+
contract_receipt = @connection.platon_get_transaction_receipt(@id)
|
28
|
+
result = contract_receipt["result"]
|
29
|
+
has_contract_address = result && result["contractAddress"]
|
30
|
+
@contract_address ||= result["contractAddress"] if has_contract_address
|
31
|
+
has_contract_address && result["blockNumber"]
|
32
|
+
end
|
33
|
+
|
34
|
+
def deployed?
|
35
|
+
@valid_deployment ||= check_deployed
|
36
|
+
end
|
37
|
+
|
38
|
+
def wait_for_deployment(timeout: DEFAULT_TIMEOUT, step: DEFAULT_STEP)
|
39
|
+
start_time = Time.now
|
40
|
+
loop do
|
41
|
+
raise "Transaction #{@id} timed out." if ((Time.now - start_time) > timeout)
|
42
|
+
yield if block_given?
|
43
|
+
return true if deployed?
|
44
|
+
sleep step
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Platon
|
2
|
+
|
3
|
+
class Encoder
|
4
|
+
|
5
|
+
def encode(type, value)
|
6
|
+
is_array, arity, array_subtype = Abi::parse_array_type(type)
|
7
|
+
if is_array && arity
|
8
|
+
encode_static_array(arity, array_subtype, value)
|
9
|
+
elsif is_array
|
10
|
+
encode_dynamic_array(array_subtype, value)
|
11
|
+
else
|
12
|
+
core, subtype = Abi::parse_type(type)
|
13
|
+
method_name = "encode_#{core}".to_sym
|
14
|
+
self.send(method_name, value, subtype)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def encode_static_array(arity, array_subtype, array)
|
19
|
+
raise "Wrong number of arguments" if arity != array.size
|
20
|
+
array.inject("") { |a, e| a << encode(array_subtype, e) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def encode_dynamic_array(array_subtype, array)
|
24
|
+
location = encode_uint(@inputs ? size_of_inputs(@inputs) + @tail.size/2 : 32)
|
25
|
+
size = encode_uint(array.size)
|
26
|
+
data = array.inject("") { |a, e| a << encode(array_subtype, e) }
|
27
|
+
[location, size + data]
|
28
|
+
end
|
29
|
+
|
30
|
+
def encode_int(value, _ = nil)
|
31
|
+
to_twos_complement(value).to_s(16).rjust(64, '0')
|
32
|
+
end
|
33
|
+
|
34
|
+
def encode_uint(value, _ = nil)
|
35
|
+
raise ArgumentError if value < 0
|
36
|
+
encode_int(value)
|
37
|
+
end
|
38
|
+
|
39
|
+
def encode_bool(value, _)
|
40
|
+
(value ? "1" : "0").rjust(64, '0')
|
41
|
+
end
|
42
|
+
|
43
|
+
def encode_fixed(value, subtype)
|
44
|
+
n = subtype.nil? ? 128 : /(\d+)x(\d+)/.match(subtype)[2].to_i
|
45
|
+
do_encode_fixed(value, n)
|
46
|
+
end
|
47
|
+
|
48
|
+
def do_encode_fixed(value, n)
|
49
|
+
encode_uint((value * 2**n).to_i)
|
50
|
+
end
|
51
|
+
|
52
|
+
def encode_ufixed(_value, _)
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
|
56
|
+
def encode_bytes(value, subtype)
|
57
|
+
subtype.nil? ? encode_dynamic_bytes(value) : encode_static_bytes(value)
|
58
|
+
end
|
59
|
+
|
60
|
+
def encode_static_bytes(value)
|
61
|
+
value.bytes.map {|x| x.to_s(16).rjust(2, '0')}.join("").ljust(64, '0')
|
62
|
+
end
|
63
|
+
|
64
|
+
def encode_dynamic_bytes(value)
|
65
|
+
location = encode_uint(@inputs ? size_of_inputs(@inputs) + @tail.size/2 : 32)
|
66
|
+
size = encode_uint(value.size)
|
67
|
+
content = encode_static_bytes(value)
|
68
|
+
[location, size + content]
|
69
|
+
end
|
70
|
+
|
71
|
+
def encode_string(value, _)
|
72
|
+
location = encode_uint(@inputs ? size_of_inputs(@inputs) + @tail.size/2 : 32)
|
73
|
+
size = encode_uint(value.bytes.size)
|
74
|
+
content = value.bytes.map {|x| x.to_s(16).rjust(2, '0')}.join("").ljust(64, '0')
|
75
|
+
[location, size + content]
|
76
|
+
end
|
77
|
+
|
78
|
+
def encode_address(value, _)
|
79
|
+
# puts "value: #{value}"
|
80
|
+
value = Utils.decode_bech32_address(value) if Utils.is_bech32_address?(value)
|
81
|
+
value = "0" * 24 + value.gsub(/^0x/,'')
|
82
|
+
raise ArgumentError if value.size != 64
|
83
|
+
value
|
84
|
+
end
|
85
|
+
|
86
|
+
def ensure_prefix(value)
|
87
|
+
value.start_with?("0x") ? value : ("0x" + value)
|
88
|
+
end
|
89
|
+
|
90
|
+
def encode_arguments(inputs, args)
|
91
|
+
raise "Wrong number of arguments" if inputs.length != args.length
|
92
|
+
@head = ""
|
93
|
+
@tail = ""
|
94
|
+
@inputs = inputs
|
95
|
+
inputs.each.with_index do |input, index|
|
96
|
+
encoded = encode(input.type, args[index])
|
97
|
+
if encoded.is_a? Array
|
98
|
+
@head << encoded[0]
|
99
|
+
@tail << encoded[1]
|
100
|
+
else
|
101
|
+
@head << encoded
|
102
|
+
end
|
103
|
+
end
|
104
|
+
@head + @tail
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
def to_twos_complement(number)
|
109
|
+
(number & ((1 << 256) - 1))
|
110
|
+
end
|
111
|
+
|
112
|
+
def size_of_inputs(inputs)
|
113
|
+
inputs.map do |input|
|
114
|
+
_, arity, _ = Abi::parse_array_type(input.type)
|
115
|
+
arity.nil? ? 32 : arity * 32
|
116
|
+
end.inject(:+)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
File without changes
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module Platon
|
2
|
+
class Formatter
|
3
|
+
|
4
|
+
UNITS = {
|
5
|
+
'von': 1,
|
6
|
+
'kvon': 1000,
|
7
|
+
'mvon': 1000000,
|
8
|
+
'gvon': 1000000000, ## 10 ** 9
|
9
|
+
'microatp': 1000000000000,
|
10
|
+
'milliatp': 1000000000000000,
|
11
|
+
'atp': 1000000000000000000, ## 10 ** 18
|
12
|
+
'katp': 1000000000000000000000,
|
13
|
+
'matp': 1000000000000000000000000,
|
14
|
+
'gatp': 1000000000000000000000000000,
|
15
|
+
'tatp': 1000000000000000000000000000000
|
16
|
+
}
|
17
|
+
|
18
|
+
def valid_address?(address_string)
|
19
|
+
address = address_string.gsub(/^0x/,'')
|
20
|
+
return false if address == "0000000000000000000000000000000000000000"
|
21
|
+
return false if address.length != 40
|
22
|
+
return !(address.match(/[0-9a-fA-F]+/).nil?)
|
23
|
+
end
|
24
|
+
|
25
|
+
def from_bool(boolval)
|
26
|
+
return nil if boolval.nil?
|
27
|
+
boolval ? "1" : "0"
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_bool(hexstring)
|
31
|
+
return nil if hexstring.nil?
|
32
|
+
(hexstring == "0000000000000000000000000000000000000000000000000000000000000001")
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_ascii(hexstring)
|
36
|
+
return nil if hexstring.nil?
|
37
|
+
hexstring.gsub(/^0x/,'').scan(/.{2}/).collect {|x| x.hex}.pack("c*")
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_utf8(hexstring)
|
41
|
+
return nil if hexstring.nil?
|
42
|
+
hexstring.gsub(/^0x/,'').scan(/.{2}/).collect {|x| x.hex}.pack("U*").delete("\u0000")
|
43
|
+
end
|
44
|
+
|
45
|
+
def from_ascii(ascii_string)
|
46
|
+
return nil if ascii_string.nil?
|
47
|
+
ascii_string.unpack('H*')[0]
|
48
|
+
end
|
49
|
+
|
50
|
+
def from_utf8(utf8_string)
|
51
|
+
return nil if utf8_string.nil?
|
52
|
+
utf8_string.force_encoding('UTF-8').split("").collect {|x| x.ord.to_s(16).rjust(2, '0')}.join("")
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_address(hexstring)
|
56
|
+
return "0x0000000000000000000000000000000000000000" if hexstring.nil?
|
57
|
+
"0x" + hexstring[-40..-1]
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_von(amount, unit = "atp") #TODO
|
61
|
+
return nil if amount.nil?
|
62
|
+
BigDecimal(UNITS[unit.to_sym] * amount, 16).to_s.to_i rescue nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def from_von(amount, unit = "atp") #TODO
|
66
|
+
return nil if amount.nil?
|
67
|
+
(BigDecimal(amount, 16) / BigDecimal(UNITS[unit.to_sym], 16)).to_s rescue nil
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_gvon(amount, unit = "gvon")
|
71
|
+
return nil if amount.nil?
|
72
|
+
BigDecimal(UNITS[unit.to_sym] * amount, 16).to_s.to_i rescue nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def from_gvon(amount, unit = "gvon")
|
76
|
+
return nil if amount.nil?
|
77
|
+
(BigDecimal(amount, 16) / BigDecimal(UNITS[unit.to_sym], 16)).to_s rescue nil
|
78
|
+
end
|
79
|
+
|
80
|
+
def from_address(address)
|
81
|
+
return "0x0000000000000000000000000000000000000000" if address.nil?
|
82
|
+
address.gsub(/^0x/,'').rjust(64, "0")
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_param(string)
|
86
|
+
string.ljust(64, '0')
|
87
|
+
end
|
88
|
+
|
89
|
+
def from_input(string)
|
90
|
+
string[10..-1].scan(/.{64}/)
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_twos_complement(number)
|
94
|
+
(number & ((1 << 256) - 1)).to_s(16)
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_int(hexstring)
|
98
|
+
return nil if hexstring.nil?
|
99
|
+
(hexstring.gsub(/^0x/,'')[0..1] == "ff") ? (hexstring.hex - (2 ** 256)) : hexstring.hex
|
100
|
+
end
|
101
|
+
|
102
|
+
def get_base_type(typename)
|
103
|
+
typename.gsub(/\d+/,'')
|
104
|
+
end
|
105
|
+
|
106
|
+
def from_payload(args)
|
107
|
+
converter = "output_to_#{self.get_base_type(args[0])}".to_sym
|
108
|
+
self.send(converter, args[1])
|
109
|
+
end
|
110
|
+
|
111
|
+
def output_to_address(bytes)
|
112
|
+
self.to_address(bytes)
|
113
|
+
end
|
114
|
+
|
115
|
+
def output_to_bytes(bytes)
|
116
|
+
self.to_utf8(bytes)
|
117
|
+
end
|
118
|
+
|
119
|
+
def output_to_string(bytes)
|
120
|
+
self.to_utf8(bytes)
|
121
|
+
end
|
122
|
+
|
123
|
+
def output_to_uint(bytes)
|
124
|
+
self.to_int(bytes)
|
125
|
+
end
|
126
|
+
|
127
|
+
def output_to_int(bytes)
|
128
|
+
self.to_int(bytes)
|
129
|
+
end
|
130
|
+
|
131
|
+
def output_to_bool(bytes)
|
132
|
+
self.to_bool(bytes.gsub(/^0x/,''))
|
133
|
+
end
|
134
|
+
|
135
|
+
def to_output(args)
|
136
|
+
converter = "output_to_#{self.get_base_type(args[0])}".to_sym
|
137
|
+
self.send(converter, args[1])
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|