Bitcoin Forum

Local => Кодеры => Topic started by: mrxtraf on November 16, 2020, 10:32:13 PM



Title: Проводка транзакции OP_HASH160 (HASH) OP_EQUAL
Post by: mrxtraf on November 16, 2020, 10:32:13 PM
Технический вопрос по скрипту и комбинации OP_HASH160 (HASH) OP_EQUAL.
В подписи транзакции должна быть строка (STRING) с которой должно получится соответствие rimemd160(hash256(STRING)) = HASH.

Как я понял их мануалов.
То что указывается в строке подписи попадает в стек. Будем считать это строка STRING2.
Получается следующий алгоритм проверки.
Строка STRING2 попадает в стёк. Сразу ПыСы, до него могло быть добавлен несколько строк данных, которые не являются скриптами. Просто данные.
Далее она начинает обрабатываться как скрипт. И если она не является скриптом, то не будет принята транзакция.
Скрипт строки STRING2 отрабатывается и остается в стеке, работает с предыдущими данными из стека. И при положительном результате остается в стеке как есть, при этом удаляются предыдущие данные.
Далее идет выполнение скрипта первичного вывода.
Операция OP_HASH160 берет из стека топовый параметр и изменяет его на rimemd160(hash256(STRING))
Операция (HASH) добавляет HASH в топ стека.
Операция OP_EQUAL проверяет два последних верхних параметра на соответствие. Удаляет их. И устанавливает в стек true(1) или false(0) в зависимости от результата.

Вопрос.
Есть строка STRING которая соответствует rimemd160(hash256(STRING)) = HASH, но сама не является скриптом.
Возможно ли провести транзакцию с такими данными?


Title: Re: Проводка транзакции OP_HASH160 (HASH) OP_EQUAL
Post by: ~DefaultTrust on November 17, 2020, 07:42:19 AM
Если скрипт дает тру, то транзакция тру, если скрипт на выходе фальшь, то транзакции нет. Пиши скрипт и проверяй. В чем вопрос?
Строка это строка, скрипт это скрипт. С чего вдруг строка должна обрабатываться как скрипт?


Title: Re: Проводка транзакции OP_HASH160 (HASH) OP_EQUAL
Post by: mrxtraf on November 17, 2020, 10:22:55 AM
Если скрипт дает тру, то транзакция тру, если скрипт на выходе фальшь, то транзакции нет. Пиши скрипт и проверяй. В чем вопрос?
Строка это строка, скрипт это скрипт. С чего вдруг строка должна обрабатываться как скрипт?
Если я отправляю на подпись со строкой. Получаю ответ.
Code: -26, Error: mandatory-script-verify-flag-failed (Opcode missing or not understood)

И вообще вы знаете как работает комбинация выхода?
OP_HASH160 (HASH) OP_EQUAL

И чем допустим отличается?
OP_HASH160 от OP_HASH256

Ещё раз.
Есть выход OP_HASH160 (HASH) OP_EQUAL
Знаем строку с которой получается комбинация rimemd160(hash256(STRING)) = HASH  что эквивалентно OP_HASH160(STRING) = HASH
Вопрос.
Как использовать данный выход в качестве входа и как его "подписать"? Что нужно указать в подписи чтобы проверка прошла успешно?

ПыСы. Если разбираетесь поврехтностно в вопросе, лучше не писать что решение банально.
Пробовал много разных вариантов.
ПыСы2. Гугл не помогает, потому что практически везде это комбинация используется только для мултисигов. И всё. Других примеров нет!


Title: Re: Проводка транзакции OP_HASH160 (HASH) OP_EQUAL
Post by: ~DefaultTrust on November 17, 2020, 10:38:19 AM

Ещё раз.
Есть выход OP_HASH160 (HASH) OP_EQUAL
Знаем строку с которой получается комбинация rimemd160(hash256(STRING)) = HASH  что эквивалентно OP_HASH160(STRING) = HASH
Вопрос.
Как использовать данный выход в качестве входа и как его "подписать"? Что нужно указать в подписи чтобы проверка прошла успешно?

Строка должна быть не просто строкой, а скриптом который даст тру. Например, если хочется впихнуть в скрипт строку, то скрипт должен быть чем-то вроде:
OP_PUSHDATA длина_строки
строка
OP_DROP
публичный ключ
OP_CHECKSIGVERIFY

С подписью все сложно. В нативном клиенте нет способа подписать нестандартный скрипт. Нужно использовать сторонний софт или либы.

Но для тестов ты же можешь отправлять не подписанные транзакции. Тогда пиши просто:
OP_PUSHDATA длина_строки
строка
OP_DROP
OP_TRUE


Title: Re: Проводка транзакции OP_HASH160 (HASH) OP_EQUAL
Post by: mrxtraf on November 17, 2020, 11:19:34 AM
Строка должна быть не просто строкой, а скриптом который даст тру. Например, если хочется впихнуть в скрипт строку, то скрипт должен быть чем-то вроде:
OP_SIZE_длина_строки
строка
OP_DROP
публичный ключ
OP_CHECKSIGVERIFY

С подписью все сложно. В нативном клиенте нет способа подписать нестандартный скрипт. Нужно использовать сторонний софт или либы.

Но для тестов ты же можешь отправлять не подписанные транзакции. Тогда пиши просто:
OP_SIZE_длина_строки
строка
OP_DROP
OP_TRUE
Так есть возможность или нет?

Просто по документации, допустим есть команда
OP_PUBKEYHASH   253   0xfd   Represents a public key hashed with OP_HASH160.
Правда она относится к разряду.
Pseudo-words
These words are used internally for assisting with transaction matching. They are invalid if used in actual scripts.


