בדיקות חוזים חכמים (מבחני אינטגרציה)

העדכון כבר ברשת הראשית, אך מערך החוזים מתנהג אחרת מאשר בסביבת הבדיקה. אנו מתכננים ומריצים תרחישי אינטגרציה מלאים: מניתוח תפקידים ועד דוח עם שלבים ניתנים לשחזור. בדיקת מסלולים מקצה לקצה לפני העלאה מסירה מהצוות הרצות ידניות ומסלקת סוג שלם של כשלים בעת השחרור.

שירותי פיתוח בלוקצ'יין

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1375
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1349
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    794
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1087
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1032
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1129

בדיקות אינטגרציה לחוזים חכמים והנקודות העיוורות שלהן

בדיקות מודולריות מאשרות שחוזה בודד פועל לפי המפרט שלו. הערך של הפרוטוקול נולד במפגשים — בין הטוקן לאחסון, בין החישוב לתשלום, בין הלוגיקה למקור נתונים חיצוני. בדיקות אינטגרציה לחוזים חכמים בודקות את המערך כולו בסדר הקריאות שבו תראה אותו רשת Ethereum בתוך עסקה אחת.

כשלים במפגשים כמעט אינם נראים בנפרד: הנמען חושב שהתשלום עבר, השולח כבר רשם את החיוב, וביניהם בוצעה החזרה. חוסר סנכרון מצבים צף מאוחר יותר, כשעל נתונים סוטים מחשבים מגבלות, חלקים או תגמולים, ואת השחזור צריך לבצע ידנית.

אזור נפרד הוא סדר הקריאות וכניסות חוזרות. אם התשלום יוצא לכתובת חיצונית לפני עדכון היתרה, הנמען מספיק לקרוא לפונקציה שוב ולמשוך יותר ממה שמותר לו. הגנה כזו נבדקת רק ברמת שרשרת הקריאות, ולא ברמת חוזה בודד.

ענפים שהוחמצו בתרחישים — זו החור הטיפוסי השני. בודקים מסלול מוצלח וכשל מלא, אבל לא חלקי: תקלה באמצע מחזירה את העסקה כולה לאחור, והשירות החיצוני כבר קיבל אירוע ורשם פעולה במאגר שלו. אי-התאמה בין הרשת למערכת החשבונאית מתגלה בהתאמות, כלומר מאוחר מדי.

תקלות אחרי עדכון עולות הכי ביוקר: הלוגיקה משתנה בחוזה חדש, ומודולים סמוכים ממשיכים לפנות לישן, וחלק מהמצב נשאר לא מחושב. נפרק מה בדיוק בודקים במערך ואיך תופסים את אי-ההתאמות האלה לפני הפריסה.

מה נותנת בדיקת תרחישי מקצה לקצה לפני פריסה לרשת הראשית

תרחיש מקצה לקצה מריץ את כל השרשרת — מקריאה למתודה ציבורית ועד שינוי מצב ואירוע שקורא השירות החיצוני. אנחנו מקימים מתקן מבודד עם עותק מקומי של מצב הרשת הראשית, מקבעים את מספר הבלוק ופורסים את כל מערך החוזים.

זה נותן יכולת שחזור: אותה קבוצת עסקאות על אותו צילום מצב נותנת תוצאה זהה אצל כל מהנדס ובכל סביבת בנייה.

מערכת תרחישים מלאה עוברת בדקות במקום שעות של בדיקות ידניות: ריצות מקבילות על עותקים של המתקן אינן מפריעות זו לזו, והמצב מוחזר באמצעות צילום מצב. חזרתיות התוצאות — האפקט העיקרי: כשל מעיד על שגיאה אמיתית בלוגיקה, ולא על הבדל ביתרת חשבון הבדיקה או בזמן הבלוק.

כך מוסרים מחלקות שלמות של כשלים: אי-התאמה בהרשאות בין תפקידים, סדר קריאות שגוי בהעברות בין חוזים, כניסה חוזרת, גלישה בחישוב חלקים, אי-התאמה בין אירועים למצב בפועל. שיעור הפגמים שמגיעים למשתמש יורד — הם נתפסים במקום שבו התיקון אורך שעות, ולא תחקור תקלה ברשת הראשית.

שדרוג נבדק באותו מעגל: תרחיש מיישם גרסה חדשה על צילום מצב נוכחי ומריץ מיגרציה. רואים שהנתונים הישנים נקראים כראוי, וזמן ההשבתה בשדרוג מוגבל לעסקת החלפה אחת, ולא לחיפוש סיבת הכשל אחריה.

פורמטי ריצה: מתקן מקומי, רשת סגורה, רשת ראשית

