منذ أكثر من عام ، أصبح معروفًا عن خطط برنامج Telegram messenger لإطلاق شبكة Telegram Open Network الخاصة بها . ثم أصبحت وثيقة تقنية ضخمة متوفرة ، والتي من المفترض أن كتبها نيكولاي دوروف ووصفت هيكل الشبكة المستقبلية. بالنسبة لأولئك الذين فاتتهم ، أوصي بقراءة إعادة سرد هذه الوثيقة ( الجزء 1 ، الجزء 2 ؛ الجزء الثالث ، للأسف ، ما زال يجمع الغبار في نسخ مسودة).
منذ ذلك الحين ، لم تكن هناك أخبار مهمة حول حالة تطوير TON ، حتى قبل يومين (في إحدى القنوات غير الرسمية ) رابط للصفحة https://test.ton.org/download.html ظهر ، حيث:
◦ ton-test-liteclient-full.tar.xz - مصادر العميل الخفيف لشبكة اختبار TON ؛
◦ ton-lite-client-test1.config.json - ملف التكوين للاتصال بشبكة اختبار ؛
AD README - معلومات حول بناء العميل وبدء تشغيله ؛
OW HOWTO - إرشادات خطوة بخطوة حول إنشاء عقد ذكي باستخدام عميل ؛
◦ ton.pdf - وثيقة محدثة (بتاريخ 2 مارس 2019) مع نظرة عامة تقنية على شبكة TON ؛
◦ tvm.pdf - الوصف التقني لـ TVM (TON Virtual Machine ، TON Virtual machine) ؛
bl tblkch.pdf - الوصف الفني لسلسلة TON blockchain ؛
ift fiftbase.pdf - وصف للغة Fift الجديدة ، المصممة لإنشاء عقود ذكية في TON.
أكرر ، لم يكن هناك تأكيد رسمي للصفحة وجميع هذه الوثائق من قبل Telegram ، ولكن حجم هذه المواد يجعلها معقولة للغاية. قم بتشغيل عميل منشور على مسؤوليتك الخاصة .
اختبار بناء العميل
أولاً ، دعونا نحاول إنشاء عميل اختبار وتشغيله - لحسن الحظ ، تصف README هذه العملية البسيطة بالتفصيل. سأفعل ذلك باستخدام المثال macOS 10.14.5 ، لا يمكنني أن أضمن نجاح التجميع على الأنظمة الأخرى.
قم بتنزيل وفك ضغط الأرشيف باستخدام أكواد المصدر . من المهم تنزيل أحدث إصدار ، نظرًا لأن التوافق مع الإصدارات السابقة غير مضمون في هذه المرحلة.
نتأكد من تثبيت أحدث إصدارات make ، cmake (الإصدار 3.0.2 أو أعلى) ، OpenSSL (بما في ذلك ملفات رأس C) ، g ++ أو clang على النظام. لم أكن مضطرًا إلى إعادة تثبيت أي شيء ، فكل شيء تجمع على الفور.
افترض أن المصادر تم فك ضغطها في مجلد ~/lite-client
. بشكل منفصل ، نقوم بإنشاء مجلد فارغ للمشروع المجمع (على سبيل المثال ، ~/liteclient-build
) ، ومنه ( cd ~/liteclient-build
) cd ~/liteclient-build
الأوامر:
cmake ~/lite-client cmake --build . --target test-lite-client

لإنشاء مترجم لغة Fift للعقود الذكية (انظر أدناه) ، ندعو أيضًا
cmake --build . --target fift
قم بتنزيل ملف التكوين الحالي للاتصال بشبكة الاختبار ووضعه في المجلد مع العميل المجمَّع.
تم ، يمكنك بدء العميل:
./test-lite-client -C ton-lite-client-test1.config.json
إذا تم كل شيء بشكل صحيح ، فعندئذ يجب أن ترى شيئًا مثل هذا:

