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?
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
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
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
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
Enter the following command three times to create three new addresses in this account
Enter this command to view your newly created addresses
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
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.
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.
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:
(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.
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.
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 public 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 transaction 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 ”?)
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:
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
And finally, this will return the transaction has 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.
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 is the number of signature to continue
What the actual transaction does qould be set into the input script.
See here for an example of a transaction with a third party.