Цей посібник показує, як створити масштабований бекенд для квитків на події на основі NFT на PHP, використовуючи Symfony Messenger для безпечної та надійної обробки затримок блокчейну.Цей посібник показує, як створити масштабований бекенд для квитків на події на основі NFT на PHP, використовуючи Symfony Messenger для безпечної та надійної обробки затримок блокчейну.

Створення децентралізованої системи продажу квитків на події Web3 з Symfony 7.4

2025/12/22 01:43

Перетин Web3 і традиційних веб-фреймворків — це те місце, де починається реальна корисність. Хоча хайп-цикли приходять і йдуть, корисність Невзаємозамінних токенів (NFT) для верифікації власності — особливо в квитках на заходи — залишається надійним випадком використання.

У цій статті ми побудуємо основу Децентралізованої системи продажу квитків на заходи за допомогою Symfony 7.4 і PHP 8.3. Ми вийдемо за межі базових туторіалів і реалізуємо архітектуру виробничого рівня, яка обробляє асинхронну природу блокчейн-транзакцій за допомогою компонента Symfony Messenger.

Архітектура

«Сеньйорський» підхід визнає, що PHP не є довготривалим процесом, як Node.js. Тому ми не прослуховуємо події блокчейну в реальному часі в контролері. Натомість ми використовуємо гібридний підхід:

  1. Пряма взаємодія (запис): ми використовуємо Symfony Messenger для передачі транзакцій «мінтингу» воркеру, запобігаючи тайм-аутам HTTP.
  2. RPC-опитування (читання): ми використовуємо заплановані команди для перевірки статусу он-чейн.
  3. Смартконтракт: ми припускаємо стандартний контракт ERC-721, розгорнутий у EVM-сумісному ланцюзі (Ethereum, Polygon, Base).

Передумови та стек

  • PHP: 8.3+
  • Symfony: 7.4 (LTS)
  • блокчейн-вузол: Infura, Alchemy або локальний вузол Hardhat.

Багато PHP Web3-бібліотек занедбані або погано типізовані. Хоча web3p/web3.php найвідоміший, строго покладатися на нього може бути ризиковано через прогалини в обслуговуванні.

Для цього посібника ми використаємо web3p/web3.php (версія ^0.3) для ABI-кодування, але скористаємося нативним HttpClient Symfony для фактичного JSON-RPC транспорту. Це дає нам повний контроль над тайм-аутами, повторними спробами та логуванням — критично для виробничих застосунків.

Налаштування проєкту

Спочатку давайте встановимо залежності. Нам потрібен Symfony runtime, HTTP-клієнт і Web3-бібліотека.

composer create-project symfony/skeleton:"7.4.*" decentralized-ticketing cd decentralized-ticketing composer require symfony/http-client symfony/messenger symfony/uid web3p/web3.php

Переконайтеся, що ваш composer.json відображає стабільність:

{ "require": { "php": ">=8.3", "symfony/http-client": "7.4.*", "symfony/messenger": "7.4.*", "symfony/uid": "7.4.*", "web3p/web3.php": "^0.3.0" } }

Блокчейн-сервіс

Нам потрібен надійний сервіс для спілкування з блокчейном. Ми створимо EthereumService, який обгортає JSON-RPC виклики.

