ПРЕКРАСНОЕ ДАЛЕКО

Технологии развиваются с поразительной скоростью. Кажется, только вчера появились отечественные микропроцессоры КР1810ВМ86М с тактовой частотой всего 8 мегагерц, навсегда разделившие наш быт на «до» и «после». А набор из восьми микросхем памяти К565РУ7 (аналог Intel 41256) давал фантастический по тем временам объем ОЗУ в 256 килобайт.

Тогда казалось, что с такой динамикой развития, человечество вот-вот выйдет за пределы галактики и понесётся к другим мирам. Сегодня эти цифры вызывают лишь улыбку, но именно с таких достижений в области вычислительной техники 80-х и 90-х годов начиналось наше путешествие в будущий мир единиц и нулей.

Скрытый текст
один из первых "Суперкомпьютеров"
один из первых "Суперкомпьютеров"

Вспоминаю, как спустя пару лет после выхода OS DOS-6.22 я впервые запустил установку Windows 95. Заведя будильник на два часа вперед, чтобы не пропустить фееричный запуск окна окончания установки, на моем первом DX386 с 40 мегагерцами в турборежиме, я отправлялся спать.

Чуть позже, я уже писал свои первые программы на Turbo Basic. И заметьте именно программы а не приложения. Ведь для их работы не требовалось никаких драйверов или пакетов установки. Всё работало в режиме интерпретатора, то есть внутри самой среды программирования. Размер таких программ не превышал нескольких килобайт.

ВСЕ ВЫШЕ И ВЫШЕ

Время шло. Технологический бум казалось не затихнет никогда. Процессоры, память, интернет, все стремительно развивалось и уже никто не думал об ограничениях. Появились первые мессенджеры. ICQ (аська) со своим уникальным "ку-ку" звучала во всех офисах. Помню на некоторых фирмах руководители отделов даже штрафовали своих сотрудников за использование мессенджера на рабочем компьютере. Появились первые программы по автоматизации учета на предприятиях. 1С-ку кажется знали все в лицо. Ну а что, встроенный язык программирования с русским диалектом, это вам не хухры-мухры. Вот какие были времена. Всё крутилось и сверкало внутри системных блоков, гордо стоящих на полках магазинов компьютерной техники. Уже ушли в прошлое так полюбившиеся многим геймерам Trident TVGA и Cirrus Logic с одним мегабайтом памяти, звуком Creative Sound Blaster и игрой DOOM под DOS/4GW.

Скрытый текст
теперь видокарты собирают в массивы
теперь видокарты собирают в массивы

Ну да бог с ним с железом. Но давайте посмотрим на то, что стало с программным обеспечением. Оно вырасло до гигантских размеров, съев всё свободное пространство на жестком диске. Помню раньше играя в Alladdin мне хватало нескольких дискет чтобы загрузить игру на виртуальный диск. Теперь поиграть в GTA5 нужно порядка 100+ Гигов только под минимальную установку, а на подходе GTA6. Но я уже давно не геймер, годы не те.

Написав кучу приложений на Visual Basic 6 я был шокирован выходом в свет новой версии с приставкой .NET посчитав "микромягких" (Microsoft) сошедших с ума. Какой ещё .Net, разве того что есть кому то мало? Теперь современная студия от тех же "микромягких" весит около 220 Гигабайт и это при том, что Turbo Basic который по сути и сделал из меня программистом, весил всего 950 килобайт. Вот вам друзья и технологизация в полной своей красе.

ХИТРО И ДЕРЗКО

Современные программисты сейчас выпускают программы, которые потребляют сотни мегабайт памяти и требуют мощных процессоров для простых задач. Это не 1990-е годы, когда в 640 КБ оперативной памяти MS-DOS нужно было уместить игровой движок, драйверы и саму игру.

Почему так происходит, это лень разработчика или осознанный экономический и технический выбор. На это есть несколько причин:

  1. Бизнесу важнее выпустить продукт на рынок раньше конкурентов.

  2. Зачем применять векторную графику если у пользователя 8 ГБ ОЗУ.

  3. Написание кроссплатформенных приложений для разных ОС.

  4. Зачем писать что то с нуля, если есть наборы сторонник библиотек.

  5. Пишут без оптимизации чтобы сдать проект, потом хоть потоп.

