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

تراکنش‌ها

آخرین ویرایش: @nader.sedigh(opens in a new tab), ۲۵ خرداد ۱۴۰۳

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

پیش‌نیازها

برای کمک به فهمیدن این صفحه، بهتر است حساب های کاربری و مقدمه‌ای بر اتریوم را مطالعه کنید.

تراکنش چیست؟

تراکنش اتریوم به اقدامی اشاره دارد که توسط یک حساب تحت مالکیت خارجی آغاز می‌شود، به عبارت دیگر حسابی که توسط یک انسان مدیریت می‌شود، نه یک قرارداد. به‌عنوان مثال، اگر باب به آلیس 1 اتر ارسال کند، حساب باب باید بدهکار شود و حساب آلیس باید بستانکار شود. این عمل تغییر وضعیت توسط یک تراکنش صورت می‌گیرد.

شکلی نشان‌دهنده‌ی یک تراکنش که باعث تغییر وضعیت می‌شود نمودار برگرفته از Ethereum EVM illustrated(opens in a new tab)

تراکنش‌هایی که وضعیت EVM را تغییر می‌دهند، باید در کل شبکه پخش شوند. هر گره‌ می‌تواند اجرای تراکنش در ماشین مجازی اتریوم (EVM) را درخواست کند؛ پس از این اتفاق، یک اعتبارسنج تراکنش را اجرا می‌کند و تغییر حالت حاصل را در بقیه شبکه تکثیر می‌کند.

تراکنش ها نیاز به کارمزد دارند و باید در یک بلوک تأیید شده قرار گیرند. برای ساده‌تر کردن این نمای کلی، کارمزدهای گاز و اعتبارسنجی را در جای دیگری پوشش خواهیم داد.

تراکنش ارسالی شامل اطلاعات زیر است:

  • از - آدرس فرستنده که تراکنش را امضا خواهد کرد. این یک حساب مالکیت خارجی خواهد بود، چون حساب قرارداد نمیتواند تراکنش ارسال کنند.
  • دریافت‌کننده - آدرس دریافت‌کننده (اگر یک حساب با مالکیت خارجی باشد، تراکنش یک ارزش را منتقل می‌کند. اگر یک حساب قرارداد باشد، تراکنش کد قرارداد را اجرا می‌کند)
  • امضاء - شناسه‌ فرستنده. زمانی ایجاد می‌شود که کلید خصوصی فرستنده تراکنش را امضا کند و تأیید کند که فرستنده این تراکنش را مجاز کرده است
  • Nonce - یک شمارنده که به شکل متوالی افزایش می یابد و تعداد تراکنش های حساب را نشان میدهد
  • ارزش - مقدار اتر فرستاده شده از آدرس فرستنده تراکنش به گیرنده (این مقدار در واحد اندازه گیری WEI نمایش داده میشود، که هر اتر برابر با 1e+18 wei است)
  • داده ورودی(input data) - قسمتی اختیاری برای قراردادن هر داده دلخواه
  • gasLimit - حداکثر مقدار واحدهای گازی که می‌تواند توسط تراکنش مصرف شود. ماشین مجازی اتریوم (EVM) واحدهای گاز لازم برای انجام هر مرحله محاسباتی تراکنش را مشخص می کند
  • حداکثر انعام به ازای هر گاز (maxPriorityFeePerGas) - حداکثر قیمت گازهایی که به‌عنوان انعام به اعتبارسنج پرداخت میشود
  • حداکثر کارمزد به ازای هر گاز (maxFeePerGas) - حداکثر قیمتی که کاربر به ازای هر واحد گاز مایل به پرداخت است (شامل قیمت پایه به ازای هر گاز (baseFeePerGas)وحداکثر قیمت اولویت به ازای هر گاز (maxPriorityFeePerGas))

گاز به محاسبات لازم برای پردازش تراکنش توسط اعتبارسنج اشاره میکند. کاربران برای این محاسبه باید هزینه‌ای بپردازند. محدوده گاز (gasLimit)، وحداکثر قیمت اولویت به ازای هر گاز (maxPriorityFeePerGas) نشان دهنده بیشترین کارمزد تراکنش پرداخت شده به اعتبارسنج می باشد. درباره‌ی گاز بیشتر بدانید.

