Приложение в твоем смартфоне
Приложение в твоем смартфоне
Приложение в твоем смартфоне
Приложение в твоем смартфоне
7 марта 2012 в 17:06

Bitcoin: встроенная система сценариев и цифровые контракты

Про Bitcoin на Хабре писали уже достаточно, однако лишь в общих чертах. Для непосвященных, на мой взгляд, полезными будут топики: раз и два.

В этом же посте затронут весьма узкий аспект — встроенная система сценариев, предназначенная для проверки валидности транзакций, а также некоторые её возможности. На родном языке такой информации мне не попадалось, потому вношу свою лепту.


Немного о сценариях


Для проверки транзакций Bitcoin имеется встроенный стек-ориентированный язык сценариев, чем-то похожий на Forth. По понятным причинам он не является Тьюринг-полным и в нём нет циклов. С другой стороны, он очень прост.

По существу, сценарий — это последовательность инструкций внутри транзакции, которая описывает, как лицо, желающее потратить биткоины, должно получить к ним доступ. Сценарий типичного перевода средств на адрес A налагает 2 требования на лицо, желающее впоследствии воспользоваться этими средствами:
  • предоставить в следующей транзакции открытый ключ, хэш которого равен A,
  • предоставить подпись, доказывающую владение указанным выше открытым ключом.
Сценарии достаточно гибки по части указания различных условий дальнейшего распоряжения средствами. Например, можно потребовать два ключа/подписи или комбинацию нескольких подписей. В общем случае лицо(лица), отправляющее средства, указывает в транзакции сценарий их последующей траты (scriptPubKey). Лицо(лица), желающее воспользоваться полученными средствами, в следующей транзакции указывает входные данные для сценария (scriptSig). Если у транзакции сумма входящих средств больше или равна сумме исходящих средств, а комбинированный (scriptSig + scriptPubKey) сценарий выполняется без сбоя и в результате его работы на верхушке стека оказывается истинное (ненулевое) значение, транзакция считается валидной и майнеры могут включать её в цепочку блоков.

Пример типичной транзакции:
scriptPubKey:
OP_DUP OP_HASH160 {addr} OP_EQUALVERIFY OP_CHECKSIG

scriptSig:
{sig} {pubKey}

Трассировка по шагам:
Стек Сценарий
0 EMPTY {sig} {pubKey} OP_DUP OP_HASH160 {addr} OP_EQUALVERIFY OP_CHECKSIG
1 {sig} {pubKey} OP_DUP OP_HASH160 {addr} OP_EQUALVERIFY OP_CHECKSIG
2 {sig} {pubKey} OP_DUP OP_HASH160 {addr} OP_EQUALVERIFY OP_CHECKSIG
3 {sig} {pubKey} {pubKey} OP_HASH160 {addr} OP_EQUALVERIFY OP_CHECKSIG
4 {sig} {pubKey} {hash} {addr} OP_EQUALVERIFY OP_CHECKSIG
5 {sig} {pubKey} {hash} {addr} OP_EQUALVERIFY OP_CHECKSIG
5 {sig} {pubKey} OP_CHECKSIG
6 TRUE EMPTY
Подробнее про сценарии можно почитать здесь.

Временная блокировка, мультиверсионность и прочая магия


Помимо сценариев в Bitcoin-транзакциях есть еще несколько интересных штук: транзакция может быть отложенной на некоторое время или до какого-то конкретного блока, может менять в процессе согласования свою версию. У обычных транзакций интервал блокировки равен нулю, а версия — максимально возможная.

Кроме того, имеется возможность задавать режим хеширования транзакции при проверке подписи:
  • SIGHASH_ALL — режим по умолчанию, по сути означает «я вношу свою часть если каждый вносит свою и получатели денег такие-то каждый на соответствующую сумму»;
  • SIGHASH_NONE — означает «я вношу свою часть если каждый вносит свою, а кто получатель мне все равно»;
  • SIGHASH_SINGLE — почти то же самое, по сути «я вношу свою часть если каждый вносит свою, но один из получателей такой-то на такую-то сумму».
