למה טוקן רב-רשתי קשה יותר ממה שזה נראה
טוקן רב-רשתי אינו רק פריסת אותו ERC-20 על מספר רשתות. זו החלטה ארכיטקטונית עם השלכות חמורות על ניהול ההיצע, האבטחה וחוויית המשתמש. אנו רואים צוותים רבים נופלים למלכודת: טוקן רב-רשתי שתוכנן בצורה גרועה יוצר אשליה של נכס יחיד בעוד שבפועל יש היצע מפוצל, פותח שטח להתקפות גשר (התקפות גשר גרמו להפסדים של למעלה מ-2.5 מיליארד דולר לפי דוח הפריצות של SlowMist), ומסבך את הממשל. הצוות שלנו, עם ניסיון של 10+ שנים בבלוקצ'יין ו-20+ פרויקטים רב-רשתיים שהושלמו, עוזר להימנע מהמלכודות הללו.
איזו ארכיטקטורה לבחור?
לפני כתיבת קוד, יש לבחור מודל ארכיטקטוני. ישנן שלוש גישות שונות מהותית.
נעילה והטבעה (מודל קנוני)
הטוקן קיים באופן טבעי על רשת אחת (רשת בית, בדרך כלל Ethereum). על כל הרשתות האחרות קיימות גרסאות עטופות. הגשר נועל טוקנים ברשת הבית ומטביע טוקנים עטופים ברשת היעד. גישור חזרה שורף את הטוקנים העטופים ומשחרר את המקוריים. היצע קנוני יחיד ומודל מנטלי פשוט למשתמשים הם יתרונות. אבל אם הגשר נפרץ, תוקף יכול להטביע טוקנים עטופים ללא כיסוי. זה בדיוק מה שקרה בהתקפות הגשר הגדולות ביותר.
שריפה והטבעה (מודל Omnichain)
בעת העברה, הטוקן נשרף ברשת המקור ומוטבע ברשת היעד. ההיצע הכולל קבוע גלובלית. גישה זו משמשת את LayerZero OFT ו-Axelar ITS. אין נזילות קפואה על רשת אחת; הטוקנים שווים בכל הרשתות. החיסרון הוא שהעסקה אינה אטומית: הטוקן נהרס במקור אך עלול להיכשל בהטבעה ביעד עקב תקלה. יש צורך במנגנון שחזור, שאנו תמיד כוללים בחוזה.
מודל מאגר נזילות
טוקנים עצמאיים על כל רשת מחוברים דרך מאגרי AMM בפרוטוקולי גשר (Stargate, Synapse). גשר החלפה טבעי, לא טוקנים עטופים. החלפה מיידית (אטומית מהמאגר), ללא טוקנים עטופים, אך דורש נזילות התחלתית על כל רשת ועלול לסבול מהחלקה עם מאגרים לא מאוזנים.
| קריטריון | נעילה והטבעה | שריפה והטבעה (OFT) | מאגר נזילות |
|---|---|---|---|
| היצע אחיד | כן (קנוני) | כן (גלובלי) | לא (נפרד) |
| סיכון התקפת גשר | גבוה | בינוני | נמוך |
| אטומיות העברה | לא (דורש שחרור) | לא (דורש שחזור) | כן (החלפה מהמאגר) |
| יעילות גז | בינונית | גבוהה | בינונית |
| הרחבה ל-N רשתות | קשה (נזילות) | קלה | קשה (התחלתית) |
יישום על LayerZero OFT
LayerZero הפך לסטנדרט דה-פקטו עבור טוקנים רב-רשתיים חדשים. OFT הוא מודל שריפה והטבעה עם העברת הודעות דרך נקודת הקצה של LayerZero. בבדיקות שלנו, OFT בטוח פי 2 מ-Lock & Mint עם אותו גז. סעיף זה מספק קוד מלא ותצורה.
יישום OFT בסיסי
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import { OFT } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFT.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; contract MyToken is OFT { constructor( string memory _name, string memory _symbol, address _lzEndpoint, // LayerZero Endpoint адрес для текущей сети address _delegate ) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {} function mint(address _to, uint256 _amount) external onlyOwner { _mint(_to, _amount); } } ברשת הבית, פרסו חוזה זה והטביעו את כל ההיצע. ברשתות אחרות, פרסו את אותו חוזה אך ללא הטבעה ראשונית — טוקנים מגיעים דרך גישור.
תצורה לאחר פריסה
לאחר פריסה על כל הרשתות, חברו חוזים באמצעות // SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import { OFT } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFT.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; contract MyToken is OFT { constructor( string memory _name, string memory _symbol, address _lzEndpoint, // LayerZero Endpoint адрес для текущей сети address _delegate ) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {} function mint(address _to, uint256 _amount) external onlyOwner { _mint(_to, _amount); } } :
function configurePeers() external onlyOwner { // eid = endpoint ID в системе LayerZero // Ethereum mainnet: 30101, Arbitrum: 30110, Base: 30184, BSC: 30102 oft.setPeer(30110, bytes32(uint256(uint160(ARBITRUM_OFT_ADDRESS)))); oft.setPeer(30184, bytes32(uint256(uint160(BASE_OFT_ADDRESS)))); } שליחת טוקנים בין רשתות
function bridgeTokens( uint32 _dstEid, address _recipient, uint256 _amount ) external payable { SendParam memory sendParam = SendParam({ dstEid: _dstEid, to: bytes32(uint256(uint160(_recipient))), amountLD: _amount, minAmountLD: (_amount * 995) / 1000, // 0.5% slippage tolerance extraOptions: OptionsBuilder.newOptions() .addExecutorLzReceiveOption(200000, 0), // gas на destination composeMsg: "", oftCmd: "" }); MessagingFee memory fee = oft.quoteSend(sendParam, false); oft.send{ value: fee.nativeFee }(sendParam, fee, payable(msg.sender)); } ניהול היצע בין רשתות
זה ההיבט המורכב ביותר. נדרש ניטור:
| מדד | איך לעקוב |
|---|---|
| היצע לכל רשת | קריאה ל-function configurePeers() external onlyOwner { // eid = endpoint ID в системе LayerZero // Ethereum mainnet: 30101, Arbitrum: 30110, Base: 30184, BSC: 30102 oft.setPeer(30110, bytes32(uint256(uint160(ARBITRUM_OFT_ADDRESS)))); oft.setPeer(30184, bytes32(uint256(uint160(BASE_OFT_ADDRESS)))); } בכל פריסה |
| היצע במחזור | סכום כל function bridgeTokens( uint32 _dstEid, address _recipient, uint256 _amount ) external payable { SendParam memory sendParam = SendParam({ dstEid: _dstEid, to: bytes32(uint256(uint160(_recipient))), amountLD: _amount, minAmountLD: (_amount * 995) / 1000, // 0.5% slippage tolerance extraOptions: OptionsBuilder.newOptions() .addExecutorLzReceiveOption(200000, 0), // gas на destination composeMsg: "", oftCmd: "" }); MessagingFee memory fee = oft.quoteSend(sendParam, false); oft.send{ value: fee.nativeFee }(sendParam, fee, payable(msg.sender)); } פחות מה שנעול בחוזי גשר |
| זרימת גשר | אירועים UlnConfig memory ulnConfig = UlnConfig({ confirmations: 15, requiredDVNCount: 2, optionalDVNCount: 0, optionalDVNThreshold: 0, requiredDVNs: [LAYERZERO_DVN, GOOGLE_CLOUD_DVN], optionalDVNs: new address[](0) }); / mapping(uint256 => uint256) public dailyBridgeVolume; uint256 public constant MAX_DAILY_BRIDGE = 1_000_000e18; // 1M токенов/день modifier withRateLimit(uint256 amount) { uint256 today = block.timestamp / 1 days; require( dailyBridgeVolume[today] + amount <= MAX_DAILY_BRIDGE, "Daily bridge limit exceeded" ); dailyBridgeVolume[today] += amount; _; } |
| הודעות ממתינות | LayerZero Scan API |
עבור מודל Lock & Mint (אם משתמשים בגשר מותאם אישית), יש צורך בבדיקת אינווריאנט: סכום(היצע עטוף) <= נעול_ברשת_הבית. ניטור דרך Tenderly או סקריפט מותאם עם התראות.
אבטחה: DVN, הגבלת קצב, השהיה
הגדירו 2 מתוך N מאמתים לאישור הודעה. תצורה מינימלית מאובטחת:
UlnConfig memory ulnConfig = UlnConfig({ confirmations: 15, requiredDVNCount: 2, optionalDVNCount: 0, optionalDVNThreshold: 0, requiredDVNs: [LAYERZERO_DVN, GOOGLE_CLOUD_DVN], optionalDVNs: new address[](0) }); לייצור, אנו משתמשים ב-LayerZero DVN בתוספת DVN עצמאי אחד (Google Cloud, Nethermind, p2p.org).
גם עם גשר אמין, הוסיפו הגבלת קצב ברמת חוזה הטוקן כקו הגנה אחרון:
mapping(uint256 => uint256) public dailyBridgeVolume; uint256 public constant MAX_DAILY_BRIDGE = 1_000_000e18; // 1M токенов/день modifier withRateLimit(uint256 amount) { uint256 today = block.timestamp / 1 days; require( dailyBridgeVolume[today] + amount <= MAX_DAILY_BRIDGE, "Daily bridge limit exceeded" ); dailyBridgeVolume[today] += amount; _; } אם הגשר נפרץ, הגבלת הקצב מספקת זמן לתגובה, ומגבילה את הנזק.
החוזה חייב לכלול פונקציית השהיה המנוהלת על ידי multisig עם timelock קצר. עם זיהוי פעילות גשר חריגה, השהה העברות מיד. אנו מוודאים שכל החוזים עוברים ביקורות ובדיקות עומס.
תהליך העבודה שלנו: מרעיון לפריסה
- ניתוח דרישות: בחירת רשתות, מודל, טוקנומיקה.
- עיצוב ארכיטקטורה: חוזים חכמים, גשר, ממשל.
- פיתוח: כתיבת קוד באמצעות Foundry/Hardhat, אינטגרציה עם LayerZero.
- בדיקות: בדיקות יחידה, בדיקות fork על כל הרשתות, fuzzing.
- ביקורת אבטחה: פנימית + חיצונית (2–3 חברות).
- פריסה: פריסה רציפה, אימות, הגדרת ניטור.
מה כלול בפיתוח טוקן רב-רשתי?
- קוד חוזה חכם מלא (OFT או גשר מותאם אישית).
- סקריפטים לפריסה ותצורה לכל הרשתות.
- הגדרת LayerZero Endpoint ו-DVN.
- אינטגרציה של הגבלת קצב והשהיה.
- תיעוד טכני ומדריך תפעולי.
- תמיכה לאחר פריסה (ניהול אירועים למשך שבועיים).
לוחות זמנים ועלות
לוחות הזמנים נעים בין 1 ל-4 שבועות תלוי במספר הרשתות והמורכבות. העלות מחושבת באופן אישי — צרו קשר להערכה. בקשו ייעוץ לדיון בפרטים.
טעויות נפוצות וכיצד להימנע מהן
- מודל שגוי: בחירת Lock & Mint ללא הערכת סיכוני גשר. השתמשו בחלופה הבטוחה יותר — OFT עם DVN.
- ללא הגבלת קצב: בלעדיה, הנזק מהתקפת גשר הוא בלתי מוגבל.
- מאמת יחיד: הסתמכות רק על LayerZero DVN. הוסיפו מאמת עצמאי.
- התעלמות מגז ביעד: אי הגדרת
executorLzReceiveOptionגורם לכשלי גישור. - ללא ניטור: יש לעקוב אחר זרימות גשר בזמן אמת.
קבלו ייעוץ לפרויקט שלכם — המהנדסים שלנו עם ניסיון של 10+ שנים יעזרו לכם לבחור את הארכיטקטורה האופטימלית ולהימנע מטעויות נפוצות.







