מדוע חבילת npm עם חוזה חכם מתפצלת מהרשת
החוזה נפרס, חבילת ה-npm עם החוזה החכם פורסמה, הבדיקות עוברות. ואז פרסו את החוזה מחדש: לבנאי נוסף ארגומנט חובה, סדר הפרמטרים של המתודה השתנה, שם האירוע שונה. החבילה נותרה כשהייתה — בה תיאור מיושן של הממשק וכתובת שכבר אינה תואמת את הקוד שנפרס.
הבנייה עצמה עוברת, כיוון שהמהדר משווה קריאות לא מול השרשרת, אלא מול התיאור שבתוך החבילה. אי-ההתאמה בין טיפוסי החוזה אינה מתבטאת עד הפנייה האמיתית הראשונה: הקוד מפנה ל-ABI מהחבילה, והרשת מריצה את מה שנפרס.
הנתונים מקודדים לפי הסכימה הישנה, והטרנזקציה מתבטלת — או, גרוע מכך, עוברת ורושמת לא את מה שהמפתח התכוון.
שגיאת קריאה לחוזה צפה ברשת החיה וברגע הכי לא נוח: בשיא העומס, בתרחיש שכבר אושר, בקריאה שעבדה תקין עד כה. מכאן — חקירה, השוואה ידנית של ארטיפקטים ושאלה מדוע «הבנייה עוברת, אבל הקריאה נופלת».
השורש בכך שהחבילה חיה חיים נפרדים מהרשת: כתובות, טיפוסים ותיאורים מתעדכנים ביד ולפי הזיכרון. נפרק איך זה נסגר — ייצור מתוך ארטיפקטי הבנייה, קישור כתובות לרשת מסוימת ובדיקות שעוצרות את הצינור לפני הפרסום.
מה נותנת הטיפוסיות של חבילת npm עם חוזה חכם
טיפוסיות של קריאות לחוזה נשענת על עיקרון אחד: חבילת ה-npm נבנית מאותם קבצי מקור שמהם נבנה החוזה עצמו. לכל מתודה מותאמת חתימה עם טיפוסי הארגומנטים והערכים המוחזרים, ותיאור הממשק נוצר בייצור בזמן הבנייה — את ה-ABI כבר לא מתקנים ביד.
במונחים של TypeScript זהו מודול רגיל עם טיפוסים מוצהרים: קריאה עם סדר ארגומנטים מבולבל פשוט לא תיבנה.
מכאן נכנסת לפעולה בדיקת טיפוסים בזמן הבנייה. אי-התאמה בין קוד החוזה לתיאור הממשק שוברת את בניית החבילה, ולא את הטרנזקציה ברשת: השגיאה נראית על מחשב המפתח, לפני השליחה ולפני הכתיבה לבלוקצ'יין. גרסת החבילה מקושרת בקשיחות לגרסת החוזה — מבחינה טכנית אי אפשר להוציא לקוח שנבנה מול ממשק מיושן.
קיצור זמן הבנייה נותן מטמון ארטיפקטים: בתיקון של חוזה אחד נבנות מחדש רק היחידות שנגעו בהן, והשאר נלקח מהמטמון. בנייה מלאה אורכת דקות, אינקרמנטלית — עשרות שניות, וההבדל מורגש כשהחבילה נבנית מחדש על כל שינוי במאגר.
כך נשלל סוג שלם של כשלים — בגלל סנכרון ידני של תיאור הממשק והקוד. לפי ההטמעות שלנו, 8-9 אי-התאמות מתוך 10 נתפסות בבדיקת טיפוסים לפני ההרצה, ולא ברשת.
אפשרויות בנייה: ייצוא ידני מול ייצור אוטומטי
בניית חבילה עם טיפוסים ו-ABI היא בחירה בין ייצוא ידני של ארטיפקטים לייצור אוטומטי מתוצאות הקומפילציה. ההבדל כמעט אינו נראה בחוזה אחד, אך מתגלה בריליס השלישי וברשת השנייה: הסכימה הידנית מתפצלת בשקט ממה שנפרס בפועל, וצרכן החבילה לומד על כך משגיאת קריאה.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| ייצוא ידני של ארטיפקטים | חוזה אחד-שניים, ריליסים נדירים, אינטגרציות חד-פעמיות | הגרסה בחבילה מתפצלת מזו שנפרסה ברשת, אין היסטוריית שינויים, השגיאה נתפסת כבר בצד הצרכן |
| ייצור אוטומטי של טיפוסים מתוצאות הקומפילציה | כמה חוזים, ריליסים תכופים, כמה צוותים-צרכנים | נדרש סט קבוע של קבצי פלט; שינוי חתימות שובר את בניית הצרכן בלי אזהרה |
| ייצור אוטומטי עם שער ידני לפרסום | כמה רשתות, צרכנים חיצוניים, הכנה לביקורת | נדרשים השוואת כתובות וסקירת אי-התאמות ב-ABI לפני הוצאת הגרסה |
| בנייה ידנית עם בדיקת התאמה אוטומטית | החוזה מתעדכן לעיתים נדירות, אך הוא קריטי | השלבים הידניים נשארים, האוטומציה רק מאותתת על אי-התאמה |
האוטומציה מסירה שגרה, אך אינה מבטלת נקודות ביקורת: השוואת כתובות מול הסביבה, סקירת שינויים בתיאור הממשק, קיבוע הגרסה לפני ההוצאה. האפשרות הידנית מוצדקת במקום שבו החוזה מתעדכן אחת לכמה חודשים והצרכן הוא אחד — אז ייצוא הארטיפקטים זול מתחזוקת צינור בנייה רציף.
בחירת הגישה קובעת כמה עבודה ידנית תיוותר בכל ריליס ואיפה בדיוק השגיאה תגיע אל צרכן החבילה.
כיצד אנו מטמיעים: מביקורת המאגר ועד למסירה
חבילה לחוזה חכם נבנית לעיתים קרובות ביד: טיפוסים מיוצרים בסקריפט נפרד, ABI מיוצא מהארטיפקטים, והגרסה במרשם חיה בנפרד מגרסת החוזה. כעבור כמה ריליסים הטיפוסים מתפצלים מה-ABI, ואצל הצרכנים הבנייה נשברת. כך אנו הופכים זאת לתהליך משוחזר.
- ביקורת המאגר. מפרקים היכן נמצאים החוזים, במה מיוצרים הטיפוסים, מה נכנס לחבילה המפורסמת ומה מייבאים הצרכנים. בפלט — מפת אי-התאמות בין הבנייה המקומית למה שכבר פורסם.
- סכימת פרסום גרסאות. מקשרים את גרסת החבילה לגרסת החוזה ולרשת: תגיות קדם-ריליס — לרשת הבדיקות, תגיות יציבות — לרשת הראשית. ה-Changelog מתעד שינויים ב-ABI ובטיפוסים בין ההוצאות.
- הגדרת בנייה אוטומטית. קומפילציה, ייצור ABI וטיפוסים, השוואת ארטיפקטים לקבצי המקור. הבנייה רצה על כל קומיט, הפרסום — רק לפי תג, כדי שבנייני ביניים לא ייכנסו למרשם.
- בדיקת ארטיפקטים ברשת הבדיקות. פורסים את החוזה, מחברים את החבילה הבנויה כצרכן חיצוני ומריצים תרחישים: משווים את ה-ABI לקוד שנפרס, בודקים קריאות ברשת אמיתית, ולא על סטאבים.
- סכימת הוצאה ונסיגה. מפרסמים לפי תג, שומרים גרסאות ותגיות קודמות — הנסיגה הופכת להוצאה של הגרסה הקודמת, ולא לשכתוב ההיסטוריה. אצל הצרכנים נשאר מסלול עדכון צפוי.
- מסירה והדרכת הצוות. מראים כיצד להכניס תיקון בחוזה ולהוביל אותו עד לפרסום, מוסרים תיעוד על מחזור הריליס והתורנות על הבנייה — מכאן והלאה הצוות מוציא את החבילה בעצמו.
ערכת האספקה: טיפוסים, סכימות, נהלי עדכון
חוזה חכם בלי תשתית תומכת הוא קוד מקור שאיש לא יוכל לבנות כעבור חודש. לכן באספקה נכלל לא רק החוזה עצמו, אלא כל הסט שאיתו הצוות ממשיך לעבוד באופן עצמאי: טיפוסים, סכימת פריסה, מדיניות סודות ותקנון גרסאות. להלן — מה בדיוק נשאר במאגר שלכם.
- תיאורי טיפוסים וממשקים. חבילה עם טיפוסים למתודות החוזה ולאירועים שלו: ארגומנטים, מבנים, קודי שגיאה. כשהיא מחוברת לפרונטאנד ולבקאנד, היא תופסת אי-התאמת חתימות בשלב הבנייה — לפני שליחת הטרנזקציה, ולא אחריה.
- ייצור ABI וכתובות. הבנייה שולפת את ה-ABI מהארטיפקטים ומציבה את כתובות החוזים לפי רשתות, כדי שלא יתקנו אותן ביד בכל עדכון.
- סכימת פריסה. רצף שלבים עם תלויות, פרמטרי הבנאי, אתחול של חוזים קשורים ובדיקות לאחר הפרסום — לפיה הדפלוי משוחזר אחד לאחד.
- מדיניות גישה לסודות. הפרדת תפקידי החותם לרשת הבדיקות ולרשת הראשית, הנפקת מפתחות רק מכספת, רוטציה ואיסור על חדירת מפתחות לקוד וללוגים.
- תיעוד הבנייה. פקודות בנייה ובדיקות, דרישות לסביבה, סדר הקמת סטנד מקומי — מהנדס חדש מגיע לקומיט הראשון בלי התכתבות עם המחבר.
- תקנון הוצאת גרסאות. כללי מספור, מה נחשב שינוי בלתי תואם, בדיקות חובה לפני פרסום החבילה וסדר ביטול ריליס שגוי.
מקרה בוחן: אי-התאמות גרסאות בין סטנדים לרשת החיה
הפרויקט — פרוטוקול נזילות מכמה חוזים עם פרונטאנד, שירות אינדוקס ושלושה סטנדים. תיאורי החוזים והכתובות לפי רשתות נמצאו ישירות במאגר האפליקציה: עדכנו אותם ביד אחרי כל פריסה, ואת הטיפוסים לקריאות הוסיפו לפי הזיכרון.
לפני: סנכרון ידני של תיאורים
לפני ההוצאה המהנדס העתיק תיאורים מארטיפקטי הבנייה, השווה כתובות בכל רשת ותיקן את טיפוסי הקוד הקורא — 12–15 תיקונים ידניים לריליס. הוצאת גרסה ארכה 3–4 ימים, ורוב הזמן הוקדש להשוואה, ולא לשינויים.
כל ריצת אינטגרציה חמישית נפלה בגלל אי-התאמת תיאורים: בקוד נשאר קטע ממשק ישן, והקריאה יצאה עם חתימה שגויה.
אחרי: חבילה שנבנתה מהארטיפקטים
החוזים נבנים בסביבה אחודה (Hardhat), ומארטיפקטי הבנייה מיוצרת חבילת npm: טיפוסי קריאות, תיאורים וכתובות לפי רשתות. גרסת החבילה מקושרת בקשיחות לגרסת החוזים, ובצינור שלב נפרד משווה את תוכנה לבנייה טרייה ועוצר את ההוצאה בעת אי-התאמה. הסטנדים והאפליקציה מעדכנים את התלות בפקודה אחת, בלי העתקה ידנית.
- תיקונים ידניים לריליס: 12–15 → 1–2 (רק קונפיגורציית רשת).
- זמן הוצאת גרסה: 3–4 ימים → כמה שעות.
- כשלים בגלל אי-התאמת תיאורים: כל ריצה חמישית → אף אחד ברבעון של תצפיות.
יציבות הקריאות חדלה להיות תלויה במשמעת של מהנדס בודד: אי-התאמה נתפסת בבנייה, ולא בסטנד או ברשת הראשית.
במה נבדל סטנד מקומי מהרשת החיה בזמן בדיקה
סטנד מקומי עונה על השאלה «האם לוגיקת החוזה נכונה», רשת הבדיקות — «האם החוזה מתנהג באותו אופן בסביבה חיה». אלה סוגים שונים של בדיקות, ואין להחליף האחד בשני: צומת מקומי עולה תוך שניות, המצב נשמר ומתבטל, ולכן התרחישים מורצים בקבוצות — סכומי גבול, הרשאות תפקידים, סדר הקריאות.
הטיפוסיות נבדקת כאן גם כן: חבילת ה-npm המיוצרת מה-ABI מאפשרת למהדר לתפוס אי-התאמה של ארגומנטים וכתובות לפני ההרצה. אך שום ריצה מקומית לא תציג את עלות הגז האמיתית, את תור האישורים ואת ההשהיה בין שליחת הקריאה להכללתה בבלוק.
רשת הבדיקות מוסיפה את מה שאין בסטנד: צמתים ציבוריים עם מגבלות, התנהגות של חוזים ואורקלים של צד שלישי, ארגון מחדש של שרשרת הבלוקים. רק כאן רואים שהפעולה בלולאה נתקלת במגבלת גז, או שהקריאה נופלת על חוזה שהוחלף מקומית בסטאב.
שגיאות אופייניות של סביבות — אי-התאמת ארטיפקטים. מקומית מחובר מופע אחד, ברשת אחר; קובץ הטיפוסים וה-ABI נבנו מבניינים שונים, והקריאה יוצאת עם חתימה שגויה. לכן הבדיקה לפני הפרסום מתבצעת על ארטיפקטים מתואמים: ABI אחד, טיפוסים אחדים, כתובת מקובעת.
הסדר הוא כזה: ריצה מקומית כמסנן מהיר, אחר כך רשת הבדיקות, ואחר כך פרסום בדיוק של אותו בניין שעבר את הבדיקות. הארטיפקטים מיוצרים פעם אחת ומועברים הלאה — אחרת אי-התאמות בין הסביבות בלתי נמנעות.
ספקות נפוצים: טיפוסים, ארטיפקטים, הרשאות, תמיכה
ספקות בנוגע לאינטגרציה עולים בדרך כלל כשהחבילה כבר בנויה, והמאגר של הלקוח חי חיים משלו. להלן — מה שבדרך כלל מבררים לפני ההתחלה: כיצד מסתנכרנות גרסאות החבילה והחוזה הנפרס, מה לעשות עם סכימה שכבר עובדת ולמי נשארות ההרשאות.
האם החבילה תתאים לחוזה שכבר נפרס?
העטיפה נבנית סביב הכתובת וה-ABI, ולכן עבור חוזה שנפרס הטיפוסיות מיוצרת לפי הארטיפקטים שלו, והכתובת מקובעת בקונפיג הסביבה. גרסת החבילה מקושרת לטביעת האצבע של הארטיפקטים — אי-התאמה בין הקוד במאגר למה שעובד ברשת נתפסת בבנייה, ולא אחרי ההוצאה.
האם אפשר לחבר זאת למאגר הנוכחי בלי לשכתב?
כן. החבילה מותקנת כתלות רגילה, הטיפוסים נקלטים בעורך, והעטיפות מונחות מעל הקריאות הקיימות. הקוד הישן ממשיך לעבוד ומועבר לשכבה המטופסת בהדרגה, מודול אחר מודול — אין צורך לעצור את הפיתוח בזמן המיגרציה.
כיצד נשמרים הסודות והמפתחות לפריסה?
המפתחות אינם נכנסים לא למאגר ולא לארטיפקטים הבנויים. הם חיים בכספת הסודות של הסביבה, הגישה ניתנת לפי תפקידים ורק לפעולות הנדרשות, ובלוגים נשארים כתובות וטביעות אצבע של בניינים בלי נתונים רגישים.
מה נכלל במסירת התמיכה?
מוסרים את המאגר, סכימת הקונפיגים, תיאור תהליך הריליס, הבדיקות וסדר הנסיגה לגרסה הקודמת. המהנדסים שלכם מוציאים עדכונים בעצמם; אנו מתחברים כשמשתנה לוגיקת החוזה או כללי הגישה.
בואו נדון במשימה: תוכנית עבודה והערכה למאגר שלכם
איננו נותנים הערכה «לפי תחושה» — תחילה בוחנים כיצד החוזה נבנה ומתפרסם כיום. שלחו קישור למאגר וכמה נתוני פתיחה, ונחזור עם תוכנית הטמעה, סדר עבודה וגבולות ברורים: מה אנו עושים, ומה נשאר בצד שלכם.
מה נדרש להתחלה:
- קישור למאגר עם החוזים והרשאות קריאה — זה מספיק כדי לפרק את המבנה;
- כיצד מכינים כיום את ארטיפקטי הבנייה: ביד, בסקריפטים או דרך CI;
- רשימת הרשתות והסביבות שאליהן נפרסים החוזים, והאם נדרשות כתובות בתיאור הממשק;
- דרישות לטיפוסים ולפורמט תיאור הממשק — אם יש כללים פנימיים או העדפות לשמות;
- אילו בדיקות הן חובה לפני ההוצאה: בדיקות, לינטרים, אישור ידני;
- מגבלות על תלויות ומרשמים פרטיים, אם החבילה אינה לגישה ציבורית.
סדר העבודה נראה כך: פירוק המאגר והבנייה הנוכחית, אחר כך אב-טיפוס של החבילה על חוזה אחד, далее חיבור השאר, הגדרת ייצור אוטומטי של תיאור הממשק והטיפוסים, ורק אחר כך — בנייה במחזור רציף והוצאה עם ניהול גרסאות. כך אתם רואים תוצאה עובדת בשלב מוקדם ויכולים לתקן את הדרישות לפני שמשהו מקובע.
תארו את המשימה בשתיים-שלוש משפטים וצרפו קישור למאגר — נחזור עם הערכה ותוכנית.







