A assinatura parcial permite que várias partes assinem a mesma transação em momentos diferentes ou em dispositivos diferentes. Um coordenador cria a mensagem, cada signatário necessário assina os bytes exatos da mensagem serializada, e o coordenador verifica e combina as assinaturas antes do envio.
As assinaturas autorizam bytes, não intenções
Alterar o pagador da taxa, o blockhash, a ordem das instruções, a lista de contas ou qualquer instruction data produz uma mensagem diferente e invalida todas as assinaturas já recolhidas.
Fluxo de assinatura parcial
- Acorde as instruções da transação e quem pagará a taxa.
- Defina o tempo de vida da transação e o pagador da taxa.
- Serialize a mensagem uma única vez. Trate esses bytes como imutáveis.
- Distribua os bytes da mensagem e um resumo legível por humanos a cada signatário.
- Recolha e verifique cada assinatura Ed25519 em relação aos mesmos bytes da mensagem.
- Associe as assinaturas aos respetivos endereços de signatários necessários.
- Confirme que todas as assinaturas necessárias estão presentes e são válidas e, em seguida, envie.
Exemplo completo
O pagador da taxa e o remetente de SOL abaixo assinam de forma independente. O coordenador verifica ambas as assinaturas, combina-as e envia a transação concluída.
O exemplo utiliza assinatura Ed25519 em bruto para tornar explícita a fronteira entre o coordenador e cada signatário. Uma carteira, um dispositivo de hardware, um serviço de custódia ou um signatário offline pode substituir qualquer keypair local, desde que assine exatamente os mesmos bytes da mensagem.
Congele a mensagem antes de assinar
Cada assinatura abrange a mensagem de transação serializada. A mensagem inclui tudo o que se segue:
- o pagador da taxa
- o blockhash recente ou o nonce durável
- todos os endereços de programas e contas
- as permissões de signatário e de escrita das contas
- a ordem das instruções e a instruction data
Defina primeiro estes campos, serialize a mensagem uma única vez e distribua esse array de bytes a todos os signatários. É útil guardar um resumo (digest) da mensagem junto de cada pedido de assinatura, para que o coordenador possa rejeitar uma assinatura devolvida para uma mensagem diferente.
Não desserialize uma mensagem, não a altere e não espere que as assinaturas recolhidas anteriormente continuem válidas. Mesmo uma alteração que pareça operacional, como substituir um blockhash expirado ou alterar o pagador da taxa, obriga todos os signatários a assinar novamente.
Coordenar o pagador da taxa
O pagador da taxa é sempre um signatário necessário e tem de ser escolhido antes de a mensagem ser congelada. Confirme que a conta tem SOL suficiente para a taxa base e para qualquer taxa de prioridade. Se um patrocinador ou um backend pagar a taxa, coloque esse endereço na mensagem antes de recolher a assinatura do utilizador; adicionar o patrocinador mais tarde altera os bytes assinados.
O coordenador deve verificar se uma assinatura recebida pertence a um endereço indicado como signatário necessário. Nunca aceite uma chave pública arbitrária e a acrescente à transação.
Gerir o tempo de vida da transação
Uma transação com blockhash recente só é válida enquanto o respetivo blockhash permanecer na
fila de blockhashes recentes do validator. Antes de iniciar um fluxo de assinatura com várias partes,
avalie se todos os signatários conseguem responder antes de lastValidBlockHeight.
Se o blockhash expirar, crie uma nova mensagem com um blockhash recente e recolha novamente todas as assinaturas. Para fluxos de trabalho que possam demorar mais ou incluir signatários offline, utilize um nonce durável. Um nonce durável evita a janela do blockhash recente, mas avançar ou consumir de outra forma esse nonce continua a invalidar a transação pendente.
Verificar antes do envio
Para cada assinatura devolvida:
- Verifique a assinatura em relação aos bytes da mensagem congelada e à chave pública esperada do signatário.
- Associe-a à posição desse signatário no array de assinaturas da transação.
- Verifique se a transação montada tem assinaturas válidas para todos os signatários necessários.
- Envie a transação serializada sem reconstruir a respetiva mensagem.
Após o envio, confirme utilizando as mesmas informações de tempo de vida que foram incluídas na mensagem assinada. Se a confirmação indicar um blockhash expirado ou um nonce consumido, não tente novamente com uma transação modificada; reinicie o fluxo de assinatura.
Is this page helpful?