[Перевод] Заблуждения программистов о Биткоине
В духе статьи «Заблуждения программистов о телефонных номерах» (вот её перевод на Хабре — прим. переводчика), я решил собрать самые распространённые ошибочные представления о Биткоине.
Блоки
Высота блока будет только расти.
Более легитимной, «честной» цепочкой считается не та, в которой больше всего блоков, а та, что накопила наибольшую работу. Работа, которая требуется, чтобы найти валидное доказательство выполнения, зависит от цели сложности (см. также сложность). Поэтому возможно, что существует цепочка с большим количеством блоков, чем честная, если сложность в ней ниже. Если клиент сначала видит только цепочку с большим количеством блоков, а потом вдруг узнаёт о существовании «честной», с более высокой работой, он отбросит первую в пользу второй. В этом случае блоковая высота, валидная с точки зрения ноды, может и уменьшиться.
Придумать сценарий, в котором это могло бы произойти, — та ещё задачка.Мысленный эксперимент: допустим, есть майнер с приличным хешрейтом, превосходящим мощность сети. Этот майнер не сообщает публично о найденных им блоках. После 2016 блоков происходит корректировка сложности, и сложность спрятанной цепочки многократно увеличивается. Все блоки, намайненные в скрытой цепочке, теперь содержат больше работы, чем соответствующие блоки в публичной. Майнер добавляет ещё несколько блоков, прекращает майнить и ждёт, пока другая цепь доберётся до [размера его цепочки + 1]. После этого он объявляет о своих блоках. Все ноды переключатся на цепочку с меньшей высотой, потому что в ней больше работы.
Насколько это вероятно? Ответ на этот вопрос оставлю упражнением для читателя. Если придумаете ещё какой-нибудь вариант, пожалуйста, во имя Сатоши, сделайте пулл-реквест (прим. переводчика: к репозиторию, в котором лежит оригинал статьи)!
Время, требуемое для создания нового блока, будет только расти.
Когда майнер находит новый блок, он точно будет добавлен в блокчейн.
Ну ладно, но когда майнер единолично находит валидный блок, этот блок точно добавят в блокчейн.
Нет, если хэш нового блока совпадёт с хэшем более раннего. Поскольку инвентарный вектор нового блока будет копией вектора уже существующего блока, ноды не будут этот блок запрашивать. Его просто проигнорируют, как будто его и вовсе никогда не обнаруживали. Все будут убеждены, что на этой высоте пока не нашли ни одного нового блока.
Каждый блок всегда генерирует ровно
${CURRENT_BLOCKREWARD}
биткоинов.В блоке 124724 в наградогенерирующей (coinbase) транзакции не хватает одного сатоши. В блоке 501726 и вовсе нет награды за майнинг блока.
Чем больше нулей в начале хэша блока (то есть, чем ниже хэш), тем больший вклад этот блок делает в общую работу.
Довольно распространённое заблуждение — считать, что блоки с более низким хэшем (т.е. имеющие в начале хэша больше нулей) больше вкладываются в общую работу, чем блоки с большим хэшем (т.е. имеющие меньше нулей в начале хэша). Хэш блока подсчитывается в ходе множества независимых операций хэширования SHA256. Этот процесс продолжается до тех пор, пока не обнаруживается хэш ниже нынешней цели. Цель хранится в поле nBits в шапке блока и балансируется каждые 2016 блоков в рамках корректировки сложности. Каждая из этих операций хэширования никак не зависит от предыдущих. Поскольку результат SHA256 распределяется псевдослучайно, вероятность того, что будет найден отвечающий целевым требованиям хэш, зависит только от самого нынешнего значения цели. Любой хэш ниже этой цели будет считаться валидным доказательством блока, но вероятность найти такой хэш одинакова для всех значений ниже цели (без разницы, 15 у него нулей в начале или 30). Поэтому только значение сложности (= самая высокая цель/нынешняя цель), активное на момент генерации блока, учитывается в подсчёте общей суммы работы. В validation.cpp#L3138 можно посмотреть, где именно работа нынешнего блока прибавляется к
nChainWork
. Ещё обратите внимание наGetBlockProof(…)
в chain.cpp — работа блока подсчитывается только на основе поля nBits (то есть, нынешней цели) в шапке блока.Корретировки сложности основаны на предыдущих 2016 блоках.
У алгоритма корректировок сложностей есть баг на единицу. Из-за него расчёты основываются на предыдущих 2015 блоках, а не ровно 2016.
Пустые блоки пусты.
В пустых блоках всё ещё есть данные. В них просто нет других транзакций, кроме наградогенерирующей. Поскольку блок не содержит никаких транзакций из мемпула, он считается пустым. Пустые блоки тоже дорого обходятся с точки зрения вычисительной мощности, потому что им тоже нужно производить доказательство работы в рамках консенсуса. У них тоже есть блоковые шапки, весящие 80 байтов, и у них есть все поля, которые есть у не-пустых блоков.
Транзакции
Если валидная транзакция оказалась в мемпуле, её обязательно в итоге включат в блокчейн.
Транзакции могут быть исключены из мемпула. Мемпул ноды может занимать ровно столько памяти, сколько задано через
maxmempool
. Как только нода достигнет этого лимита, она исключит транзакции с самыми низкими комиссиями и повыситmempoolminfee
. После этого она сообщит о своём новомmempoolminfee
другим нодам. То есть, в сущности, скажет пока не отправлять ей транзакции с комиссией ниже этой планки. Заметьте, что каждая нода делает это индивидуально и независимо, так что нода с большим мемпулом или другой архитектурой может выкидывать транзакции раньше или позже.Прежде чем транзакцию включат в блокчейн, она обязательно должна пройти через мемпул.
Если я вижу транзакцию в своём мемпуле, я могу быть уверен, что она есть в мемпуле всех нод.
Нет. И вот почему:
Транзакции всегда нужно время, чтобы «дойти» до всех нод. Если вы её видите, это не значит, что её видят все.
Каждая нода настраивается по-своему и имеет свои ограничения (например, достигнут размер
maxmempool
).Нода не обязана включать транзакцию в мемпул и имеет право отказаться это делать.
Если транзакцию не приняли в мемпул, значит, её уже не сочтут валидной и не добавят в блок.
Нода может не принять, не добавить и не запросить транзакцию по множеству самых разных причин, например из-за того, что предлагаемая за эту транзакцию комиссия ниже, чем
minrelaytxfee
ноды.Параметр
minrelaytxfee
указывает уровень комиссии, который для мемпула этой ноды считается нижней планкой. Нода не будет принимать неподверждённые транзакции с комиссией ниже этого уровня в свой мемпул, а значит, не будет и передавать её никому.minrelaytxfee
— настройка, которая задаётся в конфигурации. Каждый оператор ноды может задавать её сам, независимо от кого-либо.Это не значит, что транзакция невалидная, или её нельзя будет включить в блок.
Ну ладно, но как только транзакцию включают в блок, значит, она останется в блокчейне навсегда.
У каждой транзакции ровно один получатель.
У каждой транзакции ровно один отправитель.
Назначение для выхода Биткоин-транзакции — это всегда адрес.
Майнер всегда выберет транзакцию с самой высокой комиссией.
Все хэши транзакций в блокчейне уникальны.
Комиссия явно задаётся в транзакции.
Если я создам транзакцию, помеченную как RBF, я всегда её смогу заменить другой, пока она ещё не подтвердилась.
Если я вижу не-RBF транзакцию с достаточной комиссией, я могу быть уверен, что она будет принята в блокчейн без каких-либо изменений.
Если я вижу неподтверждённую транзакцию, отправленную на мой адрес, я могу сохранить её ID — он никогда не поменяется.
Если ID неподтверждённой транзакции изменился, значит, это однозначно была злоумышленная попытка двойной траты.
Кошельки
Все кошельки поддерживают p2pkh-транзакции.
Все кошельки используют стандартизированные пути деривации/вывода.
Brain wallets — это безопасно.
12 (или 15, 18, 21, 24) слов мнемоники — это всё, что нужно, чтобы восстановить свой кошелёк.
Существует только один стандарт для мнемоник (12/24 слов).
Каждый путь деривации/вывода (например,
m/44'/0'/0'/0/0
,m/44'/0'/0'/0/1
, так далее) гарантированно выведет валидный адрес.Ключ BIP 32 выводится так: применяется HMAC-SHA512 (см. BIP 32 за подробностями), и первые 256 битов результата становятся ключом. Биткоин использует для операций подписи эллиптическую кривую secp256k1. Не все числа от 0 до 2^256 — валидные ключи для secp256k1. Например, 0 и все числа > n, где n — порядок кривой, к валидным ключам не относятся (по определению secp256k1). Поскольку n secp256k1-кривой очень близок к возможному максимуму в 2^256, очень маловероятно (вероятность меньше 1 в 2^127), что значение, выведенное генерацией BIP 32 ключа, не будет валидным приватным ключом. Если такое вообще когда-нибудь произойдёт, BIP 32 указывает, что кошельку следует просто пропустить этот индекс и перейти к следующему по возрастанию (см. спецификацию выведения ключей за подробностями).
Таким образом, возможно, что существуют кошельки с пропусками в индексах. Для таких пропущенных индексов просто не существует адреса, и они в итоге будет просто молча проигнорированы кошельками. Однако, вероятность этого так мала, что никто, скорее всего, подобного никогда не увидит. Забавный факт: автор pycoin даже подготовил особенное сообщение об ошибке на случай, если это когда-либо произойдёт :)
Если я частично опустошу (sweep) бумажный кошелёк, остаток денег всегда будет и дальше лежать на этом кошельке.
Но если я воспользуюсь приложением, отдельно предлагающим функцию опустошения бумажного кошелька, и при этом переведу только часть средств, всё остальное непременно вернётся именно на тот адрес, что указан в бумажном кошельке.
Ключи
Каждый приватный ключ соответствует ровно одному адресу.
Приватные ключи, сокращённые в WIF, короче несокращённых.
Каждое целое число от 1 до 2^256 — валидный приватный ключ от Биткоин-аккаунта.
Возможно перевести существующий Биткоин-ключ в мнемонику формата BIP39 (12/24 слов).
Если у меня есть приватный ключ, выведенный из расширенного (xpub/xprv) ключа, то можно со спокойной душой сообщить его человеку, который знает родительский xpub (не xprv) этого ключа. Это безопасно.
Адреса
У каждого Биткоин-адреса есть ровно один приватный ключ.
Всегда возможно вывести адрес из входных данных (или выходных).
Все Биткоин-адреса имеют одинаковую длину (количество символов).
Все Биткоин-адреса чувствительны к регистру.
Приватность
Биткоин анонимен.
У каждой монеты есть чёткая и ясная история владения ею, которая прослеживается вплоть до её создания. Кроме того, блокчейн позволяет кому угодно видеть совершенные транзакции. Любой участник сети может провести аудит транзакций, адресов и количества монет в сети.
Адреса — это просто строки с буквами и цифрами, которые сами по себе никак не привязаны к определённому пользователю или кошельку. И пользователи, и кошельки могут использовать какое угодно количество адресов, чтобы держать биткоины, а multisig-адреса могут хранить монеты, принадлежащие нескольким пользователям. Таким образом, Биткоин скорее можно назвать псевдонимным, чем анонимным.
Все монеты, потраченные в рамках одной транзакции (входы), контролируются одной и той же сущностью или принадлежат одному и тому же человеку.
Обменники
Обменники всегда будут разрешать выводить средства.
Монеты, лежащие в моём аккаунте в обменнике, принадлежат мне.
Монеты, лежащие в моём аккаунте в обменнике, действительно существуют.
Ордеры, принятые обменниками, гарантированно будут выполнены.
Запрашиваемая цена всегда будет равна или выше цены ставки.
Прочее
Всего существует ровно 21 миллион биткоинов.
Общее количество биткоинов имееет асимптоту в 21 миллион, что обусловлено самой структурой блокчейна (если конкретно, выход транзакции — целое число). Более точное число — 20,999,999.9769 биткоинов. Из-за недоплат майнерам общее количество, однако, даже ниже.Таким образом, невозможно точно узнать, сколько биткоинов будет существовать в 2140, но точно меньше, чем 21 миллион.
Ну ладно, но я хотя бы могу быть уверен, что выпущенных биткоинов никогда не будет больше 21 миллиона.
Ну как сказать… Нет.
В августе 2010 произошёл небольшой инцидент на высоте #74638. Кто-то обнаружил, что сумма транзакции не проверяется на предмет того, не превосходит ли она баланс кошелька (то есть, тогда такой проверки не было). Затем этот кто-то создал транзакцию с двумя выходами, каждый на 92233720368.54277039 BTC (92 миллиарда!). Эту транзакцию сочли валидной все ноды в сети, потому что сумма входов с комиссией показалась им соответствующей сумме выходов. На самом же деле эта сумма просто вызывала целочисленное переполнение. Биткоин-сообщество это быстро заметило, и за пару часов ошибку поправили. Как только большинство майнеров перешло на исправленную версию, цепочку с тем блоком отклонили как невалидную, и все ноды её исключили. В новой основной цепочке, таким образом, этого блока уже не было, поэтому в нынешнем блокчейне вы его не увидите. Следы этого случая, однако, и сейчас можно заметить по временным отметкам в блоке 74637 и блоке 74638. Их разделяет несколько часов, потому что это ровно то время, в которое существовала цепочка с невалидной транзакцией. Существовала, пока её не отклонили в пользу честной цепочки, поддержанной большинством.
То есть, технически, был такой короткий промежуток времени, в котором общая сумма всех биткоинов превосходила 21 миллион. Если бы RPC-запрос
bitcoin-cli gettxoutsetinfo
уже существовал в 2010, то 15 августа 2010 года, между 17:02 and 23:53, он бы вернул общее количество существующих монет в 184 миллиарда BTC.Все UTXO (непотраченные выходы транзакций) можно потратить.
Некоторые доказанно нельзя потратить в принципе никогда (например, выход на 50 BTC в первичном блоке). Кроме того, ещё есть выходы выходы со скриптом
OP_RETURN
и прочие, которые невозможно потратить с очень большой вероятностью. Например, адреса, которые выглядят «сгенерированными». По ним кажется, что кто-то просто пытался найти валидную контрольную сумму для адреса; очень, очень маловероятно, что этот адрес — дейсвительно результат работы случайной операции хэширования.Примеры: 1CounterpartyXXXXXXXXXXXXXXXUWLpVr или 1BitcoinEaterAddressDontSendf59kuE. Можно уверенно предположить, что эти монеты уже никогда не потратить. Кроме того, есть множество адресов, приватный ключ от которых утерян.