-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ScriptValidationError: Unknown script type #31
Comments
It may be due to the input type of the This is from bip-178. Although it's not formally accepted yet, it is referenced in the code base of this project. cryptotools/cryptotools/ECDSA/secp256k1.py Lines 62 to 66 in dbdced8
The flag def spend(private_key_bytes, recipient):
private = PrivateKey.from_bytes(private_key_bytes)
address = private.to_public().to_address("P2WPKH")
# ... the rest is the same If you only have wifs from some other system, then pull the private key bytes out of it, and ignore the compression flags entirely. from cryptotools.HD.bip32 import base53
def spend(wif, recipient):
private = PrivateKey.from_bytes(base53.decode(wif)[1:33])
address = private.to_public().to_address("P2WPKH")
# ... |
hey @massmux I think this might be related with a recent change to pull utxo data from blockstream.info instead of blockchain.info and the utxo endpoint does not contain output scripts. Could you try setting the environmental variable |
@mcdallas my wif controls a 3xx address in which funds are. now i am using same code to spend to a bc1 address. I set the environment var as you suggested, the situation actually changed, but i got a different error
can i spend only to legacy? |
@yurisich my wif is created externally but it seems ok, it begins with K |
@massmux You can send to segwit but the problem is where you are spending from. P2SH addresses (starting with 3) have no direct correlation to a single private key, for example they can be 2-of-3 multisig addresses that require multiple keys to sign or they can require no signature at all. As such there is no standard method on how to spend from them. In the special case that the P2SH address is a segwit-wrapped address (P2SH-P2WPKH) then there is a 1-to-1 relation with a key and perhaps your address is such but I have not yet implemented this functionality. I'll look into adding it. Finally I would caution against using the send/spend mechanisms in this library with mainnet addresses containing any significant amount because as I mentioned in the disclaimer this library is mostly for educational purposes and not as well battle tested as other wallets like for example electrum. |
@mcdallas ok i understand. i try then to spend from bc1 to bc1. this should work, correct? about last point, dont worry i understand. your library so far is very good, clear and well done |
now i am in the condition suggested. from bc1 towards bc1 address. wif starting with L. But i get again an error, different, but another one. What is it? where am i wrong? Traceback (most recent call last): |
@massmux I have been spending some time attempting to implement a valid utxo spend that includes witness data. In my case, it was a There's an issue where the sighash uses a tx version number from the default value of private = cryptotools.PrivateKey.from_hex("...")
public = private.to_public()
script = cryptotools.push(public.encode(compressed=True)) + cryptotools.OP.CHECKSIG.byte
p2sh_address = cryptotools.script_to_address(script, "P2WSH-P2SH")
p2sh_txid = "..."
p2sh_tx = cryptotools.Transaction.get(p2sh_txid)
p2sh_output = p2sh_tx.outputs[0]
send_to = Address("...")
send_amount = 50_000
fee = p2sh_output.value - send_amount
input_tx = p2sh_output.spend()
output_tx = send_to._receive(send_amount)
tx = cryptotools.Transaction(
inputs=[input_tx],
outputs=[output_tx]
)
p2sh_bytes = cryptotools.BTC.base58.decode(p2sh_address)
payload = p2sh_bytes[1:-4]
redeem_script = cryptotools.push(cryptotools.sha256(script))
# just to demonstrate....
witness_byte = b'\x00'
assert cryptotools.BTC.script.witness_byte(witver=0) == witness_byte
assert payload == cryptotools.hash160(
witness_byte + redeem_script
) Ok, that's the setup. Here's where things can get tricky if you're looking to build your own transaction for signing: assert input_tx.is_nested() == False
assert input_tx.segwit == False
input_tx.script = (
# push the witness byte b'\x00' and the 0x21 byte redeem_script
b'\x22' + (b'\x00' + redeem_script)
)
assert input_tx.segwit == False
# the tx is now "nested", though
assert input_tx.is_nested() == cryptotools.TX.P2WSH The witness data should be populated with an empty signature at first: empty_sig = b''
input_tx.witness = [empty_sig, script]
assert input_tx.segwit == True And then, creating a signature will fail to verify: utxo_input_to_sign = 0
sig = private.sign_hash(tx.sighash(i=utxo_input_to_sign))
# for clarity's sake
sig_verification_strictness = b'\x01'
assert sig_verification_strictness == cryptotools.SIGHASH.ALL.byte
tx.inputs[0].witness[0] = sig.encode() + b'\x01'
# this isn't working...
assert tx.verify() == False Fixing the verify step: assert tx.version == 1
assert tx._version == b'\x00\x00\x00\x01'
tx._version = b'\x00\x00\x00\x02'
tx.version = 2
assert tx.version == 2
assert tx._version == b'\x00\x00\x00\x02'
assert tx.verify() == True |
in this code
i run with
spend("wifxxx","bc1source","bc1qdest")
i get this error
but it seems that bech32 (bc1q) is supported by the lib.
where am i wrong?
The text was updated successfully, but these errors were encountered: