Haskell سان FunC کي FunCtional ۾ تبديل ڪرڻ: ڪيئن Serokell Telegram Blockchain مقابلو کٽيو

توهان شايد ٻڌو آهي ته ٽيليگرام Ton blockchain پليٽ فارم لانچ ڪرڻ بابت آهي. پر توهان شايد اها خبر ياد ڪري ڇڏي آهي جيڪا گهڻو وقت اڳ نه هئي ٽيليگرام مقابلي جو اعلان ڪيو هن پليٽ فارم لاءِ هڪ يا وڌيڪ سمارٽ معاهدن تي عمل درآمد لاءِ.

Serokell ٽيم، وڏين بلاڪچين منصوبن کي ترقي ڪرڻ ۾ وسيع تجربو سان، هڪ طرف بيهڻ نه ٿي سگهي. اسان پنجن ملازمن کي مقابلي لاءِ نمائندو ڪيو، ۽ ٻن هفتن کان پوءِ هنن ان ۾ پهرين جاءِ ورتي (ان ۾) معمولي بي ترتيب لقب Sexy Chameleon. هن آرٽيڪل ۾ آئون ڳالهائيندس ته انهن ڪيئن ڪيو. اسان اميد ٿا ڪريون ته ايندڙ ڏهن منٽن ۾ توهان گهٽ ۾ گهٽ هڪ دلچسپ ڪهاڻي پڙهندا، ۽ وڌ ۾ وڌ توهان کي ان ۾ ڪجهه مفيد ملندو جيڪو توهان پنهنجي ڪم ۾ لاڳو ڪري سگهو ٿا.

پر اچو ته ٿورڙي حوالي سان شروع ڪريون.

مقابلي ۽ ان جا شرط

تنهن ڪري، شرڪت ڪندڙن جا بنيادي ڪم هڪ يا وڌيڪ تجويز ڪيل سمارٽ معاهدن تي عمل ڪرڻ، انهي سان گڏ TON ماحولياتي نظام کي بهتر ڪرڻ لاء تجويزون ٺاهڻ. مقابلو 24 سيپٽمبر کان 15 آڪٽوبر تائين ٿيو ۽ نتيجن جو اعلان صرف 15 نومبر تي ڪيو ويو. ڪافي عرصو، غور ڪندي ته هن عرصي دوران ٽيليگرام منظم ڪيو ۽ مقابلي جي نتيجن کي C++ ۾ ايپليڪيشنن جي ڊيزائن ۽ ڊولپمينٽ تي ٽيليگرام ۾ VoIP ڪالن جي معيار کي جانچڻ ۽ جانچڻ لاءِ.

اسان منتظمين پاران تجويز ڪيل فهرست مان ٻه سمارٽ معاهدو چونڊيو. انهن مان هڪ لاءِ، اسان ٽولن سان ورهايل اوزار استعمال ڪيا، ۽ ٻيو اسان جي انجنيئرن پاران خاص طور تي TON لاءِ تيار ڪيل نئين ٻولي ۾ لاڳو ڪيو ويو ۽ Haskell ۾ ٺاهيو ويو.

فنڪشنل پروگرامنگ ٻولي جو انتخاب حادثاتي نه آهي. اسان ۾ ڪارپوريٽ بلاگ اسان اڪثر ان بابت ڳالهايون ٿا ڇو ته اسان سمجهون ٿا ته فعلي ٻولين جي پيچيدگي هڪ وڏو مبالغ آهي ۽ ڇو اسان انهن کي عام طور تي اعتراض جي بنياد تي ترجيح ڏين ٿا. رستي جي ذريعي، اهو پڻ شامل آهي ھن مضمون جو اصل.

اسان ڇو حصو وٺڻ جو فيصلو ڪيو؟

مختصر ۾، ڇاڪاڻ ته اسان جي اسپيشلائيزيشن غير معياري ۽ پيچيده منصوبا آهن جن کي خاص صلاحيتن جي ضرورت آهي ۽ اڪثر ڪري IT ڪميونٽي لاءِ سائنسي قدر آهن. اسان مضبوط طور تي اوپن سورس جي ترقي جي حمايت ڪريون ٿا ۽ ان جي مقبوليت ۾ مصروف آهيون، ۽ ڪمپيوٽر سائنس ۽ رياضي جي شعبي ۾ معروف روسي يونيورسٽين سان پڻ تعاون ڪريون ٿا.

اسان جي محبوب ٽيليگرام پروجيڪٽ ۾ مقابلي ۽ شموليت جا دلچسپ ڪم پاڻ ۾ هڪ بهترين حوصلا هئا، پر انعام فنڊ هڪ اضافي ترغيب بڻجي ويو. 🙂

TON blockchain تحقيق

اسان بلاڪچين، مصنوعي ذهانت ۽ مشين لرننگ ۾ نيون ترقيات کي ويجهڙائي سان مانيٽر ڪريون ٿا ۽ ڪوشش ڪريون ٿا ته هر هڪ اهم رليز کي وڃائڻ نه ڏيو انهن علائقن مان جنهن ۾ اسان ڪم ڪريون ٿا. تنهن ڪري، مقابلو شروع ٿيڻ وقت، اسان جي ٽيم اڳ ۾ ئي خيالن کان واقف هئي TON اڇو پيپر. بهرحال، TON سان ڪم شروع ڪرڻ کان اڳ، اسان ٽيڪنيڪل دستاويزن ۽ پليٽ فارم جي اصل سورس ڪوڊ جو تجزيو نه ڪيو، تنهن ڪري پهريون قدم بلڪل واضح هو - سرڪاري دستاويزن جو مڪمل مطالعو сайте ۽ اندر پروجيڪٽ repositories.

مقابلي جي شروع ٿيڻ وقت، ڪوڊ اڳ ۾ ئي شايع ٿي چڪو هو، تنهنڪري وقت بچائڻ لاء، اسان هڪ گائيڊ يا خلاصو ڳولڻ جو فيصلو ڪيو. صارفين طرفان. بدقسمتي سان، اهو ڪو به نتيجو نه ڏنو - Ubuntu تي پليٽ فارم گڏ ڪرڻ جي هدايتن کان سواء، اسان کي ٻيو مواد نه مليو.

دستاويز پاڻ چڱي طرح تحقيق ڪئي وئي، پر ڪجهه علائقن ۾ پڙهڻ ڏکيو هو. گهڻو ڪري اسان کي ڪجهه نقطن ڏانهن موٽڻو پوندو هو ۽ تجريدي خيالن جي اعليٰ سطحي وضاحتن کان گهٽ-سطح تي عمل درآمد جي تفصيلن ڏانهن موٽڻو پوندو هو.

اهو آسان ٿيندو جيڪڏهن وضاحتن ۾ مڪمل طور تي عملدرآمد جي تفصيلي وضاحت شامل نه هجي. معلومات بابت معلومات ڪيئن هڪ ورچوئل مشين پنهنجي اسٽيڪ جي نمائندگي ڪري ٿي ڊولپرز کي پريشان ڪرڻ جو وڌيڪ امڪان آهي TON پليٽ فارم لاءِ سمارٽ معاهدو ٺاهي انهن جي مدد ڪرڻ بجاءِ.

نڪس: منصوبي کي گڏ ڪرڻ

Serokell تي اسان وڏا مداح آهيون نيڪس. اسان ان سان گڏ اسان جا منصوبا گڏ ڪريون ٿا ۽ انهن کي استعمال ڪندي ترتيب ڏيون ٿا NixOps، ۽ اسان جي سڀني سرورن تي انسٽال ٿيل نڪسس. انهي جي مهرباني، اسان جون سڀئي تعميرات ٻيهر پيداوار آهن ۽ ڪنهن به آپريٽنگ سسٽم تي ڪم ڪن ٿيون جنهن تي نڪس نصب ٿي سگهي ٿو.

تنهنڪري اسان ٺاهڻ شروع ڪيو TON اسيمبلي لاء اظهار سان نڪس اوورلي. ان جي مدد سان، گڏ ڪرڻ TON ممڪن طور تي آسان آهي:

$ cd ~/.config/nixpkgs/overlays && git clone https://github.com/serokell/ton.nix
$ cd /path/to/ton/repo && nix-shell
[nix-shell]$ cmakeConfigurePhase && make

نوٽ ڪريو ته توهان کي ڪنهن به انحصار کي انسٽال ڪرڻ جي ضرورت ناهي. Nix جادوئي طور تي توهان لاءِ سڀ ڪجهه ڪندو، ڇا توهان استعمال ڪري رهيا آهيو NixOS، Ubuntu، يا macOS.

TON لاء پروگرامنگ

