تخطٍ إلى المحتوى الرئيسي

EIP-1271: توقيع توقيعات العقد الذكي والتحقق منها

eip-1271
العقود الذكيه
التحقق
signing
المستوى المتوسط
ناثان إتش. ليونغ
12 يناير 2023
6 دقيقة قراءة

يسمح معيار EIP-1271 (opens in a new tab) للعقود الذكية بالتحقق من التوقيعات.

في هذا البرنامج التعليمي، نقدم نظرة عامة على التوقيعات الرقمية، وخلفية EIP-1271، والتنفيذ المحدد لـ EIP-1271 الذي يستخدمه Safe (opens in a new tab) (المعروف سابقًا باسم غنوسيس Safe). كل ذلك معًا، يمكن أن يكون بمثابة نقطة انطلاق لتنفيذ EIP-1271 في عقودك الخاصة.

ما هو التوقيع؟

في هذا السياق، التوقيع (بتعبير أدق، "التوقيع الرقمي") هو رسالة بالإضافة إلى نوع من الإثبات على أن الرسالة جاءت من شخص/مرسل/عنوان محدد.

على سبيل المثال، قد يبدو التوقيع الرقمي كما يلي:

  1. الرسالة: "أريد تسجيل الدخول إلى هذا الموقع باستخدام محفظة إيثريوم الخاصة بي".
  2. الموقّع: عنواني هو 0x000…
  3. الإثبات: هذا إثبات بأنني، 0x000…، أنشأت بالفعل هذه الرسالة بأكملها (عادة ما يكون هذا شيئًا مشفرًا).

من المهم ملاحظة أن التوقيع الرقمي يتضمن كلاً من "الرسالة" و"التوقيع".

لماذا؟ على سبيل المثال، إذا أعطيتني عقدًا للتوقيع، ثم قمت بقطع صفحة التوقيع وأعدت لك توقيعاتي فقط بدون بقية العقد، فلن يكون العقد صالحًا.

بنفس الطريقة، التوقيع الرقمي لا يعني أي شيء بدون رسالة مرتبطة به!

لماذا يوجد EIP-1271؟

لإنشاء توقيع رقمي للاستخدام على سلاسل الكتل القائمة على إيثريوم، تحتاج بشكل عام إلى مفتاح خاص سري لا يعرفه أي شخص آخر. هذا ما يجعل توقيعك خاصًا بك (لا يمكن لأي شخص آخر إنشاء نفس التوقيع دون معرفة المفتاح السري).

حساب إيثريوم الخاص بك (أي حسابك المملوك خارجيًا/EOA) لديه مفتاح خاص مرتبط به، وهذا هو المفتاح الخاص الذي يستخدم عادةً عندما يطلب منك موقع ويب أو تطبيق لامركزي توقيعًا (على سبيل المثال، لـ "تسجيل الدخول باستخدام إيثريوم").

يمكن للتطبيق التحقق من التوقيع (opens in a new tab) الذي تنشئه باستخدام مكتبة تابعة لجهة خارجية مثل ethers.js دون معرفة مفتاحك الخاص (opens in a new tab) وأن يكون واثقًا من أن أنت من أنشأ التوقيع.

في الواقع، نظرًا لأن التوقيعات الرقمية لـ EOA تستخدم تشفير المفتاح العام، فيمكن إنشاؤها والتحقق منها خارج السلسلة! هذه هي الطريقة التي يعمل بها تصويت المنظمات المستقلة اللامركزية (داو) بدون رسوم غاز — فبدلاً من إرسال الأصوات على السلسلة، يمكن إنشاء التوقيعات الرقمية والتحقق منها خارج السلسلة باستخدام المكتبات المشفرة.

في حين أن حسابات EOA لديها مفتاح خاص، فإن حسابات العقود الذكية لا تملك أي نوع من المفاتيح الخاصة أو السرية (لذا فإن "تسجيل الدخول باستخدام إيثريوم" وما إلى ذلك لا يمكن أن يعمل بشكل أساسي مع حسابات العقود الذكية).

المشكلة التي يهدف EIP-1271 إلى حلها: كيف يمكننا معرفة ما إذا كان توقيع العقد الذكي صالحًا إذا لم يكن لدى العقد الذكي "سر" يمكنه دمجه في التوقيع؟

كيف يعمل EIP-1271؟

لا تمتلك العقود الذكية مفاتيح خاصة يمكن استخدامها لتوقيع الرسائل. إذًا كيف يمكننا معرفة ما إذا كان التوقيع أصليًا؟

حسنًا، إحدى الأفكار هي أنه يمكننا ببساطة أن نسأل العقد الذكي ما إذا كان التوقيع أصليًا!

ما يفعله EIP-1271 هو أنه يوحد فكرة "سؤال" العقد الذكي عما إذا كان توقيع معين صالحًا.

يجب أن يحتوي العقد الذي ينفذ EIP-1271 على دالة تسمى isValidSignature والتي تأخذ رسالة وتوقيعًا. يمكن للعقد بعد ذلك تشغيل بعض منطق التحقق (لا تفرض المواصفات أي شيء محدد هنا) ثم يعيد قيمة تشير إلى ما إذا كان التوقيع صالحًا أم لا.

إذا أعادت isValidSignature نتيجة صالحة، فهذا يعني إلى حد كبير أن العقد يقول "نعم، أوافق على هذا التوقيع + الرسالة!".

واجهة

