Class: OpenAssets::Protocol::MarkerOutput

Inherits:
Object
  • Object
show all
Extended by:
Util
Includes:
Util
Defined in:
lib/openassets/protocol/marker_output.rb

Constant Summary collapse

MAX_ASSET_QUANTITY =
2 ** 63 -1
OAP_MARKER =

A tag indicating thath this transaction is an Open Assets transaction.

"4f41"
VERSION =

The major revision number of the Open Assets Protocol.(1=0x0100)

"0100"

Constants included from Util

Util::OA_NAMESPACE, Util::OA_VERSION_BYTE, Util::OA_VERSION_BYTE_TESTNET

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util

address_to_asset_id, address_to_oa_address, coin_to_satoshi, decode_leb128, encode_leb128, generate_asset_id, oa_address_to_address, oa_address_to_asset_id, pubkey_hash_to_asset_id, read_leb128, read_var_integer, satoshi_to_coin, script_to_address, to_bytes, valid_asset_id?, validate_address

Constructor Details

#initialize(asset_quantities, metadata = '') ⇒ MarkerOutput

Returns a new instance of MarkerOutput.

Parameters:

  • asset_quantities (Array)

    The asset quantity array

  • metadata (String) (defaults to: '')

    The metadata in the marker output.



21
22
23
24
# File 'lib/openassets/protocol/marker_output.rb', line 21

def initialize(asset_quantities,  = '')
  @asset_quantities = asset_quantities
   = 
end

Instance Attribute Details

#asset_quantitiesObject

Returns the value of attribute asset_quantities.



16
17
18
# File 'lib/openassets/protocol/marker_output.rb', line 16

def asset_quantities
  @asset_quantities
end

#metadataObject

Returns the value of attribute metadata.



17
18
19
# File 'lib/openassets/protocol/marker_output.rb', line 17

def 
  
end

Class Method Details

.deserialize_payload(payload) ⇒ OpenAssets::Protocol::MarkerOutput

Deserialize the marker output payload.

Parameters:

  • payload (String)

    The Open Assets Payload.

Returns:



45
46
47
48
49
50
51
52
53
54
# File 'lib/openassets/protocol/marker_output.rb', line 45

def self.deserialize_payload(payload)
  return nil unless valid?(payload)
  payload = payload[8..-1] # exclude OAP_MARKER,VERSION
  asset_quantity, payload = parse_asset_qty(payload)
  list = to_bytes(payload).map{|x|(x.to_i(16)>=128 ? x : x+"|")}.join.split('|')[0..(asset_quantity - 1)].join
  asset_quantities = decode_leb128(list)
  meta = to_bytes(payload[list.size..-1])
   =  meta.empty? ? '' : meta[1..-1].map{|x|x.to_i(16).chr}.join
  new(asset_quantities, )
end

.parse_asset_qty(payload) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/openassets/protocol/marker_output.rb', line 71

def self.parse_asset_qty(payload)
  bytes = to_bytes(payload)
  case bytes[0]
    when "fd" then
      [(bytes[1]+bytes[2]).to_i(16), payload[6..-1]]
    when "fe" then
      [(bytes[1]+bytes[2]+bytes[3]+bytes[4]).to_i(16),payload[10..-1]]
    else
      [bytes[0].to_i(16),payload[2..-1]]
  end
end

.parse_script(output_script) ⇒ String

Parses an output and returns the payload if the output matches the right pattern for a marker output,

Parameters:

  • output_script: (Bitcoin::Script)

    The output script to be parsed.

Returns:

  • (String)

    The byte string of the marker output payload if the output fits the pattern, nil otherwise.



59
60
61
62
# File 'lib/openassets/protocol/marker_output.rb', line 59

def self.parse_script(output_script)
  data = Bitcoin::Script.new(output_script).get_op_return_data
  return data if valid?(data)
end

.valid?(data) ⇒ Boolean

validate marker output format @param data marker output data with start with 4f41

Returns:

  • (Boolean)


106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/openassets/protocol/marker_output.rb', line 106

def self.valid?(data)
  return false if data.nil?
  # check open assets marker
  return false unless data.start_with?(OAP_MARKER + VERSION)
  # check asset quantity
  offset = [OAP_MARKER + VERSION].pack('H*').length
  count, offset = read_var_integer(data, offset)
  return false unless count
  # check metadata
  count.times do
    quantity, length = read_leb128(data, offset)
    return false if quantity.nil? || (length - offset) > 9
    offset = length
  end
  # check metadata
  length, offset = read_var_integer(data, offset)
  return false unless length
  return false if [data].pack('H*').bytes.length < length + offset
  true
end

Instance Method Details

#build_scriptBitcoin::Script

Creates an output script containing an OP_RETURN and a PUSHDATA from payload.

Returns:

  • (Bitcoin::Script)

    the output script.



66
67
68
# File 'lib/openassets/protocol/marker_output.rb', line 66

def build_script
  Bitcoin::Script.from_string("OP_RETURN #{to_payload}")
end

#to_payloadString

Serialize the marker output into a Open Assets Payload buffer.

Returns:

  • (String)

    The serialized payload.



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/openassets/protocol/marker_output.rb', line 28

def to_payload
  payload = [OAP_MARKER, VERSION]
  asset_quantity_count = Bitcoin::Protocol.pack_var_int(@asset_quantities.length).unpack("H*")
  payload << sort_count(asset_quantity_count[0])
  @asset_quantities.map{|q|payload << encode_leb128(q)}
   ||= ''
   = Bitcoin::Protocol.pack_var_int(.length).unpack("H*")
  payload << sort_count([0])
  tmp = []
  .bytes{|b| tmp << b.to_s(16)}
  payload << tmp.join
  payload.join
end