Solidity Cheat Sheet: דף עזר מהיר
מבנה חוזה
כל קובץ מתחיל ברישיון וב-pragma; חוזה הוא יחידת הפריסה.
| תחביר | משמעות |
|---|---|
// SPDX-License-Identifier: MIT | הערת רישיון שהקומפיילר מצפה לה בשורה 1 |
pragma solidity ^0.8.0; | גרסת הקומפיילר שעבורה נכתב הקובץ |
contract Counter { ... } | הגדרת חוזה (מצב + פונקציות) |
constructor(uint start) { count = start; } | רץ פעם אחת, בזמן הפריסה |
import "./Token.sol"; | ייבוא קובץ אחר |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ייבוא חבילת ספרייה |
interface IToken { function balanceOf(address a) external view returns (uint); } | הגדרת ממשק (בלי מימוש) |
library Math { function min(uint a, uint b) internal pure returns (uint) { ... } } | ספרייה של פונקציות לשימוש חוזר |
טיפוסי ערך
למספרים שלמים יש גודל קבוע ואין להם חלק עשרוני; גרסה 0.8 מבטלת את הפעולה בגלישה.
| טיפוס | מה הוא מכיל |
|---|---|
uint256 / uint | מספר שלם בלי סימן, מ-0 עד 2^256-1 (uint הוא uint256) |
uint8, uint16, ... uint128 | מספרים שלמים קטנים יותר בלי סימן, בקפיצות של 8 ביט |
int256 / int | מספר שלם עם סימן (מותר שלילי) |
bool | true או false |
address | כתובת של חשבון או חוזה בגודל 20 בתים |
address payable | כתובת שיכולה לקבל Ether דרך transfer/send |
bytes32, bytes1... | מערכי בתים בגודל קבוע |
enum Status { Open, Closed } | קבוצה של קבועים עם שמות, שנשמרת כ-uint8 |
1 ether, 1 gwei, 1 wei | יחידות Ether: 1 ether = 10^18 wei |
1 days, 2 hours, 30 minutes | יחידות זמן, בשניות |
טיפוסי הפניה ומיקום נתונים
מערכים, מחרוזות, bytes, structs ו-mappings נמצאים ב-storage, ב-memory או ב-calldata.
| תחביר | משמעות |
|---|---|
string memory name | מחרוזת UTF-8 דינמית (עותק זמני) |
bytes memory data | מערך בתים דינמי |
uint[] public scores; | מערך דינמי ב-storage |
uint[3] fixed; | מערך בגודל קבוע של 3 |
uint[] memory tmp = new uint[](5); | הקצאת מערך ב-memory |
scores.push(42); | הוספה למערך ב-storage |
scores.pop(); | הסרת האיבר האחרון |
scores.length | מספר האיברים |
storage | נשמר לצמיתות, על השרשרת, יקר לכתיבה |
memory | זמני, קיים לאורך קריאה אחת |
calldata | קלט לקריאה בלבד של פונקציה חיצונית, הזול ביותר |
Mappings ו-structs
mapping הוא טבלת גיבוב בלי אורך ובלי אפשרות מעבר על איברים; struct מקבץ שדות.
| תחביר | משמעות |
|---|---|
mapping(address => uint) public balances; | מאגר מפתח וערך, כל מפתח קיים (ברירת מחדל 0) |
balances[msg.sender] += 1; | קריאה/כתיבה לפי מפתח |
mapping(address => mapping(address => uint)) allowance; | mapping מקונן |
struct User { string name; uint age; bool active; } | הגדרת struct |
User memory u = User("Ada", 36, true); | יצירת struct ב-memory |
User memory u = User({name: "Ada", age: 36, active: true}); | יצירה עם שמות שדות |
users[msg.sender] = u; | שמירת struct ב-mapping |
users[msg.sender].age = 37; | עדכון שדה אחד ב-storage |
delete users[msg.sender]; | איפוס לערכי ברירת המחדל |
פונקציות ונראות
כל פונקציה מציינת מי יכול לקרוא לה והאם היא קוראת או כותבת מצב.
| תחביר | משמעות |
|---|---|
function add(uint a, uint b) public pure returns (uint) { return a + b; } | פונקציה עם פרמטרים וערך מוחזר |
public | ניתנת לקריאה מכל מקום (מבפנים ומבחוץ) |
external | ניתנת לקריאה רק מחוץ לחוזה |
internal | החוזה הזה וחוזים שיורשים ממנו |
private | החוזה הזה בלבד |
view | קוראת מצב, אף פעם לא כותבת אותו |
pure | לא קוראת מצב בכלל |
payable | יכולה לקבל Ether עם הקריאה |
returns (uint sum, bool ok) | כמה ערכים מוחזרים עם שמות |
(uint s, bool ok) = f(); | פירוק של כמה ערכים מוחזרים |
uint public count; | משתנה מצב ציבורי מקבל getter אוטומטי count() |
Modifiers, קבועים וירושה
שימוש חוזר בבדיקות עם modifiers; קיבוע ערכים עם constant ו-immutable.
| תחביר | משמעות |
|---|---|
modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; } | הגדרת modifier (_ = הרצת גוף הפונקציה) |
function withdraw() public onlyOwner { ... } | החלת modifier |
uint public constant MAX = 100; | קבוע בזמן קומפילציה |
address public immutable owner; | נקבע פעם אחת בבנאי, ואז קבוע |
contract Token is ERC20, Ownable { ... } | ירושה מחוזים אחרים |
function f() public virtual { ... } | אפשור דריסה |
function f() public override { ... } | דריסת פונקציה של ההורה |
super.f(); | קריאה למימוש של ההורה |
abstract contract Base { function f() public virtual; } | חוזה עם פונקציות שלא מומשו |
בקרת זרימה
הפקודות הרגילות ממשפחת C; אין switch, ולולאות עולות gas על כל איטרציה.
| תחביר | משמעות |
|---|---|
if (x > 5) { ... } else if (x > 2) { ... } else { ... } | הסתעפויות מותנות |
for (uint i = 0; i < n; i++) { ... } | לולאה עם מונה |
while (x < 10) { x++; } | לולאה כל עוד תנאי מתקיים |
do { ... } while (cond); | רצה לפחות פעם אחת |
break; / continue; | יציאה מהלולאה / דילוג לאיטרציה הבאה |
x > 0 ? a : b | ביטוי טרנרי |
a / b | חילוק שלמים (השארית נזרקת) |
a % b | שארית |
a ** 2 | חזקה |
unchecked { x++; } | דילוג על בדיקות גלישה (חוסך gas, השתמשו בזהירות) |
שגיאות: require, revert, assert
בדיקה שנכשלה מבטלת את כל הטרנזקציה ומחזירה את ה-gas שלא נוצל.
| תחביר | משמעות |
|---|---|
require(amount > 0, "Amount must be positive"); | אימות קלט או מצב; ביטול עם הודעה |
revert("Not allowed"); | ביטול ללא תנאי |
error Insufficient(uint available, uint requested); | הגדרת שגיאה מותאמת (זולה יותר ממחרוזות) |
revert Insufficient(balance, amount); | ביטול עם שגיאה מותאמת |
assert(total == a + b); | בדיקת אינווריאנט שאסור לו להיכשל אף פעם |
try token.transfer(to, amt) returns (bool ok) { ... } catch { ... } | טיפול בקריאה חיצונית שנכשלה |
Events
Events כותבים לוגים שאפליקציות מחוץ לשרשרת יכולות להירשם אליהם; חוזים לא יכולים לקרוא אותם.
| תחביר | משמעות |
|---|---|
event Transfer(address indexed from, address indexed to, uint value); | הגדרת event |
emit Transfer(msg.sender, to, amount); | שליחתו (emit) |
indexed | פרמטר שאפשר לסנן לפיו (עד 3 לכל event) |
event Log(string message); | אפשר לתעד כל טיפוס ABI |
Ether, כתובות ומשתנים גלובליים
ההקשר של הטרנזקציה מגיע מ-msg, block ו-tx.
| תחביר | משמעות |
|---|---|
msg.sender | הכתובת שקראה לפונקציה הזו |
msg.value | Wei שנשלח עם הקריאה (דורש payable) |
block.timestamp | זמן הבלוק הנוכחי (שניות מאז ה-epoch) |
block.number | גובה הבלוק הנוכחי |
tx.origin | החשבון החיצוני שהתחיל את הטרנזקציה (הימנעו משימוש בו לאימות הרשאות) |
address(this).balance | יתרת ה-Ether של החוזה הזה |
payable(to).transfer(1 ether); | שליחת Ether, מבטלת בכישלון |
(bool ok, ) = to.call{value: amt}(""); | שליחה ברמה נמוכה, מחזירה דגל הצלחה |
receive() external payable {} | רצה בהעברת Ether פשוטה |
fallback() external payable {} | רצה כשאף פונקציה לא מתאימה |
keccak256(abi.encodePacked(a, b)) | גיבוב ערכים |
abi.encode(x), abi.decode(data, (uint)) | קידוד / פענוח נתוני ABI |
כל רכיבי התחביר של Solidity שאתם צריכים, בעמוד אחד. ה-Solidity cheat sheet הזה הוא דף עזר מהיר לשפת החוזים החכמים של Ethereum ושל כל רשת EVM: הגדרת חוזה, בחירת טיפוסים, שמירת נתונים ב-mappings וב-structs, כתיבת פונקציות עם הנראות וה-mutability הנכונות, והגנה עליהן עם require, modifiers ו-events.
התחביר כאן הוא של Solidity 0.8, שבודקת גלישה אריתמטית כברירת מחדל ועובדת עם Remix, Hardhat ו-Foundry. העתיקו את מה שאתם צריכים, או נסו בזמן אמת בעורך האונליין של Solidity: כתבו חוזה, קמפלו אותו והריצו אותו על EVM בדפדפן.