Как будут работать адреса с мультиподписью?

Как будут работать адреса с мультиподписью? Будут ли они состоять из нескольких традиционных адресов или будут иметь другую структуру? Можно ли будет указать, потребуются ли они 2 из 2, 2 из 3 или M из N подписей? Где я могу узнать больше об их характеристиках?

Мультиподписные адреса функционируют с 2013 года.
@gladoscc Этот вопрос задан 12 января 2013 г.

Ответы (2)

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

Биткойн-адрес: Биткойн-адрес — это строка (обычно) из 33 или 34 цифр, которую мы даем людям, когда хотим, чтобы они прислали нам биткойны. Вот пример публичного обращения

19evXeJDDLNeRS4st4bGUJNGk8eBgVCCg4

Открытый ключ: открытый ключ используется для получения биткойн-адреса, хотя знание биткойн-адреса НЕ позволит вам найти соответствующий открытый ключ этого адреса. Для получения дополнительной информации об отношениях между открытым ключом и биткойн-адресом перейдите по ссылке https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses . Вот как выглядит открытый ключ для биткойн-адреса, вставленного выше.

035739f07de25c205525d81b126ed87bc30377e688705072d186e4f5c88908ce3a

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

Мультиподписная транзакция/адрес: мультиподписная транзакция — это просто транзакция, одним из входов которой является мультиподписной адрес. Адреса с мультиподписью используются для того, чтобы для перемещения биткойнов по адресу требовалось несколько ключей, принадлежащих отдельным объектам.

Ок, отлично! Теперь, вот шаги и предыстория создания мультиподписного адреса. Сначала я объясню все на простом английском языке, а затем расскажу о командах bash/терминала, которые вы будете использовать для создания/добавления денег/расхода мультиподписного адреса. Я использую стандартный разделитель bash «$>», чтобы указать, что все, что идет после «$>», — это то, что вы должны ввести в свой терминал. Строки, идущие после строки, содержащей «$>», являются выводом этой команды. Если у вас когда-либо возникнут вопросы о вводимой вами команде, вы можете ввести в терминал следующее, чтобы показать, какие аргументы должны быть переданы команде.

$> bitcoind help <nameofcommandhere>

В этом объяснении предполагается, что у вас есть актуальное обновление и работающий биткойн-сервер, который может принимать команды RPC.

я. Создайте открытые ключи, которые будут содержать мультиподписной адрес. Вы собираетесь использовать эти открытые ключи и еще одну часть информации для создания своего мультиподписного адреса. Наиболее распространенное распределение адресов в 3-адресном мультиподписном адресе (можно иметь мультиподписной адрес, состоящий из более чем трех адресов, но они поддерживаются не всеми майнерами, поэтому для этого объяснения мы будем иметь дело с наиболее распространенным 3-адресный мультиподписной адрес) выглядят следующим образом. PubKey#1 обычно принадлежит вам и хранится на устройстве, к которому у вас есть легкий доступ (например, на вашем мобильном телефоне). PubKey # 2 обычно также принадлежит вам, но хранится в безопасном месте (например, в холодном хранилище или в бумажном кошельке). PubKey # 3 часто является открытым ключом какой-либо третьей стороны, например, вашего брата или компании, предлагающей услуги, связанные с биткойнами, такие как Coinbase. Назовем каждого из этих владельцев открытого ключа сущностью. Напомним, что Биткойн использует криптографию с закрытым/открытым ключом, поэтому тот, кто создает открытый ключ, также хранит соответствующий закрытый ключ у себя. Этот закрытый ключ будет важен позже в объяснении. Итак, давайте создадим 3 новых общедоступных адреса, которые мы в конечном итоге будем использовать для создания мультиподписного адреса! Обратите внимание, что, как я объяснил выше, если бы вы использовали мультиподписной адрес в реальной ситуации, вы, вероятно, получили бы один из трех открытых ключей от какой-то третьей стороны, но для этого объяснения здесь мы просто создадим все три сами. . Вот соответствующие команды RPC для создания открытых ключей: Этот закрытый ключ будет важен позже в объяснении. Итак, давайте создадим 3 новых общедоступных адреса, которые мы в конечном итоге будем использовать для создания мультиподписного адреса! Обратите внимание, что, как я объяснил выше, если бы вы использовали мультиподписной адрес в реальной ситуации, вы, вероятно, получили бы один из трех открытых ключей от какой-то третьей стороны, но для этого объяснения здесь мы просто создадим все три сами. . Вот соответствующие команды RPC для создания открытых ключей: Этот закрытый ключ будет важен позже в объяснении. Итак, давайте создадим 3 новых общедоступных адреса, которые мы в конечном итоге будем использовать для создания мультиподписного адреса! Обратите внимание, что, как я объяснил выше, если бы вы использовали мультиподписной адрес в реальной ситуации, вы, вероятно, получили бы один из трех открытых ключей от какой-то третьей стороны, но для этого объяснения здесь мы просто создадим все три сами. . Вот соответствующие команды RPC для создания открытых ключей:

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

