SOL, Lamports e Unidades
A Solana armazena toda moeda nativa como lamports - inteiros sem sinal de 64 bits. Entender denominações previne bugs de arredondamento, transações com falha e cálculos incorretos de taxa.
Busque em todas as páginas da documentação
A Solana armazena toda moeda nativa como lamports - inteiros sem sinal de 64 bits. Entender denominações previne bugs de arredondamento, transações com falha e cálculos incorretos de taxa.
Cartão de receita de referência rápida - pronto para copiar.
import { lamports } from "@solana/kit";
const ONE_SOL = 1_000_000_000n;
const halfSol = lamports(500_000_000n);
function solToLamports(sol: number): bigint {
return BigInt(Math.round(sol * 1e9));
}
function lamportsToSol(lps: bigint): string {
return (Number(lps) / 1e9).toFixed(9);
}Quando usar:
decimals do mint (separado de SOL nativo)import { createSolanaRpc, address, lamports } from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
import {
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
pipe,
} from "@solana/kit";
const rpc = createSolanaRpc("https://api.devnet.solana.com");
const sender = address("SENDER_PUBKEY");
const recipient = address("RECIPIENT_PUBKEY");
// Usuário digita "0.25" SOL em formulário da UI
const userInputSol = 0.25;
const amountLamports = BigInt(Math.round(userInputSol * 1_000_000_000));
const { value: balance } = await rpc.getBalance(sender).send();
if (balance < amountLamports) {
throw new Error(
`Insufficient: have ${Number(lamports(balance)) / 1e9} SOL, need ${userInputSol}`,
);
}
const { value: blockhash } = await rpc.getLatestBlockhash().send();
const transferIx = getTransferSolInstruction({
source: sender,
destination: recipient,
amount: amountLamports,
});
const message = pipe(
createTransactionMessage({ version: 0 }),
(m) => setTransactionMessageFeePayer(sender, m),
(m) => setTransactionMessageLifetimeUsingBlockhash(blockhash, m),
(m) => appendTransactionMessageInstruction(transferIx, m),
);
console.log("Transfer message built for", amountLamports, "lamports");O que isso demonstra:
bigint antes de qualquer comparação on-chaingetBalance retorna lamports - compare inteiros, não floatslamports() do Kit envolve valores brutos para clareza de tipo| Unidade | Lamports | Uso Típico |
|---|---|---|
| 1 lamport | 1 | Menor unidade nativa |
| 1 SOL | 1.000.000.000 | Exibição voltada ao usuário |
| Priority fee | microlamports/CU | Compute Budget Program |
| Taxa base | 5.000 lamports/signature | Custo por signature (padrão atual) |
use anchor_lang::prelude::*;
const LAMPORTS_PER_SOL: u64 = 1_000_000_000;
pub fn transfer_amount(ctx: Context<Transfer>, sol: f64) -> Result<()> {
let lamports = (sol * LAMPORTS_PER_SOL as f64) as u64; // evite em produção
// Prefira: usuário fornece lamports diretamente, ou use crate fixed-point
require!(lamports > 0, ErrorCode::ZeroAmount);
Ok(())
}f64 para u64 em código financeiro de produção - use input inteiroanchor_lang fornece alias de tipo Lamports em alguns contextoschecked_add, checked_sub para aritmética de saldo em programas0.1 + 0.2 !== 0.3 pode produzir lamports errados. Correção: parse strings de usuário para bigint via matemática inteira ou biblioteca decimal.Number.MAX_SAFE_INTEGER perdem precisão. Correção: formate lamports como bigint ou use formatador baseado em string.mint.decimals antes de converter valores de token.getMinimumBalanceForRentExemption e armazene valor exato em lamports.| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
bigint em TypeScript | Todo tratamento de valor on-chain | Precisa suporte legacy de browser sem polyfills |
Decimal.js / bignumber.js | Parse seguro de strings decimais de usuário | Dentro de programas Rust on-chain |
| Apenas lamports inteiros (sem tipo SOL) | Args de instrução de programa | Montando UIs de carteira voltadas ao usuário |
Helper lamports() do @solana/kit | Pipelines Kit type-safe | Scripts RPC brutos onde Kit é excesso |
1.000.000.000 (10^9). Isso é fixo e nunca muda.
Execução determinística entre validadores exige aritmética exata. Ponto flutuante varia por hardware; inteiros u64 não.
1 lamport. Na prática, taxas de transação (5.000 lamports por signature por padrão) tornam transferências sub-lamport sem sentido.
function parseSolToLamports(input: string): bigint {
const [whole, frac = ""] = input.split(".");
const padded = (frac + "000000000").slice(0, 9);
return BigInt(whole) * 1_000_000_000n + BigInt(padded);
}Lamports. Divida por 1e9 só para exibição - nunca para instruções on-chain.
1 microlamport = 0.000001 lamport. Priority fees são precificadas em microlamports por compute unit via Compute Budget Program.
Teoricamente com ~18,4 bilhões de SOL de supply total não é preocupação prática, mas lógica de programa ainda deve usar aritmética verificada.
Baseada no tamanho de dados da conta em bytes. RPC getMinimumBalanceForRentExemption(dataSize) retorna o depósito exato em lamports exigido.
Armazene lamports como inteiros (ou strings para valores muito grandes). Converta para SOL só na camada de apresentação.
O System Program rejeita transferências de zero lamport. Use mínimo significativo ou pule a instrução.
Não. Tokens SPL usam o campo decimals do mint. Um valor USDC de 1_000_000 significa 1 USDC (6 decimals), não lamports.
Divida lamports bigint em partes inteiras e fracionárias com matemática de string, ou use biblioteca. Evite Number(lamports) para valores que reenviará on-chain.
Versões da stack: Esta página foi escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 e LiteSVM 0.6.x.
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026