קודקודייל
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
קודקודייל
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
ראשי ♦ בלוקציין ♦ קורס סולידיטי – חלק ראשון – Functions Types

קורס סולידיטי – חלק ראשון – Functions Types

וינר יאיר 14 בינואר 2023 אין תגובות

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

הגדרות בסיסיות לפונקציות בסולידיטי

נתחיל מלהתבונן בדוגמה הראשונה והפשוטה הבאה של פונקציה:

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.9;

contract FunctionsTypes { 
    uint favNumber = 10;

    constructor() {
    }

    function getFaveNumber(uint x) external pure returns(uint) {
        return x;
    }
}

זוהי דוגמה פשוטה של פונקציה ונעבור בה על המשתנים השונים המגדירים פונקציה, למשל:

כל פונקציה מוגדרת בתוך contract , ומתחילה במילה function. לאחר מכן שם הפונקציה (כרצונכם, רק להקפיד על camel case) . לאחר מכן המשתנים של הפונקציה (אם יש) , הכוונה בתוך הסוגריים העגולים , יגיעו המשתנים שהפונקציה מקבלת, וגם להם יינתנו ההגדרות המתאימות , למשל במקרה שלנו uint, וגם יכול להיות הגדרה של סוג המידע כפי שדיברנו בפוסט קורס סולידיטי – חלק ראשון – memory, calldata and storage .

לאחר מכן תגיע הגדרה חשובה (בדומה ל access modifiers אבל מעט יותר משוכלל הייתי אומר – מה שנקרא גם visibility modifiers). אפשר לראות בדוגמה את הביטוי external אך יש 4 אפשרויות שונות:

  1. external – הגדרה זו אחת החשובות והשימושיות ביותר, מאפשרת שימוש מחוץ לחוזה (ואין אפשרות לשימוש בתוך החוזה) כמו כן חוזים וכתובות אחרים כן יכולים לגשת לפונקציה זו.
  2. internal – פונקציה בעלת הגדרה זו תהיה זמינה רק לטובת החוזה שבה הוגדרה אך כן תהיה גם זמינה מחוזים אחרים שהם יורשים (inherit) של חוזה זה. הגדרה זו דומה לprivate רק שזמינה גם לחוזים יורשים של חוזה זה.
  3. public – כל אחד יכול לגשת לפונקציה זו ולעשות בה שימוש כולל החוזה עצמו.
  4. private – פונקציה בעלת הגדרה זו תהיה זמינה רק לשימוש החוזה בלבד. למשל איזו פונקציית util שנעשה בה שימוש בחוזה זה בלבד ושום שימוש חיצוני לא יוכל לגשת אליה. לפעמים תראו כי משתמשים בקונבנציה nameOfFunction_ בפונקציות אלו. כמו כן לאחר deploy לא תמצאו את הפונקציה זמינה כמובן.

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

ההבדל בין external and public

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

שימוש בpublic יעלה לכם יותר גז , מכוון שכל מידע מועתק מועתק ל memory בעת שימוש ב public ושימוש עם בexternal קורא את המידע שנשמר כ calldata ולכן שימוש הרבה יותר יעיל עם external.

להלן דוגמה דיי מוכר בדיונים השונים בין שני הגדרות אלו:

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.9;

contract Test {
    function test(uint[20] a) public pure returns (uint){  //  496 gas
         return a[10]*2;
    }

    function test2(uint[20] a) external pure returns (uint){  //  261 gas
         return a[10]*2;
    }
}

אפשר לראות כי בדוגמה הזו את ההבדלים בין עלויות הגז. מכוון שמערך a מועתק ישירות לmemory . כמו כן אם תגדירו את המערך להיות calldata מצבכם יהיה יותר טוב. אך עדיין העתקה תתקיים ועדיין מחיר הגז יהיה גבוה.

הגדרת הפונקציה

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

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.9;


contract Test {
     uint constant FAV_NUMBER = 10;
     uint s_value; 
     constructor() {}

     function getValue() external view returns(uint) {
          return s_value;
     } 
  
     function setValue() external {
          s_value = 2;
     }
}
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.9;


contract Test {
     uint constant FAV_NUMBER = 10;
     uint s_value; 
     constructor() {}

     function getValue() external pure returns(uint) {
          return FAV_NUMBER;
     } 
  
     function setValue() external {
          s_value = 2;
     }
}

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

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

שימוש עם רמיקס:

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

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

הגדרת תשובת הפונקציה

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

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.9;


contract Test {
     uint constant FAV_NUMBER = 10;
     uint s_value; 
     constructor() {}

 	 function testReturns(uint[20] calldata a) external pure returns (uint) {
          return a.length;
     }
}  

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

פונקציה מסוג payable

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

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.9;


contract Test {
     uint constant FAV_NUMBER = 10;
     uint s_value; 
     constructor() {}
  
     function deposit() payable external {
         require(msg.value == 1 ether);
     }
}

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

שימוש עם רמיקס: פונקציות payable יהיו בצבע אדום.

סיכום חלק ראשון – Functions Types בקורס סולידיטי

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

בהצלחה! 🐊

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

פוסטים קשורים:

remix-קורס-סולידיטיקורס סולידיטי – חלק ראשון – constant, immutable remix-קורס-סולידיטיקורס סולידיטי – חלק ראשון – basic types remix-קורס-סולידיטיקורס סולידיטי – חלק ראשון – memory, calldata and storage remix-קורס-סולידיטיקורס סולידיטי – חלק ראשון – remix
blockchain solidity מפתח בלוקציין מתכנת בלוקציין סולידיטי קורס בלוקציין קורס סולידיטי

אודות המחבר

יאיר וינר להציג את כל הפוסטים של וינר יאיר


« פוסט קודם
פוסט הבא »

השארת תגובה

ביטול

חיפוש באתר
בחירת העורכים
29 בדצמבר 2023 עידן יצחקי

שדה טקסט עשיר עם תמונות

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

1 באוקטובר 2021 עידן יצחקי

איך למשוך דינמית favicon של אתרים אחרים ב-JS

בפוסט זה נראה איך אפשר על פי לינקים בדף למשוך את ה-favicon מהדומיין שלהם באופן דינמי, בדיקה של תקינות התמונה

פופולרי
Javascript functions – היכרות עם סוגי פונקציות
Javascript
21 בדצמבר 2024 אין תגובות
Nested routing in angular standalone component
Typescript
15 בנובמבר 2024 תגובה אחת
בחרו לפי תגיות
angular blockchain css ethers express front-end fullstack GQL html javascript next js nextjs nodejs react hooks reactjs solidity webgl אנגולר בלוקציין וורדפרס לימודי אנגולר לימודי וורדפרס לימוד ריאקט מדריך front-end מדריך GQL מדריך אנגולר מדריך וורדפרס מדריך חינם react מדריך ריאקט מפתח בלוק מפתח בלוקציין מתכנת front-end מתכנת בלוקציין מתכנת פרונט סולידיטי קורס front end קורס fullstack קורס nextjs קורס אנגולר קורס בלוקציין קורס בלוקציין בחינם קורס סולידיטי קורס ריאקט קורס תכנות קורס תכנות בחינם
סינון על פי קטגוריות
CSS fullstack HTML IIS Javascript nodeJs SEO Typescript אנגולר בלוקציין בניית אתרים וורדפרס חיפוש עבודה כלים נוספים כללי נגישות קורסים ריאקט תלת מימד תקלות ופתרונות
צור קשר
כל הזכויות שמורות לקודקודייל
ליצירת קשר: @ קודקודייל
גלילה לראש העמוד