monacoin-ruby 0.1.2 → 0.1.3

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.
@@ -0,0 +1,130 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require 'socket'
4
+ require 'eventmachine'
5
+ require 'bitcoin'
6
+ require 'resolv'
7
+
8
+ module Bitcoin
9
+
10
+ module ConnectionHandler
11
+ def on_inv_transaction(hash)
12
+ p ['inv transaction', hash.hth]
13
+ pkt = Protocol.getdata_pkt(:tx, [hash])
14
+ send_data(pkt)
15
+ end
16
+
17
+ def on_inv_block(hash)
18
+ p ['inv block', hash.hth]
19
+ pkt = Protocol.getdata_pkt(:block, [hash])
20
+ send_data(pkt)
21
+ end
22
+
23
+ def on_get_transaction(hash)
24
+ p ['get transaction', hash.hth]
25
+ end
26
+
27
+ def on_get_block(hash)
28
+ p ['get block', hash.hth]
29
+ end
30
+
31
+ def on_addr(addr)
32
+ p ['addr', addr, addr.alive?]
33
+ end
34
+
35
+ def on_tx(tx)
36
+ p ['tx', tx.hash]
37
+ end
38
+
39
+ def on_block(block)
40
+ p ['block', block.hash]
41
+ #p block.payload.each_byte.map{|i| "%02x" % [i] }.join(" ")
42
+ #puts block.to_json
43
+ end
44
+
45
+ def on_version(version)
46
+ p [@sockaddr, 'version', version, version.time - Time.now.to_i]
47
+ send_data( Protocol.verack_pkt )
48
+ end
49
+
50
+ def on_verack
51
+ on_handshake_complete
52
+ end
53
+
54
+ def on_handshake_complete
55
+ p [@sockaddr, 'handshake complete']
56
+ @connected = true
57
+
58
+ query_blocks
59
+ end
60
+
61
+ def query_blocks
62
+ start = ("\x00"*32)
63
+ stop = ("\x00"*32)
64
+ pkt = Protocol.pkt("getblocks", "\x00" + start + stop )
65
+ send_data(pkt)
66
+ end
67
+
68
+ def on_handshake_begin
69
+ block = 127953
70
+ from = "127.0.0.1:8333"
71
+ from_id = Bitcoin::Protocol::Uniq
72
+ to = @sockaddr.reverse.join(":")
73
+ # p "==", from_id, from, to, block
74
+ pkt = Protocol.version_pkt(from_id, from, to, block)
75
+ p ['sending version pkt', pkt]
76
+ send_data(pkt)
77
+ end
78
+ end
79
+
80
+
81
+ class Connection < EM::Connection
82
+ include ConnectionHandler
83
+
84
+ def initialize(host, port, connections)
85
+ @sockaddr = [port, host]
86
+ @connections = connections
87
+ @parser = Bitcoin::Protocol::Parser.new( self )
88
+ end
89
+
90
+ def post_init
91
+ p ['connected', @sockaddr]
92
+ EM.schedule{ on_handshake_begin }
93
+ end
94
+
95
+ def receive_data(data)
96
+ @parser.parse(data)
97
+ end
98
+
99
+ def unbind
100
+ p ['disconnected', @sockaddr]
101
+ self.class.connect_random_from_dns(@connections)
102
+ end
103
+
104
+ def self.connect(host, port, connections)
105
+ EM.connect(host, port, self, host, port, connections)
106
+ end
107
+
108
+ def self.connect_random_from_dns(connections)
109
+ seeds = Bitcoin.network[:dns_seeds]
110
+ if seeds.any?
111
+ host = Resolv::DNS.new.getaddresses(seeds.sample).map {|a| a.to_s}.sample
112
+ connect(host, Bitcoin::network[:default_port], connections)
113
+ else
114
+ raise "No DNS seeds available. Provide IP, configure seeds, or use different network."
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+
121
+ if $0 == __FILE__
122
+ EM.run do
123
+
124
+ connections = []
125
+ #Bitcoin::Connection.connect('127.0.0.1', 8333, connections)
126
+ #Bitcoin::Connection.connect('217.157.1.202', 8333, connections)
127
+ Bitcoin::Connection.connect_random_from_dns(connections)
128
+
129
+ end
130
+ end
@@ -0,0 +1,76 @@
1
+ #
2
+ # Ruby port of https://github.com/Blockstream/contracthashtool
3
+ #
4
+
5
+ module Bitcoin
6
+ module ContractHash
7
+
8
+ HMAC_DIGEST = OpenSSL::Digest.new("SHA256")
9
+ EC_GROUP = OpenSSL::PKey::EC::Group.new("secp256k1")
10
+
11
+ def self.hmac(pubkey, data)
12
+ OpenSSL::HMAC.hexdigest(HMAC_DIGEST, pubkey, data)
13
+ end
14
+
15
+ # generate a contract address
16
+ def self.generate(redeem_script_hex, payee_address_or_ascii, nonce_hex=nil)
17
+ redeem_script = Bitcoin::Script.new([redeem_script_hex].pack("H*"))
18
+ raise "only multisig redeem scripts are currently supported" unless redeem_script.is_multisig?
19
+ nonce_hex, data = compute_data(payee_address_or_ascii, nonce_hex)
20
+
21
+ derived_keys = []
22
+ redeem_script.get_multisig_pubkeys.each do |pubkey|
23
+ tweak = hmac(pubkey, data).to_i(16)
24
+ raise "order exceeded, pick a new nonce" if tweak >= EC_GROUP.order.to_i
25
+ tweak = OpenSSL::BN.new(tweak.to_s)
26
+
27
+ key = Bitcoin::Key.new(nil, pubkey.unpack("H*")[0])
28
+ key = key.instance_variable_get(:@key)
29
+ point = EC_GROUP.generator.mul(tweak).ec_add(key.public_key).to_bn.to_i
30
+ raise "infinity" if point == 1/0.0
31
+
32
+ key = Bitcoin::Key.new(nil, point.to_s(16))
33
+ key.instance_eval{ @pubkey_compressed = true }
34
+ derived_keys << key.pub
35
+ end
36
+
37
+ m = redeem_script.get_signatures_required
38
+ p2sh_script, redeem_script = Bitcoin::Script.to_p2sh_multisig_script(m, *derived_keys)
39
+
40
+ [ nonce_hex, redeem_script.unpack("H*")[0], Bitcoin::Script.new(p2sh_script).get_p2sh_address ]
41
+ end
42
+
43
+ # claim a contract
44
+ def self.claim(private_key_wif, payee_address_or_ascii, nonce_hex)
45
+ key = Bitcoin::Key.from_base58(private_key_wif)
46
+ data = compute_data(payee_address_or_ascii, nonce_hex)[1]
47
+
48
+ pubkey = [key.pub].pack("H*")
49
+ tweak = hmac(pubkey, data).to_i(16)
50
+ raise "order exceeded, verify parameters" if tweak >= EC_GROUP.order.to_i
51
+
52
+ derived_key = (tweak + key.priv.to_i(16)) % EC_GROUP.order.to_i
53
+ raise "zero" if derived_key == 0
54
+
55
+ Bitcoin::Key.new(derived_key.to_s(16))
56
+ end
57
+
58
+ # compute HMAC data
59
+ def self.compute_data(address_or_ascii, nonce_hex)
60
+ nonce = nonce_hex ? [nonce_hex].pack("H32") : SecureRandom.random_bytes(16)
61
+ if Bitcoin.valid_address?(address_or_ascii)
62
+ address_type = case Bitcoin.address_type(address_or_ascii)
63
+ when :hash160; 'P2PH'
64
+ when :p2sh; 'P2SH'
65
+ else
66
+ raise "unsupported address type #{address_type}"
67
+ end
68
+ contract_bytes = [ Bitcoin.hash160_from_address(address_or_ascii) ].pack("H*")
69
+ else
70
+ address_type = "TEXT"
71
+ contract_bytes = address_or_ascii
72
+ end
73
+ [ nonce.unpack("H*")[0], address_type + nonce + contract_bytes ]
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,97 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # This module includes (almost) everything necessary to add dogecoin support
4
+ # to bitcoin-ruby. When switching to a :dogecoin network, it will load its
5
+ # functionality into the Script class.
6
+ # The only things not included here should be parsing the AuxPow, which is
7
+ # done in Protocol::Block directly, and passing the txout to #store_doge from
8
+ # the storage backend.
9
+ module Bitcoin::Dogecoin
10
+
11
+ def self.load
12
+ Bitcoin::Util.class_eval { include Util }
13
+ end
14
+
15
+ # fixed reward past the 600k block
16
+ POST_600K_REWARD = 10000 * Bitcoin::COIN
17
+
18
+ # Dogecoin-specific Script methods for parsing and creating of dogecoin scripts,
19
+ # as well as methods to extract address, doge_hash, doge and value.
20
+ module Util
21
+
22
+ def self.included(base)
23
+ base.constants.each {|c| const_set(c, base.const_get(c)) unless constants.include?(c) }
24
+ base.class_eval do
25
+
26
+ def block_creation_reward(block_height)
27
+ if block_height < Bitcoin.network[:difficulty_change_block]
28
+ # Dogecoin early rewards were random, using part of the hash of the
29
+ # previous block as the seed for the Mersenne Twister algorithm.
30
+ # Given we don't have previous block hash available, and this value is
31
+ # functionally a maximum (not exact value), I'm using the maximum the random
32
+ # reward generator can produce and calling it good enough.
33
+ Bitcoin.network[:reward_base] / (2 ** (block_height / Bitcoin.network[:reward_halving].to_f).floor) * 2
34
+ elsif block_height < 600000
35
+ Bitcoin.network[:reward_base] / (2 ** (block_height / Bitcoin.network[:reward_halving].to_f).floor)
36
+ else
37
+ POST_600K_REWARD
38
+ end
39
+ end
40
+
41
+ def block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
42
+ new_difficulty_protocol = (prev_height + 1) >= Bitcoin.network[:difficulty_change_block]
43
+
44
+ # target interval for block interval in seconds
45
+ retarget_time = Bitcoin.network[:retarget_time]
46
+
47
+ if new_difficulty_protocol
48
+ # what is the ideal interval between the blocks
49
+ retarget_time = Bitcoin.network[:retarget_time_new]
50
+ end
51
+
52
+ # actual time elapsed since last retarget
53
+ actual_time = prev_block_time - last_retarget_time
54
+
55
+ if new_difficulty_protocol
56
+ # DigiShield implementation - thanks to RealSolid & WDC for this code
57
+ # We round always towards zero to match the C++ version
58
+ if actual_time < retarget_time
59
+ actual_time = retarget_time + ((actual_time - retarget_time) / 8.0).ceil
60
+ else
61
+ actual_time = retarget_time + ((actual_time - retarget_time) / 8.0).floor
62
+ end
63
+ # amplitude filter - thanks to daft27 for this code
64
+ min = retarget_time - (retarget_time/4)
65
+ max = retarget_time + (retarget_time/2)
66
+ elsif prev_height+1 > 10000
67
+ min = retarget_time / 4
68
+ max = retarget_time * 4
69
+ elsif prev_height+1 > 5000
70
+ min = retarget_time / 8
71
+ max = retarget_time * 4
72
+ else
73
+ min = retarget_time / 16
74
+ max = retarget_time * 4
75
+ end
76
+
77
+ actual_time = min if actual_time < min
78
+ actual_time = max if actual_time > max
79
+
80
+ # It could be a bit confusing: we are adjusting difficulty of the previous block, while logically
81
+ # we should use difficulty of the previous 2016th block ("first")
82
+
83
+ prev_target = decode_compact_bits(prev_block_bits).to_i(16)
84
+
85
+ new_target = prev_target * actual_time / retarget_time
86
+ if new_target < Bitcoin.decode_compact_bits(Bitcoin.network[:proof_of_work_limit]).to_i(16)
87
+ encode_compact_bits(new_target.to_s(16))
88
+ else
89
+ Bitcoin.network[:proof_of_work_limit]
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,162 @@
1
+ # encoding: ascii-8bit
2
+
3
+ class Mnemonic
4
+ # ruby version of: https://github.com/spesmilo/electrum/blob/master/lib/mnemonic.py
5
+
6
+ # list of words from http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists/Contemporary_poetry
7
+ Words = (<<-TEXT).split
8
+ like just love know never want time out there make look eye down only think
9
+ heart back then into about more away still them take thing even through long always
10
+ world too friend tell try hand thought over here other need smile again much cry
11
+ been night ever little said end some those around mind people girl leave dream left
12
+ turn myself give nothing really off before something find walk wish good once place ask
13
+ stop keep watch seem everything wait got yet made remember start alone run hope maybe
14
+ believe body hate after close talk stand own each hurt help home god soul new
15
+ many two inside should true first fear mean better play another gone change use wonder
16
+ someone hair cold open best any behind happen water dark laugh stay forever name work
17
+ show sky break came deep door put black together upon happy such great white matter
18
+ fill past please burn cause enough touch moment soon voice scream anything stare sound red
19
+ everyone hide kiss truth death beautiful mine blood broken very pass next forget tree wrong
20
+ air mother understand lip hit wall memory sleep free high realize school might skin sweet
21
+ perfect blue kill breath dance against fly between grow strong under listen bring sometimes speak
22
+ pull person become family begin ground real small father sure feet rest young finally land
23
+ across today different guy line fire reason reach second slowly write eat smell mouth step
24
+ learn three floor promise breathe darkness push earth guess save song above along both color
25
+ house almost sorry anymore brother okay dear game fade already apart warm beauty heard notice
26
+ question shine began piece whole shadow secret street within finger point morning whisper child moon
27
+ green story glass kid silence since soft yourself empty shall angel answer baby bright dad
28
+ path worry hour drop follow power war half flow heaven act chance fact least tired
29
+ children near quite afraid rise sea taste window cover nice trust lot sad cool force
30
+ peace return blind easy ready roll rose drive held music beneath hang mom paint emotion
31
+ quiet clear cloud few pretty bird outside paper picture front rock simple anyone meant reality
32
+ road sense waste bit leaf thank happiness meet men smoke truly decide self age book
33
+ form alive carry escape damn instead able ice minute throw catch leg ring course goodbye
34
+ lead poem sick corner desire known problem remind shoulder suppose toward wave drink jump woman
35
+ pretend sister week human joy crack grey pray surprise dry knee less search bleed caught
36
+ clean embrace future king son sorrow chest hug remain sat worth blow daddy final parent
37
+ tight also create lonely safe cross dress evil silent bone fate perhaps anger class scar
38
+ snow tiny tonight continue control dog edge mirror month suddenly comfort given loud quickly gaze
39
+ plan rush stone town battle ignore spirit stood stupid yours brown build dust hey kept
40
+ pay phone twist although ball beyond hidden nose taken fail float pure somehow wash wrap
41
+ angry cheek creature forgotten heat rip single space special weak whatever yell anyway blame job
42
+ choose country curse drift echo figure grew laughter neck suffer worse yeah disappear foot forward
43
+ knife mess somewhere stomach storm beg idea lift offer breeze field five often simply stuck
44
+ win allow confuse enjoy except flower seek strength calm grin gun heavy hill large ocean
45
+ shoe sigh straight summer tongue accept crazy everyday exist grass mistake sent shut surround table
46
+ ache brain destroy heal nature shout sign stain choice doubt glance glow mountain queen stranger
47
+ throat tomorrow city either fish flame rather shape spin spread ash distance finish image imagine
48
+ important nobody shatter warmth became feed flesh funny lust shirt trouble yellow attention bare bite
49
+ money protect amaze appear born choke completely daughter fresh friendship gentle probably six deserve expect
50
+ grab middle nightmare river thousand weight worst wound barely bottle cream regret relationship stick test
51
+ crush endless fault itself rule spill art circle join kick mask master passion quick raise
52
+ smooth unless wander actually broke chair deal favorite gift note number sweat box chill clothes
53
+ lady mark park poor sadness tie animal belong brush consume dawn forest innocent pen pride
54
+ stream thick clay complete count draw faith press silver struggle surface taught teach wet bless
55
+ chase climb enter letter melt metal movie stretch swing vision wife beside crash forgot guide
56
+ haunt joke knock plant pour prove reveal steal stuff trip wood wrist bother bottom crawl
57
+ crowd fix forgive frown grace loose lucky party release surely survive teacher gently grip speed
58
+ suicide travel treat vein written cage chain conversation date enemy however interest million page pink
59
+ proud sway themselves winter church cruel cup demon experience freedom pair pop purpose respect shoot
60
+ softly state strange bar birth curl dirt excuse lord lovely monster order pack pants pool
61
+ scene seven shame slide ugly among blade blonde closet creek deny drug eternity gain grade
62
+ handle key linger pale prepare swallow swim tremble wheel won cast cigarette claim college direction
63
+ dirty gather ghost hundred loss lung orange present swear swirl twice wild bitter blanket doctor
64
+ everywhere flash grown knowledge numb pressure radio repeat ruin spend unknown buy clock devil early
65
+ false fantasy pound precious refuse sheet teeth welcome add ahead block bury caress content depth
66
+ despite distant marry purple threw whenever bomb dull easily grasp hospital innocence normal receive reply
67
+ rhyme shade someday sword toe visit asleep bought center consider flat hero history ink insane
68
+ muscle mystery pocket reflection shove silently smart soldier spot stress train type view whether bus
69
+ energy explain holy hunger inch magic mix noise nowhere prayer presence shock snap spider study
70
+ thunder trail admit agree bag bang bound butterfly cute exactly explode familiar fold further pierce
71
+ reflect scent selfish sharp sink spring stumble universe weep women wonderful action ancient attempt avoid
72
+ birthday branch chocolate core depress drunk especially focus fruit honest match palm perfectly pillow pity
73
+ poison roar shift slightly thump truck tune twenty unable wipe wrote coat constant dinner drove
74
+ egg eternal flight flood frame freak gasp glad hollow motion peer plastic root screen season
75
+ sting strike team unlike victim volume warn weird attack await awake built charm crave despair
76
+ fought grant grief horse limit message ripple sanity scatter serve split string trick annoy blur
77
+ boat brave clearly cling connect fist forth imagination iron jock judge lesson milk misery nail
78
+ naked ourselves poet possible princess sail size snake society stroke torture toss trace wise bloom
79
+ bullet cell check cost darling during footstep fragile hallway hardly horizon invisible journey midnight mud
80
+ nod pause relax shiver sudden value youth abuse admire blink breast bruise constantly couple creep
81
+ curve difference dumb emptiness gotta honor plain planet recall rub ship slam soar somebody tightly
82
+ weather adore approach bond bread burst candle coffee cousin crime desert flutter frozen grand heel
83
+ hello language level movement pleasure powerful random rhythm settle silly slap sort spoken steel threaten
84
+ tumble upset aside awkward bee blank board button card carefully complain crap deeply discover drag
85
+ dread effort entire fairy giant gotten greet illusion jeans leap liquid march mend nervous nine
86
+ replace rope spine stole terror accident apple balance boom childhood collect demand depression eventually faint
87
+ glare goal group honey kitchen laid limb machine mere mold murder nerve painful poetry prince
88
+ rabbit shelter shore shower soothe stair steady sunlight tangle tease treasure uncle begun bliss canvas
89
+ cheer claw clutch commit crimson crystal delight doll existence express fog football gay goose guard
90
+ hatred illuminate mass math mourn rich rough skip stir student style support thorn tough yard
91
+ yearn yesterday advice appreciate autumn bank beam bowl capture carve collapse confusion creation dove feather
92
+ girlfriend glory government harsh hop inner loser moonlight neighbor neither peach pig praise screw shield
93
+ shimmer sneak stab subject throughout thrown tower twirl wow army arrive bathroom bump cease cookie
94
+ couch courage dim guilt howl hum husband insult led lunch mock mostly natural nearly needle
95
+ nerd peaceful perfection pile price remove roam sanctuary serious shiny shook sob stolen tap vain
96
+ void warrior wrinkle affection apologize blossom bounce bridge cheap crumble decision descend desperately dig dot
97
+ flip frighten heartbeat huge lazy lick odd opinion process puzzle quietly retreat score sentence separate
98
+ situation skill soak square stray taint task tide underneath veil whistle anywhere bedroom bid bloody
99
+ burden careful compare concern curtain decay defeat describe double dreamer driver dwell evening flare flicker
100
+ grandma guitar harm horrible hungry indeed lace melody monkey nation object obviously rainbow salt scratch
101
+ shown shy stage stun third tickle useless weakness worship worthless afternoon beard boyfriend bubble busy
102
+ certain chin concrete desk diamond doom drawn due felicity freeze frost garden glide harmony hopefully
103
+ hunt jealous lightning mama mercy peel physical position pulse punch quit rant respond salty sane
104
+ satisfy savior sheep slept social sport tuck utter valley wolf aim alas alter arrow awaken
105
+ beaten belief brand ceiling cheese clue confidence connection daily disguise eager erase essence everytime expression
106
+ fan flag flirt foul fur giggle glorious ignorance law lifeless measure mighty muse north opposite
107
+ paradise patience patient pencil petal plate ponder possibly practice slice spell stock strife strip suffocate
108
+ suit tender tool trade velvet verse waist witch aunt bench bold cap certainly click companion
109
+ creator dart delicate determine dish dragon drama drum dude everybody feast forehead former fright fully
110
+ gas hook hurl invite juice manage moral possess raw rebel royal scale scary several slight
111
+ stubborn swell talent tea terrible thread torment trickle usually vast violence weave acid agony ashamed
112
+ awe belly blend blush character cheat common company coward creak danger deadly defense define depend
113
+ desperate destination dew duck dusty embarrass engine example explore foe freely frustrate generation glove guilty
114
+ health hurry idiot impossible inhale jaw kingdom mention mist moan mumble mutter observe ode pathetic
115
+ pattern pie prefer puff rape rare revenge rude scrape spiral squeeze strain sunset suspend sympathy
116
+ thigh throne total unseen weapon weary
117
+ TEXT
118
+
119
+ def self.encode(hex, words=Words)
120
+ n = words.size
121
+ [hex].pack("H*").unpack("N*").map{|x|
122
+ w1 = x % n
123
+ w2 = ((x / n) + w1) % n
124
+ w3 = ((x / n / n) + w2) % n
125
+ [ words[w1], words[w2], words[w3] ]
126
+ }.flatten
127
+ end
128
+
129
+ def self.decode(word_list, words=Words)
130
+ n = words.size
131
+ word_list.each_slice(3).map{|three_words|
132
+ w1, w2, w3 = three_words.map{|word| words.index(word) % n }
133
+ '%08x' % ( w1 + n*((w2-w1)%n) + n*n*((w3-w2)%n) )
134
+ }.join
135
+ end
136
+
137
+ end
138
+
139
+
140
+
141
+ if $0 == __FILE__
142
+ hex = "4c7d10656aa55383a5d88e3f63300af5e169918f4058bf349d99b20239909b61"
143
+ expected_words = ['horse', 'love', 'nose', 'speak', 'diamond', 'gaze', 'wash', 'drag', 'glance',
144
+ 'money', 'cease', 'soft', 'complete', 'huge', 'aside', 'confusion', 'touch',
145
+ 'grass', 'pie', 'play', 'bread', 'exactly', 'bubble', 'great']
146
+
147
+ # from http://brainwallet.org/#chains
148
+ hex = "ff64b72c431f75799f0c5ebe438e46dd"
149
+ expected_words = %w[muscle lot sea got revenge crack wait yeah gas study embrace spend]
150
+ hex = "18cfaf96961750c7a4e4e39c861d1415"
151
+ expected_words = %w[example poor twice expect decision master blame rub forward easy jump carve]
152
+
153
+ # from https://en.bitcoin.it/wiki/Electrum#Brain_Wallet
154
+ hex = "431a62f1c86555d3c45e5c4d9e10c8c7"
155
+ expected_words = %w[constant forest adore false green weave stop guy fur freeze giggle clock]
156
+
157
+ #p Mnemonic.encode(hex)
158
+ p Mnemonic.encode(hex) == expected_words
159
+ #p Mnemonic.decode(expected_words)
160
+ p Mnemonic.decode(expected_words) == hex
161
+ end
162
+