Intoduction to Multisig Scripts

I’ve decided to go through creating a multisig address using libbitcoin both because it’s one of the powerful features of bitcoin and it allows me to see the abstraction libbitcoin uses to manage bitcoin scripting without having to go through an entire transaction.

For this practice script I’m going to be using the HD wallet class I created in my previous tutorial, so go here if you haven’t built that yet or just go here to grab the source code. The one adjustment I’m going to make to the wallet class is adding the functionality to randomly generate a wallet from entropy as an argument-free constructor.


 HD_Wallet()
 {
      entropy = data_chunk(16);
      pseudo_random_fill(entropy);
      mnemonic = wallet::create_mnemonic(entropy);
      seed = to_chunk(wallet::decode_mnemonic(mnemonic));
      privateKey = wallet::hd_private(seed);
      publicKey = privateKey.to_public();
 }

With that addition, I’m going to save the “HD_Wallet.cpp” file and create a new one named “scriptingTest.cpp”. I’ll then need to add my include statements for my wallet class and libbitcoin’s library as well as namespacing the scopes I want to work with, which in this case is going to be “wallet”, “machine” and “chain”.


#include <bitcoin/bitcoin.hpp>
#include "HD_wallet.cpp"


using namespace bc;
using namespace bc::wallet;
using namespace bc::machine;
using namespace bc::chain;

Multiple Signature Addresses

Multisig Addresses take advantage of bitcoin’s scripting language and the concept of pay-to-script hash addresses in order to trustlessly create a conditional account whose funds can only be spent if the conditions are met, in the case of multisig that means reaching a preset threshold of keys present in a transaction.

For example, say you’re managing a team of three researchers and want to give them an expense account for the project but want to make sure that there is at least some discussion and agreement on purchases. You could create a 2 of 3 multisig address that requires at least two of the three keys to be present and sign the transaction in order to spend any money, which means if two out of the three researchers don’t think the purchase is a good idea the purchase won’t happen.

For this utility, I’ll want to create 3 keys and then use them to generate the multisig address I’ll be funding with the proper conditions (2 of 3). I would then need to distribute the corresponding private keys to my researchers for spending.

Multisig Utility

  • Generate 3 sets of Keys
  • Create a 2/3 redeem script
  • Create a pay to script hash locking script
  • Output the resulting multisig address
  • Output three mnemonics for the private keys

In more practical uses the researchers could simply send their own public keys to me in order to generate the address since private keys are not required for the construction of a multsig address.

Multisig Addresses are created by using bitcoin’s specialized scripting language to create a locking script that can only be satisfied by the hash of a signature from a certain number of keys. Their are three parts to a multisig transaction the “redeem script”, this will encode the rules of the address and the hash of this script gets encoded into an address, “the locking script”, this is a special pay to script hash(P2SH) script which includes a hash of the redeem script. The last part is the unlocking script which is the combination of the signatures and the redeem script required to spend money from the address.

The redeem script sets the rules for the address, which in this case is a relatively easy template script:

2 [PUBKEY1] [PUBKEY2] [PUBKEY3] 3 CHECKMULTISIGVERIFY

By making this script into a P2SH address we’re able to get a multisig bitcoin address that can be paid just like any other address.

That means we would double hash the above script using sha256 and then ripemd160 and put that hash in the following script to create what is known as the Locking Script.

HASH160 [20-byte script hash] EQUAL

The 20-byte has of the original MultiSig script would then be base58-check encoded to a bitcoin address.

358vPZP3zaBpNMatFgRBxX58ftUbqDreMN

All multisig Addresses start with a 3.

The Code

Okay, so now that we have the concept down let’s dive into some code. Since this utility is just a script, I’m going to put the whole thing in the main function. To start I’ll need to generate 3 HD wallets using the empty constructor I just added. From there, I’ll need to derive a child key from each of them and save the compressed public key as a data chunk.


 HD_Wallet wallet1 = HD_Wallet();
 HD_Wallet wallet2 = HD_Wallet();
 HD_Wallet wallet3 = HD_Wallet();

 data_chunk pubkey1 = to_chunk(wallet1.childPublicKey(1).point());
 data_chunk pubkey2 = to_chunk(wallet2.childPublicKey(1).point());
 data_chunk pubkey3 = to_chunk(wallet3.childPublicKey(1).point());

Scripting

Bitcoin has it’s own scripting language consisting of various op_codes used to program transactions. The libbitcoin framework has three basic structures for scripting. The first is a c++ enum class of all the opcodes allowing us to pass opcodes to a constructor and return the operation. The next is an operation object to hold all the members and routines of an operation. One level higher is the script object which takes a bunch of operations and accesses all the serialization and validation routines for the entire script.

So, to build our script we are going to take advantage of a special operation type list which is a vector of operations. First we pass the opcode to the opcode enum class and pass that opcode to an operation object which we in turn are passing to our operation vector(list).

We’re passing the code ’82’ first which corresponds to push positive 2, our scripts first argument. Then we pass The three public keys. After doing that for all 3 public keys we pass the codes for 3 and checkmultisigverfy.

After we have the whole operation list we pass the vector to a script constuctor.


