Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: pbies on March 06, 2024, 12:32:30 AM



Title: Sign SIGHASH_SINGLE [unsolved]
Post by: pbies on March 06, 2024, 12:32:30 AM
At which stage should I connect two signed inputs in python script for SIGHASH_SINGLE tx? When they should be in one variable and where given to?

Options:

Code:
- redeem_script
- sighash
- signature
- witness
- witness in CScript
- ctxinwitnesses
- tx.wit = CTxWitness(ctxinwitnesses?)


Title: Re: Sign SIGHASH_SINGLE [unsolved]
Post by: pooya87 on March 07, 2024, 05:39:00 AM
[unsolved]
You need to clarify your question.
Are you trying to compute the hash digest needed for signing a certain input using SIGHASH_SINGLE or are you stuck using a certain library with the "options" you posted?
Because if it is the former, the respond is too long and doesn't fit in one comment since we already have 3 output "families" (legacy, wit ver 0, wit ver 1) and sighash is computed differently for each of them. Both legacy and witness version 0 also have their own subcategories (like P2SH) which demand a different approach.

If you want details on a certain smaller part, be more specific otherwise if you want to know how all of it works you have to check out the source code. The two SignatureHash methods inside interpreter.cpp (https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp) is a place to start.


Title: Re: Sign SIGHASH_SINGLE [unsolved]
Post by: pbies on March 07, 2024, 06:04:19 AM
You need to clarify your question.
Are you trying to compute the hash digest needed for signing a certain input using SIGHASH_SINGLE or are you stuck using a certain library with the "options" you posted?
Because if it is the former, the respond is too long and doesn't fit in one comment since we already have 3 output "families" (legacy, wit ver 0, wit ver 1) and sighash is computed differently for each of them. Both legacy and witness version 0 also have their own subcategories (like P2SH) which demand a different approach.

If you want details on a certain smaller part, be more specific otherwise if you want to know how all of it works you have to check out the source code. The two SignatureHash methods inside interpreter.cpp (https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp) is a place to start.

Question is clear as it can be.

Now sharing additional info which shouldn't be needed by person which is involved in such script creation:

1. I am trying to put both inputs into one place because there is such need and don't know which place it should be, at which stage of python script which builds the transaction and was meant to create new raw hex tx data.
2. Library I am using is "bitcoin" with python 3.11. "bitcoin.core" and "bitcoin.wallet".
3. Output can be any, 1..., 3..., bc1.... However now the script is created for testnet. I am not asking about output, but inputs.
4. SigHash for now looks like that: sighash1 = SignatureHash(redeem_script1, tx, txin_index, SIGHASH_SINGLE, amount=amount1, sigversion=SIGVERSION_WITNESS_V0)

Hope that helps.


Title: Re: Sign SIGHASH_SINGLE [unsolved]
Post by: NotATether on March 07, 2024, 09:07:54 AM
You need all the inputs in order to create the sighashes for each of the inputs.

So you would put them in the "sighash" area.

Assuming "signature" is just a function for doing DER signing, it doesn't explicitly make use of the inputs themselves, but deals with an entire transaction.

And then you have the witness step where the inputs are definitely required.

I'm not familiar with your code or the "bitcoin" PyPI library so I can't give you a code example, but like I said you can just round them up for the sighash calculation.


Title: Re: Sign SIGHASH_SINGLE [unsolved]
Post by: pbies on March 07, 2024, 03:27:11 PM
You need all the inputs in order to create the sighashes for each of the inputs.

So you would put them in the "sighash" area.

Assuming "signature" is just a function for doing DER signing, it doesn't explicitly make use of the inputs themselves, but deals with an entire transaction.

And then you have the witness step where the inputs are definitely required.

I'm not familiar with your code or the "bitcoin" PyPI library so I can't give you a code example, but like I said you can just round them up for the sighash calculation.

The last code is:

Code:
txins= []
txin1 = CTxIn(COutPoint(lx(txid1), vout1))
txin2 = CTxIn(COutPoint(lx(txid2), vout2))
txins=[txin1,txin2]

txout = CTxOut(amount_less_fee, target_scriptPubKey)

tx = CMutableTransaction(txins, [txout])

txin_index = 0

redeem_script1 = address1.to_redeemScript()
redeem_script2 = address2.to_redeemScript()

sighash1 = SignatureHash(redeem_script1, tx, txin_index, SIGHASH_SINGLE, amount=amount1, sigversion=SIGVERSION_WITNESS_V0)
sighash2 = SignatureHash(redeem_script2, tx, txin_index, SIGHASH_SINGLE, amount=amount2, sigversion=SIGVERSION_WITNESS_V0)

signature1 = seckey1.sign(sighash1) + bytes([SIGHASH_SINGLE])
signature2 = seckey2.sign(sighash2) + bytes([SIGHASH_SINGLE])
witness1 = [signature1, public_key1]
witness2 = [signature2, public_key2]
witness1next = CScript(witness1)
witness2next = CScript(witness2)
ctxinwitnesses1 = [CTxInWitness(CScriptWitness(witness1))]
ctxinwitnesses2 = [CTxInWitness(CScriptWitness(witness2))]

tx.wit = CTxWitness(ctxinwitnesses1)

VerifyScript(witness1next, scriptPubKey1, tx, 0, (SCRIPT_VERIFY_P2SH,))

print(b2x(tx.serialize()))

At which line should be the inputs moved into one variable to fulfill the tx requirements?