شی‌ء تراکنش کمی شبیه به این خواهد بود:

1{
2 from: "0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8",
3 to: "0xac03bb73b6a9e108530aff4df5077c2b3d481e5a",
4 gasLimit: "21000",
5 maxFeePerGas: "300",
6 maxPriorityFeePerGas: "10",
7 nonce: "0",
8 value: "10000000000"
9}
نمایش همه
کپی

اما یک شیء تراکنش باید با استفاده از کلید خصوصی فرستنده امضا شود. این کار ثابت می‌کند که تراکنش فقط می‌تواند از طرف فرستنده انجام شود و به صورت تقلبی ارسال نشده است.

یک کلاینت اتریوم مانند Geth این فرایند امضا را انجام می‌دهد.

نمونه‌ فراخوانی JSON-RPC:

1{
2 "id": 2,
3 "jsonrpc": "2.0",
4 "method": "account_signTransaction",
5 "params": [
6 {
7 "from": "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db",
8 "gas": "0x55555",
9 "maxFeePerGas": "0x1234",
10 "maxPriorityFeePerGas": "0x1234",
11 "input": "0xabcd",
12 "nonce": "0x0",
13 "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",
14 "value": "0x1234"
15 }
16 ]
17}
نمایش همه
کپی

نمونه‌ی پاسخ:

1{
2 "jsonrpc": "2.0",
3 "id": 2,
4 "result": {
5 "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",
6 "tx": {
7 "nonce": "0x0",
8 "maxFeePerGas": "0x1234",
9 "maxPriorityFeePerGas": "0x1234",
10 "gas": "0x55555",
11 "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",
12 "value": "0x1234",
13 "input": "0xabcd",
14 "v": "0x26",
15 "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e",
16 "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",
17 "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"
18 }
19 }
20}
نمایش همه
کپی
  • raw تراکنشی امضا شده است در فرم کدگذاری شده Recursive Length Prefix (RLP)
  • tx تراکنش امضاشده به شکل JSON است

با هش امضا، می‌توان به صورت رمزنگاری ثابت کرد که تراکنش از فرستنده آمده و به شبکه ارسال شده است.

فیلد داده‌ها

اکثریت قریب‌به‌اتفاق تراکنش‌ها از طریق یک حساب دارای مالکیت خارجی به یک قرارداد دسترسی دارند. اکثر قراردادها در Solidity نوشته شده‌اند و فیلد داده‌های آن‌ها را مطابق با تفسیر می‌کنند.

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

بقیه فراخوان‌داده‌ها (calldata) آرگومان هستند، که مطابق با مشخصات ABI مشخص شده‌اند(opens in a new tab).

برای مثال، بیایید به این تراکنش(opens in a new tab) نگاه کنیم. از برای مشاهده‌ی بیشتر کلیک کنید برای دیدن فراخوان‌داده‌ها استفاده کنید.

انتخابگر تابع 0xa9059cbb است. چندین تابع شناخته‌شده با این امضا وجود دارد(opens in a new tab). در این مورد کد منبع قرارداد(opens in a new tab) در Etherscan آپلود شده است، بنابراین می‌دانیم که این تابع transfer(address, uint256) است.

بقیه داده‌ها عبارتند از:

10000000000000000000000004f6742badb049791cd9a37ea913f2bac38d01279
2000000000000000000000000000000000000000000000000000000003b0559f4

با توجه به مشخصات ABI، مقادیر صحیح (مانند آدرس‌ها که اعداد صحیح 20 بایتی هستند) در ABI به صورت کلمات 32 بایتی ظاهر می‌شوند که ممکن است یک یا چند صفر در ابتدای آن‌ها قرار داده شود. بنابراین ما می‌دانیم که آدرس «to»‏ 4f6742badb049791cd9a302791cd9a302791cd99a32791cd99a310.com است. مقدار 0x3b0559f4 = 990206452 است.

انواع تراکنش‌ها

