
یکی از ویژگی های اصلی اتریوم و سایر ارزهای دیجیتال، قابلیت امضا اطلاعات است که توسط تمام کاربران قابل ثبت است. این موضوع باعث تقویت ماهیت توزیع شده بلاک چین میشود. در بیت کوین، تراکنشی را امضا میکنید که بیانگر ارسال ۴ بیت کوین به سالی میباشد. بدون این ویژگی، هرکسی میتواند تراکنش های جعلی ایجاد کند و تمام کوین ها را به خود ارسال کند.
امضا چیست؟
امضا، اقدام کاربر A در خصوص امضای اطلاعات است تا تمام کاربران بتوانند تایید کنند این امضا از جانب کاربر A میباشد. این موضوع در تراکنش ها استفاده میشود تا واقعی بودن آن بررسی شود.
سوالی رایجی که مطرح میشود این است که چگونه میتوان تایید کرد که تراکنشها واقعی هستند؟ پاسخ کوتاه به این پرسش، رمزنگاری کلید عمومی است. این رمزنگاری، الگوریتمی است که دارای ۳ بخش است.
- ایجاد کلید
- رمزنگاری / امضا
- رمزگشایی / تایید
رمزنگاری به طور کل برای پنهان کردن اطلاعات در سایر اطلاعات استفاده میشود. اگر عبارتی نظیر سلام بر دنیا (hello world) را رمزنگاری کنید به صورت dqE3gJz/+5CQHfSJwMP2nQ تبدیل می شود. هدف رمزنگاری پنهان کردن پیام سلام بر دنیا است. امضا کردن برای ایجاد خروجی متفاوت استفاده میشود اما پیام اصلی را نیز عمومی میکنید.
خروجی ایجاد کلید، دو رشته خواهد بود؛ کلید عمومی و کلید خصوصی. این دو کلید از طریق الگوریتمی که ویژگیهای تایید و امضا دارد به یکدیگر متصل میشوند. امضا در کلید عمومی، کلید خصوصی و پیام وارد خواهد شد. خروجی، رشته دیگری خواهد بود که همان امضا است.
- امضا = F (کلید عمومی، کلید خصوصی، پیام)
- تایید = F (امضا، پیام)
- معتبر است اگر: تایید = کلید عمومی
توجه کنید که تایید به دانستن کلید خصوصی نیازی ندارد. این همان موضوعی است که به اشخاص ثالث امکان میدهد تا اطلاعات را تایید کنند. اگر خروجی تابع تایید برابر با کلید عمومی باشد، امضا واقعی است در غیر این صورت امضا جعلی است.
امضا از ۳ متغیر تشکیل شده است: v و r و s. اتریوم از رمزنگاری منحنی بیضوی استفاده میکند و این متغیرها بخشی از محاسبات مورد نظر است.
چرا امضا کردن مهم است؟
امضا کردن روشی بسیار خوب برای دانستن این موضوع است که آیا اقدامات توسط شخص یا قرارداد درستی انجام شده است یا خیر. یعنی میتوانیم به افرادی اعتماد کنیم که حرفی که میزنند را انجام میدهند.
به جای امضاهای واقعی که میتوان آنها را جعل کرد، امضاهای دیجیتال غیرقابل جعل است. اگر میخواهید بدانید کاربر A اقدامی انجام میدهد یا خیر، قبل از انجام هرکاری او را مجبور به امضا کنید. سپس اگر تناقضی به وجود آمد، امضا را بررسی کنید.
توسعه
شما به عنوان یک توسعه دهنده از کاربران خود میخواهید تا پیامی را امضا کنند. ایجاد این ویژگی در برنامه غیرمتمرکز مورد نظر ۳ بخش دارد که عبارتند از:
- تابع تایید کننده سالیدیتی
- کد کلاینت برای امضای پیام
- کد کلاینت برای فراخوانی تایید کننده سالیدیتی
تایید کننده سالیدیتی
سالیدیتی یا همان زبان برنامه نویسی اتریوم روش دسترسی جهانی به اسم ecrecover ارائه میدهد که آدرس را برمیگرداند. اگر آدرس برگشتی مشابه با آدرس امضا کننده باشد، امضا واقعی است.
کد فوق، قرارداد Verifier با توابع recoverAddr و isSigned ایجاد میکند. تابع isSigned آدرس را برخواهد گرداند. شما به عنوان توسعه دهنده، خارج از سالیدیتی باید صحت آدرس را تایید کنید. روش دوم اینگونه است که تابع isSigned داخل سالیدیتی بررسی میکند. اگر msgHash توسط addr_ امضا شده باشد، مقدار isSigned برابر با صحیح یا غلط (true or false) خواهد بود.
ایجاد امضا
دو روش برای ایجاد امضا وجود دارد:
- استفاده از تابع جاوااسکریپت Web3 (تابع web3.eth.sign)
- فراخوانی RPC API نود اتریوم
اگر از جاوااسکریپت استفاده میکنید، تنها کاری که باید انجام دهید این است که Web3 داشته باشید و به نود اتریوم ضمیمه کنید. در کد زیر، نود خصوصی اتریوم با localhost:8545 را اجرا میکنیم.
نکته: این مورد بر روی TESTRPC کار نخواهد کرد.
ساختاری در تابع وجود ندارد که رشته را به کد Hex تبدیل کند. بنابراین برای تبدیل از تابع toHex استفاده کردیم. آدرس کاربر (web3.eth.accounts[0]) و پیام دارای پیشوند 0x به تابع web3.eth.sign وارد شدند.
روش دیگر برای ایجاد امضا، فراخوانی RPC API اتریوم است. با استفاده از curl میتوانید به نود اتریوم درخواست دهید.
اولین پارامتر در params آدرس کاربر و دومین پارامتر، مقدار hex پیام است. توجه داشته باشید که برای کار کردن RPC API، حساب شما باید باز باشد. عبارتی مشابه با عبارت زیر را دریافت خواهید کرد:
0x9955af11969a2d2a7f860cb00e6a00cfa7c581f5df2dbe8ea16700b33f4b4b9b69f945012f7ea7d3febf11eb1b78e1adc2d1c14c2cf48b25000938cc1860c83e01
امضای طولانی، متغیرهای v، r و s را رمزنگاری میکند. برای به دست آوردن این مقادیر، باید امضا را به زیر رشته های خود تجزیه کنید.
نکته: v باید یک عدد دسیمال باشد بنابراین v_decimal دوم hex v را به decimal v تبدیل میکند.
خطر: نتیجه v_decimal باید ۲۷ یا ۲۸ باشد.
بررسی صحیح بودن
با اتمام کار امضا و تایید کننده، تنها کاری که باقی میماند بررسی واقعی بودن امضا است. یک هشدار کوچک در این خصوص وجود دارد. به یاد میآورید هنگام ایجاد امضا از رشته 0x + toHex(msg) استفاده کردیم؟ این همان هشی نیست که به تایید کننده انتقال میدهید.
هش مورد نیاز برای ایجاد امضا همان هش تایید کننده نیست. دلیل این موضوع، محافظت از کاربر در مقابل امضا کردن ظرفیت های دلخواه است.
راهکار این موضوع، افزودن پیام های شخصی سازی شده اتریوم است.
این تفکیک بسیار ضروری است. وقت خود را با انجام مراحل بعد تلف نکنید.
آخرین مرحله، فراخوانی کد سالیدیتی است. ما از ترافل ۳ برای اجرای قرارداد هوشمند قبلی استفاده میکنیم. لطفا توجه داشته باشید که محل نود اتریوم برای قرارداد باید اعلام شود. در غیر این صورت طبق انتظار کار نخواهد کرد.
ترافل یک تابع اجرا شده ایجاد میکند که قرارداد را برمیگرداند. ما پیام sha3 خود را ایجاد میکنیم و متغیرهای مورد نیاز را به instance.verify.call انتقال میدهیم. اگر دو خط آخر آدرس های برگشتی مشابه باشد، امضای پیام واقعی است. در غیر این صورت جعلی است و باید نادیده گرفته شود.
نتیجه گیری
امضای اطلاعات برای هر نوع برنامه غیرمتمرکز، مهم است. بعضی از برنامهها دارای مدیریت حقوق، کپی رایت و مالکیت اختراع و پتنت میباشند. کاربران میتوانند این فایلها را امضا کنند و سایرین نیز صحت امضا را تایید کنند. دیگر چه کاربردهایی به ذهن شما میرسد؟
آخرین به روز رسانی: ۱۳۹۹/۳/۱۷