پرش به محتوای اصلی
Change page

زبان های قرارداد هوشمند

یکی از جنبه‌های مهم در مورد اتریوم این است که قراردادهای هوشمند می‌توانند با استفاده از زبان‌های نسبتاً مناسب برای توسعه‌دهندگان برنامه‌نویسی شوند. اگر با پایتون و یا هر زبان براکت کرلی(opens in a new tab) دیگر تجربه دارید، می توانید یک زبان با ترکیب مشابه را پیدا کنید.

دو زبان فعال و نگهداری شده عبارتند از:

  • Solidity
  • Vyper

Remix IDE یک محیط توسعه جامع برای ایجاد و تست قراردادها در سالیدیتی و وایپر فراهم می‌کند. برای شروع کدنویسی، محیط توسعه Remix IDE(opens in a new tab) درون مرورگر را امتحان کنید.

توسعه‌دهندگان با تجربه‌تر ممکن است بخواهند از Yul یک زبان میانی برای ماشین مجازی اتریوم، یا Yul+ افزونه‌ای برای Yul استفاده کنند.

اگر کنجکاو هستید و دوست دارید زبان‌های جدیدی را آزمایش کنید که هنوز در حال توسعه هستند، می‌توانید با Fe، یک زبان قرارداد هوشمند نوظهور که در حال حاضر هنوز در مراحل ابتدایی خود است، آزمایش کنید.

پیش‌نیازها

دانش قبلی از زبان های برنامه نویسی، به ویژه جاوا اسکریپت یا پایتون، می تواند به شما کمک کند تفاوت زبان های قرارداد هوشمند را درک کنید. ما همچنین توصیه می کنیم قبل از اینکه به مقایسه عمیق زبان‌ها بپردازید، قراردادهای هوشمند را به عنوان یک مفهوم درک کنید. معرفی قراردادهای هوشمند.

Solidity

  • زبان شی‌گرا و سطح بالا برای اجرای قراردادهای هوشمند.
  • زبان براکتی کرلی که عمیق‌ترین تأثیر را از C++ گرفته است.
  • استاتیک تایپ (نوع متغیر در زمان کامپایل مشخص است).
  • موارد زیر را پشتیبانی می‌کند:
    • ارث‌بری (شما می‌توانید دیگر قراردادها را بسط دهید).
    • کتابخانه ها (شما می توانید کدهای قابل استفاده مجدد ایجاد کنید که می توانید آنها را از قراردادهای مختلف فراخوانی کنید - مانند توابع استاتیک در یک کلاس ثابت در سایر زبان های برنامه نویسی شی گرا).
    • انواع پیچیده‌ مشخص‌شده توسط کاربر.

قرارداد نمونه

1// SPDX-License-Identifier: GPL-3.0
2pragma solidity >= 0.7.0;
3
4contract Coin {
5 // The keyword "public" makes variables
6 // accessible from other contracts
7 address public minter;
8 mapping (address => uint) public balances;
9
10 // Events allow clients to react to specific
11 // contract changes you declare
12 event Sent(address from, address to, uint amount);
13
14 // Constructor code is only run when the contract
15 // is created
16 constructor() {
17 minter = msg.sender;
18 }
19
20 // Sends an amount of newly created coins to an address
21 // Can only be called by the contract creator
22 function mint(address receiver, uint amount) public {
23 require(msg.sender == minter);
24 require(amount < 1e60);
25 balances[receiver] += amount;
26 }
27
28 // Sends an amount of existing coins
29 // from any caller to an address
30 function send(address receiver, uint amount) public {
31 require(amount <= balances[msg.sender], "Insufficient balance.");
32 balances[msg.sender] -= amount;
33 balances[receiver] += amount;
34 emit Sent(msg.sender, receiver, amount);
35 }
36}
نمایش همه
کپی

این مثال باید به شما این حس را بدهد که سینتکس قرارداد Solidity چگونه است. برای جزئیات بیشتر در مورد توابع و متغیرها مستندات را مشاهده کنید(opens in a new tab).

