Comments (7)
While I'm not inclined to help with inscriptions, I decided to take a look anyway as a way to express my appreciation for your honesty. I recommend using Message::from(sighash)
which is more readable, at first I thought there's a problem.
One problem I see is you're passing 0
to taproot_key_spend_signature_hash
and commit_input_index
into witness_mut
. You need to pass the same number into both, so I guess just change 0
to commit_input_index
.
from rust-bitcoin.
OK, still recommend to use the variable to keep it in sync. :) I will try to look later when I have more time. Things like these inform us how horrible our signing API is. There's a bunch of things that really should've taken like one line of code and require no error handling.
from rust-bitcoin.
Found the mistake!
Instead of
let mut sighasher = SighashCache::new(&mut reveal_tx);
let sighash = sighasher
.taproot_key_spend_signature_hash(
commit_input,
&sighash::Prevouts::All(commit_tx.output.as_slice()),
TapSighashType::Default,
)
.expect("failed to construct sighash");
I had to use
let sighash = sighash_cache
.taproot_script_spend_signature_hash(
commit_input,
&Prevouts::All(&prevouts),
TapLeafHash::from_script(&reveal_script, LeafVersion::TapScript),
TapSighashType::Default,
)
.expect(""failed to construct sighash");
from rust-bitcoin.
You can try compiling with libbitcoinconsensus
and running versification using it. RNG shouldn't be an issue but could have security implications.
If you're getting invalid schnorr signature you likely created wrong signing data.
from rust-bitcoin.
@domwoe, If you share your signing code, we can help debugging it.
from rust-bitcoin.
Thank you @Kixunil and @sanket1729
I hope you'll be helping me even if I disclose that I'm working on an inscription example...
Here's the main code:
(The entire code, which is not completely current, can be seen here)
let mut builder = Builder::new();
builder = inscription.append_reveal_script_to_builder(builder);
let secp256k1 = Secp256k1::new();
// In practice the signer will be external
let key = SecretKey::from_str("SomeSecretString").unwrap();
let key_pair = Keypair::from_secret_key(&secp256k1, &key);
let (schnorr_public_key, _parity) = XOnlyPublicKey::from_keypair(&key_pair);
builder = builder
.push_slice(&schnorr_public_key.serialize())
.push_opcode(opcodes::all::OP_CHECKSIG);
let reveal_script = builder.into_script();
/* The reveal script will be something like
Reveal script: OP_0 OP_IF OP_PUSHBYTES_3 6f7264 OP_PUSHBYTES_1 01 OP_PUSHBYTES_24 746578742f706c61696e3b636861727365743d7574662d38 OP_0 OP_PUSHBYTES_11 48656c6c6f20576f726c64 OP_ENDIF OP_PUSHBYTES_32 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 OP_CHECKSIG
*/
let taproot_spend_info = TaprootBuilder::new()
.add_leaf(0, reveal_script.clone())
.expect("adding leaf should work")
.finalize(&secp256k1, schnorr_public_key)
.expect("finalizing taproot builder should work");
let control_block = taproot_spend_info
.control_block(&(reveal_script.clone(), LeafVersion::TapScript))
.expect("should compute control block");
...
let mut reveal_tx = Transaction {
input: reveal_inputs
.iter()
.map(|outpoint| TxIn {
previous_output: *outpoint,
script_sig: Builder::new().into_script(),
witness: Witness::new(),
sequence: Sequence::ENABLE_RBF_NO_LOCKTIME,
})
.collect(),
output: reveal_outputs,
lock_time: LockTime::ZERO,
version: Version(2),
};
let mut sighasher = SighashCache::new(&mut reveal_tx);
let sighash = sighasher
.taproot_key_spend_signature_hash(
0,
&sighash::Prevouts::All(commit_tx.output.as_slice()),
TapSighashType::Default,
)
.expect("failed to construct sighash");
// Simplified the following line
let sig = secp256k1.sign_schnorr_no_aux_rand(&Message::from(sighash), &key_pair);
let witness = sighasher
.witness_mut(commit_input_index)
.expect("getting mutable witness reference should work");
witness.push(
Signature {
sig,
hash_ty: TapSighashType::Default,
}
.to_vec(),
);
witness.push(reveal_script);
witness.push(&control_block.serialize());
...
The reveal transaction will look like
02000000000101876f7be78b31088dbcab7e2c8ea1588596c4a3498956da7501fdbc692e9d9f9c0000000000fdffffff01d2b70b54020000001976a9148c946686f84ee4af2d4df8d4f79f15106afc2cd188ac0340c1c1f59a5cf745c9f9f2b17ee5761e8e2381fb954f52709f4dbfdff6e50cb3716b96b2d2cee401127b7767ec2117a125e7aba9e0fa48f73d34a0ef9bd307c3b5510063036f7264010118746578742f706c61696e3b636861727365743d7574662d38000b48656c6c6f20576f726c64682079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac21c179be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800000000
The relevant vin
"locktime": 0,
"vin": [
{
"txid": "9c9f9d2e69bcfd0175da568949a3c4968558a18e2c7eabbc8d08318be77b6f87",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"txinwitness": [
"c1c1f59a5cf745c9f9f2b17ee5761e8e2381fb954f52709f4dbfdff6e50cb3716b96b2d2cee401127b7767ec2117a125e7aba9e0fa48f73d34a0ef9bd307c3b5",
"0063036f7264010118746578742f706c61696e3b636861727365743d7574662d38000b48656c6c6f20576f726c64682079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
"c179be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"sequence": 4294967293
}
],
from rust-bitcoin.
Thank you @Kixunil. This is highly appreciated!
I'll investigate, but commit_input_index
is currently fixed to 0
(see code)
from rust-bitcoin.
Related Issues (20)
- Fuzz failure in hashes/cbor HOT 2
- The `sha256t_hash_newtype!` call in the `taproot` module is unclear HOT 3
- Make `bitcoin::p2p::Magic::from_bytes` const function HOT 1
- Unused manifest key warning HOT 2
- What's the point of `Denomination::MilliSatoshi`? HOT 23
- `SegwitV0Sighash` is missing an `into_secp256k1_message` HOT 3
- Should be able to directly sign with sighashes HOT 7
- `Amount` should support milisats HOT 1
- Links to crate code inside `hash_newtype!` don't work HOT 3
- Mutation testing improvements (get rid of mutagen) HOT 9
- Fix bug in `pow.rs` HOT 3
- Consider Enabling explicitly formatting a derivation path with the `m/` prefix HOT 6
- Rustdoc: private doc tests lint HOT 2
- Add a script for common tasks updating lock files HOT 1
- Pin `cargo public-api` and other tools HOT 2
- Change `PushBytes::read_scriptint(x)` to `x.read_scriptint()`
- Displaying hex HOT 5
- No way to access `UnprefixedHexError` HOT 3
- Remove usage of wildcard imports
- Cannot get DerivationPath serialised from root anymore HOT 12
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rust-bitcoin.