lian / bitcoin-ruby

bitcoin utils and protocol in ruby.
Other
922 stars 322 forks source link

Cannot create transaction #240

Closed cfcayan closed 6 years ago

cfcayan commented 6 years ago

Could you please suggest me what to do?

/var/lib/gems/2.3.0/gems/bitcoin-ruby-0.0.14/lib/bitcoin/builder.rb:415:in has_keys?': undefined methodpriv' for # (NoMethodError) from /var/lib/gems/2.3.0/gems/bitcoin-ruby-0.0.14/lib/bitcoin/builder.rb:222:in sig_hash_and_all_keys_exist?' from /var/lib/gems/2.3.0/gems/bitcoin-ruby-0.0.14/lib/bitcoin/builder.rb:282:insign_input' from /var/lib/gems/2.3.0/gems/bitcoin-ruby-0.0.14/lib/bitcoin/builder.rb:201:in block in tx' from /var/lib/gems/2.3.0/gems/bitcoin-ruby-0.0.14/lib/bitcoin/builder.rb:200:ineach' from /var/lib/gems/2.3.0/gems/bitcoin-ruby-0.0.14/lib/bitcoin/builder.rb:200:in each_with_index' from /var/lib/gems/2.3.0/gems/bitcoin-ruby-0.0.14/lib/bitcoin/builder.rb:200:intx' from /var/lib/gems/2.3.0/gems/bitcoin-ruby-0.0.14/lib/bitcoin/builder.rb:23:in `build_tx'

` include Bitcoin::Builder

Bitcoin.network = :testnet3

address="muLGqMS6tkqb9sBQ4sqeXjMzaV8rk8o3gv"

url = "https://testnet.blockexplorer.com/api/addr/#{address}" uri = URI(url) response = Net::HTTP.get(uri) if Connect.valid_json(response) response = JSON.parse(response) $transactions = response["transactions"] end puts $transactions

prev_hash = $transactions[0]

url = "https://testnet.blockexplorer.com/api/rawtx/#{prev_hash}" uri = URI(url) response = Net::HTTP.get(uri) if Connect.valid_json(response) response = JSON.parse(response) $prev_tx = Bitcoin::P::Tx.new("#{response['rawtx']}".htb) end

key = Connect.get_private_key

new_tx = build_tx do |t|

add the input you picked out earlier

t.input do |i| i.prev_out $prev_tx i.prev_out_index 0 i.signature_key key end

add an output that sends some bitcoins to another address

t.output do |o| o.value 500000 # 0.005 BTC in satoshis o.script {|s| s.recipient "mmCzhx3eUqv6t43adPtHzWmP4JavGMwF1d" } end end

puts new_tx.to_json`

longhoangwkm commented 6 years ago

key is Bitcoin::Key object not string, You should import like this key = Bitcoin::Key.from_base58("92ZRu28m2GHSKaaF2W7RswJ2iJYpTzVhBaN6ZLs7TENCs4b7ML8")

cfcayan commented 6 years ago

@longhoangwkm thank you! But how to encode private key correctly to base58? given function is not working

longhoangwkm commented 6 years ago

show me your Connect.get_private_key method, what did you do with this method and the way you generated pk

cfcayan commented 6 years ago

@longhoangwkm key = Bitcoin::generate_key private_key = key[0].to_s

longhoangwkm commented 6 years ago

you can use pk_base58 = Bitcoin::Key.generate.to_base58 then Bitcoin::Key.from_base58(pk_base58)

cfcayan commented 6 years ago

@longhoangwkm I did as you said. by the way, there is an error in `sig_hash_and_all_keys_exist?': Script type must be hash160, pubkey, p2wpkh or multisig (RuntimeError)

Bitcoin.network = :testnet3

address="mjAmDuHnTHm7aJHTXbAejKitgUWUofPjMK"

url = "https://testnet.blockexplorer.com/api/addr/#{address}" uri = URI(url) response = Net::HTTP.get(uri) if Connect.valid_json(response) response = JSON.parse(response) $transactions = response["transactions"] end

prev_hash = $transactions[0]

url = "https://testnet.blockexplorer.com/api/rawtx/#{prev_hash}" uri = URI(url) response = Net::HTTP.get(uri) if Connect.valid_json(response) response = JSON.parse(response) response= response['rawtx'] $prev_tx = Bitcoin::P::Tx.new(response.htb) end

key = Bitcoin::Key.from_base58(Connect.get_private_key)

new_tx = build_tx do |t|

add the input you picked out earlier

t.input do |i| i.prev_out $prev_tx i.prev_out_index 1 i.signature_key key end

add an output that sends some bitcoins to another address

t.output do |o| o.value 50000 # 0.0005 BTC in satoshis o.script {|s| s.recipient "n4HZeZmQT4CnmrHKrJ83Yer7QVLoh8jSmm" } end end

puts new_tx.to_json p "verified? #{new_tx.verify_input_signature(0, $prev_tx)}"

longhoangwkm commented 6 years ago

https://github.com/lian/bitcoin-ruby/blob/master/examples/generate_tx.rb you can try this way, i dont use build_tx method. p/s: this way use private_key hex format, so you dont need to use to_base58

longhoangwkm commented 6 years ago

btw, you should wrap code with markdown syntax

cfcayan commented 6 years ago

@longhoangwkm exactly! it works, but how to send/push to network?

longhoangwkm commented 6 years ago

You can use third party api such as blockcypher to broadcast on the Bitcoin network like this https://www.blockcypher.com/dev/bitcoin/#push-raw-transaction-endpoint Or in hardcore way you use openassets-ruby to push transaction into bitcoind(install yourself)

cfcayan commented 6 years ago

@longhoangwkm Error sending transaction: Transaction 4a762238529450737b85ad481deae0e836e623afd63e04a29a5b90363c0345fd has too high fees: 12372992. I have an error. What do you think about it?

cfcayan commented 6 years ago

@longhoangwkm I solved this question. By the way, why I cannot use some part of received money. I mean that my address took 1.3 btc, and I tried to use 0.5 btc from transaction to send another address. but it shown error given above. When I tried to send all volume, it uploaded to network

lian commented 6 years ago

@cfcayan bitcoin doesn't work like that, you can't just use some amount of a transaction. you always have to use the full amount of the input you are redeeming, the rest is miner fees otherwise. to send your 0.5 btc you have to make two outputs, 0.5 and 0.7.

@longhoangwkm without any safe guards, sending via examples/simple_network_monitor_and_util.rb works too