Vyper

  • زبان برنامه نویسی پایتونیک
  • تایپ کردن قوی
  • کد کامپایلر کوچک و قابل فهم
  • تولید بایت کد کارآمد
  • عمدا دارای ویژگی های کمتری نسبت به Solidity با هدف ایمن تر کردن قراردادها و تسهیل حسابرسی است. Vyper موارد زیر را پشتیبانی نمی کند:
    • اصلاح‌کننده‌ها
    • ارث‌بری
    • اسمبلی درخط
    • اضافه بار تابع
    • اضافه باز اپراتور
    • فراخوانی بازگشتی
    • لوپ‌های طول بی‌نهایت
    • نقاط ثابت دوتایی

برای اطلاعات بیشتر منطق Vyper را مطالعه کنید(opens in a new tab).

مثال

1# Open Auction
2
3# Auction params
4# Beneficiary receives money from the highest bidder
5beneficiary: public(address)
6auctionStart: public(uint256)
7auctionEnd: public(uint256)
8
9# Current state of auction
10highestBidder: public(address)
11highestBid: public(uint256)
12
13# Set to true at the end, disallows any change
14ended: public(bool)
15
16# Keep track of refunded bids so we can follow the withdraw pattern
17pendingReturns: public(HashMap[address, uint256])
18
19# Create a simple auction with `_bidding_time`
20# seconds bidding time on behalf of the
21# beneficiary address `_beneficiary`.
22@external
23def __init__(_beneficiary: address, _bidding_time: uint256):
24 self.beneficiary = _beneficiary
25 self.auctionStart = block.timestamp
26 self.auctionEnd = self.auctionStart + _bidding_time
27
28# Bid on the auction with the value sent
29# together with this transaction.
30# The value will only be refunded if the
31# auction is not won.
32@external
33@payable
34def bid():
35 # Check if bidding period is over.
36 assert block.timestamp < self.auctionEnd
37 # Check if bid is high enough
38 assert msg.value > self.highestBid
39 # Track the refund for the previous high bidder
40 self.pendingReturns[self.highestBidder] += self.highestBid
41 # Track new high bid
42 self.highestBidder = msg.sender
43 self.highestBid = msg.value
44
45# Withdraw a previously refunded bid. The withdraw pattern is
46# used here to avoid a security issue. If refunds were directly
47# sent as part of bid(), a malicious bidding contract could block
48# those refunds and thus block new higher bids from coming in.
49@external
50def withdraw():
51 pending_amount: uint256 = self.pendingReturns[msg.sender]
52 self.pendingReturns[msg.sender] = 0
53 send(msg.sender, pending_amount)
54
55# End the auction and send the highest bid
56# to the beneficiary.
57@external
58def endAuction():
59 # It is a good guideline to structure functions that interact
60 # with other contracts (i.e. they call functions or send ether)
61 # into three phases:
62 # 1. checking conditions
63 # 2. performing actions (potentially changing conditions)
64 # 3. interacting with other contracts
65 # If these phases are mixed up, the other contract could call
66 # back into the current contract and modify the state or cause
67 # effects (ether payout) to be performed multiple times.
68 # If functions called internally include interaction with external
69 # contracts, they also have to be considered interaction with
70 # external contracts.
71
72 # 1. Conditions
73 # Check if auction endtime has been reached
74 assert block.timestamp >= self.auctionEnd
75 # Check if this function has already been called
76 assert not self.ended
77
78 # 2. Effects
79 self.ended = True
80
81 # 3. Interaction
82 send(self.beneficiary, self.highestBid)
نمایش همه
کپی

این مثال باید به شما این حس را بدهد که سینتکس قرارداد Vyper چگونه است. برای جزئیات بیشتر در مورد توابع و متغیرها مستندات را مشاهده کنید(opens in a new tab).

Yul و +Yul

اگر به تازگی وارد اتریوم شده اید و هنوز هیچ کدنویسی با زبان های قرارداد هوشمند انجام نداده اید، توصیه می کنیم با Solidity یا Vyper شروع کنید. فقط زمانی به Yul یا +Yul نگاه کنید که با بهترین روش‌های امنیتی قرارداد هوشمند و ویژگی‌های کار با EVM آشنا شدید.

Yul