كما ترون ، هناك بعض الأوامر المتاحة:
◦ help
- عرض قائمة الأوامر هذه ؛
◦ quit
- الخروج ؛
◦ time
- عرض الوقت الحالي على الخادم ؛
◦ status
- إظهار حالة الاتصال وقاعدة البيانات المحلية ؛
◦ last
- تحديث حالة blockchain (تحميل الكتلة الأخيرة). من المهم تنفيذ هذا الأمر قبل أي طلبات للتأكد من أنك ترى تمامًا الحالة الحالية للشبكة.
◦ sendfile
<filename>
- تحميل ملف محلي إلى شبكة TON. هذا هو التفاعل مع الشبكة - بما في ذلك ، على سبيل المثال ، إنشاء عقود ذكية جديدة وطلبات تحويل الأموال بين الحسابات ؛
◦ getaccount
<address>
- عرض حالة الحساب الحالية (في وقت تنفيذ last
أمر) مع العنوان المحدد ؛
◦ privkey
<filename>
- قم بتحميل المفتاح الخاص من الملف المحلي.
إذا قمت عند تشغيل العميل بتمرير المجلد إليه باستخدام الخيار -D
، فسوف يقوم بإضافة الكتلة الأخيرة من السلسلة الرئيسية إليه:
./test-lite-client -C ton-lite-client-test1.config.json -D ~/ton-db-dir
الآن يمكننا الانتقال إلى أشياء أكثر إثارة للاهتمام - تعلم لغة Fift ، ومحاولة ترجمة عقد ذكي (على سبيل المثال ، إنشاء محفظة اختبار) ، وتحميلها على الشبكة ومحاولة تحويل الأموال بين الحسابات.
اللغة الخمس
من المستند fiftbase.pdf ، يمكنك معرفة أنه لإنشاء عقود ذكية ، ابتكر فريق Telegram لغة مكدس جديدة Fift (على ما يبدو ، من الرقم الخامس ، عن طريق القياس مع Forth - لغة تشترك Fift فيها كثيرًا).
المستند ضخم جدًا ، حيث يحتوي على 87 صفحة ، ولن أعيد بيع محتوياته بالتفصيل في إطار هذه المقالة (على الأقل لأنني أنا لم أكمل قراءتها :). سأتطرق إلى النقاط الرئيسية وسأقدم بضعة أمثلة على الكود في هذه اللغة.
في المستوى الأساسي ، يكون بناء جملة Fift بسيطًا للغاية: يتكون الكود من كلمات ، وعادةً ما تكون مفصولة بمسافات أو فواصل أسطر (حالة خاصة: بعض الكلمات لا تتطلب محددًا بعدها). أي كلمة هي سلسلة أحرف حساسة لحالة الأحرف تتوافق مع بعض التعريفات (بشكل تقريبي ، ما يجب على المترجم القيام به عندما يواجه هذه الكلمة). إذا لم يكن هناك تعريف للكلمة ، يحاول المترجم تحليلها كرقم ووضعها في المجموعة. بالمناسبة ، فإن الأرقام هنا - فجأة - أعداد صحيحة 257 بت ، ولكن لا توجد أرقام كسرية على الإطلاق - وبشكل أكثر دقة ، فإنها تتحول على الفور إلى زوج من الأعداد الصحيحة ، وتشكل البسط والمقام لكسر عقلاني.
تتفاعل الكلمات عادة مع معاني في الجزء العلوي من المكدس. لا يستخدم نوع منفصل من الكلمات - بادئة - المكدس ، ولكن الأحرف اللاحقة من الملف المصدر. على سبيل المثال ، يتم تطبيق القيم الحرفية للسلسلة بهذه الطريقة - حرف "علامة اقتباس" ( "
) هو كلمة بادئة تبحث عن علامة اقتباس (الإغلاق) التالية وتضع السلسلة بينهما في الحزمة. تتصرف سطر واحد ( //
) وخط متعدد الأسطر ( /*
) بنفس الطريقة. التعليقات.
في هذا ، ينتهي الهيكل الداخلي للغة تقريبًا. يتم تعريف كل شيء آخر (بما في ذلك هياكل التحكم) ككلمات (إما داخلية ، مثل العمليات الحسابية وتعريف الكلمات الجديدة ؛ أو المعرفة في "المكتبة القياسية" Fift.fif
، والتي تقع في crypto/fift
في المصدر).
مثال بسيط لبرنامج Fift:
{ dup =: x dup * =: y } : setxy 3 setxy x . y . xy + . 7 setxy x . y . xy + .
يحدد السطر الأول كلمة setxy
الجديدة (لاحظ البادئة {
، التي تنشئ الكتلة قبل الإغلاق }
والبادئة :
والتي تحدد الكلمة فعليًا). يأخذ setxy
رقمًا من أعلى المكدس ، setxy
(أو يعيد تعريفه) باعتباره ثابتًا عالميًا x
، ومربع هذا الرقم ثابتًا y
(بالنظر إلى أن قيم الثوابت يمكن إعادة تعريفها ، فأنا أفضل أن أسميها متغيرات ، لكنني أتبع التسمية باللغة).
في السطرين التاليين ، يتم وضع رقم في الحزمة ، يتم setxy
، ثم يتم عرض قيم الثوابت x
، y
(يتم استخدام الكلمة للإخراج .
) ، يتم وضع كلا الثوابت على المكدس ، ولخصهما ، كما يتم عرض النتيجة. نتيجة لذلك ، سوف نرى:
3 9 12 ok 7 49 56 ok
(يقوم المترجم بطباعة الخط "موافق" عندما ينتهي من معالجة الخط الحالي في وضع الإدخال التفاعلي)
حسنًا ، مثال رمز كامل:
"Asm.fif" include -1 constant wc // create a wallet in workchain -1 (masterchain) // Create new simple wallet <{ SETCP0 DUP IFNOTRET INC 32 THROWIF // return if recv_internal, fail unless recv_external 512 INT LDSLICEX DUP 32 PLDU // sign cs cnt c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk s1 s2 XCPU // sign cs cnt pubk cnt' cnt EQUAL 33 THROWIFNOT // ( seqno mismatch? ) s2 PUSH HASHSU // sign cs cnt pubk hash s0 s4 s4 XC2PU // pubk cs cnt hash sign pubk CHKSIGNU // pubk cs cnt ? 34 THROWIFNOT // signature mismatch ACCEPT SWAP 32 LDU NIP DUP SREFS IF:<{ 8 LDU LDREF // pubk cnt mode msg cs s0 s2 XCHG SENDRAWMSG // pubk cnt cs ; ( message sent ) }> ENDS INC NEWC 32 STU 256 STU ENDC c4 POPCTR }>c // code <b 0 32 u, newkeypair swap dup constant wallet_pk "new-wallet.pk" B>file B, b> // data // no libraries <bb{00110} s, rot ref, swap ref, b> // create StateInit dup ."StateInit: " <s csr. cr dup hash dup constant wallet_addr ."new wallet address = " wc . .": " dup x. cr wc over 7 smca>$ type cr 256 u>B "new-wallet.addr" B>file <b 0 32 u, b> dup ."signing message: " <s csr. cr dup hash wallet_pk ed25519_sign_uint rot <bb{1000100} s, wc 8 i, wallet_addr 256 u, b{000010} s, swap <ss, b{0} s, swap B, swap <ss, b> dup ."External message for initialization is " <s csr. cr 2 boc+>B dup Bx. cr "new-wallet-query.boc" tuck B>file ."(Saved to file " type .")" cr
تم تصميم ملف المظهر المخيف هذا لإنشاء عقد ذكي - سيتم وضعه في ملف new-wallet-query.boc
بعد التنفيذ. يرجى ملاحظة أنه يتم استخدام لغة تجميع أخرى هنا لـ TON Virtual Machine (لن أتناولها بالتفصيل) ، وسيتم وضع التعليمات الخاصة بها على blockchain.
وبالتالي ، يتم تجميع المجمّع لـ TVM في Fift - مصادر هذا المجمّع موجودة في ملف crypto/fift/Asm.fif
ويتم توصيلها في بداية قطعة الشفرة أعلاه.
ماذا يمكنني أن أقول ، على ما يبدو ، يحب Nikolai Durov فقط إنشاء لغات برمجة جديدة :)
إنشاء عقد ذكي والتفاعل مع TON
لذلك ، لنفترض أننا قمنا بتكوين عميل TON ومترجم فوريت ، كما هو موضح أعلاه ، وأصبحنا على دراية باللغة. كيفية إنشاء عقد ذكي الآن؟ هذا موصوف في ملف HOWTO المرفق بالمصدر.
حسابات تون
كما وصفت في مراجعة TON ، تحتوي هذه الشبكة على أكثر من كتلة واحدة - هناك واحدة مشتركة ، ما يسمى "سلسلة رئيسية" ، بالإضافة إلى عدد عشوائي من "سلاسل العمل" الإضافية المحددة برقم 32 بت. تحتوي السلسلة الرئيسية على معرف -1 ، بالإضافة إلى ذلك ، يمكن أيضًا استخدام سلسلة عمل "أساسية" ذات المعرف 0. يمكن أن يكون لكل سلسلة عمل تكوينها الخاص. داخليًا ، يتم تقسيم كل مجموعة عمل إلى مجموعات أسهم ، ولكن هذا يمثل بالفعل تفصيلًا للتنفيذ ، والذي لا يجب وضعه في الاعتبار.
يتم تخزين الكثير من الحسابات داخل سلسلة عمل واحدة ، لها معرفات حسابية خاصة بها. بالنسبة للسلسلة الرئيسية وسلسلة العمل الصفرية ، يبلغ طولها 256 بت. وبالتالي ، يتم كتابة معرف الحساب ، على سبيل المثال ، مثل هذا:
-1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
هذا تنسيق "خام": أولاً ، معرف سلسلة العمل ، ثم نقطتين ، ومعرف الحساب بترميز سداسي عشري.
بالإضافة إلى ذلك ، هناك تنسيق مختصر - يتم تشفير رقم سلسلة العمل وعنوان الحساب في شكل ثنائي ، ويتم إضافة المجموع الاختباري لهم ويتم ترميز كل ذلك في Base64:
Ef+BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb
مع العلم بتنسيق التسجيل هذا ، يمكننا طلب الحالة الحالية للحساب من خلال عميل اختبار باستخدام الأمر
getaccount -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
نحصل على إجابة مثل هذا:
[ 3][t 2][1558746708.815218925][test-lite-client.cpp:631][!testnode] requesting account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D [ 3][t 2][1558746708.858564138][test-lite-client.cpp:652][!testnode] got account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D with respect to blocks (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F and (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F account state is (account addr:(addr_std anycast:nothing workchain_id:-1 address:x8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D) storage_stat:(storage_info used:(storage_used cells:(var_uint len:1 value:3) bits:(var_uint len:2 value:539) public_cells:(var_uint len:0 value:0)) last_paid:0 due_payment:nothing) storage:(account_storage last_trans_lt:74208000003 balance:(currencies grams:(nanograms amount:(var_uint len:7 value:999928362430000)) other:(extra_currencies dict:hme_empty)) state:(account_active ( split_depth:nothing special:nothing code:(just value:(raw@^Cell x{} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} )) data:(just value:(raw@^Cell x{} x{0000000D} )) library:hme_empty)))) x{CFF8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D2068086C000000000000000451C90E00DC0E35B7DB5FB8C134_} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} x{0000000D}
-client.cpp: [ 3][t 2][1558746708.815218925][test-lite-client.cpp:631][!testnode] requesting account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D [ 3][t 2][1558746708.858564138][test-lite-client.cpp:652][!testnode] got account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D with respect to blocks (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F and (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F account state is (account addr:(addr_std anycast:nothing workchain_id:-1 address:x8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D) storage_stat:(storage_info used:(storage_used cells:(var_uint len:1 value:3) bits:(var_uint len:2 value:539) public_cells:(var_uint len:0 value:0)) last_paid:0 due_payment:nothing) storage:(account_storage last_trans_lt:74208000003 balance:(currencies grams:(nanograms amount:(var_uint len:7 value:999928362430000)) other:(extra_currencies dict:hme_empty)) state:(account_active ( split_depth:nothing special:nothing code:(just value:(raw@^Cell x{} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} )) data:(just value:(raw@^Cell x{} x{0000000D} )) library:hme_empty)))) x{CFF8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D2068086C000000000000000451C90E00DC0E35B7DB5FB8C134_} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} x{0000000D}
ل-1: 8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D فيما يتعلق كتل (-1،8000000000000000،72355): F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296: 1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F و [ 3][t 2][1558746708.815218925][test-lite-client.cpp:631][!testnode] requesting account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D [ 3][t 2][1558746708.858564138][test-lite-client.cpp:652][!testnode] got account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D with respect to blocks (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F and (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F account state is (account addr:(addr_std anycast:nothing workchain_id:-1 address:x8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D) storage_stat:(storage_info used:(storage_used cells:(var_uint len:1 value:3) bits:(var_uint len:2 value:539) public_cells:(var_uint len:0 value:0)) last_paid:0 due_payment:nothing) storage:(account_storage last_trans_lt:74208000003 balance:(currencies grams:(nanograms amount:(var_uint len:7 value:999928362430000)) other:(extra_currencies dict:hme_empty)) state:(account_active ( split_depth:nothing special:nothing code:(just value:(raw@^Cell x{} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} )) data:(just value:(raw@^Cell x{} x{0000000D} )) library:hme_empty)))) x{CFF8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D2068086C000000000000000451C90E00DC0E35B7DB5FB8C134_} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} x{0000000D}
نرى الهيكل الذي يتم تخزينه في DHT من سلسلة العمل المحددة. على سبيل المثال ، في الحقل storage.balance
هو رصيد الحساب الحالي ، وفي storage.state.code
هو رمز العقد الذكي ، وفي storage.state.data
هي بياناته الحالية. لاحظ أن مخزن بيانات TON - الخلية ، الخلايا - عبارة عن شجرة ، ويمكن أن تحتوي كل خلية على بياناتها الخاصة ، وكذلك الخلايا التابعة. يظهر هذا كالتقدم البادئة في الأسطر الأخيرة.
عقد العقد الذكية
الآن ، لنقم بإنشاء مثل هذه البنية بأنفسنا (يطلق عليها BOC - كيس من الخلايا ) باستخدام لغة Fift. لحسن الحظ ، لن تضطر إلى كتابة عقد ذكي بنفسك - في مجلد crypto/block
من أرشيف المصدر ، يوجد ملف new-wallet.fif
سيساعدنا في إنشاء محفظة جديدة. قم ~/liteclient-build
إلى المجلد مع العميل المجمَّع ( ~/liteclient-build
، إذا ~/liteclient-build
الإرشادات أعلاه). لقد ذكرت محتوياتها أعلاه كمثال على الكود على Fift.
نحن ننفذ هذا الملف على النحو التالي:
./crypto/fift -I"<source-directory>/crypto/fift" new-wallet.fif
هنا يجب استبدال <source-directory>
بالمسار إلى المصادر غير المحزومة (لا يمكن استخدام الرمز "~" هنا ، لسوء الحظ ، تحتاج إلى المسار الكامل). بدلاً من استخدام رمز -I
يمكنك تحديد FIFTPATH
البيئة FIFTPATH
ووضع هذا المسار فيه.
نظرًا لأننا أطلقنا Fift باسم الملف new-wallet.fif
، فسيتم تنفيذه new-wallet.fif
. إذا حذفت اسم الملف ، فيمكنك اللعب مع المترجم الفوري في الوضع التفاعلي.
بعد التنفيذ ، يجب عرض شيء مثل هذا في وحدة التحكم:
StateInit: x{34_} x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54} x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B} new wallet address = -1 : 4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ signing message: x{00000000} External message for initialization is x{89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001_} x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54} x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B} B5EE9C724104030100000000D60002CF89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001001020084FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED5400480000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B6290698B (Saved to file new-wallet-query.boc)
} StateInit: x{34_} x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54} x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B} new wallet address = -1 : 4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ signing message: x{00000000} External message for initialization is x{89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001_} x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54} x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B} B5EE9C724104030100000000D60002CF89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001001020084FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED5400480000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B6290698B (Saved to file new-wallet-query.boc)
هذا يعني أن المحفظة ذات المعرف -1:4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2
(أو ، وهو نفس الشيء ، 0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ
new-wallet-query.boc
الرمز المقابل لها في ملف new-wallet-query.boc
، وعنوانه في new-wallet.addr
، والمفتاح الخاص في new-wallet.pk
(كن حذرًا - ستؤدي إعادة تشغيل البرنامج النصي إلى الكتابة فوق هذه الملفات).
بالطبع ، شبكة TON لا تعرف عن هذه المحفظة بعد ، يتم تخزينها فقط في شكل هذه الملفات. أنت الآن بحاجة إلى تحميله على الشبكة. صحيح أن المشكلة تكمن في إنشاء عقد ذكي تحتاج إلى دفع عمولة ، ولا يزال رصيد حسابك صفراً.
في وضع العمل ، سيتم حل هذه المشكلة عن طريق شراء غرام في البورصة (أو عن طريق التحويل من محفظة أخرى). حسنًا ، في وضع الاختبار الحالي ، تم إنشاء عقد ذكي خاص ، يمكنك من خلاله طلب ما يصل إلى 20 جرامًا من هذا القبيل تمامًا.
طلب عقد ذكي ، وتوزيع غرام اليسار واليمين ، القيام بذلك. في نفس المجلد crypto/block
نجد ملف testgiver.fif
:
// "testgiver.addr" file>B 256 B>u@ 0x8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d dup constant wallet_addr ."Test giver address = " x. cr 0x4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 constant dest_addr -1 constant wc 0x00000011 constant seqno 1000000000 constant Gram { Gram swap */ } : Gram*/ 6.666 Gram*/ constant amount // bx --> b' ( serializes a Gram amount ) { -1 { 1+ 2dup 8 * ufits } until rot over 4 u, -rot 8 * u, } : Gram, // create a message (NB: 01b00.., b = bounce) <bb{010000100} s, wc 8 i, dest_addr 256 u, amount Gram, 0 9 64 32 + + 1+ 1+ u, "GIFT" $, b> <b seqno 32 u, 1 8 u, swap ref, b> dup ."enveloping message: " <s csr. cr <bb{1000100} s, wc 8 i, wallet_addr 256 u, 0 Gram, b{00} s, swap <ss, b> dup ."resulting external message: " <s csr. cr 2 boc+>B dup Bx. cr "wallet-query.boc" B>file
نحن أيضا حفظه في المجلد مع العميل المجمعة ، ولكن إصلاح السطر الخامس - قبل السطر " constant dest_addr
". استبدلها بعنوان المحفظة التي قمت بإنشائها من قبل (ممتلئة ، غير مختصرة). "-1:" لا تحتاج إلى الكتابة في البداية ، بدلاً من ذلك ضع "0x" في البداية.
يمكنك أيضًا تغيير السطر 6.666 Gram*/ constant amount
- هذا هو المبلغ بالجرامات التي تطلبها (لا يزيد عن 20). حتى لو قمت بتحديد عدد صحيح ، اترك العلامة العشرية.
أخيرًا ، تحتاج إلى تصحيح السطر 0x00000011 constant seqno
. الرقم الأول هنا هو رقم التسلسل الحالي ، والذي يتم تخزينه في الحساب الذي يصدر الجرامات. من أين تحصل عليه؟ كما ذكر أعلاه ، قم ببدء تشغيل العميل وتشغيله:
last getaccount -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
في النهاية سوف تكون بيانات العقد الذكي
... x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} x{0000000D}
الرقم 0000000D (سيكون لديك المزيد) هو رقم التسلسل ، الذي يجب استبداله في testgiver.fif
.
هذا كل شيء ، احفظ الملف وقم بتشغيله ( ./crypto/fift testgiver.fif
). سيكون الإخراج wallet-query.boc
. هذه هي الرسالة المشكلة لعقد شخص آخر - الطلب هو "نقل الكثير من الغرامات إلى حساب كهذا وكذا".
باستخدام العميل ، نقوم بتحميله على الشبكة:
> sendfile wallet-query.boc [ 1][t 1][1558747399.456575155][test-lite-client.cpp:577][!testnode] sending query from file wallet-query.boc [ 3][t 2][1558747399.500236034][test-lite-client.cpp:587][!query] external message status is 1
إذا اتصلنا الآن بالآخر ، ثم طلبنا مرة أخرى حالة الحساب الذي طلبنا منه غرامات ، فمن المفترض أن نرى أن رقم التسلسل الخاص به قد زاد بمقدار واحد - وهذا يعني أنه أرسل الأموال إلى حسابنا.
تبقى الخطوة الأخيرة - نقوم بتحميل رمز محفظتنا (تم تجديد رصيدها بالفعل ، لكن بدون رمز العقد الذكي لن نتمكن من إدارته). sendfile new-wallet-query.boc
- وهذا هو ، لديك محفظتك الخاصة في شبكة TON (وإن كان ذلك الآن اختبار واحد فقط).
إنشاء المعاملات الصادرة
لتحويل الأموال من رصيد الحساب الذي تم إنشاؤه ، يوجد ملف crypto/block/wallet.fif
، والذي يجب أيضًا وضعه في المجلد مع العميل الذي تم جمعه.
على غرار الخطوات السابقة ، تحتاج إلى ضبط المبلغ الذي تنقله ، وعنوان المستلم (dest_addr) ، و seqno محفظتك (هو 1 بعد تهيئة المحفظة ويزيد بمقدار 1 بعد كل معاملة صادرة - يمكنك الاطلاع عليها عن طريق طلب حالة حسابك) . للاختبارات ، يمكنك استخدام ، على سبيل المثال ، محفظتي - 0x4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2
.
عندما تقوم بتشغيل ( ./crypto/fift wallet.fif
) ، سينتقل البرنامج النصي إلى عنوان محفظتك (من أين تنقلها من) والمفتاح الخاص بها من الملفات new-wallet.addr
و new-wallet.pk
، وكتابة الرسالة المستلمة إلى new-wallet-query.boc
.
كما كان من قبل ، لتنفيذ المعاملة مباشرةً ، ندعو sendfile new-wallet-query.boc
في العميل. بعد ذلك ، لا تنسَ تحديث حالة blockchain ( last
) وتحقق من أن رصيد و seqno من محفظتنا قد تغيرت ( getaccount <account_id>
).

هذا كل شيء ، الآن يمكننا إنشاء عقود ذكية في TON وإرسال الطلبات إليها. كما ترون ، الوظيفة الحالية كافية بالفعل ، على سبيل المثال ، لإنشاء محفظة أكثر ودية مع واجهة رسومية (ومع ذلك ، فمن المتوقع أن تصبح متاحة كجزء من برنامج المراسلة).