TON نيٽورڪ ۾ سمارٽ ڪانٽريڪٽ ڪوڊ TON ورچوئل مشين (TVM) تي هلندو آهي. TVM ٻين مجازي مشينن کان وڌيڪ پيچيده آهي، ۽ تمام دلچسپ ڪارڪردگي آهي، مثال طور، اهو ڪم ڪري سگهي ٿو. تسلسل и ڊيٽا سان ڳنڍيل.

ان کان علاوه، TON مان ماڻهو ٽي نوان پروگرامنگ ٻوليون ٺاهيا آهن:

پنجون هڪ عالمگير اسٽيڪ پروگرامنگ ٻولي آهي جيڪا هڪجهڙائي رکي ٿي فورٿ. هن جي سپر قابليت TVM سان لهه وچڙ ڪرڻ جي صلاحيت آهي.

فن سي هڪ سمارٽ ڪانٽريڪٽ پروگرامنگ ٻولي آهي جيڪا ساڳي آهي C ۽ ٻئي ٻوليءَ ۾ مرتب ڪيو ويو آهي - Fift Assembler.

پنجون جمع ڪندڙ - ٽي وي ايم لاءِ بائنري ايگزيڪيوٽو ڪوڊ پيدا ڪرڻ لاءِ ففٽ لائبريري. پنجين اسمبلر وٽ ڪو ڪمپلر ڪونهي. هي شامل ٿيل ڊومين مخصوص ٻولي (eDSL).

اسان جو مقابلو ڪم ڪري ٿو

آخرڪار، اهو وقت آهي اسان جي ڪوششن جي نتيجن کي ڏسڻ لاء.

هم وقت ادائگي چينل

ادائيگي چينل هڪ سمارٽ معاهدو آهي جيڪو ٻن صارفين کي بلاڪچين کان ٻاهر ادائيگي موڪلڻ جي اجازت ڏئي ٿو. نتيجي طور، توهان نه رڳو پئسا بچائيندا آهيو (ڪو به ڪميشن ناهي)، پر وقت پڻ (توهان کي پروسيس ٿيڻ لاء ايندڙ بلاڪ جو انتظار ڪرڻو پوندو). ادائگيون ننڍيون ٿي سگھن ٿيون جيترو گھربل ۽ جيترو گھربل آھي. انهي حالت ۾، پارٽين کي هڪ ٻئي تي ڀروسو ڪرڻ جي ضرورت ناهي، ڇو ته حتمي حل جي منصفانه سمارٽ معاهدي جي ضمانت آهي.

اسان کي مسئلي جو ڪافي سادو حل مليو. ٻه پارٽيون دستخط ٿيل پيغامن کي مٽائي سگهن ٿيون، هر هڪ ۾ ٻه نمبر آهن- هر پارٽي طرفان ادا ڪيل مڪمل رقم. اهي ٻه نمبر ڪم ڪن ٿا ویکٹر ڪلاڪ روايتي ورهايل سسٽم ۾ ۽ ٽرانزيڪشن تي "اڳ ۾ ٿيو" آرڊر مقرر ڪريو. هن ڊيٽا کي استعمال ڪندي، معاهدو ڪنهن به ممڪن تڪرار کي حل ڪرڻ جي قابل هوندو.

حقيقت ۾، هن خيال کي لاڳو ڪرڻ لاء هڪ نمبر ڪافي آهي، پر اسان ٻنهي کي ڇڏي ڏنو ڇو ته هن طريقي سان اسان هڪ وڌيڪ آسان يوزر انٽرفيس ٺاهي سگهون ٿا. ان کان علاوه، اسان هر پيغام ۾ ادائگي جي رقم شامل ڪرڻ جو فيصلو ڪيو. ان کان سواء، جيڪڏهن پيغام ڪنهن سبب جي ڪري گم ٿي ويو آهي، پوء، جيتوڻيڪ سڀئي مقدار ۽ آخري حساب صحيح هوندا، صارف شايد نقصان کي نوٽيس نه ڪري سگھن.

اسان جي خيال کي جانچڻ لاءِ، اسان ڏٺو مثالن جي استعمال جي اهڙي سادي ۽ جامع ادائگي چينل پروٽوڪول. حيرت انگيز طور تي، اسان صرف ٻه مليا:

  1. بيان ھڪڙو ساڳيو طريقو، صرف ھڪڙي غير طرفي چينل جي صورت ۾.
  2. ٽيوشن، جيڪو بيان ڪري ٿو ساڳيو خيال جيڪو اسان جو آهي، پر ڪيترن ئي اهم تفصيلن جي وضاحت ڪرڻ کان سواءِ، جيئن عام درستي ۽ تڪرار جي حل جا طريقا.

