Zum Hauptinhalt springen

EIP-1271: Signieren und Verifizieren von Smart-Contract-Signaturen

eip-1271
Smart Contracts
Verifizieren
Signieren
Fortgeschritten
Nathan H. Leung
12. Januar 2023
6 Minuten Lesezeit

Der EIP-1271 (opens in a new tab)-Standard ermöglicht es Smart Contracts, Signaturen zu verifizieren.

In diesem Tutorial geben wir einen Überblick über Digitale Signaturen, den Hintergrund von EIP-1271 und die spezifische Implementierung von EIP-1271, die von Safe (opens in a new tab) (ehemals Gnosis Safe) verwendet wird. Alles in allem kann dies als Ausgangspunkt für die Implementierung von EIP-1271 in Ihren eigenen Verträgen dienen.

Was ist eine Signatur?

In diesem Zusammenhang ist eine Signatur (genauer gesagt eine „Digitale Signatur“) eine Nachricht plus eine Art Beweis, dass die Nachricht von einer bestimmten Person/einem bestimmten Absender/einer bestimmten Adresse stammt.

Eine Digitale Signatur könnte zum Beispiel so aussehen:

  1. Nachricht: „Ich möchte mich auf dieser Website mit meinem Ethereum-Wallet anmelden.“
  2. Unterzeichner: Meine Adresse lautet 0x000…
  3. Beweis: Hier ist ein Beweis, dass ich, 0x000…, diese gesamte Nachricht tatsächlich erstellt habe (dies ist normalerweise etwas Kryptografisches).

Es ist wichtig zu beachten, dass eine Digitale Signatur sowohl eine „Nachricht“ als auch eine „Signatur“ enthält.

Warum? Wenn Sie mir zum Beispiel einen Vertrag zur Unterschrift geben würden und ich dann die Unterschriftenseite abschneiden und Ihnen nur meine Unterschriften ohne den Rest des Vertrags zurückgeben würde, wäre der Vertrag nicht gültig.

Genauso bedeutet eine Digitale Signatur ohne eine zugehörige Nachricht nichts!

Warum gibt es EIP-1271?

Um eine Digitale Signatur für die Verwendung auf Ethereum-basierten Blockchains zu erstellen, benötigen Sie im Allgemeinen einen geheimen Private-Key, den niemand sonst kennt. Das macht Ihre Signatur zu Ihrer eigenen (niemand sonst kann ohne Kenntnis des geheimen Schlüssels dieselbe Signatur erstellen).

Mit Ihrem Ethereum-Konto (d. h. Ihrem extern verwalteten Konto/EOA) ist ein Private-Key verknüpft, und dies ist der Private-Key, der typischerweise verwendet wird, wenn eine Website oder Dapp Sie um eine Signatur bittet (z. B. für „Mit Ethereum anmelden“).

Eine App kann eine Signatur verifizieren (opens in a new tab), die Sie mit einer Drittanbieter-Bibliothek wie ethers.js erstellen, ohne Ihren Private-Key zu kennen (opens in a new tab), und sicher sein, dass Sie derjenige waren, der die Signatur erstellt hat.

Da EOA-Digitale-Signaturen Public-Key-Kryptografie verwenden, können sie tatsächlich Off-Chain generiert und verifiziert werden! So funktioniert die gaslose DAO-Abstimmung – anstatt Stimmen auf der Blockchain einzureichen, können Digitale Signaturen mithilfe kryptografischer Bibliotheken Off-Chain erstellt und verifiziert werden.

Während EOA-Konten einen Private-Key haben, verfügen Smart-Contract-Konten über keinerlei privaten oder geheimen Schlüssel (daher kann „Mit Ethereum anmelden“ usw. nicht nativ mit Smart-Contract-Konten funktionieren).

Das Problem, das EIP-1271 lösen möchte: Wie können wir feststellen, ob eine Smart-Contract-Signatur gültig ist, wenn der Smart Contract kein „Geheimnis“ hat, das er in die Signatur integrieren kann?

Wie funktioniert EIP-1271?

Smart Contracts haben keine Private-Keys, die zum Signieren von Nachrichten verwendet werden können. Wie können wir also feststellen, ob eine Signatur authentisch ist?

Nun, eine Idee ist, dass wir den Smart Contract einfach fragen können, ob eine Signatur authentisch ist!

Was EIP-1271 tut, ist, diese Idee des „Fragens“ eines Smart Contracts, ob eine bestimmte Signatur gültig ist, zu standardisieren.

Ein Vertrag, der EIP-1271 implementiert, muss eine Funktion namens isValidSignature haben, die eine Nachricht und eine Signatur entgegennimmt. Der Vertrag kann dann eine Validierungslogik ausführen (die Spezifikation schreibt hier nichts Spezifisches vor) und dann einen Wert zurückgeben, der angibt, ob die Signatur gültig ist oder nicht.

Wenn isValidSignature ein gültiges Ergebnis zurückgibt, bedeutet das im Grunde, dass der Vertrag sagt: „Ja, ich genehmige diese Signatur + Nachricht!“

Schnittstelle

Hier ist die genaue Schnittstelle in der EIP-1271-Spezifikation (wir werden unten über den Parameter _hash sprechen, aber betrachten Sie ihn vorerst als die Nachricht, die verifiziert wird):

