Contratos de chamada¶
Este capítulo traça a linha Ler o Estado da Cadeia de Blocos já implicado, mas não soletrou completamente: a diferença entre chamando um contrato (simulado, livre, apenas para leitura) eth_call) e enviando uma transação a um contrato (uma ação real, de custo de gás, que exige uma assinatura). Confundir os dois é uma fonte comum de bugs e gastos desnecessários com gás.
Duas operações fundamentalmente diferentes por detrás de um código semelhante¶
// A CALL — free, instant, read-only, no signature needed.
const balance = await client.readContract({
address: tokenAddress,
abi: erc20Abi,
functionName: "balanceOf",
args: [someAddress],
});
// A TRANSACTION — costs gas, requires a signature, takes time to confirm.
const hash = await walletClient.writeContract({
address: tokenAddress,
abi: erc20Abi,
functionName: "transfer",
args: [recipientAddress, amount],
});
A distinção remonta diretamente a Funções: a view/pure função pode ser chamada com segurança com readContract (ou em bruto eth_call), uma vez que não faz alterações de estado para simular. Uma função de mudança de estado (não view/pure modificador) necessidades writeContract, que constrói, sinais (através da carteira conectada, veja Conectando as Carteiras), e transmite uma transação real.
Simular uma escrita antes de a enviar¶
Uma aplicação bem construída em geral simula uma chamada de mudança de estado antes de realmente enviá-la como uma transação, usando eth_call contra a mesma função e argumentos exatos que a transação real usará, especificamente para capturar uma falha (um reverso, um saldo insuficiente, argumentos inválidos) antes pagar qualquer gás real ou esperar por uma confirmação real:
// Simulates the write, catching failures for free, before spending real gas.
const { request } = await client.simulateContract({
address: tokenAddress,
abi: erc20Abi,
functionName: "transfer",
args: [recipientAddress, amount],
account: senderAddress,
});
const hash = await walletClient.writeContract(request);
Este padrão de duas etapas (simular, em seguida, enviar exatamente o que simulação validada) é prática padrão especificamente porque uma transação na cadeia falhou ainda custa o gás consumido até seu ponto de falha (recordar Gás), simulando as primeiras capturas mais falhas evitáveis de graça.
Conceitos errôneos comuns¶
Uma simulação bem sucedida não garante que a transação real também terá sucesso (o estado pode mudar entre simulação e a transação realmente sendo minada (outra transação poderia executar primeiro, alterando um saldo ou o estado de um contrato de uma forma que faça com que a chamada originalmente simulada falhe))) simulação reduz, mas não elimina, o risco de uma transação falhada, particularmente para condições de cadeia on- Execução frontal).
Chamar um view a função através do fluxo de envio de transações de uma carteira (em vez de uma leitura simples) não é "mais correta" ou "mais segura"É simplesmente desnecessário: a view função não faz alterações de estado para uma assinatura de carteira para autorizar significativamente, por isso roteá-lo através do fluxo de transação apenas adiciona atrito desnecessário (um popup carteira, uma espera para confirmação) para nenhum benefício adicional sobre uma planície, livre readContract Cubro.
Outras leituras¶
← Anterior: Lendo Blockchain Estado · Voltar para Construindo Aplicações Web3 · Próximo: Envio de Transações →