Class: Dropzone::Item

Inherits:
MessageBase show all
Defined in:
lib/dropzone/item.rb

Defined Under Namespace

Classes: Validator

Constant Summary collapse

EARTH_RADIUS_IN_METERS =
6_371_000
HASH_160_PARTS =
/\A(?:mfZ|1DZ)([1-9X]{9})([1-9X]{9})([1-9X]{6}).+/

Constants inherited from MessageBase

MessageBase::DEFAULT_TIP

Instance Attribute Summary collapse

Attributes inherited from MessageBase

#block_height, #sender_addr, #txid

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from MessageBase

attr_message, attr_message_int, attr_message_pkey, #data_to_hash, #data_to_hex, find, #initialize, is_attr_int?, is_attr_pkey?, message_attribs, message_type, new_message_from, #save!, #to_transaction, types_include?

Methods inherited from RecordBase

#blockchain, #errors, #valid?

Constructor Details

This class inherits a constructor from Dropzone::MessageBase

Instance Attribute Details

#latitudeObject (readonly)

These are receiver address attributes, not message attribs:



11
12
13
# File 'lib/dropzone/item.rb', line 11

def latitude
  @latitude
end

#longitudeObject (readonly)

These are receiver address attributes, not message attribs:



11
12
13
# File 'lib/dropzone/item.rb', line 11

def longitude
  @longitude
end

#radiusObject (readonly)

These are receiver address attributes, not message attribs:



11
12
13
# File 'lib/dropzone/item.rb', line 11

def radius
  @radius
end

Class Method Details

.blockchainObject



72
73
74
# File 'lib/dropzone/item.rb', line 72

def self.blockchain
  Dropzone::RecordBase.blockchain
end

.distance_between(lat1, lon1, lat2, lon2) ⇒ Object

haversine formula, pulled from : www.movable-type.co.uk/scripts/latlong.html



97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/dropzone/item.rb', line 97

def self.distance_between(lat1, lon1, lat2, lon2)
  delta_phi = to_rad(lat2-lat1)
  delta_lamba = to_rad(lon2-lon1)

  a = Math.sin(delta_phi/2) ** 2 + [ Math.cos(to_rad(lat1)), 
    Math.cos(to_rad(lat2)), Math.sin(delta_lamba/2), 
    Math.sin(delta_lamba/2) ].reduce(:*)

  c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))

  EARTH_RADIUS_IN_METERS * c
end

.find_creates_since_block(starting_at, block_depth, &block) ⇒ Object

Returns all *Items created* since (and including) the provided block These are items and not listings, so as to query faster. Items are returned in the order of newest to oldest



79
80
81
82
83
84
85
# File 'lib/dropzone/item.rb', line 79

def self.find_creates_since_block(starting_at, block_depth, &block)
  starting_at.downto(starting_at-block_depth).collect{|i|
    blockchain.messages_in_block(i, type: 'ITCRTE').collect do |item|
      (block_given?) ? block.call(item, i) : item
    end
  }.flatten.compact
end

.find_in_radius(starting_at, block_depth, lat, long, in_meters, &block) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/dropzone/item.rb', line 87

def self.find_in_radius(starting_at, block_depth, lat, long, in_meters, &block)
  find_creates_since_block(starting_at, block_depth) do |item, nb|
    if distance_between(item.latitude, item.longitude, lat, long) <= in_meters 
      (block_given?) ? block.call(item, nb) : item
    end
  end
end

.to_rad(angle) ⇒ Object



110
111
112
# File 'lib/dropzone/item.rb', line 110

def self.to_rad(angle)
  angle.to_f / 180 * Math::PI
end

Instance Method Details

#message_typeObject



33
34
35
36
37
# File 'lib/dropzone/item.rb', line 33

def message_type
  return @message_type if @message_type 

  create_txid ? 'ITUPDT' : 'ITCRTE'
end

#receiver_addrObject

This is an easy guide to what we’re doing here: www.reddit.com/r/Bitcoin/comments/2ss3en/calculating_checksum_for_bitcoin_address/

NOTE: There was a digit off in the reference spec, this radius is a seven

digit number, not an eight digit number.


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/dropzone/item.rb', line 44

def receiver_addr
  case 
    when @receiver_addr then @receiver_addr
    when create_txid then @sender_addr
    when latitude && longitude && radius
      receiver_addr_base = ('%s%09d%09d%06d' % [
        (blockchain.is_testing?) ? 'mfZ' : ('1' + BitcoinConnection::PREFIX),
        latlon_to_integer(latitude.to_f), 
        latlon_to_integer(longitude.to_f, 180), 
        radius.abs ]).tr('0','X')

      # The x's pad the checksum component for us to ensure the base conversion
      # produces the correct output. Similarly, we ignore them after the decode:
      hex_address = Bitcoin.decode_base58(receiver_addr_base+'XXXXXXX')[0...42]

      hash160 = [hex_address].pack('H*')
       
      # Bitcoin-ruby has a method to do much of this for us, but it is 
      # broken in that it only supports main-net addresses, and not testnet3
      checksum = Digest::SHA256.digest(Digest::SHA256.digest(hash160))[0,4]
   
      # Return the checksum'd receiver_addr
      Bitcoin.encode_base58((hash160 + checksum).unpack('H*').first)
    else 
      nil
  end
end