operation::list opList {operation(opcode(82)), operation(pubkey1), operation(pubkey2), operation(pubkey3), operation(opcode(83)), operation(opcode(174))};
script multisigScript(opList);
if(script().is_pay_multsig_pattern(opList)
{
     std::cout << "Is Multisig Pattern!" << std::endl;
}

We can then check the validity of our script before we output it to the console both as a string and in hex.


 if(multisigScript.is_valid())
 {
     std::cout << "Script is Valid!\n" << std::endl;
 }else{
     std::cout << "Script Invalid! \n" << std::endl;
 }

 std::cout << "Redeeem Script: \n" << std::endl;
 std::cout << multisigScript.to_string(0) << "\n" &lt;&lt; std::endl;
 std::cout << encode_base16(multisigScript.to_data(0)) << "\n" << std::endl;

Now, we can use the libbitcoin function “bitcoin_short_hash” to invoke the hash ripemd160(sha256(script)). Then using a special factory member of the script object we can pass the hash into a template stack for a pay to script hash type transaction.

short_hash scriptHash = bitcoin_short_hash(multisigScript.to_data(0));
script pay2ScriptHash = script(multisigScript.to_pay_script_hash_pattern(scriptHash));

After that we have created a P2SH script which allows us to view the locking script. The original MultiSig script can then be hashed and encoded as an address whose balance will only be spendable if the underlying multsig script is satisfied. We can pass the libbitcoin payment_address() either the redeem scripts hash or the script object itself and retrieve the multisig address.


 std::cout << "Locking Script: " << std::endl;
 std::cout << pay2ScriptHash.to_string(0) << "\n" << std::endl;

 payment_address multsigAddress(multisigScript);
 std::cout << "Payment Address: " << std::endl;
 std::cout << multsigAddress.encoded() << "\n" << std::endl;
 std::cout << payment_address(scriptHash).encoded() << "\n" << std::endl;

Once the address is funded, I can distribute to my researchers the three mnemonic seeds whose first child key corresponds to this address.


 std::cout << "Private Key Mnemonics: \n" << std::endl;
 std::cout << "Key One: " << wallet1.displayMnemonic() << std::endl;
 std::cout << "Key Two: " << wallet2.displayMnemonic() << std::endl;
 std::cout << "Key Three: " << wallet3.displayMnemonic() << "\n" << std::endl; 

Now, this script can be compiled an run as usual and the result should look something like usual.

Funds sent to this address can only be spent in a transaction that includes the unlocking script consisting of at least 2 of the private keys signatures and the redeem script. My next post will go over creating a transaction from this multisig address.

As always sample code is on Github.

Libbitcoin: Interactive HD Keychain Part 2/2

HD Keychain.

Now that I’ve created my keychain object I just need to write a command line interface for the user to interact with the class. To do this I’ll need to start with a separate file and in that file I’m going to use my usual includes and namespace but with the addition of the file that contains the HD wallet class I’ve just created.

	#include <bitcoin/bitcoin.hpp>
	#include <string.h>
	#include <iostream>
	#include "HD_Wallet.cpp"

	using namespace bc;

Now, for this program I’m going to want a main menu and a sub-menu for the display options.


void mainMenu()
{
	std::cout << "\n==========================" << std::endl;
	std::cout << "1. Generate New Wallet" << std::endl;
	std::cout << "2. Import Wallet" << std::endl;
	std::cout << "3. display" << std::endl;
	std::cout << "4. Exit" << std::endl;
	std::cout << "==========================" << std::endl;
}

void displayMenu()
{
	std::cout << "\n==========================" << std::endl;
	std::cout << "1. Private Key" << std::endl;
	std::cout << "2. Mnemonic" << std::endl;
	std::cout << "3. Child Private Key" << std::endl;
	std::cout << "4. Payment Address" << std::endl;
	std::cout << "5. Address Range" << std::endl; 
	std::cout << "6. Dump Keys" << std::endl;
	std::cout << "7. Exit" << std::endl;
	std::cout << "==========================" << std::endl;
}

Once I have my menu I’m going to want to write a function to get the user’s menu selection and return it as an integer. Simple enough with the standard library.

int getInput()
{
	int choice;
	std::cout << "Enter a Number: "; 
	std::cin >> choice;
	return choice;

}

I also want the user to be able to import a wallet via it’s seed, so I’ll need a function that takes the users mnemonic and converts it to a word_list object before returning it. Note that the split function here splits a string up by each space and puts it into a word list.


wallet::word_list getWordList()
{
	std::string mnemonicSeed;
	std::cout << "Enter Seed String:";
	cin.ignore();
	std::getline(cin, mnemonicSeed);
	return split(mnemonicSeed);
}

Okay, with these helper functions done, I now need a function to initialize my HD_Wallet object from 128-bits of entropy and then return that object. For good measure I’m also going to have this function call it’s dumpKeys member and display all the newly created keys to the user.



HD_Wallet randomGen()
{
	data_chunk entropyChunk = data_chunk(16);
	pseudo_random_fill(entropyChunk);
	HD_Wallet(entropyChunk).dumpKeys();
	return HD_Wallet(entropyChunk);
}

With that done, I’m now going to write my driver function. Everything from here on is going to go in the main function.

Starting with initializing a wallet object using the randomGen() function.



int main(){
	HD_Wallet wallet = randomGen();
}

For the user interface, I’m going to use a while loop and since “option 4” maps to exit in the menu I’m going to have it loop as long as choice does not equal 4. To get this loop started I’m going set the choice variable to 0 and immediately inside the while loop call the main menu function and setting the choice variable to whatever gets return by the get input function.



int choice = 0;
	while(choice != 4)
	{
		mainMenu();
		choice = getInput();
	}

From there, I just fill out if statements with functions corresponding to the options in the menu.
Here I’ve filled in the options for the two types of wallet constructors.



int choice = 0;
	while(choice != 4)
	{
		mainMenu();
		choice = getInput();
		if(choice == 1)
		{	
			wallet = randomGen();
		} else if(choice == 2)
		{	
			wallet::word_list mnemonicSeedList = getWordList();
			if(wallet::validate_mnemonic(mnemonicSeedList))
			{
				wallet = HD_Wallet(mnemonicSeedList);
				wallet.dumpKeys();
			} else {
				std::cout << "Mnemonic Invalid!" << std::endl;
			}

		}

	}

Now, for the display menu I just need to replicate this while loop and simply nest it inside another if statement but instead of calling the main menu I need to call the display menu. Similarly, I need to fill out the if statements inside of this while loop with the corresponding options in the display menu.



int choice = 0;
	while(choice != 4)
	{
		mainMenu();
		choice = getInput();
		if(choice == 1)
		{	
			wallet = randomGen();
		} else if(choice == 2)
		{	
			wallet::word_list mnemonicSeedList = getWordList();
			if(wallet::validate_mnemonic(mnemonicSeedList))
			{
				wallet = HD_Wallet(mnemonicSeedList);
				wallet.dumpKeys();
			} else {
				std::cout << "Mnemonic Invalid!" << std::endl;
			}

		}

	}else if (choice == 3)
		{	
			while(choice != 7){
				displayMenu();
				choice = getInput();
				std::cin.ignore();
				int index;
				
				if(choice == 1)
				{
					wallet.displayPrivateKey();
				} else if(choice == 2) 
				{
					wallet.displayMnemonic();

				} else if (choice == 3)
				{
					index = getInput();
					wallet.displayChildPrivateKey(index);

				} else if (choice == 4)
				{
					index = getInput();
					wallet.displayAddress(index);
				} else if (choice == 5)
				{
					int start = getInput();
					int end = getInput();
					wallet.addressRange(start, end);
				}else if (choice == 6)
				{
					wallet.dumpKeys();
				}else if (choice == 7)
				{
					std::cout << "Bye" << std::endl;
				} else
				{
					std::cout << "Selection Invalid! " << std::endl;
				}
			}
		}
	}

