How will multisig addresses work? Will they consist of multiple traditional addresses, or will they have some different structure? Will one be able to specify whether they will require 2 out of 2, 2 out of 3 or M out of N signatures? Where can I find out more about their specification?
2 Answers
I know this question is old, but I stumbled upon it looking how to teach myself how multisig addresses work, and I imagine others will to. So I’m going to try to explain the typical flow for creating, adding bitcoins to, and eventually spending a multisig address. This explanation is aimed at beginners, so please excuse my lack of brevity. First off, some terminology we should get out of the way.
Bitcoin Address: A bitcoin address is a string of (usually) 33 or 34 digits which we give to people when we want them to send us bitcoins. Here is an example of public address
19evXeJDDLNeRS4st4bGUJNGk8eBgVCCg4
Public Key: A public key is used to derive a bitcoin address, although knowing a bitcoin address WILL NOT allow you to find that address’s corresponding public key. For more information on the public key / bitcoin address relationship go to https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses. Here’s what the public key for the bitcoin address pasted above looks like
035739f07de25c205525d81b126ed87bc30377e688705072d186e4f5c88908ce3a
Note that I only know that public key because it’s stored along with my private key in my wallet, I’m posting this usually confidential information here because it is easier to understand bitcoin when you have examples.
Multisig transaction/address: A multisig transaction is just a transaction that has as one of its inputs a multisig address. Multisig addresses are used to make it so multiple keys owned by separate entities are needed to move the bitcoins in an address.
OK great! Now, here are the steps and background for making a multisig address. I’m going to explain things in plain English first, and then follow up with the bash/Terminal commands you will use to create/add money to/spend the multisig address. I’m using the standard bash delimiter “$>” to indicate that whatever comes after the “$>” is what you should enter into your terminal. Lines that come after the line containing “$>” are the output of that command. If you ever have any questions about a command your entering, you can type the following into the Terminal to show what arguments should be passed to the command
$> bitcoind help <nameofcommandhere>
This explanation assumes you have an update to date and functioning bitcoind server running that can accept RPC commands.
i. Create the public keys that will comprise the multisig address. You are going to use these public keys and one other piece of information to create your multisig address. The most common distribution of the addresses in a 3-address multisig address (it’s possible to have a multisig address comprised of more than three addresses, but they’re not supported by all miners so for this explanation we’ll deal with the most common 3-address multisig address) are as follows. PubKey#1 is typically owned by you and stored on a device you have easy access to (like your mobile phone). PubKey#2 is typically also owned by you but stored somewhere secure (like cold storage or in a paper wallet). PubKey#3 is often the public key of some third party, like your brother or a company offering bitcoin-related services like Coinbase. Let’s call each of these owners of a public key an entity. Recall that Bitcoin uses private/public key cryptography, so whomever creates a public key also keeps the corresponding private key to themselves. This private key will be important later in the explanation. So let’s create 3 new public addresses which we’ll end up using to create a multisig address! Note that as I explained above, if you were using a multisig address in a real world situation you’d probably get one of the three public keys from some third party, but for this explanation here we’re just going to create all three ourselves. Here are the relevant RPC commands for creating public keys:
Enter this command to see all your accounts. Assuming you’re starting fresh, you’ll only have the account with the name empty string and no bitcoins in it
$> bitcoind listaccounts
{
"" : 0.00000000
}
Enter the following command three times to create three new addresses in this account
$> bitcoind getnewaddress “"
Enter this command to view your newly created addresses
$> bitcoind getaddressesbyaccount “”
[
"1CtfcziAhqx83CtSPdufgZDGmL8ohTFTdd",
"1JeK7TZR85BL8WvtHgCiTSYtPJupdYYXgR",
"1MP3BzdhzoBmGoBiVfLmhv7B4Czxm3MbrU"
]
You’re not done though. So far you’ve only seen the public addresses. You need to get the public keys of these addresses. Luckily you can do that simply by typing the following command three times, each time substituting for one of the addresses you created
$> bitcoind validateaddress <btcaddress>
{
"isvalid" : true,
"address" : "19evXeJDDLNeRS4st4bGUJNGk8eBgVCCg4",
"ismine" : true,
"isscript" : false,
"pubkey" : "035739f07de25c205525d81b126ed87bc30377e688705072d186e4f5c88908ce3a",
"iscompressed" : true,
"account" : ""
}
The value to the right of “pubkey” is that address’s public key.
ii. You then use these three keys to create the multisig address. In the previous paragraph I mentioned how you needed the public keys plus one other piece of information to create the multisig wallet. That piece of information is the number of signatures needed to spend the bitcoins in a multisig address. One of the useful things about a multisig address is that, in order to send the money in the address, it takes multiple private keys (I told you we’d come back to these!) signing the transaction to make it valid. So for this example we’re going to use the number 2; two out of the three entities will need to sign the transaction in order for bitcoins to move anywhere. When we create the multisig address, bitcoind will return the multisig 34 digit address, as well as a bunch of hex data called the “redeemScript”. Note that the first digit in the address is a “3”. Most addresses your used to probably begin with a “1”, but all multisig begin with “3”. Copy, paste, and save the address and redeemScript values somewhere as we’ll need them in a bit. So, we create the multisig address by entering the following command. Be sure to type the apostrophes and quotes exactly as I have, and substitute for the public keys you got from validateaddress.
$> bitcoind createmultisig 2 ‘[“<pubkey>", "<pubkey>", "<pubkey>”]'
{
"address" : "3DS7Y6bdePdnFCoXqddkevovh4s5M8NhgM",
"redeemScript" : "5221027ca87e1aa2595ec7771afee8fdc6efdbc301b8370c4386731b4bd82247dc74a321022cc9874ba092095dd a47a4e4edb1781c43c35b3ec0429ac005df37b9d6eec94b21035739f07de25c205525d81b126ed87bc30377e6887 05072d186e4f5c88908ce3a53ae"
}
Copy the output that you get somewhere, we will need it soon.
iii. Send some bitcoins from one of your wallets to the multisig address. I was surprised to learn Coinbase doesn’t think that multisig addresses are valid, so if you’re using Coinbase you can’t send directly from your Coinbase wallet to the multisig address. As a workaround, you can use Coinbase to send a small amount of bitcoins (I sent 1 dollar’s worth) to one of the three addresses you originally created, wait for that transaction to get confirmed, and then use the following command to send bitcoins from that regular address to the multisig address. Replace with the multisig address and with some amount of bitcoins worth less than the amount you sent to the regular address. Remember that you’ll have to pay transaction fees! If the command works it will return the transaction’s transaction hash. You can look at this transaction by entering the transaction hash into the search field at blockchain.info.
$> bitcoind sendtoaddress <bitcoindaddress> <amount>
0ac29fc675909eb565a0984fe13a47dae16ca53fb477b9e03446c898b925ab6b
iv. Finally, we’re going to spend the bitcoins we just received in the multisig address. We will use the private keys of the first two addresses we created in step 1. In order to obtain the private keys, we enter the following command twice into the Terminal, each time replacing with one of the bitcoin addresses you created:
$> bitcoind dumpprivkey <btcaddress>
KyiRjmZYPH7cfyKf1WNb3BZFz1ySurWEYKxLngkH6VmTcSCirBPG
(As a side note, the worst possible thing you can do in the bitcoin community is to paste the private key of one of your addresses onto a public forum. NEVER DO THIS! I am only doing this because I want to make sure readers can follow along with my explanation, and there's only a couple dollars in these addresses)
v. Now that you have two public/private key pairs, we can finally spend the bitcoins we sent to the multisig address. To do so, we first need to gather some information about that transaction where we sent bitcoins to the multisig address, because we need to choose the correct output from that transaction to use as the input in the raw transaction we’re about to create. Type the following into the terminal, replacing with the transaction hash that was returned earlier.
$> 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
}
Look for the key “vout”, which should have a JSON array as its value. We need two values here; the index of the output in vout which has the largest value, and the value of the “hex” key within that same output. When I originally sent this transaction I had sent 0.00160400 bitcoins. 0.0001 of that went to paying miner fees, and the remaining 0.0010000 went to a change address that my client software created for me. We’ll want to use the output with the largest value (here 0.00140400) as the input in our transaction when we create our raw transaction. So here the index is equal to 1. In this same transaction we’ll need the value for the key “hex” within “scriptPubKey. It’s too much to go into detail here as to what this value represents, if you’re interested in learning about one of the more fascinating parts of the bitcoin protocol start reading here https://bitcointalk.org/index.php?topic=377604.0. At a high level, the scriptPubKey “hex” value is a hexadecimal encoding of the script that gets run as part of a transaction input in order to verify that the transaction is valid. Anyways, the value for “hex” we want is thus a91480cff499983050ec4268d749a1f898bec53e9fc287
Remember when we created the multisig address one of the values that was returned was something called the “redeemScript”? Hopefully you copied and pasted that somewhere because we’ll need that to create our raw transaction as well. This also is used to verify that the transaction is valid and can thus be passed around by nodes when it is broadcasted to the network.
OK, here comes the most confusing part coding-wise; we’re going to do some relatively low-level bitcoin operations that are what is actually going on when you send coins from one address to another, though with the added complication of using a multisig address. We’re going to use the transaction hash, the index in the vout array we just found, the scriptPubKey, the redeemScript, as well as a bitcoin address which will receive a certain amount of coins we specify. Enter the following into the Terminal exactly as I have written, replacing with the transaction hash, with 1, with the scriptPubKey, with the redeemScript, with the address you want to send these bitcoins to (I used one of the three I created at the start), and (you guessed it) with the amount you want to send. Don't forget to account for a roughly 0.0001 transaction fee. Be warned that the warnings you’ll get are not very descriptive, so make sure you follow this layout exactly.
$> bitcoind createrawtransaction '[{"txid”:”<txid>","vout”:<vindex>,"scriptPubKey”:”<scriptPubKey","redeemScript”:”<redeemScript>"}]' ‘{“<sentToAddress”:<amount>}'’
01000000016bab25b998c84634e0b977b43fa56ce1da473ae14f98a065b59e9075c69fc20a0100000000ffffffff0160fd0100000000001976a9145eed147e77af70c64c31c056c3b3474c79c65da088ac00000000
That command just returned a raw hex-encoded transaction, this is the collection of bytes that bitcoin clients broadcast to the network, and which contain the information necessary to verify that the outputs being used as input in the transaction are valid. But right now this transaction is NOT valid, because it has not been signed by at least two of the private keys that are associated with this multisig address. Let’s do that now. We’re going to take this raw hex transaction, most of the information we just entered in the previous command, and the private key of the first address we created and sign the transaction. The command looks like this, where you’ll replace with the output of the previous command, and with the private key of the first address we created (remember, the one we obtained by running “bitcoind dumprivkey ”?)
$> bitcoind signrawtransaction ‘<rawhextransaction>' '[{"txid”:”<txid>","vout”:<vindex>,"scriptPubKey”:”<scriptPubKey","redeemScript”:”<redeemScript>"}]' ‘[“<privkeyone>”]'
{
"hex" : "01000000016bab25b998c84634e0b977b43fa56ce1da473ae14f98a065b59e9075c69fc20a01000000b500483045022100f98068a026e2fc75cfeffe84bbac4223ed172df42bca01fd748a14bd960b1695022062c61a7f4f2a63a65d96b0feaf2a048bc2ca93e5de13013978a187395f880b6d014c695221027ca87e1aa2595ec7771afee8fdc6efdbc301b8370c4386731b4bd82247dc74a321022cc9874ba092095dda47a4e4edb1781c43c35b3ec0429ac005df37b9d6eec94b21035739f07de25c205525d81b126ed87bc30377e688705072d186e4f5c88908ce3a53aeffffffff0160fd0100000000001976a9145eed147e77af70c64c31c056c3b3474c79c65da088ac00000000",
"complete" : false
}
You’ll note that the “complete” key is false. That’s because we’ve only provided one of the two signatures we need to make this a valid transaction. The value for “hex” is hexadecimal representation of the raw transaction we created, but with one signature included. Next we’re going to take the transaction with one signature and sign it with the private key of the second address we created. The Terminal command is very similar:
$> bitcoind signrawtransaction ‘<onesigrawtransaction>' '[{"txid”:”<txid>","vout”:<vindex>,"scriptPubKey”:”<scriptPubKey","redeemScript”:”<redeemScript>"}]' ‘[“<privkeytwo>”]'
{
"hex" : "01000000016bab25b998c84634e0b977b43fa56ce1da473ae14f98a065b59e9075c69fc20a01000000fdfd0000483045022100f98068a026e2fc75cfeffe84bbac4223ed172df42bca01fd748a14bd960b1695022062c61a7f4f2a63a65d96b0feaf2a048bc2ca93e5de13013978a187395f880b6d0147304402201ce986e3fd780f4fe81f40ceb271a8ff34c3845e385b8424f8b20d1b91f1282102205dc71831baf5606f59d06b1d115bda3ec28817cdb4bf9df06643d550c30ef193014c695221027ca87e1aa2595ec7771afee8fdc6efdbc301b8370c4386731b4bd82247dc74a321022cc9874ba092095dda47a4e4edb1781c43c35b3ec0429ac005df37b9d6eec94b21035739f07de25c205525d81b126ed87bc30377e688705072d186e4f5c88908ce3a53aeffffffff0160fd0100000000001976a9145eed147e77af70c64c31c056c3b3474c79c65da088ac00000000",
"complete" : true
}
You’re probably happy to note that “complete” is now true. We now have only one more step! We’re going to take the output of this last command, which is a valid and fully signed transaction sending bitcoins from a multisig address to an address you specifying, and send it off using the “sendrawtransaction” command, like this
$> bitcoind sendrawtransaction <fullysignedtransaction>
bc26380619a36e0ecbb5bae4eebf78d8fdef24ba5ed5fd040e7bff37311e180d
And finally, this will return the transaction hash for the transaction you just sent out.
That’s it! You can use blockchain.info to see that transaction on the network. Now you know how multisig addresses are created, how to send money to multisig addresses, and most importantly how to spend those bitcoins. Now please, go out and help make wallet software that implements multisig transactions in a user friendly way.
-
This is awesome. Thanks a lot for this very detailed answer. I'd give +1000 ;) Commented Nov 20, 2014 at 16:41
-
What if the
value
on thevout
from the input transaction you're using oncreaterawtransaction
is less than the total bitcoins you want to send? Do you need to select multiple transactions till you reach the amount you need? Commented Nov 21, 2014 at 12:06 -
2@FelipeLima sorry this reply is so late! Take a look at the createrawtransaction command, and you'll see that the first argument is actually an array (you can tell by the square brackets) that contains a single "txid + vout + scriptPubKey + redeemScript" element. That means you can pass multiple of those elements, each contained within curly braces, to specify enough transactions with vouts that are equal to or greater than the amount of BTC you want to send (plus a little extra for miners fees!)– almelCommented Aug 14, 2015 at 16:23
-
@almel: In reality, how two people (A & B, for example) can collectively sign a multisig transaction?– anhldbkCommented Feb 4, 2017 at 8:28
-
@anhldbk Let's say A signs first, they call
signrawtransaction
and it outputs an object with ahex
field. They send this hex data to B, who then signs it and broadcasts the transaction to the network. It's safe for A to hand the half-signed tx to B, because the only thing B can do is sign the transaction. If they try to change it, it will invalidate A's signature and B won't be able to broadcast the changed tx, even if B signs it.– almelCommented Feb 8, 2017 at 23:34
Transcation in bitcoin are actually scripts, where normaly it states one input and one output address. But there are other op code such as CHECKMULTISIGVERIFY script. Each signing party will have their own public key hence their own address. The way it works is as shown:
N K1 K2 K3 M CHECKMULTISIGVERIFY
Where :
-N is the number of signature to continue
-K1, K2, K3 The actual 3 public key
-M The number of public key you provided
What the actual transaction does qould be set into the input script.
See here for an example of a transaction with a third party.