اهو واضح ٿيو ته اهو اسان جي پروٽوڪول کي تفصيل سان بيان ڪرڻ جو احساس آهي، ان جي درستي تي خاص ڌيان ڏيڻ. ڪيترن ئي ورهاڱي کان پوء، وضاحت تيار هئي، ۽ هاڻي توهان پڻ ڪري سگهو ٿا. هن کي ڏس.

اسان FunC ۾ ڪانٽريڪٽ تي عمل ڪيو، ۽ اسان پنھنجي ڪانٽريڪٽ سان مڪمل طور تي Fift ۾ رابطو ڪرڻ لاءِ ڪمانڊ لائن يوٽيلٽي لکيو، جيئن آرگنائيزرز جي تجويز ڪيل آھي. اسان پنھنجي CLI لاءِ ڪا ٻي ٻولي چونڊي سگھون ھا، پر اسان Fit جي ڪوشش ڪرڻ ۾ دلچسپي وٺندا ھئاسين ته ڏسو ته اھو عملي طور تي ڪيئن ڪم ڪري ٿو.

ايمانداريءَ سان، ففٽ سان ڪم ڪرڻ کان پوءِ، اسان هن ٻوليءَ کي ترقي يافته اوزارن ۽ لائبريرين سان مشهور ۽ فعال طور تي استعمال ٿيندڙ ٻولين تي ترجيح ڏيڻ لاءِ ڪي به زبردست سبب نه ڏٺا. اسٽيڪ تي ٻڌل ٻولي ۾ پروگرامنگ ڪافي ناپسنديده آهي، ڇو ته توهان کي مسلسل پنهنجي سر ۾ رکڻو پوندو ته اسٽيڪ تي ڇا آهي، ۽ ڪمپلر ان سان مدد نٿو ڪري.

تنهن ڪري، اسان جي راء ۾، ففٽ جي وجود جو واحد جواز اهو آهي ته ان جو ڪردار ففٽ اسمبلر لاءِ ميزبان ٻولي جي حيثيت ۾. پر ڇا اهو بهتر نه هوندو ته TVM اسمبلر کي ڪنهن موجوده ٻولي ۾ شامل ڪيو وڃي، بجاءِ ان بنيادي مقصد لاءِ ڪا نئين ايجاد ڪرڻ جي؟

TVM Haskell eDSL

هاڻي اهو اسان جي ٻئي سمارٽ معاهدي بابت ڳالهائڻ جو وقت آهي. اسان هڪ گھڻن دستخطي والٽ کي ترقي ڪرڻ جو فيصلو ڪيو، پر FunC ۾ هڪ ٻيو سمارٽ معاهدو لکڻ ڏاڍو بورنگ هوندو. اسان ڪجهه ذائقو شامل ڪرڻ چاهيون ٿا، ۽ اها اسان جي پنهنجي اسيمبلي جي ٻولي هئي TVM لاءِ.

Fift Assembler وانگر، اسان جي نئين ٻولي سرايت ڪئي وئي آهي، پر اسان ففٽ جي بدران Haskell کي ميزبان طور چونڊيو، اسان کي ان جي جديد قسم جي سسٽم مان پورو فائدو وٺڻ جي اجازت ڏني. جڏهن سمارٽ معاهدي سان ڪم ڪري رهيا آهيو، جتي هڪ ننڍڙي غلطي جي قيمت تمام گهڻي ٿي سگهي ٿي، جامد ٽائپنگ، اسان جي راء ۾، هڪ وڏو فائدو آهي.

