كل المقالات
7 دقائق قراءة

سجل معاملات TON: الزمن المنطقي lt والهاش والعمق الأرشيفي

كيف يعمل سجل معاملات TON: الزمن المنطقي (lt) والهاش ومؤشر آخر معاملة. كيف يقرأ الوكيل السجل عبر MCP ولماذا يحتاج العمق الكامل إلى عقدة أرشيفية.

سجل معاملات TONlogical timelt hash TONget_transactionsعقدة TON الأرشيفيةMCP TON

تعمل ليلًا، وفي الساعة 3:47 تصلك رسالة: مستخدم دفع ثمن طلبه بـ TON، والبوت لم يحتسب الدفعة. تفتح المستكشف — المال في مكانه، والتحويل الوارد ظاهر. إذن المشكلة ليست في البلوكتشين، بل في طريقة قراءة خدمتك لسجل المعاملات. وهنا يتبيّن أن هذا السجل على TON مبنيّ بطريقة مختلفة تمامًا عمّا اعتدته في Ethereum.

مراقبة المدفوعات على TON تبدو بسيطة على نحو خادع: استعلم عن الرصيد وتفاعل مع أي تغيّر. لكن كل شيء ينهار عمليًا. دفعتان بالمبلغ نفسه في الدقيقة نفسها — كم عددها، واحدة أم اثنتان؟ المستخدم دفع بـ USDT، ورصيد GRAM لم يتحرّك. تحتاج إلى كشف حساب لستة أشهر، واللايت-سيرفر يعطيك آخر المعاملات فقط ويصمت عن الباقي.

إن كنت توصّل وكيل ذكاء اصطناعي بشبكة TON أو تكتب خلفيةً تُطابق المدفوعات، فلنتناول الأمر بجدّية: ما سجل معاملات TON، ولماذا يلزم زوج lt + hash، ولماذا يصطدم العمق بالعقدة الأرشيفية، وكيف يُقرأ ذلك كله بوكيل عبر MCP.

ما سجل المعاملات في TON ولماذا يحتاجه الوكيل

في TON لكل حساب — سواءٌ أكان محفظةً أم عقدًا أم محفظةَ جيتون — سلسلة معاملات خاصة به. وكل معاملة هي نتيجة معالجة رسالة واردة: استلام GRAM، أو تحويل جيتون، أو استدعاء دالة في عقد. وبالنسبة إلى وكيل (Claude أو Cursor أو أي عميل MCP) يستقبل المدفوعات أو يطابق الحسابات، فالسجل هو المصدر الموثوق الوحيد: الرصيد يقول «كم لديك الآن»، أما السجل فيقول «ماذا حدث بالضبط ومتى، وممّن، وبأي مبلغ».

مهامّ عملية جدًا يحتاج فيها الوكيل إلى السجل:

  • تأكيد وصول الدفعة («تحقّق مما إذا وصل تحويل إلى هذا العنوان خلال الساعة الماضية»)؛
  • تجميع كشف حساب لمحفظة؛
  • تتبّع معاملة بعينها عبر معرّفها؛
  • مطابقة الجيتونات الواردة (USDT مثلًا) مع المبلغ المتوقَّع.

والمشكلة أن «أعطني المعاملات من رقم 100 إلى 120» لا يعمل في TON. فلا وجود هنا لترقيم كتل عام متّصل يمكن أن تطلب على أساسه «المعاملة رقم N». الترتيب يُحدَّد بطريقة أخرى — عبر الزمن المنطقي.

الزمن المنطقي (lt): لماذا لا يوجد ترقيم كتل معتاد في TON

في Ethereum الأمر بسيط: هناك الكتلة رقم 19,000,000، وفيها المعاملات بالترتيب. عدّاد عام واحد يتزايد باطّراد، والجميع يعتمد على الرقم نفسه.

أما TON فنظام متعدّد الخيوط: سلسلة رئيسية (masterchain)، وسلاسل عمل (workchains)، وشاردات تنقسم وتندمج تحت الحمل. ولا وجود هنا لـ«رقم كتلة» واحد يتيح ترتيب كل أحداث الشبكة ترتيبًا خطيًا. وبدلًا منه يستخدم TON الزمن المنطقي (lt، logical time) — عدّادًا يتزايد باطّراد تُرتّب به الشبكة الأحداث والرسائل والمعاملات. وهو يضمن: إن أثّر الحدث A في الحدث B، فإن lt(A) < lt(B).

ومن هنا نتيجة عملية: موضع المعاملة لا يحدّده رقم كتلة، بل الزوج (lt, hash). فالـ lt مسؤول عن الترتيب (أيّها أسبق)، والـ hash عن التعريف القاطع للمعاملة بعينها. وكلٌّ منهما على حدة عديم الفائدة للاستعلام الدقيق: فقد تتقارب قيم lt لكائنات مختلفة، والـ hash وحده لا يخبر liteserver من أين يبدأ القراءة.

هاش المعاملة وزوج lt + hash: مؤشر آخر معاملة في الحساب

هاش المعاملة هو بصمتها التشفيرية؛ وعلى TON يصلك بصيغة base64 أو hex. الـ lt يقول «متى في الترتيب»، والـ hash يقول «أيّ معاملة بالضبط»، لأن الالتباس ممكن نظريًا عند شريحة lt واحدة، ومن دون الهاش لن يعطيك liteserver المعاملة. واحفظ هذا جيدًا: الزوج (lt, hash) إلزامي معًا. الـ lt وحده أو الـ hash وحده لا يكفي.

ومن أين تأتي نقطة البداية؟ حالة الحساب تحتفظ بمؤشر إلى أحدث معاملة — last_transaction_id، وهو زوج lt + hash نفسه (الحقلان last_trans_lt / last_trans_hash). وهذا هو «رأس» القائمة الذي يبدأ منه المرور في السجل رجوعًا.

وفي مجموعة أدوات MCP لدى TONNode تقوم بذلك الأداةُ get_account_state — فهي تعيد حالة الحساب وأعلامه ومؤشر آخر معاملة.

كيف يقلّب get_transactions السجل: lt + hash وسلسلة prev_trans

والآن النقطة الجوهرية التي يصير بها تقليب السجل ممكنًا أصلًا. كل معاملة، إلى جانب lt وhash الخاصين بها، تحتوي على حقلين: prev_trans_lt وprev_trans_hash — إشارةً إلى المعاملة السابقة للحساب نفسه. أي أن المعاملات تشكّل قائمة أحادية الوصل تسير رجوعًا في الزمن؛ ورأسها هو last_transaction_id المأخوذ من الحالة.

وتستقبل get_transactions ما يلي:

  • account — عنوان الحساب؛
  • الـ lt والـ hash الابتدائيين — النقطة التي تُقرأ منها؛
  • count — حجم الدفعة.

وهي تعيد دفعة من المعاملات سائرةً رجوعًا من النقطة المحدّدة. ومنطق المرور صفحةً صفحة:

  1. خذ last_trans_lt / last_trans_hash من get_account_state — هذا هو الرأس.
  2. استدعِ get_transactions(account, lt, hash, count) — لتحصل على دفعة.
  3. خذ من آخر معاملة في الدفعة قيمتي prev_trans_lt وprev_trans_hash.
  4. استدعِ get_transactions مجددًا بهذا الزوج — وهذه هي الصفحة التالية.
  5. كرّر حتى يصير prev_trans_lt مساويًا لـ 0 (بداية عمر الحساب) أو حتى تبلغ العمق المطلوب.

هكذا يعمل الترقيم الصفحي في TON: ليس «الصفحة 2»، بل «تابِع من هذا الزوج (lt, hash)».

الكتل الحديثة في مقابل السجل العميق: لماذا تلزم عقدة أرشيفية

وهنا يتعثّر أكثر الناس. فالـ liteserver العادي يعطي الكتل الحديثة والسجل القريب للحساب: إذ يحتفظ بنافذة حالة محدودة — عددًا من الكتل الأخيرة — ومع نمو الشبكة تُزاح البيانات القديمة عنه. امْضِ في سلسلة prev_trans عميقًا بما يكفي، وعند نقطة ما سيتوقف liteserver ببساطة عن إعطائك المعاملات: فهي لم تعد موجودة فعليًا في نافذته. سترى الدفعة الحديثة، أما معاملة عمرها ستة أشهر فلا.