Now I just need to add a goodbye message and an invalid input catcher to the main while loop and the program is ready to go. The complete main function should look like this:



int main(){
	HD_Wallet wallet = randomGen();
	int choice = 0;
	while(choice != 4)
	{
		mainMenu();
		choice = getInput();
		if(choice == 1)
		{	
			wallet = randomGen();
		} else if(choice == 2)
		{	
			wallet::word_list mnemonicSeedList = getWordList();
			if(wallet::validate_mnemonic(mnemonicSeedList))
			{
				wallet = HD_Wallet(mnemonicSeedList);
				wallet.dumpKeys();
			} else {
				std::cout << "Mnemonic Invalid!" << std::endl;
			}

		} else if (choice == 3)
		{	
			while(choice != 7){
				displayMenu();
				choice = getInput();
				std::cin.ignore();
				int index;
				
				if(choice == 1)
				{
					wallet.displayPrivateKey();
				} else if(choice == 2) 
				{
					wallet.displayMnemonic();

				} else if (choice == 3)
				{
					index = getInput();
					wallet.displayChildPrivateKey(index);

				} else if (choice == 4)
				{
					index = getInput();
					wallet.displayAddress(index);
				} else if (choice == 5)
				{
					int start = getInput();
					int end = getInput();
					wallet.addressRange(start, end);
				}else if (choice == 6)
				{
					wallet.dumpKeys();
				}else if (choice == 7)
				{
					std::cout << "Bye" << std::endl;
				} else
				{
					std::cout << "Selection Invalid! " << std::endl;
				}
			}
		} else if (choice == 4)
		{
			std::cout << "Goodbye" << std::endl;
		}else {
			std::cout << "Selection Invalid!" << std::endl;
		}
	}
}

The entire program can be found at https://github.com/AaronJaramillo/LibbitcoinTutorial

The program can now be compile as usual, though this time passing both files to the compiler, with:


$ g++ -std=c++11 -o HDwallet HD_wallet.cpp wallet.cpp $(pkg-config --cflags libbitcoin --libs libbitcoin)

$ ./HDwallet

And the initial output should look something like this:

HDKeychain_Menu

 

 

Libbitcoin: Interactive HD Keychain Part 1/2

HD Keychain.

So, now that we’ve looked into how HD keys are used, I’ve decided to put together a proper HD keychain program that will allow a user to manage Hierarchical Deterministic keys from the command line.

The program I build is going to have the following features:

• Allow the user to generate a new wallet from entropy
• Allow the user to import a wallet from its mnemonic seed
• Allow the user to display:

