, ,

12 января, 2025

Обход защиты сайтов от парсинга данных или anti-anti-scraping

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

  • Формирование HTML-страницы с помощью JavaScript.
  • Ожидание специальных заголовков или куки.
  • Блокировку «подозрительных» запросов.

Посмотрев на это, я немного приуныл и начал искать способ быстрее решить задачу. Мне нужно было решение, которое бы запускало парсер так, как если бы запрос выполнял обычный браузерный пользователь. В голову сразу пришла идея использовать Chromium как сервис внутри Docker. Я мог бы передавать ссылку страницы в этот сервис, а в ответ получать HTML уже после отработки JavaScript.

Выбор инструментов

Парсить я планирую на PHP. В качестве браузерного сервиса я выбрал Selenium. Также можно использовать Puppeteer, но он у меня не запустился под Docker, поэтому я отказался от него.

Selenium — это инструмент для тестировщиков, позволяющий автоматизировать действия на сайте с помощью эмуляции браузера. Мне достаточно одного браузера — Chrome, но Selenium поддерживает и другие браузеры. Подробнее можно прочитать на официальном сайте: https://www.selenium.dev

version: '3.8'

services:

  selenium:
    image: selenium/hub:4.8.0  # Selenium Hub
    container_name: selenium_parser
    environment:
      - GRID_MAX_SESSION=5
      - GRID_BROWSER_TIMEOUT=300
      - GRID_TIMEOUT=300
    networks:
      - network

  chrome:
    image: selenium/node-chrome:4.8.0  # Браузер Chrome
    shm_size: 2gb
    depends_on:
      - selenium
    environment:
      - SE_EVENT_BUS_HOST=selenium
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
    networks:
      - network

  php:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: parser_php
    volumes:
      - ./:/var/www/html
    depends_on:
      - selenium
    networks:
      - network

networks:
  network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 192.168.210.0/28

selenium — контейнер с нашим Selenium, который будет использоваться как сервис для запуска сайтов из браузера Chrome.

chrome — контейнер с браузером (можно добавить контейнеры с другими браузерами, если нужно).

php — контейнер с PHP-скриптом.

Поскольку я буду использовать стороннюю библиотеку Composer для взаимодействия с API Selenium, мне нужно, чтобы Composer был установлен в моем контейнере PHP. Для этого создаем дополнительный Dockerfile для PHP.

# Используем базовый образ PHP 8.3
FROM php:8.3-fpm

# Установка необходимых пакетов
RUN apt-get update && apt-get install -y \
    git \
    unzip \
    libpq-dev \
    && docker-php-ext-install bcmath

# Установка Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Установка Symfony CLI
RUN curl -sS https://get.symfony.com/cli/installer | bash \
    && mv /root/.symfony*/bin/symfony /usr/local/bin/symfony

# Установка прав доступа к директории
WORKDIR /var/www/html

Запуск Docker Compose

Теперь все готово для запуска docker-compose:

$ docker-compose up -f docker-compose.yaml

Обратите внимание, что я использую минимальный набор контейнеров. В реальном проекте для полноценного парсера потребуются контейнеры с HTTP-сервером, базой данных, Redis и т. д. Поскольку написание полноценного парсера выходит за рамки этого поста, здесь я привожу пример упрощенной конфигурации docker-compose.

Заходим в контейнер PHP и инициализируем Composer:

$ docker exec -it parser_php bash

docker# composer require php-webdriver/webdriver 

После успешной инициализации Docker пишем небольшой скрипт на PHP для проверки работоспособности Selenium:

<?php

require_once 'vendor/autoload.php';

use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;

// Подключение к Selenium Hub
$host = 'http://selenium:4444/wd/hub'; // URL Selenium Hub
$capabilities = DesiredCapabilities::chrome(); // Используем Chrome
$driver = RemoteWebDriver::create($host, $capabilities);

// Открываем страницу
$driver->get('https://example.com');

// Получаем HTML страницы
$html = $driver->getPageSource();
echo $html;

// Закрываем браузер
$driver->quit();

Все теперь можно из контейнера с php обращаться к любым сайтам через selenium как полноценный браузер Chrome, выполнять JS, можно эмулировать обычные действия пользователя на сайте, все зависит от вашей фантазии, задачи.

Теперь можно из контейнера PHP обращаться к любым сайтам через Selenium как полноценный браузер Chrome. Вы можете выполнять JavaScript, эмулировать действия пользователя на сайте — все зависит от ваших задач и фантазии.

, , ,

6 января, 2025

Разворачиваем git хранилище на своем сервере

Всем привет! Сегодня хочу рассказать про установку такого замечательного программного обеспечения как Gitea. Данный продукт предназначен для удобного доступа к git хранилищу, напоминает по своим возможностям gitlab, github, bitbucket.

Сейчас особенно полезно задуматься о создании своих независимых git хранилищ потому что пидарская протекционистская политика государств нарастает и очень вероятно, что в будущем пользователей из России могут лишить доступа к github или bitbucket, а код где-то хранить необходимо и так как мудаки гениальные стратеги отвечающие за импортузамещение до сих пор не создали ничего более менее альтернативного в России, то лучше создавать свои хранилища на своих выделенных серверах. Gitea прекрасно подходит в качестве альтернативы, а так же он гораздо проще в установке и настройке чем тот же самый GitLab.

Для установки я выбрал способ развертывания через docker compose, так что требуется установить docker если это еще не сделано, затем создать директорию в котором будет находится файловая система gitea и создать файл docker-compose.yaml

$ sudo apt update
$ sudo apt install -y docker.io
$ sudo systemctl start docker
$ sudo systemctl enable docker
$ sudo apt install -y docker-compose
$ mkdir ~/gitea && cd ~/gitea
$ vim docker-compose.yml

Соответственно, на хостинге у меня Ubuntu ( если у вас что-то другое, используйте свои команды для установки Docker ). В качестве редактора само собой я использую православный vim

version: '3.7'

services:
  db:
    image: postgres:15
    container_name: gitea-db
    environment:
      POSTGRES_USER: gitea
      POSTGRES_PASSWORD: gitea_password
      POSTGRES_DB: gitea
    volumes:
      - ./db:/var/lib/postgresql/data
    restart: always

  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
    volumes:
      - ./gitea:/data
    ports:
      - "127.0.0.1:3000:3000" # Веб-интерфейс Gitea
      - "2222:22"   # SSH для клонирования репозиториев
    depends_on:
      - db
    restart: always

В качестве базы данных я решил использовать postgres. Поменяйте доступы к базе данных. В принципе gitea поддерживает разные СУБД, можете использовать свой любимый. Описание портов есть в комментариях.

Так как мне нужен был отдельный домен для git я указал проброс порта 3000 только для 127.0.0.1 поэтому из вне к нему нельзя обратится ( далее я покажу как разрулить порт через настройку nginx )

Теперь создаем любымый Makefile для удобства

.PHONY: up down restart logs ps clean help

# Переменные
COMPOSE_FILE = docker-compose.yml
PROJECT_NAME = gitea_project

# Команды
up: ## Запускает все контейнеры в фоне
	docker-compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) up -d

down: ## Останавливает контейнеры и освобождает ресурсы
	docker-compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) down

restart: ## Перезапускает все контейнеры
	$(MAKE) down
	$(MAKE) up

logs: ## Показывает логи контейнеров в реальном времени
	docker-compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) logs -f

ps: ## Отображает состояние запущенных контейнеров
	docker-compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) ps

clean: ## Удаляет все контейнеры, тома и связанные ресурсы
	docker-compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) down --volumes --remove-orphans

help: ## Показывает это сообщение
	@echo "Доступные команды:"
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "  %-15s %s\n", $$1, $$2}'

.DEFAULT_GOAL := help

В Makefile можно вынести необходимые команды для работы с докером

В процессе запуска у меня возникли некоторые сложности при запуске докера на хостинге поэтому пришлось установить питон

$ sudo apt update 
$ sudo apt install python3 -y
$ sudo apt install python3-pip -y

Запускать docker-compose up от рута плохая идея поэтому необходимо добавить пользователя в группу docker и запускать docker-compose от обычного пользователя, для этого добавляем пользователя <your-user> в группу docker

$ sudo usermod -a -G docker <your-user>

Ну или так:

$ sudo usermod -aG docker $USER

После добавления пользователя в группу требуется перезапустить shell ( без этого make up ругался на то что у пользователя не хватает прав )

Теперь требуется привязать домен к нашему локальному порту 3000 на котором запущен gitea, для этого нужно перейти к настройкам nginx и создать конфиг для сервиса gittea

$ cd /etc/nginx/sites-available
$ vim gitea

Добавляем подобное содержимое

server {
        server_name domain.ru www.domain.ru;
        location / {
                proxy_pass http://localhost:3000;
        }
}

Тут все понятно — все внешние запросы проксируются на локальный порт 3000 на котором запущен наш gitea

Далее создаем линк на /etc/nginx/sites-available/gitea в
/etc/nginx/sites-enabled и перезапускаем nginx

$ sudo ln -s /etc/nginx/sites-enabled/gitea /etc/nginx/sites-available/gitea
$ sudo nginx reload

После этого я рекомендую так же настроить SSL сертификаты для нашего хранилища, я использую для этой цели certbot

$ cerbot --nginx -d domain.ru -d www.domain.ru

Чуть не забыл важный момент, необходимо создать службу в Ubuntu, которая позволит автоматически поднимать docker-compose с gitea при перезагрузки сервера, для этого создаем новую пользовательскую службу systemd

$ cd /etc/systemd/system/
$ sudo vim gitea.service

Добавляем код нового сервиса в gitea.service

[Unit]
Discription=Gitea
After=docker.service
Requires=docker.service

[Service]
WorkerDirectory=/var/www/gitea/
ExecStart=docker-compose -p gitea_project -f /var/www/gitea/docker-compose.yml up
ExecStartPost=service nginx reload
ExecStop=docker-compose -p gitea_project -f /var/www/gitea/docker-compose.yml down
Restart=on-failure

[Install]
WantedBy=multi-user.target

Тут особо пояснять нечего. Указываем, что служба запускается только после запуска docker.service и для нее обязательно должен быть запущен docker.service

Запускаем

$ sudo systemctl daemon-reload
$ sudo systemctl enable gitea

Все! На этом настройки сервера закончены и можно приступать к установке gitea.

Открываем браузер и переходим на страницу domain.ru ( тот домен который мы указали в настройках nginx )

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

Тут необходимо заполнить настройки данными, которые были указаны в docker-compose.yml

POSTGRES_USER: gitea
POSTGRES_PASSWORD: gitea_password
POSTGRES_DB: gitea

Собственно имя пользователя базы данных, имя базы данных и ваш пароль. В качестве СУБД выбираем postgreSQL

Так же можно сразу же настроить тут порт для ssh соединения, в нашем случае это будет порт 2222

И настроить доступы для администратора Gitea:

После этого нажимаем на кнопку Устанивать Gitea. Ждем пока система установится и можно приступать к работе с Gitea. Интерфейс системы интуитивно понятен, а по функционалу не сильно отличается от привычного Gitlab. Работает достаточно шустро.

На что стоит обратить внимание, конечно настройки базы данных лучше вынести в .env файл из docker-compose.yml а так же может еще имеет смысл настроить работу своего git хранилища внутри вашего собственного VPN, но это уже немного выходит за рамки темы статьи.

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

,

2 января, 2025

Сети криптовалют

Сети криптовалют — это децентрализованные системы, которые позволяют участникам передавать, получать и хранить цифровые активы (криптовалюты), а также выполнять смарт-контракты и другие операции. Эти сети работают на основе блокчейн-технологии, которая обеспечивает их безопасность, прозрачность и неизменность данных.

Основные особенности сетей криптовалют:

  1. Децентрализация
    • Сети управляются не одной центральной организацией, а распределёнными узлами (ноды), которые поддерживают и проверяют транзакции.
  2. Блокчейн
    • Все транзакции записываются в распределённый реестр (блокчейн), где каждая запись защищена криптографически и связана с предыдущими.
  3. Криптографическая защита
    • Для обеспечения безопасности используются алгоритмы шифрования, например, для генерации ключей кошельков или подтверждения транзакций.
  4. Токены
    • В каждой сети есть свой собственный цифровой актив (например, Bitcoin в сети Bitcoin, Ether в Ethereum), который используется для оплаты транзакций или как средство обмена.
  5. Смарт-контракты
    • В некоторых сетях (например, Ethereum, Solana) можно создавать программы, которые автоматически выполняются при выполнении заданных условий.

Типы криптовалютных сетей:

  1. Публичные сети
    • Открыты для всех, любой может участвовать (например, Bitcoin, Ethereum).
    • Узлы равноправны, и любой может стать частью сети, скачав программное обеспечение.
  2. Приватные сети
    • Доступ ограничен определённой группой пользователей (например, корпоративные блокчейны).
    • Используются для специфических задач, таких как внутренняя учётная система.
  3. Гибридные сети
    • Сочетают элементы публичных и приватных сетей, предоставляя доступ для разных групп пользователей (например, VeChain).

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

