На чем написать блокчейн
Языки блокчейн программиста. Разработки децентрализованных приложений
Поскольку человечество движется к оцифровке всех активов, базовые знания программирования становится необходимостью даже для любого человека, даже тех кто не увлекается технологиями. Это требование становится еще более очевидным, когда речь идет о сфере блокчейна. Если мы действительно стремимся к настоящей децентрализации, каждый из нас должен понимать как все работает, хотя бы на элементарном уровне. Независимо от того, являетесь ли вы опытным инженером-программистом или обычным Ивном, прежде чем изучать функции блокчейна, вы должны сначала выбрать язык программирования.
Для новой технологии, которая развивается в стремительном темпе, задача выбора языка программирования может быть не тривиальной. Их множество, тем не менее различные стартапы и проекты с открытым исходным кодом выбирают разные языки для создания своих продуктов, так как их фокус и набор желаемых функций различаются. Какого то стандарта и на данный момент, Ваш выбор будет в значительной степени соответствовать вашим личным критериям и типу приложений, которые вы хотите создавать.
Вы хотите начать карьеру в качестве разработчика блокчейн приложений? Или, может быть, вы просто хотите создать свою собственную криптовалюту просто для удовольствия. В этой статье мы рассмотрим самые популярные языки программирования, которые используются при разработке децентрализованных систем, чтобы помочь вам выбрать наиболее подходящий вариант.
Самые популярные языки программирования в блокчейне
Прежде всего, нам необходимо понять, какой из языков программирования используется чаще всего, когда речь идет о написании кода в блокчейне.
Прежде чем приступить к рассмотрению языков для блокчейн-программирования, нам нужно взглянуть на их дедушку — C ++. Этот язык был выпущен в 1985 году Бьярном Страуструпом, чтобы сделать оригинальный язык C более гибким. Более трех десятилетий спустя именно он использовался для создания сети биткоин.
В отличие от оригинального C, который ориентирован на процессы, C ++ является объектно-ориентированным. Такой подход делает C ++ более эффективным по времени, когда речь идет о написании кода. Данные вместе с функциями хранятся в так называемых объектах, которые впоследствии могут быть повторно использованы в других программах.
Благодаря своей зрелости, неудивительно, что с точки зрения разработки блокчейна, функциональные возможности C ++ достаточно хороши. Этот язык имеет управление памятью, которое обеспечивает скорость за счет эффективного управления процессором, многопоточность — которая позволяет одновременно выполнять параллельные / непараллельные задачи, удобную передачу семантики для копирования данных, полиморфизм во время компиляции для повышения производительности за счет разделения задач и изоляцию кода для разделения структур данных. Кроме того, его пользовательская база насчитывает более четырех миллионов разработчиков.
Плюсы: приложения независимы и мультиплатформенны
Минусы: довольно сложный в освоении, сложный и иногда трудный для отладки
Лучше всего подходит для: продвинутых пользователей, понимающих принципы сети Биткоин
C # не только гибок и прост в понимании, если вы знакомы с C ++ или Java, но также содержит множество функций. В дополнение к некоторым функциональным возможностям C ++ C # предлагает платформу. NET и ее библиотеку классов, среду выполнения общего языка и среды разработки (такие как WPF, XAML и ASP.NET).
C # предпочитают крупные блокчейн разработчики по нескольким причинам:
Открытый исходный код
Позволяет писать адаптированый для мобильных устройств код
Доступен благодаря программе BizSpark.
Плюсы: объектно-ориентированный, строго типизированный, динамическая поддержка кода
Минусы: слабая поддержка Linux
Лучше всего подходит для: создания блокчейнов инфраструктуры для пользователей Windows
JavaScript
Это, пожалуй, самый признанный язык программирования в мире. Веб-страницы, которые вы прокручиваете каждый день, используют javascript для интуитивно понятного, привлекательного и адаптивного внешнего вида (frontend ) веб сайтов и расширенной функциональности. Цитата 2007 года Джефф Этвуд:
«Любое приложение, которое может быть написано на JavaScript, в конечном итоге будет написано на JavaScript».
JavaScript — это ООП-язык, который легко выучить, но при этом он достаточно универсален. Используя JS, разработчики могут писать код для клиентской и серверной части, устройства IoT и машинного обучения. Одним из основных преимуществ JavaScript с точки зрения блокчейна является возможность асинхронного запуска событий, что означает, что он позволяет узлам свободно и эффективно взаимодействовать. Другая сила JS в том, что он не требует компиляции. В то же время простота обходится дорого. Несмотря на все свои функции, JS далека от C ++, но это отличный язык для начинающих.
JavaScript не был очень популярен среди разработчиков блокчейнов до взлета ICO проектов в 2017 году. В настоящее время на CoinMarketCap существует несколько стартапов с высокими рейтингами, основанных на этом языке, таких как Lisk, Ark и Nimiq. Один из наиболее заметных конкурентов Ethereum и Tron также поддерживает JavaScript.
Плюсы: объектно-ориентированный, основанный на прототипах, поддерживает функциональное программирование
Минусы: динамичный, слабо типизированный
Лучше всего подходит для: входа в блокчейн-пространство, создания приложений
Python
Python был создан в минималистском стиле. Вот почему этот язык чрезвычайно прост в изучении и является отличной отправной точкой для начинающих. Он был создан в 1991 году и служил множеству целей, таких как разработка приложений, разработка сетевых серверов, IoT и другие. Возможно, он еще не так признан, как JS, но безусловно, вызывает большой интерес в мире технологий.
Python был признан суперзвездами отрасли. IBM Hyperledger реализовал его в Sawtooth, а Ethereum создал свою собственную итерацию этого языка: Pyethereum.
Плюсы: очень легко учиться, готовые библиотеки и фреймворки, эффективен
Минусы: в основном используется как серверный язык
Лучше всего подходит для: Создание приложений для начинающих
Golang (или Go) — это язык с открытым исходным кодом, созданный на языке C. Это очень молодой язык, созданный в 2007 году разработчиками из Google. Реализация синтаксиса Go более похожа на Python — она упрощена, чтобы обеспечить эффективность и сделать проекты, созданные с ее помощью, ориентированными на будущее.
Сильные стороны Go для блокчейн-программирования включают в себя наличие модульного программирования, которое делает процесс разработки гибким, удобные инструменты тестирования и огромную библиотеку функций. Это было бы наиболее привлекательным для разработчиков облачных вычислений, поскольку распределенные вычисления очень просты с точки зрения этого языка. Хотя этот язык требует компиляции, он является хорошим фактором для безопасности, поскольку все ошибки будут показаны человеку, пишущему код, перед его запуском. Кроме того, параллельное программирование вместе с Goroutines повышает эффективность кода и пропускную способность приложений. Это очень важно для масштабируемости, которая сегодня является основной проблемой в пространстве блокчейнов. Наконец, Go работает с ОС, а не поверх нее. Это исключает дополнительный шаг при создании EVM, следовательно, увеличивает скорость.
Плюсы: безопасность памяти, сборка мусора, строго типизированы
Минусы: не так легко учиться, относительно небольшое сообщество, небольшое количество пакетов
Лучше всего подходит для: Создание облачных приложений
Solidity
Solidity молод, как Golang. Он был выпущен в 2014 году Кристианом Райтвайснером и его командой. Это язык, который был создан для написания умных контрактов на Ethereum, поэтому он наиболее популярен в экосистеме Ethereum. Стоит отметить, что за последние два года экосистема выросла в сотни раз из-за различных стартапов, наводнивших рынок. В результате Solidity имеет большую базу пользователей. Его стандарт ( ERC20 ) стал основным для отрасли.
Solidity ООП и контактно-ориентированный язык. Он также завершен по Тьюрингу, что означает, что он может интерпретировать различные правила манипулирования данными. Синтаксис Solidity похож на синтаксис JavaScript, но с C ++ и Python есть некоторые сходства. Несмотря на свою молодость, Solidity является функциональным языком, он предоставляет наследование, различные библиотеки и т. д. Недостатком являются проблемы с документацией, которые могут оставить некоторых разработчиков в затруднительном положении.
Плюсы: статично, легко учиться, модно
Минусы: не универсальный, уязвимый
Лучше всего подходит для: Разработка умных контрактов
Основы блокчейн программирования
Теперь, когда мы рассмотрели самые популярные языки программирования в блокчейне, пришло время показать примеры, перейти от теории к практике. Давайте посмотрим, как основные операции выполняются в разных языки программирования.
Прежде чем мы начнем, полезно уточнить наши знания о том, что такое блокчейн. Блокчейн — это распределенный регистр, в котором транзакции сохраняются в цепочке блоков.. Каждый новый блок имеет указатель на предыдущий в виде хэш-функции. После заполнения блока хеш генерируется с использованием всех его транзакций и присоединяется к нему. Существует также сервер отметок времени, который предотвращает двойные расходы и механизм согласования, который позволяет узлам согласовывать правильную версию реестра.
Теперь мы можем создать еще один блок. Для этого мы введем getLatestBlock ( ).
В результате мы увидим, как блокчейн сравнивает данные в хешах блоков, чтобы проверить, соответствуют ли они.
Механизм консенсуса представляет собой простую функцию цикла for, которая выполняется для всех блоков, начиная с 1, поскольку нет необходимости пересматривать блок 0 genesis.
Если мы визуализируем структуру, это выглядит так:
Вот как мы добавляем новые блоки:
Для того, чтобы наш блокчейн достиг консенсуса, например проверил его, нам нужно всего 2 строки кода вместе с методом IsValid, который будет проверять данные в каждом из блоков и сравнивать хэши.
3. JavaScript
Получив блок genesis, теперь мы добавим блоки с новыми данными через функцию nextBlock. Эта функция будет автоматически проходить все 5 типов данных и включать их в каждый новый блок.
Чтобы запустить наш блокчейн, нам нужно только убедиться, что процесс добавления блоков зацикливается бесконечно.
4. Python
На этот раз мы начнем с понимания того, как выглядит транзакция в Python. Это простой пост с отметкой времени и некоторыми данными.
Эти транзакции попадут в блоки. Давайте представим этот класс.
Мы будем использовать SHA-256, который используется в биткойнах для создания хэшей для проверки целостности нашей блокчейна.
После того, как это сделано, мы можем запустить наш блокчейн.
Мы начнем с определения свойств наших блоков. BPM — это произвольные данные, такие как сетевые транзакции, адреса и т. д.
Чтобы создать блоки, нам нужно хэшировать в них данные и связывать их по соответствующим результатам. Код для хеширования данных внутри блока в Go выглядит следующим образом:
Наконец, мы можем начать создавать новые блоки, используя функцию generateBlock. Время написать консенсус, который представлен функцией isBlockValid.
Поскольку все установлено, мы готовы запустить процесс производства блоков. Обратите внимание, что в этот момент для запуска блокчейна потребуется сервер, поэтому есть некоторые дополнительные фрагменты кода, отражающие это.
6. Solidity
Создание умных контрактов отличается от того, что мы только что рассмотрели. Во-первых, нам нужно создать контракт и назвать его. Этот контракт для исполнения воли человека, что в случае их смерти средства автоматически распределяются по конкретным адресам.
Здесь мы указываем адрес Эфириума владельца (владельца ), сумму, оставленную для распределения (единицы ) и условную переменную для состояния владельца (bool ). Следующим шагом является добавление модификаторов, которые расширяют условную логику для предоставления функции с состоянием владельца.
Когда это будет сделано, мы можем наметить адреса, которые получат наследство. Затем мы продолжаем указывать распределение средств в случае, если isDeceased = true. Обратите внимание, что на этом этапе мы можем скрыть функцию от общественности, поставив «private » рядом с функцией «payout ». Вуаля, код теперь можно развернуть.
Резюме
Подводя итог, нет только одного языка программирования, ориентированного на блокчейн. Сам блокчейн находится в зачаточном состоянии и существуют неизведанные горизонты и неизвестные материи. Как и во многих других сферах, лучший способ уверенно обойтись — стать full stack разработчиком, что может быть достаточно сложной задачей, учитывая сколько информации вам придется переработать. К счастью, многие языки программирования имеют сходство в синтаксисе и структуре для облегчения перехода.
Блокчейн на C# (.Net Core 3.1), Часть 0
Всем категорический привет! На связи из Волго-Вятского экономического района — великий и могучий Нукрас!
Вдохновившись этой и этой статьями, я, ̶к̶а̶к̶ ̶к̶о̶р̶е̶н̶н̶о̶й̶ ̶о̶д̶е̶с̶с̶и̶т̶ не преминул возможностью подрезать интересную идейку. Поэтому, встречайте, Блокчейн на C#, часть номер ноль!
Так как данная статья, по сути, является ̶ф̶о̶р̶к̶о̶м̶ сиквелом вышеуказанных статей, я не буду останавливаться на объяснении таких терминов как «блокчейн», «сложность», «майнинг» и так далее. В тех статьях, в принципе, все вполне понятно рассказали.
Ну и заранее отмечу, что с программированием я знаком на уровне младшего братика джуна, и вообще олень.
Первым делом определим класс «Block»
В классе «Block» мы будем хранить время, когда блок был создан, данные, который мы в него записываем, его хэш и значение nonce. Что-либо еще хранить в блоке считаю излишним.
Цепочку блоков мы будем хранить в списке:
А данный список будет лежать в статическом классе «Blockchain»:
Для того, чтобы добавлять блоки, напишем метод «AddBlock». Данный метод будет находиться в статическом классе «Blockchain», весь процесс майнинга будет происходить именно здесь.
Что такое «string dat = «genesis» и «string prvHash = «»? Дело в том, что в каждом уважающем себя блокчейне должен быть нулевой блок. В качестве нулевого блока у нас будет блок, в который будет записано слово «genesis», потому, что я так захотел.
Программистам не читать
Продолжим изучение метода добавления блока!
Думаю, не нужно объяснять, что это такое
Здесь мы и передаем в метод «getHash» время добавления, данные, хэш предыдущего блока и значение nonce.
Так как метод getHash вряд ли с первой попытки возвратит нам нужный хэш, придется проверять его на вхождение нужного количества нулей.
Воувоувоу! Полегче, ковбой! Что все это значит?!
Если в начале полученного хэша будут нули в количестве difficulity, то мы сделаем
Что такое difficulity? это количество нулей, находящихся в начале хэша блока, необходимое для добавления блока в блокчейн. Именно так мы решаем проблему сложности в нашем блокчейн-проекте. Кстати, сложность должна изменяться динамически, но об этом трошки позже.
В противном случае мы добавляем к nonce единичку и по-новой запускаем расчет хэша, получая абсолютно новое значения, и так по кругу, пока не найдем необходимое значение
Целиком код метода «AddBlock» выглядит так:
За кадром я написал простенькую логику, прямо в методе «Main» которая позволяла бы нам из консоли добавлять новый блок и выводить на экран все блоки.
Генезис-блок создается сразу же, с тридцать третьей попытки
Какой же блокчейн без блокчейн эксплорера? (К счастью, его написать крайне просто)
Этот всего лишь выводит на экран все блоки. Демонстрирую:
Все точно, как в аптеке
Но что будет, если какой-нибудь сумрачный гений решит всех обмануть и подменит данные в каком-нибудь блоке? Например Саня, который не хочет возвращать банку сотку вместе с кровной десяткой? На этот случай и был придуман метод «Verification»!
Блоки добавляются. Это хорошо Все блоки прошли проверку. Отлично
Теперь отредактируем третий блок, сделав вид, что мы ̶м̶о̶н̶а̶р̶х̶и̶с̶т̶ы̶
Нам удалось подделать блок! Прекрасно!
А теперь сисадмин Валера решил проверить, что творится на вверенном ему сервере, и запустил верификацию:
Сисадмин Валера спалил несанкционированное вмешательство в блокчейн, теперь он может сделать примерно то же, что мечтают сделать все пассажиры автобусов, когда видят тот самый молоточек: разбить стекло и выдернуть патч-корды (Я честно искал тот мем, но не нашел, может вы найдете)
В дополнение ко всему этому неплохо бы добавить динамически изменяющуюся сложность, что мы сделаем в статье номер один, и что-то вроде. GUI? Фу, мерзость. Также я хочу запихнуть это все на сервер, который будет заниматься лишь хранением и предоставлением блокчейна, считать хэш же будут должны юзеры, все как у взрослых криптовалют. Но это в будущем.
Всем большое спасибо за прочтение моей статьи, исходный код проекта вы сможете найти на гитхабе, ковыряйте в свое удовольствие!
Буду рад услышать критику и предложения, первая статья, все-таки!
Ну и, разумеется, ждите продолжения, оно не за горами! (Я еще не начинал, но все говорят именно так. )
(Эй, @ruvds не одолжите сервачок для третьей статьи?))
Языки программирования для блокчейна: на чем разрабатывают смарт-контракты?
6 августа криптосообщество узнало, что блокчейн-платформа Cosmos планирует интеграцию как минимум с двумя новыми языками программирования для смарт-контрактов: Secure ECMAScript (SES) и Kadenamint. Выход новых языков от Cosmos может привести к концу гегемонии Ethereum в сфере создания смарт-контрактов. Разберемся в новых языках программирования экосистемы Cosmos и вспомнил, какие еще из них пользуются популярностью среди блокчейн-разработчиков.
Secure ECMAScript, или SES, — язык для смарт-контрактов, основанный на JavaScript. Запуск SES был анонсирован блокчейн-стартапом Agoric в июле 2018 года и будет доступен для пользователей после того, как Cosmos выпустит свой протокол для взаимодействия блокчейнов (Inter-blockchain communications protocol). Ключевая идея SES базируется на работе Google в рамках проекта Caja и на архитектуре системы безопасности Locker Service от компании Salesforce. Оба продукта позволяют разработчикам работать со сторонним кодом в безопасной среде.
Kadenamint — новая версия языка программирования Pact. Данный язык программирования предназначен для работы с блокчейн-сетью платформы Kadena — дочерней компании JPMorgran. Основатель Kadena Стюарт Поупджой сообщил, что в рамках партнерства компания создает адаптированную под Cosmos версию своего языка Pact. Поупджой надеется, что сотрудничество с Cosmos даст разработчикам больше возможностей для работы с блокчейном Kadena, ведь, по мнению главы блокчейн-компании, Pact в разы превосходит язык Solidity от Ethereum:
«Мы видим в Pact новый стандарт среди языков программирования смарт-контрактов, поскольку он во всем лучше, чем Solidity. Каждый разработчик, который использует [Pact], работает быстрее. Он более безопасен. У нас есть официальная проверка на языке».
Помимо Kadenamint и Secure ECMAScript, есть и третий язык программирования для платформы Cosmos, который существует с 2016 года. Он называется Ethermint и по своему принципу работы практически идентичен Solidity — самому популярному языку для создания смарт-контрактов на блокчейн-платформе Ethereum.
Навигация по материалу:
Ethereum и Solidity
Solidity — язык программирования для смарт-контрактов Ethereum, который появился одновременно с релизом этой блокчейн-платформы в 2015 году. Создатели Solidity Кристиан Райтвизнер и Гевин Вуд сделали Solidity похожим на JavaScript и спецификацию для него ECMA-262, чтобы он был легко доступен широкому кругу разработчиков. В связи с чем в данный момент их количество превышает 200 000 человек. Те разработчики, которые знают один из современных языков программирования, например C#, C++, Python и выше упомянутый JavaScript, могут освоить Solidity достаточно быстро.
Однако Solidity все-таки несколько отличается от других языков программирования, поэтому новички совершают ошибки при написании кода. Так, смарт-контракты на блокчейне Ethereum исполняются с помощью собственной виртуальной машины EVM (Ethereum Virtual Machine), которая появилась вместе с запуском Ethereum в 2015 году и имеет ряд багов и уязвимостей. Например, EVM может хранить только ограниченное число хешей блоков, что позволяет обмануть крипто-казино, которое работает по принципу генератора случайных чисел на блокчейне Ethereum.
Сама EVM написана на компиляции нескольких языков программирования: JavaScript, C#, C/C++, Python, Ruby, Go, JavaScript. Помимо Solidity, существуют и версии клиентов Ethereum для этих языков программирования. Новая версия EVM и Solidity, вероятно, появится только вместе с обновлением платформы Ethereum 2.0 в 2020 году.
C, C++ и C#
C — один из старейших и самых популярных языков программирования в мире. С — компилируемый статически типизированный язык общего назначения, запущенный в 1972 году сотрудником Bell Labs Деннисом Ритчи. Данный язык оказал существенное влияние на развитие индустрии программного обеспечения, а его синтаксис стал основой для таких языков программирования, как C++, C#, Java и Objective-C.
Что касается C++, то именно на нем был написан исходный код Bitcoin. И хотя для написания смарт-контрактов в cети Ethereum он используется нечасто, зато именно с помощью C++ пишутся большинство смарт-контрактов для EOS. На нем также написан XRP Ledger — децентрализованный криптографический регистр, который хранит информацию о XRP. Также на C++ с JavaScript планирует переходить блокчейн-платформа NEM.
C# — это объектно-ориентированный язык программирования, разработанный Microsoft в 2000 году. В данный момент имеет более 2 млн разработчиков по всему миру. С помощью C# созданы блокчейн-платформы Stratis и NEO. Правда, у последнего, как и у Ethereum, есть клиенты и для других языков программирования: Python, Java и Go.
Этот относительно молодой язык программирования появился в 1995 году и с тех пор уже успел войти в тройку самых популярных в мире. Он является программной средой для выполнения сценариев EVM Ethereum, также на нем работает базовая сеть блокчейна NEM.
JavaScript
Этот мультипарадигмальный язык используют 9.7 млн программистов по всему миру. При разработке JavaScript основной целью было создание языка, похожего на Java, но при этом легкого для использования не-программистами. Языком JavaScript не владеет какая-либо компания или организация.
На сегодня наиболее широкое применение JavaScript находит в веб-браузерах, являясь языком сценариев, которые делают веб-страницы интерактивными. Что касается блокчейна, то на JavaScript написан SDK для создания dApps на сайдчейне Lisk, также его можно использовать для написания смарт-контрактов Ethereum.
Этот язык программирования создан IBM в 1974 году. Он очень популярен в веб-разработке и на данный момент им владеет более 7 млн разработчиков. Изначально SQL был основным способом работы пользователя с базой данных, который был предназначен для описания, изменения и извлечения данных.
Однако со временем SQL усложнился и стал приобретать черты, свойственные современным языкам программирования. На этом языке написаны и исполняются смарт-контракты для блокчейн-платформы Aergo.
Golang (Go)
Go — компилируемый многопоточный язык программирования, основанный на открытом коде языка C и разработанный внутри компании Google. Работа над ним началась в 2007 году, однако официально язык был представлен только в ноябре 2009 года.
Язык разрабатывался для высокоэффективных программ, работающих на современных распределенных системах и многоядерных процессорах. Запуск Go рассматривался игроками рынка как попытка создать замену С/С++. Сегодня блокчейн-платформа Hyperledger Fabric использует этот язык программирования, а сообщество разработчиков Go насчитывает около 800 000 человек.
Waves и Ride
Крупнейшая в Восточной Европе блокчейн-платформа Waves в июне запустила свой собственный язык программирования — Ride. Этот язык предназначен для создания смарт-контрактов и децентрализованных приложений.
В Waves Ride утверждают, что новое решение будет легким в освоении и эксплуатации, а это значит, что оно поможет программистам уменьшить количество ошибок. Другое преимущество Ride, о котором говорит CEO Waves Александр Иванов, заключается в понижении порога входа в блокчейн для разработчиков-новичков.
Один из самых ожидаемых в мире блокчейнов, TON, использует для создания смарт-контрактов язык программирования Fift. Он имеет много общего с языком программирования Forth, который появился около 50 лет назад, и в синтаксисе он в некоторой степени похож на Lisp. Однако этот язык совершенно недружелюбен к программистам, которые пишут на JavaScript или Python.
Этот язык оптимизирован под виртуальную машину TON, чтобы уменьшить затраты мощностей блокчейн-сети на исполнение смарт-контрактов. При этом Fift необходим только для написания смарт-контрактов и их исполнения в мастерчейне TON (базовый блокчейн), а для написания смарт-контрактов для воркчейнов (сайдчейнов) блокчейна TON могут использоваться и другие языки программирования.
Перспективы развития
В мире существуют сотни блокчейн-платформ и десятки языков программирования для них. Анонс о выходе новых языков программирования от Cosmos говорит о том, что продолжается непрерывная конкурентная борьба за привлечение разработчиков между участниками рынка. И, в отличие от других проектов, у Cosmos есть конкурентное преимущество — эта платформа предоставляет свои сервисы для любых блокчейн-разработчиков, а не только тех, кто работает с одной определенной платформой.
Ethereum рискует потерять лидирующие позиции в сфере блокчейн-разработки и уступить, особенно если долгожданное обновление Solidity снова будет отложено. У Fift есть хороший шанс создать крупное сообщество разработчиков, но вряд ли он будет активно использоваться вне блокчейна Telegram.
Дата публикации 14.08.2019
Поделитесь этим материалом в социальных сетях и оставьте свое мнение в комментариях ниже.