Далее мы рассмотрим механизм Биткойна более детально.
Мы рассмотрим реальные структуры данных и реальные скрипты.
Для начала вспомним, где мы остановились в прошлый раз.
Механизм консенсуса биткойнов дает нам реестр только для добавления, поэтому мы можем только записывать структуры данных, и как только данные записываются, они существуют навсегда.
И есть децентрализованный протокол для установления консенсуса относительно значений этого реестра.
И есть майнеры, которые выполняют этот протокол и которые проверяют транзакции, все вместе гарантируя, что транзакции хорошо сформированы, что нет двойных расходов, и в конечном итоге, что этот реестр и сеть могут функционировать как валюта.
И все потому, что мы предположили, что эта валюта может мотивировать этих майнеров.
Теперь, давайте в деталях рассмотрим, что представляет собой транзакция в биткойне, его центральная часть.
На данный момент мы будем использовать упрощенную модель реестра.
Вместо блоков предположим, что в реестр добавляются отдельные транзакции по одной за раз.
Как мы можем построить валюту на основе такой книги или реестра?
Первая модель, о которой вы могли бы подумать, которая на самом деле является ментальной моделью, которую многие люди используют для понимания того, как Биткойн работает, заключается в том, что у вас есть система на основе учетной записи.
Вы можете добавить некоторые транзакции, которые создают новые монеты и передают их кому-либо.
А затем позже вы можете эти монеты передавать дальше.
Транзакция будет содержать что-то вроде «мы передаем 17 монет от Алисы к Бобу», и эта транзакия будет подписана Алисой.
И эта информация о транзакции будет содержаться в книге.
В этом примере, после того как Алиса получила 25 монет в первой транзакции, затем передает 17 монет Бобу во второй транзакции, и у нее осталось еще 8 биткойнов на ее счете.
Недостатком этого способа ведения реестра является то, что любой, кто хочет определить, действительно ли транзакция валидна, должен будет отслеживать эти остатки на счетах.
В этом примере, что нужно сделать, чтобы понять, есть ли у Алисы 15 монет, которые она пытается передать Дэвиду?
Для этого вам нужно будет просмотреть всю книгу назад во времени, чтобы увидеть каждую транзакцию, относящуюся к Алисе, и вычислить ее баланс на момент, когда она пытается передать 15 монет Дэвиду.
Конечно, мы можем сделать это немного более эффективно с помощью дополнительной структуру данных, которая отслеживает баланс Алисы после каждой транзакции.
Но это потребует большого количества дополнительного обслуживания, кроме обслуживания самой книги.
Поэтому Bitcoin не использует модель на основе учетной записи.
Вместо этого Bitcoin использует книгу, которая просто отслеживает транзакции, подобные ScroogeCoin.
Транзакции указывают количество входов и количество выходов.
Вы можете думать о входах как о монетах, которые потребляются и которые были созданы в предыдущей транзакции, и о выходах как о создаваемых монет.
Для транзакций, в которых создаются совершенно новые монеты, нет монет, которые потребляются.
Каждая транзакция имеет уникальный идентификатор.
Выходы индексируются, начиная с 0.
В этом примере, первая транзакция не имеет входа, потому что эта транзакция создает новые монеты, и у нее есть выход из 25 монет, отправляемых Алисе.
Кроме того, поскольку это транзакция, в которой создаются новые монеты, здесь подпись не требуется.
Теперь предположим, что Алиса хочет отправить некоторые из этих монет Бобу.
Для этого она создает новую транзакцию, вторую транзакцию в нашем примере.
В транзакции она должна явно ссылаться на предыдущую транзакцию, в которой эти монеты поступили к ней.
Здесь она ссылается на выход 0 транзакции 1 (единственный выход транзакции 1), который присвоил Алисе 25 битконов.
Она также должна указать выходные адреса в этой транзакции.
В этом примере Алиса указывает два выхода, 17 монет Бобу и 8 монет Алисе.
И, конечно же, эта транзакция подписывается Алисой, так что мы знаем, что Алиса разрешает эту транзакцию.
Почему Алиса должна отправить деньги самой себе в этом примере?
Так как монеты являются неизменяемыми, в биткойне весь вывод транзакции должен потребляться другой транзакцией.
То есть транзакция должна быть самодостаточной, чтобы не калькулировать балансы.
Алиса хочет заплатить Бобу только 17 биткойнов, но выход, который у нее есть, стоит 25 биткойнов.
Поэтому ей нужно создать еще один выход, где 8 биткойнов отправляются обратно ей.
Это может отличаться от адреса, которому принадлежат 25 биткойнов, но он должен принадлежать ей. Это называется изменение адреса или change address.
Когда новая транзакция добавляется в реестр, как можно легко проверить, что она является валидной?
В нашем примере нам нужно найти выход транзакции, на который ссылается Алиса, и убедиться, что он имеет значение 25 биткойнов и что он еще не был потрачен.
Найти выход транзакции легко, так как мы используем хэш указатели.
Чтобы убедиться, что этот выход не был потрачен, нам нужно отсканировать цепочку блоков между указанной транзакцией и последним блоком.
Нам не нужно проходить весь путь назад к началу цепочки блоков, и это не требует хранения каких-либо дополнительных структур данных, хотя, как мы увидим, дополнительные структуры данных ускорят работу.
Так как транзакции могут иметь много входов и много выходов, разделять и объединять значения легко.
Например, Боб получил деньги в двух разных транзакциях – 17 биткойнов в одной и 2 биткойна в другой.
Боб может сказать, что хотел бы иметь одну транзакцию, которую он может потратить позже, где у него будут все 19 биткойнов.
Сделать это легко – он создает транзакцию с двумя входами и одним выходом, причем выходной адрес принадлежит ему.
Это позволяет ему консолидировать эти две транзакции.
Также, легко сделать и совместные платежи.
Предположим, Кэрол и Боб оба хотят заплатить Дэвиду.
Они могут создать транзакцию с двумя входами, которые принадлежат разным людям, и одним выходом.
И единственное отличие от предыдущего примера состоит в том, что, поскольку два выхода из предыдущих транзакций, которые здесь заявляются, относятся к разным адресам, для новой транзакции потребуется две отдельные подписи: одна – Кэрол, а другая – Боба.
Концептуально это все, что связано с транзакцией биткойнов.
Теперь посмотрим, как она представлена на низком уровне в биткойне.
В конечном счете, каждая структура данных, которая отправляется в сеть, представляет собой строку бит.
То, что здесь показано, является низкоуровневым форматом, но далее это дополнительно компилируется до компактного двоичного формата, который не читается человеком.
Как вы можете видеть в этом примере, транзакция делится на три части: некоторые метаданные, серия входов и серия выходов.
Что качается метаданных, здесь есть некоторая информация о самой транзакции – размер транзакции, количество входов и количества выходов.
Также здесь указан хэш всей транзакции, который служит уникальным идентификатором транзакции.
Это позволяет нам использовать хеш-указатели для ссылок на транзакции.
Наконец, есть поле «lock_time», к которому мы вернемся позже.
Теперь о входах.
Входы транзакций образуют массив, и каждый вход имеет один и тот же формат.
Вход указывает предыдущую транзакцию с помощью хэша этой транзакции, который работает как хэш-указатель на предыдущую транзакцию.
Вход также содержит индекс выхода предыдущей транзакции, на которую идет ссылка.
И здесь еще есть подпись.
Помните, что мы должны подписать транзакцию, чтобы показать, что мы на самом деле имеем возможность претендовать на эти предыдущие выходы транзакций.
Теперь о выходах.
Выходы также представляют собой массив.
Каждый выход имеет только два поля. У каждого выхода есть значение, а сумма всех выходных значений должна быть меньше или равна сумме всех входных значений.
Если сумма выходных значений меньше суммы входных значений, разница представляет собой плату за транзакцию для майнера, который публикует эту транзакцию.
Также, у выхода есть строка, которая выглядит как адрес получателя.
Мы видим, что здесь есть хэш публичного ключа, а также есть набор команд.
Так что это поле на самом деле является скриптом.
Каждый выход транзакции не просто указывает публичный ключ или адрес следующего получателя монет.
На самом деле он определяет скрипт.
Что такое скрипт и почему мы используем скрипты?
Далее мы рассмотрим язык Bitcoin скриптов и поймем, почему скрипт используется вместо простого указания открытого ключа.
Наиболее распространенным типом транзакции в биткойне является трата выхода предыдущей транзакции путем подписания с помощью правильного ключа.
В этом случае мы хотим, чтобы на выходе транзакции говорилось: «этот выход транзакции может быть потрачен с помощью подписи следующего владельца указанного адреса.»
Напомним, что адрес является хешем публичного ключа.
Поэтому просто указание адреса не дает нам публичный ключ, и не дает нам возможности проверить подпись!
Таким образом, вместо этого выход транзакции говорит нам: «этот выход транзакции может быть потрачен публичным ключом, который хешируется, а также подписью владельца этого публичного ключа».
Теперь, что происходит с этим скриптом?
Кто его запускает, и как именно эта последовательность инструкций обеспечивает соблюдение вышеуказанного утверждения?
Секрет в том, что входы также содержат скрипты вместо просто подписей.
Чтобы проверить, что новая транзакция правильно потребляет выход предыдущей транзакции, мы объединяем входной скрипт новой транзакции и выходной скрипт предыдущей транзакции.
Мы просто соединяем их вместе, и полученный скрипт должен успешно выполниться, чтобы новая транзакция была действительной.
Эти два скрипта называются scriptPubKey и scriptSig, потому что в простейшем случае выходной скрипт просто указывает хэшированный публичный ключ или адрес, который может потребить этот выход транзакции, а входной скрипт следующей транзакции указывает подпись с этим публичным ключом.
Bitcoin язык скриптов был создан специально для биткойнов и называется просто «Скрипт».
Он имеет много общего с языком под названием Forth, который является старым, простым, основанным на стеках языком программирования.
Но вам не нужно изучать Форт, чтобы понимать скрипты биткойнов.
Язык Script был создан, чтобы иметь что-то простое и компактное, но с собственной поддержкой криптографических операций.
Поэтому в нем существуют специальные инструкции для вычисления хеш-функций, а также для вычисления и проверки подписей.
Язык Script основан на стеках.
Это означает, что каждая инструкция выполняется ровно один раз, линейно.
В частности, в языке Script биткойнов нет циклов.
Таким образом, количество инструкций в скрипте дает нам верхнюю оценку того, сколько времени потребуется для запуска скрипта и сколько памяти он может использовать.
Этот язык не имеет возможности вычислять произвольно мощные функции.
И по замыслу, именно майнеры должны запускать эти скрипты, которые предоставляются произвольными участниками сети.
Поэтому мы не хотим дать этим произвольным участникам возможность представить сценарий, который может иметь бесконечный цикл.
Таким образом, чтобы проверить, правильно ли новая транзакция потребляет выход предыдущей транзакции, мы создаем комбинированный скрипт, добавляя скрипт scriptPubKey предыдущей транзакции снизу к скрипту scriptSig новой транзакции.
Обратите внимание, что <pubKeyHash?> содержит ?'.
Мы используем это обозначение, чтобы указать, что мы позже проверим, что это значение равно хешу публичного ключа, который предоставлен во входном скрипте.
Есть только два возможных результата при выполнении скрипта биткойнов.
Он либо успешно выполняется без ошибок, и в этом случае транзакция действительна.
Или, если во время выполнения скрипта есть какая-либо ошибка, тогда вся транзакция будет недействительной и не должна приниматься в цепочку блоков.
Язык скриптов биткойнов очень маленький.
В нем есть только 256 инструкций, и каждая из них представлена одним байтом.
Байт состоит из восьми бит. Используя один байт, можно закодировать один символ из 256 возможных (256 = 2 в 8 степени). Таким образом, один байт равен одному символу, то есть 8 битам.
Из этих 256 инструкций, 15 в настоящее время отключены, и 75 зарезервированы.
Зарезервированные инструкции еще не получили никакого специального значения.
Многие из основных инструкций – это те, которые вы ожидаете в любом языке программирования.
Там есть базовая арифметика, базовая логика, такая как ‘if’ и ‘then, выброс ошибки, возврат return.
Наконец, существуют криптографические инструкции, которые включают хеш-функции, инструкции для проверки подписи, а также специальную и важную инструкцию CHECKMULTISIG, которая позволяет проверять несколько подписей в одной инструкции.
Для инструкции CHECKMULTISIG требуется указать n открытых ключей и параметр t как пороговое значение.
Чтобы эта инструкция выполнялась корректно, должно быть не менее t подписей от t из n этих открытых ключей, которые действительны. В этой инструкции мы можем определить компактным образом, что t из n указанных открытых ключей должны дать правильные подписи, чтобы транзакция была действительной.
Позже мы рассмотрим несколько примеров того, как используются мультиподписи.
Кстати, существует ошибка в реализации мультиподписи, и она была там все время.
Инструкция CHECKMULTISIG выталкивает значение дополнительных данных из стека и игнорирует его.
Это всего лишь причуда языка биткойнов, и с этим приходится иметь дело, добавляя в стек дополнительную фиктивную переменную.
Ошибка была в первоначальной реализации, и затраты на ее исправление намного выше, чем причиненный ущерб, как мы увидим позже.
На данный момент эта ошибка считается просто особенностью биткойна.
Чтобы выполнить скрипт на стековом языке программирования, все, что нам понадобится, это стек, в который мы можем вносить данные и из которого можем извлекать данные.
Нам не нужна никакая дополнительная память или переменные.
Это делает скрипт простым в вычислении.
В скрипте существует два типа инструкций: инструкции данных и коды операций или опкоды.
Когда в скрипте появляется инструкция данных, эти данные просто вставляются в верхнюю часть стека.
С другой стороны, опкоды выполняют некоторую функцию, часто беря данные, находящиеся вверху стека, как входные данные.
Теперь давайте посмотрим, как выполняется Bitcoin скрипт.
Здесь мы показываем состояние стека после каждой инструкции.
Первые две инструкции в этом скрипте – это инструкции данных – подпись и публичный ключ этой подписи.
Они были указаны в элементе scriptSig или входном скрипте.
Как мы уже сказали, когда мы видим инструкцию данных, мы просто вносим данные в стек.
Дальше идет скрипт scriptPubKey.
Здесь сначала у нас есть команда дублирования OP_DUP, поэтому мы просто вносим копию публичного ключа в верхнюю часть стека.
Следующей инструкцией является OP_HASH160, в которой говорится, что нужно вытолкнуть из стека верхнее значение, вычислить его криптографический хеш и внести результат в верхнюю часть стека.
Когда эта команда завершит выполнение, мы заменим публичный ключ на вершине стека его хешем.
Здесь речь идет о публичном ключе текущего владельца биткойнов.
Затем мы вносим в стек хэш публичного ключа, который был указан в предыдущей транзакции как получатель монет и который должен использоваться для создания подписи, чтобы потратить полученные монеты.
Таким образом, на данный момент в верхней части стека есть два значения.
Существует хэш публичного ключа, который был указан в выходном скрипте, и хэш публичного ключа, который используется при трате монет и который указан во входном скрипте.
На этом этапе мы запускаем команду EQUALVERIFY, которая проверит, что эти два значения в верхней части стека равны.
Если это не так, произойдет ошибка, и скрипт прекратит выполнение.
В нашем примере мы будем считать, что они равны, то есть получатель монет использовал правильный публичный ключ.
Эта инструкция потребляет те два элемента данных, которые находятся в верхней части стека.
И теперь стек содержит два элемента – подпись и публичный ключ, который использовался для этой подписи.
Мы уже проверили, что этот публичный ключ является публичным ключом, который требуется, и теперь мы должны проверить, действительна ли подпись.
Это отличный пример того, как язык скриптов Bitcoin построен с учетом криптографии.
Несмотря на то, что это довольно простой язык с точки зрения логики, в нем есть некоторые довольно сильные инструкции, такие как инструкция «OP_CHECKSIG».
Эта инструкция выталкивает эти два значения из стека и выполняет всю проверку подписи за один раз.
Но чего это подпись?
Какой был вход функции подписи?
Оказывается, есть только одна вещь, которую вы можете подписать в биткойн – это целая транзакция.
Таким образом, инструкция «CHECKSIG» выталкивает из стека два значения, открытый ключ и подпись, и проверяет, является ли эта подпись валидной для всей транзакции, используя этот публичный ключ.
Теперь мы выполнили каждую инструкцию в скрипте, и в стеке ничего не осталось.
Если ошибок не было, выход этого скрипта будет просто true, указывая, что транзакция действительна.
Теоретически, скрипт позволяет нам в каком-то смысле указать произвольные условия, которые должны быть выполнены для того, чтобы потратить монеты.
Но на сегодняшний день эта гибкость практически не используется.
Если мы посмотрим на скрипты, которые на самом деле были использованы в истории Биткойна, подавляющее большинство, 99,9 %, – это точно такой же скрипт pay-to-public-key-hash, который мы использовали в нашем примере.
Как мы видели, этот скрипт pay-to-public-key-hash просто указывает один публичный ключ, вернее его хэш, и требует подписи для этого публичного ключа, чтобы потратить монеты.
Однако существуют несколько других инструкций, которые действительно полезны.
Иногда используется специальный тип скрипта под названием «Pay-to-Script-Hash», который обрабатывает мультиподписи MULTISIG и который мы обсудим позже.
Вообще говоря, не существует большого разнообразия используемых скриптов.
Это связано с тем, что узлы биткойнов по умолчанию имеют белый список стандартных скриптов, и они отказываются принимать скрипты, отсутствующие в списке.
Это не означает, что эти другие скрипты нельзя использовать вообще; это просто усложняет их использование.
На самом деле это различие – это очень тонкая вещь, к которой мы вернемся, когда мы будем говорить об одноранговой сети Bitcoin.
Далее рассмотрим несколько видов стандартных скриптов.
Proof of burn доказательство сжигания – это скрипт, в котором биткойны никогда не могут быть потрачены.
Отправка монет в скрипт с доказательством сжигания устанавливает, что они уничтожены, так как нет никакой возможности для их расходования.
Одно из использований доказательства сжигания заключается в том, чтобы загрузить альтернативу биткойну, заставив людей уничтожить биткойн, чтобы получить монеты в новой системе.
Мы обсудим это более подробно позже.
Доказательство сжигания довольно просто реализовать: опкод OP_RETURN выбрасывает ошибку и маркирует транзакцию как недействительную.
Таким образом, любая новая транзакция, которая попытается использовать выход с OP_RETURN, будет недействительной и не будет учитываться в блокчейне.
Независимо от того, какие значения вы ставите перед OP_RETURN, эта инструкция будет выполнена и скрипт вернет false.
Так как выбрасывается ошибка, данные в скрипте, которые появляются после OP_RETURN, не будут обрабатываться.
Таким образом, это также возможность помещать произвольные данные в скрипт и, следовательно, в цепочку блоков.
Если по какой-то причине вы хотите написать свое имя или хотите установить отметку времени и доказать, что знаете определенные данные в определенное время, тем самым, например, внести доказательство авторских прав на документ, вы можете создать транзакцию биткойнов с очень малой суммой и инструкцией OP_RETURN.
Вы можете уничтожить очень маленькую сумму валюты, но вы можете написать все, что захотите, в цепочку блоков, которая будет храниться всегда.
Теперь о скрипте Pay-to-script-hash.
Механизм работы скриптов Биткойна подразумевает, что отправитель монет должен точно указать скрипт.
Но это иногда становится затруднительным.
Скажем, например, вы являетесь покупателем интернет-магазина, и вы собираетесь что-то заказать.
И вы говорите: «Хорошо, я готов заплатить. Скажите мне адрес, на который я должен отправить свои монеты».
Теперь предположим, что компания, в которой вы заказываете товар, использует адрес MULTISIG с несколькими приватными ключами, то есть для их подписи используются несколько приватных ключей для дополнительной защиты.
Затем, так как вы должны указать это, продавец должен будет сказать вам: «Мы используем MULTISIG, и мы попросим вас отправить монеты с использованием сложного скрипта».
На что вы могли бы сказать: «Я не знаю, как это сделать. Это слишком сложно. Как потребитель, я просто хочу отправить монеты на простой адрес».
Для решения этой проблемы, в биткойне есть умный хак.
Вместо того, чтобы отправитель указывал весь скрипт, отправитель может указать только хэш скрипта, который понадобится для последующей траты этих монет.
Поэтому отправителю нужно просто указать очень простой скрипт, который просто хэширует верхнее значение в стеке и проверяет, соответствует ли оно требуемому скрипту траты монет.
Получателю этих монет необходимо указать в качестве значения данных, сам скрипт, чей хэш указан отправителем.
После этого произойдет второй этап проверки.
То есть, верхнее значение данных из стека будет переинтерпретировано в качестве инструкций, а затем оно будет выполняться во второй раз уже как скрипт.
Итак, мы видим, что здесь выполняются два этапа.
Сначала это был традиционный скрипт, который проверял, что скрипт потребления монет имеет правильный хеш.
И после этого скрипт потребления монет де-сериализуется и запускается как скрипт.
И вот где будет происходить фактическая проверка подписи.
Создание поддержки для этого типа скриптов P2SH было довольно сложным, поскольку этот тип скриптов не был частью первоначальной спецификации Bitcoin.
Он был добавлен позже.
Это, вероятно, самая известная функция, добавленная в биткойн, которой не было в исходной спецификации.
И она решает несколько важных проблем.
Она облегчает жизнь отправителю, так как получатель может просто указать хэш, на который отправитель отправляет деньги.
В нашем примере, Алисе не нужно беспокоиться о том, что Боб использует multisig, она просто отправляет деньги на адрес P2SH Боба, и ответственность Боба заключается в том, чтобы указать этот сложный скрипт, когда он хочет потратить монеты.
P2SH также ускоряет обработку.
Так, майнерам нужно отслеживать набор выходных скриптов, которые еще не были потрачены, а с P2SH выходные скрипты намного меньше, так как они указывают только хеш.
Вся сложность переносится на входные скрипты.
Теперь, когда мы понимаем, как работают скрипты Bitcoin, давайте взглянем на некоторые из применений, которые могут быть реализованы с помощью этого языка сценариев.
Оказывается, что мы можем делать много полезных вещей, которые оправдывают использование языка сценариев вместо того, чтобы просто указывать публичные ключи.
Рассмотрим транзакцию условного депонирования – это депонирование определенной суммы покупателем у третьего лица под определенные условия при сомнениях в добросовестности продавца.
Скажем, Алиса и Боб хотят вести дела друг с другом – Алиса хочет заплатить Бобу в Биткойнах, чтобы Боб отправил некоторый физический товар Алисе.
Проблема в том, что Алиса не хочет платить до тех пор, пока она не получит товар, а Боб не хочет отправлять товар до тех пор, пока он не будет оплачен.
Что мы можем с этим поделать?
Хорошим решением в биткойне, которое можно было бы использовать на практике, является введение третьей стороны и транзакция с депонированием.
Транзакция с депонированием может быть реализована достаточно просто с использованием мультиподписи MULTISIG.
Алиса не отправляет деньги непосредственно Бобу, а вместо этого создает транзакцию MULTISIG, для которой требуется два из трех человек, чтобы потратить монеты.
И эти три человека будут Алисой, Бобом, и некоторым сторонним арбитром Джуди, который вступит в игру, если возникнут какие-либо споры.
Поэтому, Алиса создает 2-из-3 транзакцию MULTISIG, которая отправляет некоторое количество монет, которыми она владеет, и указывает, что они могут быть потрачены, если будут две подписи из трех Алисы, Боба и Джуди.
Эта транзакция включена в цепочку блоков, и на данный момент эти монеты хранятся в депонировании между Алисой, Бобом и Джуди, так что любые два из них могут указать, куда должны уйти монеты.
В этот момент Боб убежден, что безопасно отправить товар Алисе, поэтому он отправит его по почте или каким-то другим способом.
Теперь, предположим, Алиса и Боб оба честны.
Поэтому Боб отправит товар, который ожидает Алиса, и когда Алиса получит товар, Алиса и Боб подпишут транзакцию, потратив средства из депонирования и отправив их Бобу.
Обратите внимание, что в этом случае, когда Алиса и Боб честны, Джуди не нужно вмешиваться.
Не было никакого спора, и подписи Алисы и Боба соответствовали требованию 2-из-3 транзакции MULTISIG.
Так что в нормальном случае это ничем не отличается, как если бы Алиса просто отправила бы Бобу деньги, но это требует одной дополнительной транзакции.
Но что могло бы произойти, если бы Боб не отправил товар или товар потерялся бы на почте?
Или, может быть, товар отличался бы от того, который заказывала Алиса?
Алиса теперь не хочет платить Бобу, потому что думает, что ее обманули, и она хочет вернуть свои деньги.
Поэтому Алиса определенно не собирается подписывать транзакцию, которая передает деньги Бобу.
Но Боб также может отрицать любые нарушения и отказываться подписывать транзакцию, которая возвращает деньги Алисе.
Здесь необходимо принять участие Джуди.
Джуди придется решить, кто из этих двух людей заслуживает денег.
Если Джуди решит, что Боб обманул, Джуди подпишет сделку вместе с Алисой, отправив деньги с эсквота обратно Алисе.
Подписи Алисы и Джуди отвечают требованиям 2-из-3 транзакции MULTISIG, и Алиса вернет себе деньги.
И, конечно, если Джуди думает, что здесь виновата Алиса, и Алиса просто отказывается платить, Джуди может подписать транзакцию вместе с Бобом, отправив деньги Бобу.
Поэтому в этом случае Джуди решает, какой будет результат.
Но ей не придется участвовать, если нет спора.
Еще одно интересное применение скриптов – это то, что называют зелеными адресами.
Предположим, Алиса хочет заплатить Бобу, но Боб не в сети.
Так как он не в сети, Боб не может взять и посмотреть на цепочку блоков, чтобы увидеть, находится ли там транзакция, которую послала Алиса.
Также возможно, что Боб находится в сети, но у него нет времени, чтобы посмотреть на цепочку блоков и дождаться подтверждения транзакции.
Помните, что обычно мы ждем, чтобы транзакция попала в цепочку блоков и была подтверждена шестью последующими блоками, что занимает около часа, прежде чем мы будем уверены, что транзакция действительно находится в цепочке блоков.
Но для некоторых товаров, таких как еда, Боб не может ждать час, чтобы начать доставку.
Если бы Боб был уличным продавцом, продающим хот-доги, маловероятно, что Алиса будет ждать около часа, чтобы получить еду.
Или, возможно, Боб по какой-либо другой причине вообще не имеет никакого подключения к Интернету и, следовательно, не сможет проверить цепочку блоков.
Чтобы решить эту проблему, чтобы вы могли отправлять деньги с помощью биткойна, не получая доступ к блокчейну, мы должны предоставить другую третью сторону, которую мы будем называть банком (на практике это может быть любой финансовый посредник).
Тогда Алиса связывается с ее банком и говорит: «Это я, Алиса. Я твой лояльный клиент. Вот моя карточка или мой идентификатор. И я бы хотела заплатить Бобу, не могли бы вы мне помочь?»
На что банк говорит: «Конечно. Я спишу эту сумму с вашего счета. И составлю транзакцию с одного из моих зеленых адресов на Боба».
Поэтому обратите внимание, что эти деньги поступают напрямую от банка к Бобу.
Какая-то сумма, конечно, может быть в обратном адресе, возвращающемся в банк.
Но, по сути, банк платит Бобу с банковского адреса, который мы называем зеленым адресом.
Более того, банк гарантирует, что он не будет дважды тратить эти деньги.
И, как только Боб видит, что эта транзакция подписана банком, если он доверяет гарантии банка не делать двойную трату этих денег, он может заранее принять то, что в конечном итоге это будут его деньги, когда транзакция будет подтверждена в цепочке блоков.
Обратите внимание, что это не гарантия, основанная на биткойнах.
Это реальная гарантия, и для того, чтобы эта система работала, Боб должен верить, что банк в реальном мире заботится о своей репутации и не будет по этой причине делать двойные траты.
И банк сможет сказать: «Вы можете посмотреть на мою историю. Я давно использую этот зеленый адрес, и я никогда не совершал по нему двойной траты. Поэтому я вряд ли сделаю это в будущем».
Таким образом, Бобу больше не нужно думать о доверии Алисе, о которой он ничего не знает.
Вместо этого он доверяет банку, что они не будут дважды тратить деньги, которые они ему отправили.
Конечно, если банк когда-либо сделает двойную трату, люди перестанут доверять этим зеленым адресам.
Фактически, двумя наиболее известными онлайн-службами, которые реализовали зеленые адреса, были Instawallet и Mt. Gox, и обе в итоге закрылись, так как совершили двойную трату.
Сегодня зеленые адреса практически не используются.
Когда идея была впервые предложена, она привлекла внимание как способ сделать платежи быстрее и без доступа к цепочке блоков.
Затем, однако, люди разочаровались в ней по причине того, что она требует слишком большого доверия банку.
Третий пример применения скриптов биткойнов – это способ совершать эффективные микроплатежи.
Предположим, что Алиса – клиент, который хочет постоянно платить Бобу небольшую сумму денег за некоторую услугу, которую предоставляет Боб.
Например, Боб может быть поставщиком услуг мобильной связи для Алисы, и требует, чтобы она платила небольшую плату за каждую минуту, которую она проговорила со своего телефона.