Class: BSV::Script::Chunk
- Inherits:
-
Object
- Object
- BSV::Script::Chunk
- Defined in:
- lib/bsv/script/chunk.rb
Overview
A single element of a parsed script — either an opcode or a data push.
Scripts are composed of a sequence of chunks. Each chunk is either a bare opcode (e.g. OP_DUP) or a data push (opcode + data payload).
Instance Attribute Summary collapse
-
#data ⇒ String?
readonly
The pushed data bytes, or
nilfor bare opcodes. -
#opcode ⇒ Integer
readonly
The opcode byte.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
trueif both chunks have equal opcode and data. -
#data? ⇒ Boolean
Whether this chunk carries a data payload.
-
#initialize(opcode:, data: nil) ⇒ Chunk
constructor
A new instance of Chunk.
-
#to_asm ⇒ String
Render this chunk as human-readable ASM.
-
#to_binary ⇒ String
Serialise this chunk back to raw script bytes.
Constructor Details
#initialize(opcode:, data: nil) ⇒ Chunk
Returns a new instance of Chunk.
18 19 20 21 |
# File 'lib/bsv/script/chunk.rb', line 18 def initialize(opcode:, data: nil) @opcode = opcode @data = data&.b end |
Instance Attribute Details
#data ⇒ String? (readonly)
Returns the pushed data bytes, or nil for bare opcodes.
14 15 16 |
# File 'lib/bsv/script/chunk.rb', line 14 def data @data end |
#opcode ⇒ Integer (readonly)
Returns the opcode byte.
11 12 13 |
# File 'lib/bsv/script/chunk.rb', line 11 def opcode @opcode end |
Instance Method Details
#==(other) ⇒ Boolean
Returns true if both chunks have equal opcode and data.
87 88 89 |
# File 'lib/bsv/script/chunk.rb', line 87 def ==(other) other.is_a?(Chunk) && @opcode == other.opcode && @data == other.data end |
#data? ⇒ Boolean
Whether this chunk carries a data payload.
26 27 28 |
# File 'lib/bsv/script/chunk.rb', line 26 def data? !@data.nil? end |
#to_asm ⇒ String
Render this chunk as human-readable ASM.
Data pushes are shown as hex strings; opcodes are shown by name. Opcodes with no defined name are rendered as OP_UNKNOWN<n> (e.g. OP_UNKNOWN186) so that the output is unambiguous and round-trippable via from_asm.
The OP_RETURN opcode is special: it carries the raw tail bytes as its data payload (absorbed during parsing). To preserve round-trip fidelity with from_asm, the tail is re-parsed into individual push items and each is rendered as a hex token after OP_RETURN.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/bsv/script/chunk.rb', line 66 def to_asm if @opcode == Opcodes::OP_RETURN && @data return 'OP_RETURN' if @data.empty? # Re-parse the tail bytes into individual chunks (without OP_RETURN # termination) so each push renders as a separate hex token. tail_script = BSV::Script::Script.new(@data) tail_chunks = tail_script.send(:parse_chunks, terminate_on_op_return: false) parts = ['OP_RETURN'] + tail_chunks.map do |ch| ch.data? ? ch.data.unpack1('H*') : (Opcodes.name_for(ch.opcode) || "OP_UNKNOWN#{ch.opcode}") end parts.join(' ') elsif @data @data.unpack1('H*') else Opcodes.name_for(@opcode) || "OP_UNKNOWN#{@opcode}" end end |
#to_binary ⇒ String
Serialise this chunk back to raw script bytes.
Preserves the original push encoding (including non-minimal pushes) so that round-tripping through parse/serialise does not alter the script bytes. This is critical for sighash computation.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/bsv/script/chunk.rb', line 37 def to_binary return [@opcode].pack('C') unless @data case @opcode when Opcodes::OP_PUSHDATA1 [Opcodes::OP_PUSHDATA1, @data.bytesize].pack('CC') + @data when Opcodes::OP_PUSHDATA2 [Opcodes::OP_PUSHDATA2].pack('C') + [@data.bytesize].pack('v') + @data when Opcodes::OP_PUSHDATA4 [Opcodes::OP_PUSHDATA4].pack('C') + [@data.bytesize].pack('V') + @data else # Direct push: opcode IS the length (0x01..0x4b) [@opcode].pack('C') + @data end end |