//src/Service/Web3/EthereumService.php namespace App\Service\Web3; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Web3\Utils; class EthereumService { private const JSON_RPC_VERSION = '2.0'; public function __construct( private HttpClientInterface $client, #[Autowire(env: 'BLOCKCHAIN_RPC_URL')] private string $rpcUrl, #[Autowire(env: 'SMART_CONTRACT_ADDRESS')] private string $contractAddress, #[Autowire(env: 'WALLET_PRIVATE_KEY')] private string $privateKey ) {} /** * Reads the owner of a specific Ticket ID (ERC-721 ownerOf). */ public function getTicketOwner(int $tokenId): ?string { // Function signature for ownerOf(uint256) is 0x6352211e // We pad the tokenId to 64 chars (32 bytes) $data = '0x6352211e' . str_pad(Utils::toHex($tokenId, true), 64, '0', STR_PAD_LEFT); $response = $this->callRpc('eth_call', [ [ 'to' => $this->contractAddress, 'data' => $data ], 'latest' ]); if (empty($response['result']) || $response['result'] === '0x') { return null; } // Decode the address (last 40 chars of the 64-char result) return '0x' . substr($response['result'], -40); } /** * Sends a raw JSON-RPC request using Symfony HttpClient. * This offers better observability than standard libraries. */ private function callRpc(string $method, array $params): array { $response = $this->client->request('POST', $this->rpcUrl, [ 'json' => [ 'jsonrpc' => self::JSON_RPC_VERSION, 'method' => $method, 'params' => $params, 'id' => random_int(1, 9999) ] ]); $data = $response->toArray(); if (isset($data['error'])) { throw new \RuntimeException('RPC Error: ' . $data['error']['message']); } return $data; } }

Запустіть локальний тест доступу до getTicketOwner із відомим змінтеним ID. Якщо ви отримуєте 0x-адресу, ваше RPC-з'єднання працює.

Асинхронний мінтинг із Messenger

Блокчейн-транзакції повільні (від 15 секунд до хвилин). Ніколи не змушуйте користувача чекати на підтвердження блоку в запиті браузера. Ми будемо використовувати Symfony Messenger для обробки цього у фоновому режимі.

Повідомлення

//src/Message/MintTicketMessage.php: namespace App\Message; use Symfony\Component\Uid\Uuid; readonly class MintTicketMessage { public function __construct( public Uuid $ticketId, public string $userWalletAddress, public string $metadataUri ) {} }

Обробник

Ось тут відбувається магія. Ми використаємо допоміжний засіб бібліотеки web3p/web3.php для локального підпису транзакції.

Примітка: у високозахищеному середовищі ви б використовували службу управління ключами (KMS) або окремий підписний анклав. Для цієї статті ми підписуємо локально.

//src/MessageHandler/MintTicketHandler.php namespace App\MessageHandler; use App\Message\MintTicketMessage; use App\Service\Web3\EthereumService; use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Web3\Contract; use Web3\Providers\HttpProvider; use Web3\RequestManagers\HttpRequestManager; use Web3p\EthereumTx\Transaction; #[AsMessageHandler] class MintTicketHandler { public function __construct( private EthereumService $ethereumService, // Our custom service private LoggerInterface $logger, #[Autowire(env: 'BLOCKCHAIN_RPC_URL')] private string $rpcUrl, #[Autowire(env: 'WALLET_PRIVATE_KEY')] private string $privateKey, #[Autowire(env: 'SMART_CONTRACT_ADDRESS')] private string $contractAddress ) {} public function __invoke(MintTicketMessage $message): void { $this->logger->info("Starting mint process for Ticket {$message->ticketId}"); // 1. Prepare Transaction Data (mintTo function) // detailed implementation of raw transaction signing usually goes here. // For brevity, we simulate the logic flow: try { // Logic to get current nonce and gas price via EthereumService // $nonce = ... // $gasPrice = ... // Sign transaction offline to prevent key exposure over network // $tx = new Transaction([...]); // $signedTx = '0x' . $tx->sign($this->privateKey); // Broadcast // $txHash = $this->ethereumService->sendRawTransaction($signedTx); // In a real app, you would save $txHash to the database entity here $this->logger->info("Mint transaction broadcast successfully."); } catch (\Throwable $e) { $this->logger->error("Minting failed: " . $e->getMessage()); // Symfony Messenger will automatically retry based on config throw $e; } } }

Контролер

Контролер залишається тонким. Він приймає запит, валідує вхідні дані, створює сутність квитка «очікує» у вашій базі даних (опущено для стислості) і відправляє повідомлення.