Сейчас установить новое приложение или развернуть облачный сервис достаточно легко. Но эти разработчики не взирая на то, что Nginx, Phyton, Node.js и прочие весят копейки. Размеры же самих приложений в тысячи раз больше. Потребители такого софта, откровенно не желают ставить новые приложения на свои смартфоны, жалуясь на недостаток свободного места.

Наблюдается странная тенденция, чем больше размер приложения, тем выше требования к железу и наоборот, чем мощнее железо, тем приложения становятся всё больше. Но когда же наступит предел этому расточительству ресурсов?

Привожу пример кода приложения "Hello World" на Java в Android Studio который после сборки "весит" около 7 Мегабайт. Но стоит убрать весь мусор из проекта, размер составит 42 килобайта!

package com.example.helloworld;

import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MyActivityTag";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.printStackTrace(); // Проверяем базовый класс
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Вывод строки "Hello World" в консоль Android (Logcat)
        Log.d(TAG, "Hello World");
    }
}

Я понимаю, сейчас многие разработчики скорее всего начнут бросать в меня тапки. Ну как же так, скажут они, ведь AppCompat + Materials это удобно, быстро и красиво, к тому же это обеспечивает обратную совместимость для устройств. Вот захочет к примеру человек на Android 4.4 заюзать современное приложение, а без AppCompat не выйдет. В результате выскочит исключение и приложение упадет. Так точно, господа хорошие, упадет. Но вопрос в том, кому в 2026 году захочется юзать KitKat? Ответ прост, самой компании Google. Именно она всё делает так, чтобы вы тянули её "библы" и раздували свои приложения. Это для них завтрашний хлеб. Вы раздуваете приложения, а Google готовит очередной девайс с большей памятью.

Возьмем для примера Material Design от Google. В этой системе есть всё: готовые наборы компонентов, стили теней и графические ассеты. Звучит здорово, но ведь базовый интерфейс можно сверстать вручную стандартными средствами. В таком случае размер приложения увеличится всего на 200–300 килобайт (вес одного JPEG-файла), и вам не придется утяжелять сборку лишними 5 мегабайтами библиотечного кода. Согласитесь, звучит гениально.

То же самое касается работы с сокетами, базами данных и криптографией. Низкоуровневые инструменты для этих задач весят копейки, обеспечивая при этом максимальную производительность и надежность. Например, библиотека OkHttp - это мощный сетевой движок, который берет на себя всю грязную работу по работе с сокетами. А вот такие популярные инструменты, как Retrofit, Ktor Client или Volley - по сути, лишь высокоуровневые надстройки. Да, они удобны, но ничего нового для функционала приложения не добавляют.

Хочется надеяться, что на этих примерах мне удалось наглядно объяснить, из чего на самом деле складывается настоящая оптимизация в разработке приложений. Нет смысла замерять производительность программного кода, если само приложение сварено из "топора".

ТЕЛЕГРАМ И ВСЕ ВСЕ ВСЕ

Возвращаемся к изначальной теме. Раз уж статья называется "Web3 мессенджер..." я плавно подойду к сути, описывающей уже готовые решения предназначенные для обмена сообщениями. Это так называемые мессенджеры. Возьмем к примеру всеми любимый Телеграм. Его размер пакета составляет около сотни мегабайт. Но что там внутри? Сам Павел Дуров, автор проекта Телеграм, с городостью заявлял, что они не используют сторонних библиотек и пишут все компоненты сами. Да, это правда, и это заслуживает уважения. Но здесь есть одна маленькая деталь. Зачем вообще писать всё с нуля. Ведь в самой операционной системе уже есть дефолтные модули которые можно просто подтянуть к своему приложению. Но это политика самой компании, и значит, с их точки зрения правильная.

Приведу ещё пример. Когда я только начал разрабатывать свой мессенджер, у меня возникла задача реализовать видеозвонки по протоколу P2P. Первым делом я обратил внимание на технологию WebRTC так как для видеосвязи это было идеальное решение. Но увидев размер этой SDK я пришел в ужас - в чистом виде размер составлял почти 50 мегабайт. Даже при использовании stripped версии, я получаю + 25 мегабайт прироста к своему пакету. Даже если писать свой движок WebRTC на C++ не факт что получится меньше.

Я пошел по пути наименьшего сопротивления при максимальной отдаче. Я подумал, ну раз уж движок WebRTC встроен в браузер Chrome в самом Андроиде, то почему бы не подключиться к нему напрямую. Прикрепив Chrome к WebView я получил вот это красивое решение...

