הסכם חוזה חכם: בד Hyperledger לעומת MultiChain לעומת Ethereum לעומת Corda

צומת המקור: 1585333

יש יותר מדרך אחת לשים קוד בבלוקצ'יין

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

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

במאמר זה, המטרה שלי היא לבחון כמה מההבדלים העיקריים בין גישות חוזים חכמים לבין הפשרות שהם מייצגים. אעשה זאת על ידי התבוננות בארבע פלטפורמות בלוקצ'יין ארגוניות פופולריות התומכות בצורה כלשהי של קוד מותאם אישית על השרשרת. ראשית, של IBM בד היפרפלגר, שמכנה את החוזים שלה "קוד שרשרת". שנית, פלטפורמת MultiChain שלנו, המציגה פילטרים חכמים בגרסה 2.0. שְׁלִישִׁי, Ethereum (וזה מורשה מִניָן ו לִנְבּוּר ספין-אוף), שהפך לפופולרי את השם "חוזה חכם". ולבסוף, R3 קורדה, המתייחסת ל"חוזים" בעסקאותיה. למרות כל הטרמינולוגיה השונה, בסופו של דבר כל אלה מתייחסים לאותו דבר - קוד ספציפי לאפליקציה המגדיר את הכללים של שרשרת.

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

יסודות Blockchain

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

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

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

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

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

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

נתחיל עם כללי העסקה, הראשון מבין האתגרים הללו, ונראה כיצד הם באים לידי ביטוי ב-Fabric, MultiChain, Ethereum ו-Corda בהתאמה.

כללי עסקה

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

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

תשומות ותפוקות

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

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

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

יש לציין שלמרות שיתוף מודל הקלט-פלט, MultiChain ו-Corda מיישמות אותו בצורה שונה מאוד. ב-MultiChain, פלטים יכולים להכיל נכסים ו/או נתונים בפורמט JSON, טקסט או בינארי. הכללים מוגדרים ב"מסנני עסקאות" או "מסנני זרם", שניתן להגדיר כך שיבדקו את כל העסקאות, או רק את אלה הכוללות נכסים מסוימים או קבוצות נתונים. לעומת זאת, "מצב" פלט של Corda מיוצג על ידי אובייקט בשפת התכנות Java או Kotlin, עם שדות נתונים מוגדרים. הכללים של קורדה מוגדרים ב"חוזים" המצורפים למדינות ספציפיות, וחוזה של מדינה מיושם רק על עסקאות המכילות את אותה מדינה בתשומות או בתפוקות שלה. זה קשור לזה של קורדה מודל נראות יוצא דופן, שבהן ניתן לראות עסקאות רק על ידי הצדדים הנגדיים שלהם או אלה שהעסקאות הבאות שלהם הן משפיעות.

חוזים והודעות

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

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

גם Fabric וגם Quorum, וריאציה על Ethereum, מסבכים את התמונה הזו בכך שהם מאפשרים לרשת להגדיר מספר "ערוצים" או "מדינות פרטיות". המטרה היא לצמצם את בעיית סודיות הבלוקצ'יין על ידי יצירת סביבות נפרדות, שכל אחת מהן גלויה רק ​​לתת-קבוצה מסוימת של משתתפים. למרות שזה נשמע מבטיח בתיאוריה, במציאות החוזים והנתונים בכל ערוץ או מדינה פרטית מבודדים מאלה שבאחרים. כתוצאה מכך, מבחינת חוזים חכמים, סביבות אלו שוות לבלוקצ'יין נפרד.

כללים לדוגמה

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

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

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

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

  1. ודא שהעסקה נחתמה על ידי השולח.
  2. בדוק שלשולח יש מספיק כסף.
  3. הפחת את הכמות המבוקשת מהשורה של השולח.
  4. הוסף את הכמות הזו לשורה של הנמען.

אם אחד מההמחאות בשני השלבים הראשונים נכשל, החוזה יבוטל ולא ישולם תשלום.

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

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

כללים מובנים

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

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

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

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

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

כללי עסקה בד MultiChain Ethereum קורדה
מספר סימוכין חוזה-הודעה פלט קלט חוזה-הודעה פלט קלט
מובנים ללא חתימה הרשאות +
נכסים + זרמים
ללא חתימה ללא חתימה

דטרמיניזם

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

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

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

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

מקורות לא-דטרמיניזם

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

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

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

ביצוע דטרמיניסטי