o The mnemonic
o The master private key
o Its children’s private keys
o a child Address
o a range of child addresses
o All keys at once

This program is not going to support building and signing transactions and it won’t be connected to the blockchain and therefore will not be able to check balances. Thus, this program is technically a keychain rather than a wallet.

So, to implement this wallet I am going to create an HD_Wallet class to hold all the functionality and in a separate driver file I will have functions that handle interfacing with the user.

To start I am going to fire up sublime, create a file named HD_Wallet.cpp and include my necessary headers.

	#include <bitcoin/bitcoin.hpp>
	#include <string.h>
	#include <iostream>

	using namespace bc;

After, I’m going to create a class called HD_Wallet and declare 2 constructor functions, one to create an object from entropy and another to create an object from a mnemonic seed. Additionally, I’m going to need to declare variables for the necessary keys as private members of the class. So, my class skeleton is going to look like this.


class HD_Wallet
{
public:

	//constructor
	HD_Wallet(const data_chunk Userentropy)
	{
		
	}

	HD_Wallet(const wallet::word_list mnemonicSeed)
	{

	}
private:
	//members
	data_chunk entropy;
	data_chunk seed;
	wallet::word_list mnemonic;
	wallet::hd_private privateKey;
	wallet::hd_public publicKey;


};

Now that I have the basics of this object I need to fill out the constructor function, starting with the constructor from entropy. First I’m going to take the entropy argument, which should be 16 byte (64-bit) datachunk, and store it in the classes entropy member. Next, I need to set the mnemonic member by using libbitcoin’s create_mnemonic function and passing it the entropy variable. Once I have the mnemonic, I can create the wallets seed by using the decode_mnemonic function and storing the returned hash in the seed variable. From there, I just need to set the master private key and public key using the libbitcoin objects we saw in my previous post.

Here’s how my first constructor looks:


HD_Wallet(const data_chunk Userentropy)
{
	entropy = Userentropy;
	mnemonic = wallet::create_mnemonic(entropy);
	seed = to_chunk(wallet::decode_mnemonic(mnemonic));		
    privateKey = wallet::hd_private(seed);
	publicKey = privateKey.to_public();
}

Mnemonics

Mnemonics are a human readable way to represent a wallets seed. Our HD wallet is created by using a pseudo-random number generator to create 64 bits of random data which is then hashed using a specialized HMAC512 function which is then used as the seed for creating the private/public key pair.

The encode_mnemonics function in the libbitcoin framework takes the 128 bits of entropy and, using a specialized word list, encodes it as a series of words, where every 3 words represents 32 bits of data. Our 128 bits of data is then represented by 12 words which the user can write down and store somewhere physically.

The decode_mnemonics function then takes a mnemonic as an argument and returns it’s hashed 512 bit seed. Note that the decode function will not return the original 128 bits of data that was encoded to create the seed as the seed already represents this data in the form of words rather than hexadecimal encoding.

The hashed 512 bit seed can then be passed to an HD_private constructor to generate a wallet’s private key.

Thus, in order to make my mnemonic constructor function for importing a wallet we are going to need to pass a mnemonic word_list as an argument to the function. From there I need to use the decode function to get the hashed seed and cast that seed as a data chunk type before storing it in the seed variable. Once I have the seed, I can just save the mnemonic in the proper variable and use the private / public key constructors with the data_chunk seed. The import wallet constructor should look like this.


HD_Wallet(const wallet::word_list mnemonicSeed)
{
	seed = to_chunk(wallet::decode_mnemonic(mnemonicSeed));
	mnemonic = mnemonicSeed;
	privateKey = wallet::hd_private(seed);
	publicKey = privateKey.to_public();


}

Child Keys

Now that I’ve built the constructor functions I am going to need to make the accessor functions in order to allow my user to access child keys and addresses of the wallet. In order to do this I simply need to use the member functions of the libbitcoin objects I went over in my previous post. Notice that I allow the user to pass the index of the desired child key pair they want. Here’s how my accessors ended up looking:


	wallet::hd_private childPrivateKey(int index)
	{
		return privateKey.derive_private(index);
	}

	wallet::hd_public childPublicKey(int index)
	{
		return publicKey.derive_public(index);
	}

	wallet::payment_address childAddress(int index)
	{
		return wallet::ec_public(childPublicKey(index).point()).to_payment_address();
	}

Display

Now I’m going to create the display functions to output the keys. Since the accessor functions I wrote return libbitcoin’s specialized objects, I can easily access a string encoded version of the key by accessing the serializer functions through the accessor in my custom class. For the child keys, I also pass an index variable and create a separate function to display a range of child addresses by creating a loop to call the display function with different indices.

Here’s how my display functions look:

	void displayPrivateKey()
	{
		std::cout << "\nPrivate Key:" << privateKey.encoded() << std::endl;
	}

	void displayChildPrivateKey(int index)
	{
		std::cout << "\nChild Key: " << childPrivateKey(index).encoded() << std::endl;
	}

	void displayAddress(int index)
	{
		std::cout << "\nAddress: " << childAddress(index).encoded() << std::endl;
	}

	void addressRange(int start, int end)
	{
		while(start != end)
		{
			displayAddress(start);
			start++;
		}
	}

