Basierend auf dem Skript von github . Ich habe versucht, eine gültige Testnet-Transaktion zu erstellen. Ich musste einige Änderungen am Skript vornehmen, also hier ist der aktuelle Code.
import struct
import base58
import hashlib
import ecdsa
import struct
import base58
import hashlib
import ecdsa
Bob_addr = "mwRhL3S4NATBKDJkgbaa1PXGFUB9Qi1uuj"
bob_hashed_pubkey = base58.b58decode_check(Bob_addr)[1:].encode("hex")
print(bob_hashed_pubkey)
print(base58.b58decode_check(Bob_addr)[1:])
Bob_private_key = "cQFXsyWHnz1CcxgDb1E4q7zLoB6jVzhCCGMyXSJaj74YGUik2N45"
prv_txid = "8310e8a8c65774651a658af96751cabbb89abd7c38661a95e662c923fa057238"
Charlie_adr = "mwRhL3S4NATBKDJkgbaa1PXGFUB9Qi1uuj"
charlie_hashed_pubkey = base58.b58decode_check(Charlie_adr)[1:].encode("hex")
class raw_tx:
version = struct.pack("<L", 1)
tx_in_count = struct.pack("<B", 1)
tx_in = {} #TEMP
tx_out_count = struct.pack("<B", 2)
tx_out1 = {} #TEMP
tx_out2 = {} #TEMP
lock_time = struct.pack("<L", 0)
def flip_byte_order(string):
flipped = "".join(reversed([string[i:i+2] for i in range(0, len(string), 2)]))
return flipped
rtx = raw_tx()
rtx.tx_in["txouthash"] = flip_byte_order(prv_txid).decode("hex")
rtx.tx_in["tx_out_index"] = struct.pack("<L", 1)
rtx.tx_in["script"] = ("76a914%s88ac" % charlie_hashed_pubkey).decode("hex")
rtx.tx_in["scrip_bytes"] = struct.pack("<B", len(rtx.tx_in["script"]))
rtx.tx_in["sequence"] = "ffffffff".decode("hex")
rtx.tx_out1["value"] = struct.pack("<Q", 100000)
rtx.tx_out1["pk_script"] = ("76a914%s88ac" % bob_hashed_pubkey).decode("hex")
rtx.tx_out1["pk_script_bytes"] = struct.pack("<B", len(rtx.tx_out1["pk_script"]))
rtx.tx_out2["value"] = struct.pack("<Q", 50000)
rtx.tx_out2["pk_script"] = ("76a914%s88ac" % bob_hashed_pubkey).decode("hex")
rtx.tx_out2["pk_script_bytes"] = struct.pack("<B", len(rtx.tx_out2["pk_script"]))
raw_tx_string = (
rtx.version
+ rtx.tx_in_count
+ rtx.tx_in["txouthash"]
+ rtx.tx_in["tx_out_index"]
+ rtx.tx_in["scrip_bytes"]
+ rtx.tx_in["script"]
+ rtx.tx_in["sequence"]
+ rtx.tx_out_count
+ rtx.tx_out1["value"]
+ rtx.tx_out1["pk_script_bytes"]
+ rtx.tx_out1["pk_script"]
+ rtx.tx_out2["value"]
+ rtx.tx_out2["pk_script_bytes"]
+ rtx.tx_out2["pk_script"]
+ rtx.lock_time
+ struct.pack("<L", 1)
)
hashed_tx_to_sign = hashlib.sha256(hashlib.sha256(raw_tx_string).digest()).digest()
print(hashed_tx_to_sign)
#sk = ecdsa.SigningKey.from_string(Bob_private_key.decode("hex"), curve = ecdsa.SECP256k1)
#vk = sk.verifying_key
print(bitcoin.privkey_to_pubkey(Bob_private_key))
vk = bitcoin.privkey_to_pubkey(Bob_private_key)
public_key = ('\04' + vk).encode("hex")
#signature = sk.sign_digest(hashed_tx_to_sign, sigencode = ecdsa.util.sigencode_der_canonize)
signature = (bitcoin.ecdsa_sign(hashed_tx_to_sign, Bob_private_key))
sigscript = (
signature
+ "\01"
+ struct.pack("<B", len(public_key.decode("hex")))
+ public_key.decode("hex")
)
real_tx = (
rtx.version
+ rtx.tx_in_count
+ rtx.tx_in["txouthash"]
+ rtx.tx_in["tx_out_index"]
+ struct.pack("<B", len(sigscript) + 1)
+ struct.pack("<B", len(signature) + 1)
+ sigscript
+ rtx.tx_in["sequence"]
+ rtx.tx_out_count
+ rtx.tx_out1["value"]
+ rtx.tx_out1["pk_script_bytes"]
+ rtx.tx_out1["pk_script"]
+ rtx.tx_out2["value"]
+ rtx.tx_out2["pk_script_bytes"]
+ rtx.tx_out2["pk_script"]
+ rtx.lock_time
)
print(real_tx.encode("hex") )
Das Skript verwendet die hier gefundene Adresse und Transaktion https://live.blockcypher.com/btc-testnet/address/mwRhL3S4NATBKDJkgbaa1PXGFUB9Qi1uuj/ . Wenn ich versuche, die Transaktion mit https://live.blockcypher.com/btc-testnet/pushtx/ zu übertragen . Ich erhalte eine Fehlermeldung, die besagt, dass etwas mit dem Skript in der Eingabetransaktion nicht stimmt. Es hat ein Skript, das auf Pay-to-Pubkey-Hash basiert, und so versuche ich, es zu entschlüsseln. Irgendwelche Tipps?
Der vom Skript generierte TX
0100000001387205fa23c962e6951a66387cbd9ab8bbca5167f98a651a657457c6a8e81083010000009e5948314d3064512b6d6668436f4849693154514f79795975646b306f57786263586c4245582f5968636954386d567943375a717a41616d454570577530435950456f72656e644f44467a4f6e5146776b69595737354b67633d014304303364393466316464383732383862613163306666656665636161373161633733393733323132303662666137326631313563313761323639316331633866336539ffffffff02a0860100000000001976a914ae8370a2d4634b2b6f29b938a996f961f73ded4888ac50c30000000000001976a914ae8370a2d4634b2b6f29b938a996f961f73ded4888ac00000000
Die Fehlermeldung ist
Fehler beim Validieren der Transaktion: Fehler beim Ausführen des Skripts für Eingabe 0 mit Verweis auf 8310e8a8c65774651a658af96751cabbb89abd7c38661a95e662c923fa057238 bei 1: Skript wurde NICHT erfolgreich verifiziert.
Wie MeshCollider betonte, ist scriptSig falsch, aber es scheint eine Struktur zu haben. Insbesondere sieht es so aus, als ob OP Operationen mit ASCII-Text anstelle der tatsächlichen Bytes ausführt:
scriptSig ist:
48314D3064512B6D6668436F4849693154514F79795975646B306F57786263586C4245582F5968636954386D567943375A717A41616D454570577530435950456F72656E644F44467A4F6E5146776B69595737354B67633D
01
43
04
303364393466316464383732383862613163306666656665636161373161633733393733323132303662666137326631313563313761323639316331633866336539
Was eigentlich ist (hex2bin einige der Daten):
1. H1M0dQ+mfhCoHIi1TQOyyYudk0oWxbcXlBEX/YhciT8mVyC7ZqzAamEEpWu0CYPEorendODFzOnQFwkiYW75Kgc= <- recoverable signature over some data
2. 01 <- probably appended to use as SIGHASH_ALL
3. 43 <- size of the next two items concatenated
4. 04 <- probably prepended by mistake,
thinking that all pubkeys are prepended with 0x04 ?
5. 03d94f1dd87288ba1c0ffefecaa71ac7397321206bfa72f115c17a2691c1c8f3e9 <- pubkey in lowercase hex characters
Es scheint auch, dass die OP-Signatur für die Transaktion ungültig ist, daher vermute ich, dass die gehashten Daten selbst fehlerhaft sind. Die korrekten Daten für sighash wären:
01000000
01
387205FA23C962E6951A66387CBD9AB8BBCA5167F98A651A657457C6A8E81083
01000000
19
76 A9 14 AE8370A2D4634B2B6F29B938A996F961F73DED48 88 AC
FFFFFFFF
02
a086010000000000
19
76 a9 14 ae8370a2d4634b2b6f29b938a996f961f73ded48 88 ac
50c3000000000000
19
76 a9 14 ae8370a2d4634b2b6f29b938a996f961f73ded48 88 ac
00000000
01000000
Und die Signatur wäre:
30440220586E47980A1329CE23A55E318772935056972FCD7F702D39594A2F0A786657E40220234CCC55AE41DED90A09D3F86F52BD0FD1B881000EDB1734FD0ACE6AFBFB7E4D01
Dann ist die letzte Transaktion:
0100000001387205FA23C962E6951A66387CBD9AB8BBCA5167F98A651A657457C6A8E81083010000006A4730440220586E47980A1329CE23A55E318772935056972FCD7F702D39594A2F0A786657E40220234CCC55AE41DED90A09D3F86F52BD0FD1B881000EDB1734FD0ACE6AFBFB7E4D012103D94F1DD87288BA1C0FFEFECAA71AC7397321206BFA72F115C17A2691C1C8F3E9FFFFFFFF02a0860100000000001976a914ae8370a2d4634b2b6f29b938a996f961f73ded4888ac50c30000000000001976a914ae8370a2d4634b2b6f29b938a996f961f73ded4888ac00000000
Ich lasse OP entscheiden, ob sie es einlösen wollen oder nicht. Es zahlt praktisch alles an Gebühren :)
Hannah Vernon
Benutzer2350155
Andreas Chow
Benutzer2350155
meshcollider
decoderawtransaction
Call-it-Bitcoin-Kern verwenden, um eine Rohtransaktion zu dekodieren. Wenn Sie sich das"asm"
Feld derscriptSig
Transaktionseingabe ansehen, können Sie deutlich erkennen, dass es sich um ein Durcheinander von Mülldaten handelt, überhaupt nicht um ein gültiges Skript