//src/Controller/TicketController.php: namespace App\Controller; use App\Message\MintTicketMessage; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Uid\Uuid; #[Route('/api/v1/tickets')] class TicketController extends AbstractController { #[Route('/mint', methods: ['POST'])] public function mint(Request $request, MessageBusInterface $bus): JsonResponse { $payload = $request->getPayload(); $walletAddress = $payload->get('wallet_address'); // 1. Basic Validation if (!$walletAddress || !str_starts_with($walletAddress, '0x')) { return $this->json(['error' => 'Invalid wallet address'], 400); } // 2. Generate Internal ID $ticketId = Uuid::v7(); // 3. Dispatch Message (Fire and Forget) $bus->dispatch(new MintTicketMessage( $ticketId, $walletAddress, 'https://api.myapp.com/metadata/' . $ticketId->toRfc4122() )); // 4. Respond immediately return $this->json([ 'status' => 'processing', 'ticket_id' => $ticketId->toRfc4122(), 'message' => 'Minting request queued. Check status later.' ], 202); } }

Конфігурація та посібник зі стилю

Дотримуючись стилю Symfony 7.4, ми використовуємо сувору типізацію та атрибути. Переконайтеся, що ваш messenger.yaml налаштований для асинхронного транспорту.

#config/packages/messenger.yaml: framework: messenger: transports: async: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' retry_strategy: max_retries: 3 delay: 1000 multiplier: 2 routing: 'App\Message\MintTicketMessage': async

Верифікація

Щоб перевірити, що ця реалізація працює без розгортання в Mainnet:

Локальний вузол: запустіть локальний блокчейн за допомогою Hardhat або Anvil (Foundry).

npx hardhat node

Середовище: встановіть свій .env.local на localhost.

BLOCKCHAIN_RPC_URL="http://127.0.0.1:8545" WALLET_PRIVATE_KEY="<один із тестових ключів, наданих hardhat>" SMART_CONTRACT_ADDRESS="<адреса розгорнутого контракту>" MESSENGER_TRANSPORT_DSN="doctrine://default"

Споживання: запустіть воркера.

php bin/console messenger:consume async -vv

Запит:

curl -X POST https://localhost:8000/api/v1/tickets/mint \ -H "Content-Type: application/json" \ -d '{"wallet_address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"}'

Ви маєте побачити, як воркер обробляє повідомлення, і, якщо ви повністю реалізували логіку підпису сирих транзакцій, хеш транзакції з'явиться у вашій консолі Hardhat.

Висновок

Створення Web3-застосунків на PHP вимагає зміни мислення. Ви не просто будуєте CRUD-застосунок; ви створюєте оркестратор для децентралізованого стану.

Використовуючи Symfony 7.4, ми скористалися:

  • HttpClient для надійної, контрольованої RPC-комунікації.
  • Messenger для обробки асинхронної реальності блокчейнів.
  • PHP 8.3 Attributes для чистого, читабельного коду.

Ця архітектура масштабується. Незалежно від того, чи продаєте ви 10 квитків або 10 000, черга повідомлень діє як буфер, гарантуючи, що ваші nonce транзакцій не конфліктують, а ваш сервер не зависає.

Готові масштабувати свою Web3-інфраструктуру?

Інтеграція блокчейну вимагає точності. Якщо вам потрібна допомога з аудитом ваших взаємодій зі смартконтрактами або масштабуванням ваших споживачів повідомлень Symfony, зв'яжемося.

\

Відмова від відповідальності: статті, опубліковані на цьому сайті, взяті з відкритих джерел і надаються виключно для інформаційних цілей. Вони не обов'язково відображають погляди MEXC. Всі права залишаються за авторами оригінальних статей. Якщо ви вважаєте, що будь-який контент порушує права третіх осіб, будь ласка, зверніться за адресою service@support.mexc.com для його видалення. MEXC не дає жодних гарантій щодо точності, повноти або своєчасності вмісту і не несе відповідальності за будь-які дії, вчинені на основі наданої інформації. Вміст не є фінансовою, юридичною або іншою професійною порадою і не повинен розглядатися як рекомендація або схвалення з боку MEXC.

