Неподтвержденная транзакция, или Возвращаем криптовалюту из небытия / Habr
Волею судеб довелось мне иметь дело с криптовалютами. Не то что бы плотно работаю с ними, но иногда то отправлю монетки, то получу. Скажем так, понемногу прощупываю новую сферу изнутри.И вот однажды беда приключилась. Отослал я криптомонетки, а до получателя они не дошли. Собственно, пост о том, как средства возвращались. Ну и размышления и советы по сложившейся ситуации на десерт. Сразу отмечу, что нижесказанное применимо не к какой-то конкретной валюте, а к большинству форков (если не ко всем).
Начну с того, что пост местами пронизан догадками относительно происходящего. Где-то я могу ошибаться. Объективные поправки и дополнения только приветствуются.
Немного о терминологии.
- Кошельком буду называть файл wallet.dat.
- Публичный ключ (адрес, на который перечисляются средства, например) временами тоже удобнее назвать кошельком, но, во избежание путаницы, пусть он будет просто номером счета.
- Комиссия — Transaction Fee. Называть эту штуку комиссией, я считаю, не совсем правильно, но это наиболее привычный и не режущий слух вариант, потому пусть будет комиссией.
- Размер транзакции — размер блока данных, в котором содержится вся информация о транзакции.
Ко всей этой криптовалютной кухне я изначально подошел как типичный юзер — не особо вникая в систему. Установил, запустил, работает — и ладно. Иногда при попытке послать куда-то средства клиент выдавал сообщение вроде «Размер транзакции слишком велик, нельзя просто взять и послать ее. Но вы можете добавить комиссию в размере N, и тогда все будет хорошо» — я соглашался с добавлением комиссии, и все действительно было хорошо.
Казалось бы, если меня просят дополнительно заплатить, когда это нужно, значит я и буду платить, когда попросят (если комиссия будет устраивать). Это и было главной ошибкой.
Делаю очередной перевод на сумму значительно крупнее, чем обычно. Средства со счета уходят, предложения заплатить комиссию не было и… Ничего. До получателя средства не доходят, статус транзакции «0/Не подтверждено». И такую картину я наблюдал больше недели, попутно перегугливая и перечитывая интернеты в поисках информации по решению подобной проблемы. Причем искал и для конкретной криптовалюты, и в целом для всех — проблем куча, решения нет.
А, собственно, что же это за комиссия? Идея в том, что транзакции могут проходить без комиссии, но только в случае соблюдения некоторых условий:
- Размер транзакции должен быть не больше определенной величины.
- Переводимая сумма должна быть больше некоего порога.
- Транзакция должна обладать достаточным приоритетом.
Если первые два пункта более-менее понятны (конкретные величины приводить не стал, полагаю, они могут варьироваться от форка к форку), то в третьем вся загвоздка. Грубо говоря, транзакции при создании попадают в очередь, отсортированные по приоритету. При генерации очередного блока в него включаются транзакции с комиссией (которая идет в награду тому, кто нашел блок), а также транзакции без комиссии с наиболее высоким приоритетом.
Поиски решения показали, что это сравнительно частая для криптовалют проблема. К сожалению, все советы сводились к нижеперечисленному и часто не помогали:
- Подождите сутки-двое, вашу транзакцию включат в очередной блок.
- Подождите сутки-двое, программе-клиенту надоест ждать, и она сама отменит транзакцию.
- Загрузите заново всю цепочку блоков.
- Запустите клиент с каким-нибудь волшебным ключом (-rescan / -reindex / -salvagewallet).
Ждал я больше недели. Ни в какой блок транзакцию не включили. Даже после повторных отправок через sendrawtransaction. Блокчейн говорил, что о той транзакции ничего не знает, и на счету лежат те самые средства, никуда они не ушли. И только клиент стоял на своем: «Я транзакцию отправил, дальше как хочешь. Уже потраченными деньгами распоряжаться не позволю».
Итак, в чем же суть проблемы? Транзакция не попала в блок и уже не попадет. В кошельке хранится информация о том, что транзакция в общем-то была, поэтому средства, которые должны были с ней отправиться, недоступны для использования. Возможно, спустя еще какое-то время транзакция будет отменена, на этот счет у меня несколько предположений:
- Зависит от валюты, где-то быстро отменяется, где-то нужно ждать долго.
- Баг конкретного клиента.
- Информация об отмене неверна.
В любом случае, неделя — это достаточно большой срок. Если за это время не прошло само, то есть основания полагать, что и не пройдет.
Как нормальный человек, после того, как все уже сломалось, я наконец-то пошел читать мануалы. Попытка повторить транзакцию с включением в нее комиссии потерпела фиаско. Зато бесконечные прыжки по ссылкам между форумами (в выдаче гугла ничего стоящего не нашлось) довели меня до некоего поста, где и нашлась дельная подсказка. К сожалению, теперь найти этот пост не удается, даже не знаю, что был за форум. Полагаю, некий околобиткойновый.
Решение буду описывать на примере клиента, наиболее распространенного для форков, известного как Satoshi Client. Насколько понимаю, оно применимо и к прочим клиентам, но, возможно, со своими нюансами.
Несмотря на простоту и очевидность решения, к нему мало кто приходит, судя по многостраничным веткам форумов. Средства на счете блокируются кошельком, и все, что требуется, это получить доступ к счету вне текущего кошелька.
Итак, если транзакция зависла и не имеет подтверждений:
- Проявите терпение. Не поднимайте сразу панику. Подождите пару дней, вдруг и правда само пройдет.
- Убедитесь, что транзакция зависла. Зайдите в Block Explorer (обычно гуглится по запросу «blockchain %названиекриптовалюты%») и проверьте, что про зависшую транзакцию там ничего не знают, а на счете деньги на самом деле есть.
- Перейдите в отладочную консоль (Помощь — Окно отладки — Консоль)
- Если кошелек зашифрован (он же зашифрован?), то для начала необходимо получить доступ, используя команду walletpassphrase <passphrase>.
- Теперь нужно получить приватный ключ от нужного счета. dumpprivkey <address>. Вместо <address> нужно подставить публичный номер счета, на котором лежат заблокированные средства. В ответ получите приватный ключ данного счета. Его нужно куда-нибудь скопировать, он еще понадобится. Если средства для транзакции брались с нескольких счетов, то и импортировать нужно их все. И да, никогда не храните приватные ключи в доступном для кого-либо месте. Знание ключа дает полный доступ к соответствующему ему счету.
- Закройте клиент и удалите кошелек. Расположение кошелька (wallet.dat) зависит от конкретного клиента и ОС. Естественно, совсем удалять его не стоит, лучше переименовать или переместить в надежное место.
- Запустите клиент заново. Создастся новый кошелек. В него необходимо импортировать полученный ранее ключ (ключи). Идем в отладочную консоль и пишем importprivkey <privkey>. Импорт может производиться достаточно долго. Позвольте ему завершиться — дождитесь получения ответа на команду.
- В новом кошельке должен появиться счет с реальным его состоянием. Для надежности можно перезапустить клиент с ключом -rescan, но, полагаю, это уже лишнее. Ранее заблокированные средства снова доступны для отправки, шлите их заново, на этот раз не забудьте включить комиссию. (есть важные дополнения по этому пункту в upd3
- Если на старом кошельке остались прочие используемые и важные счета, можно снова вернуться к нему.
Таким нехитрым образом удалось вернуть криптомонетки. Хотя я уже и начал думать, что они потеряны совсем. В общем, не надейтесь на чудо, перед использованием нового клиента убедитесь, что комиссия всегда включена. Рекомендуемый размер комиссии, думаю, лучше искать на ресурсах, посвященных используемой криптовалюте.
Upd: Необходимость описанной операции зависит от используемого клиента (а так как у многих криптовалют по одному клиенту, то и от используемые валюты). Похоже, в некоторых случаях информация о транзакции записывается не в файл кошелька, а только в локальную цепочку блоков. При таком раскладе может помочь удаление имеющейся цепочки или запуск клиента с ключами.
Upd2: Значительно упростить описанный процесс переноса счетов в новый кошелек может ключ -salwagewallet, уже упомянутый ранее. При запуске клиента с этим ключом создается новый wallet.dat, в который импортируются все счета из старого, а история транзакций к нему берется из цепочки блоков (за описание спасибо grich). К сожалению, запуск с данным ключом реализован не во всех клиентах.
Upd3: Если после импорта перечислить не всю сумму, имеющуюся на счету, то часть средств (сдача от используемых выходов) будет перечислена на другой счет нового кошелька. Учитывайте это, если планируете вернуться к старому кошельку:
- Импортировав счет в новый кошелек, переведите все средства с него на другой свой счет, вернитесь к старому кошельку и после этого уже распоряжайтесь возвращенными средствами.
- После совершения транзакции с нового кошелька определите, на какой счет упала сдача, и импортируйте этот счет в старый кошелек.
habr.com
Неподтвержденные транзакции Blockchain — проверить, подтвердить
Количество транзакций в сети постоянно растет, а это значит, что блоки, в которых они хранятся, заполняются быстрее. Ведь размер блока остается прежним. Из-за этого возникает распространенная проблема – задержка транзакции в результате того, что она не подтверждена.
Время ожидания перевода может затянуться на несколько часов, дней, а порой и недель. Это создает очевидные неудобства, особенно в ситуациях, когда необходимо перевести средства в сжатые сроки. В этой статье мы рассмотрим, что такое неподтвержденные транзакции Blockchain и выясним, что необходимо делать в таких ситуациях.
Что такое транзакция и очередь
Транзакция – это запись в цепочке блоков, называемой Блокчейн.
Любая криптотранзакция содержит три типа данных:
- Input – записывается адрес отправителя.
- Amount – сумма, полученная от отправителя.
- Output – адрес получателя.
Очередь транзакций Биткоина — набор операций в Blockchain, которые долгое время ждут проведения из-за низкой комиссии, повышенной нагрузки и прочих факторов. Известно, что работоспособность сети обеспечивают майнеры, которые используют имеющиеся мощности для обработки транзакций и поиска необходимого хэша при проведении операции. В первую очередь обрабатываются сделки с более высокой комиссией, после чего майнеры принимаются за транзакции с меньшей премией. Так и формируется очередь Биткоин, в «голове» которой более привлекательные операции, а в «хвосте» платежи с минимальной премией.
Как проверить транзакцию в Блокчейн
Чтобы посмотреть очередь транзакций Blockchain, можно воспользоваться одним из следующих сервисов:
Кошелек Blockchain.info. Чтобы отследить транзакцию, необходимо внести сведения о ней в специальную строку «Поиск». Посмотреть операцию можно по хэшу, IP или адресу. Если перейти в раздел Charts, легко узнать очередь транзакций Биткоина сейчас, а именно общий размер не проведённых операций.
Chain.so — ещё один удобный сервис, где легко можно глянуть список транзакций блокчейн. В верхней строке можно найти сделку по одному из предложенных вариантов. Здесь же указывается приблизительное время, которое уходит на обработку каждой транзакции, ее размер, наименование майнера и прочие параметры.
Btc.com. Сразу после входа на главную страницу пользователь видит список и размер последних блоков, время и вознаграждение. Ниже можно перейти по ссылке «Неподтвержденные транзакции». После перехода можно увидеть рекомендуемую комиссию. Ниже можно увидеть время перечисления с учётом размера комиссии, а также размер мемпул.
Что значит неподтвержденная транзакция
Неподтвержденная транзакция – это транзакция, которая после ее инициирования не была добавлена в блок. Работа сети Bitcoin поддерживается майнерами, которые и «обрабатывают» переводы. У них есть собственный приоритет – чем выше комиссия за байт транзакции, тем быстрее она будет добавлена в новый блок. Так что подтверждение транзакции Биткоин в Blockchain зависит от комиссии, которую выбрал отправитель.
Главной причиной неподтвержденной транзакции называют низкую комиссию, которую выставил пользователь. В большинстве кошельков есть понятие рекомендуемой комиссии, которую программа выбирает сама. Однако, этот показатель может быть, как занижен, так и завышен.
Как ускорить транзакцию Blockchain
Если проводка уже была отправлена в систему, но по какой-то причине зависла транзакция в Блокчейн, есть несколько вариантов решить эту проблему.
Opt-In Replace-by-Fee
Эта опция позволяет пользователю направить криптотранзакцию еще раз, но только уже с более высокими крипторасходами.
Если владелец Биткоинов попытается проделать все это без соответствующей опции, сеть воспримет ее как попытку двойной траты. Соответственно, такая криптосделка не будет обработана.
Использование Opt-In Replace-by-Fee позволяет решить эту проблему, так как сеть увидит, что пользователь отправляет ту же проводку, но только с более высокой комиссией.
Единственная проблема, с которой можно столкнуться клиент сети в этом случае – не все майнеры поддерживают такую функцию. То есть необходимо дождаться момента, пока на операцию обратит внимание тот майнер, который работает с Opt-In Replace-by-Fee.
CPFP (Child Pays for Parent)
Этот метод рассчитан на ситуации, когда отправитель создал новую транзакцию с битками, которые «условно» получил с другой транзакции, которая еще не была подтверждена. В таком случае, для проведения операции необходимо оплатить комиссию еще за ту самую неподтвержденную транзакцию.
Итак, особенность этого способа в том, что он не бесплатный, и его поддерживают не все пулы. Но всё же в его эффективности нет сомнений. Чтобы продвинуть сделку, надо воспользоваться одним из выходов операции, с которой возникли проблемы. Правда, важно, чтобы этой суммы хватило как для старой, так и для новой сделки.
То есть, пользователь создаёт ещё одну транзакцию, используя для этого выход, например, сдачу, для того чтобы открыть ещё одну сделку. Пересылать Биткоины можно себе же, главное, чтобы была задействована сдача с проблемного перевода.
Ускорители
Ускоритель транзакций viabtc контролирует скорость прохождения в сети Блокчейн. Это относительно новый сервис, который успел собрать множество поклонников. Его основная цель в том, чтобы ускорить продвижение зависших переводов в сети. Причём его необходимость не вызывает сомнений, потому что таких зависающих транзакций появляется всё больше, и с ними не может справиться даже человек, который действительно разбирается в криптовалюте. А новичкам вообще без сервиса viabtc не обойтись. Так что с помощью этого небольшого ускорителя можно забыть об ожидании подтверждения транзакции, которое не поступает на протяжении нескольких суток.
Отмена транзакции
Сеть настолько загружена, что неподтверждённая транзакция Blockchain появляется очень часто, а значит, нужно разобраться, что с этим делать. Несмотря на то, что в Блокчейне неподтверждённая транзакция – это обычное явление, что делать, знают немногие. Самый популярный вопрос «можно ли отменить транзакцию в Blockchain».
Да, можно. Но есть условие – это можно сделать лишь в установленном на компьютере кошельке. Такая процедура не принесёт никакого результата, если пользователь использует облачные кошельки. Если транзакция была совершена с них, надо искать альтернативный вариант её отмены.
Неподтвержденные транзакции на Blockchain (видео)
guland.biz
Как пользователям Биткоина обезопасить себя при хардфорке без защиты от дублирования транзакций — BlockchainHouse
Хардфорк SegWit2x неумолимо приближается, и так как вопрос защитой от дублирования транзакций (Replay protection) так и остался нерешенным, многие пользователи считают, что ее отсутствие станет причиной серьезных проблем для сети. На данный момент разработчики SegWit2x не включили в репозиторий своего клиента код для защиты от дублирования, поскольку стремятся не к разделению сети, а к получению преимущества над сторонниками Bitcoin Core в действующем блокчейне.
В этой статье мы расскажем о нескольких способах, которые позволят вам обезопасить себя от копирования транзакций в другом блокчейне, независимо от того, появится ли такая защита или нет. Для этого необходимо объяснить, как совершаются транзакции биткоина и что происходит с неизрасходованными выходами (UTXO).
Неизрасходованные выходы (UTXO)
Чтобы понять, как защититься от дублирования транзакций, сначала нужно разобраться в том, как работает Биткоин. В Биткоине у вас на самом деле нет единого баланса, даже если все платежи были отправлены на один адрес. У вас наверняка есть много небольших входящих платежей, которые называются неизрасходованными выходами (UTXO). Вы можете потратить только те средства, которые у вас есть, а сумма всех UTXO — это и есть тот баланс, который отображается в вашем кошельке.
Когда вы тратите некоторое количество биткоинов, ваш кошелек использует один или несколько неизрасходованных выходов в качестве входящей информации для транзакции. Поэтому, если пользователь А прислал вам 5 биткоинов, пользователь Б – 3 биткоина, а вы в свою очередь отослали 8 биткоинов пользователю В, ваш кошелек использует неизрасходованные выходы как по транзакции «5 биткоинов», так и «3 биткоина» в качестве входных данных. Когда вы отослали 8 биткоинов пользователю В, он становится обладателем UTXO на «8 биткоинов» (в этом примере комиссии не учитываются).
Важной особенностью неизрасходованных выходов является то, что все они должны быть потрачены каждый раз, когда UTXO используются как входы. Поэтому если у вас есть неизрасходованные выходы по транзакции на 100 биткоинов, а вы хотите потратить только 0.001 биткоина, что вы должны сделать? Здесь вам сыграет на руку тот факт, что в одной транзакции можно послать биткоины нескольким людям – вы можете переслать 0.001 биткоина тому, кому собирались, и отослать 99.9985 самому себе (и заплатить при этом комиссию в 0.0005 майнеру). Обычно возвратный платеж на другой адрес в вашем кошельке формируется автоматически, и называется «сдачей». Теперь в вашем кошельке будут находиться неизрасходованные выходы на 99.9985 биткоина.
Таким образом, как только конкретные UTXO потрачены, про них можно забыть. Они либо расходуются, либо нет — промежуточного состояния быть не может, что делает код намного проще.
Глобальный набор UTXO или полный набор неизрасходованных выходов для всех адресов в сети — это то, что отслеживают полные узлы, чтобы убедиться, что никакие транзакции не дублируются.
Дублирование транзакций
На момент хардфорка одни и те же неизрасходованные выходы находятся в обеих сетях. Точнее, на этот момент все еще существует одна сеть, как идентичная основа для двух сетей, образующихся после разделения. Чтобы можно было осуществить дублирование транзакции, она целиком должна быть действительна в обеих сетях, то есть удовлетворять правилам обеих сетей. Если защиты не будет, то все UTXO, имеющиеся на момент форка, будут уязвимы.
Однако, поскольку две цепи после создания отдельных и несовместимых блоков в каждой из них, расходятся в составе транзакций, набор UTXO тоже начнет отличаться. Например, транзакции coinbase (речь идет о транзакциях-вознаграждениях для майнеров, которые появляются один раз за блок, а не о компании) в обоих блокчейнах, безусловно, будут отличаться, так как блоки добываются разными майнерами и по разным правилам консенсуса (даже если различие между ними незначительно).
Транзакции coinbase после хардфорка нельзя будет продублировать. То есть транзакция coinbase в сети 2x не будет копироваться в сеть 1x, и ни одна транзакция coinbase из сети 1x не будет дублироваться в 2x.
Конечно, coinbase транзакции (которые мы называем транзакциями нулевого уровня) обладают выходами, и они будут частью нового набора UTXO. Любая транзакция, использующая UTXO нулевого уровня (которые мы называем транзакциями первого уровня) в качестве входных данных, также не будет дублироваться в другой цепочке. Кроме того, любые транзакции, которые используют выходы транзакций первого уровня (которые мы называем транзакциями второго уровня), также не будут копироваться в другую цепочку. Таким образом все будет работать и с транзакциями третьего уровня и далее.
Обратите внимание: если даже одна транзакция уровня N становится входом в следующую транзакцию, то она не может быть продублирована в другой сети. То есть, транзакция уровня N в сети 2x не копируется в 1x, а транзакция уровня N в 1x не дублируется в 2x. Таким образом можно назвать все неизрасходованные выходы транзакций уровня N+1 защищенными от дублирования UTXO.
Этот конкретный метод весьма громоздок, поскольку coinbase транзакции подчиняются правилу, которое не позволяет их истратить в ближайшие 100 блоков. Обычно это около 17 часов, но может быть и больше, и меньше, в зависимости от того, как распределяется мощность хэширования.
Одновременная отправка
Другой способ, с помощью которого можно создавать защищенные от дублирования UTXO, без участия coinbase или аналогичных транзакций, заключается в создании двух разных транзакций, которые отправляются самому себе, используя один и тот же UTXO. Вот как это работает:
- Предположим, у вас есть неистраченный выход – u.
- Потратьте u в двух разных транзакциях между своими кошельками, первая (tx1) отправится на адрес 1, а вторая (tx2) – на адрес 2.
- Отправьте tx1 в цепочку 1, а tx2 – в цепочку 2 одновременно, с достаточной комиссией.
Если все получится, то по итогу у вас будет tx1, созданная в цепочке 1 и tx2, созданная в цепочке 2, с одного исходного UTXO. Конечно, tx1 может быть продублирована в цепочке 2, но поскольку tx2 была отправлена в ту же цепочку, для узлов в сети 2 это будет выглядеть как повтор, и они, скорее всего, отклонят ее. Тоже самое произойдет и в сети 1.
Поскольку отправка обеих транзакций происходит в разных цепочках, а комиссии достаточны для обеих транзакций, в каждой цепочке у вас будут UTXO, уже защищенные от дублирования.
Даже если каким-то образом транзакция все же скопируется – ничего страшного. Адреса контролируются вами, и вы ничего не потеряете, кроме комиссии за транзакции, и сможете попробовать еще раз.
Использование locktime
Еще один способ создания защищенных от дублирования UTXO – использование функции под названием locktime. Она есть не в каждом кошельке, но позволит вам сделать так, чтобы транзакция не включалась в цепочку Биткоина до определенного номера блока. То есть, если вы укажете номер блока 500 000, любой блок до этого номера, который включает такую транзакцию, будет отклонен сетью.
Этот способ возможен в том случае, если одна цепочка значительно длиннее другой (по крайней мере на 6, но лучше на 20-30 блоков). Предложим, что длина цепочки 1 — 500 010 блоков, а цепочки 2 – 500 000 блоков.
- Предположим, у вас есть неистраченный выход – u.
- Потратьте u в сети 1, установив ограничение на включение транзакции (tx1) до блока 500 011
- Как только tx1 будет включена в блок (до блока 500 011 в сети 2), создайте еще одну транзакцию (tx2), которая потратит u в сети 2 на другой адрес.
- Если tx2 будет подтверждена до блока 500 011 в сети 2, то вы станете обладателем UTXO, защищенных от дублирования в обеих цепочках.
Естественная защита от дублирования
Защищенные от копирования неистраченные выходы – весьма эффективный способ защиты от дублирования транзакций.
Все, что вам нужно — это один защищенный от копирования UTXO для его присоединения в одной транзакции к другому, еще не защищенному. UTXO может иметь очень маленькую ценность, так как сумма не имеет значения. Скорее всего, в конечном итоге произойдет следующее – обе сети предложат каждому пользователю небольшое количество UTXO, защищенных от копирования, и вы можете использовать их, чтобы убедиться, что ваша транзакция не будет дублироваться.
Также можно ждать, что биржи, продавцы и другие биткоиновые компании будут использовать этот метод, чтобы случайно не отправлять эквивалентное количество других монет своим клиентам. Другими словами, вы сможете получать UTXO с защитой от копирования от бирж, продавцов и т. д., вскоре после хардфорка так как защита от дублирования – в их интересах.
Что это значит для пользователей
Если вы только храните свои средства и не планируете совершать транзакции в ближайшее время, то вас ситуация с дублированием транзакций вообще не должна беспокоить.
Даже если Segwit2x не предложит никакой защиты от копирования, скорее всего появятся фильтры для защиты от дублирования, чтобы вы могли безопасно совершать транзакции. Вам будет необходимо взять несколько сатоши из таких фильтров и переместить весь баланс (включая ваши недавно полученные сатоши) вашего кошелька на другой адрес в вашем кошельке. Это сделает ваши операции менее конфиденциальными, так как все ваши адреса будут связаны, но эта транзакция будет защищена от дублирования. После того, как выход будет потрачен в нужной сети и транзакция подтверждена (желательно дождаться 6 и более подтверждений), все биткоины на новом выходе уже не могут быть продублированы.
Если вы беспокоитесь о конфиденциальности, вам необходимо будет взять больше защищенных от копирования UTXO из разных фильтров. К сожалению, это займет много времени, в зависимости от того, сколько адресов в вашем кошельке, не говоря уже о том, что это будет дорого с точки зрения комиссий. Вашему кошельку также «функция контроля монет», чтобы все работало как надо (в Bitcoin Core и Armory есть такая функция, в Electrum тоже есть что-то подобное). Если кошельки внедрят такой функционал, то чем больше участников сообщества будет его использовать, тем выше будет конфиденциальность сети в целом.
Также в кошельках может появиться функция, которая позволит вам попытаться создать защищенные от дублирования UTXO. Для этого кошельки должны будут установить locktime (Bitcoin Core это умеет). Другими словами, вам придется подождать появления нового функционала в вашем любимом кошельке.
Резюме
Защита от дублирования транзакций на время хардфорка – нужная функция, но не переживайте, если она в итоге не будет внедрена в сеть. Появятся различные решения – фильтры и новый функционал в кошельках. Вам нужно только сохранят бдительность и внимательно следить за обновлениями. Рано или поздно кризис разрешится, и одна из сторон противостояния станет «настоящим биткоином» , а другая станет альткойном или просто умрет, оставшись без пользователей.
blockchainhouse.media
Как пользователям Биткоина обезопасить себя при хардфорке без защиты от дублирования транзакций
Хардфорк SegWit2x неумолимо приближается, и так как вопрос
защитой от дублирования транзакций (Replay protection) так и остался нерешенным, многие пользователи считают, что ее отсутствие станет причиной серьезных проблем для сети. На данный момент разработчики SegWit2x не включили в репозиторий своего клиента код для защиты от дублирования, поскольку стремятся не к разделению сети, а к получению преимущества над сторонниками Bitcoin Core в действующем блокчейне.
В этой статье мы расскажем о нескольких способах, которые позволят вам обезопасить себя от копирования транзакций в другом блокчейне, независимо от того, появится ли такая защита или нет. Для этого необходимо объяснить, как совершаются транзакции биткоина и что происходит с неизрасходованными выходами (UTXO).
Неизрасходованные выходы (UTXO)
Чтобы понять, как защититься от дублирования транзакций, сначала нужно разобраться в том, как работает Биткоин. В Биткоине у вас на самом деле нет единого баланса, даже если все платежи были отправлены на один адрес. У вас наверняка есть много небольших входящих платежей, которые называются неизрасходованными выходами (UTXO). Вы можете потратить только те средства, которые у вас есть, а сумма всех UTXO — это и есть тот баланс, который отображается в вашем кошельке.
Когда вы тратите некоторое количество биткоинов, ваш кошелек использует один или несколько неизрасходованных выходов в качестве входящей информации для транзакции. Поэтому, если пользователь А прислал вам 5 биткоинов, пользователь Б – 3 биткоина, а вы в свою очередь отослали 8 биткоинов пользователю В, ваш кошелек использует неизрасходованные выходы как по транзакции «5 биткоинов», так и «3 биткоина» в качестве входных данных. Когда вы отослали 8 биткоинов пользователю В, он становится обладателем UTXO на «8 биткоинов» (в этом примере комиссии не учитываются).
Важной особенностью неизрасходованных выходов является то, что все они должны быть потрачены каждый раз, когда UTXO используются как входы. Поэтому если у вас есть неизрасходованные выходы по транзакции на 100 биткоинов, а вы хотите потратить только 0.001 биткоина, что вы должны сделать? Здесь вам сыграет на руку тот факт, что в одной транзакции можно послать биткоины нескольким людям – вы можете переслать 0.001 биткоина тому, кому собирались, и отослать 99.9985 самому себе (и заплатить при этом комиссию в 0.0005 майнеру). Обычно возвратный платеж на другой адрес в вашем кошельке формируется автоматически, и называется «сдачей». Теперь в вашем кошельке будут находиться неизрасходованные выходы на 99.9985 биткоина.
Таким образом, как только конкретные UTXO потрачены, про них можно забыть. Они либо расходуются, либо нет — промежуточного состояния быть не может, что делает код намного проще.
Глобальный набор UTXO или полный набор неизрасходованных выходов для всех адресов в сети — это то, что отслеживают полные узлы, чтобы убедиться, что никакие транзакции не дублируются.
Дублирование транзакций
На момент хардфорка одни и те же неизрасходованные выходы находятся в обеих сетях. Точнее, на этот момент все еще существует одна сеть, как идентичная основа для двух сетей, образующихся после разделения. Чтобы можно было осуществить дублирование транзакции, она целиком должна быть действительна в обеих сетях, то есть удовлетворять правилам обеих сетей. Если защиты не будет, то все UTXO, имеющиеся на момент форка, будут уязвимы.
Однако, поскольку две цепи после создания отдельных и несовместимых блоков в каждой из них, расходятся в составе транзакций, набор UTXO тоже начнет отличаться. Например, транзакции coinbase (речь идет о транзакциях-вознаграждениях для майнеров, которые появляются один раз за блок, а не о компании) в обоих блокчейнах, безусловно, будут отличаться, так как блоки добываются разными майнерами и по разным правилам консенсуса (даже если различие между ними незначительно).
Транзакции coinbase после хардфорка нельзя будет продублировать. То есть транзакция coinbase в сети 2x не будет копироваться в сеть 1x, и ни одна транзакция coinbase из сети 1x не будет дублироваться в 2x.
Конечно, coinbase транзакции (которые мы называем транзакциями нулевого уровня) обладают выходами, и они будут частью нового набора UTXO. Любая транзакция, использующая UTXO нулевого уровня (которые мы называем транзакциями первого уровня) в качестве входных данных, также не будет дублироваться в другой цепочке. Кроме того, любые транзакции, которые используют выходы транзакций первого уровня (которые мы называем транзакциями второго уровня), также не будут копироваться в другую цепочку. Таким образом все будет работать и с транзакциями третьего уровня и далее.
Обратите внимание: если даже одна транзакция уровня N становится входом в следующую транзакцию, то она не может быть продублирована в другой сети. То есть, транзакция уровня N в сети 2x не копируется в 1x, а транзакция уровня N в 1x не дублируется в 2x. Таким образом можно назвать все неизрасходованные выходы транзакций уровня N+1 защищенными от дублирования UTXO.
Этот конкретный метод весьма громоздок, поскольку coinbase транзакции подчиняются правилу, которое не позволяет их истратить в ближайшие 100 блоков. Обычно это около 17 часов, но может быть и больше, и меньше, в зависимости от того, как распределяется мощность хэширования.
Одновременная отправка
Другой способ, с помощью которого можно создавать защищенные от дублирования UTXO, без участия coinbase или аналогичных транзакций, заключается в создании двух разных транзакций, которые отправляются самому себе, используя один и тот же UTXO. Вот как это работает:
Предположим, у вас есть неистраченный выход – u.
Потратьте u в двух разных транзакциях между своими кошельками, первая (tx1) отправится на адрес 1, а вторая (tx2) – на адрес 2.
Отправьте tx1 в цепочку 1, а tx2 – в цепочку 2 одновременно, с достаточной комиссией.
Если все получится, то по итогу у вас будет tx1, созданная в цепочке 1 и tx2, созданная в цепочке 2, с одного исходного UTXO. Конечно, tx1 может быть продублирована в цепочке 2, но поскольку tx2 была отправлена в ту же цепочку, для узлов в сети 2 это будет выглядеть как повтор, и они, скорее всего, отклонят ее. Тоже самое произойдет и в сети 1.
Поскольку отправка обеих транзакций происходит в разных цепочках, а комиссии достаточны для обеих транзакций, в каждой цепочке у вас будут UTXO, уже защищенные от дублирования.
Даже если каким-то образом транзакция все же скопируется – ничего страшного. Адреса контролируются вами, и вы ничего не потеряете, кроме комиссии за транзакции, и сможете попробовать еще раз.
Использование locktime
Еще один способ создания защищенных от дублирования UTXO – использование функции под названием locktime. Она есть не в каждом кошельке, но позволит вам сделать так, чтобы транзакция не включалась в цепочку Биткоина до определенного номера блока. То есть, если вы укажете номер блока 500 000, любой блок до этого номера, который включает такую транзакцию, будет отклонен сетью.
Этот способ возможен в том случае, если одна цепочка значительно длиннее другой (по крайней мере на 6, но лучше на 20-30 блоков). Предложим, что длина цепочки 1 — 500 010 блоков, а цепочки 2 – 500 000 блоков.
Предположим, у вас есть неистраченный выход – u.
Потратьте u в сети 1, установив ограничение на включение транзакции (tx1) до блока 500 011
Как только tx1 будет включена в блок (до блока 500 011 в сети 2), создайте еще одну транзакцию (tx2), которая потратит u в сети 2 на другой адрес.
Если tx2 будет подтверждена до блока 500 011 в сети 2, то вы станете обладателем UTXO, защищенных от дублирования в обеих цепочках.
Естественная защита от дублирования
Защищенные от копирования неистраченные выходы – весьма эффективный способ защиты от дублирования транзакций.
Все, что вам нужно — это один защищенный от копирования UTXO для его присоединения в одной транзакции к другому, еще не защищенному. UTXO может иметь очень маленькую ценность, так как сумма не имеет значения. Скорее всего, в конечном итоге произойдет следующее – обе сети предложат каждому пользователю небольшое количество UTXO, защищенных от копирования, и вы можете использовать их, чтобы убедиться, что ваша транзакция не будет дублироваться.
Также можно ждать, что биржи, продавцы и другие биткоиновые компании будут использовать этот метод, чтобы случайно не отправлять эквивалентное количество других монет своим клиентам. Другими словами, вы сможете получать UTXO с защитой от копирования от бирж, продавцов и т. д., вскоре после хардфорка так как защита от дублирования – в их интересах.
Что это значит для пользователей
Если вы только храните свои средства и не планируете совершать транзакции в ближайшее время, то вас ситуация с дублированием транзакций вообще не должна беспокоить.
Даже если Segwit2x не предложит никакой защиты от копирования, скорее всего появятся фильтры для защиты от дублирования, чтобы вы могли безопасно совершать транзакции. Вам будет необходимо взять несколько сатоши из таких фильтров и переместить весь баланс (включая ваши недавно полученные сатоши) вашего кошелька на другой адрес в вашем кошельке. Это сделает ваши операции менее конфиденциальными, так как все ваши адреса будут связаны, но эта транзакция будет защищена от дублирования. После того, как выход будет потрачен в нужной сети и транзакция подтверждена (желательно дождаться 6 и более подтверждений), все биткоины на новом выходе уже не могут быть продублированы.
Если вы беспокоитесь о конфиденциальности, вам необходимо будет взять больше защищенных от копирования UTXO из разных фильтров. К сожалению, это займет много времени, в зависимости от того, сколько адресов в вашем кошельке, не говоря уже о том, что это будет дорого с точки зрения комиссий. Вашему кошельку также «функция контроля монет», чтобы все работало как надо (в Bitcoin Core и Armory есть такая функция, в Electrum тоже есть что-то подобное). Если кошельки внедрят такой функционал, то чем больше участников сообщества будет его использовать, тем выше будет конфиденциальность сети в целом.
Также в кошельках может появиться функция, которая позволит вам попытаться создать защищенные от дублирования UTXO. Для этого кошельки должны будут установить locktime (Bitcoin Core это умеет). Другими словами, вам придется подождать появления нового функционала в вашем любимом кошельке.
Резюме
Защита от дублирования транзакций на время хардфорка – нужная функция, но не переживайте, если она в итоге не будет внедрена в сеть. Появятся различные решения – фильтры и новый функционал в кошельках. Вам нужно только сохранят бдительность и внимательно следить за обновлениями. Рано или поздно кризис разрешится, и одна из сторон противостояния станет «настоящим биткоином» , а другая станет альткойном или просто умрет, оставшись без пользователей.
Источник
[ ОБСУДИТЬ НА ФОРУМЕ ]
promining.net
что делать и как подтвердить
Неподтвержденные транзакции “bitcoin” встречаются все чаще. Связано это с многими факторами, в том числе с ростом желающих заработать на криптовалюте. Какие способы исправления ситуации существуют?
Что такое неподтвержденная транзакция?
Транзакции blockchain.Для того, чтобы понять, что такое неподтвержденные транзакции blockchain, следует разобраться в нюансах их проведения к адресату. Если идти от обратного, от значения этого термина, то подтверждение транзакции – это ее слияние с найденным блоком. Необходимо это подтверждение для предотвращения двойных трат. То есть, неподтвержденная транзакция – та, которая находится в стадии проверки и перехода.
В том случае, когда пользователь совершает любую операцию с криптовалютой, ее на подлинность обязательно необходимо проверить, а затем подтвердить. Проверка происходит на всех возможных узлах, это достаточно сложный процесс. Подтвержденной транзакция считается только в том случае, если наберется 6 блоков и больше.
После того, как верификация пройдена, транзакция попадает в очередь в так называемом мемпуле (Memory Pool), специально отведенной области для ожидания подтверждения операций.
Схема работы блокчейна.Поскольку каждый узел имеет разный RAM, алгоритм проверки и проведения операций также будет разный. Если объем оперативной памяти мемпула близок к объему ОП узла, последний устанавливает минимальный размер комиссии. Те транзакции, комиссия которых была меньше, из узла исключаются, последующие транзакции проходят только в случае применения комиссии, превышающей установленный порог. В случае, когда скорость добычи новых блоков превышает параметры добавления очередной транзакции в мемпул, происходит резкое замедление всей работы системы.
В среднем, на проведение транзакции необходимо от 15 до 60 минут, иногда больше. Однако в том случае, если присутствуют некоторые проблемы, ожидание может растянуться на несколько дней и даже больше, поскольку транзакция в прямом смысле зависают.
Если по истечении 72 часов (иногда больше или меньше) транзакция не включается в блок по умолчанию, биткойны возвращаются в кошелек отправителя.
Количество неподтвержденных транзакций и размер мемпула можно просмотреть на blockchain.info.
Размер мемпула, количество неподтвержденных транзакций.То есть по этим данным можно предположить, что очередь подтверждения транзакции составит 90 блоков.
На сайте blockchain.info можно узнать среднее время подтверждения транзакции, на графике.
Сайт blockchain.info.В конце 2017 года из-за резкого повышения BTC в цене резко увеличилось и количество операций, а неподтвержденных транзакций Bitcoin насчитывалось до 20 тыс.
Каковы причины зависания?
Период обработки операций может затянуться по нескольким причинам. Факторы, предрасполагающие к торможению переводов, следующие:
- Загруженность системы. Такое случается из-за резких скачков стоимости биткойна, что само по себе является еще одной причиной затора транзакций, или по причине большого, критического размера мемпула. По некоторым данным загруженность за последние 2-3 года возросла более, чем в 8 раз.
- Маленькая комиссия. Однако некоторые пользователи сознательно устанавливают низкую комиссию за транзакцию, поскольку переводят мелкие суммы, они готовы ждать.
- Приоритет суммы. Большие размеры транзакций переводятся первыми.
То есть индивидуальному пользователю, отправителю перевода, в некоторых случаях повлиять на последующую ситуацию сложно.
Как исправить ситуацию?
Транзакция криптовалюты.Эксперты предлагают сразу несколько эффективных способов исправления той ситуации, когда транзакция криптовалюты не подтверждена.
Практически всегда есть вариант просто отменить неподтвержденную транзакцию:
- В кошельке следует перейти в отладочную консоль. Если бумажник зашифрован, необходим доступ к нему. Получают его с помощью комбинации команд walletpassphrase <passphrase> – dumpprivkey <адрес транзакции>. Если транзакции многосоставные, следует получить все ключи доступа и экспортировать их.
- Ключ (ключи) необходимо скопировать.
- Удалить кошелек. Можно переименовать файл или переместить его, чтобы заново не скачивать.
- Далее требуется перезапуск клиента, который впоследствии создаст кошелек.
- Ввести приватный ключ, путем комбинации команд importprivkey -<ключ>.
- Новый кошелек не содержит отправленных транзакций, на баланс возвращены средства.
Теперь можно заново создавать транзакции, скорректировав их.
Выборочная замена комиссии
Opt-In RBF.Этот метод доступен не для всех пользователей. Opt-In RBF – опция, доступная только в некоторых кошельках.
Функция заключается в том, чтобы заново отправить транзакцию, но уже с большей комиссией. В обычном режиме новый перевод с увеличенными комиссионными был бы расценен сетью как двойная трата, но, благодаря Opt-In RBF, узлы оповещены о предстоящей новой операции.
Эту функцию поддерживают не все майнеры, но большинство. Однако по причине необходимости дополнительной проверки, перевод будет осуществляться несколько дольше, чем обычная транзакция с высокой комиссией.
Кошельки, поддерживающие выборочную замену комиссии:
- Bitcoin Core;
- Armory;
- Electrum;
- GreenAdress.
Только GreenAdress использует необходимые настройки по умолчанию, в остальных кошельках необходимо задать определенные параметры.
Двойное расходование
Двойная трата (даблспенд) – повтор перевода с одними и теми же параметрами. Чтобы добиться этого, следует сначала убедиться, что транзакция действительно не подтверждена.
Сделать это можно на сайте blockchain.info или других подобных сервисах.
Blockchain.info.Если после проведенного поиска появилась информация «unconfirmed transaction», значит операция ждет подтверждения.
Далее требуется:
- Закрыть кошелек, запустить его заново через командную строку. Если использовали Bitcoin Core, задать параметр zapwallettxes. В некоторых случаях понадобится переименовать или перенести файл mempool.dat.
- Создать новую транзакцию, комиссия которой будет выше предыдущей.
- Для того, чтобы в последствии старая транзакция не подтвердилась, ведь она все еще находится в системе, требуется задать тот же размер входа для нового перевода, что и был в старом. Плюс необходимо выбрать дополнительно еще входы, чтобы она в общей сложности с запасом перекрывала сумму старой транзакции с комиссией.
- Завершить отправку.
Некоторые специалисты склонны считать, что в приоритете будет все равно та транзакция, комиссия которой выше предыдущей, поэтому дополнительные действия с полной установкой прошлых параметров, не целесообразны.
Использование CPFP
CPFP.Такой способ подойдет для получателя транзакции, для отправителя он доступен только в том случае, если транзакция прошла со сдачей. Это возможно в тех ситуациях, когда майнеры вместо одной транзакции с большой комиссией берут группу переводов, у которых в сумме комиссионные будут выше.
Child Pays for Parent (CPFP) – метод, суть которого в трате одного выхода неподтвержденной транзакции и установки такой комиссии, которой бы хватило для включения двух таких в блок.
Действовать необходимо так:
- В кошельке в настройках зайти во вкладку «Бумажник», поставить галочки напротив «Включить управление входами», «Тратить неподтвержденную сдачу».
- Создать новый перевод, входом которого указать выход неподтвержденного. Можно указать «сдачу».
- Рассчитать размер корректной комиссии, учитывая две транзакции.
Таким образом для обработки будут доступны сразу две транзакции, их проверят совместно. Майнеры получат максимальную комиссию, пользователь – включение перевода в блок.
Динамическое изменение комиссии
Динамическое изменение комиссии – опция кошелька, которая в автоматическом режиме избавит отправителя от зависания транзакции.
То есть кошелек самостоятельно в зависимости от загруженности сети определяет допустимую для успешного проведения транзакции комиссионную плату.
В том случае, если пользователь изначально установил комиссию меньше необходимой на данный момент, умный кошелек оповестит его об этом и предложит увеличить сумму.
Поддерживают функцию, к примеру, такие кошельки:
- Bitcoin Core;
- Ledger;
- Electrum; Airbitz;
- GreenAddress.
Бумажники могут как снизить, так и увеличить комиссию. В том случае, если даже при условии правильно выставленных параметров кошелька, транзакция задерживается, следует обновить имеющийся кошелек.
Ускорение транзакций
Аntpool.com.Некоторые предприимчивые компании создавали так называемые «ускорители транзакций», когда отправитель просто указывал хеш, и майнеры пула обрабатывали ее. Наиболее распространенными считаются antpool.com, viabtc.com. Однако по некоторым данным, в настоящее время осуществляет эту функцию только viabtc.com.
Используя ViaBTC, необходимо ввести id транзакции, которая зависла, и капчу, в соответствующие окна. Система распознает влияние ускорителя и поставит транзакцию в расшифрованный блок, добытый пулом.
Также предусмотрены такие способы повышения скорости транзакций:
- Повышение комиссии. Допустимо превышение от 0,0002 ВТС.
- Перевод больших объемов. Гораздо эффективнее будет перевод единожды, но большой суммы, чем несколько мелких транзакций.
- Использование специализированных платформ, например, coinbase.com, здесь сохраняются приватные ключи и продавцов, и покупателей, а перевод осуществляется в пределах платформы. Система блокчейн при том не задействована.
- Использование кошельков с функцией мультиподписи. Мультиподпись, например, у GreenAddress, будет подтверждением надежного перевода. Система возьмет в блок такую транзакцию гораздо быстрее.
Некоторые специалисты советуют использовать открытые транзакции, поскольку такие переводы проверить проще и быстрее. Однако об анонимности перевода можно забыть.
Как защититься от зависаний?
Сервис.Для того, чтобы предотвратить зависание, следует выполнять всегда несколько простых правил.
Требуется:
- Выставлять правильную комиссию. В том случае, если ожидание невозможно, не следует экономить. Приблизительную стоимость комиссии относительно размера перевода можно узнать на сервисах вроде blockchain.info.
- Использовать кошельки с динамическим изменением комиссии, прислушиваться к их предупреждениям о целесообразности повышения комиссионных.
- Включать опцию выборочной замены комиссии. Не помешает и функция мультиподписи. Если кошелек на данный момент не поддерживает представленных опций, следует задуматься о его замене или обновлении.
- Использовать ресурсы, имеющие автономную систему транзакций.
Выполняя эти простые правила, можно существенно сократить время ожидания подтверждения транзакций до минимума.
crypta.guru
Неподтвержденная транзакция на blockchain: что делать?
Число платежей внутри сети Биткоин с каждым днем растет. Это значит, что блоки, в которые отправляются данные о транзакциях, заполняются быстрее. При этом размер блока в 1 мБ не увеличивается. Как результат – задержка платежей, которые выстраиваются в длинную очередь для получения двух подтверждений (согласно условиям системы).
В последнее время операции с ВТС становятся все более медленными (иногда их приходится ждать до нескольких дней), неудобства для пользователей – более ощутимыми.
Неподтвержденная транзакция: определение
Неподтвержденным считается платеж, который был инициирован, но не отправлен в блок.
Обработка платежных операций в сети ВТС осуществляется в процессе майнинга. При этом действует система приоритетов: чем больше сумма комиссионных за 1 Б платежа, тем скорее она добавляется в цепочку блоков. Поэтому без подтверждения, как правило, оказываются операции, при отправке которых была проставлена минимальная комиссия.
Статус платежа и его путь всегда можно отследить на ресурсе blockchain.info (ввести TXID в поисковое поле). Пометка цифрой «2» и голубой цвет кнопки Cofirmations в блокчейне означает, что платежная операция подтверждена. У неподтвержденных платежей красный цвет кнопки и пометка Unconfirmed Transaction.
В среднем платежи с высокими комиссионными проходят за 10-30 минут, с низкими – до 72 часов.
Подробнее о выборе комиссионных
Почти во всех криптовалютных кошельках существует понятие рекомендованной комиссии (алгоритм сети подбирает ее самостоятельно). Это значение может быть и слишком низким, и слишком высоким.
Следует учитывать, что величина комиссионного сбора зависит от размера платежа, а не от пересылаемой суммы. Пересылка 100 ВТС может стоить меньше, чем пересылка 0,001 ВТС. Размер транзакции находится в прямой зависимости от числа взаимосвязанных платежных операций. К примеру, если Александр получил по одному ВТС от Ивана и Михаила, а затем переслал два ВТС Владимиру, то в этой операции задействуется четыре адреса, а это примерно 600 добавочных байт.
Но если попробовать добраться до первопричины проблемы неподтверждений, станет ясно, что это результат недостаточного размера блоков. Сеть Биткоин просто не справляется с постоянно увеличивающимся количеством платежей.
При размере блока 1 мБ размер обычной транзакции составляет примерно 370 Б. На подтверждение каждого блока уходит около 10 мин, значит, за это время должно подтверждаться 2 600 операций. В действительности их гораздо больше.
На том же ресурсе Блокчейн Инфо можно увидеть mempool операций, ожидающих подтверждения.
Общий размер транзакций составляет 100 мБ. Это значит, что в следующие 10 мин. подтвердится не больше 1 % всех ожидающих платежей, а на обработку остальных уйдет порядка 17 ч. И это с условием, что других платежей в это время в сети проводиться не будет.
Решить проблему раз и навсегда можно только увеличением блока. С этой целью был инициирован Seg wit – оптимизация памяти для сохранения информации о платежах и подготовка сети к последующему расширению блока через софтворк. Segwit 2x – hardfork и радикальное разделение blockchain с расширением объема блоков до двух мБ – после долгих дискуссий решено было отменить.
Что будет с биткоинами, которые зависли из-за неподтверждения?
Волноваться о деньгах нет причин, они никуда не исчезнут. В ситуации с неподтвержденным платежом можно действовать двумя способами:
- ожидать, пока операция подтвердится – периодически просматривать статус на сайте blockchain.info;
- принимать меры, чтобы она прошла скорее.
На некоторых ресурсах можно посмотреть приблизительное время подтверждения, но оно обычно имеет мало общего с действительностью. Можно рассчитать время, воспользовавшись информацией в строке FeeperByte. Далее зайти на сайт btc.com во вкладку unconfirmed transactions, где указана усредненная цена одного байта и приблизительное время прохождения транзакции с разным размером комиссионных.
Ускорить платеж можно несколькими способами:
- Double Spend;
- Replace-by-free;
- CPFR;
- ускорители.
Далее – подробнее о каждом способе.
Двойная трата (double spend)
Актуально для пользователей кошельков Biitcoin Kots и Bitcoin Core. Рассмотрим план действий на примере Bit Core.
Сначала нужно закрыть кошелек, затем убрать из каталога файл memoral.dat и запустить его заново в CMD посредством строки zap wallet etettxes. После этого провести платеж заново, но уже с более высокой комиссией. Для этого нужно «перехватить» неподтвержденную транзакцию путем объединения ее с новой: в Bitcoin Core в разделе Input выбрать старую операцию и добавить в нее вход с другой операции, чтобы открыть комиссионные.
CPFP
Способ рассчитан на случаи, при которых пользователи инициируют отправку биткоинов, еще фактически не полученных ими от другого пользователя из-за очереди на подтверждение, т. е. при наличии двух взаимосвязанных неподтвержденных операций. В этом случае отправитель второго платежа должен заплатить комиссию дважды: за свою транзакцию и транзакцию, отправленную ему.
Для этого перейти в кошелек (Wallet), отметить разделы Enablecoin features и Spend unconfirmed change, нажать кнопку отправки.
Вернуться в раздел Inputs, указать свой адрес как адрес получателя, ввести сумму ранее отправленного платежа и отметить ее галочкой amount или subtract, установить размер комиссионных через Custom.
То же самое, но проще можно выполнить через бумажник Электрум, в котором есть опция replace by free. Но она сработает только если при первой отправке была проставлена галочка Repaceable.
Ускорители
Ускорением платежей занимаются майнинг-пулы Ант пул, Виа ВТС и др. Необходимо зайти в раздел Tools на одном из таких сервисов, выбрать вкладку Transaction Accelerator, указать номер платежа и ввести капчу. Правда, данный способ помогает не всегда. В Telegram работает бот для ускорения платежей –- @FastTXbot.
Как сделать, чтобы платежи не зависали?
Прежде всего – понять, от чего зависит скорость подтверждения.
Зависит: | Не зависит: |
Время выполнения операции | Сумма платежа |
Комиссионные Путь отправленных ВТС | Кошелек |
Пересылка 10 ВТС, полученных десятью платежами по одному ВТС, будет стоить дороже, чем пересылка ста ВТС, полученных с одного адреса. Таким образом, чем больше адресов, тем выше комиссионные. При необходимости отправки BTC нескольким адресатам целесообразно объединить платежи в один и затем разослать их через Input.
Важнейший показатель – размер комиссионных за один байт. Перед отправкой ВТС следует посмотреть показатели mempool и величину средней комиссии в системе (например, на Bitcoin Fees).
Если в мемпуле пусто, тогда даже платеж с минимальной комиссией пройдет оперативно – так действует извечный закон предложения и спроса. Майнеры работают с любыми платежами, поскольку выгодных предложений у них недостаточно. Лучшее время для переводов – когда китайцы и японцы спят.
Правильное обращение с кошельком, мемпулом и информацией о размере комиссионных позволит быстро проводить операции и одновременно экономить.
Резюме
Неподтвержденная транзакция – та, которая по тем или иным причинам не попала в блок. Чтобы ускорить ее подтверждение, можно использовать DoubleSpend, CPFP, Replace-by-fee или ускорители. Чтобы обезопасить себя от подобных ситуаций, следует правильно выставлять размер комиссионных и проводить операции в определенное время.
coinmania.com
Транзакции, часть 1 / Habr
Привет, Habr! Представляю вашему вниманию перевод статьи «Building Blockchain in Go. Part 4: Transactions 1».Содержание
- Blockchain на Go. Часть 1: Прототип
- Blockchain на Go. Часть 2: Proof-of-Work
- Blockchain на Go. Часть 3: Постоянная память и интерфейс командной строки
- Blockchain на Go. Часть 4: Транзакции, часть 1
- Blockchain на Go. Часть 5: Адреса
- Blockchain на Go. Часть 6: Транзакции, часть 2
- Blockchain на Go. Часть 7: Сеть
Вступление
Транзакции являются сердцем Биткоина, и единственная цель цепи блоков — это хранить транзакции безопасным и надежным способом, чтобы никто не смог модифицировать их после создания. В этой статье мы начинаем работу над реализацией механизма транзакций. Но поскольку это довольно большая тема, я разбил ее на две части: в этой части мы реализуем общий механизм, а во второй части мы детально разберем весь остальной функционал.
В данной статье мы будем практически полностью редактировать весь наш предыдущий код, поэтому не имеет смысла описывать каждое изменение, все изменения вы можете посмотреть тут.
Ложки нет
Если Вы когда-то разрабатывали веб-приложение, то для реализации платежей, вероятно, создавали в базе данных две эти таблицы:
учетные записи
и транзакции
. Учетная запись хранила информацию о пользователе, включая его персональную информацию и баланс, а транзакция хранит информацию о переводе денег с одной учетной записи на другую. В Биткоине платежи осуществляются совершенно по-другому:- Нет аккаунтов.
- Нет балансов.
- Нет адресов.
- Нет монет.
- Нет отправителей и получателей.
Поскольку блокчейн является публичной и открытой базой данных, мы не хотим хранить конфиденциальную информацию о владельцах кошельков. Монеты не хранятся на счетах. Транзакции не переводят деньги с одного адреса на другой. Нет полей и атрибутов, которые содержат баланс счета. Есть только транзакции. Но что внутри?
Биткоин транзакция
Транзакция представляет собой комбинацию входов и выходов:
type Transaction struct {
ID []byte
Vin []TXInput
Vout []TXOutput
}
Входы новой транзакции ссылаются на выходы предыдущей транзакции (есть исключение, о котором мы поговорим ниже). Выходы — место, где хранятся монеты. Следующая диаграмма демонстрирует взаимосвязь транзакций:
Заметьте:
- Есть выходы, которые не связаны с входами.
- В одной транзакции входы могут ссылаться на выходы нескольких транзакций.
- Вход всегда должен ссылаться на выход.
В этой статье мы будем использовать слова «деньги», «монеты», «потратить», «отправить», «учетная запись» и т.д. Но в Биткоине таких концепций нет. Транзакции — это просто заблокированное скриптом значение, которое может разблокировать лишь тот, кто его заблокировал.
Выходы транзакций
Начнем с выходов:
type TXOutput struct {
Value int
ScriptPubKey string
}
Фактически, это выходы, которые хранят «монеты» (обратите внимание на поле
Value
выше). Средства блокируются особым пазлом, которая хранится в ScriptPubKey
. Внутри Bitcoin использует скриптовый язык Script
, который используется для определения логики блокировки и разблокировки выходов. Язык довольно примитивен (это делается намеренно, чтобы избежать возможных взломов), но мы не будем обсуждать его подробно. Вы можете прочитать подробнее о нем здесь.В Биткоине поле значений хранит количество сатоши, а не количество BTC. 1 сатоши = 0.00000001 BTC. Таким образом, это самая маленькая единица валюты в Биткойне (как, к примеру, цент).Поскольку у нас нет адресов, пока что мы будем избегать всей связанной с сценариями логики. Для начала
ScriptPubKey
будет хранить произвольную строку (пользовательский адрес кошелька).Кстати, наличие такого языка сценариев означает, что Биткоин можно использовать как платформу смарт-контрактов.Одна важная вещь которую нужно знать о выходах, это то, что они неделимы, а это означает, что вы не можете ссылаться на часть своего значения. Когда выход ссылается на новую транзакцию, он расходуется полностью. И если его значение больше, чем требуется, генерируется разница и новое значение отправляется обратно отправителю. Это похоже на реальную ситуацию в мире, когда вы платите, скажем, $5 долларов за то, что стоит $1, и получаете сдачу $4.
Входы транзакций
Рассмотрим вход:
type TXInput struct {
Txid []byte
Vout int
ScriptSig string
}
Как упоминалось ранее, вход ссылается на предыдущий выход:
Txid
хранит идентификатор такой транзакции, а Vout
хранит индекс выхода данной транзакции. ScriptSig
— это скрипт, который предоставляет данные, которые будут в дальнейшем использоваться в скрипте ScriptPubKey
. Если данные верны, выход можно разблокировать, а его значение можно использовать для генерации новых выходов; если же это не так, вход не может ссылаться на выход. Этот механизм гарантирует, что пользователи не могут тратить монеты, принадлежащие другим людям.Опять же, поскольку у нас все еще нет адресов, ScriptSig
сохранит только произвольный пользовательский адрес кошелька. Мы создадим открытый ключ и проверку подписи в следующей статье.
Подведем итог. Выходы — это место, в котором хранятся «монеты». Каждый выход имеет сценарий разблокировки, который определяет логику разблокировки выхода. Каждая новая транзакция должна иметь как минимум один вход и выход. Вход ссылается на результат предыдущей транзакции и предоставляет данные (поле ScriptSig
), которые используются в сценарии разблокировки выхода, чтобы разблокировать его и использовать его значение для создания новых выходов.
Но что пришло первым: входы или выходы?
Яйцо
В Биткоине, яйцо появилось до цыпленка. Логика inputs-referencing-outputs представляет собой классическую ситуацию «курица или яйцо»: входы производят выходы, а выходы позволяют создавать входы. И в Биткоине выходы всегда появляются перед входами.
Когда майнер начинает майнить блок, он добавляет к нему coinbase транзакцию. Транзакция coinbase — это особый тип транзакции, который не требует ранее существующих выходов. Он создает выходы (т. е. «Монеты») из ниоткуда. Яйцо без курицы. Это награда, которую майнеры получают за добычу новых блоков.
Как вы знаете, в начале цепи есть блок генезиса. Именно этот блок генерирует самый первый выход в цепочке блоков. И никаких предыдущих выходов не требуется, поскольку нет предыдущих транзакций и нет никаких выходов.
Давайте создадим coinbase транзакцию:
func NewCoinbaseTX(to, data string) *Transaction {
if data == "" {
data = fmt.Sprintf("Reward to '%s'", to)
}
txin := TXInput{[]byte{}, -1, data}
txout := TXOutput{subsidy, to}
tx := Transaction{nil, []TXInput{txin}, []TXOutput{txout}}
tx.SetID()
return &tx
}
В coinbase транзакции имеется только один вход. В нашей реализации
Txid
пуст, а Vout
равен -1. Кроме того, транзакция coinbase не хранит скрипт в ScriptSig
. Вместо этого там хранятся произвольные данные.В биткойне самая первая coinbase транзакция содержит следующее сообщение: “The Times 03/Jan/2009 Chancellor on brink of second bailout for banks”. Вы сами можете на это посмотреть.
subsidy
— это сумма вознаграждения. В Биткоине это число не хранится нигде и рассчитывается только на основе общего количества блоков: количество блоков делится на 210000. Майнинг блока генезиса приносит 50 BTC, и каждые 210000 блоков награда уменьшается вдвое. В нашей реализации мы будем хранить вознаграждение как константу (по крайней мере на данный момент).Сохранение транзакций в цепи
С этого момента каждый блок должен хранить как минимум одну транзакцию, и должно стать невозможным майнить блоки без транзакции. Теперь, удалим поле date из Block и вместо этого теперь будем хранить транзакции.
type Block struct {
Timestamp int64
Transactions []*Transaction
PrevBlockHash []byte
Hash []byte
Nonce int
}
NewBlock
и NewGenesisBlock
также должны быть соответствующим образом измененыfunc NewBlock(transactions []*Transaction, prevBlockHash []byte) *Block {
block := &Block{time.Now().Unix(), transactions, prevBlockHash, []byte{}, 0}
...
}
func NewGenesisBlock(coinbase *Transaction) *Block {
return NewBlock([]*Transaction{coinbase}, []byte{})
}
Теперь создадим функцию
CreateBlockchain
func CreateBlockchain(address string) *Blockchain {
...
err = db.Update(func(tx *bolt.Tx) error {
cbtx := NewCoinbaseTX(address, genesisCoinbaseData)
genesis := NewGenesisBlock(cbtx)
b, err := tx.CreateBucket([]byte(blocksBucket))
err = b.Put(genesis.Hash, genesis.Serialize())
...
})
...
}
Теперь функция принимает адрес, который получит вознаграждение за добычу блока генезиса.
Proof-of-Work
Алгоритм Proof-of-Work должен рассматривать транзакции, хранящиеся в блоке, чтобы гарантировать согласованность и надежность цепи как хранилища транзакции. Итак, теперь мы должны изменить метод
ProofOfWork.prepareData
:func (pow *ProofOfWork) prepareData(nonce int) []byte {
data := bytes.Join(
[][]byte{
pow.block.PrevBlockHash,
pow.block.HashTransactions(), // This line was changed
IntToHex(pow.block.Timestamp),
IntToHex(int64(targetBits)),
IntToHex(int64(nonce)),
},
[]byte{},
)
return data
}
Вместо
pow.block.Data
теперь мы добавим pow.block.HashTransactions ()
:func (b *Block) HashTransactions() []byte {
var txHashes [][]byte
var txHash [32]byte
for _, tx := range b.Transactions {
txHashes = append(txHashes, tx.ID)
}
txHash = sha256.Sum256(bytes.Join(txHashes, []byte{}))
return txHash[:]
}
Повторюсь, мы используем хеширование как механизм обеспечения уникального представления данных. Мы хотим, чтобы все транзакции в блоке были однозначно идентифицированы с помощью одного хеша. Чтобы достичь этого, мы получаем хеши каждой транзакции, объединяем их и получаем хеш объединенных комбинаций.
Биткоин использует более сложную технику: он представляет все транзакции, содержащиеся в блоке как дерево хешей, и использует корневой хеш дерева в системе Proof-of-Work. Такой подход позволяет быстро проверить, содержит ли блок определенную транзакцию, имеющую только корневой хеш и без загрузки всех транзакций.Проверим правильность работы:
$ blockchain_go createblockchain -address Ivan
00000093450837f8b52b78c25f8163bb6137caf43ff4d9a01d1b731fa8ddcc8a
Done!
Отлично! Мы получили свою первую награду. Но как нам проверить баланс?
Непотраченные выходы
Нам нужно найти все непотраченные выходы (UTXO). Это означает, что эти выходы не ссылались ни на какие входы. На приведенной выше диаграмме это:
- tx0, output 1;
- tx1, output 0;
- tx3, output 0;
- tx4, output 0.
Конечно, когда мы проверяем баланс, нам не нужны они все, нужны только те, которые могут быть разблокированы ключом, которым мы владеем (в настоящее время у нас нет реализованных ключей и вместо них будут использоваться пользовательские адреса). Для начала, давайте определим методы блокировки-разблокировки на входах и выходах:
func (in *TXInput) CanUnlockOutputWith(unlockingData string) bool {
return in.ScriptSig == unlockingData
}
func (out *TXOutput) CanBeUnlockedWith(unlockingData string) bool {
return out.ScriptPubKey == unlockingData
}
Здесь мы просто сравниваем поля из
ScriptSig
с unlockingData
. В следующей статье мы их улучшим, после того, как реализуем адреса, основанные на закрытых ключах.Следующий шаг — поиск транзакций с непотраченными выходами — это уже более сложно:
func (bc *Blockchain) FindUnspentTransactions(address string) []Transaction {
var unspentTXs []Transaction
spentTXOs := make(map[string][]int)
bci := bc.Iterator()
for {
block := bci.Next()
for _, tx := range block.Transactions {
txID := hex.EncodeToString(tx.ID)
Outputs:
for outIdx, out := range tx.Vout {
// Was the output spent?
if spentTXOs[txID] != nil {
for _, spentOut := range spentTXOs[txID] {
if spentOut == outIdx {
continue Outputs
}
}
}
if out.CanBeUnlockedWith(address) {
unspentTXs = append(unspentTXs, *tx)
}
}
if tx.IsCoinbase() == false {
for _, in := range tx.Vin {
if in.CanUnlockOutputWith(address) {
inTxID := hex.EncodeToString(in.Txid)
spentTXOs[inTxID] = append(spentTXOs[inTxID], in.Vout)
}
}
}
}
if len(block.PrevBlockHash) == 0 {
break
}
}
return unspentTXs
}
Поскольку транзакции хранятся в блоках, мы должны проверять каждый блок в цепочке. Начнем с выходов:
if out.CanBeUnlockedWith(address) {
unspentTXs = append(unspentTXs, tx)
}
Если выход был заблокирован по тому же адресу, мы ищем непотраченные выходы, которые мы хотим. Но перед тем, как принять его, нам нужно проверить, был ли на выходе уже указан вход:
if spentTXOs[txID] != nil {
for _, spentOut := range spentTXOs[txID] {
if spentOut == outIdx {
continue Outputs
}
}
}
Мы пропускаем те, на которые уже ссылаются входы (их значения были перенесены на другие выходы, поэтому мы не можем их подсчитать). После проверки выходов мы собираем все входы, которые могут разблокировать выходы, заблокированные с предоставленным адресом (это не относится к coinbase транзакциям, поскольку они не разблокируют выходы):
if tx.IsCoinbase() == false {
for _, in := range tx.Vin {
if in.CanUnlockOutputWith(address) {
inTxID := hex.EncodeToString(in.Txid)
spentTXOs[inTxID] = append(spentTXOs[inTxID], in.Vout)
}
}
}
Функция возвращает список транзакций, содержащих непотраченные выходы. Для расчета баланса нам нужна еще одна функция, которая берет транзакции и возвращает только выходы:
func (bc *Blockchain) FindUTXO(address string) []TXOutput {
var UTXOs []TXOutput
unspentTransactions := bc.FindUnspentTransactions(address)
for _, tx := range unspentTransactions {
for _, out := range tx.Vout {
if out.CanBeUnlockedWith(address) {
UTXOs = append(UTXOs, out)
}
}
}
return UTXOs
}
Готово! Теперь реализуем команду
getbalance
func (cli *CLI) getBalance(address string) {
bc := NewBlockchain(address)
defer bc.db.Close()
balance := 0
UTXOs := bc.FindUTXO(address)
for _, out := range UTXOs {
balance += out.Value
}
fmt.Printf("Balance of '%s': %d\n", address, balance)
}
Баланс счета — это сумма значений всех непотраченных выходов, заблокированных адресом учетной записи.
Давайте проверим наш баланс после добычи блока генезиса:
$ blockchain_go getbalance -address Ivan
Balance of 'Ivan': 10
Это наши первые монеты!
Отправка монет
Теперь мы хотим отправить несколько монеты кому-то другому. Для этого нам нужно создать новую транзакцию, поместить ее в блок и обработать его. До сих пор мы реализовали только транзакцию coinbase (которая является специальным типом транзакций), теперь нам нужна общая транзакция:
func NewUTXOTransaction(from, to string, amount int, bc *Blockchain) *Transaction {
var inputs []TXInput
var outputs []TXOutput
acc, validOutputs := bc.FindSpendableOutputs(from, amount)
if acc < amount {
log.Panic("ERROR: Not enough funds")
}
// Build a list of inputs
for txid, outs := range validOutputs {
txID, err := hex.DecodeString(txid)
for _, out := range outs {
input := TXInput{txID, out, from}
inputs = append(inputs, input)
}
}
// Build a list of outputs
outputs = append(outputs, TXOutput{amount, to})
if acc > amount {
outputs = append(outputs, TXOutput{acc - amount, from}) // a change
}
tx := Transaction{nil, inputs, outputs}
tx.SetID()
return &tx
}
Прежде чем создавать новые выходы, нам для начала нужно найти все непотраченные выходы и убедиться, что в них есть достаточное количество монет. Это метод
FindSpendableOutputs
. После этого для каждого найденного выхода создается вход, ссылающийся на него. Затем мы создаем два выхода:- Тот, который заблокирован с адресом получателя. Это фактическая передача монет на другой адрес.
- Тот, который заблокирован с адресом отправителя. Это разница. Он создается только тогда, когда непотраченные выходы имеют большее значение, чем требуется для новой транзакции. Помните: выходы неделимы.
Метод
FindSpendableOutputs
основан на методе FindUnspentTransactions
, который мы определили ранее:func (bc *Blockchain) FindSpendableOutputs(address string, amount int) (int, map[string][]int) {
unspentOutputs := make(map[string][]int)
unspentTXs := bc.FindUnspentTransactions(address)
accumulated := 0
Work:
for _, tx := range unspentTXs {
txID := hex.EncodeToString(tx.ID)
for outIdx, out := range tx.Vout {
if out.CanBeUnlockedWith(address) && accumulated < amount {
accumulated += out.Value
unspentOutputs[txID] = append(unspentOutputs[txID], outIdx)
if accumulated >= amount {
break Work
}
}
}
}
return accumulated, unspentOutputs
}
Метод выполняет обход по всем неизрасходованным транзакциям и накапливает их значения. Когда накопленное значение больше или равно сумме, которую мы хотим передать, обход останавливается и возвращает накопленные значения и выходные индексы, сгруппированные по идентификаторам транзакций. Нам не надо брать больше, чем мы собираемся потратить.
Теперь мы можем изменить метод Blockchain.MineBlock
:
func (bc *Blockchain) MineBlock(transactions []*Transaction) {
...
newBlock := NewBlock(transactions, lastHash)
...
}
Наконец, создадим команду
send
:func (cli *CLI) send(from, to string, amount int) {
bc := NewBlockchain(from)
defer bc.db.Close()
tx := NewUTXOTransaction(from, to, amount, bc)
bc.MineBlock([]*Transaction{tx})
fmt.Println("Success!")
}
Отправка монет означает создание транзакции и добавление ее в цепь блоков посредством майнинга блока. Но Биткоин не делает это сразу (как и мы). Вместо этого он помещает все новые транзакции в пул памяти (или mempool), и когда майнер готов к добыче блока, он берет все транзакции из mempool и создает блок-кандидат. Транзакции становятся подтвержденными только тогда, когда блок, содержащий их, добывается и добавляется к цепи блоков.
Давайте проверим, как работает отправка монет:
$ blockchain_go send -from Ivan -to Pedro -amount 6
00000001b56d60f86f72ab2a59fadb197d767b97d4873732be505e0a65cc1e37
Success!
$ blockchain_go getbalance -address Ivan
Balance of 'Ivan': 4
$ blockchain_go getbalance -address Pedro
Balance of 'Pedro': 6
Отлично! Теперь давайте создадим больше транзакций и убедимся, что отправка с нескольких выходов работает правильно:
$ blockchain_go send -from Pedro -to Helen -amount 2
00000099938725eb2c7730844b3cd40209d46bce2c2af9d87c2b7611fe9d5bdf
Success!
$ blockchain_go send -from Ivan -to Helen -amount 2
000000a2edf94334b1d94f98d22d7e4c973261660397dc7340464f7959a7a9aa
Success!
Теперь монеты Хелен заблокированы на двух выходах: один выход от Педро и один от Ивана. Отправим кому-нибудь еще:
$ blockchain_go send -from Helen -to Rachel -amount 3
000000c58136cffa669e767b8f881d16e2ede3974d71df43058baaf8c069f1a0
Success!
$ blockchain_go getbalance -address Ivan
Balance of 'Ivan': 2
$ blockchain_go getbalance -address Pedro
Balance of 'Pedro': 4
$ blockchain_go getbalance -address Helen
Balance of 'Helen': 1
$ blockchain_go getbalance -address Rachel
Balance of 'Rachel': 3
Выглядит хорошо! Теперь давайте протестируем исключения:
$ blockchain_go send -from Pedro -to Ivan -amount 5
panic: ERROR: Not enough funds
$ blockchain_go getbalance -address Pedro
Balance of 'Pedro': 4
$ blockchain_go getbalance -address Ivan
Balance of 'Ivan': 2
Заключение
Уф! Это было нелегко, но теперь у нас есть транзакции! Хотя, некоторые ключевые особенности Биткоин-подобной криптовалюты отсутствуют:
- Адреса. Пока у нас нет адресов на основе приватного ключа.
- Награды. Майнить блоки абсолютно невыгодно!
- UTXO. Получение баланса требует сканирования всей цепочки блоков, что может занять очень много времени, когда есть очень много блоков. Кроме того, это займет очень много времени, если мы захотим подтвердить последующие транзакции. UTXO предназначен для решения этих проблем и для быстрой работы с транзакциями.
- Mempool. Здесь хранятся транзакции, прежде чем они будут упакованы в блок. В нашей текущей реализации блок содержит только одну транзакцию, и это очень неэффективно.
Ссылки
- Full source codes
- Transaction
- Merkle tree
- Coinbase
habr.com