lian / bitcoin-ruby

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

undefined method `each' for nil:NilClass (NoMethodError) #313

Closed Matthiasclee closed 2 years ago

Matthiasclee commented 2 years ago

Whenever I use i.prev_out Bitcoin::P::Tx.from_json( Net::HTTP.get(URI("https://blockstream.info/api/tx/#{txn_hash}")) ) in the inputs of a transaction, I get /Users/matthiaslee/.rvm/gems/ruby-2.7.5/bundler/gems/bitcoin-ruby-f9b817c946b3/lib/bitcoin/protocol/txin.rb:117:in `from_hash': undefined method `each' for #<String:0x00007ff983a8cf58> (NoMethodError). The JSON that it is given is here. Is there something wrong with how I am setting the prev_out or should I be pulling tx data from somewhere else?

azuchi commented 2 years ago

from_json depends on a specific JSON format, and various APIs do not use the same format. Therefore, I recommend using raw tx as mentioned in previous Issue responses.

https://github.com/lian/bitcoin-ruby/issues/280#issuecomment-421801721

Matthiasclee commented 2 years ago

Will look into that. Are there any apis you know that send it in the correct format?

Matthiasclee commented 2 years ago

If not, is there a way to download the raw txns from the internet as I want to avoid running my own node

azuchi commented 2 years ago

You can get raw tx in hex format by setting the ?format=hex parameter in the URL like:

https://blockchain.info/rawtx/76cf8510596bffaf5f99d3202860a6cf7ac4c14f8da5092545572916a99eebd6?format=hex

Matthiasclee commented 2 years ago

It seems that that works but now I get /Users/matthiaslee/.rvm/gems/ruby-2.7.5/bundler/gems/bitcoin-ruby-f9b817c946b3/lib/bitcoin/builder.rb:401:in 'prev_out_index': undefined method 'pk_script' for nil:NilClass (NoMethodError). When I look at the JSON transaction, it seems that the index I am trying to use (0) does exist.

Matthiasclee commented 2 years ago

Here is the code:

    key = Bitcoin::Key.from_base58($PRIV_KEY)

    new_tx = build_tx do |t| 

        t.input do |i| 
          rawtx = Net::HTTP.get(URI("https://blockchain.info/rawtx/#{txn_hash}?format=hex"))

          i.prev_out Bitcoin::Protocol::Tx.new(rawtx)

          i.prev_out_index index # Index is 0

          i.signature_key key 
        end 

      # add an output that sends some bitcoins to another address
      t.output do |o| 
        o.value 3333
        o.script {|s| s.recipient "#{to_addr}" }
      end 

      # add another output spending the remaining amount back to yourself
      # if you want to pay a tx fee, reduce the value of this output accordingly
      # if you want to keep your financial history private, use a different address
      t.output do |o| 
        o.value 1000
        o.script {|s| s.recipient key.addr }
      end 

    end 
azuchi commented 2 years ago

Bitcoin::Protocol::Tx.new requires binary format, so you have to convert data.

Bitcoin::Protocol::Tx.new([rawtx].pack('H*'))
Matthiasclee commented 2 years ago

Hmm. Now I get a undefined method 'bytesize' for nil:NilClass (NoMethodError)...

Matthiasclee commented 2 years ago

Nevermind, I still had a testnet addr in the out