ברוב הפעמים, כשאנשים מתחילים ללמוד איך לכתוב חוזים חכמים, הדבר הראשון שהם שומעים עליו הוא Solidity ו-Ethereum. גם זה היה הדבר הראשון ששמעתי עליו. זה מה שרוב ההדרכות מתמקדות בו, ומסיבה טובה. סולידיות אפשרה לכתוב תוכניות שחיות על בלוקצ'יין, ואת'ריום הפך למקום שבו אנשים רבים התחילו. אבל Solidity היא לא שפת החוזים החכמה היחידה בחוץ. ו-Ethereum הוא לא הבלוקצ'יין היחיד שתומך ביישומים מבוזרים. יש גם , קיצור של . היא נוצרה על ידי טלגרם, אך כעת היא רשת ציבורית מונעת על ידי קהילה. זה מהיר, קל משקל ומטפל בדברים קצת אחרת ממה שהיית רגיל אליו ב-Ethereum. זה כולל איך נכתבים חוזים חכמים. כשהתחלתי לחקור את התיעוד של TON, נתקלתי בארבע שפות שונות לכתיבת חוזים חכמים: . אני לא אכנס כאן לארבעה. TON The Open Network Tact, Tolk, FunC ו-Fift מדריך זה מתמקד בשפת טקט, ונראה כיצד להשתמש בה כדי לבנות חוזה הצבעה בסיסי המאפשר למשתמשים להצביע ולבדוק תוצאות על השרשרת. למה החלטתי ללמוד טקט קודם המערכת האקולוגית של TON תומכת למעשה במספר שפות, שכל אחת מהן משרתת מקרי שימוש שונים, רמות הפשטה וחוויית מפתח שונים. להלן סקירה מהירה של כל אחד מהם: היא השפה המסורתית לכתיבת חוזים חכמים של TON. זה ברמה נמוכה ונותן לך שליטה מדויקת על איך החוזה שלך עובד מתחת למכסה המנוע. זה רב עוצמה, אבל זה גם אומר שתצטרך להבין כיצד פועלת ה-TON Virtual Machine (TVM), כולל מושגים כמו מניפולציה של מחסנית, פריסת זיכרון וביצוע דטרמיניסטי. התחביר דומה במקצת ל-C, שיכול להרגיש לא מוכר אם לא עבדת עם סגנון השפה הזה בעבר. FunC משמש בדרך כלל לצד FunC. זוהי שפה מבוססת מחסנית המשמשת בעיקר לאינטראקציה ישירה עם ה-TVM ומשמשת לפריסה, ניפוי באגים וביצוע חישובים על השרשרת. בדרך כלל זו לא השפה שאתה מתחיל איתה לכתיבת חוזים חכמים מלאים, אבל היא חשובה בתהליך העבודה הכולל של הפיתוח ב-TON. Fift הוא תוספת חדשה יותר שעדיין מתפתחת. ממה שאספתי, מטרתו היא לשפר כלי עבודה ותאימות עם שפות ברמה גבוהה יותר. זה מבטיח, אבל עדיין לא מאומץ או מתועד באופן נרחב. Tolk היא שפה ברמה גבוהה שתוכננה במיוחד כדי להפוך את פיתוח חוזים חכמים של TON לנגיש וידידותי יותר למפתחים. Tact מפשט הרבה מהמורכבות ברמה נמוכה יותר ומאפשר לך להתמקד בכתיבת ההיגיון שלך בצורה נקייה וקריאה. התחביר קרוב יותר למה שהיית רואה ב-TypeScript או ב-Solidity, מה שמקל הרבה יותר להתחיל בלי צורך לצלול עמוק לתוך החלקים הפנימיים של TVM. Tact טקט מספקת נתיב מהיר יותר לבנייה ופריסה של חוזים בבלוקצ'יין TON. הבנת איך עובד טקט לפני שנתחיל לכתוב קוד, חשוב להבין כיצד בנויים חוזים חכמים של טאקט. חוזה טקט טיפוסי כולל כמה מרכיבי ליבה: חסימת - זה המקום שבו אתה מגדיר את שם החוזה שלך ומצהיר על כל משתני מצב. contract block - הוא מאתחל את משתני המצב של החוזה שלך וקובע את תנאי ההתחלה של החוזה. בלוק זה פועל פעם אחת בזמן הפריסה. init בלוקים - אלה הם כמו מאזינים לאירועים. הם מטפלים בהודעות נכנסות ומגדירים כיצד החוזה שלך מגיב אליהם. receive פונקציות של Getter ( ) – אלו הן פונקציות אופציונליות לקריאה בלבד המאפשרות למשתמשים או חוזים אחרים לבצע שאילתות על מצב החוזה מבלי לשנות אותו. get fun טאקט משתמשת בתקשורת מבוססת הודעות, וכך עובדות כל האינטראקציות ב-TON. כל חוזה מקבל הודעה ומעבד אותה בבלוק משלו. מבנה מבוסס הודעות זה עוזר לארגן את היגיון החוזה שלך בצורה מודולרית וניתנת לתחזוקה. receive בואו ליישם זאת כעת בדוגמה אמיתית על ידי בניית חוזה הצבעה פשוט. בניית חוזה ההצבעה הראשון שלך בטקט (באמצעות ה-IDE האינטרנטי של TON) בסעיף זה, נסקור כיצד ליישם מערכת הצבעה בסיסית באמצעות טאקט. חוזה הצבעה זה יאפשר למשתמשים להצביע עבור מועמדים מוגדרים מראש ועוקב אחר המספר הכולל של הקולות שכל מועמד מקבל. אנחנו נעשה הכל בתוך TON Web IDE, שהוא כלי בדפדפן שבו אתה יכול לכתוב, לבנות ולבדוק את החוזים שלך מבלי להתקין שום דבר באופן מקומי. שלב 1 - פתח את TON Web IDE עבור אל . https://ide.ton.org לחץ על . בחלון הקופץ: צור פרויקט חדש ודא שהשפה נמצאת ב- . Tact בחר כתבנית שלך. חוזה ריק תן שם לפרויקט שלך כמו . VotingContract לחץ על . + צור שלב 2 – כתיבת קוד חוזה ההצבעה לאחר יצירת הפרויקט, פתח את קובץ . תראה הגדרת לוחית: main.tact // Import the Deployable trait so the contract can be deployed easily import "@stdlib/deploy"; contract BlankContract with Deployable { init() { } } נדרש כדי שהפריסה תעבוד ואין להסיר אותו מהקוד. import "@stdlib/deploy"; הוא שם מציין המיקום. BlankContract בלוק פועל רק פעם אחת כאשר החוזה נפרס ומשמש לאתחול משתני מצב. init() עכשיו, בואו נמפה את הקוד שלנו. ראשית, נגדיר את מבנה ההודעה להצבעה: // Import the Deployable trait so the contract can be deployed easily import "@stdlib/deploy"; // Define a message structure for voting message Vote { candidate: Int as uint32; // 1 = Alice, 2 = Bob } זו הודעת ההצבעה. כאשר מישהו רוצה להצביע, הוא ישלח הודעה לחוזה הכוללת מספר: 1 עבור אליס 2 לבוב טאקט משתמש במבנה זה כדי לעבד את ההצבעה הנכנסת ולהחליט מי המועמד מקבל את הנקודה. לאחר מכן, נגדיר את החוזה שלנו ונוסיף שני משתני מדינה כדי לעקוב אחר ההצבעות של כל מועמד: ... contract VotingContract with Deployable { // State variables to track votes votesAlice: Int as uint32; votesBob: Int as uint32; בתוך החוזה, הגדרנו שני משתנים: : מאחסן את מספר הקולות שאליס מקבלת. votesAlice : מאחסן את מספר ההצבעות שבוב מקבל. votesBob כעת נאתחל את ספירת ההצבעות הללו לאפס בתוך בלוק כדי להגדיר את מצב ההתחלה של החוזה כאשר הוא ייפרס לראשונה. init init() { self.votesAlice = 0; self.votesBob = 0; } בלוק פועל , ממש כאשר החוזה נפרס והוא מגדיר את שתי ספירת ההצבעות לאפס. init פעם אחת בלבד עכשיו מגיע ההיגיון. כאשר נשלחת הצבעה, אנו רוצים שהחוזה יבדוק למי מיועדת ההצבעה ויגדיל את ספירת הקולות הנכונה. // Handle vote messages receive(msg: Vote) { if (msg.candidate == 1) { self.votesAlice += 1; } else if (msg.candidate == 2) { self.votesBob += 1; } } אז כשמתקבלת הצבעה: אם הוא 1, אנו מוסיפים 1+ ל- msg.candidate votesAlice אם הוא 2, אנו מוסיפים 1+ ל- msg.candidate votesBob לבסוף, ניצור פונקציות משבר כדי לאפשר לכל אחד לשאול את ספירת הקולות עבור כל מועמד מבלי לשנות את מצב החוזה. // Getter for Alice's votes get fun getVotesForAlice(): Int { return self.votesAlice; } // Getter for Bob's votes get fun getVotesForBob(): Int { return self.votesBob; } } שתי פונקציות המשבר הללו מאפשרות לנו לבדוק את מספר הקולות שכל מועמד קיבל מבלי לשנות שום דבר בחוזה. זו פעולה לקריאה בלבד. להלן קוד חוזה ההצבעה המלא: import "@stdlib/deploy"; // Define a message structure for voting message Vote { candidate: Int as uint32; // 1 = Alice, 2 = Bob } contract VotingContract with Deployable { // State variables to track votes votesAlice: Int as uint32; votesBob: Int as uint32; init() { self.votesAlice = 0; self.votesBob = 0; } // Handle vote messages receive(msg: Vote) { if (msg.candidate == 1) { self.votesAlice += 1; } else if (msg.candidate == 2) { self.votesBob += 1; } } // Getter for Alice's votes get fun getVotesForAlice(): Int { return self.votesAlice; } // Getter for Bob's votes get fun getVotesForBob(): Int { return self.votesBob; } } שלב 4 - בנה ופריסה של החוזה בסרגל הצד השמאלי, לחץ על Build & Deploy תחת , ודא ש- נבחרה. סביבה Sandbox ודא ש- נבחר ולחץ על . זה ירכיב את החוזה שלך ויבדוק אם יש שגיאות תחביר או בעיות בקוד שלך. main.tact Build לאחר מכן, ודא נבחר בתפריט הנפתח מכיוון שזהו החוזה האמיתי שלך, לא מציין המיקום המוגדר כברירת מחדל. אם אינך רואה אותו, הקש כדי לשמור את הקובץ שלך כך שה-IDE יוכל לזהות את החוזה המעודכן. שחוזה הצבעה Ctrl + S לאחר מכן לחץ על . אם הכל עובד כשורה, תראה הודעת אישור ביומנים המראה שהחוזה שלך נפרס בהצלחה ב-Sandbox. ReDeploy שלב 5 - אינטראקציה עם החוזה לאחר הפריסה, גלול מטה ותראה שני חלקים: , Getters: getVotesForAlice getVotesForBob כונסים: Vote בקטע , הזן בשדה הקלט ולחץ על זה עתה הצבעת לאליס! אתה יכול לחזור על זה כדי להצביע יותר. להצבעה: הצבעה 1 candidate שלח. : לחץ על תחת ובדוק את לוח כדי לראות את ספירת הקולות כדי לבדוק את ספירת הקולות התקשר getVotesForAlice היומנים עשה את אותו הדבר עבור בוב על ידי שליחת בשדה , ולאחר מכן סמן 2 candidate getVotesForBob בהרצת המבחן שלי, הצבעתי לאליס ולבוב , ופונקציות ה-Gutter הראו בדיוק את זה. 9 פעמים 6 פעמים 💭 מחשבות אחרונות: המשיכו לבנות, המשיכו לחקור 🙌 מזל טוב אם קראתם עד הסוף! כעת, לאחר שראית כיצד עובד חוזה הצבעה פשוט ב-Tact, עשית את הצעד הראשון שלך לפיתוח חוזים חכמים ב-TON. חוזה זה עשוי להיות בסיסי, אך המבנה והמושגים חלים גם על לוגיקה מורכבת יותר. אם אתה רוצה להמשיך להתנסות, נסה להאריך את החוזה הזה או לחקור תבניות אחרות שנבנו מראש מ- . ה-TON Web IDE גם מקל על ניסוי מקרי שימוש שונים והוא מגיע גם עם תבניות כדי לעזור לך לבנות וללמוד מהר יותר. https://tact-by-example.org/all אז קדימה, לשנות, לבדוק, לבנות משהו טוב יותר.