1. Блокчейны первого поколения

Эти сети фокусируются на передаче ценности и создании децентрализованных платежных систем.

  • Bitcoin (BTC): Первая и самая известная криптовалюта. Используется в основном как средство сбережения и платежей.
  • Litecoin (LTC): «Легкий» вариант Биткоина с более быстрыми транзакциями.
  • Bitcoin Cash (BCH): Форк Биткоина с увеличенным размером блока для ускорения транзакций.

2. Блокчейны второго поколения

Сети с поддержкой смарт-контрактов, которые позволяют создавать децентрализованные приложения (dApps).

  • Ethereum (ETH): Основная сеть для смарт-контрактов и децентрализованных приложений.
  • Binance Smart Chain (BSC): Быстрая и дешевая альтернатива Ethereum, популярная в DeFi.
  • Cardano (ADA): Платформа на основе доказательства доли владения (Proof-of-Stake), ориентированная на безопасность и устойчивость.
  • TRON (TRX): Сеть для децентрализованных приложений и медиа.

3. Блокчейны третьего поколения

Эти сети ориентированы на масштабируемость, межсетевую совместимость и энергоэффективность.

  • Polkadot (DOT): Позволяет блокчейнам взаимодействовать друг с другом (межсетевые мосты).
  • Solana (SOL): Сеть с высокой пропускной способностью и низкими комиссиями.
  • Avalanche (AVAX): Поддерживает создание множества цепочек и совместимость с Ethereum.
  • Cosmos (ATOM): Сеть, соединяющая разные блокчейны через протокол Inter-Blockchain Communication (IBC).

4. Сети, ориентированные на конфиденциальность

Блокчейны, предоставляющие высокий уровень приватности транзакций.

  • Monero (XMR): Фокусируется на полной анонимности и конфиденциальности.
  • Zcash (ZEC): Использует zk-SNARK для защиты данных о транзакциях.
  • Dash (DASH): Поддерживает опциональные приватные транзакции.

5. DeFi и токенизированные экосистемы

Сети, популярные в сфере децентрализованных финансов.

  • Uniswap: Протокол на Ethereum для децентрализованного обмена токенов.
  • PancakeSwap: Децентрализованный обмен на Binance Smart Chain.
  • Aave: Платформа для децентрализованных займов и кредитов.

6. Сети второго уровня (Layer 2)

Облегчают масштабирование основных блокчейнов, таких как Ethereum.

  • Polygon (MATIC): Сеть второго уровня для масштабируемых dApps.
  • Arbitrum: Решение для масштабирования Ethereum через оптимистичные роллапы.

7. NFT-сети

Популярные блокчейны для создания и торговли невзаимозаменяемыми токенами (NFT).

  • Ethereum (ETH): Лидер в области NFT через стандарт ERC-721.
  • Flow (FLOW): Сеть, разработанная для NFT, таких как NBA Top Shot.
  • Tezos (XTZ): Энергоэффективная сеть для NFT и искусственного интеллекта.

8. Корпоративные блокчейны

Сети, разработанные для использования компаниями.

  • Hyperledger Fabric: Разработан для корпоративных приложений.
  • Corda: Ориентирован на финансовые сервисы.
  • Quorum: Модификация Ethereum, адаптированная для банков.

9. Сети, ориентированные на стабильность (Stablecoin Networks)

Сети для поддержки стабильных криптовалют (stablecoins).

  • Tether (USDT): Самый популярный стейблкоин на основе блокчейнов Ethereum, Tron и других.
  • USD Coin (USDC): Стейблкоин от Circle, поддерживается на Ethereum, Solana, Avalanche и других.

Для взаимодействия с разными сетями криптовалют, можно использовать разные подходы. Это может быть взаимодействие по HTTP протоколу через через публичные сервисы, которые предоставляют возможность взаимодействия в криптовалютными сетями ( пример такого взаимодействия ранее был описан тут ) такими как Infura которые поддерживают большое количество сетей или через локальный АПИ по протоколу JSON-RPC через создание собственного узла на своей сервере.

, , , , , ,

22 декабря, 2024

Блокировка Газпромбанка, но выход есть.

После последних санкций империалистов заблокировали Газпромбанк. Как обычно самыми пострадавшими от этих так называемых антипутинских санкций оказались в первую очередь обычные простые рабочие люди, которые по мнению дегенератов из руководства США и ЕС должны тут же бросить свои дела и начать шатать режим которые получали зарплаты в рублях, но жили и работали за границей.

Если вы попали в такую ситуацию или ваши знакомые, то не стоит расстраиваться! Выход есть! И сейчас я расскажу как можно, получая деньги на карту Газпромбанка, выгоднее всего переводить средства в доллары США или любую другую валюту, которая вам необходима.

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

  1. Самый простой и быстрый, вам нужно зайти на один из самых популярных аррегаторов платежных системе — bestcgange.ru. Выбрать банк слева откуда вам нужно перевести и выбрать платежную систему или карту куда вы хотите перевести.

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

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

Следующий способ которым я хочу поделиться — это перевод денег через криптовалюту, т.е, вы сначала покупаете криптовалюту за рубли, а затем переводите деньги на карту банка, в котором еще не успели заблокировать Swift, например, платежную систему whitebird ( Белая птица ) Вообще эта система позволяет проводить финансовые операции между криптовалютами и банковскими картами, единственное условие, у вас должна быть карта в банке стран СНГ, но так же через нее вы можете создать себе карту и счет в Альфа банке Белорусь. Туда можете переводить деньги, затем уже в этом банке вы сможете открыть счет валютный и переводить со своего счета деньги на свою карту ( я это еще не проверял сам, но удивительно банк позволяет открывать счета гражданам России и вроде его пока не заблокировали в swift ). Но в данной статье, я бы хотел рассказать способ перевода денежных средств из Газпромбанка ( или любого другого российского банка ) на зарубежную карту. Для этого всего еще нам потребуется еще использовать криптовалюты. Схема простая:

Российская карта => P2P покупка стэйблкоина USDT => вывод USDT денежных средств на mastercard/visa через карту Белой птицы или тот же обменник на bestchange.ru или карту ByBit

Если вы выбираете вариант вывода средств через Альфа-банк Белорусь, для начала регистрируйтесь в Белой птице где вам так же будет необходимо пройти KYC (KnowYourCustomer) поэтому вам потребуется подготовить паспорт РФ и нужно будет отправить свое фото.

После этого вам нужно будет купить стейблкоины, я чаще всего использую стейбкоин USDT курс которого привязан к курсу доллара США и так как это USDT в сети Tron то операции с ним можно проводить с наименьшими комиссиями. Если вы не знакомы с криптовалютами и не знаете как пользоваться криптокошельком, то это обязательно нужно сделать, за блокчейном и криптовалютой в целом будущие планетарной финансовой систем поэтому вам все равно нужно будет с этим разобраться рано или поздно, лучше рано.. Обязательно подписывайтесь на мой телеграм канал куда я отправляю обновления на этом сайте, на котором в том числе пишу о том что из себя представляет криптовалюта и как ее можно использовать.

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

Если говорить про криптокошельки, то это тема для отдельной большой темы ( о которой я обязательно напишу на этом сайте ) сейчас же, если незнакомы с криптовалютой, кошелек на бирже можно воспринимать как любой другой интернет кошелек в интернете, вроде paypal или payer и так далее.

Далее я будт рассказывать про криптобиржу ByBit, ей я пользуюсь сам уже более года и в целом она полностью удовлетворяет моим потребностям. Там же я пользуюсь сервисом P2P для покупки стейблкоина USDT.

Итак, регистрируйтесь по ссылке на ByBit и после регистрации для совершение финансовых операций, вам нужно слить ваши персональные данные товарищам майорам и господам из ЦРУ пройти KYC. После успешного прохождения верификации KYC, у вас появится доступ ко всем сервисам бирже в том числе к P2P обмену.

Если говорить о том что же из себя представляет P2P (point-to-point, от человека человеку), то это по-сути торговля между людьми, биржа ничего с этого не имеет так как комиссия отсутствует, вы сами можете выбрать того продавца, который наилучшем образом вам подходит, по способу перевода, по лимитам, по стоимости USDT. Биржа лишь предоставляет инфраструктуру сервиса, замораживает денежные средства на своей стороне и после подтверждения операции и подтверждении о согласии всех сторон переводит вам USDT и закрывает сделку.

Вот так выглядит экран с различными продавцами USDT