webView.setWebChromeClient(new WebChromeClient() {
  @Override
  public void onPermissionRequest(final PermissionRequest request) {
    runOnUiThread(() -> request.grant(request.getResources()));
  }
});

Далее, я инициировал подключение к этой либе через отдельный класс на JavaScript и вуаля, всё заработало без проблем:

    class CallManager {
        constructor(localVideoSelector, remoteVideoSelector) {
            this.localVideo = document.querySelector(localVideoSelector);
            this.remoteVideo = document.querySelector(remoteVideoSelector);
            this.peerConnection = null;
            this.localStream = null;
            this.remoteStream = null;
            this.pendingCandidates = [];
            this.config = { iceServers: [{ urls: "stun_address" }] };
        }
      //...

Если вы Java программист, а я уверен что это именно так, то вы заметите, что размер пакета при таком подходе вырастет ровно на "0" байт вместо 25-50 Мегабайт.

Привожу список размеров установочных пакетов (APK) разных мессенджеров:

  • Telegram = 100 МБ.

  • WhatsApp = 112 МБ.

  • Viber = 167 МБ.

  • Signal = 65 МБ.

  • Discord = 130 МБ.

  • Elyon (Accord) = 3.5 МБ. (разработчик ваш покорный слуга)

При общем размере моего приложения в 3.5 мегабайт мне удалось впихнуть туда не только видеозвонки но даже собственную криптоэкономику. Более того, я также реализовал полноценный мессенджер с частными каналами, ботами и даже встроенным искусственным интеллектом. И всё это за счет интеграций, внешних API и рукописного кода. Возможности мессенджера были значительно расширены за счет использования user-bots. Взаимодействия с внешними сервисами сделало приложение платформой с неограниченными возможностями. И это друзья, при нулевом бюджете. Я выступил как в роли заказчика проекта, так и его исполнителя.

Web-3 ЧТО ЭТО И ЗАЧЕМ

Итак, немного ликбеза. Web3 - это концепция нового поколения интернета. Главная его идея заключается в децентрализации вычислительных мощностей. Такой интернет позволяет вместо использования одного мощного сервера распределить нагрузку на другие вычислительные блоки. Потому дальше мы уже имеем дело с блокчейн-технологиями, где вместо привычных учетных записей (номера телефона, или имейла) используются криптографические адреса или кошельки.

Самым гравным критерием перехода к Web3 является его быстродействие и надежность. Неразрывность всех транзакций проведенных через блокчейн позволяет к примеру записывать финансовые операции не боясь их подделки.

Сама криптовалюта является лишь следствием развития технологии блокчейна. Теперь не трудно догадаться что появилось раньше, блокчейн или биткойн.

КАК Я ЭТО ИСПОЛЬЗУЮ

Разрабатывая свой мессенджер, я столкнулся со многими задачами. Одна из которых состояла в том, как реализовать систему внутренних платежей для обеспечения доступа к закрытым ресурсам пользователей. Иными словами, нужно было придумать механизм монетизации платных подписок на частные каналы и другие платные сервисы приложения.

Доступ к таким каналам обычно закрыт для обычных пользователей. Для просмотра контента, будет необходимо оплатить доступ. Но даже если кошелек пользователя пуст, можно получить донат или заработать немного монет внутри приложения. Для этого существует несколько способов. Один из них, собирать вознаграждения с призовых выплат играя во встроенные игры.

Понятное дело, что связываться с реальными деньгами дело трудное и опасное. Нужно регистрировать бизнес, рассчитывать налоги, вести учет всех пользователей с последующей передачей личных данных в соответствующие органы. Но я пошел по другому пути. Я запустил свою криптоэкономику и выпустил собственный "биткоин" прямо внутри мессенджера.

На деле все выглядит довольно просто. Любой желающий, может купить номинальную криптовалюту через терминал в соседнем супермаркете. К примеру так называемый "эфир" (Ethereum) и затем поменять его на монету приложения, отправив этот "эфир" на указанный в профиле мессенджера смарт-контракт. Этот смарт-контракт, сам переведет полученную сумму на кошелек пользователя в нужной валюте. Теперь, в аккаунте пользователя, появится зачисленная сумма. Комиссии в привычном понимании нет, но есть плата за так называемый "газ". "Газ" или "топливо" это плата за совершенную транзакцию самому блокчейну в "эфире". Кстати её то и получают майнеры когда регистрируют чужие транзакции, пыхтя при этом своими видеокартами на кухне. "Газ" стоит копейки. Даже одного цента на балансе будет достаточно на десятки подобных транзакций.

Итак, когда пользователь подписывается на частный (платный) канал, его монетки падают уже в кошелек владельцу этого канала. Вся прелесть технологии web3 в том, что все транзакции можно видеть на любом блокчейне в интернете введя адрес нужного кошелька. Причем прозрачно по всем операциям за любой период времени. Никто не знает настоящих владельцев кошельков, это анонимная система. Поэтому, никакие ограничительные меры к ним не применяются.

Ниже я приведу пример как я использую web3 для некоторых задач:

пример создания криптокошелька:

public string CreateWallet()
{
    var ecKey = EthECKey.GenerateKey();
    string privateKey = ecKey.GetPrivateKey();
    var account = new Account(privateKey);
    return $"{account.Address}:{privateKey}";
}

Здесь после генерации уникального ключа, формируется приватный ключ. Далее из приватного ключа вытягивается готовый адрес кошелька.

Теперь немного сложнее. Получим баланс (остаток) на кошельке игрового контракта:

using System;
using System.Numerics;
using System.Threading.Tasks;

public async Task<long> GetTreasuryBalance()
{
    var web3 = new Web3(url-RPC-server);
    string treasuryBalAbi = "[здесь специальный код интерфейса смарт-контракта]]";
    var treasuryBalFunc = web3.Eth.GetContract(treasuryBalAbi, GAMES_CONTRACT).GetFunction("treasuryBalance");

    BigInteger totalTreasuryTokens = await treasuryBalFunc.CallAsync<BigInteger>();
    decimal balanceDecimal = Web3.Convert.FromWei(totalTreasuryTokens);
    long integerBalance = (long)Math.Truncate(balanceDecimal);
    
    return integerBalance;
}

Как видно из кода выше, используется специальный тип переменной BigInteger. Так как web3 не поддерживает значения с плавающей запятой, то здесь используется тип целых чисел с большим количеством нулей. К примеру, в моём контракте используется аж 18 нулей после единицы. Чтобы отразить баланс в одну монету нужно записать: 1000000000000000000. Это обратимое значение которое легко сконвертировать в тип decimal.

ВСТРОЕННЫЕ ИГРЫ С WEB3

Теперь немного расскажу об отдельной фиче которая помогает пользователям не только тратить свои монеты но и зарабатывать. Если учитывать что моя криптовалюта это условные деньги а не настоящие, я решил сделать онлайн игры, где игрок сможет получать вознаграждение за свои призовые выигрыши. К примеру, если у вас нулевой баланс, то при запуске например рулетки для вас откроется демо режим. Играть можно бесконечно и это не влияет на ваш баланс на кошельке. Если в демо режиме вы достигните выигрыша в десятикратном размере от первоначального депозита, вы получите одну реальную монету на свой личный кошелек. Далее, вы уже можете играть на полученные монеты, что будет реально отражаться на вашем капитале.

На данный момент я написал несколько довольно простых аркадных игр в формате HTML. Некоторые из них уже подключил к Web3. Сейчас доступны следующие игры:

  • BlackJack - аркадная игра в карты (подобие игры в "Очко" или в "21");

  • Roulette - напоминает рулетку в казино с колесом и ставками;

  • Slots - туповатая на мой взгляд игра где нужно крутить три колеса на удачу.

    Все эти игры были написаны за пару вечеров на скорую руку, поэтому прошу сильно меня не пинать за слабую графику. Задача была подключить их к экономике мессенджера и сделать возможным делать ставки. Кстати, если вам это заходит и вы хотели бы улучшить эти игры или написать свои, буду рад посотрудничать. С меня "печеньки и кофе".

    Ниже скриншот игры "BlackJack"

Скрытый текст
игра BlackJack на HTML
игра BlackJack на HTML

СЕКРЕТНЫЕ ЧАТЫ

Мой мессенджер сильно отличается от вышеупомянутых. Одно из его отличий, это отсутствие кеша сообщений на стороне бэкенда. Иными словами, сервис не хранит переписку пользователей вообще. В базе данных хранится только скжатый отпечаток сообщения, который удаляется сразу после того, как абонент запустит свой мессенджер и прочитает одресованное ему сообщение.

Такой подход избавляет базу данных от раздувания и пользователей от случайной утечки данных переписки. Тем не менее, для реализации абсолютной секретности, я также реализовал подсистему шифрования по протоколу E2E. Суть данного метода заключается в использовании криптографических ключей шифрования с последующей передачей зашифрованного сообщения между двумя пользователями.

Принцип работы основан на так называемом "сквозном шифровании" и выглядит следующим образом. Приватные ключи хранятся у каждого пользователя на смартфоне в закрытом хранилище TEE (Trusted Execution Environment). Публичные ключи, хранятся на сервере бэкенда. Как только один пользователь активирует "секретный чат" его приложение тут же запрашивает публичный ключ его собеседника. Далее, пользователь шифрует своё сообщение публичным ключем собеседника и отправляет на сервер. Как только пользьзователь входит в сеть, он забирает это зашифрованное сообщение и расшифровывает его своим приватным ключем.

Здесь действует правило, что только приватный ключ может расшифровать сообщение зашифрованное публичным ключем. На практике ключами шифруется не само сообщение но лишь пароль к другому алогоритму шифрования, которое и зашифровывает само сообщение. К примеру, сообщение шифруется алгоритмом AES с паролем, а сам пароль шифруется публичным ключем по алгоритму RSA. В итоге, на сервер передаётся два сообщения. Первое, это сообщение зашифрованное алгоритмом AES, второе, пароль от AES зашифрованный алгоритмом RSA. Или в другом порядке, не важно. Это классическая схема сквозного шифрования. В этом случае, никто кроме получателя, не сможет прочесть зашифрованное сообщение. Так что Павел Дуров был прав, когда говорил что у него нет ключей от зашифрованных сообщений пользователей. Они хранятся у самих пользователей.

ниже условный пример кода для генерации ключей и записи их в хранилище:

// Флаг обновлен
KEYS_HAS_UPDATED = true;

try {
    // 1. Инициализируем генератор
    KeyPairGenerator generator = KeyPairGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_RSA, 
            "AndroidKeyStore" 
    );

    // 2. Настраиваем параметры
    generator.initialize(new KeyGenParameterSpec.Builder(
            "ALIAS", 
            KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_SIGN)
            .setKeySize(2048) 
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
            .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
            .build());

    // 3. Генерация ключа внутри keystore
    KeyPair keyPair = generator.generateKeyPair();

} catch (Exception e) {
    e.printStackTrace(); 
}