اهو ڏيکارڻ لاءِ ته TVM اسمبلر ڇا ڏسڻ ۾ اچي ٿو هاسڪل ۾ شامل ٿيل ، اسان ان تي هڪ معياري والٽ لاڳو ڪيو. هتي ڪجھ شيون آهن جن تي ڌيان ڏيڻ گهرجي:

  • هي معاهدو هڪ فنڪشن تي مشتمل آهي، پر توهان استعمال ڪري سگهو ٿا جيترو توهان چاهيو. جڏهن توهان ميزبان ٻولي (يعني هاسڪيل) ۾ هڪ نئين فنڪشن جي وضاحت ڪريو ٿا، اسان جو اي ڊي ايس ايل توهان کي اهو چونڊڻ جي اجازت ڏئي ٿو ته ڇا توهان چاهيو ٿا ته اهو TVM ۾ هڪ الڳ معمول بڻجي وڃي يا صرف ڪال جي نقطي تي.
  • هاسڪيل وانگر، افعال جا قسم آهن جيڪي مرتب ڪيل وقت تي چڪاس ڪيا ويا آهن. اسان جي eDSL ۾، هڪ فنڪشن جو ان پٽ قسم اسٽيڪ جو قسم آهي جيڪو فنڪشن توقع ڪري ٿو، ۽ نتيجو قسم اسٽيڪ جو قسم آهي جيڪو ڪال کان پوء پيدا ڪيو ويندو.
  • ڪوڊ ۾ تشريحون آهن stacktype، ڪال پوائنٽ تي متوقع اسٽيڪ قسم جي وضاحت ڪندي. اصل والٽ جي معاهدي ۾ اهي صرف تبصرا هئا، پر اسان جي اي ڊي ايس ايل ۾ اهي اصل ۾ ڪوڊ جو حصو آهن ۽ مرتب ڪيل وقت تي چڪاس ڪيا ويا آهن. اهي دستاويزن يا بيانن جي طور تي ڪم ڪري سگهن ٿيون جيڪي ڊولپر کي مسئلو ڳولڻ ۾ مدد ڪن ٿيون جيڪڏهن ڪوڊ تبديل ٿئي ٿي ۽ اسٽيڪ قسم تبديل ٿئي ٿي. يقينن، اهڙيون تشريحون رن ٽائم ڪارڪردگي تي اثرانداز نه ٿيون ٿين، ڇو ته انهن لاءِ ڪو به ٽي وي ايم ڪوڊ نه ٺاهيو ويو آهي.
  • اهو اڃا تائين هڪ پروٽوٽائپ آهي جيڪو ٻن هفتن ۾ لکيو ويو آهي، تنهنڪري اڃا تائين پروجيڪٽ تي تمام گهڻو ڪم ڪرڻو آهي. مثال طور، ڪلاس جا سڀئي مثال جيڪي توھان ھيٺ ڏنل ڪوڊ ۾ ڏسندا آھيو پاڻمرادو ٺاھيو وڃي.

اھو اھو آھي جيڪو ھڪڙي ملٽيگ والٽ جو نفاذ اسان جي اي ڊي ايس ايل تي نظر اچي ٿو:

main :: IO ()
main = putText $ pretty $ declProgram procedures methods
  where
    procedures =
      [ ("recv_external", decl recvExternal)
      , ("recv_internal", decl recvInternal)
      ]
    methods =
      [ ("seqno", declMethod getSeqno)
      ]

data Storage = Storage
  { sCnt :: Word32
  , sPubKey :: PublicKey
  }

instance DecodeSlice Storage where
  type DecodeSliceFields Storage = [PublicKey, Word32]
  decodeFromSliceImpl = do
    decodeFromSliceImpl @Word32
    decodeFromSliceImpl @PublicKey

instance EncodeBuilder Storage where
  encodeToBuilder = do
    encodeToBuilder @Word32
    encodeToBuilder @PublicKey

data WalletError
  = SeqNoMismatch
  | SignatureMismatch
  deriving (Eq, Ord, Show, Generic)

instance Exception WalletError

instance Enum WalletError where
  toEnum 33 = SeqNoMismatch
  toEnum 34 = SignatureMismatch
  toEnum _ = error "Uknown MultiSigError id"

  fromEnum SeqNoMismatch = 33
  fromEnum SignatureMismatch = 34

recvInternal :: '[Slice] :-> '[]
recvInternal = drop