$> bitcoind listaccounts
{
    "" : 0.00000000
}

Введите следующую команду три раза, чтобы создать три новых адреса в этой учетной записи.

$> bitcoind getnewaddress “"

Введите эту команду, чтобы просмотреть вновь созданные адреса.

$> bitcoind getaddressesbyaccount “”
[
    "1CtfcziAhqx83CtSPdufgZDGmL8ohTFTdd",
    "1JeK7TZR85BL8WvtHgCiTSYtPJupdYYXgR",
    "1MP3BzdhzoBmGoBiVfLmhv7B4Czxm3MbrU"
]

Вы еще не закончили. До сих пор вы видели только публичные адреса. Вам необходимо получить открытые ключи этих адресов. К счастью, вы можете сделать это, просто введя следующую команду три раза, каждый раз заменяя один из созданных вами адресов.

$> bitcoind validateaddress <btcaddress>
{
    "isvalid" : true,
    "address" : "19evXeJDDLNeRS4st4bGUJNGk8eBgVCCg4",
    "ismine" : true,
    "isscript" : false,
    "pubkey" : "035739f07de25c205525d81b126ed87bc30377e688705072d186e4f5c88908ce3a",
    "iscompressed" : true,
    "account" : ""
}

Значение справа от «pubkey» является открытым ключом этого адреса.

II. Затем вы используете эти три ключа для создания мультиподписного адреса. В предыдущем абзаце я упомянул, что вам нужны открытые ключи и еще одна информация для создания мультиподписного кошелька. Эта часть информации — количество подписей, необходимых для того, чтобы потратить биткойны на адрес с мультиподписью. Одна из полезных особенностей адреса с мультиподписью заключается в том, что для отправки денег по адресу требуется несколько закрытых ключей (я же говорил, что мы еще вернемся к ним!), подписывающих транзакцию, чтобы сделать ее действительной. Итак, для этого примера мы будем использовать число 2; два из трех субъектов должны будут подписать транзакцию, чтобы биткойны могли перемещаться куда угодно. Когда мы создадим мультиподписной адрес, биткойн вернет мультиподписной 34-значный адрес, а также набор шестнадцатеричных данных, называемый «redeemScript». Обратите внимание, что первая цифра в адресе — «3». Большинство ваших адресов, вероятно, начинались с «1», но все мультиподписи начинаются с «3». Скопируйте, вставьте и сохраните адрес и значения redeemScript где-нибудь, так как они нам понадобятся немного позже. Итак, мы создаем мультиподписной адрес, введя следующую команду. Обязательно введите апострофы и кавычки точно так же, как я, и замените открытые ключи, которые вы получили от validateaddress.

$> bitcoind createmultisig 2 ‘[“<pubkey>", "<pubkey>", "<pubkey>”]'