Я отметил на скриншоте цифрами на что следует обратить внимание при обмене. Итак.

  1. Валюта которую нам нужно купить, в данном случае это будет USDT
  2. Валюта на которую мы хотим купить, в данном случае нам нужно купить за рубли
  3. Способ оплаты, деньги в рублях у нас лежат на счету Газпрома, именно этот способ оплаты и выбираем
  4. Имя продавца
  5. Количество выполненных сделок у данного продавца
  6. Количество выполненных успешных сделок у продавца. В целом 94% это хороший результат, который может говорить о том, что продавец достаточно надежный.
  7. Стоимость USDT в рублях. Тут стоит отметить, что продавец сам вправе выставлять стоимость USDT. Тут видим, что за 1USDT (1$) продавец хочет — 104,19 в целом это не самый плохой вариант.
  8. Количество доступных USDT у продавца, в данном случае продавец продает 255 USDT (255$)
  9. Лимиты, в данном случае лимит установлен на весь доступный объем USDT те продавец согласен на сделку только если у него купят весь оставшийся объем в размере 255 USDT

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

  1. Количество сделок у продавца
  2. Процент успешных сделок
  3. Количество доступеых USDT
  4. Лимиты ( в данном случае от 50 до ~145 тысяч рублей
  5. Список доступных платежных систем, в данном случае видно, что газпромбанк так же доступен.
  6. Цена USDT у данного продавца
  7. Сумма в рублях на которую вы хотите купить USDT
  8. Количество USDT которую вы получите после успешной выполненной сделки

Так вышло, что данный пост я писал несколько дней поэтому скриншот экрана непосредственно самой сделки я делаю еще от одного продавца, но смысл остается прежним

  1. время сделки, еслс за указанный период сделка не совершится, то она будет отменена, так же можно отменить сделку нажав на кнопку внизу экрана — Отменить ордер. Только внимание! Если вы отмените 2 ордера, то на сутки вам заморозят покупку на P2P. Если не уверены, что готовы совершать сделку не переходите на этот экран.
  2. Стоимость 1 USDT в рублях
  3. Сумма сделки. Именно эту сумму нужно будет перевести по реквизитам продавца, чтобы он перевел вам USDT
  4. Сумма USDT которую вы получите после успешной сделки.
  5. Наш Газпромбанк в списке способов оплаты, выбираете его и либо вам сразу отобразятся реквизиты банка на который нужно будет перевести сумму в 150000 руб или будет написано что реквизиты требуется получить в чате.
  6. Чат с продавцом. Тут важно понимать одно. Когда вы создали данный ордер, то деньги продавца уже заблокированы на бирже до успеха ордера или до отмены ордера. Важно! Не переходите не по каким внешним ссылкам, которые вам может отправить продавец и не оплачивайте ничего вне рамках коммуникаций бирже. В случае если переписки с продавцом будут происходить в каких-то других чатах и системах и будут произведены мошеннические действия со стороны продавца, у бирже не будет информации о том чтобы подтвердить, что вы совершили платеж. Поэтому общайтесь только в чате биржи.

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

Итак, производим оплату, скидываем в чат квитанцию PDF и нажимаем кнопку — Платеж выполнен. Продавец со своей стороны проверяет, что платеж прошел и соглашается со сделкой. После этого деньги оказываются на вашем счету ByBit.

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

В принципе после этого вы можете вывести их на карту Visa, Mastercard в любом проверенном платеже на BestChange или можете совершить вывод через платежный сервис WhiteBird ( все комиссии и оплаты составят 1,5% по банковским картам Белоруси и чуть больше для других стран СНГ ), но для этого вам потребуется привязать карту Visa к системе. Карта Visa должна быть выпущена в СНГ, к счастью можно сделать карту в стране в которой пока не под санкциями и уже с нее переводить деньги на зарубежные карты через Swift. Так же можно поменять USDT в офлайн обменнике на доллары или валюту, которая вам нужна с более выгодным курсом, еще есть вариант вывода USDT напрямую с ByBit на карту, но с небольшой комиссией, ну и конечно так же можно продать USDT на доллары на P2P бирже. Так же при помощи ByBit можно оформить себе карту и расплачиваться непосредственно криптовалютой с нее.

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

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

, , ,

15 декабря, 2024

Поднимаем Chat GPT у себя на компьютере

Привет! Сегодня хотел бы рассказать как можно развернуть на своей локальной машине аналог чата GPT. Особых знаний для этого иметь не нужно. Все достаточно просто.

Для тех кто не знает что такое chatGTP, то это  чат-бот с генеративным искусственным интеллектом, разработанный компанией OpenAI и способный работать в диалоговом режиме, поддерживающий запросы на естественных языках. ( кусок из Викепедии )

Но возможно не все знают, что существуют альтернативные чат боты, платные и бесплатные, централизованные и децентрализованные

Существует несколько популярных моделей с открытым исходным кодом, которые можно развернуть локально:

Эти модели предоставляют функциональность, схожую с ChatGPT, но менее мощные.

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

По-своей сути подобные чаты представляют из себя ML-модели

ML (Machine Learning) — это технология, позволяющая компьютерам обучаться и принимать решения на основе данных, не будучи явно запрограммированными. ML-модель — это математическое представление данных и логики, которое позволяет системе делать предсказания или выполнять задачи, анализируя входные данные.

Основные этапы работы ML-модели:

  1. Сбор данных: Системе нужны данные для обучения.
  2. Обработка данных: Данные очищаются, нормализуются и подготавливаются для анализа.
  3. Обучение: Модель обучается на данных, выявляя закономерности и зависимости.
  4. Валидация: Проверяется, как хорошо модель работает на новых данных.
  5. Применение: Обученная модель используется для анализа новых данных.

Типы ML-моделей:

  1. Супервизорное обучение (Supervised Learning): Обучение на размеченных данных (например, классификация писем как «спам» или «не спам»).
  2. Без учителя (Unsupervised Learning): Выявление скрытых структур в неразмеченных данных (например, кластеризация клиентов).
  3. Обучение с подкреплением (Reinforcement Learning): Модель учится через награды за правильные действия (например, обучение робота).

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

В данной статье я бы хотел продемонстрировать как достаточно просто можно развернуть чат ollana, пару слов о том, что из себя представляет ollama

Ollama — это платформа и инструмент для локальной работы с большими языковыми моделями (LLM, Large Language Models). Она позволяет запускать и использовать LLM прямо на вашем устройстве, не требуя обращения к внешним серверам.

Основные особенности Ollama:

  • Локальная работа: Запуск моделей происходит локально, что повышает конфиденциальность и безопасность.
  • Оптимизация: Использует аппаратные ресурсы устройства максимально эффективно.
  • Поддержка популярных моделей: Ollama работает с различными открытыми и специализированными языковыми моделями, включая модели вроде Llama 2, Alpaca, или GPT.

Модели: Ollama предоставляет доступ к языковым моделям, которые работают с текстами. Это может быть генерация текста, обработка запросов, написание кода и многое другое.

Технология:

  • Использует LLM, которые обучены на огромных текстовых датасетах.
  • Поддерживает работу с моделями, оптимизированными для локального запуска.
  • Совместима с архитектурами, такими как Transformer, лежащими в основе современных LLM.

Применение:

  • Генерация текста (автоматизация переписки, написание статей).
  • Классификация (определение тематики текста).
  • Анализ (суммаризация текста, ответ на вопросы).

Ollama может использовать любые модели, доступные в формате GGML, подходящем для локального запуска.

По управлению ollama немного напоминает docker

Для установки ollama нужно перейти на официальный сайт и скачать версию для вашей операционной системы

После установке можно запустить ollama выполнив команду в консоле:

$ ollama run llama3.2

Данная команда скачает и запустит модель llama3.2

Список моделей доступных для ollama можно посмотреть тут модели могут быть мощными 90B и выше, так и менее мощными 2B

Можно установить любое количество моделей ( если у вас хватает ресурсов ), для просмотра уже скаченных моделей можно воспользоваться командой:

$ ollama list

NAME               ID              SIZE      MODIFIED     
codestral:22b      0898a8b286d5    12 GB     12 hours ago    
phi:latest         e2fd6321a5fe    1.6 GB    14 hours ago    
llama3.2:latest    a80c4f17acd5    2.0 GB    4 days ago 

Так же хотелось бы отметить, что такое 2B, 90B. Это обозначения, которые указывают на количество параметров в машинной модели (в миллиардах, где B означает billion — миллиард). Параметры — это числовые значения, которые модель настраивает во время обучения для выполнения задач, таких как обработка текста или генерация ответов. К примеру, GPT-4 использует 1.8 триллиона параметров (или 1,800 миллиардов)

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

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

так же после запуска чат доступен по адресу http://localhost:11434, по которому можно обратится, сформировав HTTP запрос. Вот пример как это сделать:

На curl из командной строки:

curl -X POST http://localhost:11434/api/generate \
-H "Content-Type: application/json" \
-d '{
  "model": "llama3.2",
  "prompt": "Привет! Как дела?",
  "stream": false
}'

Получаем ответ, что-то вроде:

{
  "model": "llama3.2",
  "created_at": "2024-12-14T22:15:02.891574Z",
  "response": "Здравствуйте! Я работаю нормально, gracias за вопрос. Как youre?",
  "done": true,
  "done_reason": "stop",
  "context": [
    ...
  ],
  "total_duration": 1162500333,
  "load_duration": 50502583,
  "prompt_eval_count": 32,
  "prompt_eval_duration": 618000000,
  "eval_count": 20,
  "eval_duration": 491000000
}

Тут важно отметить, что если не передать в теле запроса «stream»: false то ответ будет возвращаться в виде так называемых чанков, на каждое генерацию ответа:

{"model":"llama3.2","created_at":"2024-12-14T22:12:32.01656Z","response":"Пр","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.032929Z","response":"ив","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.054271Z","response":"ет","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.076969Z","response":"!","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.098469Z","response":" Как","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.122245Z","response":" я","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.144477Z","response":" могу","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.165088Z","response":" пом","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.186886Z","response":"очь","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.207423Z","response":" вам","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.229528Z","response":"?","done":false}
...

Так же к чату можно обращаться из своих скриптов, вот простой пример скрипта на PHP:

<?php

$url = 'http://localhost:11434/api/generate';
$data = [
    "model" => "llama3.2",
    "prompt" => "Привет! Как дела?",
    "stream" => true // включение потокового режима
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $chunk) {
    // Обрабатываем чанки текста
    $response = json_decode($chunk, true);
    if (isset($response['response'])) {
        echo $response['response'];
    }
    return strlen($chunk);
});

curl_exec($ch);
curl_close($ch);

Далее не помешало бы настроить какой-то удобный интерфейс для взаимодействия с ИИ чатом. Для этого можно воспользоваться готовым решением — open-webui

Open-webui — это графический интерфейс при помощи которого можно подключаться как к локальным так и к удаленным генеративным моделя наподобие chatGPT или LLaMa

open-webui можно установить локально ( для этого потребуется установить Paython ) или воспользоваться образом из докера. Мне больше нравится работать с докером, поэтому я выбрал вариант с контейнером:

$ docker run -d -p 3000:8080 -e OLLAMA_BASE_URL=http://host.docker.internal:11434 -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main

Тут важно отметить, что я указал в команде значение переменной -e OLLAMA_BASE_URL=http://host.docker.internal:11434

Она указывает на адрес на котором ollama запускается локально. В моем случае подобный вариант запуска привел к тому, что UI web интерфейса очень сильно тормозил, поэтому в команде я указал вместо http://host.docker.internal:11434 — http://localhost:11434 а уже после запуска изменил адрес на http://host.docker.internal:11434 из панеле управления: Админ Панель -> настройки -> соедниение

После запуска, open-webui будет доступен по адресу http://localhost:3000

Нужно будет зарегистрироваться и можно общаться с чатом:

Ну вот и все! Надеюсь данная информация будет полезна кому-нибудь.

, , , ,

10 декабря, 2024

Работа с Tron ( TRX ) на PHP

Сегодня хотел бы рассказать про такую замечательную криптовалюту как TRON ( TRX ), а так же показать как достаточно просто можно создать сервис процессинга оплаты при помощи АПИ — https://api.trongrid.io на любимом многими РHP

Почему я считаю, что TRX замечательным:

  • Сеть Tron работает очень быстро с минимальными затратами. TRON способен обрабатывать до 2000 транзакций в секунду, что значительно больше, чем у Ethereum (15-30 транзакций/секунда) или Bitcoin (5-7 транзакций/секунда).
  • Транзакции в TRON практически бесплатны. Это делает его отличным выбором для частых и мелких переводов, особенно в DeFi-приложениях и микротранзакциях.
  • Огромная популярность стэйблкоина в сети TRON (TRC20) из-за скорости и минимальных комиссий

Теперь я хотел бы продемонстрировать простой способ как можно процессить проведение платежей на примере реализации простого API на PHP с использованием Symfony.

Каким образом настроить докер для работы Symfony а так же как развернуть на Symfony API я углоблятся не буду ( может напишу про это отдельный пост чуть позже ), а вот как установить библиотеку и подключить ее к проекту на Symfony расскажу.

Для установки библиотеки для работы с АПИ TRX потребуется composer

Устанавливаем необходимый пакет:

# composer require iexbase/tron-api

Я хочу создать API который будет реализовывать 2 метода REST API:

  1. метод создания кошелька
  2. метод получения баланса кошелька

В целом думаю этого будет достаточно для того чтобы создать кошелек TRON для оплаты чего-либо и далее регулярно выполняя запросы на метод получения данных о балансе можно будет производить проверку проведения платежа, если сумма платежа будет соответствовать той под которую создавался кошелек, тогда оплату можно считать успешной.

<?php

namespace App\Controller;

use IEXBase\TronAPI\Exception\TronException;
use IEXBase\TronAPI\Provider\HttpProvider;
use IEXBase\TronAPI\Tron;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;

class CreateWalletController extends AbstractController
{
    /**
     * @throws TronException
     */
    #[Route('/wallet', name: 'create_wallet', methods: ['POST'])]
    public function __invoke(Request $request): JsonResponse
    {
        $fullNode = new HttpProvider('https://api.trongrid.io'); // Нода Tron
        $solidityNode = new HttpProvider('https://api.trongrid.io');
        $eventServer = new HttpProvider('https://api.trongrid.io');
        $tron = new Tron($fullNode, $solidityNode, $eventServer);
        $wallet = $tron->generateAddress();
        $data = $wallet->getRawData();

        return new JsonResponse([
            'wallet' => $data['address_base58']
        ]);
    }
}

Это простой метод POST при вызове которого будет создан кошелек.
Тут важно отметить, что приватный ключ не будет нигде сохранен и передан, поэтому с кошельком далее нельзя будет выполнить какие-либо действия ( тут приводится упрощенный код для того чтобы показать как это можно сделать на PHP )

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

<?php

namespace App\Controller;

use IEXBase\TronAPI\Exception\TronException;
use IEXBase\TronAPI\Provider\HttpProvider;
use IEXBase\TronAPI\Tron;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;

class GetAddressInfo
{
    #[Route('/address/{address}', name: 'get_address_info')]
    public function __invoke(string $address): JsonResponse {
        $fullNode = new HttpProvider('https://api.trongrid.io');
        $solidityNode = new HttpProvider('https://api.trongrid.io');
        $eventServer = new HttpProvider('https://api.trongrid.io');

        try {
            $tron = new Tron($fullNode, $solidityNode, $eventServer);
            $tron->setAddress($address);
            $balance = $tron->getBalance();
            $info = $tron->getAccount();
        } catch (TronException $e) {
            exit($e->getMessage());
        }
        return new JsonResponse([
            'address' => $address,
            'create_date' => date('Y-m-d H:i:s', $info['create_time']/1000),
            'balance' => $balance,
        ]);
    }
}

Таким образом мы можем получить баланс кошелька и сопоставить его с ожидаемой суммой в TRX для оплаты того под что создавался кошелек. Тут важно понимать, что подобная система не является полностью работоспособной. Чтобы далее что-то делать со средствами которые поступили на счет нового кошелька, потребуется как минимум приватный ключ, но я думаю эти методы вполне могут подойти для каркаса будущего приложения в парадигме web3

Продолжение следует.

, ,

8 декабря, 2024

Что такое майнинг. За что дают вознаграждение.

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

Итак, мы все слышали про майнеров и майнинг Биткона, но в чем суть этого процесса. Попытаюсь рассказать как можно проще.

Криптовалюты, такие как Биткоин и Эфириум, представляют собой децентрализованную базу данных — своеобразный журнал (лог), в котором хранится история взаимодействий между адресами. Каждое взаимодействие — это транзакция, записанная в блокчейн.

Блокчейн — это последовательная цепочка блоков, где каждый блок содержит множество транзакций. Записи (блоки) связаны между собой, что делает их неизменными и надежными. Такой децентрализованный подход означает, что данные не хранятся на одном сервере, а распределяются между участниками сети.

Как работает майнинг?