בחירת הסביבה קובעת אילו פגמים הריצה בכלל מסוגלת לתפוס. מתקן מקומי נותן בידוד מלא של נתוני בדיקה ושניות למחזור, אך אינו משחזר את ההתנהגות של מאגרי נזילות אמיתיים, אורקלים ועומס רשת.

רשת סגורה עם אותם חוזים וצילומי מצב מכסה את האמצע: ההתנהגות קרובה לזו של הסביבה המבצעית, והנתונים אינם חופפים לנתוני העבודה.

מה משווים

אפשרות מתי מתאימה מגבלות הסביבה
מתקן מקומי לוגיקת החוזה, הרשאות גישה, גבולות ערכים, רגרסיה אחרי כל שינוי קוד אין עומס אמיתי, קריאות חיצוניות מוחלפות בסטאבים
רשת סגורה תרחישים בין כמה חוזים, מיגרציות מצב, תנאים תלויים בזמן יש להקים ולתחזק צמתים, המצב נבנה מחדש לכל ריצה
ריצה ברשת הראשית בדיקה סופית לפני השקה: קריאות חיצוניות אמיתיות, הערכה מהימנה של צריכת גז עסקאות בלתי הפיכות, אין בידוד של נתוני בדיקה — רק קריאה או חשבונות נפרדים

הקריטריון העיקרי לבחירה — בידוד נתוני הבדיקה. ריצה ברשת הראשית מוצדקת כאשר בודקים את החיבור לחוזים חיצוניים ואת העלות בפועל של פעולות, ולא את הלוגיקה. רשת סגורה הופכת בדרך כלל למצב העבודה עבור תרחישי אינטגרציה: היא היחידה שנותנת גם מהימנות וגם אפשרות להחזיר מצב.

גם הסביבה מכתיבה מגבלות: גרסאות שונות של צמתים, מגבלות נקודות גישה ותזמוני הפקת בלוקים יכולים להיות שונים, ולכן אנו מחזיקים מערכי בדיקות נפרדים לכל מצב.

שלבי העבודה: מפירוק תרחישים ועד בדיקות במתקן

בדיקות אינטגרציה לחוזים חכמים מתחילות לא בקוד הבדיקות, אלא בפירוק המערך: כיצד חוזים קוראים זה לזה, מה הם מצפים משירותים חיצוניים ובאיזה מצב נשארת המערכת אחרי כל פעולה. שגיאה בסדר הקריאות או במצב הצפוי של החוזה הסמוך מתגלה כבר אחרי הפריסה, כאשר התיקון מחייב מיגרציה. לכן סדר העבודה שלנו הוא כזה: תחילה מפת המערך, אחר כך הבדיקות.

  1. ביקורת תרחישים — אוספים מסלולי משתמש ותפקידים: מי קורא למתודה, אילו מגבלות ומצבים נבדקים בכך, היכן צפויים כשלים. בפלט — רשימת תרחישים עם עדיפות לפי סיכון.
  2. מפת קריאות — מתעדים קשרים בין חוזים, טוקנים ומקורות נתונים חיצוניים: מי קורא למי, אילו ערכים מעביר ומה מחזיר. המפה מראה מיד מקומות שבהם הבדיקה חייבת לבדוק גם שינויי מצב לוואי.
  3. סכמת תרחישים — כל מסלול הופכים למערכת שלבים עם מצב צפוי לפני ואחרי הקריאה, כדי שאי-התאמה תיקרא נקודתית, ולא כ"כל הריצה נפלה".
  4. הגדרת הסביבה — המתקן משחזר את רשת היעד לפי פרמטרי עמלות, סדר אישורים וגרסאות תלויות; בנפרד מקימים רשת בדיקה לבדיקות שאינן משוחזרות מקומית.
  5. ריצה וניתוח אי-התאמות — מריצים תרחישים בקבוצות, רושמים לוגים של קלטים, מצב ואירועים, וכל אי-התאמה מביאים עד הסיבה: שגיאה בחוזה, בסביבה או בציפייה של הבדיקה עצמה.
  6. קריטריוני קבלה — לפני הריצה הסופית מסכימים אילו תרחישים חובה ואיזו תוצאה נחשבת להצלחה, כדי שהקבלה לא תהפוך למשא ומתן.
  7. מסירה — מוסרים מערך בדיקות, קונפיגורציות של המתקן ודוח עם כיסוי מסלולים, כדי שהריצה תחזור על עצמה אצל הצוות שלכם בלעדינו.

ארטיפקטים בפלט: מערכי תרחישים, דוחות, נהלים

