kaspanet / rusty-kaspa

Kaspa full-node reference implementation and related libraries in the Rust programming language
ISC License
469 stars 152 forks source link

How to construct a partially signed transaction #463

Open Ligang9 opened 6 months ago

Ligang9 commented 6 months ago

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 commented 6 months ago

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

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

Ligang9 commented 6 months ago

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

Ligang9 commented 6 months ago

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 commented 6 months ago

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 commented 1 month ago

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 commented 1 month ago

as long as dimensionality of the dynamic model is right and you have the overwhelming stage, it doesn't matter you can perceive all families at once like hypersphere

On Wed, 18 Sept 2024 at 08:12, PATRICK DALLA BERNARDINA < @.***> wrote:

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?

— Reply to this email directly, view it on GitHub https://github.com/kaspanet/rusty-kaspa/issues/463#issuecomment-2357025657, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACCK6LGQ3YN6AJTKCFLCQSTZXCSONAVCNFSM6AAAAABGWWT6UGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNJXGAZDKNRVG4 . You are receiving this because you are subscribed to this thread.Message ID: @.***>