tapyrus 0.2.13 → 0.3.2

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: 82146cdd150374b76b593273e44c31f4f578d38a1b7dcabea0b0d1fd9acbbb5f
4
- data.tar.gz: 8895de33dd2b36412f509c4e35465d513d3d6c98a0bcfc0e7db241a77acd8b3b
3
+ metadata.gz: bfdff40e4807919098065d5d956383663673f20a264d0eaadaa89124467166f8
4
+ data.tar.gz: 731e768f37f843fc6a03d337e8aea349d57f23449068356348d2bef171d02a2f
5
5
  SHA512:
6
- metadata.gz: e386ac9d8578846437902e78d79b3d4419c85df861c831c92641da94d2d46a37c4793efaafa8e28a1da4466e5347fbe79f66beb0d925fe2bfc83cca1d1e90c99
7
- data.tar.gz: a34fa0709093aafb118356b7736b409c733e1185a22538f7e2ed4392dac0ac661a652a31853f652d988860ee66c8b57124815b0fc28dd795b7bea97ad44182c5
6
+ metadata.gz: 0360ede886fe0a3512ea68e212270b5d931b8c085ceb04c6790978e325bc98b1d112d74deaa80232c97109c50ad8b1175566cb04ccd5324a218563677d90fbbd
7
+ data.tar.gz: 3f6f38a994e81c0b1d5157584cf14669ee7f8be612a6e878bf7cc216995ca60255a133b1b318e6210d6328015fdd99434bde021fd124bdc44454da564023ddab
@@ -18,7 +18,7 @@ jobs:
18
18
  runs-on: ubuntu-latest
19
19
  strategy:
20
20
  matrix:
21
- ruby-version: ["2.5", "2.6", "2.7", "3.0"]
21
+ ruby-version: ["2.6", "2.7", "3.0", "3.1"]
22
22
 
23
23
  steps:
24
24
  - run: sudo apt install libleveldb-dev
@@ -26,8 +26,7 @@ jobs:
26
26
  - name: Set up Ruby
27
27
  # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
28
28
  # change this to (see https://github.com/ruby/setup-ruby#versioning):
29
- # uses: ruby/setup-ruby@v1
30
- uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
29
+ uses: ruby/setup-ruby@v1
31
30
  with:
32
31
  ruby-version: ${{ matrix.ruby-version }}
33
32
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.0.2
1
+ 3.1.2
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Tapyrusrb [![Build Status](https://travis-ci.org/chaintope/tapyrusrb.svg?branch=master)](https://travis-ci.org/chaintope/tapyrusrb) [![Gem Version](https://badge.fury.io/rb/tapyrus.svg)](https://badge.fury.io/rb/tapyrus) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
1
+ # Tapyrusrb [![Build Status](https://github.com/chaintope/tapyrusrb/actions/workflows/ruby.yml/badge.svg?branch=master)](https://github.com/chaintope/tapyrusrb/actions/workflows/ruby.yml) [![Gem Version](https://badge.fury.io/rb/tapyrus.svg)](https://badge.fury.io/rb/tapyrus) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
2
2
 
3
3
  Tapyrusrb is a Ruby implementation of [Tapyrus](https://github.com/chaintope/tapyrus-core) Protocol.
4
4
 
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'tapyrus'
4
+ require 'terminal-table'
5
+
6
+ class EmptyTxChecker
7
+ def check_sig(script_sig, pubkey, script_code)
8
+ warn "Signature verification failed. You need to enter tx and input index."
9
+ exit
10
+ end
11
+ def verify_sig(sig, pubkey, digest, allow_hybrid: false)
12
+ warn "Signature verification failed. You need to enter tx and input index."
13
+ exit
14
+ end
15
+ end
16
+
17
+ def run_step(interpreter, script, chunk, index, is_redeem_script)
18
+ if chunk.pushdata?
19
+ puts "PUSH #{chunk.pushed_data.bth}"
20
+ else
21
+ puts "APPLY #{Tapyrus::Opcodes.opcode_to_name(chunk.opcode)}"
22
+ end
23
+ result = interpreter.next_step(script, chunk, index, is_redeem_script)
24
+ if result.is_a?(FalseClass)
25
+ warn "script failed. Reason: #{interpreter.error}"
26
+ exit
27
+ end
28
+ rows = interpreter.stack.map{|s|[s]}.reverse
29
+ table = Terminal::Table.new(title: 'Current Stack', rows: rows )
30
+ puts table
31
+ end
32
+
33
+ print "Enter scriptPubkey: "
34
+ script_pubkey_hex = gets.chomp
35
+ script_pubkey = Tapyrus::Script.parse_from_payload(script_pubkey_hex.htb)
36
+ puts script_pubkey unless script_pubkey_hex.empty?
37
+
38
+ print "Enter scriptSig: "
39
+ script_sig_hex = gets.chomp
40
+ script_sig = Tapyrus::Script.parse_from_payload(script_sig_hex.htb)
41
+ puts script_sig unless script_sig_hex.empty?
42
+
43
+ unless script_sig.push_only?
44
+ warn "scriptSig has non-push opcode."
45
+ puts
46
+ end
47
+
48
+ if script_pubkey_hex.empty? && script_sig.empty?
49
+ puts "Empty script."
50
+ exit
51
+ end
52
+
53
+ print "Enter tx: "
54
+ tx_hex = gets.chomp
55
+ if tx_hex.length == 0
56
+ tx_checker = EmptyTxChecker.new
57
+ else
58
+ print "Enter index of the input: "
59
+ input_index = gets.chomp
60
+ tx_checker = Tapyrus::TxChecker.new
61
+ begin
62
+ tx_checker.tx = Tapyrus::Tx.parse_from_payload(tx_hex.htb)
63
+ rescue StandardError
64
+ warn "Invalid tx data."
65
+ exit
66
+ end
67
+ if input_index.empty?
68
+ warn "Index of input missing."
69
+ exit
70
+ end
71
+ tx_checker.input_index = input_index.to_i
72
+ if (tx_checker.tx.in.size - 1) < tx_checker.input_index
73
+ warn "Tx does not have #{tx_checker.input_index}-th input."
74
+ exit
75
+ end
76
+ end
77
+
78
+ interpreter = Tapyrus::ScriptInterpreter.new(checker: tx_checker)
79
+
80
+ target_script = script_sig
81
+ is_redeem = false
82
+ interpreter.reset_params
83
+ chunks = target_script.chunks.each
84
+ chunk_index = 0
85
+ chunks_size = target_script.chunks.length
86
+ stack_copy = nil
87
+
88
+ puts "The Script is ready to be executed; you can step execution it by putting the Enter key."
89
+ print "> "
90
+ while cmd = gets.chomp
91
+ if cmd.length == 0
92
+ if chunks_size == chunk_index
93
+ if target_script == script_sig
94
+ stack_copy = interpreter.stack.dup
95
+ target_script = script_pubkey
96
+ interpreter.reset_params
97
+ chunks = target_script.chunks.each
98
+ chunk_index = 0
99
+ chunks_size = target_script.chunks.length
100
+ elsif target_script == script_pubkey
101
+ if interpreter.stack.empty? || !interpreter.cast_to_bool(interpreter.stack.last.htb)
102
+ warn "Script evaluated without error but finished with a false/empty top stack element"
103
+ exit
104
+ end
105
+ if script_pubkey.p2sh?
106
+ interpreter.stack = stack_copy
107
+ redeem_script = Tapyrus::Script.parse_from_payload(interpreter.stack.pop.htb)
108
+ puts "APPLY P2SH: #{redeem_script}"
109
+ rows = interpreter.stack.map{|s|[s]}.reverse
110
+ table = Terminal::Table.new(title: 'Current Stack', rows: rows )
111
+ puts table
112
+ target_script = redeem_script
113
+ chunks = target_script.chunks.each
114
+ chunk_index = 0
115
+ chunks_size = target_script.chunks.length
116
+ else
117
+ puts "Execution finished."
118
+ exit
119
+ end
120
+ else
121
+ puts "Execution finished."
122
+ exit
123
+ end
124
+ end
125
+ run_step(interpreter, target_script, chunks.next, chunk_index, is_redeem)
126
+ chunk_index += 1
127
+ else
128
+ puts "Put enter key to step execution or Ctrl+D to exit."
129
+ end
130
+ print "> "
131
+ end
@@ -104,7 +104,7 @@ module Tapyrus
104
104
  end
105
105
  end
106
106
 
107
- # Check this header contains upgrade aggregated publiec key.
107
+ # Check this header contains upgrade aggregated public key.
108
108
  # @return [Boolean] if contains return true, otherwise false.
109
109
  def upgrade_agg_pubkey?
110
110
  x_field_type == X_FILED_TYPES[:aggregate_pubkey]
@@ -54,7 +54,8 @@ module Tapyrus
54
54
  end
55
55
 
56
56
  def self.init(name)
57
- i = YAML.load(File.open("#{__dir__}/chainparams/#{name}.yml"))
57
+ yaml = File.open("#{__dir__}/chainparams/#{name}.yml")
58
+ i = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(yaml) : YAML.load(yaml)
58
59
  i.dust_relay_fee ||= Tapyrus::DUST_RELAY_TX_FEE
59
60
  i
60
61
  end
@@ -94,8 +94,6 @@ module Tapyrus
94
94
  # 80 bytes of data, +1 for OP_RETURN, +2 for the pushdata opcodes.
95
95
  MAX_OP_RETURN_RELAY = 83
96
96
 
97
- SIG_VERSION = [:base]
98
-
99
97
  # for script error
100
98
  SCRIPT_ERR_OK = 0
101
99
  SCRIPT_ERR_UNKNOWN_ERROR = 1
data/lib/tapyrus/ext.rb CHANGED
@@ -1,5 +1,21 @@
1
1
  module Tapyrus
2
2
  module Ext
3
3
  autoload :JsonParser, 'tapyrus/ext/json_parser'
4
+
5
+ refine Object do
6
+ def build_json
7
+ self.is_a?(Array) ? "[#{self.map { |o| o.to_h.to_json }.join(',')}]" : to_h.to_json
8
+ end
9
+
10
+ def to_h
11
+ return self if self.is_a?(String)
12
+ instance_variables.inject({}) do |result, var|
13
+ key = var.to_s
14
+ key.slice!(0) if key.start_with?('@')
15
+ value = instance_variable_get(var)
16
+ value.is_a?(Array) ? result.update(key => value.map { |v| v.to_h }) : result.update(key => value)
17
+ end
18
+ end
19
+ end
4
20
  end
5
21
  end
@@ -2,6 +2,8 @@ module Tapyrus
2
2
  module Network
3
3
  # P2P message handler used by peer connection class.
4
4
  module MessageHandler
5
+ using Tapyrus::Ext
6
+
5
7
  # handle p2p message.
6
8
  def handle(message)
7
9
  peer.last_recv = Time.now.to_i
@@ -96,7 +96,7 @@ module Tapyrus
96
96
  script = Tapyrus::Script.parse_from_payload(hex_script.htb)
97
97
  h = script.to_h
98
98
  h.delete(:hex)
99
- h[:p2sh] = script.to_p2sh.addresses.first unless script.p2sh?
99
+ h[:p2sh] = script.to_p2sh.to_addr unless script.p2sh?
100
100
  h
101
101
  rescue Exception
102
102
  raise ArgumentError.new('Script decode failed')
@@ -61,7 +61,7 @@ module Tapyrus
61
61
  end
62
62
 
63
63
  # Add color identifier to existing p2pkh or p2sh
64
- # @param [ColorIdentifier] color identifier
64
+ # @param [ColorIdentifier] color_id color identifier
65
65
  # @return [Script] CP2PKH or CP2SH script
66
66
  # @raise [ArgumentError] if color_id is nil or invalid
67
67
  # @raise [RuntimeError] if script is neither p2pkh nor p2sh
@@ -75,7 +75,6 @@ module Tapyrus
75
75
  end
76
76
 
77
77
  # Remove color identifier from cp2pkh or cp2sh
78
- # @param [ColorIdentifier] color identifier
79
78
  # @return [Script] P2PKH or P2SH script
80
79
  # @raise [RuntimeError] if script is neither cp2pkh nor cp2sh
81
80
  def remove_color
@@ -118,26 +117,18 @@ module Tapyrus
118
117
  # @param [String] addr address.
119
118
  # @return [Tapyrus::Script] parsed script.
120
119
  def self.parse_from_addr(addr)
121
- begin
122
- segwit_addr = Bech32::SegwitAddr.new(addr)
123
- raise 'Invalid hrp.' unless Tapyrus.chain_params.bech32_hrp == segwit_addr.hrp
124
- Tapyrus::Script.parse_from_payload(segwit_addr.to_script_pubkey.htb)
125
- rescue Exception => e
126
- hex, addr_version = Tapyrus.decode_base58_address(addr)
127
- case addr_version
128
- when Tapyrus.chain_params.address_version
129
- Tapyrus::Script.to_p2pkh(hex)
130
- when Tapyrus.chain_params.p2sh_version
131
- Tapyrus::Script.to_p2sh(hex)
132
- when Tapyrus.chain_params.cp2pkh_version
133
- color = Tapyrus::Color::ColorIdentifier.parse_from_payload(hex[0..65].htb)
134
- Tapyrus::Script.to_cp2pkh(color, hex[66..-1])
135
- when Tapyrus.chain_params.cp2sh_version
136
- color = Tapyrus::Color::ColorIdentifier.parse_from_payload(hex[0..65].htb)
137
- Tapyrus::Script.to_cp2sh(color, hex[66..-1])
138
- else
139
- throw e
140
- end
120
+ hex, addr_version = Tapyrus.decode_base58_address(addr)
121
+ case addr_version
122
+ when Tapyrus.chain_params.address_version
123
+ Tapyrus::Script.to_p2pkh(hex)
124
+ when Tapyrus.chain_params.p2sh_version
125
+ Tapyrus::Script.to_p2sh(hex)
126
+ when Tapyrus.chain_params.cp2pkh_version
127
+ color = Tapyrus::Color::ColorIdentifier.parse_from_payload(hex[0..65].htb)
128
+ Tapyrus::Script.to_cp2pkh(color, hex[66..-1])
129
+ when Tapyrus.chain_params.cp2sh_version
130
+ color = Tapyrus::Color::ColorIdentifier.parse_from_payload(hex[0..65].htb)
131
+ Tapyrus::Script.to_cp2sh(color, hex[66..-1])
141
132
  end
142
133
  end
143
134
 
@@ -189,6 +180,17 @@ module Tapyrus
189
180
  chunks.size == 0
190
181
  end
191
182
 
183
+ # Returns the address corresponding to this script. Return nil if there is no corresponding address.
184
+ # @return [String] address
185
+ def to_addr
186
+ return p2pkh_addr if p2pkh?
187
+ return p2sh_addr if p2sh?
188
+ return cp2pkh_addr if cp2pkh?
189
+ return cp2sh_addr if cp2sh?
190
+ nil
191
+ end
192
+
193
+ # @deprecated use #to_addr method.
192
194
  def addresses
193
195
  return [p2pkh_addr] if p2pkh?
194
196
  return [p2sh_addr] if p2sh?