EIP-1271: स्मार्ट अनुबंध हस्ताक्षरों पर हस्ताक्षर करना और सत्यापित करना
EIP-1271 (opens in a new tab) मानक स्मार्ट अनुबंधों को हस्ताक्षरों को सत्यापित करने की अनुमति देता है।
इस ट्यूटोरियल में, हम डिजिटल हस्ताक्षरों, EIP-1271 की पृष्ठभूमि, और Safe (opens in a new tab) (पहले Gnosis Safe) द्वारा उपयोग किए जाने वाले EIP-1271 के विशिष्ट कार्यान्वयन का अवलोकन देते हैं। कुल मिलाकर, यह आपके स्वयं के अनुबंधों में EIP-1271 को लागू करने के लिए एक शुरुआती बिंदु के रूप में काम कर सकता है।
हस्ताक्षर क्या है?
इस संदर्भ में, एक हस्ताक्षर (अधिक सटीक रूप से, एक "डिजिटल हस्ताक्षर") एक संदेश और किसी प्रकार का प्रमाण है कि संदेश किसी विशिष्ट व्यक्ति/प्रेषक/पते से आया है।
उदाहरण के लिए, एक डिजिटल हस्ताक्षर कुछ इस तरह दिख सकता है:
- संदेश: "मैं अपने इथेरियम वॉलेट से इस वेबसाइट में लॉग इन करना चाहता हूँ।"
- हस्ताक्षरकर्ता: मेरा पता
0x000…है - प्रमाण: यहाँ कुछ प्रमाण है कि मैंने,
0x000…, वास्तव में यह पूरा संदेश बनाया है (यह आमतौर पर कुछ क्रिप्टोग्राफिक होता है)।
यह ध्यान रखना महत्वपूर्ण है कि एक डिजिटल हस्ताक्षर में "संदेश" और "हस्ताक्षर" दोनों शामिल होते हैं।
ऐसा क्यों? उदाहरण के लिए, यदि आपने मुझे हस्ताक्षर करने के लिए एक अनुबंध दिया, और फिर मैंने हस्ताक्षर वाला पृष्ठ काट दिया और आपको शेष अनुबंध के बिना केवल अपने हस्ताक्षर वापस दे दिए, तो अनुबंध मान्य नहीं होगा।
उसी तरह, एक संबद्ध संदेश के बिना डिजिटल हस्ताक्षर का कोई मतलब नहीं है!
EIP-1271 क्यों मौजूद है?
इथेरियम-आधारित ब्लॉकचेन पर उपयोग के लिए एक डिजिटल हस्ताक्षर बनाने के लिए, आपको आमतौर पर एक गुप्त निजी कुंजी की आवश्यकता होती है जिसे कोई और नहीं जानता है। यही आपके हस्ताक्षर को आपका बनाता है (गुप्त कुंजी के ज्ञान के बिना कोई और समान हस्ताक्षर नहीं बना सकता है)।
आपके इथेरियम खाते (यानी, आपका बाह्य रूप से स्वामित्व वाला खाता/EOA) के साथ एक निजी कुंजी जुड़ी होती है, और यह वह निजी कुंजी है जिसका उपयोग आमतौर पर तब किया जाता है जब कोई वेबसाइट या विकेंद्रीकृत एप्लिकेशन (dapp) आपसे हस्ताक्षर मांगता है (उदा., "इथेरियम के साथ लॉग इन करें" के लिए)।
एक ऐप हस्ताक्षर को सत्यापित कर सकता है (opens in a new tab) जिसे आप Ethers.js जैसी थर्ड-पार्टी लाइब्रेरी का उपयोग करके अपनी निजी कुंजी जाने बिना (opens in a new tab) बनाते हैं और आश्वस्त हो सकता है कि आप ही वह व्यक्ति थे जिसने हस्ताक्षर बनाया था।
वास्तव में, क्योंकि EOA डिजिटल हस्ताक्षर सार्वजनिक-कुंजी क्रिप्टोग्राफी का उपयोग करते हैं, उन्हें ऑफचेन उत्पन्न और सत्यापित किया जा सकता है! इस तरह गैस-रहित DAO वोटिंग काम करती है — ऑनचेन वोट सबमिट करने के बजाय, क्रिप्टोग्राफिक लाइब्रेरी का उपयोग करके डिजिटल हस्ताक्षर बनाए और ऑफचेन सत्यापित किए जा सकते हैं।
जबकि EOA खातों में एक निजी कुंजी होती है, स्मार्ट अनुबंध खातों में किसी भी प्रकार की निजी या गुप्त कुंजी नहीं होती है (इसलिए "इथेरियम के साथ लॉग इन करें", आदि मूल रूप से स्मार्ट अनुबंध खातों के साथ काम नहीं कर सकते हैं)।
वह समस्या जिसे EIP-1271 हल करना चाहता है: हम कैसे बता सकते हैं कि एक स्मार्ट अनुबंध हस्ताक्षर मान्य है यदि स्मार्ट अनुबंध में कोई "रहस्य" नहीं है जिसे वह हस्ताक्षर में शामिल कर सके?
EIP-1271 कैसे काम करता है?
स्मार्ट अनुबंधों में निजी कुंजियाँ नहीं होती हैं जिनका उपयोग संदेशों पर हस्ताक्षर करने के लिए किया जा सके। तो हम कैसे बता सकते हैं कि कोई हस्ताक्षर प्रामाणिक है या नहीं?
खैर, एक विचार यह है कि हम बस स्मार्ट अनुबंध से पूछ सकते हैं कि क्या कोई हस्ताक्षर प्रामाणिक है!
EIP-1271 जो करता है वह यह है कि यह एक स्मार्ट अनुबंध से "पूछने" के इस विचार को मानकीकृत करता है कि क्या दिया गया हस्ताक्षर मान्य है।
EIP-1271 को लागू करने वाले अनुबंध में isValidSignature नामक एक फ़ंक्शन होना चाहिए जो एक संदेश और एक हस्ताक्षर लेता है। अनुबंध तब कुछ सत्यापन लॉजिक चला सकता है (विनिर्देश यहाँ कुछ भी विशिष्ट लागू नहीं करता है) और फिर एक मान लौटा सकता है जो यह दर्शाता है कि हस्ताक्षर मान्य है या नहीं।
यदि isValidSignature एक मान्य परिणाम लौटाता है, तो यह काफी हद तक अनुबंध का यह कहना है कि "हाँ, मैं इस हस्ताक्षर + संदेश को स्वीकृति देता हूँ!"
इंटरफ़ेस
यहाँ EIP-1271 विनिर्देश में सटीक इंटरफ़ेस है (हम नीचे _hash पैरामीटर के बारे में बात करेंगे, लेकिन अभी के लिए, इसे उस संदेश के रूप में सोचें जिसे सत्यापित किया जा रहा है):
pragma solidity ^0.5.0;
contract ERC1271 {
// bytes4(keccak256("isValidSignature(bytes32,bytes)")
bytes4 constant internal MAGICVALUE = 0x1626ba7e;
/**
* @dev यह वापस करना चाहिए कि क्या प्रदान किया गया हस्ताक्षर प्रदान किए गए हैश के लिए मान्य है
* @param _hash हस्ताक्षर किए जाने वाले डेटा का हैश
* @param _signature _hash से जुड़ा हस्ताक्षर बाइट ऐरे
*
* फ़ंक्शन के पास होने पर bytes4 मैजिक वैल्यू 0x1626ba7e वापस करना चाहिए।
* स्टेट को संशोधित नहीं करना चाहिए (solc < 0.5 के लिए STATICCALL का उपयोग करके, solc > 0.5 के लिए view मॉडिफायर)
* बाहरी कॉल की अनुमति देनी चाहिए
*/
function isValidSignature(
bytes32 _hash,
bytes memory _signature)
public
view
returns (bytes4 magicValue);
}
उदाहरण EIP-1271 कार्यान्वयन: Safe
अनुबंध isValidSignature को कई तरीकों से लागू कर सकते हैं — विनिर्देश सटीक कार्यान्वयन के बारे में बहुत कुछ नहीं कहता है।
एक उल्लेखनीय अनुबंध जो EIP-1271 को लागू करता है वह Safe (पहले Gnosis Safe) है।
Safe के कोड में, isValidSignature को लागू किया गया है (opens in a new tab) ताकि हस्ताक्षरों को दो तरीकों (opens in a new tab) से बनाया और सत्यापित किया जा सके:
- ऑनचेन संदेश
- निर्माण: एक Safe मालिक संदेश पर "हस्ताक्षर" करने के लिए एक नया Safe लेन-देन बनाता है, संदेश को लेन-देन में डेटा के रूप में पास करता है। एक बार जब पर्याप्त मालिक मल्टीसिग सीमा तक पहुँचने के लिए लेन-देन पर हस्ताक्षर कर देते हैं, तो लेन-देन प्रसारित और चलाया जाता है। लेन-देन में, (
signMessage(bytes calldata _data)) नामक एक Safe फ़ंक्शन होता है जो संदेश को "स्वीकृत" संदेशों की सूची में जोड़ता है। - सत्यापन: Safe अनुबंध पर
isValidSignatureकॉल करें, और संदेश पैरामीटर के रूप में सत्यापित करने के लिए संदेश पास करें और हस्ताक्षर पैरामीटर के लिए एक खाली मान (opens in a new tab) (यानी,0x) पास करें। Safe देखेगा कि हस्ताक्षर पैरामीटर खाली है और हस्ताक्षर को क्रिप्टोग्राफ़िक रूप से सत्यापित करने के बजाय, यह जान जाएगा कि बस आगे बढ़ें और जांचें कि क्या संदेश "स्वीकृत" संदेशों की सूची में है।
- निर्माण: एक Safe मालिक संदेश पर "हस्ताक्षर" करने के लिए एक नया Safe लेन-देन बनाता है, संदेश को लेन-देन में डेटा के रूप में पास करता है। एक बार जब पर्याप्त मालिक मल्टीसिग सीमा तक पहुँचने के लिए लेन-देन पर हस्ताक्षर कर देते हैं, तो लेन-देन प्रसारित और चलाया जाता है। लेन-देन में, (
- ऑफचेन संदेश:
- निर्माण: एक Safe मालिक ऑफचेन एक संदेश बनाता है, फिर अन्य Safe मालिकों से संदेश पर व्यक्तिगत रूप से हस्ताक्षर करवाता है जब तक कि मल्टीसिग स्वीकृति सीमा को पार करने के लिए पर्याप्त हस्ताक्षर न हो जाएं।
- सत्यापन:
isValidSignatureकॉल करें। संदेश पैरामीटर में, सत्यापित किए जाने वाले संदेश को पास करें। हस्ताक्षर पैरामीटर में, प्रत्येक Safe मालिक के व्यक्तिगत हस्ताक्षरों को एक साथ जोड़कर, बैक-टू-बैक पास करें। Safe जांच करेगा कि सीमा को पूरा करने के लिए पर्याप्त हस्ताक्षर हैं और कि प्रत्येक हस्ताक्षर मान्य है। यदि ऐसा है, तो यह सफल हस्ताक्षर सत्यापन का संकेत देने वाला मान लौटाएगा।
_hash पैरामीटर वास्तव में क्या है? पूरा संदेश क्यों नहीं पास करते?
आपने देखा होगा कि EIP-1271 इंटरफ़ेस (opens in a new tab) में isValidSignature फ़ंक्शन संदेश को स्वयं नहीं लेता है, बल्कि इसके बजाय एक _hash पैरामीटर लेता है। इसका मतलब यह है कि isValidSignature को पूर्ण मनमानी-लंबाई वाला संदेश पास करने के बजाय, हम इसके बजाय संदेश का 32-बाइट हैश (आमतौर पर keccak256) पास करते हैं।
कॉल डेटा के प्रत्येक बाइट — यानी, स्मार्ट अनुबंध फ़ंक्शन को पास किया गया फ़ंक्शन पैरामीटर डेटा — की लागत 16 गैस (यदि शून्य बाइट है तो 4 गैस) होती है (opens in a new tab), इसलिए यदि कोई संदेश लंबा है तो यह बहुत सारी गैस बचा सकता है।
पिछले EIP-1271 विनिर्देश
व्यवहार में ऐसे EIP-1271 विनिर्देश हैं जिनमें isValidSignature फ़ंक्शन होता है जिसका पहला पैरामीटर bytes प्रकार का होता है (निश्चित-लंबाई bytes32 के बजाय मनमानी-लंबाई) और पैरामीटर का नाम message होता है। यह EIP-1271 मानक का एक पुराना संस्करण (opens in a new tab) है।
मेरे स्वयं के अनुबंधों में EIP-1271 को कैसे लागू किया जाना चाहिए?
विनिर्देश यहाँ बहुत खुला (ओपन-एंडेड) है। Safe कार्यान्वयन में कुछ अच्छे विचार हैं:
- आप अनुबंध के "मालिक" के EOA हस्ताक्षरों को मान्य मान सकते हैं।
- आप स्वीकृत संदेशों की एक सूची संग्रहीत कर सकते हैं और केवल उन्हीं को मान्य मान सकते हैं।
अंत में, यह अनुबंध डेवलपर के रूप में आप पर निर्भर है!
निष्कर्ष
EIP-1271 (opens in a new tab) एक बहुमुखी मानक है जो स्मार्ट अनुबंधों को हस्ताक्षरों को सत्यापित करने की अनुमति देता है। यह स्मार्ट अनुबंधों के लिए EOA की तरह अधिक कार्य करने के द्वार खोलता है — उदाहरण के लिए स्मार्ट अनुबंधों के साथ काम करने के लिए "इथेरियम के साथ लॉग इन करें" का एक तरीका प्रदान करना — और इसे कई तरीकों से लागू किया जा सकता है (Safe में विचार करने के लिए एक गैर-तुच्छ, दिलचस्प कार्यान्वयन है)।