Когда в сети происходит новая транзакция, она сначала попадает в мемпул — специальное хранилище неподтвержденных транзакций. Задача майнеров — взять эти транзакции, объединить их в блок и вычислить его хэш. Однако, чтобы хэш считался корректным, он должен соответствовать определенному правилу, например, начинаться с нескольких нулей. Это правило определяет сложность майнинга.

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

Зачем нужна сложность хэширования?

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

Как майнеры зарабатывают?

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

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

Пример майнинга (на уровне идеи) с использованием PHP

<?php

// Простые данные блока
$blockData = "Example Block Data"; // Данные блока
$previousHash = "0000abc123";      // Хеш предыдущего блока
$difficulty = 4;                  // Количество нулей в начале хеша

$nonce = 0;                       // Начальное значение nonce
$found = false;                   // Флаг успешного нахождения

// Майнинг — перебор значений nonce
while (!$found) {
    $nonce++;
    $hash = hash('sha256', $blockData . $previousHash . $nonce);

    // Условие: хеш должен начинаться с заданного количества нулей
    if (substr($hash, 0, $difficulty) === str_repeat('0', $difficulty)) {
        $found = true;
        echo "Блок найден!\n";
        echo "Хеш: $hash\n";
        echo "Nonce: $nonce\n";
    }
}

Пример майнинга (на уровне идеи) с использованием Rust

use sha2::{Sha256, Digest};

fn main() {
    let data = b"Example Block Data";
    let mut nonce: u64 = 0;
    let difficulty = 4;
    
    loop {
        // Формируем строку: данные + nonce
        let input = format!("{}{}", String::from_utf8_lossy(data), nonce);
        
        // Создаем SHA256 хеш
        let mut hasher = Sha256::new();
        hasher.update(input);
        let hash = hasher.finalize();
        
        // Проверяем, начинается ли хеш с заданного числа нулей
        if hash.iter().take(difficulty).all(|&byte| byte == 0) {
            println!("Блок найден!");
            println!("Nonce: {}", nonce);
            println!("Hash: {:x}", hash);
            break;
        }
        
        nonce += 1;
    }
}

Пример скрипта на Python создания нового блока и майнинга

import hashlib
import time

class Block:
    def __init__(self, index, previous_hash, data, difficulty):
        self.index = index  # Номер блока
        self.timestamp = time.time()  # Время создания блока
        self.previous_hash = previous_hash  # Хеш предыдущего блока
        self.data = data  # Данные транзакций
        self.difficulty = difficulty  # Сложность (число нулей в начале хэша)
        self.nonce = 0  # Счетчик, который будет меняться, чтобы найти подходящий хеш
        self.hash = self.compute_hash()  # Текущий хеш блока

    def compute_hash(self):
        """
        Вычисляет SHA256-хеш текущего блока на основе его данных.
        """
        block_string = f"{self.index}{self.timestamp}{self.previous_hash}{self.data}{self.nonce}"
        return hashlib.sha256(block_string.encode()).hexdigest()

    def mine_block(self):
        """
        Ищет такой хеш, который удовлетворяет условиям сложности (difficulty).
        """
        prefix = "0" * self.difficulty
        while not self.hash.startswith(prefix):
            self.nonce += 1  # Меняем nonce
            self.hash = self.compute_hash()  # Пересчитываем хеш
        return self.hash

# Пример работы
def main():
    # Сложность: требуется, чтобы хеш начинался с двух нулей
    difficulty = 2

    # Генерация блока 1
    genesis_block = Block(index=1, previous_hash="0" * 64, data="First Block", difficulty=difficulty)
    print("Mining genesis block...")
    print(f"Block mined with hash: {genesis_block.mine_block()}")
    print(f"Nonce: {genesis_block.nonce}\n")

    # Генерация блока 2
    block_2 = Block(index=2, previous_hash=genesis_block.hash, data="Second Block", difficulty=difficulty)
    print("Mining second block...")
    print(f"Block mined with hash: {block_2.mine_block()}")
    print(f"Nonce: {block_2.nonce}\n")

if __name__ == "__main__":
    main()

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

,

6 декабря, 2024

Репостинг wordpress постов в VK в 2024 году

Всем привет! Когда-то давно уже делал подобное для других сайтов на вордпрессе, решил сделать так же для данного блога подобную систему репостинга в социальную сеть вконтакте.

Думал, что сложностей не возникнет, но оказывается, что сейчас что-то стало проще, а что-то труднее.

Информации по интеграции WordPress с новым АПИ ВК изложенной последовательно и просто, я не нашел поэтому пришлось собирать данные об этом из разных частей, а потом пробовать те или иные вариант, но в итоге я пришел к более-менее приемлемому варианту для себя.

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

Поэтому я решил делать репостинг через токен группы, чтобы его подключить необходимо в своей группе перейти в управление и создать ключ доступа ( он потребуется для выполнения дальнейших запросов от WP к нашей группе )

Перед тем как писать код на php я бы хотел так же отметить, что выбранный мной формат репоста будет являться ссылка на пост сайта. Сначала были предприняты попытки добавление полноценной записи со своим изображением и текстом, но проблемой оказалось так сделать потому что для загрузки изображение в группу а так же получения данных альбомов группы треубется пользовательский токен, а его теперь стало труднее получить поэтому я отказался от создания полноценного поста в ВК.

Не знаю по какой причине по токену группы нельзя получить список фотографий этой же группы и почему нельзя загрузить фотографию в эту же группу, возможно это бага, возможно фича. Общаться на эту тему в группе VK API у меня не было особого желания поэтому я отказался от создания полноценных записей на стену сообщества и остановился на варианте передачи attachments в запрос к АПИ со ссылкой на запись поста.

И тут хотелось бы так же сказать еще, что для красивого отображения прикрепленных ссылок требуется чтобы на сайте на который вы оставляете ссылку были прописаны Open Graph теги, как это можно сделать я писал тут
Добавить Open Graph в WordPress необходимо, вот, например как будет выглядеть репост в социальную сеть с Open Graph и без него:

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

Теперь расширяем функционал репостинга для ВК

Открываем на редактирование functions.php нашей темы и создаем функцию, которая будет отправлять наш пост на стену сообщества

// Добавляем функцию авторипостинга в хуки смены статуса поста

// Если пост переходит из автосохраненной в публикацию 
add_action('auto-draft_to_publish', 'send_post_vk', 20, 1);

// Если пост переходит из запланированного поста в публикацию
add_action('future_to_publish', 'send_post_vk', 20, 1);

// Если пост переходит из черновика в публикацию
add_action('draft_to_publish', 'send_post_vk', 20, 1);

function send_post_vk($post_id)
{
    // Получаем пост 
    $post = get_post($post_id);

    // Добавляем к тексту сообщения теги поста
    $text = get_tags_to_message($post->ID);
    if (!empty($text)) {
        $text = PHP_EOL.$text.PHP_EOL;
    }

    // Убираем из текста лишнее и обрезаем его до 500 символов
    $text .= preg_replace('/[\n\r]+/s', "\n\n", strip_tags($post->post_content));
    $text = strip_tags($text);
    if (strlen($text) > 500) {
        $text = mb_substr($text, 0, 500) . '...';
    }

    // Закидываем в текст прямую ссылку на пост ( иногда почему-то аттачмент не срабатывает, поэтому я решил дополнительно еще добавить ссылку поста к тексту
    $text .= PHP_EOL.get_permalink($post->ID).PHP_EOL;
    $data = [
        'message' => $text,
        'link' => get_permalink($post->ID)
    ];

    // Вызываем функцию обращения к АПИ и передаем ее сформированный массив с данными
    vk_send_message_to_channel($data);
}

function vk_send_message_to_channel($data) {
    $url = 'https://api.vk.com/method/wall.post';
    $params = [
        'owner_id' => VK_GROUP, // ВК сообщество ( не забываейте что это должно быть отрицательное целое с минусом в начале ID сообщества)
        'message' => $data['message'], // Текст сообщения на стене
        'attachments' =>  $data['link'], // В атачменте передаем прикрепленную ссылку с необходимым постом
        'access_token' => VK_TOKEN, // Тут должен передаваться токен АПИ вашего сообщества, я показывал где его можно создать на скриншоте выше
        'from_group' => 1, // Сообщаем, что пост будет от автора сообщества
        'v' => '5.131'
    ];

    // Вызываем метод отправки данных через curl
    curl_sender_exec($url, $params);
}

// Функция отправки данных через curl, вынес его чтобы не дублировать в других местах, где необходимо также отправка данных через curl
function curl_sender_exec($url, $params) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_exec($ch);
    curl_close($ch);
}

Ну вот и все :) Теперь автопостинг будет автоматически отправлять при публикации в WordPress вашу статью в сообщество. Вот тут можно посмотреть как выглядет репостинг, за одно подписаться

, ,

5 декабря, 2024

Netcat: универсальный швейцарский нож для сетевых операций

Давно на этом сайте не было статей про unix way подход. Не было ничего насчет инструментов командной строки, который нельзя игнорировать даже в наш век сложных UI UX инструментов, командная строка остается один из самых эффективных инструментов в профессиях связанных с IT индустрией, поэтому тут хотел бы рассказать и привести примеры взаимодействия с сетью через такую замечательную команду как netcat доступная в большинстве дестрибутивом unix подобных систем

Итак, поехали!

Netcat (nc) — это маленькая, но мощная утилита в мире UNIX, которая часто упоминается как «швейцарский нож» для сетевых операций. Она позволяет нам отправлять и принимать данные по сети, а также может заменить сразу несколько специализированных утилит. В этой статье мы разберём, как nc может облегчить жизнь системного администратора, разработчика, а также просто энтузиаста, заинтересованного в исследовании сетевых возможностей.

Зачем нужен Netcat?

Использование nc может быть полезно для диагностики сети, передачи файлов, отладки сетевых приложений и даже создания простых серверов и клиентов. Главный плюс — это гибкость nc и поддержка широкого диапазона сетевых протоколов и операций.

Установка Netcat

В большинстве UNIX-систем Netcat уже установлен. Но если вдруг у вас его нет, можно легко добавить его через менеджер пакетов:

# На Debian/Ubuntu
sudo apt install netcat

# На CentOS/RHEL
sudo yum install nc

# На MacOS
brew install netcat

Теперь, когда nc у нас на борту, давайте разберёмся с реальными примерами использования.

1. Диагностика открытых портов

Вы хотите узнать, открыт ли определённый порт на сервере, или, возможно, провести быструю диагностику состояния сети? Netcat может помочь!

nc -zv example.com 80
  • -z — режим проверки портов (без отправки данных).
  • -v — включение режима подробного вывода (verbose).

Пример вывода:

Connection to example.com 80 port [tcp/http] succeeded!

Этот трюк полезен для быстрого анализа открытых портов на сервере, например, при проверке, работает ли сервер после перезагрузки.

2. Передача файлов

Netcat можно использовать для передачи файлов по сети — простой и быстрый способ отправить что-то, не прибегая к сложным утилитам.

На стороне отправителя (отправка файла):

cat myfile.txt | nc -l 1234

На стороне получателя (приём файла):

nc <IP-адрес> 1234 > receivedfile.txt

После выполнения этих команд содержимое myfile.txt на отправляющей стороне будет передано и сохранено как receivedfile.txt на принимающей стороне. Эта опция отлично подходит для работы в рамках одного сегмента сети или виртуальной среды.

3. Запуск простого сервера или тестового чата

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

# Серверная сторона
nc -l 5555

Сервер готов и прослушивает подключение на порту 5555. Теперь на клиентской стороне подключаемся к этому порту:

# Клиентская сторона
nc <IP-адрес сервера> 5555

Теперь у нас есть простой чат-сервер! Всё, что вы набираете на стороне клиента, будет отображаться на сервере, и наоборот. Этот метод часто используется для тестирования или отладки сетевых соединений и приложений в реальном времени.

4. Реализация теста скорости сети

С помощью nc и pv (pipe viewer) можно провести тест скорости сети, чтобы понять, насколько хорошо она работает. В этом случае pv отправляет данные через nc, и это полезно, когда требуется быстро протестировать локальную сеть.

На серверной стороне:

nc -l 5555 > /dev/null

На клиентской стороне:

pv /dev/zero | nc <IP-адрес сервера> 5555

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

5. Проверка DNS-серверов и отправка DNS-запросов

С помощью nc можно отправить DNS-запрос напрямую на сервер для отладки или диагностики.

Например, чтобы отправить DNS-запрос на определённый сервер, можно использовать комбинацию с echo:

echo -e "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x06google\x03com\x00\x00\x01\x00\x01" | nc -u 8.8.8.8 53
  • Команда echo -e создаёт DNS-запрос в шестнадцатеричном формате, чтобы запросить www.google.com.
  • -u указывает, что нужно использовать UDP, так как DNS работает на этом протоколе.

Это полезно для диагностики сетевых проблем и проверки того, как работает DNS-сервер.

6. Мониторинг TCP и UDP портов (сетевой сниффер)

