58 lines
1.6 KiB
Ruby
58 lines
1.6 KiB
Ruby
|
class UpdateAddressOpReturnJob < ApplicationJob
|
||
|
queue_as :default
|
||
|
|
||
|
OP_RETURN_RE = /\AOP_RETURN ([0-9a-fA-F]*)\z/.freeze
|
||
|
MIN_CONFIRMATIONS = 1
|
||
|
|
||
|
def perform(address)
|
||
|
return unless address.update_op_return?
|
||
|
|
||
|
all_tx_datas = JSON.parse %x[dash-cli listtransactions "*" 100]
|
||
|
|
||
|
tx_datas = all_tx_datas.select do |tx_data|
|
||
|
tx_data['address'] == address.value &&
|
||
|
tx_data['category'] == 'send' &&
|
||
|
tx_data['confirmations'] >= MIN_CONFIRMATIONS
|
||
|
end
|
||
|
|
||
|
tx_ids = tx_datas.map { |tx_data| tx_data['txid'] }.uniq
|
||
|
|
||
|
tx_full_datas = tx_ids.map do |tx_id|
|
||
|
JSON.parse %x[dash-cli getrawtransaction #{tx_id} 1]
|
||
|
end
|
||
|
|
||
|
all_tx_vouts = tx_full_datas.flat_map do |tx_full_data|
|
||
|
tx_full_data['vout'].map do |vout|
|
||
|
tx_full_data.merge 'vout' => vout
|
||
|
end
|
||
|
end
|
||
|
|
||
|
tx_vouts = all_tx_vouts.select do |tx_vout|
|
||
|
tx_vout['vout']['scriptPubKey'] != nil &&
|
||
|
tx_vout['vout']['scriptPubKey']['asm'] != nil &&
|
||
|
tx_vout['vout']['scriptPubKey']['asm'].match?(OP_RETURN_RE)
|
||
|
end
|
||
|
|
||
|
if tx_vouts.empty?
|
||
|
address.update! op_return_value: nil,
|
||
|
op_return_updated_at: Time.zone.now
|
||
|
return
|
||
|
end
|
||
|
|
||
|
actual_tx_vout = tx_vouts.sort_by do |tx_vout|
|
||
|
[
|
||
|
tx_vout['confirmations'],
|
||
|
-tx_vout['vout']['n'],
|
||
|
]
|
||
|
end.first
|
||
|
|
||
|
asm = actual_tx_vout['vout']['scriptPubKey']['asm']
|
||
|
match = OP_RETURN_RE.match asm
|
||
|
hex = match[1]
|
||
|
ascii = [hex].pack 'H*'
|
||
|
|
||
|
address.update! op_return_value: ascii,
|
||
|
op_return_updated_at: Time.zone.now
|
||
|
end
|
||
|
end
|