Finally, I just need to add a function to display the mnemonic seed. To do this, I’m going to first use and if statement to validate the mnemonic and then cast the word_list variable as a string using the join function. From there I can just use the standard cout function to display it.


	void displayMnemonic()
	{
		if(wallet::validate_mnemonic(mnemonic))
		{
			std::string mnemonicString = join(mnemonic);
			std::cout << "\n" << mnemonicString << std::endl;

		}else{
			std::cout << "mnemonic invalid!" << std::endl;
		}
	}

Now that I have all the display functions I can create a function to display all the keys by simply calling all of the functions I’ve just created, like so:


void dumpKeys()
{
	displayMnemonic();
	displayPrivateKey();
	displayChildPrivateKey(1);
	displayAddress(1);

}

With that, I’ve created my entire HD wallet keychain class. In part 2 of this post I will be creating the command line interface to use this object. As always the full code to this tutorial can be found at https://github.com/AaronJaramillo/LibbitcoinTutorial

Libbitcoin: HD Keys

Modern Wallets use Hierarchical Deterministic(HD) Keys rather than simple keys in order to allow a user to use a different bitcoin address with every transaction.

Today, We’re going to program an HD keychain that generates all the necessary keys for a bitcoin wallet. This is going to allow us to see how all the special data structures are used to represent keys in libbitcoin.

HD keys are comprised of a Master Key, a Chain code, and an index all of which are used to derive child public/private keys and thereby generating unlinkable bitcoin addresses which are all cryptographically usable by the same master key. This allows the user to create a custom and complex wallet structure involving different addresses for different purposes and spendable with only with certain keys while maintain a central point of control with the master key. For example, a certain set of keys might be used as a change addresses while others are used for receiving customer funds. Additionally, certain private keys can be used as employee expense accounts by limiting access to a certain set of funds.

Our program is going to be a simple HD keychain generator which generates a brand new set of HD keys from entropy and displays all of it’s elements including a mnemonic designed to be a more human readable form of the seed to be stored.

Start out by including the necessary libraries and namespaceing libbitcoin.

#include <bitcoin/bitcoin.hpp>
#include <string.h>
#include <iostream>


using namespace bc;

Now, in our main function we are going to need to create a seed using the pseudo-randomness generator. This seed is going to be hashed into out private key so the more random the more secure it will be. For this we first need to declare a data chunk variable and declare it’s size since libbitcoin’s randomness function allows us fill it directly. Since a data chunk is a vector of bytes(8 bit structures) we are going to declare 16 bytes which allows us enough room for a 128 bit seed, the standard for a “short seed”. Then we simply call the utility function for pseudo random fill on the chunk and then call the encode base16 function on it to print it in hex format to the console.

	data_chunk seedChunk(16);
	pseudo_random_fill(seedChunk);
	std::cout << "\nHex Seed: " << std::endl;
	std::cout << encode_base16(seedChunk)<< std::endl;

Once we have the seed we need to generate a mnemonic in order to make it easier to write down. To do so we declare a “word_list” type variable and store the return result of our “create_mnemonic” function in it. Here, again, we need to remember to scope the wallet namespace.

Please Note: This mnemonic will not be able to retrieve the seed within the libbitcoin framework. Since we are using a simple seed to generate the private keys rather than hashing. The libbitcoin function to decode these mnemonics rely on hashed seeds. I will explain this in depth in my following post.

wallet::word_list writtenWord = wallet::create_mnemonic(seedChunk);
Now we use the validator function to make sure it worked and print out the mnemonic by iterating over the word list.
 
if(wallet::validate_mnemonic(writtenWord)){ for (auto i = writtenWord.begin(); i != writtenWord.end(); ++i) 
std::cout << *i << ' '; 
}else{ std::cout << "mnemonic invalid!" << std::endl; } 

Once we have the seed, we just need to insatiate the keys using the special libbitcoin objects in the same way describe in my previous post except that now we will specify the type as HD.

For the private keys take note of the member functions used to display the keys. Calling the serializer function “encoded()” displays the base58check(WIF) format of the key while calling “to_hd_key()” returns the raw byte array which can be encoded using hex for display:

	wallet::hd_private privateKey(seedChunk);
	std::cout << "\n\nMaster Private Key: " << std::endl;
	std::cout << privateKey.encoded() << std::endl;

	wallet::hd_key keys = privateKey.to_hd_key();
	std::cout << "\nHex Master Private Key: " << std::endl;
	std::cout << encode_base16(keys) << std::endl;

Next, using the master private key object’s factories we can derive the public key easily.

	wallet::hd_public publicKey = privateKey.to_public();
	std::cout << "\nMaster Public Key: " << std::endl;
	std::cout << publicKey.encoded() << std::endl;

Now that we have generated the master keys, deriving the child keys is once again relatively simple using the private key’s factory methods. Although, it is important to notice that we are passing an index as an argument to the “derive_private” method. The index is useful for keeping track of the structure of your wallet, for example, keys derived from index 1 – 5 are used as receiving addresses while 6-9 are used for chain address.

	wallet::hd_private childPrivateKey = privateKey.derive_private(1);
	std::cout << "\nChild Private Key: " << std::endl;
	std::cout << childPrivateKey.encoded() << std::endl;

