How to send Bitcoin in the Testnet?

0

1

I'm using this library: https://github.com/lian/bitcoin-ruby

And here's my code:

require 'open-uri'
require 'net/http'
require 'net/https'
require 'json'

require 'bitcoin'

Bitcoin.network = :testnet3

def get_response(prev_tx)
  url = "https://testnet.blockexplorer.com/api/rawtx/#{prev_tx}"
  uri = URI(url)
  response = Net::HTTP.get(uri)
  response = JSON.parse(response)
  response = response['rawtx'].to_s
  return response
end

def build_transaction(prev_tx, prev_out_index, key, satoshi_to_spend, addr, message)
  include Bitcoin::Builder

  new_tx = build_tx do |t|
    t.input do |i|
      i.prev_out prev_tx
      i.prev_out_index prev_out_index
      i.signature_key key
    end
    t.output do |o|
      o.value satoshi_to_spend
      o.script {|s| s.type :address; s.recipient addr }
    end
  end
  puts ""
  puts "--- new tx ---"
  puts new_tx.to_json
  return new_tx
end

def bin_to_hex(s)
  s.unpack('H*').first
end

bitcoin_key_1_pub = "0367e6251a89c5afc1212c3e2169866ccfe9d6059a4cfc15dc139b534b974fd7ca"
bitcoin_key_1_priv = "*****24c56528becd02d23076123a2edc2f3cf52c3c0202178c1b7fa9ac*****"
bitcoin_key_1_addr = "mxz4hu6JrTHevn22W4GDVjS3ko9MwXuHND"

# the previous transaction that has an output to your address #1
prev_tx_1 = "427138ed5f2443fbfbf8065e990f1bf9ce0236e14376e8abca0b2876eabca653"

# the number of the output you want to use
prev_out_index = 1

# 0.5 BTC in satoshis
btc_to_spend = 0.5
satoshi_to_spend = btc_to_spend * 100000000

bitcoin_key_2_pub = "02989d0578f715a1980d4d6e968bcba487077e74aaf8a219d11ee4384ea1fc1eda"
bitcoin_key_2_priv = "*****cb521a27f9782cc503b461bf5c6b470469ca00ba1d7dc26f4ab61b*****"
bitcoin_key_2_addr = "n4SYP6TJyK7pUouW65fnC1hDBrbb7Za8RR"

# fetch the tx from whereever you like and parse it
response = get_response(prev_tx_1)
$prev_tx = Bitcoin::P::Tx.new(response.htb)
prev_tx = $prev_tx

tx_value = prev_tx.outputs[prev_out_index].value
puts "tx_value: #{tx_value}"

key = Bitcoin::Key.new(bitcoin_key_1_priv, bitcoin_key_1_pub)
tx = build_transaction(prev_tx, prev_out_index, key, satoshi_to_spend, bitcoin_key_2_addr, "hello")

puts ""
puts "--- bin_to_hex ---"
puts bin_to_hex(tx.to_payload)

Here's the output:

➜  examples git:(master) ✗ ruby sandbox.rb

tx_value: 75972791
/Users/glaksmono/.rvm/gems/ruby-2.4.2/gems/bitcoin-ruby-0.0.18/lib/bitcoin/script.rb:281: warning: constant ::Fixnum is deprecated
/Users/glaksmono/.rvm/gems/ruby-2.4.2/gems/bitcoin-ruby-0.0.18/lib/bitcoin/script.rb:455: warning: constant ::Fixnum is deprecated

--- new tx ---
/Users/glaksmono/.rvm/gems/ruby-2.4.2/gems/bitcoin-ruby-0.0.18/lib/bitcoin/script.rb:261: warning: constant ::Fixnum is deprecated
{
  "hash":"88217866a40829f144e2d2c19b2e506812ae013d08d9335ce8fa839582f1b18e",
  "ver":1,
  "vin_sz":1,
  "vout_sz":1,
  "lock_time":0,
  "size":191,
  "in":[
    {
      "prev_out":{
        "hash":"427138ed5f2443fbfbf8065e990f1bf9ce0236e14376e8abca0b2876eabca653",
        "n":1
      },
      "scriptSig":"304402201cf2d99b7f10c71a1c77ae629ec134a3f255c0027f47815aff3e43d500e6da46022008409ea148d6cce6876910c7a7218b8197c3a827a6a7bf3d5f064a3ed3a0616701 0367e6251a89c5afc1212c3e2169866ccfe9d6059a4cfc15dc139b534b974fd7ca"
    }
  ],
  "out":[
    {
      "value":"0.50000000",
      "scriptPubKey":"OP_DUP OP_HASH160 fb75447d6038b05bb736e5b05f18a3c9da2b34db OP_EQUALVERIFY OP_CHECKSIG"
    }
  ]
}

--- bin_to_hex ---
010000000153a6bcea76280bcaabe87643e13602cef91b0f995e06f8fbfb43245fed387142010000006a47304402201cf2d99b7f10c71a1c77ae629ec134a3f255c0027f47815aff3e43d500e6da46022008409ea148d6cce6876910c7a7218b8197c3a827a6a7bf3d5f064a3ed3a0616701210367e6251a89c5afc1212c3e2169866ccfe9d6059a4cfc15dc139b534b974fd7caffffffff0180f0fa02000000001976a914fb75447d6038b05bb736e5b05f18a3c9da2b34db88ac00000000

It seems to be successful, but I don't see the BTC actually transferred from bitcoin_key_1_addr to bitcoin_key_2_addr on the Blockcypher Explorer:

As you notice in the Blockcypher Explorer, the BTC amount is not yet transferred from bitcoin_key_1_addr to bitcoin_key_2_addr. Ideas?

Grady

Posted 2018-04-26T05:44:37.793

Reputation: 113

Did you broadcast the transaction? I don't see any code that looks like the transaction is actually being sent to the network. A transaction needs to be broadcast before it can be seen by block explorers and included in the blockchain by miners.Andrew Chow 2018-04-26T16:50:22.683

@AndrewChow very good point - any ideas how to do that in bitcoin-ruby?Grady 2018-04-26T17:04:33.247

I figured, you need to use this: https://live.blockcypher.com/btc-testnet/pushtx/ but then I'm getting an error saying that the transaction has "too high fees", ideas? @AndrewChow

Grady 2018-04-26T17:11:19.060

You can use that to broadcast. If you get an error, then you probably built your transaction wrong. Too-high-fees usually means that you did not create a change output so the change ends up all going to fees.Andrew Chow 2018-04-26T17:14:50.167

Did you see anything wrong with my code above? Not really sure which part of it was wrong @AndrewChowGrady 2018-04-27T03:54:27.303

The problem is that you are only creating one output whereas you need to have two outputs, the second being for the change output. The change output is exactly like any other output except that the output is spendable by you, not by your recipient.Andrew Chow 2018-04-27T03:57:03.933

@AndrewChow I don't understand. Do you have a sample code I can take a look?Grady 2018-04-27T05:02:04.607

It seems you are having a hard time grasping the idea of change. Since this is testnet, just make your output value almost match the input value. I say almost match because you will still need a transaction fee.Andrew Chow 2018-04-27T05:17:49.150

Answers

0

Decided to use BlockCypher API, and it just works. Just follow this CURL example: https://gist.githubusercontent.com/matthieu/b07c5ba27bc99188a15f/raw/870a9d0e1bdd05a6230acde359e6953add15621a/gistfile1.sh

And you can always translate that into whatever language you want to use. In my case I'm using Ruby.

Grady

Posted 2018-04-26T05:44:37.793

Reputation: 113