lian / bitcoin-ruby

bitcoin utils and protocol in ruby.
Other
923 stars 323 forks source link

can not sign raw transaction with hardened key #238

Closed SFzxc closed 6 years ago

SFzxc commented 6 years ago

require 'bitcoin'
require 'open-uri'
require 'pry'

include Bitcoin::Builder
Bitcoin.network = :testnet3

sender_addr    = 'mw8arBSNVpm1dL1zwwCQM9pZ9D2dbxWPe5'
private_key    = '74b332bb6b56e353d1edfe5b09a8e79da1e61e203837a4324d9c3ff1bfe761ab' # hex format
recipient_addr = 'mypcUU2fYyJav7XUpPLtMVhuPupArLJtiM'
change_addr    = 'mh4wVkmhu8Ry6nqFSpe7yNn94P5DeG7cYs'

# MoneyTree::Node.from_bip32('tprv...')
#        .node_for_path("m/0/0'/0/21/19")
#        .private_key
#        .to_wif(network: :bitcoin_testnet)
#
# cRVYvQsd6fs835rT8C6o1vVX1f4xUCzqdxNNuaHzfSmXaBEYVhm3
#
# Import from wif format
key = Bitcoin::Key.from_base58('cRVYvQsd6fs835rT8C6o1vVX1f4xUCzqdxNNuaHzfSmXaBEYVhm3')

# prev_tx_hash: 4bbd47c3a291f495cc536b70e821e2f950c09f604a64dd90e3b561a761834133
prev_tx_hex = '0100000001aedfe7499b41c131e4d274788042fc42573898b1bdf0c1064ee40f4d578f1ea1000000006a47304402205ae4768f240ce17a5fb19a76ec3616d2874f302cb3d1ab4c48be12edced0896a022014ba68188c298d66b1dc4a249adeb3bfb4a197ba0c2951b537b142ed60dacb7301210309ea54e6a644fc16273b862ec34f9a19c07fa33b8e4f690d9dc288a4b3e3addaffffffff02d0dd0600000000001976a91478569a1d7735dfb5f868760ea18389ad6382dbcb88ac6003b807000000001976a914ab46f586adc4bcdef8a101d1ed3dd8f474e10f7d88ac00000000'
prev_tx = Bitcoin::P::Tx.new(prev_tx_hex.htb)
prev_tx_output_index = 1

tx = Bitcoin::Protocol::Tx.new
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(2_950_000, recipient_addr)
tx.add_out Bitcoin::Protocol::TxOut.value_to_address(126_500_000, change_addr)

sig = key.sign(tx.signature_hash_for_input(0, prev_tx))
tx.in[0].script_sig = Bitcoin::Script.to_signature_pubkey_script(sig, [key.pub].pack("H*"))

tx = Bitcoin::Protocol::Tx.new( tx.to_payload )

p tx.hash
p tx.verify_input_signature(0, prev_tx) == true

puts "json:\n"
puts tx.to_json # json
puts "\nhex:\n"
puts tx.to_payload.unpack("H*")[0] # hex binary
false

I dont have any problems with non-hardened key, but with hardened key, i cant sign, can anyone help me, i was struggling it in a week, thanks you!!

SFzxc commented 6 years ago

looking forward to your help @azuchi -san

lian commented 6 years ago

your imported key is not the same used in the output of the prev_tx.

key hash160 is 79aa41a7dc28ca02eff911759d7f47ccc263cd15 output 1 of prev_tx is ab46f586adc4bcdef8a101d1ed3dd8f474e10f7d

if you sign the new tx the <signature> <pubkey> OP_DUP OP_HASH160 ab46f586adc4bcdef8a101d1ed3dd8f474e10f7d OP_EQUALVERIFY OP_CHECKSIG will fail because hash160(pubkey) doesn't match the scripts hash160

SFzxc commented 6 years ago

Thanks @lian , i used same database and Wallet Master Private Key with testnet enviroment, i wonder why testnet still work and local is not, Thanks for supporting, i keep research about this different