אנחנו מוסרים לא תיקייה עם בדיקות, אלא מעגל עבודה פעיל: מערך תרחישים ניתן להרצה, נתונים ניתנים לשחזור וכללים שלפיהם הצוות שלכם מריץ ומעדכן בדיקות בעצמו אחרי כל תיקון בחוזים. להלן מה שנשאר פיזית אצלכם במאגר ובמסמכים.

  • מערך תרחישי בדיקות אינטגרציה — מקובץ לפי דומיינים: טוקן, הרשאות, תשלומים, קריאות חיצוניות. כל תרחיש מורץ בנפרד, ולכן בדיקה שנפלה מצביעה על פונקציה מסוימת, ולא על "משהו נשבר".
  • פיקסצ'רים ותיעוד נתונים — מתואר מאיזה מצב עולה המתקן: צילום מצב של הרשת הראשית בגובה הבלוק הנדרש, כתובות ממומנות, תפקידים מוגדרים מראש. המתקן עולה בפקודה אחת ונותן תוצאה זהה אצל המפתח ובשרת הבנייה.
  • סכמת אינטראקציה בין מודולים — מפת קריאות בין חוזים לשירותים חיצוניים עם סימון מה מכוסה בבדיקות ומה נותר בבקרה ידנית.
  • דוח ריצה — תרחישים שעברו ונפלו, זמן ביצוע, שינוי בצריכת הגז לעומת הריצה הקודמת, כיסוי ענפים. רגרסיה נראית לפני הפריסה, ולא אחריה.
  • נוהל עדכון — מערך תרחישים חובה בעת תיקון חוזה, מי מאשר את הריצה, כיצד מתעדים גרסה חדשה וכיצד מחזירים לגרסה קודמת.
  • תפקידים והרשאות — מטריצת הרשאות לשינוי תרחישים, מפתחות של רשתות בדיקה, הפרדת גישה למתקן ולקונפיגורציות המבצעיות.

מקרה בוחן: כיצד נעלמה מחלקת כשלים בעת שחרור עדכון

הלקוח שחרר עדכונים למערך של שישה חוזים: טוקן, מאגר, אורקל, מודול הצבעה ושני מודולי עזר. את המודולים בדקו בנפרד, ואת ההתנהגות המשותפת בדקו ידנית ברשת בדיקה — השחרור ארך יומיים, וכשליש מהמהדורות נאלצו להחזיר, כי אי-התאמה בממשקים צפה כבר אחרי הפרסום.

מה שינו

אספו ריצה אחודה: פיקסצ'רים פורסים את כל המערך ברשת מבודדת, כולל עדכון תוך שמירה על האחסון המצטבר, ולכן נבדק לא רק הקוד החדש של המודול, אלא גם התאימות לנתונים שכבר נכתבו.

הוסיפו בדיקות אינווריאנטים — סכום החלקים, הרשאות תפקידים, מגבלות הנפקה — הן מורצות אחרי כל פעולה, ולא פעם אחת בסוף. תרחיש החזרה לגרסה הקודמת הפך לחלק מהריצה, ולא לנהלי חירום לפי הוראות.

הפריסה וההרצה מבוססות על Hardhat: אותם תרחישים מבוצעים אצל המהנדס מקומית ובבנייה — אין אי-התאמות בין הסביבות.

מדד לפני אחרי
שיעור מהדורות עם החזרה כל שלישית אחת מתוך ארבע-עשרה
זמן בדיקה מלאה של המערך יומיים ידנית כארבעים דקות
זמן החזרה לגרסה קודמת שלוש-ארבע שעות עד עשר דקות בתרחיש אחד

כעת המהדורה לא ממתינה לחלון בסוף השבוע: הריצה מתחילה על כל שינוי ונופלת על אי-התאמה לפני הפרסום. החזרה חדלה להיות תקלה עם צעדים ידניים — זה אותו תרחיש מהריצה, המבוצע ברשת המבצעית.

מה לעשות אם המערך כבר פרוס ועובד ברשת הראשית?

מערכת חיה נבדלת בכך שאי אפשר לעצור אותה לבדיקה: יתרות ואחסון משתנים מתחת לידיים. הבדיקה נבנית על עותק — צילום מצב בבלוק קבוע נפרס בצומת מבודד, שבו משוחזרת כל רצף קריאות בלי סיכון לרשת הראשית. אותו צילום משמש כנקודת השוואה: אחרי הריצה משווים יתרות, אירועים ואחסון לערכים הצפויים.

המעגל השני — ריצת צל: הגרסה החדשה של הלוגיקה מקבלת את אותן קריאות, אך התוצאה לא נשלחת לשום מקום ומושווית לתשובת החוזה הפעיל. אי-התאמה בתרחיש אחד לפחות משמעה אי-תאימות, והבנייה לא מגיעה לרשת.

תלויות חיצוניות — אורקלים, מאגרים, חוזים של שותפים — מוחלפות בסטאבים נשלטים עם התנהגות מוגדרת, כולל כשלים ועיכובי תשובה.