در اتریوم چند نوع تراکنش مختلف وجود دارد:

  • تراکنش های منظم: تراکنش از یک حساب به حساب دیگر.
  • تراکنش‌های استقرار قرارداد: تراکنش بدون آدرس «to»، که در آن از فیلد داده‌ها برای کد قرارداد استفاده می‌شود.
  • اجرای قرارداد: تراکنشی که با یک قرارداد هوشمند مستقر تعامل دارد. در این مورد، آدرس «to»، آدرس قرارداد هوشمند است.

درباره‌ی گاز

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

بنابراین برای اینکه باب 1 اتر را به آلیس با baseFeePerGas به میزان 190 gwei و maxPriorityFeePerGas به میزان 10 gwei ارسال کند، باب باید هزینه‌ی زیر را بپردازد:

1(190 + 10) * 21000 = 4,200,000 gwei
2--یا--
30.0042 اتر

مقدار 1.0042 اتر از حساب باب کسر خواهد شد (1 اتر برای آلیس + 0.0042 اتر برای هزینه گاز)

به حساب آلیس 1.0+ اتر بستانکار خواهد شد

کارمزد پایه 0.00399- اتر خواهد شد

اعتبارسنج انعام +0.000210 ETH را نگه می دارد

گاز برای هر تعامل قرارداد هوشمند نیز لازم است.

شکلی نشان‌دهنده‌ی نحوه‌ی بازپرداخت گاز مصرف‌نشده نمودار برگرفته از Ethereum EVM illustrated(opens in a new tab)

هر گازی که در تراکنش استفاده نشده باشد به حساب کاربری مسترد می‌شود.

چرخه‌ی حیات تراکنش

هنگامی که تراکنش ارسال شد، موارد زیر اتفاق می‌افتد:

  1. یک هشِ تراکنش به صورت رمزنگاری شده تولید میشود: 0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017

  2. سپس تراکنش شما در شبکه مخابره می شود و به استخری که شامل تمامی تراکنش های شبکه است که در حال انتظار می باشند اضافه می شود.

  3. به منظور تایید و "موفقیت آمیز" در نظر گرفته شدن تراکنش شما، یک اعتبارسنج باید تراکنش شما را انتخاب کرده و داخل یک بلوک قرار دهد.

  4. با گذر زمان بلوکی که حامل تراکنش شما است به وضعیت "مشروع" و سپس "نهایی" برروز رسانی می شود. این ارتقاها موجب می شوند که کاملا مطمئن شوید که تراکنش شما موفقیت آمیز بوده و هرگز تغییر نخواهد کرد. زمانی که یک بلوک "نهایی" شد فقط تنها زمانی که مورد یک حمله در حد و سطح شبکه قرار بگیرد می تواند تغییر یابد که چندین میلیارد دلار هزینه به بار خواهد آورد.

یک نسخه‌ی آزمایشی تصویری

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

پاکت تراکنش تایپ‌شده

اتریوم در ابتدا یک قالب برای تراکنش‌ها داشت. هر تراکنش حاوی نانس (nonce)، قیمت گاز، حد گاز، آدرس گیرنده، مقدار، داده، v، r و s بود. این فیلد ها کدگذاری شده RLP هستند، تا چیزی شبیه این به نظر برسند:

RLP([nonce, gasPrice, gasLimit, to, value, data, v, r, s])

اتریوم به گونه‌ای تکامل یافته است که از چندین نوع تراکنش پشتیبانی می‌کند تا پیاده‌سازی ویژگی‌های جدیدی مانند لیست‌های دسترسی و EIP-1559(opens in a new tab) را بدون تأثیر بر قالب‌های تراکنش قدیمی امکان‌پذیر سازد.

EIP-2718(opens in a new tab) چیزی است که به این رفتار اجازه می دهد. تراکنش ها به صورت زیر تفسیر می شوند:

نوع معامله || TransactionPayload

که در آن فیلدها به صورت زیر تعریف می‌شوند:

  • TransactionType - عددی بین 0 و 0x7f، برای مجموع 128 نوع تراکنش ممکن.
  • TransactionPayload - یک آرایه‌ی بایت دلخواه که توسط نوع تراکنش تعریف شده است.

بیشتر بخوانید

آیا منبعی اجتماعی می‌شناسید که به شما کمک کرده باشد؟ این صفحه را ویرایش کنید و به آن اضافه کنید!

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