Same goes for the public key.

	wallet::hd_public childPublicKey = privateKey.derive_public(1);
	std::cout << "\nChild Public Key: " << std::endl;
	std::cout << publicKey.encoded() << std::endl;

Finally, we can display a payment address spendable by our master key but not obviously associated with it.

To do this we use the child public keys accessor function “point()”, which returns an elliptic curve public key point that we will use to instantiate an “ec_public” object. Once we have the public key object we will use its factory method “to_payment_address()” and then call the returned address’s serializer function “encoded()” to print it out.

Although, this encoding can be done separately I have shown it as a one liner for the sake of style points.

	std::cout << "\nPayment Adress: " << std::endl;
	std::cout << wallet::ec_public(childPublicKey.point()).to_payment_address().encoded()<< "\n" << std::endl;

Then, just compile as usual and the output should look like this.

HDkeys output

Next, we will be looking at how to persistently manage these keys in a wallet-like environment rather than just generating them.

Libbitcoin: First Program

Working with Private Keys

This example program will walk through converting bitcoin private keys with libbitcoin and will help you get an understanding of how the library is used.

If you don’t already have libbitcoin installed follow my tutorial here.

Our starter program is going to take a 256-bit secret key and convert it to a bitcoin private key in wallet import format. I will go over how the libbitcoin API works as well as how this conversion works on a conceptual level.

Bitcoin Private Keys Explained

Private Keys in Libbitcoin

How It Works

How to Compile with Libbitcoin

Private Keys

Bitcoin private keys are 256-bit hashes generally expressed in wallet import format(WIF) as a base58 checksum encoded number. What does that mean? Basically, a private key is just some sequence of 256 1’s and 0’s which is then encoded into a format that’s easier to read.

Generally, a random number generator is used to produce a seed from entropy which is then hashed using the SHA256 hashing function which returns our coveted 256-bit number. This product of the hashing function is our valuable password(secret key) on the bitcoin network so it is to be protected and kept secret.

This secret key is then encoded to make it easier to read and transfer between wallet software. Secret keys are generally encoded with certain metadata, such as key type, version info and its checksum, resulting in wallet import format. WIF is structured like so:

Version Prefix + Secret Key + Key Type + Checksum

Where, the version prefix for private keys is 128(0x80 in hex) the secret key is the secret key, the key type is 01 if it is a compressed key or not included if it is an uncompressed key. The checksum is the result of a double SHA256 performed on all the previous parts of the key. The first 4 bytes of this hash are then concatenated to the end of the key and the entire thing is base58 encoded.

Base58 encoding is common encoding used with bitcoin and is similar to an encoding like base16(hex) or base64 it is simply optimized to be easier to read by eliminating ambiguous characters such as I(capital i) and l(lowercase L). This is the same format used for bitcoin addresses.

The checksum is used to ensure that no mistakes have been made in the transcription of any of the characters as wallet software will check that the 4-byte hash matches the hash of the rest of the data thus preventing a costly typo based mistake.

The resulting WIF private key can easily be encoded into a QR code for easy transfer.

How to convert a secret key to WIF in Libbitcoin

Now, the fun part. Fire up your text editor and add your includes.


#include <bitcoin/bitcoin.hpp>
#include <string.h>
#include <iostream>

The libbitcoin library is included as bitcoin/bitcoin.hpp. After that we’re going to have to use the libbitcoin namespace as shown below. This is because libbitcoin has multiple sub namespaces to accommodate the ambiguity introduced by a lot of the custom types used.


using namespace bc;

Now, inside our main function we are going to declare our hexadecimal secret key as a string and print it out. In order to create this key we will first need to generate it using a pseudo random number generator.

We’re going to work with a general libbitcoin type called a data_chunk which is just a vector of bytes, specifically a vector of unsigned 8 bit integers. Data chunks are used to represent all kinds of raw data in the libbitcoin toolkit.

For our seed we will first need to declare a data_chunk vector of 16-bytes, this will be used as a buffer which we will fill with entropy using the pseudo_random_fill function. After that, we can declare an ec_secret object. Remember a secret key is distinct from a private key; where, secret key refers to the 256-bit value and private key refers to the secret key plus all its metadata(WIF).

We can create the secret key by sha256 hashing the seed twice, both hashes can be accomplished by using the bitcoin_hash_function

data_chunk seed(16);
pseudo_random_fill(seed);
ec_secret secretKey = bitcoin_hash(seed);

Then, we can use the handy encode_base16 function to encode the vector of raw bytes, AKA our secret_key object, into a base16 formatted string.(Note: these encode/decode function are available for many types including base58, and base64)


std::string hexKey = encode_base16(secretKey);
std::cout << "Hex secret: " << std::endl;
std::cout << hexKey << std::endl;

Now, to convert the secret key using the libbitcoin API we’re going to use the following code:


	ec_secret rawprivateKey;
	decode_base16(rawprivateKey, hexKey);
	wallet::ec_private privateKey(rawprivateKey, 0x8000, false);
	std::cout << "\nPrivate Key Structure: " << std::endl;
	std::cout << privateKey.encoded() << std::endl;
	ec_secret keyTest = privateKey.secret();
	std::string keyTestString = encode_base16(keyTest);
	if(keyTestString == hexKey){
		std::cout << "Confirmed: " <<keyTestString << std::endl;
	} else {
		std::cout << "Error!" <<keyTestString << std::endl;
	}

The first line here declares a special libbitcoin type ec_secret, which is a special byte array type used for private keys. The next line uses the decode_base16 function to convert our hexKey string from base16 and save it into our ec_secret type variable. The decode_base16 function takes arguments for the output byte array and the input string and returns a bool(true/false) if it worked properly.

	ec_secret rawprivateKey;
	decode_base16(rawprivateKey, hexKey);

Next, we instantiate a libbitcoin private key object by first scoping the namespace wallet and then passing the following arguments to the constructor function: the raw byte array of the secret key, the key version code for a mainnet WIF, 0x8000, and since we want an uncompressed WIF we pass “false” to the compression argument.

wallet::ec_private privateKey(rawprivateKey, 0x8000, false);

Now that we have our private key object, we can print it out using its string serializer function encoded().

	std::cout << "\nPrivate Key Structure: " << std::endl;
	std::cout << privateKey.encoded() << std::endl;

After, we can check that our WIF private key did in fact originate from our initial hex key by using the secret() accessor function and the encode_base16 function to output the the private key in hex form and check that against the original hexKey.

ec_secret keyTest = privateKey.secret();
	std::string keyTestString = encode_base16(keyTest);
	if(keyTestString == hexKey){
		std::cout << "Confirmed: " << keyTestString << std::endl;
	} else {
		std::cout << "Error!" << keyTestString << std::endl;
	}

How It Works

Now that we have seen how to convert private keys using the special libbitcoin data structures, we can walk through how the keys are actually formatted by manually using some of libbitcoin’s helper functions.

We’ll start by adding 80, the hex version prefix, to the front of the secret key’s hex string and print that out for reference.


	hexKey = "80" + hexKey;
	std::cout << "\nVersioned Key: " << std::endl;
	std::cout << hexKey << std::endl;

So, we define 2 variables of this type to store the raw secret key and the WIF key. Additionally, we need to declare a byte array in order to hash the checksum. The size declared here is for an uncompressed WIF.


	data_chunk fullKey;
	data_chunk wifVersion;
	byte_array<37u> versionedKey;

Once we have our memory allocated, we can use some of the encoding functions we’ve already seen to convert the necessary parts of the key. First, we decode the hex secret key and save the raw bytes into our data chunk variable. Next, we do the same decoding with “0x80”, the hex version prefix, and save that into a data chunk.

After we have the parts of our key converted we need to add the checksum to the end. This is easily accomplished with a libbitcoin helper function which takes the destination byte array and an aggregator of the prefix and secret key as arguments in that order.


	decode_base16(fullKey, hexKey);
	decode_base16(wifVersion, "0x80");
	build_checked_array(versionedKey, { wifVersion, fullKey});

After the build_checked_array function executes, we have our full key with it’s prefix and checksum saved into our byte array. This leaves us with just one more step: to encode the key into a bitcoin readable format, base58.


	std::string practiceKey = encode_base58(versionedKey);
	std::cout<< "\nBy Hand:" << std::endl;
	std::cout<< practiceKey << std::endl;

The output here is the wallet import format for an uncompressed private key.

How to Compile and Run a Libbitcoin Program

In order to run a program with libbitcoin we are going to need to compile our program to link the libbitcoin library and specify standard c++11 syntax using g++.

$ g++ -std=c++11 -o first libbitcoinFirstProgram.cpp $(pkg-config --cflags libbitcoin --libs libbitcoin)

after that we can run it like most c++ programs.

	$./first

The output should look similar to this:

libbitcoinfirstoutputjpg

This program converts into an uncompressed WIF which is a rarely used format type. For extra practice, go ahead and reimplement this program for compressed keys which simply require the suffix “01” added to the end of the hex secret key.

Getting Started with Libbitcoin

Libbitcoin is a system’s level C++ toolkit for programming with the Bitcoin Blockchain. It’s a highly modular framework and with a little practice it can be a great tool to implement privacy and security focused bitcoin features. In this multi-part series I’ll be going over some of the basics of the library.

First step is installation; I’ll be going over installation for Mac.

On Mac OSX, clang version >7 is required so go ahead and check it with:


$clang++ --version

After that you need to have the xcode toolchain installed. Easy enough with:

$ xcode-select --install

Next, you’ll need to use homebrew to install some of libbitcoin’s dependency stack with:

$ brew install autoconf automake libtool pkgconfig wget
$ brew install boost

After you have all the dependencies installed on your system you go ahead and clone the repo into a local directory:


$ git clone https://github.com/libbitcoin/libbitcoin.git

then checkout the latest version tag with git:

$ git checkout tags/v3.6.0 

and walk through the make file with autotools:


$ ./autogen.sh
$ ./configure
$ make
$ sudo make install

Getting started with IoT by hacking Amazon Dash

Being that it’s 2016, IoT(Internet of Things) is one of the most unavoidable buzzwords in technology. So, I thought I’d better get on board the future train and dip my feet into the utopia of our connected society, starting out by hacking an amazon dash button into a wifi doorbell.