Вам також може сподобатися

Honda тимчасово зупиняє заводи в Японії та Китаї через дефіцит чипів

Honda тимчасово зупиняє заводи в Японії та Китаї через дефіцит чипів

Глобальний дефіцит напівпровідників продовжує впливати на автомобільну промисловість, попри очікування поступового відновлення ланцюгів постачання. Японська Hon
Поділитись
Finance2025/12/22 11:05
Bitcoin 8% прибуток вже робить вересень 2025 його другим найкращим

Bitcoin 8% прибуток вже робить вересень 2025 його другим найкращим

Пост Bitcoin з прибутком у 8% вже робить вересень 2025 року другим найкращим з'явився на BitcoinEthereumNews.com. Ключові моменти: Bitcoin порушує сезонні тенденції, додавши 8%, що робить цей вересень найкращим з 2012 року. Вересень 2025 року потребував би зростання на 20%, щоб стати найсильнішим для Bitcoin за всю історію. Волатильність ціни BTC знаходиться на рівнях, які рідко спостерігалися раніше в незвичайному бичачому циклі. Bitcoin (BTC) приніс більше прибутку цього вересня, ніж будь-якого року з 2012 року, встановивши новий рекорд бичачого ринку. Історичні дані про ціни від CoinGlass та BiTBO підтверджують, що при 8% зростання Bitcoin у вересні 2025 року є другим найкращим за всю історію. Bitcoin уникає "Rektember" з прибутком у 8% Вересень традиційно є найслабшим місяцем для Bitcoin, із середніми втратами близько 8%. Щомісячна прибутковість BTC/USD (скріншот). Джерело: CoinGlass Цього року ставки високі для сезонності ціни BTC, оскільки історичні патерни вимагають наступного піку бичачого ринку, а інші ризикові активи встановлюють повторні нові історичні максимуми. У той час як золото і S&P 500 знаходяться у фазі відкриття цін, BTC/USD коливався протягом вересня після встановлення власних нових максимумів минулого місяця. Однак навіть при "лише" 8% продуктивність цього вересня наразі достатня, щоб зробити його найсильнішим для Bitcoin за 13 років. Єдиний раз, коли дев'ятий місяць року був більш прибутковим для биків Bitcoin, був у 2012 році, коли BTC/USD виріс приблизно на 19,8%. Минулого року зростання досягло максимуму в 7,3%. Щомісячна прибутковість BTC/USD. Джерело: BiTBO Волатильність ціни BTC зникає Ці цифри підкреслюють надзвичайно незвичайний рік піку бичачого ринку для Bitcoin. Пов'язано: BTC 'враховує в ціні' те, що наближається: 5 речей, які потрібно знати про Bitcoin цього тижня На відміну від попередніх бичачих ринків, волатильність ціни BTC зникла у 2025 році, всупереч очікуванням довгострокових учасників ринку, заснованим на попередніх показниках. Дані CoinGlass показують, що волатильність знизилася до рівнів, не бачених більше десятиліття, з особливо різким падінням з квітня. Історична волатильність Bitcoin (скріншот). Джерело: CoinGlass Тим часом, аналітична фірма Glassnode підкреслює...
Поділитись
BitcoinEthereumNews2025/09/18 11:09
Важливі новини з минулої ночі та сьогоднішнього ранку (21 грудня-22 грудня)

Важливі новини з минулої ночі та сьогоднішнього ранку (21 грудня-22 грудня)

Ф'ючерси на срібло в Шанхаї перевищили позначку в 16 000 юанів/кг, встановивши новий історичний максимум. Основний контракт на ф'ючерси на срібло в Шанхаї одного разу зріс більш ніж на
Поділитись
PANews2025/12/22 10:30