נתחיל עם Ethereum, מכיוון שהגישה שלו היא הכי "טהורה". חוזי Ethereum מתבטאים בפורמט ייעודי הנקרא "Ethereum bytecode", אשר מבוצע על ידי ה-Ethereum Virtual Machine ("EVM"). מתכנתים אינם כותבים bytecode ישירות, אלא יוצרים או "מקמפלים" אותו משפת תכנות דמוית JavaScript הנקראת Solidity. (שפות אחרות היו זמינות בעבר אך מאז הוצאו משימוש.) דטרמיניזם מובטח על ידי העובדה שקוד בתים של Solidity ו-Ethereum אינם יכולים לקודד שום פעולה לא דטרמיניסטית - זה כל כך פשוט.

מסנני MultiChain וחוזי Corda בוחרים בגישה שונה, על ידי התאמת שפות תכנות קיימות וסביבות זמן ריצה. MultiChain משתמש ב-JavaScript הפועל ב-Google V8 מנוע, המהווה גם את הליבה של דפדפן Chrome ופלטפורמת Node.js, אך עם מקורות לא-דטרמיניזם מושבתים. באופן דומה, Corda משתמש ב-Java or קוטלין, שניהם מורכבים ל-"Java bytecode" המופעל בתוך Java Virtual Machine ("JVM"). לעת עתה, קורדה משתמשת ב-JVM הסטנדרטי הלא דטרמיניסטי של אורקל, אך מתבצעת עבודה לשילוב גרסה דטרמיניסטית. בינתיים, מפתחי חוזי Corda חייבים לדאוג לא לאפשר אי-דטרמיניזם בקוד שלהם.

כיצד משתווה הטהרנות של Ethereum לגישה האבולוציונית של MultiChain ו-Corda? היתרון העיקרי של Ethereum הוא מזעור סיכונים - סביר להניח שמכונה וירטואלית בנויה למטרה תכיל מקור לא מכוון של אי-דטרמיניזם. אמנם ניתן לתקן כל פיקוח כזה על ידי עדכון תוכנה, אבל זה יהיה מפריע לכל שרשרת שלא התמזל מזלה להיתקל בה. אולם הבעיה של Ethereum היא שסולידיטי וה-EVM מהווים מערכת אקולוגית זעירה ומתהווה בהקשר הרחב יותר של שפות תכנות וסביבות זמן ריצה. לשם השוואה, JavaScript ו-Java הם שתי השפות המובילות ב-Github, פועלים על מיליארדי מכשירים דיגיטליים, ויש להם זמני ריצה שעברו אופטימיזציה במשך עשרות שנים. ככל הנראה זו הסיבה שהבלוקצ'יין הציבורי של Ethereum שוקל לעבור אל eWASM, מזלג דטרמיניסטי של תקן WebAssembly המתהווה.

דטרמיניזם על ידי אישור

כשזה מגיע לדטרמיניזם, Hyperledger Fabric נוקט בגישה שונה לחלוטין. ב-Fabric, כאשר צומת "לקוח" רוצה לשלוח הודעה לקוד שרשרת כלשהו, ​​הוא שולח תחילה את ההודעה הזו לכמה צמתים של "מאשר". כל אחד מהצמתים הללו מבצע את קוד השרשרת באופן עצמאי, ויוצר דעה של ההודעה השפעה במסד הנתונים של אותו chaincode. חוות דעת אלו נשלחות חזרה ללקוח בצירוף חתימה דיגיטלית המהווה "אישור" פורמלי. אם הלקוח מקבל מספיק אישורים על התוצאה המיועדת, הוא יוצר עסקה המכילה את האישורים האלה, ומשדר אותה להכללה בשרשרת.

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

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

לדטרמיניזם-לפי-הסכמה של Fabric יש מספר השלכות מעניינות. ראשית, קוד שרשרת יכול להיכתב בשפות תכנות רבות ושונות, מכיוון שאין צורך להתאים אותן לדטרמיניזם (נכון לעכשיו נתמכות Go, Java ו-JavaScript). שנית, קוד שרשרת יכול להיות מוסתר מחלק ממשתתפי הבלוקצ'יין, מכיוון שהוא צריך להתבצע רק על ידי לקוחות ומסמכים (בסיס הנתונים עצמו גלוי גלובלי). לבסוף ובעיקר, Fabric chaincode יכול לעשות דברים שאסורים בסביבות בלוקצ'יין אחרות, כמו בדיקת מזג האוויר באמצעות API אינטרנטי מקוון. במקרה הגרוע ביותר, שבו כל נותן תמיכה יקבל תשובה שונה מ-API זה, הלקוח לא יצליח להשיג מספיק אישורים עבור כל תוצאה מסוימת, ולא תתבצע עסקה. (יש לציין שחברי צוות בד עדיין להמליץ באמצעות לוגיקה דטרמיניסטית בתוך קוד שרשרת, על מנת למנוע הפתעות.)

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

