3.6 KiB
Offline Transaction Signing
Some security models require keeping signing keys, and thus the signing process, separated from transaction creation and network broadcast. Examples include:
- Collecting signatures from geographically disparate signers in a multi-signature scheme
- Signing transactions using an airgapped signing device
This document describes using Solana's CLI to separately sign and submit a transaction.
Commands Supporting Offline Signing
At present, the following commands support offline signing:
create-stake-account
deactivate-stake
delegate-stake
split-stake
stake-authorize-staker
stake-authorize-withdrawer
stake-set-lockup
transfer
withdraw-stake
Signing Transactions Offline
To sign a transaction offline, pass the following arguments on the command line
--sign-only
, prevents the client from submitting the signed transaction to the network. Instead, the pubkey/signature pairs are printed to stdout.--blockhash BASE58_HASH
, allows the caller to specify the value used to fill the transaction'srecent_blockhash
field. This serves a number of purposes, namely:- Eliminates the need to connect to the network and query a recent blockhash via RPC
- Enables the signers to coordinate the blockhash in a multiple-signature scheme
Example: Offline Signing a Payment
Command
solana@offline$ solana pay --sign-only --blockhash 5Tx8F3jgSHx21CbtjwmdaKPLM5tWmreWAnPrbqHomSJF \
recipient-keypair.json 1
Output
Blockhash: 5Tx8F3jgSHx21CbtjwmdaKPLM5tWmreWAnPrbqHomSJF
Signers (Pubkey=Signature):
FhtzLVsmcV7S5XqGD79ErgoseCLhZYmEZnz9kQg1Rp7j=4vC38p4bz7XyiXrk6HtaooUqwxTWKocf45cstASGtmrD398biNJnmTcUCVEojE7wVQvgdYbjHJqRFZPpzfCQpmUN
{"blockhash":"5Tx8F3jgSHx21CbtjwmdaKPLM5tWmreWAnPrbqHomSJF","signers":["FhtzLVsmcV7S5XqGD79ErgoseCLhZYmEZnz9kQg1Rp7j=4vC38p4bz7XyiXrk6HtaooUqwxTWKocf45cstASGtmrD398biNJnmTcUCVEojE7wVQvgdYbjHJqRFZPpzfCQpmUN"]}'
Submitting Offline Signed Transactions to the Network
To submit a transaction that has been signed offline to the network, pass the following arguments on the command line
--blockhash BASE58_HASH
, must be the same blockhash as was used to sign--signer BASE58_PUBKEY=BASE58_SIGNATURE
, one for each offline signer. This includes the pubkey/signature pairs directly in the transaction rather than signing it with any local keypair(s)
Example: Submitting an Offline Signed Payment
Command
solana@online$ solana pay --blockhash 5Tx8F3jgSHx21CbtjwmdaKPLM5tWmreWAnPrbqHomSJF \
--signer FhtzLVsmcV7S5XqGD79ErgoseCLhZYmEZnz9kQg1Rp7j=4vC38p4bz7XyiXrk6HtaooUqwxTWKocf45cstASGtmrD398biNJnmTcUCVEojE7wVQvgdYbjHJqRFZPpzfCQpmUN
recipient-keypair.json 1
Output
4vC38p4bz7XyiXrk6HtaooUqwxTWKocf45cstASGtmrD398biNJnmTcUCVEojE7wVQvgdYbjHJqRFZPpzfCQpmUN
Buying More Time to Sign
Typically a Solana transaction must be signed and accepted by the network within
a number of slots from the blockhash in its recent_blockhash
field (~2min at
the time of this writing). If your signing procedure takes longer than this, a
Durable Transaction Nonce can give you the extra time you
need.