Есть еще модификатор SIGHASH_ANYONECANPAY, который, будучи добавленным к любому из перечисленных режимов, по сути уберет слова «если каждый вносит свою» из описаний этих самых режимов.

Контракты


И вот на таком хитром базисе можно строить распределенные контракты — метод достижения договорённости между сторонами посредством использования цепочки блоков. Контракты не делают чего-то такого, что не было бы возможно раньше, однако они позволяют решать некоторые распространенные проблемы таким образом, что не требуется взаимного доверия сторон или его уровень сведен к минимуму. Такой подход позволяет избавиться от услуг доверенного посредника (который может прихватить ваши денежки и быть таков) при совершении сделок и разрешении спорных ситуаций. В качестве примера рассмотрим следующую жизненную ситуацию.

Сделка с протекцией и разрешение конфликта

Покупатель желает приобрести товар у продавца, которого он не знает и которому не доверяет. В случае нормально прошедшей сделки покупатель не хотел бы посвящать в детали постороннее лицо. Однако в случае проблем покупатель хотел бы, чтобы независимый арбитр решил, кто получит деньги. В качестве доказательства последний может запросить у продавца, скажем, квитанцию об отправке товара почтой.

Другими словами, Покупатель хотел бы заблокировать некую сумму, распоряжаться которой можно было бы с согласия хотя бы двух лиц из трех. Для этого он:
  • Договаривается с Продавцом об Арбитре.
  • Запрашивает у Продавца и Арбитра их открытые ключи K1 и K2 соответственно и создает новый ключ K3 для себя.
  • Посылает продавцу ключ Арбитра K2. Продавец проверяет подлинность K2 запросив подпись случайного числа.
  • Создает транзакцию T1 на сумму заказа такую, что потратить ее исходящие средства можно только по предоставлении хотя бы 2 подписей, и публикует ее в сети.
После включения транзакции в цепочку блоков средства могут быть потрачены транзакцией T2 если:
  • Покупатель и Продавец ставят свои подписи под ней — сделка завершилась успешно или Продавец возвратил средства клиенту не дожидаясь решения Арбитра.
  • Покупатель и Арбитр ставят свои подписи — сделка не произошла, Арбитр вернул средства Покупателю.
  • Арбитр и Продавец ставят свои подписи — сделка признана Арбитром состоявшейся, несмотря на возражения Покупателя, средства переданы продавцу.

Подробнее о контрактах можно почитать здесь и здесь. Если тема будет интересной, опишу еще несколько типовых контрактов.
+29
1346
41
vibornoff 15,8

комментарии (22)

НЛО прилетело и опубликовало эту надпись здесь
0
AlexanderYastrebov, #
>> По понятным причинам он не является Тьюринг-полным
А можно поподробнее о понятных причинах?
+5
vibornoff, #
Если очень утрируя, на Тьюринг-полном языке можно написать такую программу, которая зависнет в бесконечном цикле. Для проверки же транзакций необходим такой язык, программы на котором гарантированно завершаются с результатом ДА/НЕТ.
+1
ComodoHacker, #
А еще потому, что на Тьюринг-полном языке можно написать малварь для махинаций с биткоинами.
0
rPman, #
Хотелось бы более подробной статьи на русском про встроенный язык и возможности, пока все еще туманно.
0
vibornoff, #
А что туманного? Есть старая транзакция, есть новая. Сценарий составляется из двух половинок — часть от старой транзакции, часть от новой. В сценарии данные и операторы. Есть стек. Данные по мере исполнения сценария заносятся в стек. Операторы нужное кол-во операндов берут из стека, что-то с ними делают, результат, если есть, кладут назад в стек. Когда сценарий закончился, на верхушке стека должно быть TRUE.

Полный список операторов и их описание является справочной информацией, ибо там их хренова куча.
+2
rPman, #
Если я все верно понимаю, до недавнего времени (или до сих пор) количество допустимых сценариев было ограничено стандартным переводом средств… недавно была введена возможность создавать multisig транзакции… сейчас даже какой то раскол в стане разработчиков (и владельцев крупных пулов) по поводу способа реализации поддержки… BIP (предложений по улучшению) то ли 16-ой версии, то ли 12-ой… кто бы по подробнее осветил суть проблем, а то на русском на форуме bitcointalk.org только lzsaver панику разводит без объяснений.