recvExternal :: '[Slice] :-> '[]
recvExternal = do
  decodeFromSlice @Signature
  dup
  preloadFromSlice @Word32
  stacktype @[Word32, Slice, Signature]
  -- cnt cs sign

  pushRoot
  decodeFromCell @Storage
  stacktype @[PublicKey, Word32, Word32, Slice, Signature]
  -- pk cnt' cnt cs sign

  xcpu @1 @2
  stacktype @[Word32, Word32, PublicKey, Word32, Slice, Signature]
  -- cnt cnt' pk cnt cs sign

  equalInt >> throwIfNot SeqNoMismatch

  push @2
  sliceHash
  stacktype @[Hash Slice, PublicKey, Word32, Slice, Signature]
  -- hash pk cnt cs sign

  xc2pu @0 @4 @4
  stacktype @[PublicKey, Signature, Hash Slice, Word32, Slice, PublicKey]
  -- pubk sign hash cnt cs pubk

  chkSignU
  stacktype @[Bool, Word32, Slice, PublicKey]
  -- ? cnt cs pubk

  throwIfNot SignatureMismatch
  accept

  swap
  decodeFromSlice @Word32
  nip

  dup
  srefs @Word8

  pushInt 0
  if IsEq
  then ignore
  else do
    decodeFromSlice @Word8
    decodeFromSlice @(Cell MessageObject)
    stacktype @[Slice, Cell MessageObject, Word8, Word32, PublicKey]
    xchg @2
    sendRawMsg
    stacktype @[Slice, Word32, PublicKey]

  endS
  inc

  encodeToCell @Storage
  popRoot

getSeqno :: '[] :-> '[Word32]
getSeqno = do
  pushRoot
  cToS
  preloadFromSlice @Word32

اسان جي اي ڊي ايس ايل جو پورو سورس ڪوڊ ۽ ملٽي دستخط والٽ ڪانٽريڪٽ تي ملي سگهي ٿو هن مخزن. ۽ وڌيڪ تفصيل سان ٻڌايو تعمير ٿيل ٻولين بابت، اسان جي ساٿي جارجي اگاپوف.

مقابلي ۽ TON بابت نتيجا

مجموعي طور تي، اسان جي ڪم ۾ 380 ڪلاڪ (جنهن ۾ دستاويزن، گڏجاڻين ۽ حقيقي ترقي سان واقفيت شامل آهي). مقابلي واري منصوبي ۾ پنج ڊولپرز حصو ورتو: CTO، ٽيم ليڊ، بلاڪچين پليٽ فارم ماهر ۽ هاسڪيل سافٽ ويئر ڊولپر.

اسان کي مقابلي ۾ بغير ڪنهن ڏکيائي جي حصو وٺڻ لاءِ وسيلا مليا، ڇو ته هيڪاٿون جو جذبو، ٽيم جي ڪم کي بند ڪرڻ، ۽ نئين ٽيڪنالاجيءَ جي پهلوئن ۾ پاڻ کي تيزيءَ سان وسارڻ جي ضرورت هميشه دلچسپ آهي. محدود وسيلن جي حالتن ۾ وڌ کان وڌ نتيجا حاصل ڪرڻ لاءِ ڪيتريون ئي بي خواب راتيون انمول تجربي ۽ شاندار يادگيرين سان معاوضي ۾ ملن ٿيون. ان کان علاوه، اهڙن ڪمن تي ڪم ڪرڻ هميشه ڪمپني جي عملن جو هڪ سٺو امتحان هوندو آهي، ڇاڪاڻ ته اندروني رابطي جي سٺي ڪم ڪرڻ کان سواء صحيح نتيجا حاصل ڪرڻ تمام ڏکيو آهي.

غزل هڪ طرف: اسان TON ٽيم پاران ڏنل ڪم جي مقدار کان متاثر ٿيا. اهي هڪ پيچيده، خوبصورت، ۽ سڀ کان اهم، ڪم ڪندڙ نظام تعمير ڪرڻ ۾ ڪامياب ٿي ويا. TON پاڻ کي ثابت ڪيو آهي ته هڪ پليٽ فارم وڏي صلاحيت سان. تنهن هوندي، هن ماحولياتي نظام کي ترقي ڪرڻ لاء، گهڻو ڪجهه ڪرڻ جي ضرورت آهي، ٻنهي بلاڪچين منصوبن ۾ ان جي استعمال جي لحاظ کان ۽ ترقياتي اوزار کي بهتر ڪرڻ جي لحاظ کان. اسان کي فخر آھي ته ھاڻي ھن عمل جو حصو بڻجڻ تي.

جيڪڏهن هن آرٽيڪل پڙهڻ کان پوءِ توهان وٽ اڃا به ڪي سوال آهن يا توهان جا خيال آهن ته توهان جا مسئلا حل ڪرڻ لاءِ TON ڪيئن استعمال ڪجي، اسان کي لکو - اسان کي اسان جو تجربو حصيداري ڪرڻ لاء خوش ٿيندو.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو