Un guide sur les signatures Starknet
Résumé
Cet article décrit le processus de signature et de vérification d'une signature sur Starknet. Il commence par présenter l'Abstraction de Compte et comment elle modifie la vérification de signature par rapport aux blockchains traditionnelles comme Ethereum. Il fournit ensuite des exemples de code complets en TypeScript et Go pour signer un message et vérifier une signature en utilisant deux méthodes disponibles sur Starknet : en utilisant la clé publique de l'utilisateur et en utilisant l'adresse du compte de l'utilisateur.
Cet article est basé sur l'article initialement publié sur dev.to par Bastien Faivre.
Abstraction de Compte
L'Abstraction de Compte est une fonctionnalité centrale de Starknet qui change fondamentalement le fonctionnement des comptes par rapport aux chaînes comme Ethereum. Dans Starknet, les comptes sont des smart contracts qui peuvent implémenter une logique arbitraire pour la validation de transaction. Cela signifie que différents contrats de compte peuvent implémenter différentes méthodes de vérification de signature. Bien que la plupart des comptes Starknet suivent un standard pour la vérification de signature, il est essentiel de comprendre que le contrat de compte lui-même définit la logique de validation.
Signer un message
Lors de la signature d'un message sur Starknet, vous devez d'abord obtenir une clé privée et son compte correspondant. Il existe différentes façons de le faire en fonction du langage et de la bibliothèque utilisés. En TypeScript, vous pouvez utiliser une bibliothèque comme `starknet` ou `starknet.js`. En Go, vous pouvez utiliser la bibliothèque `starknet.go` développée par Nethermind.
Voici un exemple de signature d'un message en TypeScript :
import { Signature, constants, ec, hash, stark } from "starknet";
// Generate a private key (usually you would use a secure storage method)
const privateKey = stark.randomAddress();
// Get the public key from the private key
const publicKey = ec.starkCurve.getStarkKey(privateKey);
// The message to sign
const message = "Hello, Starknet!";
// Hash the message
const messageHash = hash.starknetKeccak(message);
// Sign the message hash
const signature = ec.starkCurve.sign(messageHash, privateKey);
// The signature is an array of two elements: r and s
console.log("Signature:", signature);Vérifier une signature en utilisant la clé publique
Vérifier une signature en utilisant la clé publique est simple sur la plupart des plateformes blockchain. Dans Starknet, vous pouvez vérifier une signature en utilisant la clé publique du signataire avec un code comme celui-ci :
// Verify the signature using the public key
const isValid = ec.starkCurve.verify(messageHash, signature, publicKey);
console.log("Is the signature valid?", isValid);Vérifier une signature en utilisant l'adresse du compte
Dans Starknet, en raison de l'Abstraction de Compte, vous devez parfois vérifier une signature en utilisant l'adresse du compte du signataire plutôt que sa clé publique. Cela nécessite d'appeler la méthode `is_valid_signature` sur le contrat de compte. (Remarque : L'article original mentionne `isPrefixedMessageValid`, mais les contrats de compte standard utilisent souvent `is_valid_signature`. La méthode exacte peut varier.)
import { Account, Provider, constants, stark, Signature } from "starknet";
// Initialize a provider to connect to Starknet
const provider = new Provider({ sequencer: { network: constants.NetworkName.SN_MAIN } }); // Or your desired network
// Assume signerAddress, pkForSigner, messageHash and signature are defined
// const signerAddress = "0x123...";
// const pkForSigner = "0x456..."; // or connect with a wallet signer
// const messageHash = "0x789...";
// const signature: Signature = ["0xabc...", "0xdef..."];
async function verifySignatureUsingAccount(signerAddress: string, pkForSigner: string, msgHash: string, sig: Signature) {
const account = new Account(provider, signerAddress, pkForSigner);
try {
const result = await account.call("is_valid_signature", [
msgHash, // hash
sig.length.toString(), // signature_len
...sig // signature (r, s)
]);
// For Ready Wallet/Braavos standard accounts, a single felt "0x1" (VALID_SIGNATURE) is returned on success.
// Cairo0 contracts might return an array if the function has multiple return values.
// Check the specific account contract for exact return format if issues arise.
const isValid = Array.isArray(result) ? result[0] === "0x1" : result.result[0] === "0x1";
console.log("Is the signature valid (using account)?", isValid);
return isValid;
} catch (error) {
console.error("Error verifying signature using account:", error);
return false;
}
}
// Example usage (ensure variables are set)
// verifySignatureUsingAccount(signerAddress, pkForSigner, messageHash, signature);Travailler avec un portefeuille (Ready Wallet, Braavos, etc.)
Lorsque vous travaillez avec un portefeuille comme Ready Wallet ou Braavos, vous n'aurez généralement pas un accès direct à la clé privée de l'utilisateur. Au lieu de cela, vous devrez utiliser l'interface du portefeuille pour demander à l'utilisateur de signer un message.
// This is a conceptual example, actual implementation depends on the wallet connector library (e.g., starknet-react, get-starknet)
async function signMessageWithWallet(wallet: any, message: string) { // Use specific wallet type from your library
try {
// The method might be `signMessage`, `personalSign`, or similar
// The exact structure for `typedData` or `message` depends on the wallet and standard (e.g., EIP-712 for Starknet)
const signature = await wallet.account.signMessage({ message }); // Example structure, might need TypedData for some wallets
console.log("Signature from wallet:", signature);
return signature;
} catch (error) {
console.error("Error signing message with wallet:", error);
return null;
}
}Conclusion
Le modèle d'Abstraction de Compte de Starknet offre de la flexibilité pour la vérification de signature mais nécessite de comprendre les différences par rapport aux modèles de signature blockchain traditionnels. En suivant les exemples fournis, vous devriez être en mesure de signer efficacement des messages et de vérifier des signatures dans vos applications Starknet. Rappelez-vous que les détails d'implémentation spécifiques peuvent varier en fonction du fournisseur de portefeuille et du contrat de compte utilisé. Référez-vous toujours à la documentation spécifique du portefeuille ou du contrat de compte avec lequel vous travaillez.
Pour plus d'informations, consultez l'article original sur dev.to par Bastien Faivre.