solana_program::system_instruction

Function create_nonce_account

Source
pub fn create_nonce_account(
    from_pubkey: &Pubkey,
    nonce_pubkey: &Pubkey,
    authority: &Pubkey,
    lamports: u64,
) -> Vec<Instruction>
Expand description

Create an account containing a durable transaction nonce.

This function produces a vector of Instructions which must be submitted in a Transaction or invoked to take effect, containing a serialized SystemInstruction::CreateAccount and SystemInstruction::InitializeNonceAccount.

A durable transaction nonce is a special account that enables execution of transactions that have been signed in the past.

Standard Solana transactions include a recent blockhash (sometimes referred to as a nonce). During execution the Solana runtime verifies the recent blockhash is approximately less than two minutes old, and that in those two minutes no other identical transaction with the same blockhash has been executed. These checks prevent accidental replay of transactions. Consequently, it is not possible to sign a transaction, wait more than two minutes, then successfully execute that transaction.

Durable transaction nonces are an alternative to the standard recent blockhash nonce. They are stored in accounts on chain, and every time they are used their value is changed to a new value for their next use. The runtime verifies that each durable nonce value is only used once, and there are no restrictions on how “old” the nonce is. Because they are stored on chain and require additional instructions to use, transacting with durable transaction nonces is more expensive than with standard transactions.

The value of the durable nonce is itself a blockhash and is accessible via the blockhash field of nonce::state::Data, which is deserialized from the nonce account data.

The basic durable transaction nonce lifecycle is

  1. Create the nonce account with the create_nonce_account instruction.
  2. Submit specially-formed transactions that include the advance_nonce_account instruction.
  3. Destroy the nonce account by withdrawing its lamports with the withdraw_nonce_account instruction.

Nonce accounts have an associated authority account, which is stored in their account data, and can be changed with the authorize_nonce_account instruction. The authority must sign transactions that include the advance_nonce_account, authorize_nonce_account and withdraw_nonce_account instructions.

Nonce accounts are owned by the system program.

This constructor creates a SystemInstruction::CreateAccount instruction and a SystemInstruction::InitializeNonceAccount instruction.

§Required signers

The from_pubkey and nonce_pubkey signers must sign the transaction.

§Examples

Create a nonce account from an off-chain client:

use solana_rpc_client::rpc_client::RpcClient;
use solana_sdk::{
    signature::{Keypair, Signer},
    system_instruction,
    transaction::Transaction,
    nonce::State,
};
use anyhow::Result;

fn submit_create_nonce_account_tx(
    client: &RpcClient,
    payer: &Keypair,
) -> Result<()> {

    let nonce_account = Keypair::new();

    let nonce_rent = client.get_minimum_balance_for_rent_exemption(State::size())?;
    let instr = system_instruction::create_nonce_account(
        &payer.pubkey(),
        &nonce_account.pubkey(),
        &payer.pubkey(), // Make the fee payer the nonce account authority
        nonce_rent,
    );

    let mut tx = Transaction::new_with_payer(&instr, Some(&payer.pubkey()));

    let blockhash = client.get_latest_blockhash()?;
    tx.try_sign(&[&nonce_account, payer], blockhash)?;

    client.send_and_confirm_transaction(&tx)?;

    Ok(())
}