הגדרת Hardhat: ערכת כלים לחוזים חכמים

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

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

שאלות נפוצות

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

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

הגדרת Hardhat: מדוע בנייה ופריסה של חוזים נשברות

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

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

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

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

הגדרת Hardhat: מה משתנה בעבודה על חוזים

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

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

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

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

רשת מקומית, fork וסביבת בדיקות משותפת: השוואת מצבים

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

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

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

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

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

שלבי העבודה: מניתוח המאגר ועד מסירה לצוות

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

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

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

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

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

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

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

מה נשאר במאגר: תצורות, משימות, תיעוד

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

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

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

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

נקודת התחלה

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

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

מה שינינו ומה קיבלנו

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

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

זמן הבדיקה לפני release הצטמצם מ-3-4 שעות ל-10-15 דקות, ונפילות שווא עקב פערי סביבות נעלמו כסוג. דוח ההרצה מצורף ל-release, ולכן רואים אילו תרחישים עברו ומה בדיוק נפל.

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

מה לעשות אם חלק מהחוזים כבר נפרסו ברשת הראשית?

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

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

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

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

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

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

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

כיצד בוחרים את הגדרות הקומפילציה?

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

כמה תוספים מחוברים להשאיר?

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

מה המשמעות של יכולת שחזור הבנייה?

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

היכן לשמור סודות?

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

נדון במשימה: נבנה סביבה לפרויקט שלכם

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

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

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

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