lian / bitcoin-ruby

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

Did anyone make transaction using multiple transactions ? #241

Closed cfcayan closed 6 years ago

cfcayan commented 6 years ago

For instance you want to sent 0.8 btc, but you have 0.4 btc from last transaction, and 2 btc in second transaction. ` how to use 0.4 from first, and 1.6 from second I wrote some example, but I had some error, (transaction didn't verified)

[](require_relative './connect' class CreateTransaction

def self.check_address(address, currency, value_to_send) url = "https://#{Connect.api_by_number(currency)}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"] get_transaction(address, currency, transactions, 0, value_to_send) end end

def self.get_transaction(address, currency, transactions, transaction_id, value_to_send) prev_hash = transactions[0] puts prev_hash

url = "https://#{Connect.api_by_number(currency)}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'].to_s
  prev_tx = Bitcoin::P::Tx.new(response.htb)
  sell_currency(address, value_to_send, currency, prev_tx, transactions, transaction_id)
end

end

def self.get_transaction_recursive(address, currency, transactions, transaction_id, value_to_send) prev_hash = transactions[transaction_id] puts prev_hash url = "https://#{Connect.api_by_number(currency)}blockexplorer.com/api/rawtx/#{prev_hash}" p url uri = URI(url) response = Net::HTTP.get(uri) if Connect.valid_json(response) response = JSON.parse(response) response = response['rawtx'].to_s prev_tx = Bitcoin::P::Tx.new(response.htb) return prev_tx end end

def self.sell_currency(address, value_to_send, currency, prev_tx, transactions, transaction_id) Bitcoin.network = Connect.network_by_number(currency) prev_tx_output_index = 0 value = prev_tx.outputs[prev_tx_output_index].value tx = Bitcoin::Protocol::Tx.new p value < value_to_send unless (value < value_to_send) new_transaction = get_transaction_recursive(address, currency, transactions, transaction_id + 1, value_to_send) value = value + new_transaction.outputs[prev_tx_output_index].value p value tx.add_in Bitcoin::Protocol::TxIn.new(new_transaction.binary_hash, prev_tx_output_index, 0) end fee = value_to_send 0.1 fee_for_miners = 100000 value_to_save = value - value_to_send - fee - fee_for_miners if (value_to_save > 0) tx.add_in Bitcoin::Protocol::TxIn.new(prev_tx.binary_hash, prev_tx_output_index, 0) tx.add_out Bitcoin::Protocol::TxOut.value_to_address(value_to_send + fee, Connect.address_by_currency(currency)) if (value_to_save > 100000) tx.add_out Bitcoin::Protocol::TxOut.value_to_address(value_to_save, address) end key = Bitcoin.open_key(Connect.get_private_key) # <- privkey sig = Bitcoin.sign_data(key, tx.signature_hash_for_input(0, prev_tx)) tx.in[0].script_sig = Bitcoin::Script.to_signature_pubkey_script(sig, [key.public_key_hex].pack("H"))

  tx = Bitcoin::Protocol::Tx.new(tx.to_payload)
  puts tx.verify_input_signature(0, prev_tx) == true
  puts tx.to_payload.unpack("H*")[0]
  if tx.verify_input_signature(0, prev_tx) == true
    txskel = tx.to_payload.unpack("H*")[0] # hex binary
    push_hex(txskel)
  end
end

end

def self.push_hex(txskel) curl -d "{'hex':'#{txskel.to_s}'}" https://testnet-api.smartbit.com.au/v1/blockchain/pushtx end

check_address("muLGqMS6tkqb9sBQ4sqeXjMzaV8rk8o3gv", 1, 8000000) end`)

lian commented 6 years ago

you need to handle and sign each input you want to redeem. 0.4 and 1.6

lian commented 6 years ago

but those are all pretty basic bitcoin questions. i don't want this to become a support forum.