{
    "address" : "3DS7Y6bdePdnFCoXqddkevovh4s5M8NhgM",
    "redeemScript" :     "5221027ca87e1aa2595ec7771afee8fdc6efdbc301b8370c4386731b4bd82247dc74a321022cc9874ba092095dd    a47a4e4edb1781c43c35b3ec0429ac005df37b9d6eec94b21035739f07de25c205525d81b126ed87bc30377e6887    05072d186e4f5c88908ce3a53ae"
}

Скопируйте полученный результат куда-нибудь, он нам скоро понадобится.

III. Отправьте несколько биткойнов с одного из ваших кошельков на мультиподписной адрес. Я был удивлен, узнав, что Coinbase не считает адреса с мультиподписью действительными, поэтому, если вы используете Coinbase, вы не можете отправлять напрямую из своего кошелька Coinbase на адрес с мультиподписью. В качестве обходного пути вы можете использовать Coinbase для отправки небольшого количества биткойнов (я отправил на сумму 1 доллар) на один из трех адресов, которые вы изначально создали, дождаться подтверждения этой транзакции, а затем использовать следующую команду для отправки биткойнов с этот обычный адрес на мультиподписной адрес. Замените адрес с мультиподписью и некоторое количество биткойнов, которое стоит меньше, чем сумма, которую вы отправили на обычный адрес. Помните, что вам придется заплатить комиссию за транзакцию! Если команда работает, она вернет хэш транзакции.

$> bitcoind sendtoaddress <bitcoindaddress> <amount>
0ac29fc675909eb565a0984fe13a47dae16ca53fb477b9e03446c898b925ab6b

IV. Наконец, мы собираемся потратить биткойны, которые мы только что получили, на мультиподписной адрес. Мы будем использовать закрытые ключи первых двух адресов, которые мы создали на шаге 1. Чтобы получить закрытые ключи, мы дважды вводим в терминал следующую команду, каждый раз заменяя ее одним из созданных вами биткойн-адресов:

$> bitcoind dumpprivkey <btcaddress>
KyiRjmZYPH7cfyKf1WNb3BZFz1ySurWEYKxLngkH6VmTcSCirBPG

(Кстати, самое худшее, что вы можете сделать в биткойн-сообществе, — это вставить закрытый ключ одного из ваших адресов в общедоступный форум. НИКОГДА НЕ ДЕЛАЙТЕ ЭТОГО! Я делаю это только потому, что хочу убедиться, что читатели могут следуйте моим объяснениям, а в этих адресах всего пара долларов)

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

$> bitcoind getrawtransaction <txid> 1
{
    "hex" : "010000000175783b2ca3381efb15ee7f5f44632a2c699171a924185386460b91d0f211d3bb000000006a47304402207707875d5c29ed0d97cd72087c67c17c57e2ef34d0b6208a054fffece8704477022045aec0ea57830f53fa0e52094400dd4fb654d7712f2ac3341a762d0f46c02d370121027ca87e1aa2595ec7771afee8fdc6efdbc301b8370c4386731b4bd82247dc74a3ffffffff0210270000000000001976a91431e71089318d7b1ea51a1add0dd6525423f713c488ac702402000000000017a91480cff499983050ec4268d749a1f898bec53e9fc28700000000",
    "txid" : "0ac29fc675909eb565a0984fe13a47dae16ca53fb477b9e03446c898b925ab6b",
    "version" : 1,
    "locktime" : 0,
    "vin" : [
        {
            "txid" : "bbd311f2d0910b4686531824a97191692c2a63445f7fee15fb1e38a32c3b7875",
            "vout" : 0,
            "scriptSig" : {
                "asm" : "304402207707875d5c29ed0d97cd72087c67c17c57e2ef34d0b6208a054fffece8704477022045aec0ea57830f53fa0e52094400dd4fb654d7712f2ac3341a762d0f46c02d3701 027ca87e1aa2595ec7771afee8fdc6efdbc301b8370c4386731b4bd82247dc74a3",
                "hex" : "47304402207707875d5c29ed0d97cd72087c67c17c57e2ef34d0b6208a054fffece8704477022045aec0ea57830f53fa0e52094400dd4fb654d7712f2ac3341a762d0f46c02d370121027ca87e1aa2595ec7771afee8fdc6efdbc301b8370c4386731b4bd82247dc74a3"
            },
            "sequence" : 4294967295
        }
    ],
    "vout" : [
        {
            "value" : 0.00010000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 31e71089318d7b1ea51a1add0dd6525423f713c4 OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a91431e71089318d7b1ea51a1add0dd6525423f713c488ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "15Yrv3rAVxYTTGePM3ZZwumSnMfS9St9uD"
                ]
            }
        },
        {
            "value" : 0.00140400,
            "n" : 1,
            "scriptPubKey" : {
                "asm" : "OP_HASH160 80cff499983050ec4268d749a1f898bec53e9fc2 OP_EQUAL",
                "hex" : "a91480cff499983050ec4268d749a1f898bec53e9fc287",
                "reqSigs" : 1,
                "type" : "scripthash",
                "addresses" : [
                    "3DS7Y6bdePdnFCoXqddkevovh4s5M8NhgM"
                ]
            }
        }
    ],
    "blockhash" : "00000000000000002ab5cb0ee400200b8575fe393fef57d41b41a5d533a414a3",
    "confirmations" : 5,
    "time" : 1404775273,
    "blocktime" : 1404775273
}