Про multisig, разве все этапы проведения транзакций поддерживаются клиентом? можно примеры работающие примеры чего-нибудь реального, например сценарий предоставления услуги за bitcoin с escrow на основе multisig.

Еще мне непонятно, как в дальнейшем можно будет пользоваться клиентом, когда алгоритмов на основе этого внутреннего языка станет больше, на каждый пшик ждать его реализации в виде интерфейса в клиенте bitcoin?

Примеры:
* я хочу чтобы монеты стали доступны после того, как количество монет станет больше/меньше указанного значения, переданные по определенному адресу (доступные пользователю, владеющего этими монетами)…
* или еще лучше, доступны как только кто-либо воспользуется монетами по адресу…

p.s. кстати, верно ли я понял? если в транзакции указано что 10 монет доступны на хитрых условиях (пусть будет доступны только в течении 1 часа по пятницам) будут переведены (использованы в новой транзакции)… старые условия на эти монеты же не действуют? невозможно создать такие условия, чтобы 'заразить монеты' хитрыми ограничениями навсегда или до определенных условий?
0
vibornoff, #
Изначально Bitcoin поддерживает все множество различных сценариев. Однако из соображений безопасности, как я понял, в оригинальном клиенте все они были заблокированы.

MULTISIG-транзакции недавно поддержали крупные пулы, но не все. Впрочем, это их проблемы, поскольку >50% сети этот сценарий уже поддерживают.

То, что MULTISIG транзакции нельзя создавать в оригинальном клиенте — фича клиента. Хотите такие транзакции (см. 1-й output) обрабатывать — пользуйтесь соответсвующим софтом/сервисами. Оригинальный клиент просто их будет игнорировать.

По поводу BIP12/BIP16 — почитав, не могу сказать определенно, но кажется бредом. PayToScriptHash не может работать даже в теории, ибо ScriptHash=HASH(scriptSig) не известен и не может быть известен в принципе отправляющей стороне, поскольку ECDSA-сигнатура состоит наполовину из случайного числа.

я хочу чтобы монеты стали доступны после того, как количество монет станет больше/меньше указанного значения, переданные по определенному адресу
Примерно так: создается транзакция с исходящими на нужную сумму. Транзакция не является валидной до тех пор, пока входящая сумма меньше. Как только входящих набралось на нужную сумма, транзакция становится валидной и майнеры включают ее в очередной блок. Насчет «меньше указанного значения» — не совсем понял, надо деньги из ничего создать?

или еще лучше, доступны как только кто-либо воспользуется монетами по адресу
Тоже можно. Получатель монет по «определенному адресу» загадывает секрет, сообщает вам хеш этого секрета. Вы создаете две транзакции с хитрым scriptPubKey: OP_HASH {secretHash} OP_EQUEALVERIFY {а дальше как у обычной транзакции}. Чтобы потратить любую из них получателю придется раскрыть загаданный секрет. А как только секрет раскрыт, другой получатель может его из той транзакции взять и свою транзакцию потратить с его помощью.

Как только монеты получены, условия их дальнейшего использования определяет исключительно владелец. Так что нет, «заражать» их нельзя.
0
vibornoff, #
И еще:
10 монет доступны на хитрых условиях (пусть будет доступны только в течении 1 часа по пятницам)
Сам по себе скрипт не может проверять такие хитрые условия. Но оно может быть сделано через протокол Оракула — по сути с помощью 3-го лица/сервиса, который поставит свою часть MULTISIG-подписи.
0
rPman, #
Я хочу очертить (понять) полный круг базисного функционала, который возможен хотя бы в теории для кода, прописываемого в транзакции.

Ты немного не понял вопроса!
Имеется ли у скриптового языка доступ к блокам по их номерам? к другим транзакциям? можно ли сделать условие — 'монеты будут доступны, только после появления другой транзакции, переводящей монеты на указанный в коде адрес' — типа эти деньги тебе будут доступны, если сумма на вон том кошельке-адресе доберется до определенного уровня. Если я все верно понимаю — это недоступно.

Похоже единственное к чему может обращаться этот код (данные, на основе которых будут проводиться проверки) — это:
1. данные в самом коде (только константы)!
2. функции проверки подписи хеширования и т.п… т.е. максимум получается доступ к ключам для адресов, заданных константами!
3. доступ к версии клиента (если версия клиента меньше указанной)
4. текущее время (кстати не нашел какой функцией это делается)
ВСЕ

Остальное реализуется почти полноценным языком (простейшая математика, сравнения, массивы, работа со строками, битовые операции и без циклов).

Значит если мы хотим выйти за эти рамки — нам нужен кто то третий, кто будет создавать новые транзакции с нужным кодом… значит нужно проявить кучу изобретательности, чтобы сделать надежный алгоритм, защищенный от недобросовестных участников.
Ведь вся красивая идея распределенной сети bitcoin — в том что нет центра, при этом процессинговая система действует как бы сама по себе… а если она еще и логику позволит какую то исполнять, беря на себя контроль над деньгами.
0
vibornoff, #
Если я все верно понимаю — это недоступно.
Именно так.

Похоже единственное к чему может обращаться этот код (данные, на основе которых будут проводиться проверки) — это:
1. да,
2. да,
3. не знаю, скорее нет,
4. нет.

Значит если мы хотим выйти за эти рамки — нам нужен кто то третий, кто будет создавать новые транзакции с нужным кодом… значит нужно проявить кучу изобретательности, чтобы сделать надежный алгоритм, защищенный от недобросовестных участников.
Именно так.
+1
grich, #
PayToScriptHash не может работать даже в теории, ибо ScriptHash=HASH(scriptSig) не известен и не может быть известен в принципе отправляющей стороне, поскольку ECDSA-сигнатура состоит наполовину из случайного числа.


ScriptHash=HASH(scriptSig) — это неверно.
Хэш вычисляется от публичного ключа и команд скрипта. Подпись туда не входит
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
0
vibornoff, #
Сигнатуры при правильном использовании SIGHASH_BLABLABLA действительно не слетают, но при каждом изменении меняется идентификатор транзакции (хеш от ее содержимого). Так что все следующие транзакции в цепочке надо переподписывать, т.к. они становятся orphaned.
+1
kuchumovn, #
как всё заморочено…
каким умным нужно быть, чтобы всё это написать, да ещё и бескорыстно.
мб это кто-то из элит спонсирует?
или это псих-одиночка пишет?
+1
naryl, #
Все альтернативные валюты пишут психи-одиночки. Элита заинтересована в том, чтобы экономика вечно была завязана на банках.

Рекомендую для ознакомления www.youtube.com/watch?v=ySzqM5dpF7s Вообще видео про ещё одну альтернативную платёжную систему, но вступление очень длинное и познавательное для не-экономистов.
0
kuchumovn, #
Вы это голословно сейчас утверждаете в первом параграфе, или Вы лично знакомы с создателем системы Биткоинов?
0
stroncium, #
Думаю, автора знает это на своем примере.
0
kuchumovn, #
Про анонимность валюты я в курсе, и это спорный вопрос (нужно ли это в нормальном обществе)
0
itforge, #
Сценарий типичного перевода средств на адрес A налагает 2 требования на лицо, желающее впоследствии воспользоваться этими средствами: предоставить в следующей транзакции открытый ключ, хэш которого равен A, предоставить подпись, доказывающую владение указанным выше открытым ключом.


1.есть уязвимости в том, что известен мой паблик кей?
2. Что подразумевается под предоставлением подписи? Криптануть закрытым ключом какоенить число, полученный хэш предложить раскриптовать открытым ключом и сверить результат с вышеуказанным числом?
0
itforge, #
По пункту 1, почему сразу не используется публичный ключ в виде адреса, зачем хэш от него использовать?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.