Netcat может быть использован как базовый сетевой сниффер для мониторинга входящих данных на портах. Например, если нужно прослушивать UDP-порт на 5555:

nc -u -l 5555

Этот режим полезен для диагностики UDP-соединений или проверки активности на порту, особенно если данные передаются по сети случайным образом.

7. Проверка доступности веб-сайта и получение HTTP-заголовков

С помощью nc можно проверить, правильно ли работает веб-сервер, отправив к нему HTTP-запрос и получив заголовки ответа.

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | nc example.com 80

Этот запрос отправляет простую команду GET на сервер example.com, и Netcat возвращает HTTP-заголовки, позволяя увидеть статус-сообщение и понять, отвечает ли сервер.

8. Создание резервной копии диска через сеть

Netcat можно использовать для копирования содержимого одного жесткого диска на другой через сеть. Этот метод подойдёт для создания резервных копий или клонирования.

На стороне отправителя:

dd if=/dev/sda | nc -l 1234

На стороне получателя:

nc <IP-адрес отправителя> 1234 | dd of=/dev/sdb

Здесь dd используется для чтения данных с диска, а nc передаёт эти данные по сети на другой диск. Это эффективный способ, но требует осторожности, так как данные могут быть перезаписаны.

9. Отправка сообщений в чат в несколько потоков

Netcat можно настроить для создания текстового чата между несколькими пользователями, что пригодится, например, для координации действий в одной сети.

На стороне сервера:

mkfifo mypipe
nc -l 1234 < mypipe | tee mypipe

На стороне клиента:

nc <IP-адрес сервера> 1234

Тут мы используем именованный канал (FIFO) mypipe для передачи данных в двух направлениях. Это позволяет передавать сообщения от всех подключённых клиентов серверу и обратно.

10. Сканирование диапазона портов на удалённом сервере

Netcat может быть использован для быстрого сканирования диапазона портов, чтобы узнать, какие из них открыты. Хотя это и не заменяет полноценные сканеры (как nmap), Netcat предоставляет простое решение.

for port in {20..25}; do
  echo "" | nc -v -w 1 -z example.com $port
done
  • -w 1 устанавливает таймаут в 1 секунду.
  • -z указывает на то, что нам нужно только проверить открытость порта, не отправляя данных.

Это полезно для быстрого анализа доступных портов на целевом сервере.

11. Организация обратного подключения для удалённого доступа

Для отладки или диагностики можно организовать обратное подключение с использованием nc, чтобы получить доступ к удалённой системе.

На целевой стороне:

nc -l -p 1234 -e /bin/bash

На управляющей стороне:

nc <IP-адрес целевой машины> 1234

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

12. Перехват и просмотр трафика на локальном интерфейсе

Перехват и просмотр трафика на локальном интерфейсе

Если вы хотите быстро посмотреть, что за трафик проходит через ваш локальный интерфейс, можно использовать комбинацию nc и tcpdump.

tcpdump -i eth0 -s0 -w - | nc -l 1234

Эта команда захватывает трафик на интерфейсе eth0 и передаёт его через nc для анализа. На другой стороне можно подключиться к этому порту и просматривать трафик в реальном времени.

Ну и немного совсем экзотических примеров использования команды nc

13. Создание простого веб-сервера на базе nc

С помощью nc можно запустить минималистичный HTTP-сервер на своём компьютере, который будет отдавать статический файл или HTML-страницу. Это может пригодиться для быстрой демонстрации или тестирования локально без полноценного веб-сервера.

Пример команды для одностраничного веб-сервера:

while true; do echo -e "HTTP/1.1 200 OK\r\nContent-Length: $(wc -c < index.html)\r\n\r\n$(cat index.html)" | nc -l -p 8080; done
  • Эта команда запускает бесконечный цикл, который отдаёт содержимое файла index.html по HTTP на порт 8080.
  • Подойдёт для тестов, проверки HTTP-запросов и небольших демонстраций.

Теперь, зайдя на http://localhost:8080 в браузере, можно увидеть содержимое index.html.

14. Туннелирование TCP-порта через UDP (обход блокировок)

Когда на брандмауэре разрешены только UDP-порты, nc можно использовать для проброса TCP-трафика через UDP, обходя тем самым блокировки на уровне сети. Это немного хакерский метод, но работает в специфичных случаях.

Серверная сторона (UDP к TCP-туннель):

nc -u -l -p 5555 | nc localhost 80

Здесь nc принимает UDP-пакеты на порту 5555 и перенаправляет их к TCP-соединению на локальный порт 80 (обычно HTTP).

Клиентская сторона:

echo "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" | nc -u <IP-адрес сервера> 5555

Таким образом можно протестировать HTTP через UDP, например, когда нужно обойти некоторые ограничения сетевых правил.

15. Переключатель музыки или медиа-сервера через аудиопоток

С помощью nc можно создать простое потоковое аудио- или видеовещание. Например, для проигрывания музыки на другой машине по сети.

На стороне отправителя:

cat song.mp3 | nc -l -p 4000

На стороне получателя:

nc <IP-адрес отправителя> 4000 | mpv -
  • Эта команда передаёт файл song.mp3 через nc, а на принимающей стороне поток воспроизводится плеером mpv.
  • Подходит для потоковой передачи аудиофайлов или даже видео через локальную сеть без сложной настройки.

16. Координация команд в кластере

Если у вас есть несколько серверов, и вам нужно выполнить одну и ту же команду на каждом из них, nc можно использовать для координации. Один сервер действует как мастер, отправляя команды всем остальным.

На сервере-мастере:

echo "ls -l /home" | nc -w 1 <IP-адрес сервера1> 1234
echo "ls -l /home" | nc -w 1 <IP-адрес сервера2> 1234

На каждом из серверов:

nc -l 1234 | bash
  • Эта команда отправляет ls -l /home от мастера, и все серверы её выполняют.
  • Применимо для быстрой автоматизации команд или тестирования на нескольких серверах без сложной настройки.

17. Секретное сообщение с самоуничтожением

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

На стороне отправителя:

echo "Это сообщение самоуничтожится через 5 секунд" | nc -l -p 5000

На стороне получателя:

nc <IP-адрес отправителя> 5000 && sleep 5 && echo "Сообщение удалено"

После того как сообщение прочитано, команда sleep 5 завершает выполнение через 5 секунд, и на экране выводится сообщение о том, что оно было «удалено».

На этом пока что все. Буду время от времени еще выкладывать интересные инструменты командный строки.

4 декабря, 2024

Очистка кэша Open Graph для VK и Telegram

Всем привет! Ранее я писал про Open Graph и как его поддержку можно просто реализовать на WordPress

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

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

Очистка кэша Open Graph для VK

<?php
// Укажите ваш токен доступа
$token = '***';

// URL страницы, которую нужно обновить
$url_to_clear = 'https://killercoder.ru';

// URL API ВКонтакте
$api_url = 'https://api.vk.com/method/';

// Функция для очистки кэша
function clearVkCache($url, $token)
{
    $api_url = 'https://api.vk.com/method/utils.resolveScreenName';
    $params = [
        'screen_name' => $url,
        'access_token' => $token,
        'v' => '5.131'
    ];

    // Отправка запроса
    $response = file_get_contents($api_url . '?' . http_build_query($params));
    $result = json_decode($response, true);

    // Проверка результата
    if (isset($result['error'])) {
        die('Ошибка: ' . $result['error']['error_msg']);
    }

    return $result;
}

// Очистка кэша
$response = clearVkCache($url_to_clear, $token);
if ($response) {
    echo "Кэш для ссылки обновлен успешно!";
} else {
    echo "Не удалось обновить кэш ссылки.";
}

Теперь этот скрипт нужно выполнить. Это можно сделать запустив консольный php-cli или обратившись HTTP запросом к веб серверу, который будет выполнять этот код.

Очистка кэша Open Graph для Telegram

Для очистки кэша Open Graph для Telegram необходимо запустить телеграмм бота — @WebpageBot

После чего скормить ему адрес ссылки для которой требуется сбросить кэш.

Ну вот и все. Следите за обновлением сайта в телеграм канале, а также присоединяйтесь к сообществу в ВК

1 декабря, 2024

Добавление Open Graph в блог на WordPress

Всем привет! Сегодня хочу рассказать о том, что такое Open Graph, для чего нужен и как его можно добавить в свой блог на Wodpress простым способом.

Open Graph — это специальный протокол, который был разработан в Facebook. В последствие на него стали использовать большинство популярных месенджеров и социальных сетей для отображения ссылок.

Для того чтобы добавить Open Graph на свой сайт, достаточно в html внутри тега <head> разместить блок с таким содержанием:

<meta property="og:title" content="Название страницы">
<meta property="og:description" content="Описание страницы">
<meta property="og:image" content="https://example.com/image.jpg">
<meta property="og:url" content="https://example.com">
<meta property="og:type" content="website">

По-своей сути это обычные мета теги, но с дополнительной микроразметкой og: которую понимаю социальные сети вроде вконтакте и месенджеры вроде телеграмм

Наверное есть множество готовых плагинов для редактирование open graph тегов в WordPress, но плагины это не мой путь, тем более доработка для Wodpress не просто простая, а очень простая.

Для того, чтобы сделать вывод мета тегов og нужно отредактировать файл темы functions.php

Для начала давайте пропишем событие при котором будет вызываться функция которая будет автоматически заполнять content мета тегов Open Graph и возвращать блок с заполненной разметкой.

Используем для этой цели событие wp_head(). Это событие вызывается при загрузки шапки сайта, как раз то что нужно.

add_action( 'wp_head', 'load_og_meta' );

А теперь описываем функцию load_og_meta():

function load_og_meta() {
    $og_meta = '';

    // Выводим только для страниц и постов
    if ( is_page() || is_single() ) {
        
        // Получаем пост 
        $post = get_post(get_queried_object_id());

        // Эта функция получает метки нашего поста, может быть полезна для социальных сетей вроде VK
        $tags = get_tags_to_message($post->ID);
        if (!empty($text)) {
            $tags .= PHP_EOL.$text.PHP_EOL;
        }

        // Получаем изображение поста, если оно есть
        if (has_post_thumbnail($post->ID)) {
            $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'single-post-thumbnail' );
        }

        // Тут немного приводим в порядок текст для описания
        $text = $tags . preg_replace('/[\n\r]+/s', "\n\n", strip_tags($post->post_content));
        if (strlen($text) > 500) {
            $text = mb_substr($text, 0, 500) . '...';
        }

        // Заполняем мета теги данными
        $og_meta .= '<meta property="og:title" content="' . $post->post_title. '" />' . PHP_EOL;
        $og_meta .= '<meta property="og:description" content="' . $text . '" />' . PHP_EOL;
        $og_meta .= '<meta property="og:url" content="' . get_permalink($post->ID) . '" />' . PHP_EOL;
        $og_meta .= '<meta property="og:type" content="URL" />' . PHP_EOL;
        $og_meta .= '<meta property="og:site_name" content="' . get_bloginfo('name') . '" />' . PHP_EOL;
        $og_meta .= '<meta property="og:locale" content="' . get_bloginfo('language') . '" />' . PHP_EOL;
        if (isset($image[0])) {
            $og_meta .= '<meta property="og:image" content="' . $image[0] . '" />' . PHP_EOL;
        }
    }
    echo $og_meta;
}

// функция получения меток
function get_tags_to_message($post_id) {
    $post_tags = get_the_tags( $post_id );
    $text = '';
    if (!empty($post_tags)) {
        foreach ($post_tags as $tag) {
            $text .= sprintf('#%s ', $tag->name);
        }
    }

    return $text;
}

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

Если у вас есть какие-нибудь вопросы, то всегда можете написать мне в телеграм
Так же подписывайтесь на телеграм канал и если пользуетесь вконтакте, недавно была запущено сообщество, так что так же можете присоединятся.

, ,

23 ноября, 2024

DeFi. Что такое децентрализованные финансы

Всем привет! Сегодня хочу рассказать о технологии, которая меня заинтересовала — децентрализованные финансы (DeFi).

Большинство из нас регулярно пользуется финансовыми услугами: банковскими переводами, кредитами, страхованием, инвестициями. Однако централизованные системы, которые лежат в их основе, имеют определенные ограничения:

  1. Зависимость от посредников
    Деньги и данные приходится доверять банкам, брокерам и другим организациям, что несет риски утраты средств из-за ошибок, злоупотреблений или банкротства.
  2. Ограниченный доступ
    Некоторые регионы остаются отрезанными от финансовых услуг из-за слабой инфраструктуры или высоких требований со стороны учреждений.
  3. Высокие комиссии
    Централизованные учреждения часто берут значительные комиссии за переводы, обслуживание счетов и другие операции.
  4. Контроль со стороны третьих лиц
    Банки и другие организации могут устанавливать лимиты, замораживать счета или накладывать ограничения.
  5. Уязвимость для кибератак
    Централизация делает крупные финансовые структуры привлекательными для хакеров.

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

