מי שעבר על הפוסטים הקודמים כבר קצת מכיר את Payable אבל בכל זאת אחזור על הדברים ופוסט זה שכן ראיתי לנכון להקדיש פוסט שלם לPayable בגלל חשיבותה.
מהות טכנולוגיית הבלוקציין עבור איתריום(זהו קורס סולידיטי לא לשכוח) הוא נושא הטרנזקציות, ועל מנת לבצע תשלום (באיתריום), כלומר בעברה של תשלום (טרנזקציה), ובסולידיטי, ישנה הגדרה ייחודית לפונקציות שעוסקות בתשלום באיתריום, והיא Payable. וכך תוכלו לקבל תשלום באיתריום לתוך החוזה שלכם. אציג כמה דוגמאות של קוד ואז נדבר עליהם על מנת להבין איך להשתמש עם Payable:
הגדרה של פונקציית Payable
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.9; contract PayableExample { constructor() {} function deposit() payable external { } }
כך נראית הגדרתה של פונקציית Payable, סה"כ משתמשים בטייפ Payable, וכל קריאה של פונקציה זו תנסה להעביר איתריום מכתובת השולח אל חוזה זה. אבל לרוב נרצה פונקציות של Payable מעט יותר שימושיות ואז נוכל לממש משהו בסגנון הזה:
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.9; contract PayableExample { constructor() {} mapping(address => uint) balances; function deposit() payable external { // deposit sizes are restricted to 1 ether require(msg.value == 1 ether); // an address cannot deposit twice require(balances[msg.sender] == 0); balances[msg.sender] += msg.value; } }
בדוגמה הזו אפשר לראות שיש קצת לוגיקה בפונקציה שיכולה לקבל איתריום, למשל אם השולח לא יעביר ערך של 1 איתריום, הטרנזקציה תכשל והתשלום לא יעבור, אך חשוב לציין כי יהיו עלויות גז שישולמו (מצג השולח כמובן).
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.9; contract PayableExample { constructor() {} mapping(address => uint) balances; function deposit(uint256 val) payable external { require(val > 1 ether); balances[msg.sender] += msg.value; (bool success, ) = msg.sender.call{value: val}(""); require(success, "Failed to send Ether"); } }
דוגמה נוספת קשורה להעברה של סכום שמשתמש בוחר, כמו כן הפונקציה תהיה payable כפי שאנחנו כבר יודעים, ויש כעת שונה מעניינת שנראה ונכיר בהמשך שעושה שימוש בcall מתוך sender.
הגדרה של כתובת כ Address Payable
ישנה אפשרות להגדיר גם כתובת כ Payable למשל:
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.9; contract PayableExample { constructor() {} mapping(address => uint) balances; address payable public spender = payable(0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db); function doSomething() external { spender.transfer(1); } }
אפשר לראות שיש כאן דוגמה של פונקציה שאין לה שימוש כלל (כלומר אינה רושמת או קוראת או מעבירה תשלום) ובכל זאת ישנו שימוש מוזר שכזה עם הכתובת שהגדרתי כ Payable . למעשה כתובת שמוגדרת כPayable יכולה לקבל תשלום ויש לה את היכולות של transfer , send and call.
מה שיקרה למי שיריץ את הפונקציה הזו, היא תנסה להעביר 1 איתר לכתובת המוגדרת כpayable. כתובת זה למעשה יכולה לקבל העברות.
לסיכום שיעור קורס סולידיטי Payable functions
עברנו ביסודיות על ההגדרה של Payable וכן הצגנו את השימושים השונים בהגדרה זו, כמו כן יתכן שהשימוש העיקרי שתעשו יהיה בהגדרות של פונקציות כ Payable ופחות בכתובות. כמו כן הנושא הזה חוזר על עצמו בהרבה מהכתיבה שלנו בקורס זה וכמובן בדוגמאות בהמשך. בהצלחה ונתראה בשיעור הבא 🐊💕