TeachMeBitcoin

Using Bitcoin Core to Test Scripts

From TeachMeBitcoin, the free encyclopedia Reading time: 2 min

4. Using Bitcoin Core to Test Scripts

Setup and Prerequisites

Bitcoin Core provides a powerful RPC interface for script analysis and testing. You'll need a running bitcoind instance (mainnet or regtest). For script testing, regtest mode is ideal because you control block generation and don't need real bitcoin.

Start Bitcoin Core in regtest mode:

bitcoind -regtest -daemon -server -rpcuser=user -rpcpassword=pass

Alias the CLI:

alias bcli="bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass"

Generate initial blocks (required to have spendable coins in regtest):

bcli generatetoaddress 101 $(bcli getnewaddress)

Decoding Raw Transactions

Given a raw transaction hex, decode it to inspect scripts:

bcli decoderawtransaction <raw-tx-hex>

This returns a JSON object including scriptPubKey and scriptSig for each output and input, with both hex and ASM (assembly) representations:

{
  "vout": [{
    "scriptPubKey": {
      "asm": "OP_DUP OP_HASH160 89abcdef...abba OP_EQUALVERIFY OP_CHECKSIG",
      "hex": "76a91489abcdef...abba88ac",
      "type": "pubkeyhash",
      "address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7Divf..."
    }
  }]
}

Testing Script Execution with decodescript

The decodescript RPC decodes a hex-encoded script:

bcli decodescript 76a91489abcdefabbaabbaabbaabbaabbaabbaabbaabba88ac

Output includes the type, required signatures, and associated address. This is useful for verifying that a handcrafted script produces the expected address.

Creating and Broadcasting Test Transactions

Step 1: Create a funded address

ADDR=$(bcli getnewaddress)
bcli generatetoaddress 1 $ADDR

Step 2: Create a raw transaction

UTXO_TXID=$(bcli listunspent | python3 -c "import sys,json; u=json.load(sys.stdin)[0]; print(u['txid'])")
UTXO_VOUT=0

bcli createrawtransaction \
  '[{"txid":"'$UTXO_TXID'","vout":'$UTXO_VOUT'}]' \
  '{"'$ADDR'": 49.9999}'

Step 3: Sign and send

SIGNED=$(bcli signrawtransactionwithwallet <raw-hex>)
bcli sendrawtransaction $(echo $SIGNED | python3 -c "import sys,json; print(json.load(sys.stdin)['hex'])")

Using testmempoolaccept

Before broadcasting, validate a signed transaction without actually sending it:

bcli testmempoolaccept '["<signed-raw-tx-hex>"]'

This returns "allowed": true or false with a reject-reason. This is invaluable for checking custom scripts before committing to a broadcast.

Checking Script Type with getaddressinfo

bcli getaddressinfo <bitcoin-address>

Returns the script type, associated redeem script (if P2SH), witness script (if P2WSH), and more. This helps confirm what kind of scriptPubKey will be generated for a given address.

Pro Tip

When debugging scripts, always start with a high-level disassembly before diving into the stack trace. Tools like bitcoin-cli decodescript are your first line of defense in identifying standard script patterns.

☕ Help support TeachMeBitcoin

TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!