Tuesday, July 2, 2024

uncooked transaction – I can not broadcast my uncooked tx (P2PKH) on testnet: Signature should be zero for failed CHECK(MULTI)SIG operation

I’m attempting to broadcast my transaction on the check community with no success up to now. I get all the time this error:

sendrawtransaction RPC error: {"code":-26,"message":"mandatory-script-verify-flag-failed (Signature should be zero for failed CHECK(MULTI)SIG operation)"}

I’ve reviewed my code no less than 10 occasions the final two hours and might´t discover what’s fallacious with it. It seems like all the pieces is okay however clearly not.

May somebody spot the reason for the difficulty?

That is my code on Python. I simply eliminated the private_key_hex subject, the rest stays untouched. Additionally, discover that I received no change, the completely different between the total UTXO quantity and the worth despatched is the payment for the miners.

import base58
import hashlib
import ecdsa


def hash160(x): # Each accepts & returns bytes
    return hashlib.new('ripemd160', hashlib.sha256(x).digest()).digest()

def doublesha256(x):
    return hashlib.sha256(hashlib.sha256(x).digest()).digest()

def flip(string):
    flipped = "".be part of(reversed([string[i:i+2] for i in vary(0, len(string), 2)]))
    return flipped

def hashed_pubkey(pubkey):
    return base58.b58decode_check(pubkey)[1:].hex()

 
private_key_hex = ''
pub_address_in = 'mpfmNgZAkSdhDoP5UJKhh6wahfGboXhFmj'
hashed_pubkey_in = hashed_pubkey(pub_address_in)

model = 1
tx_input_count = 1
tx_output_count = 1

#TX_IN_VARIABLES
prev_tx_id = 'dbf7fd00e017bf3972c0fc441b2d78807c89fccd65a48adde69cd6e5435e3819'
v_out = 0
scriptPubKey_in = bytes.fromhex("76a914{}88ac".format(hashed_pubkey_in))
scriptPubKey_in_s = len(scriptPubKey_in)

#TX_OUT_VARIABLES
quantity = 56400
pub_address_out="mpkt3ZpTfZJDeN9p5LgkAHj3NmVMaND7vR"
hashed_pubkey_out = hashed_pubkey(pub_address_out)
scriptPubKey_out = bytes.fromhex("76a914{}88ac".format(hashed_pubkey_out))
scriptPubKey_out_s = len(scriptPubKey_out)                          

class raw_tx:
    model                             = (model).to_bytes(4, byteorder="little")
    tx_in_count                         = (tx_input_count).to_bytes(1, byteorder="little")
    tx_input                            = {}
    tx_out_count                        = (tx_output_count).to_bytes(1, byteorder="little")
    tx_output                           = {}
    lock_time                           = (0).to_bytes(4, byteorder="little")


rtx = raw_tx()


#TX_IN
rtx.tx_input['prev_tx_id']              = bytes.fromhex(flip(prev_tx_id))
rtx.tx_input['v_out']                   = (v_out).to_bytes(4, byteorder="little")
rtx.tx_input['scriptPubKey_in_s']       = scriptPubKey_in_s.to_bytes(1, byteorder="little")
rtx.tx_input['scriptPubKey_in']         = scriptPubKey_in
rtx.tx_input['sequence']                = bytes.fromhex('ffffffff')


#TX_OUT
rtx.tx_output['amount']                  = quantity.to_bytes(8, byteorder="little")
rtx.tx_output['scriptPubKey_out_s']      = scriptPubKey_out_s.to_bytes(1, byteorder="little")
rtx.tx_output['scriptPubKey_out']        = scriptPubKey_out


raw_tx_string = (

    rtx.model
    + rtx.tx_in_count
    + rtx.tx_input["prev_tx_id"]
    + rtx.tx_input["v_out"]
    + rtx.tx_input["scriptPubKey_in_s"]
    + rtx.tx_input["scriptPubKey_in"]
    + rtx.tx_input["sequence"]
    + rtx.tx_out_count
    + rtx.tx_output["amount"]
    + rtx.tx_output["scriptPubKey_out_s"]
    + rtx.lock_time
    + (1).to_bytes(4, byteorder="little")#SIGHASH_ALL kind of sighash

    )


#2 SHA256 TO RAW_TX
hashed_tx_to_sign = doublesha256(raw_tx_string)
sk = ecdsa.SigningKey.from_string(bytes.fromhex(private_key_hex), curve = ecdsa.SECP256k1)
vk = sk.verifying_key
public_key = vk.to_string().hex()


#COMPRESSING THE PUBLIC KEY
# Checking if the final byte is odd and even
if (ord(bytearray.fromhex(public_key[-2:])) % 2 == 0):
    public_key_compressed = '02'
else:
    public_key_compressed = '03'
    
# Add bytes 0x02 to the X of the important thing if even or 0x03 if odd
public_key_compressed += public_key[:64]
public_key = bytes.fromhex(public_key_compressed)


#SIGNING RAW_TX HASHED
signature = sk.sign_digest(hashed_tx_to_sign, sigencode = ecdsa.util.sigencode_der_canonize)


#CREATING SCRIPTSIG
signature_mod = signature + (1).to_bytes(1, byteorder="little") #SIGHASH_ALL kind of sighash
signature_mod_s = len(signature_mod)

public_key_s = len(public_key)

sigscript = (

    signature_mod_s.to_bytes(1, byteorder="little")
    + signature_mod
    + public_key_s.to_bytes(1, byteorder="little")
    + public_key
        
    )

sigscript_s = len(sigscript)


real_tx = (
    rtx.model
    + rtx.tx_in_count
    + rtx.tx_input["prev_tx_id"]
    + rtx.tx_input["v_out"]
    + sigscript_s.to_bytes(1, byteorder="little")
    + sigscript
    + rtx.tx_input["sequence"]
    + rtx.tx_out_count
    + rtx.tx_output["amount"]
    + rtx.tx_output["scriptPubKey_out_s"]
    + rtx.tx_output["scriptPubKey_out"]
    + rtx.lock_time

    )

print(real_tx.hex())

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles