اگر محصولت کاربر، نقش، و داده قابلاصلاح دارد، احتمال زیاد هنوز به blockchain نیاز نداری. این جمله مد روز نیست و برای همین کمتر گفته میشود. راهنماهای «وب ۳ برای برنامهنویس وب» معمولاً از معماری آشنا شروع میکنند و خیلی زود به کیف پول، قرارداد، و شبکه میرسند، انگار اضافه کردن زنجیره یک مرحله طبیعی بلوغ است. نیست. برای اپ معمولی، زنجیره اغلب یک منبع حقیقت دوم است که باید با منبع اول آشتی داده شود، با هزینه عملیاتی که روز اول در نمونه کد دیده نمیشود.
معماری آشنا را دست کم نگیر. مرورگر به سرور درخواست میدهد، سرور هویت را با نشست یا توکن چک میکند، و وضعیت را در پایگاه داده مینویسد. شرکت یا تیمی که نرمافزار را اداره میکند میتواند رکورد غلط را اصلاح کند، دسترسی را ببندد، و پشتیبان را برگرداند. این قدرت تمرکز، نقص فلسفی نیست. برای خیلی از محصولها همان قابلیتی است که کاربر انتظار دارد. اگر سفارش اشتباه ثبت شد، کسی باید بتواند جبران کند. زنجیره این جبران را گران و گاهی غیرممکن میکند.
چه مشکلی را واقعاً حل میکند
زنجیره وقتی معنی دارد که چند طرف بخواهند روی یک سابقه مشترک حساب کنند و هیچکدام نپذیرد سرور آن دیگری تنها مرجع باشد. مثال روشن، تسویه بین سازمانهایی است که به هم اعتماد عملیاتی ندارند، یا داراییای که باید بدون اجازه سرور تو از یک نفر به نفر بعد منتقل شود و قواعد انتقال از قبل علنی باشد. در این حالت، مقاومت در برابر تغییر پنهانی سابقه، خود محصول است نه ویژگی جانبی.
اگر چنین طرفهایی نداری، غیرمتمرکز بودن شعار است. کاربر تو به تو اعتماد کرده که سرویس را درست نگه داری. سرمایهگذار یا مدیر هم از تو میخواهد داده غلط را درست کنی. گذاشتن همان داده روی یک دفتر کل عمومی، اعتماد را حذف نمیکند. فقط شکل اعتماد را عوض میکند: حالا باید به قرارداد، به پل، به ارائهدهنده RPC، و به کلیدهایی که جایی نگهداری میشوند هم اعتماد کنی. سطح حمله بیشتر شده، نه کمتر.
شفافیت هم خودکار به دست نمیآید. چیزی که روی زنجیره مینویسی برای همیشه قابل خواندن است، مگر اینکه از اول طوری طراحی کنی که داده حساس اصلاً آنجا نرود. برای اپ معمولی این یعنی یا داده کاربر را جایی میگذاری که نباید، یا فقط یک هش و شناسه میگذاری و حقیقت باز در Postgres تو میماند. در حالت دوم زنجیره آینه است. آینه را باید با اصل همگام نگه داری. هر شکاف همگامسازی یک کلاس باگ تازه است.
هزینه روزمرهای که نمونه کد نشان نمیدهد
کاربر معمولی حساب کاربری میفهمد. عبارت بازیابی، کارمزد شبکه، و تراکنش معلق را نمیفهمد و نباید برای رزرو یک قرار یا ذخیره تنظیمات اپ مجبور به فهمیدنش باشد. کیف پول یک گام ورود است که نرخ رها کردن را بالا میبرد. اگر محصولت بدون این گام هم قابل فهم است، این گام را بهخاطر مدرن به نظر رسیدن اضافه نکن.
نوشتن وضعیت روی زنجیره کندتر و گرانتر از یک INSERT است و شکستش شکل دیگری دارد. تراکنش ممکن است بماند، جایگزین شود، یا در شبکهای که فکر میکردی نهایی شده برنگردد به شکلی که در پایگاه داده معمولی برمیگردد. رابط باید این حالتها را صادقانه نشان دهد. اگر تیمی نداری که این حالتها را پشتیبانی کند، زنجیره را به مسیر حیاتی محصول وصل نکن.
کلید هم مسئله ابزار نیست. مسئله عملیات است. کلید قرارداد، کلید مدیر، و کلید کاربر اگر گم شود با «فراموشی رمز» برنمیگردد. هر میانبری که برای راحتی کاربر کلید را پیش خودت نگه میدارد، تو را دوباره به همان متولی متمرکز تبدیل میکند، با مسئولیت بیشتر. اگر آخرش خودت متولی هستی، از اول پایگاه داده متولی باش و پیچیدگی اضافه را نخر.
قرارداد هوشمند هم کد است، فقط انتشار و اصلاحش سختتر است. باگ در منطقی که پول یا امتیاز را جابهجا میکند با یک deploy عادی جمع نمیشود. اگر هنوز قواعد محصول هر هفته عوض میشود، آن قواعد را در کدی بگذار که میتوانی فردا تغییرش دهی. ثبات زنجیره برای قواعدی خوب است که از قبل توافق شدهاند، نه برای محصولی که هنوز در حال پیدا کردن رفتار درست است.
آزمون قبل از اضافه کردن
قبل از هر ادغام، این سؤالها را کتبی جواب بده. اگر سرور من فردا خاموش شود، کدام بخش از وعده محصول باید بدون من هم درست بماند؟ چه کسی غیر از من باید بتواند سابقه را مستقل وارسی کند، و آیا واقعاً این کار را خواهد کرد؟ اگر یک رکورد غلط نوشته شد، مسیر اصلاح چیست و آیا آن مسیر برای کاربر قابل قبول است؟ داده شخصی کجا مینشیند و چه چیزی عمداً هرگز روی زنجیره نمیرود؟
اگر جواب صادقانه این است که سرور تو همچنان منبع حقیقت است، کاربر اصلاح را از پشتیبانی تو میخواهد، و وارسیکننده مستقلی در کار نیست، زنجیره را اضافه نکن. یک API امضاشده، یک لاگ اضافه فقطافزودنی در Postgres، یا خروجی قابل حسابرسی برای مشتری سازمانی معمولاً همان نیاز را با هزینه کمتر میپوشاند. اینها کمتر هیجانانگیزند و بیشتر قابل نگهداری.
اگر جواب این است که دارایی باید دستبهدست شود و تو نباید بتوانی انتقال را پنهانی پس بگیری، آن وقت زنجیره را برای همان بخش باریک طراحی کن نه برای کل اپ. بقیه محصول میتواند وب معمولی بماند: احراز هویت آشنا، پایگاه داده برای داده خصوصی، و یک مرز مشخص بین چیزی که قطعی زنجیرهای است و چیزی که کسبوکار تو اداره میکند. مرز را در مدل داده نشان بده، نه در شعار صفحه فرود.
چه وقتی وسوسه را رد کنی
رد کن وقتی انگیزه «عقب نماندن» است. رد کن وقتی توکن فقط لایه وفاداری است که با یک جدول امتیاز هم ساخته میشود. رد کن وقتی تیم هنوز مالکیت کلید، پشتیبان، و پاسخ به کاربر گیجشده را تمرین نکرده. رد کن وقتی میخواهی همه چیز را یکباره مهاجرت بدهی. و رد کن وقتی فروشنده زیرساخت، ادغام را یک کتابخانه و یک کلید API نشان میدهد. آن نمایش، عملیات ماه سوم را حذف نمیکند.
مهارت وب سنتی اینجا به کارت میآید، نه بهخاطر اینکه باید سریعتر قرارداد بنویسی. بهخاطر اینکه میتوانی تشخیص بدهی مسئله واقعاً مسئله هماهنگی بدون متولی است یا مسئله معمولی ذخیره و دسترسی. دومی را با زنجیره حل کردن، آیندهنگری نیست. قرض گرفتن یک مدل تهدید سنگین برای محصولی است که هنوز به یک مسئول مشخص نیاز دارد.
پرسشهای کوتاه
اگر بعداً خواستیم غیرمتمرکز شویم، از الان چیزی روی زنجیره نگذاریم؟ نه، مگر همان بخش از امروز آن خاصیت را لازم داشته باشد. مرز داده را تمیز نگه دار تا مهاجرت بعدی ممکن بماند. آینه زودهنگام، مهاجرت را آسانتر نمیکند.
هش عمومی برای اثبات دستنخوردگی چطور؟ گاهی مفید است، به شرطی که اصل داده و کلید وارسی معلوم باشد و کسی واقعاً وارسی کند. اگر هیچ مشتریای آن اثبات را چک نمیکند، لاگ داخلی کافی است.
کاربر خودش کیف پول دارد و اصرار دارد؟ برای یک قابلیت باریک که مالکیت واقعی دارایی معنی دارد، بله. برای ورود به اپ، تنظیمات، یا محتوای معمولی، همان حساب کاربری را نگه دار.