وهذا ليس عطبًا بل تصميم: فالاحتفاظ بالمسار الكامل لكل حساب منذ التكوين مكلف. أما السجل العميق فتحفظه العقدة الأرشيفية — وهي عقدة لا تُسقط الكتل القديمة، بل تحتفظ بحالة الشبكة الكاملة عبر تاريخها كله.

والخلاصة العملية:

  • رصد الدفعة، وكشف الحساب الحديث، و«هل وصل شيء خلال الساعة الماضية» — يكفيه liteserver عادي؛
  • التدقيق الكامل لمحفظة منذ يومها الأول — يحتاج إلى عقدة أرشيفية.

وثمة صداع منفصل: اللايت-سيرفرات العامة المأخوذة من إعدادات TON العالمية. فهي مشتركة ومحدودة: تحت الحمل كثيرًا ما تردّ بـ not ready أو تدخل في مهلة ADNL، ولا يوجد عليها سجل عميق أيضًا. وإن كان ما اصطدمتَ به هو not ready بعينه، فذلك عَرَضٌ للايت-سيرفر مشترك محمَّل فوق طاقته — والتحليل في مقال لماذا يردّ liteserver بـ not ready وكيف تصلح ذلك.

وبصراحة عن TONNode: العقدة الأرشيفية مدرجة في خارطة الطريق وتُزامَن الآن — ولا أعدك بالعمق الأرشيفي بوصفه ميزة جاهزة. أما اليوم فالمتاح هو قراءة السجل الحديث والقريب عبر نقطة نهاية مُدارة، دون يانصيب اللايت-سيرفرات العامة. وللأرشيف الكامل منذ التكوين انتظر إعلانًا منفصلًا.

كيف يقرأ وكيل ذكاء اصطناعي سجل TON عبر MCP

TONNode خادم MCP مُستضاف لشبكة TON، بـ 16 أداة بالضبط، وget_transactions جزء من كتلة القراءة. أما MCP (Model Context Protocol) فهو المعيار الذي يستدعي الوكيل بموجبه الأدوات بنفسه، دون أن تُجمّع أنت طلبات ADNL يدويًا. لا حاجة إلى تثبيت SDK، ولا إلى تشغيل لايت-سيرفر، ولا إلى تحليل TL-B — الوكيل يستدعي الأداة مباشرةً.

الربط المحلي المجاني

مجموعة القراءة الكاملة، وإعدادات عامة، وحزمة @tonnode/mcp — مفتوحة المصدر، برخصة MIT:

{
  "mcpServers": {
    "ton": {
      "command": "npx",
      "args": ["-y", "@tonnode/mcp"]
    }
  }
}

والحزمة تعمل عبر بروتوكول ADNL الأصلي في TON، دون طبقات HTTP وسيطة.

نقطة نهاية مُستضافة بمفتاحك الخاص

وللحصول على سعة تمرير مضمونة، تُؤخَذ نقطة نهاية مُستضافة بمفتاحك الخاص:

{
  "mcpServers": {
    "ton": {
      "type": "http",
      "url": "https://mcp.tonnode.io/mcp",
      "headers": { "Authorization": "Bearer tn_live_…" }
    }
  }
}

ولقراءة السجل ستفيدك:

  • get_account_state — نقطة بداية المرور (last_trans_lt / last_trans_hash)، وحالة الحساب وأعلامه؛
  • get_transactions — المعاملات نفسها صفحةً صفحة، بحسب الزوج (lt, hash)؛
  • parse_address — تحويل العناوين دون اتصال بين EQ / UQ / raw؛
  • get_jetton_info وget_jetton_balance — للسجل الخاص بالجيتونات.

عمليًا: رصد الدفعة والمرور على السجل صفحةً صفحة

لنجمّع سيناريو نمطيًا — «هل وصلت الدفعة وبأي مبلغ».

مطالبة الوكيل

عبر أداة ton خذ get_account_state للعنوان EQC…myshop، ثم get_transactions انطلاقًا من last_trans_lt / last_trans_hash الخاصين به، وبـ count 20. ابحث عن تحويل وارد بقيمة 5 GRAM خلال العشر دقائق الأخيرة. وحوّل عناوين المرسِلين عبر parse_address إلى صيغة EQ قبل المقارنة. وإن لزمك سجل أعمق، فخذ prev_trans_lt / prev_trans_hash من آخر معاملة وكرّر get_transactions.

