La firma parziale consente a più parti di firmare la stessa transazione in momenti diversi o su dispositivi diversi. Un coordinatore crea il messaggio, ogni firmatario richiesto firma i byte esatti del messaggio serializzato, e il coordinatore verifica e unisce le firme prima dell'invio.
Le firme autorizzano i byte, non l'intento
Modificare il fee payer, il blockhash, l'ordine delle istruzioni, l'elenco degli account o qualsiasi instruction data produce un messaggio diverso e invalida tutte le firme già raccolte.
Flusso di firma parziale
- Concordare le istruzioni della transazione e chi pagherà la commissione.
- Impostare la durata della transazione e il fee payer.
- Serializzare il messaggio una sola volta. Trattare quei byte come immutabili.
- Distribuire i byte del messaggio e un riepilogo leggibile a ciascun firmatario.
- Raccogliere e verificare ogni firma Ed25519 rispetto agli stessi byte del messaggio.
- Associare le firme agli indirizzi dei firmatari richiesti.
- Verificare che ogni firma richiesta sia presente e valida, quindi inviare.
Esempio completo
Il fee payer e il mittente di SOL qui sotto firmano in modo indipendente. Il coordinatore verifica entrambe le firme, le unisce e invia la transazione completata.
L'esempio utilizza la firma Ed25519 grezza per rendere esplicito il confine tra il coordinatore e ciascun firmatario. Un wallet, un dispositivo hardware, un servizio di custodia o un firmatario offline possono sostituire qualsiasi keypair locale, purché firmino esattamente gli stessi byte del messaggio.
Blocca il messaggio prima della firma
Ogni firma copre il messaggio di transazione serializzato. Il messaggio include tutto quanto segue:
- il fee payer
- il blockhash recente o il durable nonce
- gli indirizzi di ogni programma e account
- i permessi di firmatario e di scrittura degli account
- l'ordine delle istruzioni e le instruction data
Crea prima questi campi, serializza il messaggio una sola volta e distribuisci quell'array di byte a ogni firmatario. È utile conservare un digest del messaggio insieme a ogni richiesta di firma, in modo che il coordinatore possa rifiutare una firma restituita per un messaggio diverso.
Non deserializzare un messaggio, modificarlo e aspettarsi che le firme raccolte in precedenza rimangano valide. Anche una modifica che sembra operativa, come sostituire un blockhash scaduto o cambiare il fee payer, richiede che ogni firmatario firmi di nuovo.
Coordinare il fee payer
Il fee payer è sempre un firmatario richiesto e deve essere scelto prima che il messaggio venga bloccato. Verifica che l'account abbia SOL sufficienti per la commissione base e per qualsiasi commissione di priorità. Se uno sponsor o un backend pagherà la commissione, inserisci quell'indirizzo nel messaggio prima di raccogliere la firma dell'utente: aggiungere lo sponsor in un secondo momento modifica i byte firmati.
Il coordinatore deve verificare che una firma in arrivo appartenga a un indirizzo elencato come firmatario richiesto. Non accettare mai una chiave pubblica arbitraria e non aggiungerla alla transazione.
Gestire la durata della transazione
Una transazione con blockhash recente è valida solo finché il suo blockhash rimane nella coda dei
blockhash recenti del validator. Prima di avviare un flusso di firma multi-parte,
stima se tutti i firmatari possono rispondere prima di lastValidBlockHeight.
Se il blockhash scade, crea un nuovo messaggio con un blockhash aggiornato e raccogli nuovamente tutte le firme. Per i flussi di lavoro che possono richiedere più tempo o includere firmatari offline, usa un durable nonce. Un durable nonce evita la finestra del blockhash recente, ma far avanzare o consumare in altro modo quel nonce invalida comunque la transazione in sospeso.
Verificare prima dell'invio
Per ogni firma restituita:
- Verifica la firma rispetto ai byte del messaggio bloccato e alla chiave pubblica del firmatario previsto.
- Associala alla posizione di quel firmatario nell'array delle firme della transazione.
- Verifica che la transazione assemblata abbia firme valide per ogni firmatario richiesto.
- Invia la transazione serializzata senza ricostruirne il messaggio.
Dopo l'invio, conferma usando le stesse informazioni sulla durata che erano incluse nel messaggio firmato. Se la conferma segnala un blockhash scaduto o un nonce consumato, non riprovare con una transazione modificata: riavvia il flusso di firma.
Is this page helpful?