Найдите ключ «vout», значением которого должен быть массив JSON. Здесь нам нужны два значения; индекс вывода в vout, который имеет наибольшее значение, и значение ключа «hex» в том же выводе. Когда я первоначально отправил эту транзакцию, я отправил 0,00160400 биткойнов. 0,0001 из них пошли на оплату комиссий майнерам, а оставшиеся 0,0010000 пошли на адрес смены, который создало для меня мое клиентское программное обеспечение. Мы хотим использовать вывод с наибольшим значением (здесь 0,00140400) в качестве ввода в нашей транзакции, когда мы создаем необработанную транзакцию. Итак, здесь индекс равен 1. В этой же транзакции нам понадобится значение ключа «hex» в «scriptPubKey. Здесь слишком много подробностей о том, что представляет собой это значение,https://bitcointalk.org/index.php?topic=377604.0 . На высоком уровне «шестнадцатеричное» значение scriptPubKey представляет собой шестнадцатеричное кодирование сценария, который запускается как часть ввода транзакции для проверки правильности транзакции. В любом случае, значение для «hex», которое нам нужно, таким образом, равно a91480cff499983050ec4268d749a1f898bec53e9fc287.

Помните, когда мы создавали мультиподписной адрес, одно из возвращаемых значений называлось «redeemScript»? Надеюсь, вы скопировали и вставили это куда-нибудь, потому что нам это также понадобится для создания необработанной транзакции. Это также используется для проверки того, что транзакция действительна и, таким образом, может быть передана узлами, когда она передается в сеть.

Хорошо, вот самая запутанная часть с кодированием; мы собираемся выполнить несколько относительно низкоуровневых биткойн-операций, которые на самом деле происходят, когда вы отправляете монеты с одного адреса на другой, хотя и с дополнительной сложностью использования адреса с мультиподписью. Мы собираемся использовать хэш транзакции, индекс в массиве vout, который мы только что нашли, scriptPubKey, redeemScript, а также биткойн-адрес, который будет получать определенное количество монет, которое мы укажем. Введите следующее в Терминал точно так, как я написал, заменив на хэш транзакции, на 1, на scriptPubKey, на redeemScript, на адрес, на который вы хотите отправить эти биткойны (я использовал один из трех, которые я создал в start) и (как вы уже догадались) с суммой, которую вы хотите отправить. Не забудьте учесть комиссию за транзакцию примерно 0,0001.