1pragma solidity ^0.5.0;
2
3contract ERC1271 {
4
5 // bytes4(keccak256("isValidSignature(bytes32,bytes)")
6 bytes4 constant internal MAGICVALUE = 0x1626ba7e;
7
8 /* *
9 * @dev Sollte zurückgeben, ob die bereitgestellte Signatur für den bereitgestellten Hash gültig ist
10 * @param _hash Hash der zu signierenden Daten
11 * @param _signature Signatur-Byte-Array, das mit _hash verknüpft ist
12 *
13 * MUSS den magischen bytes4-Wert 0x1626ba7e zurückgeben, wenn die Funktion erfolgreich ist.
14 * DARF den Zustand NICHT ändern (Verwendung von STATICCALL für solc < 0.5, view-Modifikator für solc > 0.5)
15 * MUSS externe Aufrufe zulassen */
16
17
18
19
20
21
22
23
24
25 function isValidSignature(
26 bytes32 _hash,
27 bytes memory _signature)
28 public
29 view
30 returns (bytes4 magicValue);
31}
Alle anzeigen

Beispiel für eine EIP-1271-Implementierung: Safe

Verträge können isValidSignature auf viele Arten implementieren – die Spezifikation sagt nur nicht viel über die genaue Implementierung aus.

Ein bemerkenswerter Vertrag, der EIP-1271 implementiert, ist Safe (ehemals Gnosis Safe).

Im Code von Safe ist isValidSignature so implementiert (opens in a new tab), dass Signaturen auf zwei Arten (opens in a new tab) erstellt und verifiziert werden können:

  1. Nachrichten auf der Blockchain
    1. Erstellung: Ein Safe-Eigentümer erstellt eine neue Safe-Transaktion, um eine Nachricht zu „signieren“, wobei die Nachricht als Daten in die Transaktion übergeben wird. Sobald genügend Eigentümer die Transaktion signieren, um den Mehrfachsignatur-Schwellenwert zu erreichen, wird die Transaktion übertragen und ausgeführt. In der Transaktion gibt es eine Safe-Funktion namens (signMessage(bytes calldata _data)), die die Nachricht zu einer Liste „genehmigter“ Nachrichten hinzufügt.
    2. Verifizierung: Rufen Sie isValidSignature im Safe-Vertrag auf und übergeben Sie die zu verifizierende Nachricht als Nachrichtenparameter und einen leeren Wert für den Signaturparameter (opens in a new tab) (d. h. 0x). Der Safe wird erkennen, dass der Signaturparameter leer ist, und anstatt die Signatur kryptografisch zu verifizieren, wird er wissen, dass er einfach prüfen muss, ob die Nachricht auf der Liste der „genehmigten“ Nachrichten steht.
  2. Off-Chain-Nachrichten:
    1. Erstellung: Ein Safe-Eigentümer erstellt eine Nachricht Off-Chain und lässt dann andere Safe-Eigentümer die Nachricht jeweils einzeln signieren, bis genügend Signaturen vorhanden sind, um den Mehrfachsignatur-Genehmigungsschwellenwert zu überschreiten.
    2. Verifizierung: Rufen Sie isValidSignature auf. Übergeben Sie im Nachrichtenparameter die zu verifizierende Nachricht. Übergeben Sie im Signaturparameter die einzelnen Signaturen jedes Safe-Eigentümers, alle aneinandergereiht. Der Safe prüft, ob genügend Signaturen vorhanden sind, um den Schwellenwert zu erreichen, und ob jede Signatur gültig ist. Wenn dies der Fall ist, wird ein Wert zurückgegeben, der eine erfolgreiche Signaturverifizierung anzeigt.

Was genau ist der Parameter _hash? Warum nicht die ganze Nachricht übergeben?

Sie haben vielleicht bemerkt, dass die Funktion isValidSignature in der EIP-1271-Schnittstelle (opens in a new tab) nicht die Nachricht selbst, sondern einen Parameter _hash entgegennimmt. Das bedeutet, dass wir anstelle der vollständigen Nachricht beliebiger Länge einen 32-Byte-Hash der Nachricht (im Allgemeinen keccak256) an isValidSignature übergeben.

Jedes Byte an Calldata – d. h. Funktionsparameterdaten, die an eine Smart-Contract-Funktion übergeben werden – kostet 16 Gas (4 Gas bei einem Null-Byte) (opens in a new tab), sodass dies bei einer langen Nachricht viel Gas sparen kann.

Frühere EIP-1271-Spezifikationen

Es gibt EIP-1271-Spezifikationen in freier Wildbahn, die eine Funktion isValidSignature mit einem ersten Parameter vom Typ bytes (beliebige Länge anstelle einer festen Länge bytes32) und dem Parameternamen message haben. Dies ist eine ältere Version (opens in a new tab) des EIP-1271-Standards.

Wie sollte EIP-1271 in meinen eigenen Verträgen implementiert werden?

Die Spezifikation ist hier sehr offen. Die Safe-Implementierung hat einige gute Ideen:

  • Sie können EOA-Signaturen vom „Eigentümer“ des Vertrags als gültig betrachten.
  • Sie könnten eine Liste genehmigter Nachrichten speichern und nur diese als gültig betrachten.

Letztendlich liegt es an Ihnen als Vertragsentwickler!

Fazit

EIP-1271 (opens in a new tab) ist ein vielseitiger Standard, der es Smart Contracts ermöglicht, Signaturen zu verifizieren. Er öffnet die Tür dafür, dass sich Smart Contracts mehr wie EOAs verhalten – zum Beispiel, indem er eine Möglichkeit bietet, dass „Mit Ethereum anmelden“ mit Smart Contracts funktioniert – und er kann auf viele Arten implementiert werden (wobei Safe eine nicht triviale, interessante Implementierung aufweist, die man in Betracht ziehen sollte).

Letzte Aktualisierung der Seite: 3. März 2026

War dieses Tutorial hilfreich?