monacoin-ruby 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+