Что означает этот сценарий транзакции?

Я искал скрипты на блочной цепочке, чтобы протестировать мою программу, и я встретил странный scriptPubKey в этом tx что я не мог понять.

Коды операций

pk1 = 02085C6600657566ACC2D6382A47BC3F324008D2AA10940DD7705A48AA2A5A5E33
pk2 = 03F5D0FB955F95DD6BE6115CE85661DB412EC6A08ABCBFCE7DA0BA8297C6CC0EC4
hash1 = D68DF9E32A147CFFA36193C6F7C43A1C8C69CDA530E1C6DB354BFABDCFEFAF3C
hash2 = F531F3041D3136701EA09067C53E7159C8F9B2746A56C3D82966C54BBC553226

OP_PUSHDATA <pk1>
OP_CHECKSIG
OP_SWAP

OP_PUSHDATA <pk2>
OP_CHECKSIG
OP_SWAP

3 OP_PICK
OP_SHA256
OP_PUSHDATA <hash1>
OP_EQUAL

3 OP_PICK
OP_SHA256
OP_PUSHDATA <hash2>
OP_EQUAL

OP_BOOLAND

4 OP_PICK
OP_SIZE OP_NIP
OP_PUSHDATA 0x20
OP_PUSHDATA 0x22
OP_WITHIN

OP_BOOLAND

3 OP_PICK OP_NIP
OP_PUSHDATA 0x20
OP_PUSHDATA 0x22
OP_WITHIN

OP_BOOLAND

OP_IF

3 OP_PICK
OP_SIZE OP_NIP

3 OP_PICK
OP_SIZE OP_NIP

OP_EQUAL
OP_PICK

OP_ELSE
OP_BOOLAND
OP_ENDIF

Я попытался как-то расшифровать его, и это псевдокод в моем понимании

bool pk_script(dat1, dat2, sig1, sig2) {
    if (sha256(dat1) == hash1 &&
        sha256(dat2) == hash2 &&
        size(dat1) == 32 or 33 &&
        size(dat2) == 32 or 33) {
        if (size(dat1) == size(dat2)) {
            return checksig(sig2, pk2);
        } else {
            return checksig(sig1, pk1);
        }
    } else {
        return checksig(sig1, pk1) && checksig(sig2, pk2);
    }
}

Если это правильно, я не могу понять, что делает условие main if, и я не вижу смысла первой ветви.

Результат был потрачен в этом tx , который только толкает две пустые строки и две подписи в scriptSignature.

Может ли кто-нибудь объяснить, в чем смысл остальной части скрипта, кроме проверки достоверности двух подписей?

5 голосов | спросил R. Lin 23 FebruaryEurope/MoscowbFri, 23 Feb 2018 14:45:30 +0300000000pmFri, 23 Feb 2018 14:45:30 +030018 2018, 14:45:30

2 ответа


3

Ваш псевдокод правильный.

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

Таким образом, предположительно каждая сторона генерирует секретное значение, которое является их прообразом хэша. Если какое-либо условие нарушено, то одна сторона может быть вынуждена отказаться от своего хэш-прообраза другой стороне, тем самым позволяя другой стороне тратить все монеты, связанные с выходом.

Но также может быть проведена совместная работа, когда они подписываются на транзакцию. Это фактически похоже на то, что делает сеть Lightning для транзакций с обязательствами.

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

ответил Andrew Chow 23 FebruaryEurope/MoscowbFri, 23 Feb 2018 19:57:32 +0300000000pmFri, 23 Feb 2018 19:57:32 +030018 2018, 19:57:32
4

