Транзакция в блокчейне: от приватного ключа до необратимой записи в логе
Контекст: перевод как распределённая транзакция
На уровне системы перевод криптовалюты — это не «пересылка монет», а добавление новой записи в разделяемый журнал (ledger). Транзакция содержит инструкцию: с какого аккаунта, на какой, сколько и с какими параметрами. Как только запись включена в блок и получено достаточное число подтверждений, состояние сети обновляется. Никакие монеты физически не перемещаются — меняются балансы в таблице состояний.
Ключи, адреса и детерминированные кошельки
Приватный ключ — это 256-битное число (uint256), обычно генерируемое из мнемонической фразы по стандарту BIP39. Фраза из 12 или 24 слов кодирует энтропию и контрольную сумму. Через BIP32/44 получают дерево ключей: например, в Ethereum путь выглядит как m/44'/60'/0'/0/0. Публичный ключ вычисляется с помощью эллиптической кривой secp256k1: Q = k * G. Адрес — это последние 160 бит от keccak256(publicKey). Для защиты от опечаток адрес снабжается контрольной суммой (EIP-55) — аналог CRC в сетевых пакетах.
Структура транзакции и сериализация
В Ethereum транзакция — это RLP-кодированная структура с полями: nonce (счётчик отправленных транзакций), gasPrice (или maxFeePerGas/maxPriorityFeePerGas после EIP-1559), gasLimit, to, value, data, v/r/s (подпись) и chainId. Nonce играет роль монотонно возрастающего идентификатора, аналогичного sequence number в TCP: он предотвращает повторное воспроизведение и задаёт порядок выполнения. Если отправить две транзакции с одинаковым nonce, в блок попадёт только одна, а вторая будет отброшена как конфликтующая.
Подпись и верификация
Подпись вычисляется по схеме ECDSA: хеш транзакции (keccak256) подписывается приватным ключом, на выходе получаем r, s и recovery id v. По сигнатуре любой узел может восстановить публичный ключ и проверить, что отправитель действительно владеет приватным ключом, не раскрывая его. Это аналог проверки JWT-токена с асимметричным ключом, только вместо HMAC — эллиптическая криптография.
RPC, ноды и мемпул
Кошелёк не общается с блокчейном напрямую. Он формирует сырую транзакцию и отправляет её через JSON-RPC на узел (например, через Infura, Alchemy или собственную ноду). Метод eth_sendRawTransaction принимает подписанные байты и помещает их в мемпул. Мемпул — это распределённый пул неподтверждённых транзакций, который можно сравнить с очередью сообщений (message queue) без гарантии доставки: узлы реплицируют записи по peer-to-peer протоколу, но порядок и включение зависят от майнеров или валидаторов.
Экономика газа и приоритизация
Газ — это метрика вычислительных затрат. Каждая операция в EVM имеет фиксированную стоимость в газе (например, SSTORE для записи в storage стоит дороже, чем ADD). Лимит газа — максимальное количество газа, которое отправитель готов оплатить. Цена газа определяется рынком: до EIP-1559 это был аукцион первой цены, теперь — комбинация базовой платы (base fee), которая сжигается, и чаевых (priority fee) валидатору. Выбор параметров аналогичен выделению CPU/IO ресурсов в Kubernetes: заниженный лимит приводит к out of gas, завышенная цена — к лишним расходам.
Включение в блок и финальность
Транзакция становится частью блокчейна, когда валидатор создаёт блок, включающий её, и распространяет блок по сети. Каждый следующий блок, ссылающийся на предыдущий через хеш, добавляет «подтверждение». В PoW-сетях (Bitcoin, до перехода Ethereum) финальность вероятностная: чем больше блоков поверх, тем ниже вероятность реорганизации (reorg). В PoS-сетях с финальностью (Casper FFG) после двух эпох (примерно 12,8 минуты в Ethereum) транзакция получает экономическую гарантию необратимости. Это похоже на достижение консенсуса в распределённой БД, только вместо Paxos/Raft — экономические стимулы.
Распространённые инциденты и их разбор
Ошибки при отправке: адрес с опечаткой без контрольной суммы — монеты уходят в несуществующий или чужой аккаунт; недостаточный gasLimit — транзакция реверсится, но комиссия списывается; переиспользование nonce из-за сбоя кошелька — одна транзакция теряется; отсутствие chainId в старых кошельках — replay attack между сетями; stuck-транзакция при резком росте base fee — требуется замена с повышением fee (replace-by-fee). Все эти сценарии — классические проблемы распределённых систем: отсутствие глобальных часов, конкурентный доступ к разделяемому состоянию и отсутствие транзакционной изоляции.
Инженерные выводы
Перевод криптовалюты — это не магическое действие, а строгая последовательность: генерация ключей, формирование структуры, подпись, broadcast в сеть, конкуренция за место в блоке, подтверждение. Инженерный подход — использовать проверенные библиотеки (ethers.js, web3.py, bitcoinjs), всегда проверять chainId и nonce, оценивать газ с запасом и не воспринимать «отправлено» как «подтверждено». Понимание этих механик снижает риск потери средств и упрощает отладку.