Транзакция - это переводы биткоинов с одного адреса(адресов) на другой адрес(адреса). В Биткоине транзакция представляет из себя набор данных, которые описывают трансфер средств. Поэтому для того, чтобы перевести биткоины, вам нужно собрать все необходимые данные, подписать транзакцию с помощью своего приватного ключа и затем отправить транзакцию в сеть Биткоина для её подтверждения и включения в новый блок. Не стоит бояться! Как правило, всем этим занимается софт, а вы всего лишь указываете адрес получателя, сумму перевода и нажимаете кнопку "Отправить". Но всё же заглянем под капот и посмотрим, что же представляют из себя транзакции в сети Биткоин.
Начнём с того, что, напомним, в Биткоине используется UTXO модель, поэтому транзакции имеют входы и выходы. Причём важно помнить о двух вещах. Во-первых, каждый вход в новую транзакцию был выходом в предыдущей транзакции. Как изображено ниже, два выходы из транзакции tx₁ на 2 BTC каждый стали входами в транзакциях tx₃ и tx₄ соответственно.
Во-вторых, каждый не потраченный выход ассоциирован с каким-то адресом, то есть он лежит на этом адресе. Возвращаясь к аналогии с кошельком: адрес - карман кошелька, не потраченные выходы(utxos) - купюры, лежащие внутри кармана.
Когда вы собираетесь отправить определённую сумму биткоинов, вы берёте из одного или нескольких карманов своего кошелька(с адресов) необходимое количество купюр(не потраченных выходов), которые вместе покрывают сумму перевода, и подаёте их на вход транзакции. Поэтому не потраченные выходы становятся входами в новую транзакцию.
Жизненный цикл транзакции
От момента начала сборки транзакции и до её подтверждения, она проходит несколько стадий. Жизненный цикл транзакции включает в себя следующие этапы:
- Сборка транзакции: выбор отправителя, суммы перевода, не потраченных выходов для траты, транзакционной комиссии и т.д. Этот процесс происходит на стороне отправителя.
- Отправка собранной транзакции в сеть Биткоина и распространение транзакции по ней. На этом этапе транзакция отправляется в сеть Биткоина, где пересылается от ноды к ноде. Каждая нода, получив новую транзакцию, проверяет её. Если транзакция не содержит ошибок и является валидной, то нода ретранслирует её дальше.
- Нахождение транзакции в мемпуле майнера до её включения в блок. Часть нод в сети контролируется майнерами, у которых есть своего рода списки ожидания(mempool), где транзакции находятся до момента, когда майнер не поместит её в новый блок.
- Подтверждение транзакции и помещение её в новый блок. Как правило при сборке нового блока, майнеры берут набор транзакций, у которых общая транзакционная комиссия больше, чем у других наборов. То есть зачастую майнеры руководствуются своей выгодой. Чем большую относительная комиссию, измеряющуюся в сатоши за байт, вы установите, тем быстрее ваша транзакция будет включена в блок.
После этого транзакция становится подтвержденной, а перевод считается совершённым, но для надежности рекомендуется подождать 6 новых блоков после блока, в который была включена ваша транзакция. Это связано с теоретической возможностью атаки двойной траты(double-spending attack) и создании побочной цепочки блоков. Более подробно мы поговорим об этом в одной из следующих статей.
Структура транзакции
Транзакции в блоке записаны в так называемом "сыром" raw формате, представляющем из себя строку в шестнадцатеричном виде.
Например, транзакция
dc5ef7dda85b521b3babebc7b903c6b6ec211e58257b174a2453f3488923fb9f
в raw формате будет выглядеть так:
При этом транзакция имеет чёткую структуру, включающую в себя набор полей с различными данными.
Значение поля Версия записывается в формате от младшего байта к старшему байта. Например, если 12345678 - обычный порядок записи, то обратный порядок записи(от младшего байта к старшему байта) будет выглядеть так 78563412.
Каждый вход в списке имеет следующую структуру:
Значения полей TXID, VOUT и Sequence записываются в формате от младшего байта к старшему байта.
Каждый выход в списке имеет следующую структуру:
Значение поля Value записывается в формате от младшего байта к старшему байта.
Таким образом, каждая транзакция в raw формате содержит все эти данные. Возвращаясь к нашему примеру, мы получим:
Версия: 01000000
Количество входов: 01
TXID: bb4c8ecbecc5d0d5c0ca8e22e355fe5fb21c90669c26c54c35db7ad569fd7fe9
VOUT: 01000000
ScriptSig Size: db
ScriptSig: 00483045022100ca1186d29fb2ec938a18a798b02dd50ce2c68ffcf1ee1142c19fc5292d0d86b502204577bb23ac7bcfc71a2630d8eb716e56b667581706ea6a7a424590db77c2194e014830450221009ef1062deb41d9c8dad2b5d783a78850a41ae17834ab505f10758a42e53c1c56022018266b70f9035054f50534136071ded3c5f61f8e666d0f939d92f99af41d13360147522102cebf6ab580948d146b7cc771d8e646974349d3d7b11f3e03287d0997a477d3b921037ba651485b7a2cb222191eb64a55926e62bbabfe9b5ed2a9488aad547b20428252ae
Sequence: ffffffff
Количество выходов: 02
Value: a086010000000000
ScriptPubKey Size: 19
ScriptPubKey: 76a914da488844e595eb977b92685679ef2a1015ac448f88ac
Value: b826073b00000000
ScriptPubKey Size: 17
ScriptPubKey: a914db1283737cd93ebc1eb1298d644a7846c55a6d9687
Locktime: 00000000
Напоследок сделаем пару замечаний по поводу ScriptSig и ScriptPubKey. Мы ещё будем возвращаться к вопросу скриптов в Биткоине, но сейчас для простоты понимания стоит запомнить, что ScriptPubKey - запирающий скрипт, который запирает монеты, связанные с определённым выходом, посредством определённого условия траты. До его выполнения монеты потрачены не могут быть. ScriptSig - отпирающий скрипт, который предоставляет требуемые данные для выполнения условия траты монет. То есть ScriptSig и ScriptPubKey можно сравнить с ключом и замком.
Одним из самых простых примером условия траты является предоставление в ScriptSig открытого ключа и подписи, хэш-значение которой будет равно хэшу, записанному в ScriptPubKey. Если предоставлена действительно та подпись, хэш которой находится в ScriptPubKey, то равенство хэшей будет верным и пользователь сможет потратить свои монеты.