Что такое DeFi

DeFi (Decentralized Finance) — это один из самых горячих трендов в мире блокчейнов и криптовалют. На русском языке термин переводится как «децентрализованные финансы», что дает намек на его суть. DeFi — это финансовые услуги, которые работают без посредников, таких как банки, используя блокчейн и смарт-контракты.

Основные принципы DeFi

  1. Децентрализация: Вместо того чтобы полагаться на банки или другие учреждения, все операции происходят в блокчейне. Это устраняет необходимость в посредниках.
  2. Прозрачность: Любой пользователь может проверить транзакции в сети, что обеспечивает высокую степень доверия.
  3. Доступность: DeFi-платформы открыты для всех. Нужен только интернет и криптовалютный кошелек.
  4. Автоматизация: Используются смарт-контракты, которые автоматически выполняют условия сделки.

Основные направления применения DeFi

  1. Децентрализованные биржи (DEX)
    Это платформы для обмена криптовалют, такие как Uniswap или SushiSwap. В отличие от традиционных бирж, здесь нет центрального органа управления. Сделки заключаются напрямую между пользователями.
  2. Кредитование и займы
    DeFi позволяет брать и давать займы без участия банков. Пример платформы — Aave. Кредиторы могут зарабатывать проценты, а заемщики использовать свои криптоактивы как залог.
  3. Доходное фермерство (Yield Farming)
    Пользователи предоставляют ликвидность (свои активы) для работы протоколов и получают за это вознаграждение.
  4. Стейблкоины
    DeFi активно использует стейблкоины, такие как USDT, DAI и USDC, которые привязаны к стоимости фиатных валют, что снижает волатильность.
  5. Страхование
    В DeFi существуют платформы, которые предоставляют услуги страхования, такие как Nexus Mutual. Они защищают пользователей от финансовых рисков, например, хакерских атак.
  6. Токенизация активов
    DeFi позволяет токенизировать реальные активы, такие как недвижимость, акции или драгоценные металлы, делая их доступными для торговли.

Конечно при работе с DeFi стоит учитывать и сложности: высокая волатильность криптовалют и относительно сложный интерфейс могут отпугнуть новых пользователей, но мое личное мнение, что за децентрализованными финансовыми системами — будущие поэтому рано или поздно, но каждому предстоит погружаться в эту область технологий.

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

, ,

10 ноября, 2024

Что такое стейблкоины и зачем они вообще нужны?

Стейблкоины (от англ. stablecoin) — это криптовалюты, стоимость которых привязана к какому-то стабильному активу, чаще всего к фиатным деньгам, как доллар или евро. В отличие от обычных криптовалют, курс которых может «плавать» вверх и вниз, стейблкоины держат фиксированную цену. Идея проста: дать пользователям крипты стабильный инструмент для хранения и обмена денег, который не будет зависеть от рыночных «качелей».

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

Какие бывают стейблкоины?

Существует несколько видов стейблкоинов, и каждый из них привязан к своему обеспечению и методу поддержания стабильности. Давай разберёмся, какие они бывают.

1. Фиатные стейблкоины

Это самые популярные стейблкоины, например USDT (Tether), USDC (USD Coin) и BUSD (Binance USD). Такие монеты обеспечены реальными деньгами на банковском счёте или ликвидными активами. Один USDT или USDC всегда должен быть равен одному доллару, потому что за ним лежит настоящий доллар или его эквивалент. Фирмы, которые выпускают такие стейблкоины, должны регулярно доказывать наличие резервов для поддержания доверия.

2. Криптообеспеченные стейблкоины

Эти стейблкоины обеспечены криптовалютами. Самый известный пример — DAI от проекта MakerDAO. В отличие от USDT или USDC, здесь используется алгоритм и резерв криптовалюты (чаще всего ETH) для обеспечения курса. Поскольку криптовалюта нестабильна, такие стейблкоины часто имеют избыточное обеспечение — то есть на каждый доллар DAI приходится больше одного доллара в крипте, чтобы компенсировать возможные колебания.

3. Алгоритмические стейблкоины

Здесь ситуация интереснее. Эти стейблкоины вообще не имеют реального обеспечения, а удерживают курс с помощью алгоритмов и смарт-контрактов. Примеры: UST (Terra), FRAX. Механизм такой: если цена монеты падает ниже доллара, алгоритм сжигает часть монет, уменьшая их предложение и повышая цену. Если цена выше доллара, выпускаются новые монеты, снижая курс. Однако такие модели несут риск, так как устойчивость зависит только от алгоритма и спроса на рынке.

Стейблкоины в программном коде

Если рассмотреть стейблкоин с точки зрения кода, то это смарт-контракт, который выполняет разные функции по управлению выпуском и сжиганием монет. Наиболее распространённый стандарт для создания таких токенов на Ethereum — это ERC-20, который поддерживает базовые функции для создания и передачи токенов. Однако у стейблкоинов есть и уникальные особенности, которые добавляются к стандарту.

Вот базовый пример смарт-контракта стейблкоина на Solidity:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract StableCoin is ERC20, Ownable {
    constructor() ERC20("MyStableCoin", "MSC") {
        _mint(msg.sender, 1000000 * 10 ** decimals());
    }

    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }

    function burn(uint256 amount) public {
        _burn(msg.sender, amount);
    }
}

Что здесь происходит?

  • ERC20 — мы используем стандарт ERC-20, который предоставляет функции для работы с токенами: transfer, balanceOf, allowance и другие.
  • Ownable — это модификатор, который даёт владельцу контракта (обычно компании-эмитенту) возможность управлять ключевыми функциями. Например, только владелец может «минтить» (выпускать) новые токены.
  • mint — функция для выпуска новых токенов. В фиатных стейблкоинах такие функции используются, когда компания пополняет резервы.
  • burn — функция для сжигания токенов, если их нужно вывести из обращения.

Этот код — очень базовый пример. На практике контракты стейблкоинов гораздо сложнее, включают управление резервами, автоматическое регулирование курса и часто проходят аудиты безопасности. Также они могут включать функции «заморозки» или блокировки счетов, что может использоваться для соблюдения законодательства.

Стейблкоины — это важная часть криптоиндустрии, мост между волатильной криптой и стабильным фиатом. Они удобны для трейдинга, хранения средств и даже для международных переводов, так как транзакции могут быть намного дешевле и быстрее, чем в традиционных банках. С технической стороны стейблкоин — это токен со стандартным функционалом ERC-20, но с добавлением функций для поддержания курса и управления резервами.

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

, ,

9 ноября, 2024

Что такое Solidity и для чего используется

Что такое Solidity и зачем он вообще нужен?

Solidity — это язык программирования, созданный специально для разработки смарт-контрактов на блокчейне Ethereum. Если ты когда-нибудь хотел создать свою крипту, сделать децентрализованное приложение (dApp) или написать контракт, который сам выполняет условия, как только они наступят, то Solidity — это твой инструмент. На этом языке пишутся «самоисполняющиеся» контракты, которые потом живут в блокчейне, то есть никто их не может изменить или удалить, и они автоматически выполняют всё, что в них прописано.

Где применяется Solidity?

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

  • Binance Smart Chain,
  • Polygon,
  • Avalanche,
  • Fantom.

Эти блокчейны поддерживают виртуальную машину Ethereum (EVM), которая выполняет контракты, написанные на Solidity. Вот несколько популярных применений Solidity:

  • Токены: Можешь создать свою криптовалюту, например, на стандартном шаблоне ERC-20. Это именно те «монетки», которыми торгуют на биржах.
  • NFT: Уникальные цифровые активы (например, произведения искусства или предметы коллекционирования) тоже создаются на Solidity, часто с использованием стандарта ERC-721.
  • Децентрализованные финансы (DeFi): Можно писать контракты для кредитования, ставок, торговли и других финансовых операций без посредников.
  • DAO: Децентрализованные автономные организации, в которых решения принимаются на основе смарт-контрактов и голосования участников.
  • Игры и децентрализованные приложения (dApps): Контракты на Solidity управляют логикой игр и других приложений, где нужен блокчейн.

Как работает Solidity и с чего начать?

Solidity компилируется в байт-код, который понимает EVM. То есть, мы пишем код на Solidity, компилируем его, и после этого он становится «понятен» блокчейну. Если хочешь начать, тебе понадобится среда разработки, которая поддерживает Solidity, например:

  1. Remix — бесплатный веб-инструмент, созданный для Solidity-разработки. Он работает прямо в браузере и идеально подходит для старта.
  2. Truffle и Hardhat — фреймворки для локальной разработки, тестирования и развертывания контрактов. Они дают больше возможностей, чем Remix, и больше подходят для продвинутых проектов.
  3. MetaMask — кошелёк для взаимодействия с блокчейном Ethereum, который пригодится для тестирования и развертывания контрактов.

Основы синтаксиса Solidity

Solidity напоминает C++ и JavaScript, так что если ты знаком с этими языками, разобраться будет проще. Давай начнём с простейшего примера контракта.

Простой контракт: «Привет, мир!»

Вот минимальный код, который создаёт контракт, хранящий одну строку:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract HelloWorld {
    string public greeting = "Hello, World!";
}
  • pragma solidity ^0.8.0; — указывает версию Solidity (в данном случае 0.8 и выше).
  • contract HelloWorld — объявляем контракт с именем HelloWorld.
  • string public greeting — создаём переменную greeting, доступную всем (она публичная), и сразу присваиваем ей значение "Hello, World!".

Запустив этот контракт, ты сможешь увидеть строку "Hello, World!", просто вызвав переменную greeting.

Пример контракта для хранения чисел

Теперь попробуем что-то интереснее: контракт, который сохраняет и возвращает числа. Этот код будет полезен для понимания работы с переменными и функциями.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorage {
    uint256 private storedData;

    // Функция для записи значения
    function set(uint256 x) public {
        storedData = x;
    }

    // Функция для чтения значения
    function get() public view returns (uint256) {
        return storedData;
    }
}

Этот контракт хранит значение и позволяет его записывать и считывать. Основные моменты:

  • uint256 private storedData; — переменная storedData для хранения числа, которая доступна только внутри контракта.
  • set(uint256 x) — функция для записи значения в storedData.
  • get() — функция для получения текущего значения storedData.

Теперь, когда контракт развернут, ты можешь вызвать функцию set, чтобы записать число, и get, чтобы его прочитать.

Пример контракта для создания простого токена

А вот пример создания базового токена на стандартном шаблоне ERC-20. ERC-20 — это стандарт для токенов, которые могут передаваться и торговаться. В реальной жизни можно добавлять дополнительные функции, но вот базовый пример:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor() ERC20("MyToken", "MTK") {
        _mint(msg.sender, 1000 * 10 ** decimals());
    }
}
  • Мы подключаем библиотеку OpenZeppelin, чтобы не писать всё с нуля. Она предоставляет готовые стандарты, включая ERC-20.
  • constructor — это специальная функция, которая выполняется один раз при создании контракта. Здесь мы называем токен MyToken с символом MTK.
  • _mint(msg.sender, 1000 * 10 ** decimals()); — создаёт 1000 токенов и отправляет их на кошелёк создателя.

Запустив этот контракт, ты получишь свои токены прямо на кошелёк! Их можно передавать, использовать в других dApps, или даже листить на бирже (при выполнении дополнительных условий).

Советы для работы с Solidity

  1. Начинай с простых контрактов: Это поможет понять, как работает блокчейн и какие функции обязательны.
  2. Используй тестовые сети: Разворачивай контракты в тестовых сетях (например, Rinkeby или Ropsten), чтобы не тратить настоящие деньги.
  3. Будь осторожен с безопасностью: Ошибки в смарт-контрактах могут привести к уязвимостям. Изучай лучшие практики, такие как использование библиотеки OpenZeppelin, и обязательно проверяй код перед запуском.
  4. Тестируй код: Перед тем как контракт развернётся в реальной сети, обязательно протестируй его на различных сценариях.

Solidity — мощный инструмент для создания всего, от токенов до полноценных децентрализованных приложений. Начать может любой, у кого есть базовые знания программирования и интерес к блокчейну. Контракты, которые ты создаёшь, будут жить в блокчейне, оставаясь неизменными и выполняемыми автоматически. Так что, если ты хочешь попробовать себя в создании смарт-контрактов или даже запуска своей криптовалюты, Solidity — идеальный старт!

Если тебе так же интересна разработка под Solidity и все что связано с блокчейном, смарт-контрактами и разработкой под web3, то обязательно пиши мне в телегу, нам будет что обсудить!

, ,

8 ноября, 2024

Что такое смарт контракт и с чем его едят :)

Что такое смарт-контракт и как он работает?