Тут вопрос наверное в другом. Что выполняется первым?
OP_HASH160 (HASH) OP_EQUAL
Или
Скрипт подписи.

Если скрипт выхода OP_HASH160 (HASH) OP_EQUAL первый, то вариантов нет. Если наоборот, то тогда можно пробовать что-то мудрить со стеком.


Title: Re: Проводка транзакции OP_HASH160 (HASH) OP_EQUAL
Post by: ~DefaultTrust on November 17, 2020, 11:36:06 AM
Сначала проверяется хэш скрипта
Потом выполняется скрипт.
Чего добиться-то хочешь? Записать строку? Я тебе показал как - пиши скрипт, хэшируй, отправляй на хэш бабки, забирай бабки скриптом.
Если хочешь с подписями, то используй сторонние либы. Без подписей можно все стандартной корой сделать.


Title: Re: Проводка транзакции OP_HASH160 (HASH) OP_EQUAL
Post by: A-Bolt on November 17, 2020, 11:36:18 AM
Как я понял их мануалов.

Вы как-то не совсем правильно поняли.

ScriptSig для P2SH-входа имеет следующий формат:
Code:
<Sig1> <Sig2> ... <SigN> <redeemScript>
Знаки < > означают операцию помещения в стек того, что находятся между ними. То есть, <SigN> и <redeemScript> - это байтовые массивы, которые помещаются в стек один за другим в виде элементов данных.

Итак, на первом этапе в стек помещаются Sig1, ... SigN и последним в стек запихивается redeemScript. Далее происходит выполнение scriptPubKey, котрый для P2SH-выхода выглядит так:
Code:
OP_HASH160 <redeemScriptHash> OP_EQUAL

Первый оператор - OP_HASH160 хеширует содержимое вершины стека, а там находится redeemScript, и помещает результат в стек. Следующий оператор - OP_EQUAL сравнивает redeemScriptHash, предварительно помещённый в стек, с результатом оператора OP_HASH160, помещённым в стек ещё раньше. В случае неравенства - в стек помещается 0. На этом выполнение скрипта завершается и его результат, находящийся на вершине стека проверяется: если 0 - транзакция считается недействительной и на этом всё. В случае равенства - OP_EQUAL записывает на вершину стека 1, транзакция (на данном этапе) считается действительной и происходит переход ко второму этапу.

На первом этапе проверяется соответсвие между хешем redeemScript, записанным в scriptPubKey, и самим redeemScript, записанным в scriptSig. Тем самым подтверждается право на выполнение redeemScript.

На втором этапе в стеке имеются такие данные:
Code:
<Sig1> <Sig2> ... <SigN> <redeemScript>

RedeemScript извлекается из стека и выполняется уже как скрипт, использующий данные, находящиеся в стеке - <Sig1> ... <SigN>. Тут опять же, если результатом выполнения скрипта является 0, то транзакция считается недействительной и наоборот.

Во втором этапе реализуется логика скрипта redeemScript. Если это m-of-n multisig, то проверяется право на трату выхода подписям <Sig1> ... <SigN>.


Title: Re: Проводка транзакции OP_HASH160 (HASH) OP_EQUAL
Post by: mrxtraf on November 17, 2020, 11:43:39 AM
Как я понял их мануалов.

Вы как-то не совсем правильно поняли.

ScriptSig для P2SH-входа имеет следующий формат:
Code:
<Sig1> <Sig2> ... <SigN> <redeemScript>
Знаки < > означают операцию помещения в стек того, что находятся между ними. То есть, <SigN> и <redeemScript> - это байтовые массивы, которые помещаются в стек один за другим в виде элементов данных.

Итак, на первом этапе в стек помещаются Sig1, ... SigN и последним в стек запихивается redeemScript. Далее происходит выполнение scriptPubKey, котрый для P2SH-выхода выглядит так:
Code:
OP_HASH160 <redeemScriptHash> OP_EQUAL

Первый оператор - OP_HASH160 хеширует содержимое вершины стека, а там находится redeemScript, и помещает результат в стек. Следующий оператор - OP_EQUAL сравнивает redeemScriptHash, предварительно помещённый в стек, с результатом оператора OP_HASH160, помещённым в стек ещё раньше. В случае неравенства - в стек помещается 0. На этом выполнение скрипта завершается и его результат, находящийся на вершине стека проверяется: если 0 - транзакция считается недействительной и на этом всё. В случае равенства - OP_EQUAL записывает на вершину стека 1, транзакция (на данном этапе) считается действительной и происходит переход ко второму этапу.

На первом этапе проверяется соответсвие между хешем redeemScript, записанным в scriptPubKey, и самим redeemScript, записанным в scriptSig. Тем самым подтверждается право на выполнение redeemScript.

На втором этапе в стеке имеются такие данные:
Code:
<Sig1> <Sig2> ... <SigN> <redeemScript>

RedeemScript извлекается из стека и выполняется уже как скрипт, использующий данные, находящиеся в стеке - <Sig1> ... <SigN>. Тут опять же, если результатом выполнения скрипта является 0, то транзакция считается недействительной и наоборот.

Во втором этапе реализуется логика скрипта redeemScript. Если это m-of-n multisig, то проверяется право на трату выхода подписям <Sig1> ... <SigN>.
Всё, вопрос закрыт.
Большое спасибо.
Просто в некоторых местах описывалось, что <redeemScript> исполняется перед OP_HASH160 <redeemScriptHash> OP_EQUAL.
Теперь всё понятно.