إليك الواجهة الدقيقة في مواصفات EIP-1271 (سنتحدث عن المعلمة _hash أدناه، ولكن في الوقت الحالي، فكر فيها على أنها الرسالة التي يتم التحقق منها):

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 يجب أن تعيد ما إذا كان التوقيع المقدم صالحًا للتجزئة (الهاش) المقدمة
10 * @param _hash تجزئة (هاش) البيانات المراد توقيعها
11 * @param _signature مصفوفة بايت التوقيع المرتبطة بـ _hash
12 *
13 * يجب أن تعيد القيمة السحرية bytes4 0x1626ba7e عند نجاح الدالة.
14 * يجب عدم تعديل الحالة (باستخدام STATICCALL لـ solc < 0.5، ومعدّل العرض لـ solc > 0.5)
15 * يجب السماح بالاستدعاءات الخارجية
16 */
17 function isValidSignature(
18 bytes32 _hash,
19 bytes memory _signature)
20 public
21 view
22 returns (bytes4 magicValue);
23}

مثال على تنفيذ EIP-1271: Safe

يمكن للعقود تنفيذ isValidSignature بعدة طرق — لا تذكر المواصفات الكثير عن التنفيذ الدقيق.

أحد العقود البارزة التي تنفذ EIP-1271 هو Safe (المعروف سابقًا باسم غنوسيس Safe).

في النص البرمجي لـ Safe، يتم تنفيذ (opens in a new tab) isValidSignature بحيث يمكن إنشاء التوقيعات والتحقق منها بطريقتين (opens in a new tab):

  1. الرسائل على السلسلة
    1. الإنشاء: ينشئ مالك Safe معاملة Safe جديدة لـ "توقيع" رسالة، ويمرر الرسالة كبيانات في المعاملة. بمجرد أن يوقع عدد كافٍ من المالكين على المعاملة للوصول إلى عتبة التوقيعات المتعددة، يتم بث المعاملة وتشغيلها. في المعاملة، توجد دالة Safe تسمى (signMessage(bytes calldata _data)) تضيف الرسالة إلى قائمة الرسائل "المعتمدة".
    2. التحقق: استدعِ isValidSignature على عقد Safe، ومرر الرسالة للتحقق منها كمعلمة رسالة وقيمة فارغة لمعلمة التوقيع (opens in a new tab) (أي 0x). سيرى Safe أن معلمة التوقيع فارغة وبدلاً من التحقق من التوقيع بشكل مشفر، سيعرف أنه يجب المضي قدمًا والتحقق مما إذا كانت الرسالة موجودة في قائمة الرسائل "المعتمدة".
  2. الرسائل خارج السلسلة:
    1. الإنشاء: ينشئ مالك Safe رسالة خارج السلسلة، ثم يجعل مالكي Safe الآخرين يوقعون على الرسالة كل على حدة حتى يكون هناك عدد كافٍ من التوقيعات لتجاوز عتبة الموافقة متعددة التوقيعات.
    2. التحقق: استدعِ isValidSignature. في معلمة الرسالة، مرر الرسالة التي سيتم التحقق منها. في معلمة التوقيع، مرر التوقيعات الفردية لكل مالك Safe كلها متسلسلة معًا، واحدة تلو الأخرى. سيتحقق Safe من وجود عدد كافٍ من التوقيعات للوصول إلى العتبة وأن كل توقيع صالح. إذا كان الأمر كذلك، فسيعيد قيمة تشير إلى نجاح التحقق من التوقيع.

ما هي معلمة _hash بالضبط؟ لماذا لا نمرر الرسالة بأكملها؟

ربما لاحظت أن دالة isValidSignature في واجهة EIP-1271 (opens in a new tab) لا تأخذ الرسالة نفسها، ولكن بدلاً من ذلك معلمة _hash. هذا يعني أنه بدلاً من تمرير الرسالة الكاملة ذات الطول العشوائي إلى isValidSignature، نقوم بدلاً من ذلك بتمرير تجزئة (هاش) 32 بايت للرسالة (بشكل عام keccak256).

كل بايت من بيانات الاستدعاء — أي بيانات معلمة الدالة التي يتم تمريرها إلى دالة عقد ذكي — يكلف 16 غازًا (4 غازات إذا كان بايت صفريًا) (opens in a new tab)، لذلك يمكن أن يوفر هذا الكثير من الغاز إذا كانت الرسالة طويلة.

مواصفات EIP-1271 السابقة

هناك مواصفات EIP-1271 مستخدمة تحتوي على دالة isValidSignature مع معلمة أولى من النوع bytes (طول عشوائي، بدلاً من bytes32 ثابت الطول) واسم المعلمة message. هذا إصدار أقدم (opens in a new tab) من معيار EIP-1271.

كيف يجب تنفيذ EIP-1271 في عقودي الخاصة؟

المواصفات مفتوحة جدًا هنا. لدى تنفيذ Safe بعض الأفكار الجيدة:

  • يمكنك اعتبار توقيعات EOA من "مالك" العقد صالحة.
  • يمكنك تخزين قائمة بالرسائل المعتمدة واعتبارها فقط صالحة.

في النهاية، الأمر متروك لك كمبرمج للعقد!

الخاتمة

EIP-1271 (opens in a new tab) هو معيار متعدد الاستخدامات يسمح للعقود الذكية بالتحقق من التوقيعات. إنه يفتح الباب أمام العقود الذكية للتصرف بشكل أشبه بحسابات EOA — على سبيل المثال، من خلال توفير طريقة لـ "تسجيل الدخول باستخدام إيثريوم" للعمل مع العقود الذكية — ويمكن تنفيذه بعدة طرق (مع الأخذ في الاعتبار أن لدى Safe تنفيذًا غير بسيط ومثير للاهتمام).

آخر تحديث للصفحة: 3 مارس 2026

هل كانت تعليمات الاستخدام هذه مفيدة؟