מדוע האצלת קולות נשברת ב-DAO נייד
האצלת קולות באפליקציית DAO ניידת נשברת לא ברמת לוגיקת הספירה, אלא ברמת העברת המצב אל המכשיר. המשתמש חותם על טרנזקציה, הממשק מציג משקל הצבעה חדש, ובינתיים הרשת טרם אישרה את הפעולה.
מכאן, כל פעולה — האצלה חוזרת, החלפת נציג, ביטול — נבנית על תמונה שגויה, והאפליקציה מובילה את האדם בביטחה אל מבוי סתום.
הסיבה הנפוצה ביותר היא חוסר סנכרון בין המטמון המקומי לשרשרת. הלקוח הנייד מחזיק את התמונת המצב האחרונה הידועה של התפלגות הקולות, כדי שרשימת הנציגים תיפתח באופן מיידי, ומעדכן אותה לפי אירועים.
אם האפליקציה עברה לרקע, איבדה חיבור או פספסה בלוק, תמונת המצב מתיישנת בשקט: הממשק מצייר משקלים ישנים, והטרנזקציה יוצאת עם פרמטרים שכבר אינם רלוונטיים. המשתמש רואה דבר אחד, והרשת מבצעת דבר אחר.
קבוצת התקלות השנייה — כפילויות וטרנזקציות תקועות. הקשה כפולה על כפתור ההאצלה, שליחה חוזרת לאחר פסק זמן, הפעלה מחדש של האפליקציה ברגע ההמתנה לאישור — ובממפול מופיעות שתי פעולות עם אותה כוונה. אחת עוברת, השנייה תלויה או נדחית, ואיזון הקולות בממשק סוטה מהמצב האמיתי.
בנפרד יש להתייחס לטרנזקציה תקועה עם עמלה נמוכה מדי: היא אינה מאושרת, אך גם אינה נעלמת, וחוסמת את התור של הפעולות הבאות באותו חשבון.
המקור השלישי — אי-התאמה בין רגע החתימה לרגע הביצוע. ביניהם משתנה תקופת ההצבעה, פג תוקף סמכות הנציג או מופעל כלל המגביל את שרשרת ההאצלה. הטרנזקציה תקפה פורמלית, אך מיושמת על מצב שכבר אינו קיים.
מפרקים כיצד זה נסגר: פעולות אידמפוטנטיות, מצבי המתנה מפורשים במקום עדכון אופטימי של הממשק, ובנייה מחדש של תמונת המצב של הקולות מאירועים מאושרים, ולא מהשערות מקומיות.
מה נותנת הטמעה נכונה של האצלת הצבעות
הטמעה נכונה של האצלת הצבעות נשענת על שלושה דברים: כיצד האפליקציה מחשבת את משקל ההצבעה ברגע צילום מצב הבלוקצ'יין, כיצד היא מציגה למשתמש למי ולכמה זמן הוא מעביר את זכות ההצבעה, וכיצד היא מבטלת את ההאצלה בלי לאבד הצבעות שכבר נספרו.
אם לפחות שכבה אחת מיושמת "בעין", המשתמש רואה דבר אחד והרשת סופרת דבר אחר — והראשון שמבחין בכך אינו המפתח, אלא התמיכה.
מהירות אישור הפעולה נקבעת לא על ידי העסקה עצמה, אלא על ידי מה שקורה לפניה. כאשר האפליקציה טוענת מראש את רשימת הנציגים המעודכנת, שומרת במטמון את מצב הצילום ואינה מטלטלת את המשתמש בין שלושה מסכים בשביל חתימה אחת, האישור מסתכם בהמתנה אחת לרשת במקום כמה עוקבות. ההבדל מורגש בדיוק באינטרנט סלולרי חלש, שבו כל סנכרון מיותר הוא דקות ופעולה נטושה.
שיעור הפעולות המוצלחות עולה כאשר האפליקציה מאמתת את ההאצלה לפני השליחה: בודקת שכתובת הנציג תקינה, שהמועד לא פג, שלמשתמש יש מספיק אמצעים לעמלה, ושחתימה חוזרת לא תיצור כפילות. עסקה שנדחתה על ידי הרשת עולה למשתמש בזמן ובאמון, ולנו — בפנייה לתמיכה, היקרה מכל בדיקה מקדימה בצד הלקוח.
הפחתת מספר הפניות לתמיכה היא תוצאה ישירה של שקיפות. המשתמש צריך לראות כמה הצבעות האציל, לכמה זמן וכיצד להחזיר אותן לעצמו, בלי לקרוא תיעוד. כאשר מצב ההאצלה מוצג ביושר ומתעדכן מעצמו, השאלות "למה ההצבעה שלי לא נספרה" ו"איך לבטל" פשוט מפסיקות לעלות.
בדיוק משום כך תמיכה בהאצלה היא לא כפתור אחד, אלא צירוף של חישוב משקל, הצגת מצב וחזרה לאחור. מפרקים כיצד זה בנוי באפליקציה לנייד ומה בודקים לפני השחרור.
דרכי ספירת קולות: השוואת גישות
ספירת קולות ב-DAO נייד היא לא מכניקה אחת, אלא התפצלות למספר מודלים, והבחירה ביניהם קובעת כיצד האפליקציה תתנהג עם גידול מספר המשתתפים. להלן — אפשרויות עבודה שיישמנו, עם המגבלות הכנות של כל אחת.
| אפשרות ספירה | מתי מתאימה | מגבלות |
|---|---|---|
| האצלה ישירה לפי כתובת | קהילה קטנה, בסיס מצביעים יציב, חשוב פשטות | עם גידול מספר הנציגים מתייקר חישוב המשקלים; הקצאה מחדש ידנית בעת החלפת ארנק |
| האצלה לפי קמפיינים | ההצבעות מתנהלות בגלים, ולכל אחת הרכב משתתפים משלה | נדרשת לוגיקה נפרדת של תמונות מצב לכל קמפיין; ביקורת היסטוריה מורכבת יותר |
| תת-האצלה (שרשראות) | מבנים גדולים עם נציגים ותת-נציגים | סיכון ללולאות בשרשראות; נדרש בקרת עומק והגנה מפני מעגלים |
| היברידי: ישיר + מאגר | חלק מהקולות מוחזקים בעצמם, חלק מועברים למאגר משותף | ספירה כפולה בתמונת מצב לא מדויקת; שקיפות דורשת מסך נפרד |
האצלה ישירה לפי כתובת — האפשרות הצפויה ביותר: המשתמש ממנה נציג, המשקל מחושב מחדש בכל הצבעה. המגבלה מתגלה בקנה מידה — ככל שיש יותר קשרים, כך החישוב יקר וארוך יותר, והחלפת ארנק דורשת הקצאה מחדש ידנית.
האצלה לפי קמפיינים מסירה חלק מהעומס הזה: הקולות נקושרים להצבעה מסוימת, ולא לחשבון לתמיד. בתמורה מופיעה דרישה לתמונות מצב — יש לתעד את מצב המשקלים במועד תחילת הקמפיין, אחרת התוצאות "יזלגו" בהאצלות מאוחרות.
תת-האצלה מעניקה גמישות למבנים גדולים, אך דורשת הגנה מפני שרשראות-מעגלים והגבלת עומק. המודל ההיברידי נוח לקהילות מעורבות, אולם ספירה כפולה היא הטעות הנפוצה ביותר: ללא הפרדה ברורה בין קולות ישירים לקולות מאגר בשלב תמונת המצב, התוצאות חורגות מהציפיות.
בפועל הבחירה מצטמצמת לשלוש שאלות: כמה נציגים צפויים, באיזו תדירות משתנה הרכבם והאם נדרשת היסטוריה לצורכי ביקורת. התשובות להן הן שקובעות איזו אפשרות ספירת קולות תשמש בסיס לאפליקציה ללא שינויים בשלב הצמיחה הבא.
כיצד אנו מטמיעים מודול האצלת הצבעות
הטמעת מודול האצלת הצבעות מתחילה בביקורת: אנו בוחנים כיצד בנויים חשבונות המשתמש באפליקציה, היכן נשמרים מפתחות החתימה, ואילו רשתות וחוזים כבר מחוברים. בשלב זה חשוב להבין האם המשתמש מצביע בעצמו או מאציל את הזכות לכתובת אחרת, וכיצד הדבר בא לידי ביטוי בהיסטוריה. ללא בדיקה כזו קל לתכנן את המודול כך שיתנגש עם הלוגיקה הקיימת של הארנק.
לאחר מכן אנו בונים את סכמת ההאצלה: מי יכול לשמש כאציל, לתקופה של מה, האם ניתן לבטל את הזכות מוקדם מדי, ומה קורה בהאצלה חוזרת. בנפרד אנו מפתחים תרחישים שבהם האציל מאבד גישה או מוותר בעצמו על ההצבעות — מקרים אלו הם שלרוב שוברים את ההצבעה בקהילות אמיתיות.
- ביקורת האפליקציה הנוכחית — מנתחים חשבונות משתמש, אחסון מפתחות, רשתות וחוזים מחוברים, ומתעדים מגבלות.
- תכנון סכמת ההאצלה — מגדירים תפקידים, תקופות, כללי ביטול והעברה חוזרת של הצבעות.
- הגדרת המודול — מחברים את הלוגיקה לארנק ולחוזים, ומגדירים חתימה על פעולות ההאצלה.
- בדיקת תרחישים — מריצים העברה, ביטול, האצלה חוזרת והצבעה בשם האציל.
- בדיקה ברשת בדיקה — בודקים את התנהגות המודול ללא סיכון להצבעות ולנכסים אמיתיים.
- מסירה ותיעוד — מתארים את הסכמה, הכללים וסדר הפעולות לצוות התמיכה.
כל שלב מסתיים בבדיקה: אם תרחיש הביטול או ההאצלה החוזרת פועל באופן שגוי, אנו חוזרים לסכמה, ולא מתקנים את ההתנהגות ברמת הממשק. כך המודול נשאר צפוי הן עם גידול במספר המשתתפים והן עם החלפת אצילים.
בסיום הלקוח מקבל מודול האצלת הצבעות עובד, סכמה של האינטראקציה שלו עם הארנק והחוזים, וכן תיעוד לתמיכה. תארו את המשימה שלכם — נחזור עם הערכה ותוכנית שלבים.
מה הלקוח מקבל לידיו
אנחנו מוסרים לא "קוד עובד", אלא חבילה שלמה שלפיה מודול האצלת ההצבעות חי ומתפתח בלעדינו. כל ארטיפקט סוגר סוג אחר של שאלות: איך זה בנוי, איך בודקים, איך משנים ומה עושים בעת תקלה.
- קונפיגורציות של מודול ההאצלה — פרמטרים של הרשת, כתובות חוזים, ספי משקל הצבעה וכללי חישוב מחדש בעת החלפת נציג. מופרדים לקבצי סביבה נפרדים, כך שמעבר בין סביבת בדיקה לסביבת עבודה לא ידרוש שינוי בקוד.
- תרשימי זרימת הצבעות — איך הצבעה עוברת מהבעלים לנציג, היכן נרשם ה-snapshot, ובאיזה רגע המשקל מפסיק להיספר בעת ביטול ההאצלה. התרשים מסיר חצי מהשאלות בשיחות עם עורכי דין ומבקרים.
- מדיניות גישה ותפקידים — איזה מנהל יכול לשנות פרמטרים של האצלה, מי רק קורא, ואיך מוענקות ומבוטלות הרשאות. עם מטריצת תפקידים ויומן פעולות.
- תיעוד לאינטגרציה — תיאור המתודות, פורמטי הבקשות והתגובות, קודי שגיאה. מספיק כדי שצוות חיצוני יחבר את המודול בלי לקרוא את קוד המקור.
- נהלי תפעול — מה לעשות בעת אי-התאמה במשקל ההצבעה, איך להחזיר אחורה שינוי פרמטרים כושל, ולאן להסתכל קודם כל. עם צ'ק-ליסט לתורנות.
- מערך בדיקות — בדיקות לתרחישי האצלה וביטול, כולל מקרי קצה: הנציג עזב, המשקל השתנה בין הצבעות, האצלה כפולה.
- תיעוד מסירה — ניתוח של החלטות ארכיטקטוניות ושאלות פתוחות, כדי שההקשר לא יישאר רק בהתכתבות.
החבילה מורכבת כך שמהנדס חדש נכנס למודול דרך התיעוד, ולא דרך הסברים בעל פה. תארו את המשימה — נחזור עם הערכה ותוכנית לסביבה שלכם.
קייס: האצת האצלת הצבעות בארנק נייד
הלקוח — צוות של ארנק DAO נייד על NEAR — הגיע עם תלונה: האצלת הצבעות עבדה, אבל משתמשים הגיעו אליה לעתים רחוקות. הפעולה כללה 6 מסכים ו-4 אישורים, זמן המעבר הממוצע עמד על 3 דקות ו-40 שניות, ושיעור הניסיונות שננטשו באמצע עמד על 38%.
התמיכה קיבלה 40-60 פניות בשבוע, וכמעט כולן — "אני לא מבין למי אני מאציל" ו"ההצבעה הלכה למקום הלא נכון".
מה שינו
כתבו מחדש את הזרימה למסך אחד: בחירת נציג, גודל החלק ואישור — בתצוגה אחת עם חישוב מחדש חי של משקל ההצבעה. הוסיפו תצוגה מקדימה של ההשלכות לפני החתימה, מטמון של רשימת הנציגים עם רענון ברקע, וסטטוס ברור של הפעולה לאחר השליחה — במקום מסך המתנה עם תוצאה לא ודאית.
בנפרד סגרו סוג שגיאות שיצר את מירב הרעש: אי-התאמה בין הנציג הנבחר לבין העסקה שנחתמה בפועל. כעת פרמטרי ההאצלה נאספים במקום אחד ונבדקים לפני החתימה, ולא בדרך דרך מספר מסכים.
מה נהיה
זמן הפעולה הממוצע ירד ל-50 שניות, שיעור הניסיונות שננטשו — ל-9%. פניות לתמיכה בנושא האצלה הצטמצמו פי ארבעה, והאצלות חוזרות (החלפת נציג) גדלו פי שלושה — אנשים התחילו להשתמש בתכונה, ולא לנסות אותה פעם אחת. העומס על הרשת לא גדל: מספר העסקאות למשתמש נשאר זהה, מה שהשתנה הוא רק כמה מהן מגיעות לחתימה.
במה שונה האצלה ישירה משרשרת?
האצלה ישירה היא קשר אחד: מחזיק הטוקנים ממנה נציג, ומשקל הצבעתו עובר כולו לכתובת הזו. שרשרת נוצרת כאשר הנציג עצמו מאציל למישהו את משקלו המצטבר, וההצבעה ממשיכה לנוע בהמשך הגרף. ההבדל אינו קוסמטי: הוא קובע כיצד האפליקציה מחשבת את המשקל הסופי ברגע ההצבעה ומה קורה בעת ביטול ההאצלה.
באפשרות הישירה ספירת הקולות טריוויאלית — משקל המצביע שווה לסכום הטוקנים שהואצלו לו בתוספת היתרה שלו עצמו. החישוב מחדש מקומי, המצב מתכנס במעבר אחד, וביטול ההאצלה מחזיר את המשקל לבעלים באופן מיידי.
שרשרת דורשת מעבר על הגרף עד לכתובות הסופיות: יש למצוא את כל מי שלמעשה מצביע, ולסכום את המשקל לאורך הנתיבים. כאן מופיעים שני סיכונים הנדסיים — יצירת לולאה (A מאציל ל-B, B מאציל ל-A) ומשקל "תקוע", כאשר צומת ביניים ביטל את ההאצלה כבר לאחר תחילת ההצבעה.
בפועל הדבר משפיע על שלושה דברים. הראשון — רגע קיבוע המשקל: תמונת מצב לפני תחילת ההצבעה מונעת מניפולציות של העברת קולות לאורך השרשרת. השני — מגבלת עומק: הגבלה של 3-5 מעברים מגנה מפני מעבר אינסופי והופכת את החישוב לצפוי. השלישי — טיפול בלולאות: צומת שנקלע לטבעת מוחרג מהספירה, אחרת עסקת ההצבעה לא תסתיים.
עבור הלקוח הבחירה מצטמצמת למודל הניהול. האצלה ישירה פשוטה יותר לביקורת ומובנת יותר למשתתפים, אך אינה תומכת ב"נציג של נציגים".
שרשרת מעניקה גמישות לבעלי מניות גדולים ולנציגי הקהילה, אך דורשת לוגיקת מעבר מפורשת, הגנה מפני לולאות ותצוגה שקופה בממשק — מי עומד מאחורי מי ולאן עבר המשקל. בשני המקרים ספירת הקולות חייבת להיות דטרמיניסטית: תוצאה זהה בעת חישוב מחדש בכל צומת ברשת.
ספקות טכניים נפוצים
האצלת הצבעות היא מכניקה שבה טעות בהרשאות גישה עולה ביוקר רב ביותר: מפתח מיוצג שנפרץ מסיט את משקל ההצבעות, ועסקה בלתי הפיכה ברשת הראשית אינה מתבטלת. לכן שאלות של אבטחה, תאימות וביטול נבחנות לפני תחילת הפיתוח, ולא לאחר התקרית הראשונה.
כיצד מוגנים המפתחות והחתימות בעת האצלה?
המפתח הפרטי אינו יוצא מהמתחם המאובטח של המכשיר: החתימה נוצרת באחסון החומרה (Secure Enclave / Keystore), והאפליקציה מקבלת רק את התוצאה. הנציג מוגדר לפי כתובת, ומגבלות המשקל והתוקף נקבעות בקריאה עצמה לחוזה — אפילו בעת פגיעה במושב, התוקף לא יוכל למשוך יותר מהמותר. בנוסף, אנו מתעדים כל פעולה ושולחים התראה בעת החלפת נציג.
האם זה תואם לחוזים ולארנקים שכבר פרוסים?
כן, אם החוזה תומך בממשק האצלה תקני. אנו בודקים חתימות מתודות, סוגי ערכים מוחזרים והתנהגות בקריאה חוזרת, ואז מריצים תרחישים ברשת בדיקה עם כתובות אמיתיות. עבור ארנקים ללא תמיכה מובנית, אנו מוסיפים שכבת מתאם — המשתמש רואה מסך אישור מוכר.
מה קורה בעת ביטול עסקה?
בבלוקצ'יין ביטול אינו "מחיקה", אלא עסקה חדשה עם פעולה הפוכה. אנו מתכננים את ההאצלה כאידמפוטנטית: קריאה חוזרת עם אותם פרמטרים אינה מכפילה את המשקל, ושלילה מחזירה את ההצבעות לבעלים. אם העסקה לא עברה בגלל דלק או היפוך — המצב אינו משתנה, והאפליקציה מציגה סיבה מובנת ומציעה לנסות שוב.
כיצד אנו בודקים תקינות לפני שחרור?
אנו מכסים את החוזה והלקוח בבדיקות אוטומטיות לתרחישים: האצלה, שלילה, האצלה חוזרת, ערכי גבול של משקל ותוקף. בנפרד — בדיקה לדליפת מפתחות ולהתנהגות בעת ניתוק רשת. השחרור עובר דרך ביקורת חוזה והפעלה הדרגתית על חלק מהמשתמשים.
נדון במשימה שלכם בנושא האצלת הצבעות
האצלת הצבעות היא מכניקה שבה טעות בקונפיגורציה עולה ביוקר רב יותר מאשר במסך רגיל: משקל הצבעה שחושב באופן שגוי או מצב делегат שאבד מעוותים את תוצאת ההצבעה, ולא ניתן לבטל אותה בדיעבד.
לכן לפני ההתחלה אנחנו מפרקים את מודל ההאצלה עד לפרטים — מי מעביר למי את ההצבעה, כיצד מחושבות השרשראות, מה קורה בעת שליפה וכיצד מתנהג הממשק בעת אי-סנכרון עם הרשת.
כדי לחזור עם הערכה ותוכנית, ולא עם מילים כלליות, עלינו להבין את המשימה שלכם בנושא האצלת הצבעות באופן קונקרטי. תארו את התרחישים והמגבלות — זה מספיק כדי להעריך את ההיקף ולהציע ארכיטקטורה.
- מודל ההאצלה הנוכחי: העברת הצבעה ישירה, שרשראות делегатов או היברידי עם משקל חלקי.
- רשת ותקן: היכן מתנהלת ספירת ההצבעות, כיצד האפליקציה קוראת את המצב ומאשרת טרנזקציות.
- ארנק וחתימות: אילו אמצעי חיבור נתמכים, האם נדרשת תמיכה בארנקים חומרתיים.
- תרחישי שליפה והקצאה מחדש: כיצד ההצבעה חוזרת ל-delegate ומה רואה המשתמש באותו רגע.
- התנהגות לא מקוונת: מה מציגים בעת אובדן קשר וכיצד מסנכרנים את המצב בחזרה.
- קוד קיים: האם קיים אב-טיפוס או אפליקציה שיש לשפר ולא לכתוב מאפס.
- מגבלות בלוחות זמנים ובפלטפורמות: iOS, Android או שניהם, האם נדרשת סינכרוניות של מהדורות.
בעקבות הניתוח אנחנו חוזרים עם הערכת לוחות זמנים, תוכנית שלבים ורשימת סיכונים — מה עושים ראשון, היכן מקצים מרווח לאינטגרציה עם הרשת וכיצד בודקים את נכונות ספירת ההצבעות לפני המהדורה. תארו את המשימה — נדון בפרטים ונציע פתרון לתרחיש ההאצלה שלכם.