Смарт-контракт — это, по сути, цифровой контракт, запрограммированный в блокчейне, который выполняет всё сам, как только выполняются нужные условия. Представьте, что у вас есть договор, но вместо бумаги и подписей он закодирован на языке программирования и загружен в блокчейн. Никто не может его изменить или удалить, а всё, что в нём прописано, произойдёт автоматически, как только наступят оговоренные условия.

Смарт-контракты придумали, чтобы убрать посредников. Вам не нужен нотариус или юрист — всё контролируется кодом и самим блокчейном. Это особенно круто в финансовых сделках, где важны прозрачность и доверие. Например, смарт-контракт может отправить деньги, как только наступит определённая дата, или автоматически провести сделку по покупке токенов.

Как устроен смарт-контракт?

Смарт-контракт размещается в блокчейне — это значит, что он доступен всем, его нельзя подделать, и он всегда будет работать так, как было задумано. Как только условия выполняются, контракт автоматически совершает действия. Стороны могут быть уверены, что никто не вмешается и не изменит условия после запуска контракта.

Пример смарт-контракта на Solidity

Solidity — это популярный язык программирования для создания смарт-контрактов на платформе Ethereum. Если вы хотите попробовать написать свой смарт-контракт, вот простой пример:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorage {
    uint256 private storedData;

    // Сохраняем значение
    function set(uint256 x) public {
        storedData = x;
    }

    // Получаем значение
    function get() public view returns (uint256) {
        return storedData;
    }
}

Что тут происходит:

  • pragma solidity ^0.8.0; — это версия Solidity, которая гарантирует, что код будет совместим с текущей версией.
  • uint256 private storedData; — переменная, которая хранит число. Она приватная, так что доступна только из этого контракта.
  • set(uint256 x) — функция, которая позволяет записать значение в переменную.
  • get() — функция, возвращающая значение storedData, просто читает данные.

В этом контракте всё просто: мы можем задать какое-то число и потом получить его. Такой код можно развернуть в блокчейне, и он всегда будет там работать так, как запрограммировано.

Смарт-контракты — это мощный инструмент, который можно использовать для автоматизации действий, которые раньше требовали доверия к третьим лицам. Хочешь отправить средства по расписанию? Или обеспечить, чтобы сделка произошла только при определённых условиях? Всё это можно сделать через смарт-контракт. Это не только экономит время, но и делает процесс прозрачным и надёжным.

, , ,

7 ноября, 2024

Устанавливаем Shadowsocks на свой сервер

Для начала стоит объяснить, что такое Shadowsocks и для чего он может быть полезен.

Иногда вы можете оказаться в сети с ограничениями, где фильтруется интернет-трафик, и доступ к определённым ресурсам блокируется. Такие ограничения могут встречаться, например, в корпоративной сети на работе. Если вам необходимо обойти такие блокировки и получить доступ к нужным сайтам, на помощь может прийти инструмент под названием Shadowsocks. По сути, это прокси-сервер, который использует протокол SOCKS5 для передачи данных.

Протокол SOCKS5 позволяет создать зашифрованное соединение и направлять трафик через него, делая его менее заметным для фильтров и блокировок. В этой статье я расскажу, как быстро развернуть свой прокси-сервер с использованием Shadowsocks. Чем-то это напоминает создание шифрованного тоннеля через ssh.

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

После того как у вас появился свой сервер, необходимо установить shadowsocks
это легко сделать при помощи нескольких команд:

$ sudo apt update
$ sudo apt install shadowsocks-libev

Теперь нужно создать основной файл с настройками shadowsocks. Поэтому создаем в /etc/shadowsocks-libev файл config.json со следующем содержимым:

{
    "server": "[server]",
    "server_port": "[server_port]",
    "password":"[password]",
    "mode":"tcp_and_udp",
    "timeout": 300,
    "local_port": "[local_port]",
    "method": "xchacha20-ietf-poly1305",
    "fast_open": true,
    "nameserver": "8.8.8.8"
}

server — ip адрес сервера
server_port — сервер порт через который будет создан тоннель ( замените на свой )
password — пароль подключения ( замените на свой )
method — метод шифрования ( если не уверены, то лучше оставить такой как в примере )
local_port — порт на локальной машине через который будет проходить зашифрованный трафик

Если у вас на сервере установлен файрвол, то необходимо открыть порт, который был указан в настройках:

$ sudo ufw allow [server_port]
$ sudo ufw reload

Теперь можно запустить shadowsocks:

$ sudo systemctl restart shadowsocks-libev

После этого на сервере все готово и можно приступать к настройке клиентской части.

Для того, чтобы запустить зашифрованный socks5 на вашей локальной машине потребуется установить Shadowsocks клиент. Вот несколько вариантов для разных систем:

Windows

  1. Shadowsocks for Windows — Официальный клиент с графическим интерфейсом.
  2. ShadowsocksR — Модифицированная версия Shadowsocks, поддерживающая дополнительные шифрования и функции.
  3. Outline — Простой в использовании клиент, который также поддерживает Shadowsocks и удобен для новичков.

macOS

  1. ShadowsocksX-NG — Популярный клиент для macOS с поддержкой Shadowsocks и дополнительными функциями.
  2. Outline — Также доступен для macOS, позволяет легко подключаться к Shadowsocks-серверам.

Linux

  1. Shadowsocks-libev — Лёгкий клиент для Linux, поддерживающий командную строку и простой в настройке.
  2. Outline — Клиент с графическим интерфейсом, доступный для нескольких версий Linux.
  3. Shadowsocks-qt5 — Версия с графическим интерфейсом, подходящая для пользователей, предпочитающих GUI.

Android

  1. Shadowsocks for Android — Официальное приложение для Android с поддержкой настроек и переключений.
  2. ShadowsocksR Android — Вариант с дополнительными настройками и функциями.
  3. Outline — Отличный вариант для пользователей, которые хотят быстро подключиться без сложных настроек.

iOS

Outline — Простое и удобное приложение, особенно для начинающих.

Shadowrocket — Один из самых популярных и мощных клиентов для iOS, поддерживает Shadowsocks и другие протоколы.

Potatso Lite — Поддерживает Shadowsocks и имеет удобный интерфейс.

Выбираем подходащий клиент и настраиваем соединение в нем для сервера на который поставили shadwonsocks

После установки соединения SOCKS5 будет доступен на локальной машине на порту local_port который ранее мы указали в настройках shadownsock на сервере

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

,

19 октября, 2024

Пишем крестики нолики на javascript :)

Ради развлечения решил вспомнить немного JS и вот что в итоге получилось! Простая игра на Javascript — крестики нолики

Вот шаблон html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <link rel="stylesheet" href="x0.css">
    <script src="x0.js"></script>
</head>
<body>
<div class="status"></div>
<div class="gamespace"></div>
</body>
</html>

Код стилей x0.css

.gamespace .row * {
    box-sizing: border-box;
}
.gamespace .row {
    display: flex;
    flex-wrap: wrap;
}
.gamespace .col {
    width: 33%;
    position: relative;
    overflow: hidden;
    border: 3px solid #000;
}
.gamespace .col:after {
    content: "";
    padding-top: 100%;
    float: left;
}
.gamespace .item {
    position: absolute;
    width: 100%;
    height: 100%;
    display: flex;
    flex-flow: column;
    align-items: center;
    justify-content: center;
    color: #000;
    font-size: 8em;
}
.gamespace {
    width: 30%;
    margin: 0 auto;
}
.status {
    text-align: center;
    font-size: 2em;
}

И собственно сама бизнес логика приложения

window.addEventListener('load', function () {
    window.game = {
        finishGame: false,
        cells: 3,
        players: {
            zero: {
                value: 0,
                symbol: '0',
            },
            crosse: {
                value: 1,
                symbol: 'X',
            }
        },
        activePlayer: null,
        result: [
            [null, null, null],
            [null, null, null],
            [null, null, null]
        ],
        init: function() {
            this.activePlayer = this.players.crosse;
            this.createGameSpace();
            document.querySelector('.status').innerHTML = 'Ходит игрок: ' + this.activePlayer.symbol;
        },
        createGameSpace: function() {
            let gamespace = '';
            for(let i = 0; i < this.cells; i++) {
                gamespace += this.createRow(i);
            }
            document.querySelector('.gamespace').innerHTML = gamespace;
        },
        createRow: function(i) {
            let row = document.createElement('div');
            row.classList.add('row');
            for(let j =0; j < this.cells; j++) {
                let col = document.createElement('div');
                col.classList.add('col');
                col.insertAdjacentHTML('beforeend', this.createItem(i, j));
                row.insertAdjacentHTML('beforeend', col.outerHTML);
            }

            return row.outerHTML;
        },
        createItem: function(i, j) {
            let item = document.createElement('div');
            item.classList.add('item');
            item.dataset.row = i;
            item.dataset.col = j;

            return item.outerHTML;
        },
        switchPlayer: function() {
            this.activePlayer = this.activePlayer === this.players.zero ? this.players.crosse : this.players.zero;
        },
        finish: function() {
            this.finishGame = true;
        },
        checkWin: function() {
            let isWin = false;
            loop: for (let i = 0; i < this.result.length; i++) {
                for(let j =0; j < this.result[i].length; j++) {
                    if(this.winRow(i,j) || this.winCol(i,j)) {
                        isWin = true;
                        break loop;
                    }
                }
            }
            return isWin || this.winDia();
        },
        winRow: function(row,col) {
            return null !== this.result[row][col] && this.result[row][col] === this.result[row][col+1] && this.result[row][col] === this.result[row][col+2];
        },
        winCol: function(row,col) {
            return null !== this.result[row][col] && this.result[row][col] === this.result[row+1][col] && this.result[row][col] === this.result[row+2][col];
        },
        winDia: function() {
            return this.winDia1() || this.winDia2();
        },
        winDia1: function() {
            return this.result[0][0] === this.result[1][1] && this.result[0][0]  === this.result[2][2] && null !== this.result[0][0]
        },
        winDia2: function() {
            return this.result[0][2] === this.result[1][1] && this.result[0][2] === this.result[2][0] && null !== this.result[0][2];
        },
        showWinLine: function(isWin) {
            if (this.finishGame) {
                window.game.switchPlayer();
                document.querySelector('.status').innerHTML = 'Победил: ' + this.activePlayer.symbol;
            } else {
                document.querySelector('.status').innerHTML = this.isStandoff() ? 'Ничья!' : 'Ходит игрок: ' + this.activePlayer.symbol;
            }
        },
        isStandoff: function() {
            let standoff = true;
            for(let i = 0; i < this.result.length; i++) {
                for(let j = 0; j < this.result[i].length; j++) {
                    if (null === this.result[i][j]) {
                        standoff = false;
                    }
                }
            }
            return standoff;
        }
    }
    window.game.init();
    document.querySelectorAll('.item').forEach(function (e) {
        e.addEventListener('click', function () {
            if ('' === e.innerText && !window.game.finishGame) {
                e.innerText = window.game.activePlayer.symbol;
                window.game.result[parseInt(e.dataset.row)][parseInt(e.dataset.col)] = window.game.activePlayer.value;
                window.game.switchPlayer();
                window.game.showWinLine();
                let finishGame = window.game.checkWin();
                if (finishGame) {
                    window.game.finish();
                    window.game.showWinLine();
                }
            }
        });
    });
});

Код игры можно скачать отсюда — https://github.com/wikide/x0.git

,

6 октября, 2024

Создаем систему для партнерских программ в WordPress

Всем привет! В рамках реализации задачи по монетизации блога на wordpress мне пришла в голову мысль добавить партнерских программ на свой сайт, пертнерок тех компаний услагами которых я пользуюсь самостоятельно, но для реализации этой задачи нужно немного допилить wordpress, от сторонних плагинов по традиции решил отказаться потому что не хочу =) и к тому же для реализации такой простой задачи достаточно будет возможностей wordpress. Итак, поехали. Далее я опишу процесс создания системы партнерских программ для блога.

Для создания партнерок потребуется создать отдельный справочник записей, те зарегистрировать в системе еще один тип постов:

Открываем functions.php темы и добавляем туда что-то вроде:

add_action('init', 'register_post_types');

function register_post_types()
{
    register_post_type('partner', [
        'label' => null,
        'labels' => [
            'name' => 'Партнерки',
            'singular_name' => 'partner',
            'add_new' => 'Добавить партнерку',
            'add_new_item' => 'Добавление партнерки',
            'edit_item' => 'Редактирование пертнерки',
            'new_item' => 'Новая партнерка',
            'view_item' => 'Смотреть партнерку',
            'search_items' => 'Искать патнерку',
            'not_found' => 'Не найдено',
            'not_found_in_trash' => 'Не найдено в корзине',
            'parent_item_colon' => '',
            'menu_name' => 'Партнерка',
        ],
        'description' => '',
        'public' => true,
        'show_in_menu' => null,
        'show_in_rest' => null,
        'rest_base' => null,
        'menu_position' => null,
        'menu_icon' => null,
        'hierarchical' => false,
        'supports' => ['title', 'thumbnail'], // 'title','editor','author','thumbnail','excerpt','trackbacks','custom-fields','comments','revisions','page-attributes','post-formats'
        'taxonomies' => [],
        'has_archive' => false,
        'rewrite' => true,
        'query_var' => true,
    ]);
}