דטרמיניזם בד MultiChain Ethereum קורדה
מספר סימוכין המלצות זמן ריצה מותאם VM ייעודי זמן ריצה מותאם
שפות עבור + Java + JavaScript JavaScript מוצקות Java + Kotlin
נראות קוד צדדים נגדיים +
תומכים
Blockchain Blockchain צדדים נגדיים +
תלויים
נאכף לא יש יש לא (לעת עתה)

מניעת סכסוכים

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

שני דגמים

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

למרות הדמיון הזה, חשוב להצביע על הבדל מרכזי באופן שבו MultiChain ו-Corda מונעים קונפליקטים. ב-MultiChain, כל צומת רואה כל עסקה ולכן יכול לאמת באופן עצמאי שכל פלט בילה פעם אחת בלבד. כל עסקה שמבצעת הוצאה כפולה כנגד עסקה שאושרה קודם לכן תידחה באופן מיידי ואוטומטי. לעומת זאת, בקורדה אין בלוקצ'יין עולמי, כך ש"נוטריונים" נדרשים למנוע הוצאות כפולות אלו. כל מצב פלט של Corda מוקצה לנוטריון, שעליו לחתום על כל הוצאה של עסקה על פלט זה, לאשר שלא הוצאה בעבר. משתתפי הבלוקצ'יין חייבים לסמוך על נוטריונים שימלאו אחר כלל זה ביושר, ונוטריונים זדוניים עלולים לגרום להרס כרצונם. כמו עם המלצות ב-Farric, זה "הוצאה יחידה כשירותלעיצוב יש יתרונות במונחים של סודיות אבל מציג מחדש מתווכים, בניגוד לגרעין הבלוקצ'יין. (חשוב להבהיר כי נוטרי Corda יכולים להיות מנוהלים על ידי קבוצות של משתתפים באמצעות אלגוריתם קונצנזוס, כך שעדיין ניתן להגן על שלמות הפנקס מפני שחקנים רעים בודדים).

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

תפוקות מול חוזים

עד כה ראינו שתי טכניקות שונות למניעת עסקאות סותרות - פלטי הוצאה בודדת ב-MultiChain ו-Corda, ואימות מבוסס חוזה ב-Ethereum. אז מה עדיף?

על מנת לעזור לענות על שאלה זו, הבה נבחן חשבון "1 מתוך 2 ריבוי חתימות" לדוגמה, המחזיק 100 דולר מטעם גאווין והלן, ומאפשר לכל אחד מהם להוציא את הכסף הזה באופן עצמאי. גאווין מורה לבקשתו לשלם 80 דולר לדונה, וכמה שניות לאחר מכן, הלן רוצה לשלוח 40 דולר לאדוארד. מכיוון שאין מספיק כספים עבור שני התשלומים, עסקאות אלה יתנגשו בהכרח. במקרה ששתי העסקאות ישודרו, התוצאה תיקבע לפי מי שייכנס ראשון לשרשרת. שימו לב שבניגוד לדוגמא של אליס, הקונפליקט הזה הוא מקרי, מכיוון שאף אחד לא מנסה לשבור את כללי האפליקציה - פשוט היה להם תזמון חסר מזל.

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

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

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

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

ערכות קריאה-כתיבה

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

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

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

מניעת סכסוכים בד MultiChain Ethereum קורדה
מספר סימוכין ערכות קריאה-כתיבה הוצאה בודדת בדיקות חוזה הוצאה בודדת
אימות עצמאי עצמאי עצמאי נוטריונים מהימנים
מהירות ~10 שניות (אישור) ~1 שניות (התפשטות) ~10 שניות (אישור) 0~5 שניות (נוטריון)

בחירה מורכבת

ביצירה זו, סקרנו רבות מהדרכים השונות בהן Corda, Ethereum, Fabric ו-MultiChain מתמודדות עם האתגרים המרכזיים של "חוזים חכמים", או קוד יישום המוטמע בבלוקצ'יין. ולכל פלטפורמה יש תשובות שונות לשלוש שאלות הליבה שלנו: כיצד מיוצגים כללי העסקאות? כיצד מבוצע קוד באופן דטרמיניסטי? ואיך מונעים קונפליקטים?

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

אנא פרסם הערות ב LinkedIn.

בול זמן:

עוד מ רב-שרשראות