$> bitcoind createrawtransaction '[{"txid”:”<txid>","vout”:<vindex>,"scriptPubKey”:”<scriptPubKey","redeemScript”:”<redeemScript>"}]' ‘{“<sentToAddress”:<amount>}'’


01000000016bab25b998c84634e0b977b43fa56ce1da473ae14f98a065b59e9075c69fc20a0100000000ffffffff0160fd0100000000001976a9145eed147e77af70c64c31c056c3b3474c79c65da088ac00000000

Эта команда только что вернула необработанную транзакцию в шестнадцатеричном коде, это набор байтов, которые биткойн-клиенты транслируют в сеть и которые содержат информацию, необходимую для проверки того, что выходные данные, используемые в качестве входных данных в транзакции, действительны. Но прямо сейчас эта транзакция НЕдействительна, потому что она не была подписана по крайней мере двумя закрытыми ключами, связанными с этим мультиподписным адресом. Давайте сделаем это сейчас. Мы возьмем эту необработанную шестнадцатеричную транзакцию, большую часть информации, которую мы только что ввели в предыдущей команде, и закрытый ключ первого адреса, который мы создали, и подпишем транзакцию. Команда выглядит так, где вы замените вывод предыдущей команды и закрытый ключ первого созданного нами адреса (помните, тот, который мы получили, запустив «bitcoind dumprivkey»?)

$> bitcoind signrawtransaction ‘<rawhextransaction>' '[{"txid”:”<txid>","vout”:<vindex>,"scriptPubKey”:”<scriptPubKey","redeemScript”:”<redeemScript>"}]' ‘[“<privkeyone>”]'


{
    "hex" :     "01000000016bab25b998c84634e0b977b43fa56ce1da473ae14f98a065b59e9075c69fc20a01000000b500483045022100f98068a026e2fc75cfeffe84bbac4223ed172df42bca01fd748a14bd960b1695022062c61a7f4f2a63a65d96b0feaf2a048bc2ca93e5de13013978a187395f880b6d014c695221027ca87e1aa2595ec7771afee8fdc6efdbc301b8370c4386731b4bd82247dc74a321022cc9874ba092095dda47a4e4edb1781c43c35b3ec0429ac005df37b9d6eec94b21035739f07de25c205525d81b126ed87bc30377e688705072d186e4f5c88908ce3a53aeffffffff0160fd0100000000001976a9145eed147e77af70c64c31c056c3b3474c79c65da088ac00000000",
    "complete" : false
}

Вы заметите, что «полный» ключ является ложным. Это потому, что мы предоставили только одну из двух подписей, необходимых для того, чтобы сделать эту транзакцию действительной. Значение для «hex» — это шестнадцатеричное представление необработанной транзакции, которую мы создали, но с включенной одной подписью. Далее мы возьмем транзакцию с одной подписью и подпишем ее закрытым ключом второго созданного нами адреса. Команда терминала очень похожа:

$> bitcoind signrawtransaction ‘<onesigrawtransaction>' '[{"txid”:”<txid>","vout”:<vindex>,"scriptPubKey”:”<scriptPubKey","redeemScript”:”<redeemScript>"}]' ‘[“<privkeytwo>”]'

{
    "hex" : "01000000016bab25b998c84634e0b977b43fa56ce1da473ae14f98a065b59e9075c69fc20a01000000fdfd0000483045022100f98068a026e2fc75cfeffe84bbac4223ed172df42bca01fd748a14bd960b1695022062c61a7f4f2a63a65d96b0feaf2a048bc2ca93e5de13013978a187395f880b6d0147304402201ce986e3fd780f4fe81f40ceb271a8ff34c3845e385b8424f8b20d1b91f1282102205dc71831baf5606f59d06b1d115bda3ec28817cdb4bf9df06643d550c30ef193014c695221027ca87e1aa2595ec7771afee8fdc6efdbc301b8370c4386731b4bd82247dc74a321022cc9874ba092095dda47a4e4edb1781c43c35b3ec0429ac005df37b9d6eec94b21035739f07de25c205525d81b126ed87bc30377e688705072d186e4f5c88908ce3a53aeffffffff0160fd0100000000001976a9145eed147e77af70c64c31c056c3b3474c79c65da088ac00000000",
    "complete" : true
}

Вы, наверное, рады отметить, что теперь «complete» верно. Теперь у нас есть только один шаг! Мы возьмем вывод этой последней команды, которая представляет собой действительную и полностью подписанную транзакцию, отправляющую биткойны с мультиподписного адреса на указанный вами адрес, и отправим ее с помощью команды «senddrawtransaction», например:

$> bitcoind sendrawtransaction <fullysignedtransaction>

bc26380619a36e0ecbb5bae4eebf78d8fdef24ba5ed5fd040e7bff37311e180d

И, наконец, это вернет хэш транзакции, которую вы только что отправили.

Вот и все! Вы можете использовать blockchain.info, чтобы увидеть эту транзакцию в сети. Теперь вы знаете, как создаются мультиподписные адреса, как отправлять деньги на мультиподписные адреса и, самое главное, как тратить эти биткойны. Теперь, пожалуйста, выйдите и помогите создать программное обеспечение кошелька, которое реализует транзакции с несколькими подписями в удобной для пользователя форме.

Это круто. Большое спасибо за этот очень подробный ответ. Я бы +1000 поставил ;)
Что делать, если valueколичество voutисходных транзакций, которые вы используете createrawtransaction, меньше, чем общее количество биткойнов, которые вы хотите отправить? Вам нужно выбрать несколько транзакций, пока не будет достигнута нужная сумма?
@FelipeLima извините, этот ответ так поздно! Взгляните на команду createrawtransaction, и вы увидите, что первый аргумент на самом деле представляет собой массив (это можно определить по квадратным скобкам), который содержит один элемент «txid + vout + scriptPubKey + redeemScript». Это означает, что вы можете передать несколько таких элементов, каждый из которых заключен в фигурные скобки, чтобы указать достаточное количество транзакций с vout, которые равны или превышают количество BTC, которое вы хотите отправить (плюс небольшая дополнительная плата за комиссию майнеров!)
@almel: На самом деле, как два человека (например, A и B) могут коллективно подписать транзакцию с несколькими подписями?
@anhldbk Допустим, сначала A подписывает, они звонят, signrawtransactionи он выводит объект с hexполем. Они отправляют эти шестнадцатеричные данные B, который затем подписывает их и транслирует транзакцию в сеть. Для A безопасно передать полуподписанную транзакцию B, потому что единственное, что B может сделать, это подписать транзакцию. Если они попытаются изменить его, это сделает подпись А недействительной, и Б не сможет транслировать измененный tx, даже если Б его подпишет.
Неправильный. Биткойн-адреса не существует, весь ваш ответ вводит в заблуждение.
@almel можно ли использовать мультиподпись без открытых ключей? Я имею в виду использование только адресов.
@ user2284570 Нет, это не так. Без публичных ключей вы не сможете выполнять подписи и проверки с открытыми ключами. Если у вас есть только адреса, то все, что у вас есть, это хэш SHA256 открытых ключей, который бесполезен для любых алгоритмов цифровой подписи. Что именно вы пытаетесь сделать, что требует от вас использования адресов, но не публичных ключей?

Транзакции в биткойнах на самом деле являются скриптами, где обычно указываются один входной и один выходной адрес. Но есть и другой код операции, такой как сценарий CHECKMULTISIGVERIFY. Каждая подписывающая сторона будет иметь свой собственный открытый ключ, следовательно, свой собственный адрес. Как это работает, как показано:

N K1 K2 K3 M CHECKMULTISIGVERIFY

Где :

-N - количество подписей для продолжения
-K1, K2, K3 Фактические 3 открытых ключа
-M Номер открытого ключа, который вы предоставили

Что делает фактическая транзакция, должно быть установлено во входном скрипте.

См. здесь пример сделки с третьим лицом.