Signature

基本交易的私鑰的來源和(錯誤)處理

  • September 13, 2019

我希望通過簽名來“動手”,但是當我在<https://bitcoin.stackexchange.com/a/5241/89798>改編 Runeks 的徹底回答時,我的程式碼總是無法報告我使用了錯誤的私人鑰匙。我是否錯誤地獲取了私鑰,或者以某種方式處理不當?我在下面的過程中哪裡弄錯了?

我將首先註意到 Runeks 的程式碼正確執行,我正在使用 v0.13.2 bitcoind 和 bitcoin-cli 來獲取他的答案中使用的遺留事務,並且我使用的是 regtest 而不是 mainnet。

我的過程:

  1. 我使用腳本來重置 regtest 網路並生成 101 個塊,所以我有一個可以使用的 coinbase:
CURDIR=`pwd`
cd /home/bitcoin14/.bitcoin
/usr/local/bin/bitcoin-cli -conf=/home/bitcoin14/.bitcoin/regtest.conf -regtest stop
sleep 1
rm -rf /home/bitcoin14/.bitcoin/regtest && /usr/local/bin/bitcoind -conf=/home/bitcoin14/.bitcoin/regtest.conf -regtest -daemon
sleep 2
/usr/local/bin/bitcoin-cli -conf=/home/bitcoin14/.bitcoin/regtest.conf -regtest generate 101 &gt;/dev/null
cd $CURDIR
  1. 我將硬幣發送到一個新地址,以便不使用該 coinbase 交易
$ /usr/local/bin/bitcoin-cli -conf=/home/bitcoin14/.bitcoin/regtest.conf getnewaddress
mk5U6xEDnTmfNrHcCXkdKrXziYH1YMygVw
$ /usr/local/bin/bitcoin-cli -conf=/home/bitcoin14/.bitcoin/regtest.conf sendtoaddress mk5U6xEDnTmfNrHcCXkdKrXziYH1YMygVw 49.99
675eac8d9aebe4f84aa2bb18a9f02304d11cb8937ca103b6ccf00fdf0de69727
  1. 我獲得了上述交易的十六進制和 vout,因為其中包含我希望簽署其移動的硬幣
$ /usr/local/bin/bitcoin-cli -conf=/home/bitcoin14/.bitcoin/regtest.conf gettransaction 675eac8d9aebe4f84aa2bb18a9f02304d11cb8937ca103b6ccf00fdf0de69727 | egrep 'vout|hex'
     "vout": 1,
     "vout": 1
 "hex": "0100000001fe37d2309bb4b4f4de102ff08f08e049acaecd4c1ee195328404c02406e596c6000000004847304402206eef31e0114c8e31180da39c644fc518624e9c5f354f6c375bfffba8a3c0dc6d022021056d74ea16155036663b7aaab1e297715231747718e48ab94aefd05cded83d01feffffff0254330f00000000001976a91486d1e65bc7f89b24724f50fa5db3a7f102d9644d88acc0aff629010000001976a9143206b266d2998b1092fcd1737165c363c0e31b6c88ac65000000"
  1. 我獲得了一個新地址,代幣將被兌換到該地址
$ /usr/local/bin/bitcoin-cli -conf=/home/bitcoin14/.bitcoin/regtest.conf getnewaddress
n42ui4Tbd2mVPiRtAUr4RYW7KC7qUmXDTt
  1. 我獲得了上面“2”處生成的私鑰
$ /usr/local/bin/bitcoin-cli -conf=/home/bitcoin14/.bitcoin/regtest.conf dumpprivkey mk5U6xEDnTmfNrHcCXkdKrXziYH1YMygVw
cPMjUqc3d4WhDG8Evn2G3RrVWMyetHtwiTZhpKW1T1QUrBhYGVnG
  1. 我根據https://bitcoin.stackexchange.com/a/52954/89798將私鑰轉換為等效的十六進制(這在另一台機器上)
$ ./bitcoin-tool --input-type private-key-wif --input-format base58check --output-type private-key --output-format hex --network bitcoin --input cPMjUqc3d4WhDG8Evn2G3RrVWMyetHtwiTZhpKW1T1QUrBhYGVnG
3500dba7a3363e7127cd72273b0e475c5dbb1d378496b803edaf06f8eb3ee160
  1. 我採用上述內容並將它們編輯到 Runeks 的程式碼中
HEX_TRANSACTION="0100000001fe37d2309bb4b4f4de102ff08f08e049acaecd4c1ee195328404c02406e596c6000000004847304402206eef31e0114c8e31180da39c644fc518624e9c5f354f6c375bfffba8a3c0dc6d022021056d74ea16155036663b7aaab1e297715231747718e48ab94aefd05cded83d01feffffff0254330f00000000001976a91486d1e65bc7f89b24724f50fa5db3a7f102d9644d88acc0aff629010000001976a9143206b266d2998b1092fcd1737165c363c0e31b6c88ac65000000"
...
OUTPUT_INDEX=1
...
SEND_TO_ADDRESS="n42ui4Tbd2mVPiRtAUr4RYW7KC7qUmXDTt"
...
PRIVATE_KEY=0x3500dba7a3363e7127cd72273b0e475c5dbb1d378496b803edaf06f8eb3ee160
  1. 我執行程式碼(再次與上述不同的機器)
$ python2 sign3.py 
Traceback (most recent call last):
 File "sign3.py", line 144, in &lt;module&gt;
   (OUTPUT_INDEX, hash_160_to_bc_address(tx_info['txOut'][OUTPUT_INDEX]['scriptPubKey'][3:-2], bytes[0]))
RuntimeError: The supplied private key cannot be used to redeem output index 1
You need to supply the private key for address mk5U6xEDnTmfNrHcCXkdKrXziYH1YMygVw

錯誤很明顯:我沒有提供正確的私鑰。我的錯誤在哪裡?謝謝大家!

編輯

似乎 bitcoind-0.13 提供了一個基於壓縮公鑰的 pubkeyhash,並且下面的程式碼作用於私鑰顯示的未壓縮公鑰。兩個雜湊不同,後面的條件失敗。

k = ecdsa_ssl.KEY()
k.generate(('%064x' % PRIVATE_KEY).decode('hex'))

#here we retrieve the public key data generated from the supplied private key                                                                                                                                                                                                  
pubkey_data = k.get_pubkey()

調查仍在繼續……

如您的編輯所述,問題是公鑰壓縮。原始程式碼不處理壓縮的公鑰。

嘗試添加

k.set_compressed(True)

#here we retrieve the public key data generated from the supplied private key                                                                                                                                                                                                  
pubkey_data = k.get_pubkey()

引用自:https://bitcoin.stackexchange.com/questions/90308