После сохранения в админке WP должен появится новый пункт ниже пунтка меню Записи с названием Партнерки. Теперь у нас есть новый зарегистрированный тип записей с минимальным набором полей ( название и изображение ) для добавления наших партнеров.

Но по-мимо изображения и название так же требуется добавления реферальной ссылки, для этого потребуется для нового типа с партнерами зарегистрировать кастомезированые поля записей, поэтому добавляем следующий код в functions.php

add_action('add_meta_boxes', 'my_extra_fields_meta_box', 1);

function my_extra_fields_meta_box()
{
    $post_type = 'partner';
    add_meta_box('extra_fields', 'Дополнительные поля', 'extra_fields_box_func', $post_type, 'normal', 'high');
}

function extra_fields_box_func($post)
{
    ?>
    <p>
        Ссылка:
        <label>
            <input style="width: 100%;" type="text" name="extra[link]"
                   value="<?= get_post_meta($post->ID, 'link', 1) ?>"/>
        </label>
    </p>
    <p>
        Комментарий:
        <textarea type="text" name="extra[description]"
                  style="width:100%; height:50px;"><?= get_post_meta($post->ID, 'description', 1) ?></textarea>
    </p>
    <p>
        Количество переходов:
        <input type="text" name="extra[count]" value="<?= get_post_meta($post->ID, 'count', 1) ?>" disabled="disabled">
    </p>
    <input type="hidden" name="extra_fields_nonce" value="<?= wp_create_nonce('extra_fields_nonce_id') ?>"/>
    <?php
}

Я решил для своей системы добавить еще 2 свойства партнера, комментарий — для внутреннего использования и подсчета количества переходов по моей реферальной ссылке.

Для того чтобы дополнительные поля сохранялись так же требуется добавить следующий хук

add_action('save_post', 'my_extra_fields_save_on_update', 0);

function my_extra_fields_save_on_update($post_id)
{
    // базовая проверка
    if (
        empty($_POST['extra'])
        || !wp_verify_nonce($_POST['extra_fields_nonce'], 'extra_fields_nonce_id')
        || wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)
    ) {
        return false;
    }

    $extra = $_POST['extra'];

    // Все ОК! Теперь, нужно сохранить/удалить данные

    // Очищаем все данные
    $extra = array_map('sanitize_text_field', $extra);
    foreach ($extra as $key => $value) {
        // удаляем поле если значение пустое
        if (!$value) {
            delete_post_meta($post_id, $key);
        } else {
            update_post_meta($post_id, $key, $value); // add_post_meta() работает автоматически
        }
    }

    return $post_id;
}

Админка готова! Теперь необходимо доработать шаблоны темы, чтобы партнерские программ начали выводится на сайт.

Забыл кое-что, прежде чем переходить к редактированию шаблонов нужно добавить еще функции для выборки партнера и функцию просирования. Для вывода партнерки я буду использовать рандомную выборку одной партнерской программы из всех. При помощи такой нехитрой функции это можно осуществить. Добавляем в functions.php такую функцию

function get_partner_random() {
    $query = new WP_Query([]);
    $query->query([
        'post_type' => 'partner',
        'post_status' => 'publish',
        'orderby' => 'rand',
        'posts_per_page' => '1'
    ]);

    return $query->posts[0] ?? null;
}

Так как я хочу увеличивать количество переходов на 1 каждый раз при переходе по моей реферальной ссылки требуется добавить функцию проксирования партнерских ссылок. Это можно сделать довольно просто добавив следующий хук в functions.php

add_action( 'init', 'init_proxy' );

function init_proxy() {
    if (
            isset($_GET['action']) &&
            $_GET['action'] == 'partner' &&
            isset($_GET['id']) &&
            is_numeric($_GET['id'])
    ) {
        $query = new WP_Query([]);
        $query->query([
            'post_type' => 'partner',
            'ID' => (int)$_GET['id'],
            'post_status' => 'publish',
            'posts_per_page' => '1'
        ]);
        $posts = $query->get_posts();
        if (!empty($posts[0]->ID)) {
            $count = (int)get_post_meta($posts[0]->ID, 'count', true);
            $count++;
            update_post_meta($posts[0]->ID, 'count', $count);
            header('Location: ' . get_post_meta($posts[0]->ID, 'link', true));
            exit;
        }
    }
}

Теперь уже точно можно перейти к шаблону сайта. Тут все зависит от сложности шаблона. В моем случае шаблон очень простой поэтому править потребуется не так много

Добавляем новый шаблон для партнерок:

<?php
/** @var WP_Post $partner */
$partner = get_partner_random();
?>
<?php if ($partner): ?>
<article>
    <header class="entry-header">
        <header class="entry-header">
            <h2 class="entry-title"><a href="<?php echo sprintf('/?action=partner&id=%d', $partner->ID) ?>" rel="bookmark"><?php echo $partner->post_title?></a></h2>
        </header>
        <div class="post-thumbnail">
                <a href="<?php echo sprintf('/?action=partner&id=%d', $partner->ID) ?>">
                    <?php echo get_the_post_thumbnail( $partner->ID, 'large'); ?>
                </a>
        </div><!-- .post-thumbnail -->
        <div class="nav-links">
            <div class="nav-next kc-nav-links">
                <a href="<?php echo sprintf('/?action=partner&id=%d', $partner->ID) ?>">Взглянуть →</a>
            </div>
        </div>
    </header>
</article>
<?php endif ?>

И далее добавляем логику вывода этого шаблона в index.php темы

get_template_part( 'header' );

				if ( have_posts() ) :

                    $i = 1;
					while ( have_posts() ) :

						the_post();

						get_template_part( 'content' );

						// If comments are open or we have at least one comment, load up the comment template.
						if ( comments_open() || get_comments_number() ) :
							comments_template();
						endif;

                        if ($i % 5 == 0) {
                            get_template_part( 'partner' );
                        }

                    $i++;
					endwhile;

				else :

					get_template_part( 'content', 'none' );

				endif;
				?>

В этом куске кода я скинул шаблон полностью для наглядности, но по-сути вся правка заключается в добавлении вот этой простой логики:

                        if ($i % 5 == 0) {
                            get_template_part( 'partner' );
                        }

Этот код будет отображать рандомную партнерку после каждых 5 постов

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

А если вам нужна разработка под WP или любая другая помощь по php, можете написать мне в любое время в мой телеграмм на странице профайла

, ,

14 августа, 2024

Организация автодиплоя с BitBucket в WordPress

Доработка моего блога пошла быстрее и файлики стало неудобно заливать по штучно через ssh поэтому пришло время настроить автодеплой. В своих разработках я использую чаще всего git на Bitbucket.

Сделать автодеплой для связки Bitbucket+Wordpress не состовляет большого труда. Далее в статье я покажу как это достаточно просто можно организавать.

Для начала у вас должен быть создан репозиторий на битбаките. Выполняете пуш всех файлов вашего блога.

$ git clone git@bitbucket.org:<repository>
$ echo 'www/wp-config.php' >> .gitignore
$ echo '.env' >> .gitignore
$ git add *
$ git push 

Теперь переходим на сервер на котором планируем осуществлять автодеплой. Нам потребуется создать публичный ключ ssh для пользователя от которого будет осуществляться автодеплой ( он же должен быть владельцем файлов сайта на сервере ). Для моего сайта таким пользователем является пользователь www-data, но у него нет shell поэтому генерацию ключей нужно будет осуществить при помощи команды sudo

$ sudo -u www-data ssh-keygen -t rsa

Нажимаем Enter на все вопросы и далее копируем наш публичный ключ для того чтобы вставить его в настройки репозитория на битбаките

$ cat <dir_home_user_www-data>/.ssh/id_rsa.pub

Копируем в буфер обмена то что отобразилось и идем на битбакет с этим


Переходим в раздел Ключи доступа в настройках репозитория нашего сайта

Нажимаем Add key

Называем наш ключ доступа и заполняем нашим публичным ключем, который скопировали ранее

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

Жамкаем на добавление веб-хука

Заполняем название веб-хука
Обязательно указываем адрес к нашему скрипту автодеплоя
Выбираем триггером PUSH событие ( наш скрипт будет вызываться когда в Битбакет будет запушены изменения ) и не забываем проставить статус активности веб-хука


Вот и все, теперь переходим к созданию скрипта деплоя.

<?php

$root_dir = realpath(exec('pwd').'/..');
$result = exec(sprintf('cd %s ; git fetch ; git pull', $root_dir));

После изменений внесенных в код необходимо закомитить и запушить наш скрипт в репозиторий.

Теперь мы можем выкачать репозиторий с сайтом на наш удаленный сервер.
Делаем клон рядом с нашей директорией на которую указывает настройки http сервера.
Чаще всего это /var/www

$ cd /var/www
$ sudo -u www-data git clone git@bitbucket.org:wikide/killercoder.git killercoder_git 

И переименовываем директории

$ mv killercoder killercoder_old ; mv killercoder_git killercoder

Теперь мы имеем рабочий сайт, который подключен к репозиторию
И при выполнение команды git push в ветку main будет происходить автоматический деплой на боевом сервере.

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

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

,

4 августа, 2024

Автопубликация постов WordPress в Telegram

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

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

Итак, для репоста в свой телеграм канал, нам потребуется сайт на WordPress, телеграм канал и токен бота, который потребуется получить через папу ботов телеграмма — @BotFather

Открываем @BotFather пишим ему команду

/newbot

В ответ от вас потребуется придумать и ввести имя бота и имя бота с постфексом _bot
После этого папа ботов сгенерирует для вас токен для HTTP API

Этот токен мы и будем использовать для нашей системы репостинга обновлений на сайте

после этого требуется отредактировать wp-config.php и добавить туда константу:

define( 'TELEGRAM_BOT_TOKEN', '<TOKEN>' );

<TOKEN> заменить на тот токен, который мы получили при создании нового бота через @BotFather

После этого нам потребуется определить ID канала для того, чтобы передать нашему боту информацию о том в какой чат требуется отправлять сообщения. В моем случае, я использовал закрытый канал, поэтому мне потребовалось выполнить следующие действия для получения ID канала

  1. Добавляем в качестве администратора нашего новорожденного бота на наш канал
  2. Публикуем тестовый пост ( который потом будет не жалко удалить )
  3. Выполняем элементарный запрос curl
    curl —location ‘https://api.telegram.org/bot<TOKEN>/getUpdates’
  4. В ответ получаем ID нашего чата, который вставляем в wp-config.php
define( 'TELEGRAM_CHANNEL_ID',  <ID_CHANNEL> );

Теперь все готово к написанию нашего основного функционала!

Открываем нашу текущую тему WordPress ( предварительно скопировав ее в новую директорию, чтобы обновления темы не затерли наши изменения ) и находим там файл functions.php, в него мы и будем вносить изменения.

В данном случае нас интересуют только новые посты, поэтому мы будем использовать событие WordPress — save_post

Регистрируем новую функцию, которая будет выполнятся каждый раз, когда на сайте будет опубликован новый пост

add_action( 'save_post', 'send_telegram' );

Теперь, напишем код функции send_telegram

function send_telegram( $post_id ) {
    $post = get_post($post_id);
    $is_new = $post->post_date === $post->post_modified;
    if (  !$is_new || wp_is_post_revision( $post_id ) || $post->post_status != 'publish')
        return;
    message_to_telegram( $post );
}

Эта функция выполняет проверяет является ли пост новым публичным и не ревизией поста и если эти условия выполняются, то вызывается функция message_to_telegram

function message_to_telegram($post)
{
    $url = get_permalink($post->ID);
    $text = preg_replace('/[\n\r]+/s', "\n\n", strip_tags($post->post_content));
    if (strlen($text) > 500) {
        $text = substr($text, 0, 500) . '...';
    }
    $ch = curl_init();
    $ch_post = [
        CURLOPT_URL => sprintf('https://api.telegram.org/bot%s/sendMessage', TELEGRAM_BOT_TOKEN),
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_POSTFIELDS => [
            'chat_id' => TELEGRAM_CHANNEL_ID,
            'parse_mode' => 'HTML',
            'text' => sprintf("<a href=\"%s\">%s</a> %s \n\n<a href=\"%s\">Взглянуть ?</a>", $url, $post->post_title, $text, $url),
        ]
    ];

    curl_setopt_array($ch, $ch_post);
    curl_exec($ch);
}

Эта функция выполняет отправку ссылку и первые 500 символов нового поста в канал телеграм

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

А если вас интересует создание ботов телеграм или создание сайта на движке wordpress то всегда можете написать мне в телеграм.