{"id":13936459,"url":"https://github.com/chainside/btcpy","last_synced_at":"2025-04-04T15:07:48.649Z","repository":{"id":45251687,"uuid":"102280021","full_name":"chainside/btcpy","owner":"chainside","description":"A Python3 SegWit-compliant library which provides tools to handle Bitcoin data structures in a simple fashion.","archived":false,"fork":false,"pushed_at":"2022-07-04T22:05:31.000Z","size":37985,"stargazers_count":273,"open_issues_count":20,"forks_count":74,"subscribers_count":24,"default_branch":"master","last_synced_at":"2025-03-28T14:06:35.730Z","etag":null,"topics":["bitcoin","bitcoin-script","hacktoberfest","p2sh","segwit","transaction"],"latest_commit_sha":null,"homepage":"https://www.chainside.net","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chainside.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-03T16:59:10.000Z","updated_at":"2025-01-18T20:16:16.000Z","dependencies_parsed_at":"2022-07-13T12:50:27.282Z","dependency_job_id":null,"html_url":"https://github.com/chainside/btcpy","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainside%2Fbtcpy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainside%2Fbtcpy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainside%2Fbtcpy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainside%2Fbtcpy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chainside","download_url":"https://codeload.github.com/chainside/btcpy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247198450,"owners_count":20900080,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitcoin","bitcoin-script","hacktoberfest","p2sh","segwit","transaction"],"created_at":"2024-08-07T23:02:41.453Z","updated_at":"2025-04-04T15:07:48.629Z","avatar_url":"https://github.com/chainside.png","language":"Python","readme":"\u003cp\u003e\n\u003cimg src=\"https://www.chainside.net/wp-content/themes/chainside2018/assets/favicon//favicon-192.png\" alt=\"chainside\" width=\"80\"\u003e \n\u003cbr \\\u003e\u003cbr \\\u003e\ndeveloped with :heart: by \u003ca href=\"https://www.chainside.net\"\u003echainside\u003c/a\u003e\n\u003c/p\u003e\n\n\n# btcpy\n`btcpy` is a Python\u003e=3.3 SegWit-compliant library which provides tools to handle\nBitcoin data structures in a simple fashion. In particular, the main goal of\nthis library is to provide a simple interface to parse and create complex\nBitcoin scripts.\n\n**N.B.: this library is a work in progress so it is highly discouraged to use it in\na production environment. Also, as long as the version is 0.\\*, API breaking changes\nshould be expected**\n\n\nTable of Contents\n=================\n\n   * [btcpy](#btcpy)\n   * [Table of Contents](#table-of-contents)\n   * [Requirements](#requirements)\n   * [Installation](#installation)\n   * [What it does](#what-it-does)\n   * [What it does not do](#what-it-does-not-do)\n   * [Structure](#structure)\n   * [Usage examples](#usage-examples)\n      * [Setup](#setup)\n         * [Network](#network)\n         * [Strictness](#strictness)\n      * [Parsing and serialization](#parsing-and-serialization)\n      * [Keys](#keys)\n         * [HD keys](#hd-keys)\n      * [Scripts](#scripts)\n         * [Low-level scripting functionalities](#low-level-scripting-functionalities)\n      * [Addresses](#addresses)\n      * [Transactions](#transactions)\n         * [Creating transactions](#creating-transactions)\n         * [Spending a transaction](#spending-a-transaction)\n         * [P2PKH](#p2pkh)\n         * [P2SH](#p2sh)\n         * [P2WSH](#p2wsh)\n         * [P2WSH-over-P2SH](#p2wsh-over-p2sh)\n         * [P2PK](#p2pk)\n         * [Multisig](#multisig)\n         * [Timelocks, Hashlocks, IfElse](#timelocks-hashlocks-ifelse)\n         * [Low-level signing](#low-level-signing)\n   * [Contributing and running tests](#contributing-and-running-tests)\n   * [Roadmap to v1](#roadmap-to-v1)\n   * [TODO](#todo)\n   * [Acknowledgements](#acknowledgements)\n\n\n# Requirements\nThe strict requirements of this library are:\n\n    pip install ecdsa\n    pip install base58\n    \nas an additional requirement, only used for integration testing purposes, this\nlibrary uses:\n\n    pip install python-bitcoinlib==0.7.0\n    \nthis is used to communicate with the Bitcoin node in order to test transactions\nvalidation.\n\n# Installation\nTo install this library and its dependencies one can just run\n\n    pip install chainside-btcpy\n\n# What it does\nThe main functionalities provided by this project are the following.\n\n* Parsing of blocks\n* Parsing, creation and signing of transactions\n* Parsing and creation of scripts. This also includes many nonstandard script\ntypes such as:\n    * Hashlocked scripts\n    * Timelocked scripts, with both absolute and relative times\n    * Arbitrarily nested if-else clauses\n\n  all scripts are easily embeddable in P2SH and P2WSH format, also\n  supporting SegWit-over-P2SH formats. This library also offers functions to\n  spend such complex scripts by only providing the necessary data.\n\n# What it does not do\nThis library does not implement the following functionalities:\n\n* Validation: when blocks, transactions and scripts are parsed, only\nformat errors are reported. No proof-of-work validation, script execution, \ntransaction validation and signature verification is performed. For these\nconsensus-critical functionalities, users of this library should rely on\nBitcoin Core or other libraries that perform validation.\n* Communication with the Bitcoin nodes. This is not provided neither on an RPC\nnor a networking level. For this purpose we highly recommed python-bitcoinlib.\n\n# Structure\nAll important data structures can be found in `btcpy.structs`, helper modules\nare located in `btcpy.lib`. Objects in `btcpy.structs` are meant as a public\ninterface, while objects located in `btcpy.lib` are used internally.\n\n# Usage examples\n\n## Setup\nThe first thing to do the first time this package is imported is to set a global state which\nindicates on which network you are working and wether you want strict mode enabled.\nThese two settings are further explained in the following sections.\n\nTo setup `btcpy`, you can use the following function\n\n```python\nfrom btcpy.setup import setup\nsetup('regtest', strict=True)\n```\n\n### Network\nYou can setup the network you will work on by calling:\n\n```python\nfrom btcpy.setup import setup\nsetup('regtest')\n```\n    \nsupported network types are:\n    \n    regtest\n    testnet\n    mainnet\n\nThe `btcpy.setup` module also provides the following network-related functions:\n\n    is_mainnet() - returns True if 'mainnet' was selected, False otherwise\n    net_name()   - returns the value that was selected when calling setup()\n\n### Strictness\n`btcpy` never performs validation. However, we don't want you to inadvertently lose your funds\nfor a mistake, so, in strict mode, when you do something that looks dangerous, the library\nalways makes sure that you know exactly what you are doing.\n\nTo setup the library in strict mode, you can run the setup as follows:\n\n```python\nsetup(my_network, strict=True)  # True is actually the default for strict mode, the only other option is False\n```\n\nAdditionally, you can force (non-)strictness on specific functions that have a `strict=None`\nas keyword argument. If the `strict` keyword argument is left to `None`, then the strictness\nspecified in the `setup` will be followed, otherwise the param you pass to `strict` will be used.\n\nThe following additional checks are done when in `strict` mode:\n* Do not allow to create `P2pkScript`s with public keys that have an invalid format (please note that\nduring parsing such scripts will not even be recognised as scripts of type `'p2pk'`\nwhen strict mode is enabled, they will instead be recognised as of type `'nonstandard'`)\n* Do not allow to create m-of-n `MultisigScript`s with less than `m` public keys that have a valid format\n(please note that during parsing such scripts will not even be recognised as scripts of type `'multisig'`\nwhen strict mode is enabled, they will instead be recognised as of type `'nonstandard'`)\n* Do not allow to decode `ExtendedPublicKeys` or `ExtendedPrivateKeys` that don't match the network you set in `setup`\n* Do not allow to decode `Address`es that don't match the network you set in `setup`\n    \n## Parsing and serialization\n`Transaction`, `PublicKey`, `PrivateKey` and `Block` can be extracted\nfrom a hex string by doing:\n\n```python\nfrom btcpy.structs.transaction import Transaction\nfrom btcpy.structs.block import Block\nfrom btcpy.structs.crypto import PublicKey, PrivateKey\ntx = Transaction.unhexlify(hex_tx)\nblock = Block.unhexlify(hex_block)\npubk = PublicKey.unhexlify(pubk_hex)\nprivk = PrivateKey.unhexlify(privk_hex)\n```\n\n`PublicKey` and `PrivateKey` can also be extracted from their BIP32 formats using the\n`hd` module:\n\n```python\n\u003e\u003e\u003e from btcpy.structs.hd import ExtendedPrivateKey, ExtendedPublicKey\n\u003e\u003e\u003e priv = ExtendedPrivateKey.decode('tprv8kxXxKwakWDtXvKBjjR5oHDFS7Z21HCVLMVUqEFCSVChUZ26BMDDH1JmaGUTEYGMUyQQBSfTgEK76QBvLephodJid5GTEiGFVGJdEBYptd7')\n# priv.key holds a `PrivateKey`\n\u003e\u003e\u003e priv.key.hexlify()\n'a12618ff6540dcd79bf68fda2faf0589b672e18b99a1ebcc32a40a67acdab608'\n\u003e\u003e\u003e pub = ExtendedPublicKey.decode('tpubDHea6jyptsuZRPLydP5gCgsN194xAcPPuf6G7kHVrm16K3Grok2oTVvdkNvPM465uuKAShgba7A2hHYeGGuS9B8AQGABfc6hp7mpcLLJUsk')\n# pub.key holds a `PublicKey`\n\u003e\u003e\u003e pub.key.hexlify()\n'025f628d7a11ace2a6379119a778240cb70d6e720750416bb36f824514fbe88260'\n```\n`PrivateKey` can also be extracted from a Wallet Import Format by doing:\n```python\n\u003e\u003e\u003e privk = PrivateKey.form_wif(wif_key)\n```\n\nAll these structures can be converted back to hex by using their `hexlify()` method.\n\nIn the same way, these structures can be serialized and deserialized by using their\n`serialize()` and `deserialize()` methods. These methods respectively return and\nexpect a `bytearray` type.\n\n## Keys\nThe `PublicKey` class can handle both compressed and uncompressed public\nkeys. In any case both the compressed and uncompressed version can be extracted.\nHowever, the structure will remember how it was initialised, so the `hexlify()`,\n`hash()` and `to_address()` methods will produce different\nresults depending whether the `PublicKey` was initialised with a compressed or\nuncompressed public key. The `to_segwit_address()` method will always consider\nthe key as compressed (P2WPKH addresses are only allowed with compressed keys).\nAn example of this behaviour follows:\n\n```python\n\u003e\u003e\u003e uncomp = PublicKey.unhexlify('04ea4e183e8c751a4cc72abb7088cea79351dbfb7981ceb48f286ccfdade4d42c877d334c1a8b34072400f71b2a900a305ffae8963075fe94ea439b4b57978e9e8')\n\u003e\u003e\u003e compr = PublicKey(uncomp.compressed)\n\u003e\u003e\u003e uncomp.hexlify()\n'04ea4e183e8c751a4cc72abb7088cea79351dbfb7981ceb48f286ccfdade4d42c877d334c1a8b34072400f71b2a900a305ffae8963075fe94ea439b4b57978e9e8'\n\u003e\u003e\u003e compr.hexlify()\n'02ea4e183e8c751a4cc72abb7088cea79351dbfb7981ceb48f286ccfdade4d42c8'\n\u003e\u003e\u003e str(uncomp.to_address())\n'mtDD9VFhPaRi6C6McMSnhb7nUZceSh4MnK'\n\u003e\u003e\u003e str(uncomp.to_segwit_address())\n'tb1qxs0gs9dzukv863jud3wpldtrjh9edeqqqzahcz'  # this actually refers to the compressed version!\n\u003e\u003e\u003e str(compr.to_address())\n'mkGY1QBotzNCrpJaEsje3BpYJsktksi3gJ'\n\u003e\u003e\u003e str(compr.to_segwit_address())\n'tb1qxs0gs9dzukv863jud3wpldtrjh9edeqqqzahcz'\n```\n\nPlease note that by default the `to_address()` and `to_segwit_address()`\nmethods will return an address in the format of the network type\nspecified in `setup` (`regtest` in the case of this example) but a flag\ncan be passed to it to return an address for another network:\n\n```python\n\u003e\u003e\u003e str(uncomp.to_address(mainnet=True))\n'1DhFrSAiaYzTK5cjtnUQsfuTca1wXvXfVY'\n\u003e\u003e\u003e str(compr.to_address(mainnet=True))\n'15kaiM6q5xvx5hpxXJmGDGcDStABoGTzSX'\n```\n\nThe `PublicKey` derived from a `PrivateKey` can be obtained by doing:\n\n```python\npubk = PrivateKey.unhexlify(privk_hex).pub()\n```\n\nthe `pub()` method will return by default the compressed public key.\nThe uncompressed version can be obtained by adding the flag `compressed=False`.\n\nAdditionally, one can make sure to use the compressed version of a key by\nusing its `compress()` method:\n```python\n\u003e\u003e\u003e compr = uncomp.compress()\n\u003e\u003e\u003e str(compr.to_address())\n'mkGY1QBotzNCrpJaEsje3BpYJsktksi3gJ'\n```\n\nAddresses can be either created from a `PublicKey` or from a script.\nIn particular this second use case will be documented in the **Addresses** section.\n\n### HD keys\nThe `structs.hd` module provides functionalities to handle BIP32 HD keys.\nSpecifically, it provides the following two classes:\n\n* `ExtendedPublicKey`\n* `ExtendedPrivateKey`\n\nThese classes both provide the `get_child(index, hardened=False)` method. If\ncalled on an `ExtendedPublicKey`, `hardened` must be set to `False`, otherwise\n`heardened` can be either `True` or `False`. The `ExtendedPublicKey` corresponding\nto an `ExtendedPrivateKey` can be obtained through the `pub()` method.\n\nAs seen in the example above, `ExtendedPublicKey` and `ExtendedPrivateKey`\ncontain the simpler structures `PublicKey` and `PrivateKey`, respectively.\nThese structures can be accessed through the `key` attribute.\n\n`ExtendedPublicKey`s also provide a `derive()` method which takes as input a string\nrepresenting a path which either starts with `'m'` or with `'.'`. `'m'` indicates an\nabsolute path and can be used only when `derive()` is called on a master key, `'.'`\nrepresents a relative path and can be used from any starting key. Examples of\nderivation paths:\n* `m/0'/1'/2`: absolute path, first two derivations hardened\n* `./0/128/256'`: relative path, last derivation hardened\n\n\n## Scripts\nThe main focus of this project is providing a simple way to create complex scripts. Scripts have\nthe following hierarchy\n* `BaseScript`\n  * `ScriptSig`\n  * `ScriptPubKey`\n    * `P2pkhscript`\n    * `P2wpkhScript`\n      * `P2wpkhV0Script`\n    * `P2shScript`\n    * `P2wshScript`\n      * `P2wshV0Script`\n    * `P2pkScript`\n    * `NulldataScript`\n    * `MultisigScript`\n    * `IfElseScript`\n    * `AbsoluteTimelockScript`\n    * `RelativeTimelockScript`\n    * `Hashlock256Script`\n    * `Hashlock160Script`\n    * `UnknownScript`\n    \nScripts have the following methods:\n```python\nserialize()              - Returns the script as a bytearray\ndecompile()              - Returns a string representing the human readable opcodes and pushdata operations\nhexlify()                - Returns the script as a hex string\nunhexlify(hex_string)    - Creates the script from a hex string\nis_standard()            - Returns whether the script complies with standardness rules as of Bitcoin Core commit a90e6d2bffc422ddcdb771c53aac0bceb970a2c4\ntype                     - A property containing a string which represents the type of the script\nget_sigop_count()        - Returns the number of signature operations performed by the script\nis_push_only()           - Returns whether the script is only made of push operations\nto_address(segwit=False) - (only ScriptPubKey) Returns the script as either a P2SH or a P2WSH address, depending whether\n                           the segwit flag is set\n```\n\n### Low-level scripting functionalities\nThis section will introduce low-level creation and template-matching of scripts,\nfor more advanced features please refer to the **Transactions** section.\n\nThis libary allows to create scripts from asm and from hex, as can be seen in\nthe following examples.\n\nCreating a script from asm (i.e. opcodes):\n```python\n# this returns a bytearray with the compiled script\n\u003e\u003e\u003e compiled = Script.compile('OP_DUP OP_HASH160 a33ce8cf2760e2f9ef384bcbbe9a5491759feb14 OP_EQUALVERIFY OP_CHECKSIG')\n# the bytearray can be passed to Script() to get a generic script\n\u003e\u003e\u003e script = Script(compiled)\n# check that everything works as expected\n\u003e\u003e\u003e script.decompile()\n'OP_DUP OP_HASH160 a33ce8cf2760e2f9ef384bcbbe9a5491759feb14 OP_EQUALVERIFY OP_CHECKSIG'\n# beware, this is a generic script, no type recognition has been performed!\n\u003e\u003e\u003e script.type\n'Script'\n```\n\nCreating a script from hex:\n```python\n# this returns a bytearray with the compiled script\n\u003e\u003e\u003e script = Script.unhexlify('76a914a33ce8cf2760e2f9ef384bcbbe9a5491759feb1488ac')\n# check that everything works as expected\n\u003e\u003e\u003e script.decompile()\n'OP_DUP OP_HASH160 a33ce8cf2760e2f9ef384bcbbe9a5491759feb14 OP_EQUALVERIFY OP_CHECKSIG'\n# beware, this is a generic script, no type recognition has been performed!\n\u003e\u003e\u003e script.type\n'Script'\n```\n\nAs we have seen, these are instantiated as generic scripts, if we want to obtain the appropriate\nscript type, the `ScriptBuilder` class can be used. `ScriptBuilder`'s method `identify()`\nwill return the appropriate script type by performing template matching on the provided\nscript.\n\nIdentifying a P2PKH script:\n```python\n\u003e\u003e\u003e script = ScriptBuilder.identify('76a914341e8815a2e5987d465c6c5c1fb56395cb96e40088ac')\n\u003e\u003e\u003e script.type\n'p2pkh'\n\u003e\u003e\u003e script.decompile()\n'OP_DUP OP_HASH160 341e8815a2e5987d465c6c5c1fb56395cb96e400 OP_EQUALVERIFY OP_CHECKSIG'\n\u003e\u003e\u003e script.pubkeyhash\nbytearray(b'4\\x1e\\x88\\x15\\xa2\\xe5\\x98}F\\\\l\\\\\\x1f\\xb5c\\x95\\xcb\\x96\\xe4\\x00')\n```\n\nIdentifying a P2SH script\n```python\n\u003e\u003e\u003e script = ScriptBuilder.identify('a914bb18ed39c2a86f75f7bb5a9b36ba3581d77fd0f087')\n\u003e\u003e\u003e script.type\n'p2sh'\n\u003e\u003e\u003e script.decompile()\n'OP_HASH160 bb18ed39c2a86f75f7bb5a9b36ba3581d77fd0f0 OP_EQUAL'\n\u003e\u003e\u003e script.scripthash\nbytearray(b'\\xbb\\x18\\xed9\\xc2\\xa8ou\\xf7\\xbbZ\\x9b6\\xba5\\x81\\xd7\\x7f\\xd0\\xf0')\n```\n\nOf course, all the types listed at the beginning of this section can be recognised,\nsee the next section for more complex script types.\n\nPlease keep in mind that the fact that a script is successfully built (a script can be built\nfor every recognised script type, if no type matches, an `UnknownScript` is istantiated) does\nnot mean that the script is valid. In fact, `UnknownScript`s can even contain non valid push\noperations or non-existing opcodes. The only way to know if a script is valid is executing it\nagainst an execution stack, a functionality that this library does not implement. In particular,\nfor non-valid push operations, the script asm (obtained through the `decompile` or `__str__` methods)\nwill contain `[error]` where the push takes place. For non-existing opcodes the asm will contain\nthe special opcode `OP_INVALIDOPCODE`. These two beahviours match Bitcoin Core's behaviour when\nproducing script asm.\n\n## Addresses\n\nSupported addresses are: `P2pkhAddress`, `P2shAddress`, `P2wpkhAddress` and `P2wshAddress`.\nThese constructors can be used to build an address from a hash (plus a SegWit version in the\ncase of `P2wpkhAddress` or `P2wshAddress`), for example:\n\n```python\nfrom btcpy.structs.crypto import PublicKey\nfrom btcpy.structs.address import P2pkhAddress, P2wpkhAddress\npubk = PublicKey.unhexlify('02ea4e183e8c751a4cc72abb7088cea79351dbfb7981ceb48f286ccfdade4d42c8')\naddress = P2pkhAddress(pubk.hash())\nsw_address = P2wpkhAddress(pubk.hash(), version=0)\nprint(str(address))  # prints \"mkGY1QBotzNCrpJaEsje3BpYJsktksi3gJ\"\nprint(str(sw_address))  # prints \"tb1qxs0gs9dzukv863jud3wpldtrjh9edeqqqzahcz\"\n```\n\nPlease note that by default all the address constructors will return an address in the\nformat of the network type specified in setup (testnet in the case of this example) but\na flag can be passed to them to return an address for another network:\n\n```python\naddress = P2pkhAddress(pubk.hash(), mainnet=True)\nsw_address = P2wpkhAddress(pubk.hash(), version=0, mainnet=True)\nprint(str(address))  # prints \"15kaiM6q5xvx5hpxXJmGDGcDStABoGTzSX\"\nprint(str(sw_address))  # prints \"bc1qxs0gs9dzukv863jud3wpldtrjh9edeqq2yxyr3\"\n```\n\nHowever, a more common usecase is generating an address for a script, for this the `from_script`\nstatic method of all address classes can be used, in particular:\n\n* `P2pkhAddress.from_script(script, mainnet=None)` will instantiate a `P2pkhAddress` from a\n`P2pkhScript`, raising `WrongScriptType` exception in case another type of script is provided.\n* `P2shAddress.from_script(script, mainnet=None)` will instantiate a `P2shAddress` representing\nthe script address if a `P2shscript` is provided, while returning the address of the script\nembedded in P2SH format if other script types are provided.\n*  `P2wpkhAddress.from_script(script, version, mainnet=None)` will instantiate a `P2wpkhAddress`\n from a `P2wpkhScript`, raising `WrongScriptType` exception in case another type of script\n is provided.\n* `P2wshAddress.from_script(script, version, mainnet=None)` will instantiate a `P2wshAddress`\nrepresenting the script address if a `P2wshscript` is provided, while returning the address\nof the script embedded in P2WSH format if other script types are provided.\n\nThe only scripts that directly support an address (i.e. `P2pkhScript`, `P2wpkhScript`,\n`P2shscript`, `P2wshScript`) also provide a helper method `address()` to return the script\naddress, for all other script types will return `None` if the `address()` method is called\nand will need to be explicitly converted to P2SH or P2WSH format to obtain an address. Some\nexamples follow:\n\n```python\n\u003e\u003e\u003e str(P2pkhAddress.from_script(P2pkhScript(pubk)))\n'mkGY1QBotzNCrpJaEsje3BpYJsktksi3gJ'\n\u003e\u003e\u003e str(P2pkhScript(pubk).address())\n'mkGY1QBotzNCrpJaEsje3BpYJsktksi3gJ'\n\u003e\u003e\u003e str(P2pkhAddress.from_script(P2shScript(P2pkhScript(pubk))))\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \".../btcpy/btcpy/structs/address.py\", line 120, in from_script\n    raise WrongScriptType('Trying to produce P2pkhAddress from {} script'.format(script.__class__.__name__))\nbtcpy.structs.address.WrongScriptType: Trying to produce P2pkhAddress from P2shScript script\n\u003e\u003e\u003e str(P2shAddress.from_script(P2shScript(P2pkhScript(pubk))))\n'2NAJWD6EnXMVt16HUp5vmfwPjz4FemvPhYt'\n\u003e\u003e\u003e str(P2shScript(P2pkhScript(pubk)).address())\n'2NAJWD6EnXMVt16HUp5vmfwPjz4FemvPhYt'\n\u003e\u003e\u003e str(P2wpkhAddress.from_script(P2wpkhV0Script(pubk)))\n'tb1qxs0gs9dzukv863jud3wpldtrjh9edeqqqzahcz'\n\u003e\u003e\u003e str(P2wpkhV0Script(pubk).address())\n'tb1qxs0gs9dzukv863jud3wpldtrjh9edeqqqzahcz'\n\u003e\u003e\u003e str(P2wpkhAddress.from_script(P2shScript(P2wpkhV0Script(pubk))))\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \".../btcpy/btcpy/structs/address.py\", line 158, in from_script\n    raise WrongScriptType('Trying to produce P2pkhAddress from {} script'.format(script.__class__.__name__))\nbtcpy.structs.address.WrongScriptType: Trying to produce P2pkhAddress from P2shScript script\n```\n\nOn the other hand, addresses can also be directly converted to the scripts they represent:\n\n```python\n\u003e\u003e\u003e a = Address.from_string('mkGY1QBotzNCrpJaEsje3BpYJsktksi3gJ')\n\u003e\u003e\u003e a.to_script()\nP2pkhScript('341e8815a2e5987d465c6c5c1fb56395cb96e400')\n\u003e\u003e\u003e a = Address.from_string('tb1qxs0gs9dzukv863jud3wpldtrjh9edeqqqzahcz')\n\u003e\u003e\u003e a.to_script()\nP2wpkhScript('341e8815a2e5987d465c6c5c1fb56395cb96e400')\n```\n\n## Transactions\n\n### Creating transactions\n\nTransactions can be created by using the following classes:\n* `TxIn`, takes as input the following parameters:\n  * `txid`, the txid of the transaction being spent\n  * `txout`, the output number of the output being spent\n  * `script_sig`, a scriptSig\n  * `sequence`, the sequence number of the TxIn\n* `Sequence`, the constructor takes a sequence number, but it offers a couple of helper static\nmethods for creation:\n  * `create()`, which takes `seq`, lower 16 bits of sequence number, `blocks`, whether the `seq`\n   param expresses blocks or a timestamp, and `disable` which sets the disable bit. For further\n   info on how this all works, please refer to\n   [BIP68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) specification.\n  * `max()`, this automatically creates a `Sequence` object with the maximum sequence number\n   (i.e. `0xffffffff`).\n* `TimebasedSequence`, behaves like a `Sequence` but assumes the sequence expresses time. Can\nalso be instantiated from a `timedelta` object through its `from_timedelta` method\n* `HeightBasedSequence`, behaves like a `Sequence` but assumes the sequence expresses a block height.\n* `ScriptSig`, this can be initialised with a `bytearray` representing the script, but offers\nthe following static methods:\n  * `empty()`, this creates an empty `ScriptSig`, useful when initialising a transaction\n  which has not been signed yet\n* `StackData`, this class represents data that scripts push on the stack, it offers methods\nto convert between the push operations and the actual data pushed.\n* `Witness`, this represents a SegWit witness, it is constructed with an array of `StackData`.\n* `TxOut`, takes as input the following parameters: `value` the value spent, in satoshis, `n`,\nthe output number, `script_pubkey`, an object of type `ScriptPubKey` where the coins are being\nsent.\n* `ScriptPubKey` and derived classes, they take as input a `bytearray` representing the script\nbut can also be created through the `ScriptBuilder.identify()` method or in the way displayed\nlater in this section.\n* `Locktime`, takes as input a number representing the transaction's locktime field. Can also\nbe constructed from a `datetime` object through its `from_datetime` method\n* `Transaction`, takes as inputs: a version number, a list of `TxIn`s, a list of `TxOut`s, a\n`Locktime`.\n* `SegWitTransaction`, has the same interface as `Transaction`\n* `TransactionFactory` used to instantiate a generic transaction from a json or hex string\n\nAll the aforementioned classes are `Immutable`, this means that, after construction, their\nattributes can't be mutated. This helps caching values returned by their methods. The classes\n`Transaction`, `SegWitTransaction` and `TxIn` have mutable versions, unsurprisingly called\n`MutableTransaction`, `MutableSegWitTransaction` and `MutbleTxIn`, respectively. These mutable\nversions are mainly used to create unsigned transactions which then are mutated\nto add signatures to them. We will see how to use these in the rest of this section.\n\nTransactions can be deserialized both from json and from a hex string, see the following examples:\n```python\n\u003e\u003e\u003e tx = Transaction.unhexlify('0100000001e4da173fbefe5e60ff63dfd38566ade407532294db655463b77a783f379ce605000000006b483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2ffffffff0100c2eb0b000000001976a914df76c017354ac39bde796abe4294d31de8b5788a88ac00000000')\n\u003e\u003e\u003e tx.to_json()\n{'hex': '0100000001e4da173fbefe5e60ff63dfd38566ade407532294db655463b77a783f379ce605000000006b483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2ffffffff0100c2eb0b000000001976a914df76c017354ac39bde796abe4294d31de8b5788a88ac00000000', 'txid': 'e977c07090c2a1dcaefd3f3c4ebf4e231f4116cb272f805b0b22a85e7eece09c', 'hash': 'e977c07090c2a1dcaefd3f3c4ebf4e231f4116cb272f805b0b22a85e7eece09c', 'size': 192, 'vsize': 192, 'version': 1, 'locktime': 0, 'vin': [{'txid': '05e69c373f787ab7635465db94225307e4ad6685d3df63ff605efebe3f17dae4', 'vout': 0, 'scriptSig': {'asm': '3045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f101 02ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2', 'hex': '483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2'}, 'sequence': '4294967295'}], 'vout': [{'value': '2.00000000', 'n': 0, 'scriptPubKey': {'asm': 'OP_DUP OP_HASH160 df76c017354ac39bde796abe4294d31de8b5788a OP_EQUALVERIFY OP_CHECKSIG', 'hex': '76a914df76c017354ac39bde796abe4294d31de8b5788a88ac', 'type': 'p2pkh', 'address': '1MNZwhTBHN3QTXkwob7NvhVaTVKUm7MRCg'}}]}\n\u003e\u003e\u003e tx = SegWitTransaction.unhexlify('0100000001e4da173fbefe5e60ff63dfd38566ade407532294db655463b77a783f379ce605000000006b483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2ffffffff0100c2eb0b000000001976a914df76c017354ac39bde796abe4294d31de8b5788a88ac00000000')\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/home/rael/Dropbox/projects/btcpy/btcpy/structs/transaction.py\", line 457, in unhexlify\n    return cls.deserialize(bytearray(unhexlify(string)))\n  File \"/home/rael/Dropbox/projects/btcpy/btcpy/structs/transaction.py\", line 466, in deserialize\n    raise TypeError('Trying to load transaction from wrong transaction serialization')\nTypeError: Trying to load transaction from wrong transaction serialization\n\u003e\u003e\u003e tx = Transaction.from_json({'hex': '0100000001e4da173fbefe5e60ff63dfd38566ade407532294db655463b77a783f379ce605000000006b483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2ffffffff0100c2eb0b000000001976a914df76c017354ac39bde796abe4294d31de8b5788a88ac00000000', 'txid': 'e977c07090c2a1dcaefd3f3c4ebf4e231f4116cb272f805b0b22a85e7eece09c', 'hash': 'e977c07090c2a1dcaefd3f3c4ebf4e231f4116cb272f805b0b22a85e7eece09c', 'size': 192, 'vsize': 192, 'version': 1, 'locktime': 0, 'vin': [{'txid': '05e69c373f787ab7635465db94225307e4ad6685d3df63ff605efebe3f17dae4', 'vout': 0, 'scriptSig': {'asm': '3045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f101 02ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2', 'hex': '483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2'}, 'sequence': '4294967295'}], 'vout': [{'value': '2.00000000', 'n': 0, 'scriptPubKey': {'asm': 'OP_DUP OP_HASH160 df76c017354ac39bde796abe4294d31de8b5788a OP_EQUALVERIFY OP_CHECKSIG', 'hex': '76a914df76c017354ac39bde796abe4294d31de8b5788a88ac', 'type': 'p2pkh', 'address': '1MNZwhTBHN3QTXkwob7NvhVaTVKUm7MRCg'}}]})\n\u003e\u003e\u003e tx = SegWitTransaction.from_json({'hex': '0100000001e4da173fbefe5e60ff63dfd38566ade407532294db655463b77a783f379ce605000000006b483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2ffffffff0100c2eb0b000000001976a914df76c017354ac39bde796abe4294d31de8b5788a88ac00000000', 'txid': 'e977c07090c2a1dcaefd3f3c4ebf4e231f4116cb272f805b0b22a85e7eece09c', 'hash': 'e977c07090c2a1dcaefd3f3c4ebf4e231f4116cb272f805b0b22a85e7eece09c', 'size': 192, 'vsize': 192, 'version': 1, 'locktime': 0, 'vin': [{'txid': '05e69c373f787ab7635465db94225307e4ad6685d3df63ff605efebe3f17dae4', 'vout': 0, 'scriptSig': {'asm': '3045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f101 02ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2', 'hex': '483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2'}, 'sequence': '4294967295'}], 'vout': [{'value': '2.00000000', 'n': 0, 'scriptPubKey': {'asm': 'OP_DUP OP_HASH160 df76c017354ac39bde796abe4294d31de8b5788a OP_EQUALVERIFY OP_CHECKSIG', 'hex': '76a914df76c017354ac39bde796abe4294d31de8b5788a88ac', 'type': 'p2pkh', 'address': '1MNZwhTBHN3QTXkwob7NvhVaTVKUm7MRCg'}}]})\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/home/rael/Dropbox/projects/btcpy/btcpy/structs/transaction.py\", line 737, in from_json\n    raise TypeError('Trying to load segwit transaction from non-segwit transaction json')\nTypeError: Trying to load segwit transaction from non-segwit transaction json\n```\n\nAs you can see from the previous example, `Transaction` and `SegWitTransaction` classes can deserialise only\njson and hex strings of the appropriate type. To deserialize a generic json or hex string and build the \nappropriate object, one can use the `TransactionFactory`:\n\n```python\n\u003e\u003e\u003e TransactionFactory.unhexlify('0100000001e4da173fbefe5e60ff63dfd38566ade407532294db655463b77a783f379ce605000000006b483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2ffffffff0100c2eb0b000000001976a914df76c017354ac39bde796abe4294d31de8b5788a88ac00000000')\n\u003cbtcpy.structs.transaction.Transaction object at 0x7f3717961be0\u003e\n\u003e\u003e\u003e TransactionFactory.from_json({'hex': '0100000001e4da173fbefe5e60ff63dfd38566ade407532294db655463b77a783f379ce605000000006b483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2ffffffff0100c2eb0b000000001976a914df76c017354ac39bde796abe4294d31de8b5788a88ac00000000', 'txid': 'e977c07090c2a1dcaefd3f3c4ebf4e231f4116cb272f805b0b22a85e7eece09c', 'hash': 'e977c07090c2a1dcaefd3f3c4ebf4e231f4116cb272f805b0b22a85e7eece09c', 'size': 192, 'vsize': 192, 'version': 1, 'locktime': 0, 'vin': [{'txid': '05e69c373f787ab7635465db94225307e4ad6685d3df63ff605efebe3f17dae4', 'vout': 0, 'scriptSig': {'asm': '3045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f101 02ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2', 'hex': '483045022100af246c27890c2bc07a0b7450d3d82509702a44a4defdff766355240b114ee2ac02207bb67b468452fa1b325dd5583879f5c1412e0bb4dae1c2c96c7a408796ab76f1012102ab9e8575536a1e99604a158fc60fe2ebd1cb1839e919b4ca42b8d050cfad71b2'}, 'sequence': '4294967295'}], 'vout': [{'value': '2.00000000', 'n': 0, 'scriptPubKey': {'asm': 'OP_DUP OP_HASH160 df76c017354ac39bde796abe4294d31de8b5788a OP_EQUALVERIFY OP_CHECKSIG', 'hex': '76a914df76c017354ac39bde796abe4294d31de8b5788a88ac', 'type': 'p2pkh', 'address': '1MNZwhTBHN3QTXkwob7NvhVaTVKUm7MRCg'}}]})\n\u003cbtcpy.structs.transaction.Transaction object at 0x7f3717971518\u003e\n```\n\nExample of a transaction creation:\n\n```python\n\u003e\u003e\u003e from btcpy.structs.transaction import Transaction, TxIn, Sequence, TxOut, Locktime\n\u003e\u003e\u003e script_sig = Script.unhexlify('48304502210083e6e7507e838a190f0443441c0b62d2df94673887f4482e27e89ff415a90392022050575339c649b85c04bb410a00b62325c1b82c537135fa62fb34fae2c9a30b0b01210384478d41e71dc6c3f9edde0f928a47d1b724c05984ebfb4e7d0422e80abe95ff')\n\u003e\u003e\u003e script_pubkey = ScriptBuilder.identify('76a914905f77004d081f20dd421ba5288766d56724c3b288ac')\n\u003e\u003e\u003e tx = Transaction(version=1,\n...                  ins=[TxIn(txid='1a5a4f9a0d34cfca187db4fe6a3316f46264984c4b4c9fdb582123815afd508f',\n...                            txout=0,\n...                            script_sig=script_sig,\n...                            sequence=Sequence.max())],\n...                  outs=[TxOut(value=193000000,\n...                              n=0,\n...                              script_pubkey=script_pubkey)],\n...                  locktime=Locktime(0))\n\u003e\u003e\u003e tx.txid\n'14e6afbae7d2b1825b7ee711cbcad77d519767b70f5a1e70e5ba7f0bfc902e81'\n```\n\nExample creation of a SegWit transaction:\n\n```python\n\u003e\u003e\u003e from btcpy.structs.transaction import SegWitTransaction, Witness\n\u003e\u003e\u003e from btcpy.structs.script import StackData, empty_script\n\u003e\u003e\u003e witness_sig = StackData.from_bytes(unhexlify('304402200d0fbf48270e690be17cb0c47ee6ce2df3b671c2e4b196065e09c6df649b807c022056d8f10da83b2856458152c7f09e53a3495f3fbdd2e20638586a52ddff4f495b01'))\n\u003e\u003e\u003e witness_pubkey = StackData.from_bytes(unhexlify('02a079cb0269c933b1ee041a933092c9c439dd1b3a4eebd32ae391cf815002d378'))\n\u003e\u003e\u003e witness = Witness([witness_sig, witness_pubkey])\n\u003e\u003e\u003e script_pubkey = ScriptBuilder.identify('a914b2eb061810dac0614ac3e06d1bc55077b32b3b2687')\n\u003e\u003e\u003e tx = SegWitTransaction(version=1,\n...                        ins=[TxIn(txid='1a5a4f9a0d34cfca187db4fe6a3316f46264984c4b4c9fdb582123815afd508f',\n...                                  txout=0,\n...                                  script_sig=empty_script,\n...                                  sequence=Sequence.max(),\n...                                  witness=witness],\n...                        outs=[TxOut(value=193000000,\n...                                    n=0,\n...                                    script_pubkey=script_pubkey)],\n...                        locktime=Locktime(0))\n\u003e\u003e\u003e tx.txid\n'14dd31532ca06d62121fd13d35a2c9090246291960e73bf2bb3615abcb1bedab'\n```\n\nOf course, nobody would like to create transactions in such a cumbersome way. In fact,\nthis library provides the appropriate tools to create complex scriptPubKeys in an easy\nfashion and to automatically fill in scriptSigs and witnesses of a spending transaction\nbased on the minimum needed parameters. In the following sections we will show some\nexamples of these features.\n\nThe supported scripts can be created by using their constructor and passing them the\nneeded parameters. They can be found in `btcpy.structs.script`. All the constructors of these classes can take an input of type `Script`.\nIn this case they try to match it to their template and raise a `WrongScriptTypeException`\nif the script does not match the desired template. Otherwise, they take the following\nparameters:\n\n| Class                         | Description |Parameters      |\n| ----------------------------- | ----------- | -------------- |\n| `P2pkhScript`, `P2wpkhScript` | A P2PKH/P2WPKH script | Either a `PublickKey`, a `bytearray` representing a public key hash or an `Address`           |\n| `P2shScript`                  | A P2SH script  | Either a `ScriptPubKey` representing the redeemScript, a `bytearray` representing the redeemScript's hash or an `Address`   |\n| `P2wshScript`                 | A P2WSH script | Either a `ScriptPubKey` representing the witnessScript, a `bytearray` representing the witnessScript's hash or an `Address`  |\n| `P2pkScript`                  | A P2PK script | A `PublicKey` |\n| `NulldataScript`              | An OP_RETURN script | A `StackData` representing the data to store in the transaction |\n| `MultisigScript`              | A multisig script, where m out of n keys are needed to spend | `m`, the number of signatures needed to spend this output, an arbitrary number of `PublicKeys`, `n` the number of public keys provided |\n| `IfElseScript`              | A script consisting of an `OP_IF`, a script, an `OP_ELSE`, another script and an `OP_ENDIF` | Two `ScriptPubKey` scripts, the first to be executed in the if branch, the second to be executed in the else branch |\n| `AbsoluteTimelockScript`              | A script consisting of `\u003cpushdata\u003e OP_CHECKLOCKTIMEVERIFY OP_DROP` and a subsequent script which can be spent only after the absolute time expressed by the `\u003cpushdata\u003e` is expired | A `Locktime`, expressing the absolute time/number of blocks after which the subsequent script can be spent, and the locked `ScriptPubKey` |\n| `RelativeTimelockScript`      | A script consisting of `\u003cpushdata\u003e OP_CHECKSEQUENCEVERIFY OP_DROP` and a subsequent script which can be spent only after the relative time time expressed by the `\u003cpushdata\u003e` is expired | A `Sequence`, expressing the relative time/ number of blocks after which the subsequent script can be spent, and the locked `ScriptPubKey` |\n| `Hashlock256Script`           | A script consisting of `OP_HASH256 \u003cpushdata\u003e OP_EQUALVERIFY` and a subsequent script which can be spent only after providing the preimage of `\u003cpushdata\u003e` for the double SHA256 hash function | Either a `bytearray` or `StackData` representing the hashed value that locks the subsequent script, plus the locked `ScriptPubKey` |\n| `Hashlock160Script`           | A script consisting of `OP_HASH160 \u003cpushdata\u003e OP_EQUALVERIFY` and a subsequent script which can be spent only after providing the preimage of `\u003cpushdata\u003e` for the RIPEMPD160 of the SHA256 hash function | Either a `bytearray` or `StackData` representing the hashed value that locks the subsequent script, plus the locked `ScriptPubKey` |\n  \nPlease note that in the following sections we will frequently use the same keypair for ease of\ndocumenting, of course this is a very bad practice in a production environment\nand should be avoided at all costs.\n\n### Spending a transaction\nThis library offers `Solver`s to spend a previous transaction's output. Solvers can be found in `btcpy.structs.sig` and \nexpect as input all the data needed to create the appropriate scriptSig and witness.\nTo create a `Solver`, the `Sighash` class is needed. This class represents a SIGHASH\nand its constructor takes two parameters:\n* `sighash`, either of the literal strings `'ONE'`, `'ALL'` or `'NONE'`\n* `anyonecanpay`, a flag defaulting to `False`.\n\nThe following solvers take one sighash as last parameter, defaulting to `Sighash('ALL')`:\n* `P2pkhSolver`\n* `P2wpkhV0Solver`\n* `P2pkSolver`\n\nThe `MultisigSolver` class takes many sighashes as additional last parameters, all\ndefaulting to `Sighash('ALL')`. All other classes do not accept sighashes.\n\nAdditionally, the following solvers are available and they take the following inputs:\n\n| Class            | Inputs                                                                                               | Solves            |\n|------------------|----------------------------------------------------------------------------------------------------- |-------------------|\n| `P2pkhSolver`    | a `PrivateKey`                                                                                       | `P2pkhScript`     |\n| `P2wpkhV0Solver` | a `PrivateKey`                                                                                       | `P2wpkhV0Script`  |\n| `P2pkSolver`     | a `PrivateKey`                                                                                       | `P2pkhScript`     |\n| `P2shSolver`     | a `ScriptPubKey`, representing the redeemScript and a `Solver` which solves the redeemScript         | `P2shScript`      |\n| `P2wshV0Solver`  | a `ScriptPubKey`, representing the witnessScript and a `Solver` which solves the inner witnessScript | `P2wshV0Script`   |\n| `MultisigSolver` | an arbitrary number of `PrivateKey`s                                                                 | `MultisigScript`  |\n| `IfElseSolver`   | an object of type `Branch`. This is an enum and its values are `Branch.IF` and `Branch.ELSE`, these are used to specify whether we are spending the `if` or `else` branch of the script. The second parameter is a `Solver` for the script inside the desired branch. | `IfElseScript` |\n| `TimelockSolver` | a `Solver` of the inner timelocked script | `AbsoluteTimelockScript`, `RelativeTimelockScript` |\n| `RelativeTimelockSolver` | a `Solver` of the inner timelocked script, with relative timelocks | `RelativeTimelockScript` |\n| `AbsoluteTimelockSolver` | a `Solver` of the inner timelocked script, with absolute timelocks | `AbsoluteTimelockScript` |\n| `HashlockSolver` | the preimage needed to spend the script, as a `bytearray`, and a `Solver` for the hashlocked script | `Hashlock256Script`, `Hashlock160Script` |\n\n\nTo spend a previous transaction, the `MutableTransaction` class provides the `spend()` method.\nThe `spend()` method expects the following inputs:\n* `txouts`, an array of `TxOut`s being spent by the transaction's inputs, in the correct\norder.\n* `solvers`, an array of `Solver`s, one per input, in the correct order\n\nfor example:\n\n```python\n\u003e\u003e\u003e from btcpy.structs.sig import *\n\u003e\u003e\u003e to_spend = Transaction.unhexlify('...')\n\u003e\u003e\u003e unsigned = MutableTransction(version=1,\n...                              ins=[TxIn(txid=to_spend.txid,\n...                                        txout=0,\n...                                        script_sig=ScriptSig.empty(),\n...                                        sequence=Sequence.max())],\n...                              outs=[TxOut(value=100000,\n...                                          n=0,\n...                                          script_pubkey=P2pkhScript(pubk))],\n...                              locktime=Locktime(0))\n\u003e\u003e\u003e solver = P2pkhSolver(privk)\n\u003e\u003e\u003e signed = unsigned.spend([to_spend.outs[0]], [solver])\n```\n\nIn particular, the `spend()` method automatically recognises whether we are spending a SegWit transaction,\nhence returning either a `Transaction` or a `SegWitTransaction`.\n\nNow, let's see how more complex scripts can be created and spent. In the following examples, in solvers,\nwe will always use the default SIGHASH_ALL, to change this, as described above, one can use the\nlast parameter of the solvers that accept SIGHASHes.\n\n### P2PKH\n\nThis is how a P2PKH script can be created:\n\n```python\n# create public key\n\u003e\u003e\u003e pubk = PublicKey.unhexlify('025f628d7a11ace2a6379119a778240cb70d6e720750416bb36f824514fbe88260')\n# create P2PKH script\n\u003e\u003e\u003e p2pkh_script = P2pkhScript(pubk)\n\u003e\u003e\u003e p2pkh_script.hexlify()\n'76a914905f77004d081f20dd421ba5288766d56724c3b288ac'\n\u003e\u003e\u003e str(p2pkh_script)\n'OP_DUP OP_HASH160 905f77004d081f20dd421ba5288766d56724c3b2 OP_EQUALVERIFY OP_CHECKSIG'\n```\n\nand this is an example of a P2PKH solver:\n\n```python\n\u003e\u003e\u003e privk = PrivateKey.unhexlify('a12618ff6540dcd79bf68fda2faf0589b672e18b99a1ebcc32a40a67acdab608')\n\u003e\u003e\u003e p2pkh_solver = P2pkhSolver(privk)\n```\n\nnow let's assume we have an unsigned mutable transaction, we will use this solver to fill in the transaction's\nscriptSig:\n\n```python\n\u003e\u003e\u003e unsigned_tx = MutableTransaction(...)\n\u003e\u003e\u003e previous_txout = TxOut(value=1000, n=0, script_pubkey=p2pkh_script)\n\u003e\u003e\u003e signed_tx = unsigned_tx.spend([previous_txout], [p2pkh_solver])\n```\n\n### P2SH\nCreating a P2SH script that embeds a P2PKH script:\n\n```python\n\u003e\u003e\u003e p2sh_script = P2shScript(P2pkhScript(pubk))\n\u003e\u003e\u003e p2sh_script.hexlify()\n'a914cd1ab43e7c01a08886fd0e699988d2f44c9c57cc87'\n\u003e\u003e\u003e str(p2sh_script)\n'OP_HASH160 cd1ab43e7c01a08886fd0e699988d2f44c9c57cc OP_EQUAL'\n```\n\nA solver to spend it would be:\n\n```python\n\u003e\u003e\u003e privk = PrivateKey.unhexlify('a12618ff6540dcd79bf68fda2faf0589b672e18b99a1ebcc32a40a67acdab608')\n\u003e\u003e\u003e solver = P2shSolver(P2pkhScript(pubk),  # the redeemScript\n                        P2pkhSolver(privk)) # the redeemScript's solver\n```\n\n### P2WSH\nCreating a P2WSH script that embeds a P2PKH script:\n\n```python\n\u003e\u003e\u003e p2wsh_script = P2wshV0Script(P2pkhScript(pubk))\n\u003e\u003e\u003e p2wsh_script.hexlify()\n'002058f04cd072784e9dede6821772a195cef65424f2e4957e14232e642bbbdf1aec'\n\u003e\u003e\u003e str(p2wsh_script)\n'OP_0 58f04cd072784e9dede6821772a195cef65424f2e4957e14232e642bbbdf1aec'\n```\n\nSolving it:\n\n```python\n\u003e\u003e\u003e solver = P2wshV0Solver(P2pkhScript(pubk),  # witness script\n...                        P2pkhSolver(privk)) # witness script's solver\n```\n\n### P2WSH-over-P2SH\nLet's now create a P2SH scriptPubKey that embeds a P2WSH that, in turn, embeds\na P2PKH:\n\n```python\n\u003e\u003e\u003e p2wsh_over_p2sh = P2shScript(P2wshV0Script(P2pkhScript(pubk)))\n\u003e\u003e\u003e p2wsh_over_p2sh.hexlify()\n'a914efbd1b969b0e15e7a3dc9b1128e4cf493974e62187'\n\u003e\u003e\u003e str(p2wsh_over_p2sh)\n'OP_HASH160 efbd1b969b0e15e7a3dc9b1128e4cf493974e621 OP_EQUAL'\n\u003e\u003e\u003e solver = P2shSolver(\n...              P2wshV0Script(P2pkhScript(pubk)),   # redeemScript\n...              P2wshV0Solver(            # redeemScript solver\n...                  P2pkhScript(pubk),    # witnessScript\n...                  P2pkhSolver(privk)    # witnessScript solver\n...              )\n...           )\n```\n\n### P2PK\n\n```python\n\u003e\u003e\u003e p2pk_script = P2pkScript(pubk)\n\u003e\u003e\u003e p2pk_script.hexlify()\n'21025f628d7a11ace2a6379119a778240cb70d6e720750416bb36f824514fbe88260ac'\n\u003e\u003e\u003e str(p2pk_script)\n'025f628d7a11ace2a6379119a778240cb70d6e720750416bb36f824514fbe88260 OP_CHECKSIG'\n\u003e\u003e\u003e solver = P2pkSolver(privk)\n```\n\n### Multisig\n\n```python\n\u003e\u003e\u003e privk2 = PrivateKey.unhexlify('710b464f020b676fd9ec3af28d014dec9c8582e6a9059731a3e14aa762527ae4')\n\u003e\u003e\u003e pubk2 = privk2.pub()\n\u003e\u003e\u003e multisig_script = MultisigScript(1, pubk, pubk2, 2)  # a 1-of-2 multisig\n\u003e\u003e\u003e multisig_script.hexlify()\n'5121025f628d7a11ace2a6379119a778240cb70d6e720750416bb36f824514fbe882602102a5f22a78db5c38eaa18f73390e82e000bd52ab84edbcb3ad9b4124460acaf5ee52ae'\n\u003e\u003e\u003e str(multisig_script)\n'OP_1 025f628d7a11ace2a6379119a778240cb70d6e720750416bb36f824514fbe88260 02a5f22a78db5c38eaa18f73390e82e000bd52ab84edbcb3ad9b4124460acaf5ee OP_2 OP_CHECKMULTISIG'\n\u003e\u003e\u003e multisig_solver = MultisigSolver(privk)  # this could potentially be passed a list of SIGHASHES in the end to use them when signing\n```\n\nAs one will usually embed this in a P2SH format, this could be done as follows:\n\n```python\n\u003e\u003e\u003e p2sh_multisig = P2shScript(multisig_script)\n\u003e\u003e\u003e solver = P2shSolver(multisig_script, multisig_solver)\n```\n\n### Timelocks, Hashlocks, IfElse\nNow we are going to create a very complex output. This output can be spent in two ways:\n1. at any time, with two out of two signatures\n2. 5 blocks after it has entered a block, with only one signature.\nThis script is hence composed of two possible execution flows: an `if` branch and\nan `else` branch. Inside the first branch, a 2-of-2 multisig script can be found.\nInside the second branch there is a timelocked script. Such a script has a time\n(a relative time in this case, expressed as a `Sequence` number) and an inner script,\nwhich is the one that can be executed after the relative time has expired.\nWe can create such a script in the following way:\n\n```python\n\u003e\u003e\u003e timelocked_multisig = IfElseScript(\n...     # if branch\n...     MultisigScript(  # a multisig script, as above\n...         2,\n...         pubk,\n...         pubk2,\n...         2\n...     ),\n...     # else branch\n...     RelativeTimelockScript(  # timelocked script\n...         Sequence(5),  # expiration, 5 blocks\n...         P2pkhScript(  # locked script\n...             pubk\n...         )\n...     )\n... )\n```\n\nLet's see this script a bit more in depth:\n\n```python\n\u003e\u003e\u003e timelocked_multisig.type\n'if{ multisig }else{ [relativetimelock] p2pkh }'\n\u003e\u003e\u003e str(timelocked_multisig)\n'OP_IF OP_2 025f628d7a11ace2a6379119a778240cb70d6e720750416bb36f824514fbe88260 02a5f22a78db5c38eaa18f73390e82e000bd52ab84edbcb3ad9b4124460acaf5ee OP_2 OP_CHECKMULTISIG OP_ELSE OP_5 OP_CHECKSEQUENCEVERIFY OP_DROP OP_DUP OP_HASH160 905f77004d081f20dd421ba5288766d56724c3b2 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF'\n\u003e\u003e\u003e timelocked_multisig.if_script\nMultisigScript(2, 025f628d7a11ace2a6379119a778240cb70d6e720750416bb36f824514fbe88260, 02a5f22a78db5c38eaa18f73390e82e000bd52ab84edbcb3ad9b4124460acaf5ee, 2)\n\u003e\u003e\u003e str(timelocked_multisig.if_script)\n'OP_2 025f628d7a11ace2a6379119a778240cb70d6e720750416bb36f824514fbe88260 02a5f22a78db5c38eaa18f73390e82e000bd52ab84edbcb3ad9b4124460acaf5ee OP_2 OP_CHECKMULTISIG'\n\u003e\u003e\u003e timelocked_multisig.else_script\nRelativeTimelockScript(5, OP_DUP OP_HASH160 905f77004d081f20dd421ba5288766d56724c3b2 OP_EQUALVERIFY OP_CHECKSIG)\n\u003e\u003e\u003e str(timelocked_multisig.else_script)\n'OP_5 OP_CHECKSEQUENCEVERIFY OP_DROP OP_DUP OP_HASH160 905f77004d081f20dd421ba5288766d56724c3b2 OP_EQUALVERIFY OP_CHECKSIG'\n\u003e\u003e\u003e timelocked_multisig.else_script.locked_script\nP2pkh(905f77004d081f20dd421ba5288766d56724c3b2)\n\u003e\u003e\u003e timelocked_multisig.else_script.locked_script.decompile()\n'OP_DUP OP_HASH160 905f77004d081f20dd421ba5288766d56724c3b2 OP_EQUALVERIFY OP_CHECKSIG'\n```\n\nLet's write the solvers for this script:\n\n```python\n\u003e\u003e\u003e solver_if = IfElseSolver(Branch.IF,                      # branch selection\n...                          MultisigSolver(privk, privk2))  # inner solver\n\u003e\u003e\u003e solver_else = IfElseSolver(Branch.ELSE,\n...                            RelativeTimelockSolver(Sequence(5), P2pkhSolver(privk)))\n```\n\n### Low-level signing\nIf one wants to sign a transaction by hand, instead of using solvers, one of the following procedures can be used:\n\n* Manually writing the scriptSig (this can be seen in the **Creating transactions** section)\n* Creating the scriptSig by computing and signing the digest of the transaction\n\nLet's see an example of this last case:\n\n```python\n\u003e\u003e\u003e unsigned = MutableTransaction(...)\n\u003e\u003e\u003e digest = unsigned.get_digest(2,   # the input to be signed\n                                 prev_script,  # the previous script to spend (this is the redeem/witness script in case of P2SH/P2WSH ouputs)\n                                 sighash=Sighash('NONE', anyonecanpay=True))  # sighash: 0x02 | 0x80\n\u003e\u003e\u003e privk.sign(digest)\n```\n\nIn case one wants to sign a SegWit digest for the transaction, the following can be done:\n\n```python\n\u003e\u003e\u003e unsigned = SegWitTransaction(...)\n\u003e\u003e\u003e digest = unsigned.get_segwit_digest(2,   # the input to be signed\n                                        prev_script,  # the previous script to spend (this is the redeem/witness script in case of P2SH/P2WSH ouputs)\n                                        prev_amount,  # the amount of the output being spent\n                                        sighash=Sighash('NONE', anyonecanpay=True))  # sighash: 0x02 | 0x80\n\u003e\u003e\u003e privk.sign(digest)\n```\n\n# Contributing and running tests\nThis library has two testing tools that can be found in the `tests/` folder:\n* `unit.py`, this runs basic unit testing\n* `integration.py`, this runs tests of signed transactions, to do this, transactions are signed and\nsent to a Bitcoin Core node through the `sendrawtransaction` command.\n\nTo make sure these tests are using the code in the current repository and not a stale copy installed\nin a virtualenv or system wide, please make sure to run the following commands _from the root of the\nrepo_:\n\n```\npython3 -m unittest tests/unit.py\npython3 -m unittest tests/integration.py\n```\n\nContributors are invited to run these tests before submitting PRs. Also, contributions to improve and\nexpand these tests are highly welcome.\n\n# Roadmap to v1\nThis library's stable version 1 will be released once the following changes are made:\n* More efficient script matching (i.e. scripts should be able to specify fast matching conditions\ninstead of trying to parse the raw bytes to decide whether the template is matched)\n* Caching on SegWit digest computation to avoid quadratic hashing\n* Generation of private keys through secure entropy sources\n* An extensive documentation of all modules, classes and their parameters is produced\n\n# TODO\nSince this library is still a work in progress, the following roadmap lists the improvements to be\ndone eventually:\n* Expanding the test suites\n* Adding docstrings where missing (many places)\n* Handling `OP_CODESEPARATOR`s  in the signing process\n* Add further transaction creation helpers\n* Add RPC calls to Bitcoin Core nodes\n* Add networking with Bitcoin Core nodes\n\n# Acknowledgements\nSpecial thanks to [gdecicco](https://github.com/gdecicco) and [lorenzogiust](https://github.com/lorenzogiust)\nfor contributing with performance improvements and general review.\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchainside%2Fbtcpy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchainside%2Fbtcpy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchainside%2Fbtcpy/lists"}