This hack is as cheap and easy as it gets for an IoT project. It’s riff off of this baby-poop tracker hack. Amazon’s Dash Buttons are a great little wifi connected button that costs only 5 Dollars. Amazon’s intention is to have you set these buttons around your household items, such as Gatorade or Tide, and when you are running low, you click it and Amazon ships out a refill of the product straight to your door.

The fact that these tiny wifi triggers are only 5 dollars (free, if you order the product) makes them prime for hacking and Automating IoT tasks.

First things first, we must disable it’s original purpose. This part is simple, follow the set-up instructions that come with the device and at the point where it asks you to assign a product to the button simply do nothing and exit. With no product assigned, nothing will be ordered.

Now, The way we are going to use this trigger will take advantage of the fact that these devices are low-power meaning they run off of a AA battery. This means that the buttons can’t be continually connected to the internet, instead it functions by turning on and connecting to the wifi on each press of the button then sending the order to amazon.

Since we’ve already disabled the amazon order functionality(by not even setting it up), All we need to do now is detect when it connects to the internet and use that event to trigger our task.

To do this we simply sniff the network packets with a python script looking for the dash button on the network and trigger some event of your choosing.

The optimal vector for this would of course be a raspberry pi home server. I, however, have opted to use my Asus Chromebook as my home linux server since I just hacked a $70 chromebook into a sleek portable linux machine and wanted to show it off. (also, all my pi boards are currently occupied).

The even more optimal solution to this would be running some code from amazon lambda and having the dash directly make calls to that, which can be done with the special non-restrictive Amazon IoT dash button but at 400% ($20) the price, I’m not interested.

So, fire up your favorite IDE or text editor and let’s dive into some code.

    import socket
    import binascii 
    import struct
    import requests

Our imports are going to stay basic, with the execption of requests which your free to swap out with urllib2 if your more comfortable with that. We will be using socket in order to sniff network packets and detect the dash button press, with struct being using to unpack the contents of packets and binascii to convert the mac adresses as well as requests to trigger our event via a GET request.

rawSocket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003))

Here we open our computers socket to listen for packets from devices.

while True:
    packet = rawSocket.recvfrom(2048)
    ethernet_header = packet[0][0:14]
    ethernet_detailed = struct.unpack("!6s6s2s", ethernet_header)

 ethertype = ethernet_detailed[2]
 if ethertype != '\x08\x06':
     continue
 arp_header = packet[0][14:42]
 arp_detailed = struct.unpack("2s2s1s1s2s6s4s6s4s", arp_header)
 source_mac = binascii.hexlify(arp_detailed[5])
 print(source_mac)

In this piece we are printing the MAC Adresses of our dash button. So, run the code, and press your dash button, then record the MAC address that prints on the screen.

while True:
    packet = rawSocket.recvfrom(2048)
    ethernet_header = packet[0][0:14]
    ethernet_detailed = struct.unpack("!6s6s2s", ethernet_header)

 ethertype = ethernet_detailed[2]
 if ethertype != '\x08\x06':
     continue
 arp_header = packet[0][14:42]
 arp_detailed = struct.unpack("2s2s1s1s2s6s4s6s4s", arp_header)
 source_mac = binascii.hexlify(arp_detailed[5])

 if source_mac == '44650d294940':
     print "Gatorade Pressed"

Now, we write an if statement that checks the arp header for the mac address of the device that is trying to connect to the network. If the MAC address is that of our desired dash button, the if statement triggers our custom event. For now, we’ll have it print to the console that our “Dash Button has been pushed.”

So, at this point we are successfully triggering a custom event with our amazon dash button. The event just isn’t that useful or interesting.

There are many cool uses for a wifi button. DIY Life Alert? well, if your IoT hacking you probably won’t need such a device. Other cool uses include, habit tracking, Smart Device Control, Alerts etc.

Basically, the takeaway here is that any code you jam in that if statement will be run when you press the button.

An extremely helpful tool for automating is IFTTT, which has created a new maker channel, allowing you to call an event with a GET request. An event can range from an SMS notification, google sheets entry, to sending an email.

I decided to set up a wifi doorbell so that me an my roommates can get text notifications when the mailman delivers a package or when someones at the door.

Simply, navigate to www.IFTTT.com search for the channel “Maker” from there the instructions are rather simple. Name your event, set up the action you want preformed, in this case sending an SMS message.

Once you’ve set up the recipe, got to www.IFTTT.com/maker and click on the link how to trigger events, which should show you the neccessary URL needed to trigger the action. Copy This. and put it into a get request in the if statement. Like So.


if source_mac == '44650d294940':
    print "Gatorade Pressed"
    requests.get('https://maker.ifttt.com/trigger/Door_Bell/with/key/y_ourkeygoeshere')

Now. Whenever the Button is pushed, A text is sent to my phone. All thats left to do now is mount this on the front door.

Now, I live with roomates who wanted these notification as well and unfortunatley IFTTT only lets you verify one phone. My low-tech hack-around was to create seprate accounts with IFTTT verify their phone numbers seperatley and jam all the resulting URLS into the if statement.
There you have it! An introductory project for IoT hacking on Amazon’s Dash Button.

Bonus points if you do this project while listening to “Digital Dash by Drake & Future”