وسيذهب الوكيل بنفسه إلى رأس السلسلة، ويقلّب الدفعة، ويطابق المبالغ.

شبه كود للمرور صفحةً صفحة

المرور نفسه بشبه كود (الاستدعاءات هي أدوات MCP التي يستدعيها الوكيل):

state = get_account_state(account)
lt    = state.last_trans_lt
hash  = state.last_trans_hash

while lt != 0:
    batch = get_transactions(account, lt, hash, count=20)
    for tx in batch:
        if matches_expected_payment(tx):   # رسالة واردة بالمبلغ/التعليق المطلوب
            return tx
    last = batch[-1]
    lt   = last.prev_trans_lt
    hash = last.prev_trans_hash   # بدون hash لن تُطلب الصفحة التالية

تفاصيل توفّر عليك ساعات من التنقيح

  • العناوين تصل في حقول المعاملات بالصيغة الخام (0:abcd…). وقبل أن تقارن المرسِل أو المستلِم بعنوان EQ… المألوف لديك، حوّل الاثنين إلى صيغة واحدة عبر parse_address — وإلا فلن تتطابق مقارنة النصوص رغم أن العنوان واحد. وتفصيل الصيغ في EQ وUQ وraw في عناوين TON.
  • مدفوعات USDT لا تظهر في سلسلة محفظة GRAM. فالجيتونات تعيش في محفظة جيتون منفصلة يُحسب عنوانها على السلسلة (وget_jetton_balance يفعل ذلك نيابةً عنك ويعطيك الرصيد الحالي). ولسجل الجيتونات مُرّ على معاملات محفظة الجيتون، لا المحفظة الأساسية.
  • أعِد حساب المبالغ الخام عبر decimals. مبالغ الجيتونات تصل بأصغر الوحدات: ولتحويل 5000000 إلى 5 USDT مقروءة بشريًا، خذ decimals من get_jetton_info — فهي عند USDT تساوي 6، وعند معظم الجيتونات 9. أخطأت بينهما — أخطأت بمقدار 1000 ضعف. والتحليل الكامل في كيف تلتقط دفعة USDT واردة على TON.
  • أزِل التكرار بحسب (lt, hash) لا بحسب المبلغ. فدفعتان متطابقتان لا تختلفان إلا بزوج lt+hash — وهو بعينه مفتاح التكرار الآمن (idempotency).

وإن احتاج الوكيل، إلى جانب السجل، أن يستعلم عن الحالة الراهنة لعقد ما، فذلك عمل run_get_method — وطريقةُ استدعاء get-methods دون SDK مشروحةٌ في قراءة TON دون SDK عبر get-method.

باختصار

  • لا وجود في TON لأرقام كتل كما في Ethereum — موضع المعاملة يحدّده الزوج (lt, hash): الـ lt للترتيب، والـ hash للتعريف، وهما إلزاميان معًا.
  • معاملات الحساب قائمة موصولة عبر prev_trans_lt / prev_trans_hash؛ تقلّبها رجوعًا بدءًا من last_transaction_id المأخوذ من get_account_state.
  • الـ liteserver العادي يعطي السجل الحديث والقريب؛ أما العمق الكامل فمهمة العقدة الأرشيفية.
  • ومع الجيتونات لا تنسَ decimals من get_jetton_info (USDT = 6) والعناوين الخام التي يجب تمريرها عبر parse_address.

لا تريد التعامل مع اللايت-سيرفرات العامة التي تردّ بـ not ready؟ الأداة get_transactions متاحة جاهزةً في خطة Hobby المجانية — 60 طلبًا/دقيقة، إلى الأبد، بلا بطاقة، والمفتاح يُصدَر فور تسجيل الدخول.

فعّل قراءة سجل TON خلال دقيقة ← tonnode.io/dashboard?plan=hobby

وما الذي يستطيع الوكيل فعله على TON إلى جانب قراءة السجل — كل الأدوات الـ16 في صفحة أدوات TONNode.

امنح وكيلك الوصول إلى TON

16 أداة MCP: قراءة ومبادلات غير وصائية وعبر السلاسل ومحافظ. الباقة المجانية — 60 طلب/دقيقة، بلا بطاقة.