+Yul

  • یک برنامه افزودنی سطح پایین و بسیار کارآمد برای Yul.
  • در ابتدا برای یک قرارداد رول آپ خوش بینانه طراحی شد.
  • +Yul را می‌توان به‌عنوان پیشنهاد ارتقای آزمایشی Yul در نظر گرفت و ویژگی‌های جدیدی را به آن اضافه کرد.

قرارداد نمونه

مثال ساده زیر یک تابع توان را پیاده‌سازی می کند. می‌تواند با استفاده از solc --strict-assembly --bin input.yul کامپایل شود. مثال باید در فایل input.yul ذخیره شود.

1{
2 function power(base, exponent) -> result
3 {
4 switch exponent
5 case 0 { result := 1 }
6 case 1 { result := base }
7 default
8 {
9 result := power(mul(base, base), div(exponent, 2))
10 if mod(exponent, 2) { result := mul(base, result) }
11 }
12 }
13 let res := power(calldataload(0), calldataload(32))
14 mstore(0, res)
15 return(0, 32)
16}
نمایش همه

اگر قبلاً در قراردادهای هوشمند تجربه خوبی دارید، پیاده‌سازی کامل ERC20 در Yul را می‌توانید در اینجا(opens in a new tab) پیدا کنید.

Fe

  • زبان تایپ ایستا برای ماشین مجازی اتریوم (EVM).
  • با الهام از پایتون و Rust.
  • هدف این است که یادگیری آسان باشد -- حتی برای توسعه دهندگانی که به تازگی وارد اکوسیستم اتریوم شده اند.
  • توسعه Fe هنوز در مراحل اولیه خود است، این زبان در ژانویه 2021 انتشار نسخه آلفای خود را داشت.

قرارداد نمونه

در زیر یک قرارداد ساده اجرا شده در Fe است.

1type BookMsg = bytes[100]
2
3contract GuestBook:
4 pub guest_book: map<address, BookMsg>
5
6 event Signed:
7 book_msg: BookMsg
8
9 pub def sign(book_msg: BookMsg):
10 self.guest_book[msg.sender] = book_msg
11
12 emit Signed(book_msg=book_msg)
13
14 pub def get_msg(addr: address) -> BookMsg:
15 return self.guest_book[addr].to_mem()
16
نمایش همه

چگونه انتخاب کنیم

مانند هر زبان برنامه نویسی دیگری، بیشتر در مورد انتخاب ابزار مناسب برای کار مناسب و همچنین ترجیحات شخصی است.

اگر هنوز هیچ یک از زبان ها را امتحان نکرده اید، چند نکته را در نظر بگیرید:

چه چیز درباره‌ی Solidity عالی است؟

  • اگر مبتدی هستید، آموزش ها و ابزارهای یادگیری زیادی وجود دارد. در بخش آموزش با برنامه‌نویسی اطلاعات بیشتری در مورد آن ببینید.
  • ابزار توسعه دهنده خوب در دسترس است.
  • Solidity یک جامعه توسعه دهندگان بزرگ دارد، به این معنی که به احتمال زیاد پاسخ سوالات خود را خیلی سریع پیدا خواهید کرد.

چه چیز درباره‌ی Vyper عالی است؟

  • راه عالی برای شروع برای توسعه دهندگان پایتون که می خواهند قراردادهای هوشمند بنویسند.
  • Vyper تعداد کمتری ویژگی دارد که آن را برای نمونه سازی سریع ایده ها عالی می کند.
  • هدف Vyper این است که برای ممیزی آسان و برای انسان حداکثر خوانا باشد.

چه چیزی در مورد Yul و +Yul عالی است؟

  • زبان سطح پایین ساده و کاربردی.
  • اجازه می دهد تا به EVM خام نزدیک تر شوید، که می تواند به بهینه‌سازی مصرف گاز در قراردادهای شما کمک کند.

مقایسه‌های زبان

برای مقایسه ترکیب اولیه، چرخه عمر قرارداد، رابط ها، عملگر ها، ساختارهای داده، توابع، جریان کنترل و موارد دیگر، این برگه تقلب از Auditless(opens in a new tab) را بررسی کنید

اطلاعات بیشتر

آیا این مقاله مفید بود؟