ВЫВОДЫ

Основная идея при написании этой статьи заключалась в том, чтобы познакомить читателя с практическим использованием новой технологии Web3 основанной на блокчейне, на примере моего мессенджера "Elyon". Я попытался рассказать как легко и просто реализовать собственную экономику в своих проектах и сделать их платными. Имея в распоряжении собственный смарт-контракт со своей криптовалютой, любой разработчик сможет реализовать платные сервисы без взаимодействия с федеральными платежными системами. Ввод и вывод реальных денег берет на себя биржа. Там вы покупаете номинальную криптовалюту и меняете её на любой другой токен, указав адрес контракта. Вывод средств примерно тот же. Вы отправляете ордер на вывод, оплачиваете условную комиссию за транзакцию и перекидываете монеты назад в свой реальный криптокошелек. Дальше, через ту же биржу, выводите монеты в любую валюту мира!

Также, я показал собственное видение на то, почему приложения бывают неоправданно большими. Указал на недостатки разработчиков писать чистый программный код вместо использования тяжелых библиотек. Я уверен, что удобство использования приложений во многом зависит от их оптимизации, которое часто губит излишнее использование надстроек [ИМХО].

Если вас заинтересовала эта тема и вы хотели бы присоединиться к моему проекту, буду только рад. Пишите в личку, обсудим детали.

П.С.

В моем мессенджере осталось ещё много интересных фичей, но описывать их все в одной статье это накладно. Вы можете скачать рабочий APK файл с сайта моих проектов и убедиться в том, что все работает идеально. Этот проект полностью работоспособный и ждет своих постоянных пользователей. Там нет модерации контента, нет цензуры и нет навязчивых правил.

Прошу сильно не ругать за непрофессиональность изложения материала. Я не писатель, но хотелось поделиться своими идеями с аудиторией ХАБРа.

Всем успехов и терпения!