8614371bc6fe40adeac0a133777b30e9e0a6242b31b2e37f2570fe86b81a4607
{
  "bitpost": "article",
  "data": "I've been busy with some new projects recently. Part of that has involved re-writing my Elixir Bitcoin library, [BSV-ex](https://github.com/libitx/bsv-ex). I'll be releasing BSV-ex 2 soOoOn - it's been entirely rewritten from the ground up with many improvements.\n\nOne thing I've spent time on, is thinking about how to define contracts and build transactions in a developer friendly way. I think I've come up with something pretty unique and I'm excited to share it.\n\n## Defining contracts\n\nBSV-ex 2 ships with a `Contract` behaviour module. To implement the behaviour, all we have to do is define a module with  `locking_script/2` and `unlocking_script/2` functions. I'll use a `P2PKH` contract as a simple example.\n\n```elixir\ndefmodule P2PKH do\n  use BSV.Contract\n  \n  def locking_script(ctx, %{address: address}) do\n    ctx\n    |> op_dup\n    |> op_hash160\n    |> push(address.pubkey_hash)\n    |> op_equalverify\n    |> op_checksig\n  end\n\n  def unlocking_script(ctx, %{keypair: keypair}) do\n    ctx\n    |> sig(keypair.privkey)\n    |> push(BSV.PubKey.to_binary(keypair.pubkey))\n  end\nend\n```\n\nThat's pretty easy to follow along and reason about, right? This is just pure Elixir so we can easily add our own helper functions that act as macros for defining more complex but commonly repeated script templates. For example, it would be pretty trivial to define an `op_push_tx()` function we could call in our unlocking scripts.\n\nBSV-ex 2 also comes with a full-featured Bitcoin Script VM, and the `Contract` module allows us to test and simulate our contracts.\n\n```elixir\nkeypair = BSV.KeyPair.new()\nlock_params = %{address: BSV.Address.from_pubkey(keypair.pubkey)}\nunlock_params = %{keypair: keypair}\n\nwith {:ok, vm} <- BSV.Contract.simulate(P2PKH, lock_params, unlock_params) do\n  BSV.VM.valid?(vm)\nend\n# -> true\n```\n\n## Building transactions\n\nAnyone familiar with my JavaScript library [TxForge](https://github.com/libitx/txforge) will recognise the influence here. This is how we build transactions in BSV-ex 2.\n\n```elixir\nutxo = BSV.UTXO.from_params(utxo_params)\n\nbuilder = %BSV.TxBuilder{\n  inputs: [\n    P2PKH.unlock(utxo, %{keypair: keypair})\n  ],\n  outputs: [\n    P2PKH.lock(10000, %{address: address}),\n    OpReturn.lock(0, %{data: [\"hello\", \"world\"]})\n  ]\n}\n\ntx = BSV.TxBuilder.to_tx(builder)\nrawtx = BSV.Tx.to_binary(tx, encoding: :hex)\n```\n\nI hope you like the way this is heading. Elixir remains somewhat under-recognised as a language for Bitcoin development, but I can assure you the tools are there to consider it a top-tier language for Bitcoin and Bitcoin-app development. I hope I can convince a few more of you to try it out.\n\nBSV-ex 2 will be released in the next 7-10 days.",
  "opts": {
    "enc": "0",
    "pub": "1"
  },
  "signatures": {
    "child": {
      "hash": "281bfc4e98092a085aed2d0688924b58e234adad8580b70bbb3bfc24f0487e6f",
      "pubkey": "19a3iT6x2vw9s371FR7m3JSAFtRfVFyEBo",
      "signature": "IKF8w8GBWAmwDyEb6Ef/+a6Gl6u1mD6D0uvPj+eMFqHyVx9LbrDpRAQr6h9IU3qJ+8lZKObIPTRRYrpcA+3JkG8=",
      "timestamp": 1636032283,
      "verified": true
    },
    "parent": {
      "hash": "98da3a90c195466607c079c27f48224c798f77eed417f62badd1702a88972f48",
      "pubkey": "17L6WChSmwEtfHGxnSKDTE5Htzm9tq8isF",
      "signature": "H8zgTuFcvfrUW79GBnsz6FGtbh5P+bc9/HkiUL7aPFrGUu0M9+xbTXQEY8NN/K/9YbM+vhiqZUDVBc+aLHM1AFI=",
      "timestamp": 1636032283,
      "verified": true
    }
  },
  "title": "Creating Bitcoin custom contracts with Elixir",
  "type": "text/markdown"
}
{
  "api_version": "1.3.0",
  "block_hash": "00000000000000000a3d42d87ca443f45387156f79b7ab0ae3e7d6523e54247c",
  "block_height": 712113,
  "confirmations": 1,
  "miner_id": "030d1fe5c1b560efe196ba40540ce9017c20daa9504c4c4cec6184fc702d9f274e",
  "return_result": "success",
  "timestamp": "2021-11-04T13:34:01.7902965Z",
  "tx_second_mempool_expiry": 0,
  "txid": "8614371bc6fe40adeac0a133777b30e9e0a6242b31b2e37f2570fe86b81a4607",
  "verified": true
}