הגדרת Foundry: forge, cast, anvil, fuzzing לחוזים חכמים

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

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

שאלות נפוצות

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

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

מדוע הגדרת Foundry מתפרקת בפרויקט גדול

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

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

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

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

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

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

מה נותן מחזור build ובדיקת חוזים מסודר

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

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

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

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

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

מצבי הרצת רשת: צומת מקומי, פורק, סטנד בדיקה

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

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

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

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

הגדרת Foundry: שלבי עבודה מביקורת ריפו ועד מסירה

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

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

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

מדיניות גישה, מפתחות חתימה וארטיפקטים של build

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

להלן רשימה של מה שאנו מוסרים ומקבעים בתיעוד. כל סעיף נבדק בקבלה יחד עם המהנדס שלכם, ולא נשאר «על הנייר».

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

מקרה בוחן: איך קיצרנו את זמן ההשבתה של שחרור חוזים פי שלושה

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

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

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

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

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

במה שונה פורק רשת מקומי מסטנד בדיקה?

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

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

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

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

ספקות טכניים לפני תחילת עבודה

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

בדיקות כבר נכתבו על פריימוורק אחר — לכתוב הכל מחדש?

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

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

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

האם ה-build במכונה שלי וב-CI יהיה זהה?

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

מה יהיה אחרי מסירת הפרויקט?

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

נדון במשימה ונחזור עם הערכה ותוכנית

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

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

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

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