{"id":18705819,"url":"https://github.com/openblockchains/programming-bitcoin-script","last_synced_at":"2025-06-16T09:12:52.478Z","repository":{"id":45284190,"uuid":"40045432","full_name":"openblockchains/programming-bitcoin-script","owner":"openblockchains","description":"Programming Bitcoin Script Transaction (Crypto) Contracts Step-by-Step - Let's start with building your own bitcoin stack machine from zero / scratch and let's run your own bitcoin ops (operations)...","archived":false,"fork":false,"pushed_at":"2021-01-02T10:47:50.000Z","size":475,"stargazers_count":72,"open_issues_count":0,"forks_count":16,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-25T16:55:50.726Z","etag":null,"topics":["bitcoin","bitcoin-script","ivy","opcodes","simplicity"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openblockchains.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-01T12:07:19.000Z","updated_at":"2025-03-21T00:34:20.000Z","dependencies_parsed_at":"2022-09-07T12:02:20.596Z","dependency_job_id":null,"html_url":"https://github.com/openblockchains/programming-bitcoin-script","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openblockchains%2Fprogramming-bitcoin-script","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openblockchains%2Fprogramming-bitcoin-script/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openblockchains%2Fprogramming-bitcoin-script/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openblockchains%2Fprogramming-bitcoin-script/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openblockchains","download_url":"https://codeload.github.com/openblockchains/programming-bitcoin-script/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248550623,"owners_count":21122934,"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","ivy","opcodes","simplicity"],"created_at":"2024-11-07T12:12:00.760Z","updated_at":"2025-04-12T10:20:57.527Z","avatar_url":"https://github.com/openblockchains.png","language":"Ruby","readme":"\nFor more blockchain books, see the [**Best of Crypto Books page »**](https://openblockchains.github.io/crypto-books/)\n\n---\n\n\n# Programming Bitcoin Script Transaction (Crypto) Contracts Step-by-Step\n\n_Let's start with building your own bitcoin stack machine from zero / scratch and let's run your own bitcoin ops (operations)..._\n\n\n**BEWARE: Bitcoin is a gigantic ponzi scheme¹.\nTo the moon!? The new gold standard!? \nDo NOT \"invest\" trying to get-rich-quick HODLing. \nWhy not? The bitcoin code is archaic and out-of-date.\nBurn, baby, burn! Proof-of-work / waste is a global\nenergy environmental disaster\nusing 300 kWh per bitcoin transaction (!) that's about 179 kilograms of CO₂ emissions².\nProgrammable money (or the internet of value) \nfor all future generations with (bitcoin) script\nwithout loops and jumps (gotos) and all \"stateless\"!? LOL.**\n\n\n¹:  ![](i/trolly-ponzi.png)\n\n(Source: [Best of Bitcoin Maximalist - Scammers, Morons, Clowns, Shills \u0026 BagHODLers - Inside The New New Crypto Ponzi Economics](https://bitsblocks.github.io/bitcoin-maximalist))\n\n²: Assuming let's say 0.596 kilograms of CO₂ per kWh \n(that's the energy efficiency in Germany) that's \nabout 179 kilograms of CO₂ per bitcoin transaction (300 kWh × 0.596 kg). For more insights see the [Bitcoin Energy Consumption Index](https://digiconomist.net/bitcoin-energy-consumption).\n\n\n\n\n\n## Inside Bitcoin Script\n\nDid you know? Every (yes, every) bitcoin transaction (payment) runs\na contract script (one half coming from the \"output\" or \"lock\" transaction and the\nother half coming from the \"input\" or \"unlock\" transaction).\nThe programming language is called simply (bitcoin) script.\n\n\u003e Bitcoin uses a scripting system for transactions.\n\u003e Forth-like, Script is simple, stack-based, and processed from left to right.\n\u003e It is intentionally not Turing-complete, with no loops.\n\u003e\n\u003e (Source: [Script @ Bitcoin Wiki](https://en.bitcoin.it/wiki/Script))\n\n\nFirst impression. Adding 2+2 in Bitcoin Script starting from zero / scratch:\n\n``` ruby\n## A simple stack machine\ndef op_add( stack )\n  left  = stack.pop\n  right = stack.pop\n  stack.push( left + right )\nend\n\ndef op_2( stack )\n  stack.push( 2 )\nend\n\n## Let's run!\n\nstack = []\nop_2( stack )     #=\u003e stack = [2]\nop_2( stack )     #=\u003e stack = [2,2]\nop_add( stack )   #=\u003e stack = [4]\n```\n\n(Source: [`stackmachine_add.rb`](stackmachine_add.rb))\n\n\n\nYes, that's all the magic! You have built your own stack machine with\ntwo operations / ops, that is, `op_add` and `op_2`.\n\nThe `op_2` operation pushes the number `2` onto the stack.\nThe `op_add` operation pops the top two numbers from the stack\nand pushes the result onto the stack.  \n\n\nAside - What's a Stack? Push 'n' Pop\n\nA stack is a last-in first-out (LIFO) data structure. Use `push`\nto add an element to the top of the stack and use `pop`\nto remove the top element from the stack.\nExample:\n\n``` ruby\nstack = []                   #=\u003e []\nstack.empty?                 #=\u003e true\n\nstack.push( 1 )              #=\u003e [1]\nstack.empty?                 #=\u003e false\nstack.push( 2 )              #=\u003e [1, 2]\nstack.push( 3 )              #=\u003e [1, 2, 3]\nstack.push( \"\u003csignature\u003e\" )  #=\u003e [1, 2, 3, \"\u003csignature\u003e\"]\nstack.push( \"\u003cpubkey\u003e\")      #=\u003e [1, 2, 3, \"\u003csignature\u003e\", \"\u003cpubkey\u003e\"]\n\nstack.pop                    #=\u003e \"\u003cpubkey\u003e\"\nstack                        #=\u003e [1, 2, 3, \"\u003csignature\u003e\"]\nstack.pop                    #=\u003e \"\u003csignature\u003e\"\nstack                        #=\u003e [1, 2, 3]\n\nstack.push( 4 )              #=\u003e [1, 2, 3, 4]\nstack.push( 5 )              #=\u003e [1, 2, 3, 4, 5]\n\nstack.pop                    #=\u003e 5\nstack                        #=\u003e [1, 2, 3, 4]\nstack.pop                    #=\u003e 4\nstack                        #=\u003e [1, 2, 3]\nstack.pop                    #=\u003e 3\nstack                        #=\u003e [1, 2]\nstack.pop                    #=\u003e 2\nstack                        #=\u003e [1]\nstack.empty?                 #=\u003e false\nstack.pop                    #=\u003e 1\nstack                        #=\u003e []\nstack.empty?                 #=\u003e true\nstack.pop                    #=\u003e nil\n```\n\n(Source: [`stack.rb`](stack.rb))\n\n\n\nUnlock+Lock / Input+Output / ScriptSig+ScriptPubKey\n\nIn \"real world\" bitcoin the script has two parts / halves in two transactions\nthat get combined.\nThe \"lock\" or \"output\" or \"ScriptPubKey\" script\nthat locks the \"unspent transaction output (UTXO)\",\nand the \"unlock\" or \"input\" or \"ScriptSig\" script that unlocks\nthe bitcoins.\n\n\nAnyone Can Spend (Unlock) the Outputs (Bitcoins)\n\nThe bitcoins are yours if the bitcoins haven't been spent yet -\nsee blockchain and how it solves the double-spending problem :-) -\nAND if the script returns with true, that is, `1` is on top of the stack.\n\n``` ruby\n## A simple stack machine\ndef op_true( stack )\n  stack.push( 1 )\nend\n\n## Let's run!\n\nstack = []\n##  I) ScriptSig (input/unlock) part\nop_true( stack )  #=\u003e stack = [1]\n\n## II) ScriptPubKey (output/lock) part\n##     \u003cEmpty\u003e\n```\n\n(Source: [`stackmachine_anyone.rb`](stackmachine_anyone.rb))\n\n\nBingo! Yes, that's all the magic!\nThe `op_true` operation pushes the number `1`, that is, `true` onto the stack.\n\nThe \"official\" bitcoin script notation reads:\n\n```\nScriptSig (input):    OP_TRUE\nScriptPubKey:         (empty)\n```\n\nNow let's split the adding `2+2` script into a two part puzzle,\nthat is, `?+2=4`\nor into `ScriptSig` and `ScriptPubKey`.\nIf you know the answer you can \"unlock\" the bounty,\nthat is, the bitcoins are yours!\nHere's the challenge:\n\n``` ruby\n## A simple stack machine\ndef op_add( stack )\n  left  = stack.pop\n  right = stack.pop\n  stack.push( left + right )\nend\n\ndef op_2( stack )\n  stack.push( 2 )\nend\n\ndef op_4( stack )\n  stack.push( 4 )\nend\n\ndef op_equal( stack )\n  left  = stack.pop\n  right = stack.pop\n  stack.push( left == right ? 1 : 0 )\nend\n\n## Let's run!\n\nstack = []\n##  I) ScriptSig (input/unlock) part\n##     FIX!!! - add your \"unlock\" stack operation / operations here\n\n## II) ScriptPubKey (output/lock) part\nop_2( stack )      #=\u003e stack = [?, 2]\nop_add( stack )    #=\u003e stack = [4]\nop_4( stack )      #=\u003e stack = [4,4]\nop_equal( stack )  #=\u003e stack = [1]\n```\n\n(Source: [`stackmachine_puzzle.rb`](stackmachine_puzzle.rb))\n\n\n\n\nThe \"official\" bitcoin script notation reads:\n\n```\nScriptSig (input):    ?\nScriptPubKey:         OP_2 OP_ADD OP_4 OP_EQUAL\n```\n\n\nIf you check all Bitcoin script operations -\nthe following ops should no longer be a mystery:\n\nConstants\n\n|Word | Opcode |Hex | Input | Output | Description|\n|-----|--------|----|-------|--------|------------|\n| OP_0, OP_FALSE |  0  |  0x00 | Nothing. | (empty value) |  An empty array of bytes is pushed onto the stack. (This is not a no-op: an item is added to the stack.) |\n| OP_1, OP_TRUE  | 81  | 0x51  | Nothing. | 1 | The number 1 is pushed onto the stack. |\n| OP_2-OP_16 | 82-96 |  0x52-0x60  | Nothing. |  2-16 |  The number in the word name (2-16) is pushed onto the stack. |\n\nBitwise logic\n\n|Word | Opcode |Hex | Input | Output | Description|\n|-----|--------|----|-------|--------|------------|\n| OP_EQUAL | 135  | 0x87 | x1 x2  | True / false |  Returns 1 if the inputs are exactly equal, 0 otherwise. |\n\nArithmetic\n\n|Word | Opcode |Hex | Input | Output | Description|\n|-----|--------|----|-------|--------|------------|\n| OP_ADD |  147  | 0x93  | a b | out  | a is added to b. |\n| OP_MUL |  149  | 0x95  | a b | out  | a is multiplied by b. **disabled.** |\n| OP_DIV |  150  | 0x96  | a b | out  | a is divided by b. **disabled.** |\n\n\n\nTrivia Corner: Did you know? The `OP_MUL` for multiplications (e.g. `2*2`)\nhas been banned, that is, disabled!  Why?\nBecause of security concerns, that is, fear of stack overflows.\nWhat about `OP_DIV` for divisions (e.g. `4/2`)?  Don't ask!\nAsk who's protecting you from stack underflows?\nSo what's left for programming - not much really other than checking\nsignatures and timelocks :-).\n\n\n\n## Standard Scripts\n\nYou don't have to start from zero / scratch.\nBitcoin has many standard script templates.\nThe most important include:\n\n\n| Short Name | Long Name  |\n|------------|------------|\n| p2pk   | Pay-to-pubkey     |\n| p2pkh  | Pay-to-pubkey-hash |\n| p2sh   | Pay-to-script-hash  |\n\nStandard Scripts with SegWit (Segregated Witness)\n\n| Short Name | Long Name  |\n|------------|------------|\n| p2wpkh | Pay-to-witness-pubkey-hash  |\n| p2wsh  | Pay-to-witness-script-hash  |\n\n\n\n## p2pk - Pay-to-pubkey\n\nPay-to-pubkey (p2pk) is the simplest standard script\nand was used in the early days\nincluding by Satoshi Nakamoto (the pseudonymous Bitcoin founder).\n\nBitcoin Trivia:\n\n\u003e As initially the sole and subsequently the predominant miner,\n\u003e Nakamoto was awarded bitcoin at genesis and for 10 days afterwards.\n\u003e Except for test transactions these remain unspent since mid January 2009.\n\u003e The public bitcoin transaction log shows that Nakamoto's known addresses contain\n\u003e roughly one million bitcoins. At bitcoin's peak in December 2017,\n\u003e this was worth over US$19 billion,\n\u003e making Nakamoto possibly the 44th richest person in the world at the time.\n\u003e\n\u003e (Source: [Satoshi Nakamoto @ Wikipedia](https://en.wikipedia.org/wiki/Satoshi_Nakamoto))\n\n\nThe one million bitcoins are yours if the pay-to-pubkey (p2pk) script\nreturns with true, that is, `1` is on top of the stack.\nThe only input you need to unlock the the fortune is the signature. Are you Satoshi?\nLet's try:\n\n\n``` ruby\n## Bitcoin crypto helper\n\nclass Bitcoin\n  def self.checksig( sig, pubkey )\n    ## \"crypto\" magic here\n    ##  for testing always return false for now; sorry\n    false\n  end\nend  \n\n\n## A simple stack machine\n\ndef op_checksig( stack )\n  pubkey = stack.pop\n  sig    = stack.pop\n  if Bitcoin.checksig( sig, pubkey )\n    stack.push( 1 )\n  else\n    stack.push( 0 )\n  end\nend\n\n## Let's run!\n\nstack = []\n##  I) ScriptSig (input/unlock) part\nstack.push( \"\u003csig\u003e\" )   #=\u003e stack = [\"\u003csig\u003e\"]\n\n## II) ScriptPubKey (output/lock) part\nstack.push( \"\u003cpubkey\")  #=\u003e stack = [\"\u003csig\u003e\", \"\u003cpubkey\u003e\" ]\nop_checksig( stack )    #=\u003e stack = [0]\n```\n\n(Source: [`pay-to-pubkey.rb`](pay-to-pubkey.rb))\n\nBingo! Yes, that's all the magic!\nThe `op_checksig` operation pops two elements from\nthe stack, that is, the public key (pubkey)\nand the signature (sig) and\nif the elliptic curve crypto validates the signature (from the input/unlock transaction)\nusing the public key (from the the output/lock transaction)\nthen the fortune is yours! If not\nthe number `0`, that is, `false` gets pushed onto the stack\nand you're out of luck. Sorry.\n\nThe \"official\" bitcoin script notation reads:\n\n```\nScriptSig (input): \u003csig\u003e\nScriptPubKey:      \u003cpubKey\u003e OP_CHECKSIG\n```\n\nNote: Can you guess where the input / unlock part got its ScriptSig name\nand where the output / lock part got its ScriptPubKey name?\nYes, from the pay-to-pubkey script.\n\n\n\nAside - Ivy - Higher-Level Bitcoin Script Language\n\nWhat's Ivy?  \n\nFrom the project's readme:\n\n\u003e Ivy is a higher-level language that allows you to write (crypto) contracts\n\u003e for the Bitcoin protocol. Ivy can compile to opcodes for Bitcoin’s stack machine,\n\u003e Bitcoin Script, and can be used to create SegWit-compatible Bitcoin addresses...\n\u003e\n\u003e You can try out Ivy using the [Ivy Playground for Bitcoin](https://ivy-lang.org/bitcoin),\n\u003e which allows you to create test contracts and try spending them,\n\u003e all in a sandboxed environment.\n\u003e\n\u003e (Source: [Ivy Language Documentation](https://docs.ivy-lang.org/bitcoin/))\n\n\nLet's look at the pay-to-pubkey script in Ivy:\n\n```\ncontract LockWithPublicKey(publicKey: PublicKey, val: Value) {\n  clause spend(sig: Signature) {\n    verify checkSig(publicKey, sig)\n    unlock val\n  }\n}\n```\n\nAnd - surprise, surprise - the higher-level script compiles to\n\n```\n\u003cpubKey\u003e OP_CHECKSIG\n```\n\n\nElliptic Curve Cryptography\n\nSo what does a \"real world\" public key (pubkey) look like?\nIn the early days Satoshi Nakamoto\nused the uncompressed SEC (Standards for Efficient Cryptography) format\nfor the public key that results\nin 65 raw bytes.\nBitcoin uses elliptic curve\ncryptography and the public key is a point (x,y) on\nthe curve where the x and y coordinates are each 256-bit (32 byte) numbers.\n\nIn the uncompressed format, place the x and y coordinate next to each other,\nthen prefix with `04` to indicate that it is an uncompressed public key:\n\n```\nprefix (1 byte)         : 04\nx-coordinate (32 bytes) : fe53c78e36b86aae8082484a4007b706d5678cabb92d178fc95020d4d8dc41ef\ny-coordinate (32 bytes) : 44cfbb8dfa7a593c7910a5b6f94d079061a7766cbeed73e24ee4f654f1e51904\n    =\u003e\n04fe53c78e36b86aae8082484a4007b706d5678cabb92d178fc95020d4d8dc41ef44cfbb8dfa7a593c7910a5b6f94d079061a7766cbeed73e24ee4f654f1e51904\n```\n\nAnd in the compressed form because the elliptic curve is symmetrical\nalong its x-axis, the trick is that each x-coordinate will\nonly ever have one of two possible y coordinates:\n\n- If y is even, it corresponds to one of the points.\n- If y is odd, it corresponds to the other.\n\nThus, in the compressed public key format place the x coordinate\nalong with a prefix (`02` or `03`)\nthat tells whether the y is even (`02`) or odd (`03`).\n\n```\nprefix (1 byte)         : 03\nx-coordinate (32 bytes) : df51984d6b8b8b1cc693e239491f77a36c9e9dfe4a486e9972a18e03610a0d22\n     =\u003e\n03df51984d6b8b8b1cc693e239491f77a36c9e9dfe4a486e9972a18e03610a0d22\n````\n\n\nLet's create a public key from the private key\n\nNote: Let's use the 3rd party [Elliptic Curve Digital Signature Algorithm (ECDSA)\nlibrary / gem](https://rubygems.org/gems/ecdsa) by David Grayson.\n\n``` ruby\nrequire 'pp'\nrequire 'ecdsa'           # Use an elliptic curve library\n\n# This private key is just an example. It should be much more secure!\nprivatekey = 1234\n\n# Elliptic curve multiplication\ngroup = ECDSA::Group::Secp256k1                          # Select the curve used in Bitcoin\npoint = group.generator.multiply_by_scalar( privatekey ) # Multiply by integer (not hex)\n#=\u003e \u003cECDSA::Point: secp256k1,\n#       0xe37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f2,\n#       0x6d2ee9a82d4158f164ae653e9c6fa7f982ed8c94347fc05c2d068ff1d38b304c\u003e\n\n# Uncompressed format (with prefix 04)\n#   Convert to 64 hexstring characters (32 bytes) in length\nprefix = '04'\npubkey = prefix + \"%064x\" % point.x + \"%064x\" % point.y\n#=\u003e \"04e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f26d2ee9a82d4158f164ae653e9c6fa7f982ed8c94347fc05c2d068ff1d38b304c\"\n\n# Compressed format (with prefix - 02 = even / 03 = odd)\n#   Instead of using both x and y coordinates,\n#   just use the x-coordinate and whether y is even/odd\nprefix = point.y % 2 == 0 ? '02' : '03'\npubkey = prefix + \"%064x\" % point.x\n#=\u003e \"02e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f2\"\n```\n\n(Source: [`pubkey.rb`](pubkey.rb))\n\n\n\n\n\n\n## p2pkh - Pay-to-pubkey-hash\n\n\n...\n\n\n\nAside - What's Hash160?\n\nIt's a hash function to hash and shorten public keys. Public keys\nif uncompressed shorten from 65 bytes to 20 bytes\n(or if compressed from 33 bytes). Example:\n\n```\npubkey          = 02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737\nhash160(pubkey) = 93ce48570b55c42c2af816aeaba06cfee1224fae\n````\n\nTo compute the Hash160 run the public key through the SHA256 and RIPEMD160 hash functions.\nExample:\n\n``` ruby\nrequire 'digest'                           # Hash (Digest) Functions\n\ndef hash160( pubkey )\n  binary    = [pubkey].pack( \"H*\" )       # Convert to binary first before hashing\n  sha256    = Digest::SHA256.digest( binary )\n  ripemd160 = Digest::RMD160.digest( sha256 )\n              ripemd160.unpack( \"H*\" )[0]    # Convert back to hex\nend\n\npubkey = \"02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737\"\nhash160( pubkey )  \n#=\u003e \"93ce48570b55c42c2af816aeaba06cfee1224fae\"\n```\n\n(Source: [`hash160.rb`](hash160.rb))\n\n\nSecurity Trivia I: Why use SHA256 and RIPEMD160?\n\nRIPEMD160 gets used because it results in\na short 160 bit (20 byte) digest BUT is not the strongest hash function on it's own,\nthus, SHA256 gets used for more strength. Best of both world.\n\nSecurity Trivia II: What's RIPEMD160?\n\nRACE¹ Integrity Primitives Evaluation Message Digest 160-bit\n\n¹: Research and development in Advanced Communications technologies in Europe\n\n``` ruby\ndef ripemd160( message )\n  Digest::RMD160.hexdigest( message )\nend\n\nripemd160( \"The quick brown fox jumps over the lazy dog\" )\n#=\u003e \"37f332f68db77bd9d7edd4969571ad671cf9dd3b\"\n\nripemd160( \"The quick brown fox jumps over the lazy cog\" )\n#=\u003e \"132072df690933835eb8b6ad0b77e7b6f14acad7\"\n\n# The hash of a zero-length string is:\nripemd160( \"\" )\n#=\u003e \"9c1185a5c5e9fc54612808977ee8f548b2258d31\"\n```\n\n(Source: [RIPEMD @ Wikipedia](https://en.wikipedia.org/wiki/RIPEMD))  \n\n\n\n...\n\n\n\nThe \"official\" bitcoin script notation reads:\n\n```\nScriptSig (input): \u003csig\u003e \u003cpubKey\u003e\nScriptPubKey:      OP_DUP OP_HASH160 \u003cpubKeyHash\u003e OP_EQUALVERIFY OP_CHECKSIG\n```\n\nAnd the Ivy higher-level version reads:\n\n```\ncontract LockWithPublicKeyHash(pubKeyHash: Hash160(PublicKey), val: Value) {\n  clause spend(pubKey: PublicKey, sig: Signature) {\n    verify hash160(pubKey) == pubKeyHash\n    verify checkSig(pubKey, sig)\n    unlock val\n  }\n}\n```\n\nthat compiles to\n\n```\nOP_DUP OP_HASH160 \u003cpubKeyHash\u003e OP_EQUALVERIFY OP_CHECKSIG\n```\n\n\n\nTo be continued ...\n\n\n\n\n\n\n\n\n## Appendix\n\nAside - Simplicity - A New Bitcoin Contract Language?\n\n\u003e Simplicity is a blockchain programming language\n\u003e designed as an alternative to Bitcoin script.\n\u003e\n\u003e (Source: [Simplicity README](https://github.com/ElementsProject/simplicity))\n\n\n\u003e Why Simplicity?\n\u003e\n\u003e Bitcoin's Script language is generally limited to combinations\n\u003e of digital signature checks, timelocks, and hashlocks.\n\u003e While impressive protocols (such as the Lightning Network)\n\u003e have been built on these primitives,\n\u003e Bitcoin's Script language lacks the expressiveness needed\n\u003e for more complex contract scripts.\n\u003e\n\u003e (Source: [Simplicity: High-Assurance Bitcoin Contract Scripting](https://blockstream.com/2018/11/28/en-simplicity-github/) by Russell O'Connor, Andrew Poelstra, Blockstream Research, November 2018)\n\n\n\u003e Simplicity: A New Language for Blockchains (Whitepaper Abstract)\n\u003e\n\u003e Simplicity is a typed, combinator-based, functional language without\n\u003e loops and recursion, designed to be used for crypto-currencies\n\u003e and blockchain applications. It aims to improve upon existing crypto-currency languages,\n\u003e such as Bitcoin's Script, Ethereum's Solidity or Michelson's Liquidity,\n\u003e while avoiding some\n\u003e of the problems they face. Simplicity comes with formal denotational\n\u003e semantics defined in Coq, a popular, general purpose software proof assistant.\n\u003e Simplicity also includes operational semantics that are defined\n\u003e with an abstract machine that we call the Bit Machine.\n\u003e The Bit Machine is used as a tool for measuring the computational space and time\n\u003e resources needed to evaluate Simplicity programs. Owing to its Turing\n\u003e incompleteness, Simplicity is amenable to static analysis that can be used\n\u003e to derive upper bounds on the computational resources needed, prior to\n\u003e execution. While Turing incomplete, Simplicity can express any finitary\n\u003e function, which we believe is enough to build useful contracts for\n\u003e blockchain applications.\n\u003e\n\u003e (Source: [Simplicity Whitepaper (PDF)](https://blockstream.com/simplicity.pdf) by Russell O'Connor, Blockstream, December 2017)\n\n\n\n\n## Resources\n\nArticles\n\n- [Bitcoin Script @ Bitcoin Wiki](https://en.bitcoin.it/wiki/Script)\n- [Script - A mini programming language @ Learn Me a Bitcoin](http://learnmeabitcoin.com/glossary/script) by Greg Walker\n- [Opcodes @ Bitcoin Developer Reference](https://bitcoin.org/en/developer-reference#opcodes)\n\nBooks / Series\n\n- [A developer-oriented series about Bitcoin](https://davidederosa.com/basic-blockchain-programming/) by Davide De Rosa\n  - [The Bitcoin Script language (pt. 1)](https://davidederosa.com/basic-blockchain-programming/bitcoin-script-language-part-one/)\n  - [The Bitcoin Script language (pt. 2)](https://davidederosa.com/basic-blockchain-programming/bitcoin-script-language-part-two/)\n  - [Standard scripts](https://davidederosa.com/basic-blockchain-programming/standard-scripts/)\n\n\u003c!-- break --\u003e\n\n- [Programming Bitcoin from Scratch](https://github.com/jimmysong/programmingbitcoin) by Jimmy Song\n  - [Chapter 6 - Script](https://github.com/jimmysong/programmingbitcoin/blob/master/ch06.asciidoc) - How Script Works • Example Operations • Parsing the Script Fields • Combining the Script Fields • Standard Scripts • p2pk • Problems with p2pk • Solving the Problems with p2pkh • Scripts Can Be Arbitrarily Constructed • Conclusion\n  - [Chapter 8 - Pay-to-Script Hash](https://github.com/jimmysong/programmingbitcoin/blob/master/ch08.asciidoc) - Bare Multisig • Coding OP_CHECKMULTISIG • Problems with Bare Multisig • Pay-to-Script-Hash (p2sh) • Coding p2sh • Conclusion\n  - [Chapter 13 - Segregated Witness](https://github.com/jimmysong/programmingbitcoin/blob/master/ch13.asciidoc) - Pay-to-Witness-Pubkey-Hash (p2wpkh) • p2wpkh Transactions • p2sh-p2wpkh • Coding p2wpkh and p2sh-p2wpkh • Pay-to-Witness-Script-Hash (p2wsh) • p2sh-p2wsh • Coding p2wsh and p2sh-p2wsh • Other Improvements • Conclusion\n\n\nTalk Notes\n\n- [Contracts, Contracts, Contracts - Code Your Own (Crypto Blockchain) Contracts w/ Ruby (sruby), Universum \u0026 Co](https://github.com/geraldb/talks/blob/master/contracts.md)\n  - Genesis - Bitcoin Script\n    - Ivy - Higher-Level Bitcoin Script\n    - History Corner - Bitcoin - The World's Worst Database for Everything? - Bitcoin Maximalism in Action\n  - Turing Complete and the Halting Problem\n    - Fees, Fees, Fees - $$$ - There's No Free Lunch\n\nCode \n\n- [Learn Me a Bitcoin - Simple code snippets to help you understand how Bitcoin works](https://github.com/in3rsha/learnmeabitcoin-code) by Greg Walker\n\n\n\n## License\n\n![](https://publicdomainworks.github.io/buttons/zero88x31.png)\n\nThe Programming Bitcoin Script Step-by-Step book / guide\nis dedicated to the public domain.\nUse it as you please with no restrictions whatsoever.\n\n","funding_links":[],"categories":["Blockchain Books"],"sub_categories":["Samples"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenblockchains%2Fprogramming-bitcoin-script","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenblockchains%2Fprogramming-bitcoin-script","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenblockchains%2Fprogramming-bitcoin-script/lists"}