آشنایی با پلتفرم اتریوم (Ethereum) و معماری EVM
اتریوم چیست؟
اتریوم یکی از بسترهای بلاکچین است که پس از بیتکوین معرفی شد. مهمترین مزیتی که اتریوم نسبت به بیتکوین دارد، امکان نوشتن و دپلوی قراردادهای هوشمند در بستر اتریوم می باشد. در این مقاله به طور کامل با پلتفرم اتریوم، انواع اکانت اتریوم و همچنین Fee های اتریوم آشنا خواهید شد.
ارز دیجیتال شبکه اتریوم
هر شبکه بلاکچین، یک ارز یا توکن نیتیو دارد که اصلی ترین کاربرد آن پرداخت هزینه تراکنش های شبکه (Transaction Fee) یا همان گس (Gas) می باشد. ارز نیتیو بلاکچین اتریوم، اتر (Ether) می باشد که به اختصار Eth نامیده می شود.
ارز اتر واحدهای کوچکتری هم دارد. کوچکترین واحد اتر، Wei است. واحد Gwei نیز کاربرد زیادی در محاسبات مالی در اتریوم دارد.
1 2 |
1 Eth = 10^18 Wei 1 Eth = 10^9 Gwei |
انواع اکانت در اتریوم
در شبکه اتریوم دو نوع اکانت وجود دارد. اکانت های EOA و Smart Contract.
هر آدرس اکانت اتریوم شامل 40 کاراکتر هگزادسیمال بوده و سایز آن 20 بایت (160 بیت) است. تصویر زیر نحوه ساخته شدن هر کدام از این آدرس ها را نشان می دهد:
تصویر زیر تفاوت های اصلی بین دو نوع اکانت را نشان می دهد:
EOAs
اکانت های EOA (Externally Owned Account) از یک جفت کلید خصوصی (Private Key) و کلید عمومی (Public Key) تشکیل شده اند. به کلید عمومی یک اکانت EOA، آدرس اکانت، آدرس ولت یا آدرس عمومی اتریوم گفته می شود. هر اکانت EOA تحت کنترل یک کاربر بوده و فقط همان کاربر می تواند با استفاده از یک کیف پول بلاکچینی (Wallet) مانند متامسک (Metamask) تراکنش انجام داده و بخش دلخواهی از موجودی خود را به اکانت اتریوم دلخواهی ارسال نماید. اجرای موفق یک تراکنش انتقال مبلغ توسط یک کاربر، با امضاء (Sign) آن تراکنش توسط کلید خصوصی اکانت کاربر امکانپذیر می باشد. مالکیت یک اکانت EOA در اختیار کسی است که Private Key آن اکانت را در اختیار دارد. بنابراین اگر کلید خصوصی یک اکانت به دست فرد دیگری بیفتند، عملا آن اکانت هک شده است.
Smart Contracts
نوع دوم اکانت های اتریوم، اسمارت کانترکت ها هستند. این اکانت ها شامل یک آدرس و یک استوریج (Storage) می باشند. اکانت های قرارداد هوشمند، فاقد کلید خصوصی می باشند. اسمارت کانترکت ها در واقع برنامه های کامپیوتری هستند که توسط برنامه نویس نوشته شده و سپس با عمل دپلوی روی شبکه بلاکچین قرار می گیرند و توسط ماینر (Miner) ها و فول نود (Full Node) ها اجرا می شوند. برای اجرای یک فانشکن از قرارداد هوشمند، یک اکانت (EOA یا Contract) باید یکی از فانشکن های آن قرارداد هوشمند را توسط یک تراکنش (Transaction) یا مسیج کال (Message Call) فراخوانی نماید.
قرارداد هوشمند در اتریوم
یکی از ویژگی های مهم قراردادهای هوشمند تغیرناپذیری (immutability) آنها است. یک قرارداد هوشمند به محض دپلوی شدن در بلاک چین اتریوم، دیگر قابل تغییر نخواهد بود. البته توجه داشته باشید با معرفی شدن تکنیک های مختلف Upgradability اسمارت کانترکت، مانند پراکسی (Proxy)، قراردادهای هوشمند دیگر به معنای واقعی immutable نیستند و می توان اسمارت کانترکت هایی نوشت که حتی پس از دپلوی روی شبکه، با حفظ آدرس، کد و عملکرد آنها می تواند تغیر کند. هرچند تکنیک پراکسی امروزه در بسیاری از پروژه های بلاکچینی استفاده می شود ولی در واقع این موضوع بر خلاف خاصیت immutability بلاکچین است و ممکن است آسیب قابل توجهی به سطح اعتماد (Trust) یک پروژه بلاکچین در جامعه کاربران پروژه داشته باشد.
یک قرارداد هوشمند، برخلاف سایر نرم افزارها و اپلیکیشن های عادی، از لحاظ فضای ذخیره سازی و دسترسی به دیتا، محدودیت های بسیاری دارد. این محدودیت ها به خاطر زیرساخت اجرایی قراردادهای هوشمند است. اسمارت کاترکت های مثل سایر برنامه های کامپیوتری از CPU و RAM بهره مند نیستند بلکه باید روی یک واحد اجرایی بسیار محدود به نام ماشین مجازی اتریوم (EVM) اجرا شوند.
قراردادهای هوشمند به طور مستقیم قادر به خواندن دیتای خارج از بلاکچین (Off-chain) نیستند و فقط قادر به خواندن اطلاعات موجود روی بلاکچین (On-Chain) هستند. البته ناگفته نماند که با بکارگیری تکنولوژی اوراکل (Oracles) می توان به دیتای خارج از زنجیره نیز دسترسی پیدا کرد.
هزینه اجرای تراکنش در اتریوم
انجام هر تراکنش (Transaction) روی شبکه بلاکچین اتریوم (مانند سایر شبکه های بلاکچین)، شامل هزینه می باشد که اجرا کننده تراکنش موظف است این هزینه (Fee) را با Eth پرداخت نماید. برای فرموله کردن هزینه تراکنش ها در شبکه بلاکچین، از یک واحد به نام گس (Gas) استفاده می شود. در واقع هزینه ای که کاربر باید برای اجرای یک تراکنش پرداخت کند ضریبی از Gas می باشد. هر واحد گس بر اساس یک سری محاسبات و قوانین (eip-1559) در شبکه اتریوم قیمت گذاری شده و قیمت هر واحد گس (Gas Price) مشخص می شود و حتی کاربر می تواند با پرداخت Eth بیشتری به ازای هر واحد گس، تراکنش خود را سریع تر و با اولیت بیشتری اجرا کند.
در مورد گس تراکنش به این نکته نیز توجه داشته باشید که شما می توانید همراه با یک تراکنش، گس بیشتری بفرستید تا احیاناً به خاطر کمبود گس، اجرای تراکنش ناتمام نماند. نکته جالب این است که اگر شما مقدار گس اضافی پرداخت کرده باشید، همه گس ارسالی شما مصرف نخواهد شد. مقدار گس باقیمانده به حساب شما برگشت (Refund) داده می شود.
شاید این سوال برای شما پیش بیاید که دلیل پرداخت هزینه برای اجرای تراکنش در اتریوم چیست! برای پاسخ به این سوال، از چند جنبه به بررسی موضوع Gas اتریوم خواهیم پرداخت.
1- حفظ کارایی شبکه
در نظر داشته باشید که EVM یک کامپوتر مجازی است و هر کامپیوتر یک ماشین تورینگ کامل (Turing complete) است. همچنین هر قرارداد هوشمند یک برنامه کامپیوتری است که روی یک ماشین تورینگ کامل اجرا می شود. حال مسئله است که هیچ راهی برای اثبات پایان پذیر بودن اجرای برنامه ها روی یک ماشین تورینگ کامل وجود ندارد و اجرای یک برنامه ممکن است تا بی نهایت طول بکشد. در محیط غیرمتمرکزی مانند بلاکچین که هر کاربری می تواند قرارداد هوشمند دلخواه خود را نوشته و در شبکه دپلوی کند، این امکان وجود دارد که برخی اسمارت کانترکت ها در حلقه بی نهایت قرار گرفته و منابع شبکه در انحصار چند کاربر قرار گیرد.
برای حل این مشکل، ایده اجرای برنامه ها با یک مدل مبتنی بر تراکنش مطرح شد. بر اساس این طرح، اجرای هر کار (فانشکن) در قالب چند تراکنش انجام می شود. و از آنجایی که تراکنش ها برای اجرا باید در بلاک درج شوند و هر بلاک نیز ظرفیت محدودی برای نگهداری تراکنش ها دارد، اجرای یک فانشکن نمی تواند تا بی نهایت طول بکشد.در نظر گرفتن هزینه Gas برای انجام هر تراکنش و همچنین محدود کردن هر بلاک از لحاظ اندازه Gas، موجب می شود هر بلاک به تعداد محدودی تراکنش داشته باشد و کاربر نتواند به مدت طولانی تر از تشکیل یک بلاک، منابع بلاکچین را در دست داشته باشد.
2- محدودیت فضای ذخیره سازی بلاکچین
دلیل دیگر اعمال هزینه برای انجام تراکنش روی شبکه اتریوم این است که دیتای شبکه اتریوم روی یک لجر با تکنولوژی DLT ذخیره می شود که حجم کنونی لجر اتریوم در سال 2023 به بیش از 1 TB رسیده است. لجر بلاچین توسط نودهای بلاکچین نگهداری می شود. همچنین نگهداری و اجرای اسمارت کانترکت ها نیز توسط EVM مستقر روی نودهای بلاکچین صورت می گیرد. بنابراین اگر محدودیتی در مصرف فضای بلاکچین در نظر گرفته نشود، سایز لجر به سرعت افزایش یافته و ممکن است با تکنولوژی فعلی (ظرفیت ذخیره سازی کامپیوترها) خیلی از نودها امکان نگهداری لجر را نداشته باشند و کاهش تعداد نودها برابر است با کاهش سرعت و امنیت شبکه بلاکچین.
در شبکه اتریوم، کاربر بسته به اندازه دیتایی که روی بلاک چین می نویسد، هزینه پرداخت می کند. بنابراین کاربر تلاش می کند تا حد امکان، استفاده کمتری از فضای بلاکچین داشته و هزینه کمتری پرداخت کند.
3- حفظ امنیت شبکه
خاصیت immutable بودن تراکنش ها در بلاکچین توسط کاری که ماینرها انجام می دهند صورت می گیرد. تراکنش ها توسط ماینرها در بسته هایی به نام بلاک قرار گرفته و با افزوده شدن هر بلاک به زنجیره (ماین شدن) تراکنش های آن بلاک اجرا می شود. وظیفه ماینرها این است که تراکنش ها را از استخر تراکنش ها برداشته و با انجام یک سری محاسبات رمزنگاری از جمله Hash و … تراکنش ها را به بلاک تبدیل کرده و در زنجیره درج کنند. طوری که هر تراکنش پس از ماین شدن بلاک حاوی آن تراکنش، تغییرناپذیر شده و امکان هیچگونه تقلب یا دستگاری روی دیتای تراکنش وجود نداشته باشد.
همچنین هرچه تعداد ماینرها بیشتر باشد امکان بروز حمله 51 درصد کمتر خواهد بود. بنابراین باید یک طرح تشویقی وجود داشته باشد تا ماینرهای بیشتری حاضر باشند در شبکه کار کنند. مبلغی که شبکه بلاکچین به ماینرها پرداخت می کند از هزینه تراکنش ها تأمین می شود. بخشی از هزینه ای که برای اجرای تراکنش ها از کاربران دریافت می شود به حساب ماینرها واریز می شود.
ساختار شبکه اتریوم
State شبکه اتریوم
به وضعیت فعلی موجودی اکانت ها (account balances)، استوریج کانترکت (contract storage)، کد کانترکت (contract code)، نانس اکانت ها (account nonces) در یک بلاکچین، State گفته می شود. ساختار state اتریوم به صورت یک درخت Merkle-Patricia Trie است که در رأس درخت ریشه state قرار می گیرد.
هر تراکنش State بلاکچین را تغییر داده و آن را از state قبلی به state جدید می برد.
تراکنش های اتریوم
تراکنش ها در شبکه بلاکچین اتریوم دارای فیلدهای زیر هستند:
Nonce : عدد صحیح منحصر بفرد که تعداد تراکنش های ارسال شده از یک اکانت را نشان می دهد.
gasPrice : مقدار Eth پرداخت شده به ازای هر واحد Gas.
gasLimit : حداکثر تعداد واحد گس که کاربر تمایل دارد برای این تراکنش هزینه کند.
to : آدرس گیرنده تراکنش.
value : مقدار Eth ارسال شده به گیرنده طی این تراکنش.
signature : مقادیر V و R و S از امضای تراکنش
init (optional) : زمانی که تراکنش یک تراکنش ساخت کانترکت باشد از این فیلد استفاده می شود.
data (optional) : زمانی که تراکنش یک مسیج کال باشد این فیلد دیتای ورودی را نگهداری می کند.
بلاک های اتریوم
اتریوم یک شبکه بلاک چین است و طبیعتاً هر شبکه بلاکچین از توالی یا زنجیره (chain) ای از بلاک ها تشکیل می شود. بلاک ها در شبکه بلاکچین به صورت مرتب قرار می گیرند و بلاک جدید به آخرین بلاک وصل می شود.
در ادامه، فیلدهای یک بلاک در شبکه اتریوم توضیح داده شده است:
Timestamp : زمان ماین شدن بلاک – بر حسب ثانیه و با فرمت unix epoch.
Block number : طول زنجیره اتریوم بعد از ساخت و افزوده شدن بلاک جاری – عدد صحیح.
Difficulty : سختی شبکه بلاکچین (کار هشینگ یا استیکینگ مورد نیاز) برای ماین شدن یک بلاک – عدد هگزادسیمال.
Nonce : یک مقدار عددی که باید در ترکیب با mixHash پیدا شود تا ماین شدن بلاک توسط pow را اثبات کند.
mixHash : یک شناسه منحصر بفرد برای بلاک.
Parent hash : هش بلاکی که قبل از بلاک قعلی ماین شده است.
Transactions root : ریشه درخت مرکل (Merkle tree) متشکل از هش تمام تراکنش های قرار گرفته در بلاک.
State root : ریشه درخت مرکل-پاتریکا (Merkle-Patricia tree) متشکل از هش فیلدهای state شبکه.
Receipt hash : هش اطلاعات گیرنده (recipient).
ماشین مجازی اتریوم (EVM)
به عنوان یک تعریف سطحی، می توان گفت EVM یک دیتابیس بزرگ برای نگهداری اطلاعات تمام اکانت های اتریوم (EOA و CA) می باشد. به بیان دقیق تر، EVM یک ماشین تورینگ کامل، 256-بیتی، مبتنی بر استک است.
مشکل هالتینگ (halting problem)
چون evm یک ماشین تورینگ کامل (Turing complete) است، مشکل هالتینگ را دارد. در واقع هیچ راهی برای اطمینان از پایان پذیر بودن یک برنامه وجود ندارد مگر اینکه آن را اجرا کنیم. راه حل EVM برای مسئله هالتینگ این بوده که برای واحدهای اجرایی یک مقیاس به نام Gas در نظر گرفته که متناسب با منابع فیزیکی مورد نیاز برای اجرای دستورالعمل است.
مقدار گس هر تراکنش محدود بوده و ارسال کننده تراکنش می بایست متناسب با تعداد گس استفاده شده طی اجرای تراکنش، هزینه تراکنش را بر حسب Eth پرداخت کند. بدینصورت توسعه دهندگان اسمارت کانترکت ها همواره سعی می کنند کدهای بهینه تری بنویسند. بهینه بودن در اینجا یعنی مصرف گس کمتر برای انجام یک کار مشخص.
Virtual Machine
EVM یک پلتفرم نرم افزاری یا کامپیوتر مجازی است که به عنوان هسته اجرایی در قالب یک نرم افزار روی سیستم عامل هر نود (Node) از شبکه اتریوم و سایر شبکه های evm-compatible نصب شده و دائما در حال اجرا می باشد. یکی از ویژگی های جالب همه VM ها (از جمله EVM) این است که روی سخت افزارها و سیستم عامل های مختلف قابل اجرا بوده و محدود به سخت افزار یا سیستم عامل خاصی نیست. تصویر زیر جایگاه EVM در معماری لایه ای اتریوم را نشان می دهد:
EVM به زبان های مختلف پیاده سازی شده است. یکی از این پیاده سازی ها GoEthereum است که به آن Geth گفته می شود. این نسخه از EVM به زبان Go پیاده سازی شده و با نصب Geth روی کامپیوتر نود نصب می شود.
Opcodes
ماشین مجازی اتریوم دارای مجموعه دستور العمل های محدودی است که هر دستور زبان سالیدیتی به چندین دستور العمل زبان ماشین (Opcode) ترجمه می شود. هر آپکد 1 بایت است و کلاً evm حداکثر 256 آپکد می تواند داشته باشد.
برای سادگی کار، ما آپکدهای evm را به اینصورت دسته بندی می کنیم:
آپکدهای کار با استک
- POP
- PUSH
- DUP
- SWAP
بیتی، مقایسه، ریاضیاتی
- ADD
- SUB
- GT
- LT
- AND
- OR
محیطی
- CALLER
- CALLVALUE
- NUMBER
کار با مموری
- MLOAD
- MSTORE
- MSTORE8
- MSIZE
کار با استوریج
- SLOAD
- SSTORE
آپکدهای مرتبط با PC
- JUMP
- JUMPI
- PC
- JUMPDEST
آپکدهای مرتبط با هالتینگ
- STOP
- RETURN
- REVERT
- INVALID
- SELFDESTRUCT
bytecode
در فرآیند کامپایل، هر دستور سالیدیتی به یک یا چند آپکد ترجمه می شود. سپس به منظور بهینه سازی، opcode ها به فرمت هگزادسیمال تبدیل می شود. با این تبدیل، بایت کد (bytecode) کانترکت بدست می آید.
با دپلوی شدن کانترکت، این بایت کد، طی یک تراکنش ساخت کانترکت (Contract Creation) وارد بلاکچین شده و روی تمام نودهای شبکه کپی می شود. پس از آن هر کسی می تواند با داشتن آدرس آن اسمارت کانترکت، آن را فراخوانی کند.
تصویر زیر چگونگی تبدیل آپکدها به بایت کد را به تصویر کشیده است:
توجه داشته باشید که هر آپکد 1 بایت است و هر بایت معادل 2 کاراکتر هگزادسیمال (0x60 : PUSH1).
State Machine
EVM به صورت یک State Machine عمل کرده و با ورود هر بلاک به لجر، یک سری کد ماشین را اجرا کرده و state بلاکچین را آپدیت می کند.
EVM نصب شده روی نودها یک ماشین حالت توزیع شده (distributed state machine) را تشکیل می دهند و مسئولیت مدیریت فراخوانی کانترکت ها و تغییرات state بلاکچین را بر عهده دارند.
معماری EVM
Storage
فضای استوریج یک حافظه با ساختار key-value و قابلت خواندن/نوشتن توسط کانترکت است. ازآنجایی که اندازه کلیدها 256 بیت است، تنها 256^2 خانه حافظه در استوریج قابل آدرس دهی می باشد. بنابراین می توان گفت استوریج دارای 256^2 اسلات حافظه است که در هر اسلات یک مقدار 32 بایتی نگهداری می شود.
چون اطلاعات Storage بصورت دائمی روی بلاکچین ذخیره می شود و تغییرات آن حتی پس از اتمام فراخوانی کانترکت نیز باقی خواهد ماند، استفاده از این حافظه پر هزینه می باشد.
Memory
فضای مموری، یک حافظه موقت خطی (linear) قابل expand با قابلیت خواندن و نوشتن می باشد. این فضا را می توان بصورت یک آرایه 1-بعدی تصور کرد که در ابتدا خالی بوده و سایز هر خانه از این آرایه 256 بیت یا همان 32 بایت است. عمل خواندن، نوشتن و expand کردن این نوع حافظه هزینه دارد ولی هزینه استفاده از این فضا بسیار کمتر از Storage است.
توجه داشته باشید که ظرفیت فضای memory داینامیک بوده و اگر طی expand حافظه، سایز فضای مموری مقدار آستانه (threshold) را رد کند، هزینه با مرتبه n^2 رشد خواهد کرد. بنابر این با اینکه سایز حافظه memory به صورت تئوری محدود نیست ولی به خاطر بحث هزینه، در عمل محدود می شود.
دستور MLOAD یک کلمه حافظه 256 بیتی را از آدرس داده شده، می خواند. دستور MSTORE یک دیتای 256 بیتی را در آدرس داده شده، ذخیره می کند.
Calldata
این دیتالوکیشن محلی است که پارامترهای ورودی یا آرگومان های فانشکن call شده است در آن ذخیره شده و در payload تراکنش ارسال می شود. فضای کال دیتا مثل مموری است با این تفاوت که این فضا Readonly بوده و قابلیت نوشتن ندارد. همچنین پس از تخصیص برای هر کال، قابلیت expand ندارد. فضای کال دیتا بسیار ارزان تر از مموری بوده و هزینه گس پایین تری دارد.
Stack
اغلب زبان های سطح بالا این امکان را دارند که برنامه نویس، آرگومان ها را مستقیما به فانشکن بفرستد ولی زبان های سطح پایین اغلب از یک استک برای پاس دادن مقادیر به فانشکن استفاده می کنند. معمولا هر عملگر، یک یا دو عملوند را از بالای استک برداشته و نتیجه عملیات را در بالای استک قرار می دهد. در EVM نیز فضای استک عمدتاً برای نگهداری ورودی/خروجی های دستورات اسمارت کانترکت استفاده می شود.
حافظه موقت استک (پشته) کلا قادر به نگهداری 1024 کلمه حافظه است که هر کلمه 256 بیت یا 32 بایت است. دلیل اینکه کلمات حافظه 256 بیت در نظر گرفته شده به خاطر سازگاری با الگوریتم رمزنگاری است. در هر لحظه evm تنها به 16 آیتم بالایی استک دسترسی دارد و آیتم های پایین تر را نمی تواند بردارد. به همین دلیل، آپکدهای پیچیده تر برای پاس دادن یا دسترسی به دیتا، به جای استک از فضای مموری کانترکت استفاده می کنند.
ساختار فضای استک به صورتی است که دسترسی فقط به عنصر بالای استک میسر است و تنها دو عمل push و pop در این نوع حافظه انجام پذیر است. push برای درج عنصر جدید به بالای استک و pop برای برداشتن عنصر بالای استک. معمولاً عملیات ریاضی مانند ضرب به اینصورت انجام می شود که ابتدا دو عنصر از بالای استک برداشته شده و سپس حاصل ضرب آن دو عنصر به بالای استک اضافه می شود.
مدل اجرایی EVM
انواع فراخوانی (Call)
اگ یک کانترکت، بخواهد یک فانشکن از کانترکت دیگر را فراخوانی کند این کار از طریق یک مسیج کال (Message Call) انجام می شود. وقتی یک کال انجام می شود، کانترکت مقصد نیز می تواند یک کانترکت دیگر را کال کند. این کار تا عمق 1024 مجاز است.
فرمت یک کال در زبان سالیدیتی به اینصورت است:
address.call.gas(gas).value(value)(data)
پارامترهایی که برای یک کال اهمیت دارد عبارتند از:
- Sender
- Recipient
- Payload
- Value
- Gas
یک قرارداد هوشمند وقتی که فراخوانی می شود، یک execution context ایجاد می کند که شامل data location های زیر است:
- Storage
- Memory
- Calldata
- Stack
External Call
یک کانترکت ممکن است با دستورالعمل call یک کانترکت دیگر را فراخوانی کرده و به صورت اختیاری data و Ether به کانترکت مقصد ارسال کند. در این حالت، کانترکت فراخوانی کننده یک context برای خود ایجاد کرده و تا زمانی که اجرای کانترکت مقصد متوقف (halt) شود، آن را بدون تغییر نگه می دارد.
Static Call
این دستورالعمل مانند call است با این محدودیت که تا لحظه اتمام فراخوانی، اجازه نمی دهد global state بروزرسانی شود. یعنی طی این نوع فراخوانی هیچ تغییری روی state بلاکچین انجام نخواهد شد و فقط عملیات خواندن مجاز خواهد بود.
Delegate Call
این دستورالعمل مانند call است با این محدودیت که از کانترکت مقصد فقط کد مورد استفاده قرار می گیرد و همه تغییرات و خواندن ها روی context کانترکت مبدأ انجام خواهد شد. از این نوع فراخوانی در کتابخانه های external و کانترکت های پراکسی (Proxy) استفاده می شود.
معرفی دوره آموزشی
با آموزش های تخصصی پیاده سازی قرارداد هوشمند امن و بهینه با ما همراه باشید. برای یادگیری پیاده سازی اصولی قرارداد هوشمند و ساخت توکن در بستر اتریوم می توانید در دوره آموزش برنامه نویسی بلاکچین و قرارداد هوشمند که در مرکز آموزش علوم نوین امیرکبیر برگزار می شود شرکت نمایید.
درباره مجید شبیری
کارشناس ارشد فناوری اطلاعات از دانشگاه صنعتی امیرکبیر. مدیر و مؤسس "علوم نوین امیرکبیر"، متخصص برنامه نویسی، شبکه، لینوکس و امنیت. از سال 84 همزمان با شروع تحصیلات دانشگاهی، وارد حوزه تخصصی مهندسی نرم افزار شدم و اکنون مشغول تحقیق، توسعه و آموزش در حوزه بلاک چین هستم و معتقدم بلاکچین به زودی فضای کسب و کارها را منقلب خواهد کرد.
نوشته های بیشتر از مجید شبیری
دیدگاهتان را بنویسید