Попытка увидеть, как этот tx был успешно подтвержден (в 2013 году) в блочной цепочке, должен раскрыться секрет этого скрипта. Предыдущие комментарии дают уже представление о том, что делает скрипт, но не объясняет все. Поэтому я пытаюсь разложить дальше. Предполагается, что sigscript трассировки tx переходит в стек, а затем поверх сценария pubkey. Чтобы проверить подпись, предыдущее финансирование tx нужно было бы преобразовать в неподписанный tx, поэтому я удаляю sig из orig tx, заменяю его скриптом pubkey и изменяю длину входного скрипта:

 01000000 01 A214A2DAF91691AFDD491FD00D894EB3301E35BC18B5554B14E12843037E954C (<-- reverse hex !)
  00000000
  23         (<-- length is decimal 35 Bytes, reversed, hex 0x23)
  2102085C6600657566ACC2D6382A47BC3F324008D2AA10940DD7705A48AA2A5A5E33AC7C2103F5D0FB955F95DD6BE6115CE85661DB412EC6A08ABCBFCE7DA0BA8297C6CC0EC4AC7C5379A820D68DF9E32A147CFFA36193C6F7C43A1C8C69CDA530E1C6DB354BFABDCFEFAF3C875379A820F531F3041D3136701EA09067C53E7159C8F9B2746A56C3D82966C54BBC553226879A5479827701200122A59A5379827701200122A59A6353798277537982778779679A68 (<-- placed pkscript here into sigscript section)
  00000000   (<-- interestingly, Sequence is not FFFFFFFF)
 01 C06C3C0000000000 23 21039DC85F5FE062D4EEF0470FA96D4BBCFFF0096C62042333CD05AD491536560443AC DA538652

, который сериализуется, и double sha256 hashed:

01000000014c957e034328e1144b55b518bc351e30b34e890dd01f49ddaf9116f9daa214a200000000B52102085C6600657566ACC2D6382A47BC3F324008D2AA10940DD7705A48AA2A5A5E33AC7C2103F5D0FB955F95DD6BE6115CE85661DB412EC6A08ABCBFCE7DA0BA8297C6CC0EC4AC7C5379A820D68DF9E32A147CFFA36193C6F7C43A1C8C69CDA530E1C6DB354BFABDCFEFAF3C875379A820F531F3041D3136701EA09067C53E7159C8F9B2746A56C3D82966C54BBC553226879A5479827701200122A59A5379827701200122A59A6353798277537982778779679A680000000001c06c3c00000000002321039dc85f5fe062d4eef0470fa96d4bbcfff0096c62042333cd05ad491536560443acda53865201000000

4eb4dccd727e81315a9ff801c205efc62635471cf8668e42c1c8aebfb51500a3

Этот двойной sha256-хэш, паб-клавиши и сиг (из трассировки tx) соответствуют этим паб-клавишам:

  

ssig1:
  30450221009a29101094b283ae62a6fed68603c554ca3a624b9a78d83e8065edcf97ae231b02202cbed6e796ee6f4caf30edef8f5597a08a6be265d6601ad92283990b55c038fa   pubkey в HEX:   03F5D0FB955F95DD6BE6115CE85661DB412EC6A08ABCBFCE7DA0BA8297C6CC0EC4   pubkey в PEM:   MDYwEAYHKoZIzj0CAQYFK4EEAAoDIgAD9dD7lV + V3WvmEVzoVmHbQS7GoIq8v859oLqCl8bMDsQ =   double sha256:   4eb4dccd727e81315a9ff801c205efc62635471cf8668e42c1c8aebfb51500a3

     

ssig2:
  3044022045d08719828fbd93e49c9223e63f4d2dab2de6c568e1faa2cccb33adf2575d2c02200c00126cb0105275040a963d91e45460147e40451b590485cf438606d3c784cf   pubkey в HEX:   02085C6600657566ACC2D6382A47BC3F324008D2AA10940DD7705A48AA2A5A5E33   pubkey в PEM:   MDYwEAYHKoZIzj0CAQYFK4EEAAoDIgACCFxmAGV1ZqzC1jgqR7w /MkAI0qoQlA3XcFpIqipaXjM =   double sha256:   4eb4dccd727e81315a9ff801c205efc62635471cf8668e42c1c8aebfb51500a3

Быстрая проверка с помощью openssl (отсюда pubkey в формате PEM):

sig=30450221009a29101094b283ae62a6fed68603c554ca3a624b9a78d83e8065edcf97ae231b02202cbed6e796ee6f4caf30edef8f5597a08a6be265d6601ad92283990b55c038fa
pk=03F5D0FB955F95DD6BE6115CE85661DB412EC6A08ABCBFCE7DA0BA8297C6CC0EC4
hash=4eb4dccd727e81315a9ff801c205efc62635471cf8668e42c1c8aebfb51500a3
printf $( echo $hash | sed 's/[[:xdigit:]]\{2\}/\\x&/g' ) > tmp_utx_dsha256.hex
echo "MDYwEAYHKoZIzj0CAQYFK4EEAAoDIgAD9dD7lV+V3WvmEVzoVmHbQS7GoIq8v859oLqCl8bMDsQ=" > cat pubkey.pem
printf $( echo $sig | sed 's/[[:xdigit:]]\{2\}/\\x&/g' ) > tmp_sig.hex
openssl pkeyutl <tmp_utx_dsha256.hex -verify -pubin -inkey pubkey.pem -sigfile tmp_sig.hex

ОК, часть для подписи прозрачна. Поэтому, глядя дальше на pkscript, я попытаюсь декодировать:

pubkey1  21 02085C6600657566ACC2D6382A47BC3F324008D2AA10940DD7705A48AA2A5A5E33 AC 7C
pubkey2  21 03F5D0FB955F95DD6BE6115CE85661DB412EC6A08ABCBFCE7DA0BA8297C6CC0EC4 AC 7C
         53 79 A8 
hash1    20 D68DF9E32A147CFFA36193C6F7C43A1C8C69CDA530E1C6DB354BFABDCFEFAF3C
         87 53 79 A8 
hash2    20 F531F3041D3136701EA09067C53E7159C8F9B2746A56C3D82966C54BBC553226
         87 9A 54 79 82 77 
         01 20
         01 22
         A5 9A 53 79 82 77 
         01 20
         01 22
         A5 9A 63 53 79 82 77 53 79 82 77 87 79 67 9A 68

Проблема, которую я вижу, заключается в том, что ваше утверждение каким-то образом похоже не соответствует:

