NAME

Bitcoin::Crypto::Manual - Module overview

DESCRIPTION

This module allows you to perform low-level tasks for Bitcoin such as:

  • creating extended keys and utilizing bip32 key derivation

  • creating private key / public key pairs

  • address generation (in legacy, compatibility and segwit formats)

  • importing / exporting using popular mediums (WIF, mnemonic, hex)

  • building, serializing and running transaction scripts

  • serializing, signing and verifying transactions

This module won't help you with:

  • handling Bitcoin blocks and the blockchain

  • using any Bitcoin CLI tools / clients

  • connecting to Bitcoin network

WHERE TO START?

Documentation and examples in this module assume you're already familiar with the basics of Bitcoin protocol and asymmetric cryptography. If that's not the case, start with reading about those topics.

If you like to learn by example, dive right into the examples directory.

There are many goals which you may want to achieve with this module. Common topics include:

GENERAL INFORMATION

How to read the documentation?

Most functions in this documentation have a code line showcasing the arguments used by the function. These lines are not meant to be valid perl. They're there for you to understand what arguments the function expects.

Most packages in this module have the types of their thrown exceptions documented near the bottom of the document. The exceptions section may be useful to understand which types of exceptions can be thrown when using functions or methods from the package and what they mean. It is not meant to be a full list of exceptions a function can throw and unblessed errors may still be raised.

Class shortcuts

The most frequently used classes have their shortcuts starting with btc_ registered in Bitcoin::Crypto. Examples are btc_prv for basic private key or btc_transaction for transactions. These shortcuts can make the code more compact and avoid manually requiring too many classes, but they are completely optional. If this style does not sound reasonable to you, feel free to ignore it.

See "Exported interface" in Bitcoin::Crypto for details.

How to pass data to functions?

Many frequently used functions (like from_serialized commonly used in keys, scripts and transactions) require you to pass in a string of bytes. Bytestring is a string in which each character has numeric value less than or equal to 255. It is the default way to pass in data to functions in Bitcoin::Crypto.

It is not rare that you may want to use some other format instead, like hex strings. To avoid duplicating functions for different formats or manually transforming data to a bytestring, the module uses data structures called format descriptions. In any place where a bytestring is used you may instead use an array reference with exactly two elements. The first element must be a name of the format, and the second element is the actual data in that format. For strings of hex data, this may look like this:

use Bitcoin::Crypto qw(btc_prv);
my $private = btc_prv->from_serialized([hex => '152a3f549597a2bef783']);

Currently supported values for the first argument are:

hex (hexadecimal string, may be prefixed by 0x)
base58 (base58-encoded string with the checksum)
base64 (base64-encoded string)

It is also common for functions to return bytestrings (like to_serialized). If you need help changing that output format you may use "to_format" in Bitcoin::Crypto::Util helper function, which does the reverse operation:

use Bitcoin::Crypto::Util qw(to_format);
print to_format [hex => $private->to_serialized];

How to pass commonly used script types to functions?

Similar to format descriptions, you may use a script description anywhere a script is expected. It is an array reference of two elements, where the first one is the short name of the script type, like P2WPKH. The second one contains data specific to that script type, usually the address:

$transaction->add_output(
	locking_script => [P2WPKH => 'bc1qr9htu5sy02q6kv6mx7axz2zdg3k9nrh8pe4l47'],
);

You may also leave address detection up to the module by using the string address:

# the same thing
$transaction->add_output(
	locking_script => [address => 'bc1qr9htu5sy02q6kv6mx7axz2zdg3k9nrh8pe4l47'],
);

Note that the script created like this always belongs to the currently set default network (bitcoin by default). Passing address from the wrong network will result in an exception.

See "from_standard" in Bitcoin::Crypto::Script for more details.

Support for other cryptocurrencies

Bitcoin::Crypto has limited support for other cryptocurrency networks through Bitcoin::Crypto::Network. The network must be fully compatible with Bitcoin (a Bitcoin clone or a strict subset of Bitcoin features) - no extra cases will exist in the code, only constant values can differ between the networks. Lack of certain constant values can be used to mark feature unsupported in the given network, for example lack of segwit_hrp network constant will be interpreted as network not supporting Segregated Witness. Note that Bitcoin testnet is also considered a separate network.

Networks can be set globally through default network or on per-object basis for basic and extended keys, and scripts. Other parts of the system does not support per-object setting of networks and rely on the currently set default network. Setting keys for every object separately is considered an outdated feature which is kept for backwards compatibility (and convenience, sometimes). If you want to make sure all your keys are in the same, default network, see single-network mode in "single_network" in Bitcoin::Crypto::Network. This mode will disallow creation of objects with other network than the default. It can come handy if you are de-serializing keys from non-constant strings, for example fetched from the Internet or entered by the user.

DISCLAIMER

Although the module was written with an extra care and appropriate tests are in place asserting compatibility with many Bitcoin standards, due to complexity of the subject some bugs may still be present. In the world of digital money, a single bug may lead to losing funds. I encourage anyone to test the module themselves, review the test cases and use the module with care. Suggestions for improvements and more edge cases to test will be gladly accepted, but there is no warranty on funds manipulated by this module.

TODO

I will gladly accept help working on these: