多重簽名地址將如何工作?
多重簽名地址將如何工作?它們是由多個傳統地址組成,還是有一些不同的結構?是否能夠指定他們是否需要 2 個簽名中的 2 個、3 個中的 2 個簽名或 N 個簽名中的 M 個?我在哪裡可以找到有關其規格的更多資訊?
我知道這個問題很老了,但我偶然發現它是在尋找如何自學多重簽名地址的工作原理,我想其他人也會這樣做。因此,我將嘗試解釋創建、添加比特幣並最終花費多重簽名地址的典型流程。這個解釋是針對初學者的,所以請原諒我不夠簡潔。首先,我們應該避開一些術語。
比特幣地址:比特幣地址是(通常)33 或 34 位數字的字元串,當我們希望人們向我們發送比特幣時,我們會提供給他們。這是一個公共地址的例子
19evXeJDDLNeRS4st4bGUJNGk8eBgVCCg4
公鑰:公鑰用於派生比特幣地址,儘管知道比特幣地址不會讓您找到該地址對應的公鑰。有關公鑰/比特幣地址關係的更多資訊,請訪問<https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses>。這是上面粘貼的比特幣地址的公鑰的樣子
035739f07de25c205525d81b126ed87bc30377e688705072d186e4f5c88908ce3a
請注意,我只知道該公鑰,因為它與我的私鑰一起儲存在我的錢包中,我在此處發布通常是機密資訊,因為當您有範例時更容易理解比特幣。
多重簽名交易/地址:多重簽名交易只是一個將多重簽名地址作為其輸入之一的交易。多重簽名地址用於製作它,因此需要由不同實體擁有的多個密鑰來移動地址中的比特幣。
好,很好!現在,這裡是製作多重簽名地址的步驟和背景。我將首先用簡單的英語進行解釋,然後使用 bash/Terminal 命令來創建/添加資金到/花費多重簽名地址。我使用標準 bash 定界符“$>”來表示“$>”之後的內容是您應該輸入終端的內容。包含“$>”的行之後的行是該命令的輸出。如果您對輸入的命令有任何疑問,可以在終端中鍵入以下內容以顯示應將哪些參數傳遞給命令
$> bitcoind help <nameofcommandhere>
這個解釋假設你有一個最新的更新並且正在執行的可以接受 RPC 命令的正在執行的 bitcoind 伺服器。
一世。創建將構成多重簽名地址的公鑰。您將使用這些公鑰和另一條資訊來創建您的多重簽名地址。3地址多重簽名地址中最常見的地址分佈(多重簽名地址可能由三個以上的地址組成,但並非所有礦工都支持,因此在此解釋中,我們將處理最常見的3-address multisig address)如下。PubKey#1 通常歸您所有,並儲存在您可以輕鬆訪問的設備上(例如您的手機)。PubKey#2 通常也歸您所有,但儲存在安全的地方(如冷藏或紙質錢包)。PubKey#3 通常是某些第三方的公鑰,例如您的兄弟或提供比特幣相關服務的公司(如 Coinbase)。讓我們將公鑰的這些所有者中的每一個稱為實體。回想一下,比特幣使用私鑰/公鑰加密技術,因此創建公鑰的人也將相應的私鑰保留給自己。這個私鑰在後面的解釋中很重要。因此,讓我們創建 3 個新的公共地址,我們最終將使用它們來創建多重簽名地址!請注意,正如我上面解釋的那樣,如果您在現實世界的情況下使用多重簽名地址,您可能會從某個第三方獲得三個公鑰之一,但對於這裡的解釋,我們將自己創建所有三個. 以下是用於創建公鑰的相關 RPC 命令:這個私鑰在後面的解釋中很重要。因此,讓我們創建 3 個新的公共地址,我們最終將使用它們來創建多重簽名地址!請注意,正如我上面解釋的那樣,如果您在現實世界的情況下使用多重簽名地址,您可能會從某個第三方獲得三個公鑰之一,但對於這裡的解釋,我們將自己創建所有三個. 以下是用於創建公鑰的相關 RPC 命令:這個私鑰在後面的解釋中很重要。因此,讓我們創建 3 個新的公共地址,我們最終將使用它們來創建多重簽名地址!請注意,正如我上面解釋的那樣,如果您在現實世界的情況下使用多重簽名地址,您可能會從某個第三方獲得三個公鑰之一,但對於這裡的解釋,我們將自己創建所有三個. 以下是用於創建公鑰的相關 RPC 命令:
輸入此命令以查看您的所有帳戶。假設您剛開始,您將只有名稱為空字元串且沒有比特幣的帳戶
$> bitcoind listaccounts { "" : 0.00000000 }
輸入以下命令三遍,在該賬戶中新建三個地址
$> bitcoind getnewaddress “"
輸入此命令以查看您新創建的地址
$> bitcoind getaddressesbyaccount “” [ "1CtfcziAhqx83CtSPdufgZDGmL8ohTFTdd", "1JeK7TZR85BL8WvtHgCiTSYtPJupdYYXgR", "1MP3BzdhzoBmGoBiVfLmhv7B4Czxm3MbrU" ]
你還沒有完成。到目前為止,您只看到了公共地址。您需要獲取這些地址的公鑰。幸運的是,您只需鍵入以下命令 3 次即可做到這一點,每次替換您創建的地址之一
$> bitcoind validateaddress <btcaddress> { "isvalid" : true, "address" : "19evXeJDDLNeRS4st4bGUJNGk8eBgVCCg4", "ismine" : true, "isscript" : false, "pubkey" : "035739f07de25c205525d81b126ed87bc30377e688705072d186e4f5c88908ce3a", "iscompressed" : true, "account" : "" }
“pubkey”右邊的值是該地址的公鑰。
ii. 然後,您使用這三個密鑰來創建多重簽名地址。在上一段中,我提到瞭如何需要公鑰和其他資訊來創建多重簽名錢包。該資訊是在多重簽名地址中花費比特幣所需的簽名數量。多重簽名地址的一個有用之處是,為了在地址中發送資金,它需要多個私鑰(我告訴過你我們會回到這些!)簽署交易以使其有效。所以對於這個例子,我們將使用數字 2;三個實體中的兩個將需要簽署交易,以便比特幣可以移動到任何地方。當我們創建多重簽名地址時,bitcoind 將返回多重簽名的 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。在同一個事務中,我們需要“scriptPubKey.txt”中鍵“hex”的值。關於這個值代表什麼,這裡詳細介紹太多了,<https://bitcointalk.org/index.php?topic=377604.0>。在高層次上,scriptPubKey “hex” 值是腳本的十六進制編碼,它作為交易輸入的一部分執行,以驗證交易是否有效。無論如何,我們想要的“十六進制”的值是 a91480cff499983050ec4268d749a1f898bec53e9fc287
還記得我們創建多重簽名地址時,返回的值之一是所謂的“redeemScript”嗎?希望您將其複制並粘貼到某個地方,因為我們也需要它來創建我們的原始交易。這也用於驗證交易是否有效,因此可以在將交易廣播到網路時由節點傳遞。
好的,這是編碼方面最令人困惑的部分;我們將做一些相對低級的比特幣操作,當你將硬幣從一個地址發送到另一個地址時實際發生的事情,儘管使用多重簽名地址會增加複雜性。我們將使用交易雜湊、剛剛找到的 vout 數組中的索引、scriptPubKey、redeemScript,以及將接收我們指定的一定數量硬幣的比特幣地址。完全按照我寫的那樣在終端中輸入以下內容,替換為交易雜湊,替換為 1,替換為 scriptPubKey,替換為兌換腳本,替換為您要將這些比特幣發送到的地址(我使用了我在開始),和(你猜對了)你想發送的金額。不要忘記考慮大約 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 }
您可能很高興注意到“完成”現在是正確的。我們現在只剩下一步了!我們將獲取最後一個命令的輸出,這是一個有效且完全簽名的交易,將比特幣從多重簽名地址發送到您指定的地址,然後使用“sendrawtransaction”命令將其發送出去,如下所示
$> bitcoind sendrawtransaction <fullysignedtransaction> bc26380619a36e0ecbb5bae4eebf78d8fdef24ba5ed5fd040e7bff37311e180d
最後,這將返回您剛剛發出的交易的交易雜湊。
而已!您可以使用 blockchain.info 在網路上查看該交易。現在您知道瞭如何創建多重簽名地址,如何向多重簽名地址匯款,以及最重要的是如何使用這些比特幣。現在請出去幫助製作以使用者友好的方式實現多重簽名交易的錢包軟體。