if (sha256(dat1) == hash1 &&
    sha256(dat2) == hash2 &&
    size(dat1) == 32 or 33 &&
    size(dat2) == 32 or 33) {
    if (size(dat1) == size(dat2)) {
       return checksig(sig2, pk2);
    } else {
       return checksig(sig1, pk1);
    }

Стек будет выглядеть после sigscript:

[ssig2]
[ssig1]
[0x00]
[0x00]

И в верхней части списка будет следовать:

21: OP_DATA_0x21:        length compressed Public Key (X9.63 form, 33 Bytes)
    02085C6600657566:ACC2D6382A47BC3F:324008D2AA10940D:D7705A48AA2A5A5E:33
    corresponding bitcoin address is:   152q849uVmoB5oRcZ4d4tJHyRuB6FPB9Hz  
AC: OP_CHECKSIG:         sig must be a valid sig for hash and pubkey

- это проверит pubkey1 на ssig2, удалит pubkey и [ssig2] из стека и оставьте [TRUE] в стеке

7C: OP_SWAP:             top two items on stack are swapped

- это заменит [ssig1] [TRUE], поэтому [ssig1] находится поверх стека

21: OP_DATA_0x21:        length compressed Public Key (X9.63 form, 33 Bytes)
    03F5D0FB955F95DD:6BE6115CE85661DB:412EC6A08ABCBFCE:7DA0BA8297C6CC0E:C4
    corresponding bitcoin address is:   1BaJ2fYiAVnZC73MtX1LsyJBtXNZWDSkt6
AC: OP_CHECKSIG:         sig must be a valid sig for hash and pubkey

- это проверит pubkey2 на ssig1, удалит pubkey и [ssig1] из стека,     и оставьте [TRUE] в стеке     [0x00] [0x00] [TRUE] [TRUE]

7C: OP_SWAP:             top two items on stack are swapped

- это заменит [TRUE] [TRUE], причина нечеткая

53: OP_3:                the number 3 is pushed onto stack

- верхний элемент стека равен «3»     [0x00] [0x00] [TRUE] [TRUE] [0x53]

79: OP_PICK:             item n back in stack is copied to top

- это будет выталкивать 1 элемент из стека и приносить [0x00] в начало стека:     [0x00] [0x00] [TRUE] [TRUE] [0x00]

A8: OP_SHA256:           input is hashed using SHA-256
20: OP_Data:             next 32 bytes is data to be pushed on stack
    D68DF9E32A147CFF:A36193C6F7C43A1C:8C69CDA530E1C6DB:354BFABDCFEFAF3C
87: OP_Equal:            Returns 1 if inputs are equal, 0 otherwise

- hashed значение [0x00], положите OP_DATA сверху и сравните его. OP_EQUAL выталкивает два     элементы из стека. Это даст [FALSE] в стеке. Состояние стека:     [0x00] [0x00] [TRUE] [TRUE] [FALSE]

53: OP_3:                the number 3 is pushed onto stack
79: OP_PICK:             item n back in stack is copied to top

- это выберет значение [TRUE]

A8: OP_SHA256:           input is hashed using SHA-256
20: OP_Data:             next 32 bytes is data to be pushed on stack
    F531F3041D313670:1EA09067C53E7159:C8F9B2746A56C3D8:2966C54BBC553226
87: OP_Equal:            Returns 1 if inputs are equal, 0 otherwise

- hashed значение [0x00], положите OP_DATA сверху и сравните его. OP_EQUAL выталкивает два элемента из стека. Это даст [FALSE] в стеке. Состояние стека: [0x00] [0x00] [TRUE] [TRUE] [FALSE] [FALSE]

- интересно, этот хэш будет соответствовать sha256 (хэш), предоставленному в фонде tx, как упоминалось в предыдущем комментарии. Здесь я остановлю дальнейшую оценку скрипта. Я понимаю, что мы видели сценарий расходов с двумя значениями hex 0x00, за которыми следуют sigs. Это не соответствует псевдокоду? Может быть, больше нравитсяэто:

if (sig1 == TRUE && 
    sig2 == TRUE &&
    sha256(dat1) == hash1 &&
    sha256(dat2) == hash2 &&
    size(dat1) == 32 or 33 &&
    size(dat2) == 32 or 33) 
    ...

Тем не менее: у меня есть «один на один» при втором значении хэша (F531F3041D313670 ...). Для доступа к одному из предоставленных хэш-изображений должен быть OP_4 или OP_5 (вместо OP_3). Со значением 3 OP_PICK скопирует [TRUE] (из проверки sig) сверху, вместо хеш-изображения в позиции 4 или 5 ...

Я не выполнил следующие коды операций, есть больше условий. Также номер последовательности - «00000000» (не «FFFFFFFF»), а LockTime - «DA538652» (десятичный), который больше 500'000'000, что означает временную отметку unix. Это переводится на дату: Пт 15 Ноя 2013 18:03:22 CET. Tx появился в блокчейне в 2013-11-15 17:13:23.

Итак, я думаю, что этот tx был структурирован таким образом, что кто-то дал ключевое слово tx второй стороне, и вам нужно было подписать и «узнать» ключевое слово. Да, тип мультисиг. И это не может быть потрачено до определенного момента времени (tx будет храниться в mempool, но мы больше не можем этого видеть). Else только владелец сможет потратить tx ...

Скорее всего, это больше, я оставляю это экспертам для декодирования оставшейся части: -)

ответил pebwindkraft 25 FebruaryEurope/MoscowbSun, 25 Feb 2018 10:36:52 +0300000000amSun, 25 Feb 2018 10:36:52 +030018 2018, 10:36:52

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132