در پروژههای بلاکچین یکی از قسمتهایی که ممکن است زیاد با آن برخورد بکنید کیف پول است. حتما تا به امروز هم با چند تا از کیف پولها کار کردین.
در این سری، آموزش کار با کیف پول نداریم. بلکه میخوایم ببینیم اگر در یک پروژه بنا باشه قسمت کیف پول داشته باشیم از نظر برنامهنویسی چه چیزهایی رو باید در نظر بگیریم، مفاهیم مرتبط با کیف پول مثل آدرس یا ساخت تراکنش یا چیزهایی از این دست دقیقا یعنی چی (با نمونه کد)، ابتداییترین نکات امنیتی که باید رعایت کنیم چه مواردی هستن و در آخر شاید چندتا کیف پول با هم درست کنیم.
تعریف کیف پول
منظور من از کیف پول یک برنامه نرمافزاری هست که به شما امکان میده برای یک رمز ارز آدرس مخصوص داشته باشید و بتونید تراکنش ارسال و دریافت در اون شبکه انجام بدین. اگر بخوایم یکم فنیتر و دقیقتر توضیح بدم در واقع کیف پول دو تا کار اساسی میکنه. اول کلیدهای عمومی و خصوصی شما رو به صورت امن نگهداری میکنه و دوم زمانی که شما میخواین یه تراکنش انجام بدین عملیات امضا یا sign کردن رو انجام میده.
به عنوان اولین مثال فرض کنید میخوایم یه کیف پول برای بیتکوین با هم درست کنیم.
فعلا قسمتهای authentication و authorization رو کنار میزاریم (چون یه چیز استاندارد و تکراری هست که احتمالا قبلا ۱۰۰ بار انجامش دادین - ما هم آخر پروژه به این موضوع برمیگردیم).
اولین کاری که انتظار داریم کیف پولمون انجام بده این هست که یه آدرس معتبر توی شبکه بیتکوین به ما بده که ما بتونیم به اون آدرس بیت واریز بکنیم. تا آخر این پست همین موضوع رو دقیقتر میخوایم بررسی بکنیم.
آدرس در شبکه بیتکوین
یک آدرس در شبکه بیتکوین مجموعهای است از اعداد و کاراکترها. الگوریتم ایجاد آدرس به ترتیب زیر است :
- ایجاد یک جفت کلید (خصوصی\عمومی) با استفاده از الگوریتم ECDSA.
- کلید عمومی بدست آمده از مرحله قبل توسط الگوریتم SHA یک مرتبه hash میشود.
- خروجی مرحله دو توسط روش RIPEMD160 یک مرتبه hash میشود.
- خروجی مرحله سوم به وسیله Base58Check انکود (encode) میشود و نوع آدرس ساخته شده در ابتدای آدرس قرار داده میشود.
توضیح مراحل الگوریتم و چند نکته :
- الگوریتم رمزنگاری نامتقارن یا کلید عمومی - کلید خصوصی یکی از اصلیترین پایههای شکلگیری بلاکچین (در همه شبکهها) است. این الگوریتم کاربردهای مختلفی دارد که یکی از آنها در شبکههای بلاکچین به منظور ایجاد و صحتسنجی امضای دیجیتال است. مثلا برای ایجاد آدرس در شبکه بیتکوین یک جفت کلید ساخته میشود. سپس کلید عمومی با دو مرحله hash کردن و یک مرحله encoding تبدیل به آدرس میشود. زمانی که به این آدرس، بیتکوینی ارسال شود دادههایی نیز در آن تراکنش گنجانده خواهد شد تا در آینده فقط مالک کلید خصوصی متناظر با آن کلید عمومی اولیه (که از روی آن آدرس ایجاد شده بود) میتواند بیتکوین ارسال شده به این آدرس را برای فرد دیگری ارسال کند.
- همانطوری که در مراحل الگوریتم هم مشاهده کردید کلید عمومی و آدرس با هم تفاوت دارند. آدرس از کلید عمومی ساخته میشود اما با آن متفاوت است.
- کلیه مراحل ایجاد آدرس بدون نیاز به شبکه بیتکوین یا نود فعال از این شبکه و به صورت کاملا آفلاین قابل انجام است.
- مهمترین نکته امنیتی در الگوریتم فوق (که در دسترس برنامهنویس است) در مرحله اول است. در مرحله اول که جفت کلید ساخته میشود فراهم کردن یک ورودی تصادفی برای فرآیند ایجاد کلیدها حیاتی است. در حال حاضر امنیت الگوریتم فوق به حدی است که طی کردن مسیر برعکس این الگوریتم غیر ممکن است. اما اگر ورودی تصادفی مناسبی برای ایجاد جفت کلیدها استفاده نشود آنگاه احتمال طی کردن دوباره این الگوریتم امکانپذیر است. در نتیجه استفاده از توابع سادهای ماننده
Math.random()
در جاوااسکریپ اصلا قابل قبول نیست. - با توجه به آپدیتهایی که بیتکوین داشته است در حال حاضر سه نوع آدرس در این شبکه در حال استفاده است. نوع اول آدرسهای P2PKH (Pay-to-PubkeyHash ) است که با کاراکتر ۱ شروع میشوند و متدوالترین نوع آدرس در این شبکه است. نوع دوم آدرسهای P2SH (Pay to script hash) که با کاراکتر ۳ شروع میشوند و نوع سوم آدرسهای Bech32 (SegWit) که با کاراکترهای bc1 شروع میشوند. الگوریتمی که توضیح داده شد برای ایجاد آدرسهای نوع اول است که در اولین ورژن بیتکوین آمده است. نحوه ساخت و همچنین کاربرد دو نوع دیگر نیازمند نوشته مفصلتری است که شاید در آینده تهیه شود. ولی ذکر این نکته مهم است که بدانید در حال حاضر یک کیف پول معتبر بایستی از همه انواع آدرسها پشتیبانی کند.
نتیجهگیری
امیدوارم تا اینجا خسته نشده باشید و یه سری ابهاماتی که من در اولین پروژم داشتم (مثلا چطور میشه یه آدرس درست کرد یا آیا حتما برای درست کردن آدرس باید به شبکه بیتکوین متصل بود یا …) برای شما رفع شده باشه. ولی شاید یه سری سوالات دیگه براتون پیش اومده باشه. مثلا اینکه جفت کلیدی که باید طبق الگوریتم ECDSA باشن چطوری باید درستشون کنیم؟ یا نحوه نگهداری کلیدها باید به چه صورت باشه؟ یا الگوریتمهایی مثل SHA یا RIPEMD160 یا Base58Check دقیقا کارشون چیه و چطوری کار میکنن؟ یا سوالات دیگه. برای اینکه این نوشته خیلی طولانی نشه ترجیح دادم از توضیحات اضافی خودداری کنم اما اگر براتون خیلی سوال بود میتونید بپرسید تا جواب بدم.
در قسمت بعدی سعی میکنم همین مراحل الگوریتم رو تحت جاوااسکریپت implement بکنیم و نتیجه رو با هم بررسی کنیم.