בנפרד בודקים תאימות לאחור של עדכונים: רשומות ישנות באחסון צריכות להיקרא על ידי הלוגיקה החדשה, והאירועים שהופקו — להישאר מובנים לאינדקסרים ולארנקים. בחוזים מתעדכנים אנחנו מקבעים מראש את סדר השדות וסלוטי האחסון על גבי סכמות OpenZeppelin: שדה חדש מתווסף רק בסוף. כך נעלמת מחלקת כשלים שבה אחרי עדכון מתאפסות יתרות או נשברות הרשאות גישה.

השחרור מתבצע בשלבים: צילום מצב, ריצת צל על עותק, הפעלה מוגבלת על חלק מהתעבורה עם מגבלות והחזרה מיידית. בין השלבים אנחנו מחזיקים מדדים — שיעור קריאות מוצלחות ואי-התאמה מול האמולציה. אם אין אי-התאמות, הגרסה נפרסת לכל המערכת; אם יש — ההחזרה אורכת קריאה אחת, והמשתמשים לא מבחינים בה.

ספקות טכניים נפוצים לפני התחלה

לפני ההתחלה לקוחות שואלים את אותה קבוצת שאלות, וכמעט כולן עוסקות בגבולות: מה בדיוק בודקים, באיזו רשת, איך זה משפיע על המוצר הפעיל. להלן תשובות ענייניות לאלה שלרוב מעכבות את ההחלטה.

במה זה שונה מבדיקת מודולים בודדים?

בדיקות מודולריות מבודדות פונקציה אחת. תרחיש אינטגרציה עובר את המסלול כולו: קריאה לחוזה, העברת נכסים, רישום אירוע, מצב חדש. כאן צפים הרשאות שגויות, סדר קריאות וכניסה חוזרת — מה שהבידוד לא רואה.

האם צריך רשת אמיתית?

את עיקר הנפח מריצים על עותק מקומי של מצב הרשת: הסביבה עולה מהקונפיגורציה בדקות, תרחיש אחד אורך שניות. מעגל אמיתי נדרש בריצה הסופית — הוא מאשר התנהגות עם כתובות ומגבלות אמיתיות.

איך לדעת שכיסוי מספיק?

אנחנו סופרים לא שורות, אלא ענפי תרחישים: מסלול מוצלח, כשל בהרשאות, כשל במגבלות, סכומים בגבול, החזרה. אם ענף יכול לעצור משיכת כספים — הוא מכוסה בבדיקה.

איך זה משפיע על המוצר הפעיל?

הריצות אינן נוגעות ברשת הראשית, מפתחות מבצעיים אינם משמשים בהן. מצבים נדירים — רזרבה ריקה, מגבלה שעומדת להסתיים, עסקה תקועה — משחזרים בכפייה דרך צילום מצב, ולכן הבדיקות מתנהלות במקביל לעבודת השירות.

נדון במשימה: ממה נתחיל ומה נדרש מצדכם

השיחה הראשונה על בדיקות אינטגרציה לחוזים חכמים היא טכנית, לא מצגת: מפרקים את ארכיטקטורת הפרוטוקול, את הגבולות בין החוזים לעולם החיצון ואת התרחישים שבהם טעות עולה ביוקר.

בדרך כלל שעה מספיקה כדי להבין את ההיקף — כמה חוזים במערך, אילו מהם מתעדכנים, מה נקרא מבחוץ ואילו תפקידים רשאים לשנות מצב.

כדי שהשיחה תהיה עניינית, כדאי להכין חומרים מראש. מהלקוח נדרשים:

  • מאגר או ארכיון של החוזים יחד עם בדיקות קיימות, אפילו חלקיות;
  • תיאור הפרוטוקול: תפקידים, הרשאות גישה, לוגיקת עדכון החוזים;
  • כתובות של חוזים פרוסים ורשתות בדיקה שאליהן יש גישה פעילה;
  • רשימת אינטגרציות חיצוניות — אורקלים, גשרים, מאגרים, שירותי משמורת — והממשקים שלהן;
  • מפתחות וצמתים לרשתות בדיקה וכן סביבת בנייה, אם התרחישים אמורים לרוץ בצינור;
  • יומן תקלות ופגמים ידועים: מה כבר נשבר ובאילו תנאים שוחזר;
  • דרישות קבלה — לפי אילו תרחישים אנו מחשיבים את הכיסוי למספק.

השיחה מסתיימת לא ב"תודה, נחשוב", אלא בתוכנית עבודה: שלבים, הרכב המתקן המקומי והעותקים של הרשת הראשית, רשימת תרחישים עם עדיפויות, פורמט הדוחות והערכת היקף — לפי לוחות זמנים ועומס הצוות. תחילת הפרויקט — מיד לאחר אישור התוכנית. תארו את המשימה — נחזור עם תוכנית והערכה.