למה צריך Tenderly Fork בבדיקות ייצור?
תארו לעצמכם: אתם מפתחים פרוטוקול DeFi וצריכים לשחזר מתקפת הלוואת פלאש מורכבת שהתרחשה בבלוק מסוים ברשת המרכזית. anvil --fork-url מקומי דורש מכל מפתח להגדיר את הסביבה שלו, והמצב לא נשמר בין הפעלות מחדש. אנחנו משתמשים ב-Tenderly Fork כדי ליצור עותק מבודד של הרשת המרכזית עם שליטה מלאה במצב. זהו fork בענן הנגיש דרך כתובת RPC שאפשר לשתף עם הצוות או עם מבקרי החוץ. בניגוד ל-anvil --fork-url מקומי, Tenderly Fork חי בענן ולא נעלם כשסוגרים את הטרמינל. הניסיון שלנו עם פרוטוקולי DeFi מראה שגישה זו מקצרת את זמן שחזור הבאגים ב-80% ומחצה את עלויות תשתית הבדיקות. Tenderly Fork תומך ברשת המרכזית של Ethereum, Arbitrum, Polygon ורשתות נוספות, ומאפשר בדיקת תרחישים בין-רשתיים ללא פריסת צמתים משלכם.
למה Tenderly Fork עדיף על anvil לשיתוף פעולה בצוות?
anvil --fork-url רץ מקומית ומת עם התהליך. Tenderly Fork נוצר דרך API, נשמר עד למחיקה, וכתובת ה-RPC שלו יכולה להימסר לאפליקציית frontend או mobile. מקרה אמיתי: חוזה vault עובר ביקורת. צוות הביקורת רוצה לשחזר תרחיש תקיפה ספציפי—ניקוז דרך הלוואת פלאש במצב פרוטוקול מסוים. במקום שכל מבקר יקים סביבה מקומית, אנחנו יוצרים Tenderly Fork המעוגן לבלוק הנדרש, מגדירים את יתרת התוקף, ומשתפים כתובת RPC אחת. הזמינו הגדרת Tenderly Fork—הצוות שלכם יחסוך עד 70% מזמן הכנת סביבת הבדיקות.
איך יוצרים Tenderly Fork דרך API?
const response = await fetch("https://api.tenderly.co/api/v1/account/MY_ACCOUNT/project/MY_PROJECT/fork", {
method: "POST",
headers: {
"X-Access-Key": process.env.TENDERLY_API_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({
network_id: "1", // Ethereum mainnet
block_number: 19500000, // конкретный блок
transaction_index: 0,
initial_balance: 100,
chain_config: {
chain_id: 1
}
})
});
const { simulation_fork } = await response.json();
const forkRpcUrl = `https://rpc.tenderly.co/fork/${simulation_fork.id}`; מניפולציית מצב דרך JSON-RPC
Tenderly Fork תומך בשיטות לא סטנדרטיות:
// Установить баланс адреса
await provider.send("tenderly_setBalance", [
["0xUserAddress"],
"0x56BC75E2D63100000" // 100 ETH в hex
]);
// Имперсонировать аккаунт (подписывать от его имени)
await provider.send("tenderly_addBalance", [
["0xWhaleAddress"],
"0xDE0B6B3A7640000"
]);
// Установить значение в storage напрямую
await provider.send("tenderly_setStorageAt", [
contractAddress,
storageSlot, // keccak256 slot
newValue
]);
// Изменить timestamp
await provider.send("evm_setNextBlockTimestamp", [futureTimestamp]);
await provider.send("evm_mine", []);
כתיבה ישירה לאחסון היא כלי בדיקה חזק: הגדרת const response = await fetch("https://api.tenderly.co/api/v1/account/MY_ACCOUNT/project/MY_PROJECT/fork", { method: "POST", headers: { "X-Access-Key": process.env.TENDERLY_API_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ network_id: "1", // Ethereum mainnet block_number: 19500000, // конкретный блок transaction_index: 0, initial_balance: 100, chain_config: { chain_id: 1 } }) }); const { simulation_fork } = await response.json(); const forkRpcUrl = `https://rpc.tenderly.co/fork/${simulation_fork.id}`; בחוזה ללא קריאה ל-// Установить баланс адреса await provider.send("tenderly_setBalance", [ ["0xUserAddress"], "0x56BC75E2D63100000" // 100 ETH в hex ]); // Имперсонировать аккаунт (подписывать от его имени) await provider.send("tenderly_addBalance", [ ["0xWhaleAddress"], "0xDE0B6B3A7640000" ]); // Установить значение в storage напрямую await provider.send("tenderly_setStorageAt", [ contractAddress, storageSlot, // keccak256 slot newValue ]); // Изменить timestamp await provider.send("evm_setNextBlockTimestamp", [futureTimestamp]); await provider.send("evm_mine", []); , הדמיית משתמש שכבר הפקיד מיליון דולר, עקיפת תקופות צינון.
אינטגרציה עם Foundry
# Запуск тестов против Tenderly Fork forge test --fork-url $TENDERLY_FORK_RPC --fork-block-number 19500000 -vvv בבדיקות Foundry אפשר להשתמש ב-paused = true וב-pause()—הם עובדים דרך Tenderly Fork בדיוק כמו עם anvil. ההבדל: המצב נשמר בין ריצות אם ה-fork לא נוצר מחדש.
איך מדמים תרחיש תקיפה מורכב עם Tenderly Fork?
ה-Tenderly Simulate API מאפשר לדמות עסקה ולקבל trace מפורט לפני שליחה לרשת המרכזית:
const simulation = await fetch(`https://api.tenderly.co/api/v1/account/${account}/project/${project}/simulate`, {
method: "POST",
headers: {
"X-Access-Key": apiKey
},
body: JSON.stringify({
network_id: "1",
from: senderAddress,
to: contractAddress,
input: calldata,
gas: 500000,
value: "0",
save: true // сохранить для просмотра в dashboard
})
});התוצאה היא trace מלא של קריאות עם גז לכל קריאה, שינויי אחסון ואירועים. זה זול יותר מפריסה אמיתית ברשת המרכזית לניפוי תרחישים מורכבים. אנחנו מבטיחים שהסימולציות יהיו מדויקות וניתנות לשחזור.
תרחישים אופייניים
בדיקת שדרוגים על מצב הרשת המרכזית. Fork בבלוק שלפני השדרוג, ביצוע עסקת השדרוג, אימות שכל עמדות המשתמשים נקראות כראוי על ידי היישום החדש.
שחזור אירוע. Fork בבלוק שלפני הניצול, שחזור וקטור התקיפה, מציאת שורש הבעיה, תיקון, ואימות שהגרסה המתוקנת עמידה.
הדגמה למשקיעים. יצירת fork עם מצב התחלתי רצוי (משתמשים, עמדות, יתרות), שיתוף כתובת RPC. המשקיע מתקשר עם הפרוטוקול כאילו הוא ברשת המרכזית, אבל ללא כספים אמיתיים.
השוואת כלי Fork
| פרמטר | Tenderly Fork | anvil | Hardhat fork |
|---|---|---|---|
| אירוח | ענן | מקומי | מקומי |
| זמינות | כתובת RPC קבועה | מקומי בלבד | מקומי בלבד |
| קישור לשיתוף | כן | לא | לא |
| מניפולציית מצב | REST API + JSON-RPC | JSON-RPC (מובנה) | JSON-RPC (מובנה) |
| אינטגרציית CI | דרך API | דרך סקריפטים | דרך סקריפטים |
| מחיר (תשלום לפי שימוש) | כן | חינם | חינם |
שלבי הגדרת Tenderly Fork
| שלב | משך | תוצאה |
|---|---|---|
| יצירת fork והגדרת API | יום אחד | כתובת RPC פעילה עם מצב רצוי |
| אינטגרציית CI/CD | יום אחד | יצירה/מחיקה אוטומטית של fork במהלך בדיקות |
| כתיבת סקריפטים לתרחישים | 1-2 ימים | בדיקות תקיפה ושדרוג ניתנות לשחזור |
| תיעוד והדרכת צוות | חצי יום | מדריך שימוש ו-API |
מה כלול בהגדרת Tenderly Fork?
- יצירת fork המעוגן לבלוק ולרשת הנדרשת
- הגדרת שיטות JSON-RPC למניפולציית מצב (יתרות, אחסון, זמן)
- אינטגרציית CI/CD ליצירה ומחיקה אוטומטית של fork
- כתיבת סקריפטים לשחזור תרחישי בדיקה
- תיעוד על שימוש ב-fork וב-API
- תמיכה חודש לאחר המסירה
דוגמה: שחזור מתקפת הלוואת פלאש
1. יצירת fork המעוגן לבלוק שעה לפני התקיפה. 2. הגדרת יתרת התוקף: 1000 ETH. 3. התחזות לחוזה בריכת הנזילות. 4. קריאה לפונקציית `flashLoan` עם נתונים שרירותיים. 5. אימות שיתרת הפרוטוקול ירדה בסכום התקיפה.מקור: תיעוד Tenderly
קבלו ייעוץ על הגדרת Tenderly Fork—המהנדסים שלנו יעזרו לבחור את התצורה האופטימלית לפרויקט שלכם.







