使用场景假设使用用户a向用户b转账,做离线转账,机器1有user_a的私钥user_a.json,$solana-keygennew-ouser_a.json$solanaairdrop10user_a.json$solana-keygenpubkey
Solana 原生交易有一个硬性规则:每笔交易必须包含「最近区块哈希(Recent Blockhash)」,这个哈希对应 Solana 网络最近生成的区块,作用是:
Blockhash not found);这个规则带来两个核心痛点:
而 Nonce 就是为解决这些痛点而生 —— 它用「Nonce 账户存储的一次性数值」替代「最近区块哈希」,让交易突破有效期限制,同时保留防重放能力。
使用 Nonce 后,交易不再依赖「时效性极强的区块哈希」,而是绑定到 Nonce 账户 中的唯一一次性数值:
Nonce 是「一次性」的:
对于需要批量提交的交易(如空投、批量转账),可以将多笔交易绑定到同一个 Nonce:
虽然 anza.xyz 文档 给出的离线签名,但是执行例子会有问题, 我这里给出一个可用的例子
注意发起交易签名的用户A ,同时拥有nonce账户。 只有A签名后,nonce值会变化。
$ solana-keygen new -o user_a.json
$ solana airdrop 10 user_a.json
$ solana-keygen pubkey user_a.json
5PXGnujgn4krEznEg7QydU8YLEVJKfFEyJ46z3oZKRPt
机器1 知道 两个用户的公约USER_A,USER_B
solana-keygen new -o nonce.json
solana create-nonce-account nonce.json 0.1
solana-keygen pubkey nonce.json
机器1 知道 两个用户的公约USER_A,USER_B
$ solana-keygen new -o user_b.json
$ solana-keygen pubkey user_b.json
DmpyfL7ZQCETqixTWVNEX44QusrezjmQDzAZg3cQoWUf
export USER_A=5PXGnujgn4krEznEg7QydU8YLEVJKfFEyJ46z3oZKRPt
export USER_B=DmpyfL7ZQCETqixTWVNEX44QusrezjmQDzAZg3cQoWUf
export NONCE=ZJuCQkpqgXisayp3KCAdPsMuXcCsxvoRo7M8v6zVyfn
假设此时没有solana网络, a 向b 转账 1 sol。 如果a 签名好, 把签名信息和公约
$ solana nonce-account $NONCE
Balance: 0.1 SOL
Minimum Balance Required: 0.00144768 SOL
Nonce blockhash: 4NXnh5LHdEMyFZU6ogWyveaQ64xKYn38hGAKT6CJuYA5
Fee: 5000 lamports per signature
Authority: 5PXGnujgn4krEznEg7QydU8YLEVJKfFEyJ46z3oZKRPt
export BLOCK_HASH=`solana nonce-account $NONCE |grep blockhash |awk -F ': ' '{gsub(/[[:space:]]/, "", $2); print $2}'`
echo "blockhash is [$BLOCK_HASH]"
$ solana transfer $USER_B 1 \
--blockhash $BLOCK_HASH \
--nonce $NONCE \
--nonce-authority $USER_A \
--sign-only \
--keypair user_a.json \
--from $USER_A \
--fee-payer user_a.json \
> a2b.txt
cat a2b.txt
Blockhash: Eo8YJRk6BhzGE2LZ44i1ebTRsFgD3uNvRguHPsPuP4Ww
Signers (Pubkey=Signature):
5PXGnujgn4krEznEg7QydU8YLEVJKfFEyJ46z3oZKRPt=5psu7QbhJFHcy4uoH7cDgk8jSj1YcxRb96bdSjzd5wDfrA3TiKZjZBhSsA7TzDZa3SD9ytantSPXnk4wv6HJEiZn
export SIGNATURE_A2B=`cat a2b.txt |grep -A 1 Signers |grep $USER_A `
export SIGNATURE_A2B=`echo $SIGNATURE_A2B|xargs `
echo "SIGNATURE_A2B=[$SIGNATURE_A2B]"
echo "export BLOCK_HASH=$BLOCK_HASH"
echo "export USER_A=$USER_A"
echo "export USER_B=$USER_B"
echo "export NONCE=$NONCE"
echo "export SIGNATURE_A2B='$SIGNATURE_A2B'"
output sample
export BLOCK_HASH=Eo8YJRk6BhzGE2LZ44i1ebTRsFgD3uNvRguHPsPuP4Ww
export USER_A=5PXGnujgn4krEznEg7QydU8YLEVJKfFEyJ46z3oZKRPt
export USER_B=DmpyfL7ZQCETqixTWVNEX44QusrezjmQDzAZg3cQoWUf
export NONCE=ZJuCQkpqgXisayp3KCAdPsMuXcCsxvoRo7M8v6zVyfn
export SIGNATURE_A2B='5PXGnujgn4krEznEg7QydU8YLEVJKfFEyJ46z3oZKRPt=5psu7QbhJFHcy4uoH7cDgk8jSj1YcxRb96bdSjzd5wDfrA3TiKZjZBhSsA7TzDZa3SD9ytantSPXnk4wv6HJEiZn'
solana transfer $USER_B 1 \
--blockhash $BLOCK_HASH \
--nonce $NONCE \
--nonce-authority $USER_A \
--signer $SIGNATURE_A2B \
--from $USER_A \
--fee-payer $USER_A \
--allow-unfunded-recipient
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!