One big difference between regtest and testnet/mainnet is you don't have a fancy blockexplorer to use. But that doesn't mean you sometimes need to check or confirm things on the regtest chain. So in order to do just that I use yet another python3 program to get some basic info on the regtest chain and transactions.
Here's the python3 program I used to create a transaction (conveniently named "info.py"):
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
import sys, simplejson
rpc_connection = AuthServiceProxy("http://%s:%
[email protected]:18444"%("bitcoin", "talk"),timeout = 120)
def get_blockchain_size():
iBlockSize = rpc_connection.getblockcount()
return iBlockSize
def get_block_hash(height):
blockhash = rpc_connection.getblockhash(height)
return blockhash
def get_transactions_in_block(blockhash):
return rpc_connection.getblock(blockhash)['tx']
def get_mempool_transactions():
mempoolTransactions = rpc_connection.getrawmempool()
return mempoolTransactions
def lookup_transaction(txid):
blockfound = -1
regTestChainSize = get_blockchain_size()
for i in range(0, regTestChainSize+1):
blockhash = get_block_hash(i)
for transaction in get_transactions_in_block(blockhash):
if transaction == txid:
blockfound = i
return blockfound
def lookup_mempool_transaction(txid):
found = 0
mempoolTransactions = get_mempool_transactions()
if len(mempoolTransactions) > 0:
for transaction in get_mempool_transactions():
if transaction == txid:
found = 1
return found
def getraw_transaction(txid):
return rpc_connection.getrawtransaction(txid)
def decode_transaction(raw):
parsed = rpc_connection.decoderawtransaction(raw)
formatted_json = simplejson.dumps(parsed, indent=4)
#print(json.loads(parsed, indent=4, sort_keys=False))
return formatted_json
#=============
if __name__ == "__main__":
if len(sys.argv) == 1:
operation = 'chain'
else:
operation = sys.argv[1]
#Show info on the entire chain and mempool. This is the default operation if none is specified.
if operation.lower() == 'chain':
regTestChainSize = get_blockchain_size()
print('The network currently consists out of %s blocks.' % regTestChainSize)
if regTestChainSize < 100:
print('Warning: No transactions can be performed on this chain yet since there are no mature blocks!')
for i in range(0, regTestChainSize+1):
print('---------------------------------')
print('Block height: %s' %i)
blockhash = get_block_hash(i)
print('Block hash : %s' % blockhash)
print('Transactions:')
for transaction in get_transactions_in_block(blockhash):
print(transaction)
print('---------------------------------')
print('')
print('Mempool transactions')
print('---------------------------------')
mempoolTransactions = get_mempool_transactions()
if len(mempoolTransactions) > 0:
for transaction in get_mempool_transactions():
print(transaction)
else:
print('Mempool is empty')
#Show info on blocks containing at least one transaction other than coinbase reward
if operation.lower() == 'blocktrans':
regTestChainSize = get_blockchain_size()
print('Scanning for blocks with at least one transaction other than coinbase reward:')
for i in range(0, regTestChainSize+1):
blockhash = get_block_hash(i)
transInBlock = get_transactions_in_block(blockhash)
if len(transInBlock) > 1:
print('---------------------------------')
print('Block height: %s' %i)
print('Block hash : %s' % blockhash)
print('Transactions:')
for transaction in transInBlock:
print(transaction)
print('---------------------------------')
#Show info on blocks containing at least one transaction other than coinbase reward
if operation.lower() == 'mempool':
print('')
print('Mempool transactions:')
mempoolTransactions = get_mempool_transactions()
if len(mempoolTransactions) > 0:
for transaction in get_mempool_transactions():
print(transaction)
else:
print('Mempool is empty')
#Show info on blocks containing at least one transaction other than coinbase reward
if operation.lower() == 'trans':
try:
txid = sys.argv[2]
except:
sys.exit('Provide txid as search value')
print('Looking up transaction %s' % txid)
mempoolfound = lookup_mempool_transaction(txid)
if mempoolfound == 1:
print('')
print('------------------')
print('Transaction is in the mempool (so unconfirmed)')
print('------------------')
else:
blockfound = lookup_transaction(txid)
if blockfound > -1:
print('')
print('------------------')
print('Transaction is included in block with height %s' % blockfound)
print('------------------')
else:
sys.exit('Transaction was not found in any block or mempool.')
raw_transaction = getraw_transaction(txid)
print('------------------')
print('Raw transaction:')
print(raw_transaction)
print('------------------')
decoded_json = decode_transaction(raw_transaction)
print('')
print('------------------')
print('Decoded transaction:')
print(decoded_json)
print('------------------')
This is the first program that you can run using using a startup parameter to do different things. I'll introduce them one by one:
Running info with the chain argument (or since it's the default without any parameter) will give you general info on the regtest chain including all transaction id's per block and transactions in mempool (if any).
Hint: If you want this info in a text file you could just redirect it, so something like: python3 info.py chain > mychain.text
Especially when you are experimenting with transactions you might get lost which blocks contain your own generated transactions and not only coinbase transactions. So when you use the "blocktrans" parameter you can get a list of all blocks containg more than 1 transaction.
Pretty straightforward, when you use the mempool argument you will get all txid's (if any) currently in the mempool.
python3 info.py trans 817e8bfc4797657d4a0e77389d168aa1018dd087a3c93195525fe0414b65956d
Looking up transaction 817e8bfc4797657d4a0e77389d168aa1018dd087a3c93195525fe0414b65956d
------------------
Transaction is in the mempool (so unconfirmed)
------------------
------------------
Raw transaction:
020000000001011431a62376437bf7228db991c2fdcdf4757750eb8fcbf8e47665841082aaac750000000000ffffffff014094052a010000001976a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac0247304402204d645f8fc2193fee73f835e1987f694e2761f60a6e692b88e340bdcc2c5c4962022058fedeca7be2d22028a6dbac41589bb61e70518a407b48685ec30cf2dbb52c77012102d836add3dce8aeaa481aa2843e6c317654b6cebe36c22f72641ea44a506e245700000000
------------------
------------------
Decoded transaction:
{
"txid": "817e8bfc4797657d4a0e77389d168aa1018dd087a3c93195525fe0414b65956d",
"hash": "22ea77afe16191bc6bba5b02e62de164a2d1c70c0eda65d8e7c055c3f38c8870",
"version": 2,
"size": 194,
"vsize": 113,
"weight": 449,
"locktime": 0,
"vin": [
{
"txid": "75acaa8210846576e4f8cb8feb507775f4cdfdc291b98d22f77b437623a63114",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"txinwitness": [
"304402204d645f8fc2193fee73f835e1987f694e2761f60a6e692b88e340bdcc2c5c4962022058fedeca7be2d22028a6dbac41589bb61e70518a407b48685ec30cf2dbb52c7701",
"02d836add3dce8aeaa481aa2843e6c317654b6cebe36c22f72641ea44a506e2457"
],
"sequence": 4294967295
}
],
"vout": [
{
"value": 49.99976000,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 62e907b15cbf27d5425399ebf6f0fb50ebb88f18 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt"
]
}
}
]
}
------------------
If you want detailed information on a transaction either included in a block or in the mempool you can use the argument trans alongside with the txid. If the transaction is found detailed information will be shown.
I hope this guide has given you a good impression on what regtest is and why it can come in very handy. Especially when you want to experiment with transactions, scripts, and what not this might be a much better starting place then testnet!
Hope you enjoyed this guide and let me know if you have any doubts/concerns/tips, hell maybe even compliments