Skip to content
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

How to construct a partially signed transaction #463

Open
Ligang9 opened this issue Apr 24, 2024 · 6 comments
Open

How to construct a partially signed transaction #463

Ligang9 opened this issue Apr 24, 2024 · 6 comments

Comments

@Ligang9
Copy link

Ligang9 commented Apr 24, 2024

Can you give me a demo of a transaction involving partial signatures from multiple people?
In addition, I have a question: For example, a transaction requires three people to sign. If the first two people have signed, and it is the third person's turn to sign, will the third person see the private keys of the first two people?

@aspect
Copy link
Collaborator

aspect commented Apr 24, 2024

You only see signatures from other parties. Private keys never get exposed.

Which language/framework are you using (direct Rust or JavaScript/TypeScript)?

@Ligang9
Copy link
Author

Ligang9 commented Apr 25, 2024

The language I use is JavaScript/TypeScript, thank you for your reply

@Ligang9
Copy link
Author

Ligang9 commented Apr 25, 2024

I still have a question. For example, a transaction requires three people to sign. Now the first two people have signed, and now it is the third person's turn to sign. Does privkeys need to pass in the private keys of the three people, or does it mean that you only need to pass in your own private key? That's it

pub fn sign_with_multiple_v2(mut mutable_tx: SignableTransaction, privkeys: Vec<[u8; 32]>) -> Signed {
let mut map = BTreeMap::new();
for privkey in privkeys {
let schnorr_key = secp256k1::KeyPair::from_seckey_slice(secp256k1::SECP256K1, &privkey).unwrap();
let schnorr_public_key = schnorr_key.public_key().x_only_public_key().0;
let script_pub_key_script = once(0x20).chain(schnorr_public_key.serialize().into_iter()).chain(once(0xac)).collect_vec();
map.insert(script_pub_key_script, schnorr_key);
}

let mut reused_values = SigHashReusedValues::new();
let mut additional_signatures_required = false;
for i in 0..mutable_tx.tx.inputs.len() {
    let script = mutable_tx.entries[i].as_ref().unwrap().script_public_key.script();
    if let Some(schnorr_key) = map.get(&script.to_vec()) {
        let sig_hash = calc_schnorr_signature_hash(&mutable_tx.as_verifiable(), i, SIG_HASH_ALL, &mut reused_values);
        let msg = secp256k1::Message::from_slice(sig_hash.as_bytes().as_slice()).unwrap();
        let sig: [u8; 64] = *schnorr_key.sign_schnorr(msg).as_ref();
        // This represents OP_DATA_65 <SIGNATURE+SIGHASH_TYPE> (since signature length is 64 bytes and SIGHASH_TYPE is one byte)
        mutable_tx.tx.inputs[i].signature_script = std::iter::once(65u8).chain(sig).chain([SIG_HASH_ALL.to_u8()]).collect();
    } else {
        additional_signatures_required = true;
    }
}
if additional_signatures_required {
    Signed::Partially(mutable_tx)
} else {
    Signed::Fully(mutable_tx)
}

}

@aspect
Copy link
Collaborator

aspect commented Apr 25, 2024

Passing private keys around would defeat the purpose of any multi-party signing.

https://kaspa.aspectron.org/docs/classes/Transaction.html has serializeToJSON and serializeToSafeJSON (and the opposites) which allow ser/deser of transactions to/from JSON. "SafeJSON" converts all bigint values to strings; there is also serializeToObject that returns a pure JavaScript Object.

You should ask for feedback to your questions on Discord#development

@patrickdalla
Copy link

Hi. I would like a sample o PSKT building in javascript also.
I want to create a transaction with unpredictable inputs, and unpredictable outputs, till the creator decides to finalize it. It is possible?

@gvbgduh
Copy link
Contributor

gvbgduh commented Sep 18, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants