Ein Leitfaden zu Starknet-Signaturen
Zusammenfassung
Dieser Artikel skizziert den Prozess des Signierens und Verifizierens einer Signatur auf Starknet. Er beginnt mit der Einführung von Account Abstraction und wie sie die Signaturverifizierung im Vergleich zu traditionellen Blockchains wie Ethereum modifiziert. Anschließend bietet er umfassende Code-Beispiele in TypeScript und Go zum Signieren einer Nachricht und zum Verifizieren einer Signatur unter Verwendung von zwei auf Starknet verfügbaren Methoden: Verwendung des öffentlichen Schlüssels des Benutzers und Verwendung der Kontoadresse des Benutzers.
Dieser Beitrag basiert auf dem Artikel, der ursprünglich auf dev.to von Bastien Faivre veröffentlicht wurde.
Account Abstraction
Account Abstraction ist ein Kernmerkmal von Starknet, das grundlegend verändert, wie Konten im Vergleich zu Chains wie Ethereum funktionieren. In Starknet sind Konten Smart Contracts, die beliebige Logik für die Transaktionsvalidierung implementieren können. Das bedeutet, dass verschiedene Kontokontrakte unterschiedliche Signaturverifizierungsmethoden implementieren können. Während die meisten Starknet-Konten einem Standard für die Signaturverifizierung folgen, ist es wichtig zu verstehen, dass der Kontokontrakt selbst die Validierungslogik definiert.
Eine Nachricht signieren
Beim Signieren einer Nachricht auf Starknet benötigen Sie zunächst einen privaten Schlüssel und das entsprechende Konto. Es gibt verschiedene Möglichkeiten, dies zu tun, abhängig von der verwendeten Sprache und Bibliothek. In TypeScript können Sie eine Bibliothek wie `starknet` oder `starknet.js` verwenden. In Go können Sie die von Nethermind entwickelte `starknet.go`-Bibliothek verwenden.
Hier ist ein Beispiel für das Signieren einer Nachricht in 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);Eine Signatur mit dem öffentlichen Schlüssel verifizieren
Das Verifizieren einer Signatur mit dem öffentlichen Schlüssel ist auf den meisten Blockchain-Plattformen unkompliziert. In Starknet können Sie eine Signatur mit dem öffentlichen Schlüssel des Unterzeichners mit Code wie diesem verifizieren:
// Verify the signature using the public key
const isValid = ec.starkCurve.verify(messageHash, signature, publicKey);
console.log("Is the signature valid?", isValid);Eine Signatur mit der Kontoadresse verifizieren
In Starknet müssen Sie aufgrund von Account Abstraction manchmal eine Signatur mit der Kontoadresse des Unterzeichners anstelle ihres öffentlichen Schlüssels verifizieren. Dies erfordert das Aufrufen der `is_valid_signature`-Methode auf dem Kontokontrakt. (Hinweis: Der Originalartikel erwähnt `isPrefixedMessageValid`, aber Standard-Kontokontrakte verwenden oft `is_valid_signature`. Die genaue Methode kann variieren.)
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);Arbeiten mit einer Wallet (Ready Wallet, Braavos, etc.)
Wenn Sie mit einer Wallet wie Ready Wallet oder Braavos arbeiten, haben Sie normalerweise keinen direkten Zugriff auf den privaten Schlüssel des Benutzers. Stattdessen müssen Sie die Schnittstelle der Wallet verwenden, um den Benutzer aufzufordern, eine Nachricht zu signieren.
// 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;
}
}Fazit
Starknets Account Abstraction-Modell bietet Flexibilität für die Signaturverifizierung, erfordert aber das Verständnis der Unterschiede zu traditionellen Blockchain-Signaturmodellen. Indem Sie den bereitgestellten Beispielen folgen, sollten Sie in der Lage sein, Nachrichten effektiv zu signieren und Signaturen in Ihren Starknet-Anwendungen zu verifizieren. Beachten Sie, dass die spezifischen Implementierungsdetails je nach verwendetem Wallet-Anbieter und Kontokontrakt variieren können. Beziehen Sie sich immer auf die spezifische Dokumentation der Wallet oder des Kontokontrakts, mit dem Sie arbeiten.
Für weitere Informationen schauen Sie sich den Originalartikel auf dev.to von Bastien Faivre an.