Skip to content

Commit

Permalink
Add op_code pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Cryp Toon committed Oct 9, 2024
1 parent 578b6b7 commit e8b3249
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 deletions.
43 changes: 42 additions & 1 deletion blocksmurfer/main/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
from flask_babel import _
from datetime import timezone
import time
import inspect
import re
import difflib
from config import Config
from blocksmurfer import definitions
from blocksmurfer.main import bp
Expand All @@ -22,9 +25,10 @@
from blocksmurfer.explorer.service import *
from bitcoinlib.keys import HDKey, Signature
from bitcoinlib.transactions import Transaction, Output, TransactionError
from bitcoinlib.scripts import Script, ScriptError
from bitcoinlib.scripts import Script, ScriptError, Stack
from bitcoinlib.encoding import Quantity
from bitcoinlib.wallets import wallet_create_or_open
from bitcoinlib.config.opcodes import opcodeints, opcodenames


@bp.route('/', methods=['GET', 'POST'])
Expand Down Expand Up @@ -514,3 +518,40 @@ def store_data(network): # pragma: no cover
return render_template('explorer/store_data.html', title=_('Store data'),
subtitle=_('Embed data on the %s blockchain' % srv.network.name), form=form,
tx_fee=tx_fee)

@bp.route('/<network>/op_code/<op_code>', methods=['GET'])
def op_code(network, op_code):
if op_code.startswith('op_'):
method_str = op_code.split('_', 1)[1]
if method_str.isnumeric() and int(method_str) >= 0 and int(method_str) <= 16:
method_code = ("# Representation of Bitcoin script number. Value between 0 and 16\n"
"# Numeric value %s\n"
"Stack.op_%s"
% (method_str, method_str))
else:
try:
method_code = inspect.getsource(getattr(Stack, op_code))
except Exception as e:
flash(_('Source code for op_code not found: %s') % e, category='error')
opcodeint = opcodeints[op_code.upper()]
opcodenames_lower = [x[3:].lower() for x in opcodenames.values()]
all_methods = ['op_' + i for i in difflib.get_close_matches('sig', opcodenames_lower, cutoff=0)]
all_methods += ['op_verify', 'op_add', 'op_if']
all_methods = list(set(all_methods))
method_code = ''
return render_template('explorer/op_code.html', title=_('%s opcode' % op_code[3:].upper()),
subtitle=_('%s bitcoin script command' % op_code), network=network,
op_code=op_code,
method_code=method_code, opcodeint=opcodeint, all_methods=all_methods)
else:
flash(_('Unknown op_code'), category='error')
return redirect(url_for('main.index', network=network))

opcodeint = opcodeints[op_code.upper()]
all_methods = re.findall(r'op_\w+', method_code)
all_methods.append(opcodenames.get(opcodeint-1))
all_methods.append(opcodenames.get(opcodeint+1))
all_methods = list(set([m.lower() for m in all_methods if m != 'OP_RESERVED' and m != 'op_as_number']))
return render_template('explorer/op_code.html', title=_('%s opcode' % op_code[3:].upper()),
subtitle=_('%s bitcoin script command' % op_code), network=network, op_code=op_code,
method_code=method_code, opcodeint=opcodeint, all_methods=all_methods)
11 changes: 10 additions & 1 deletion blocksmurfer/templates/explorer/address.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,16 @@ <h2>{{ _('Details') }}</h2>
</tr>
<tr>
<td>Locking Script OP</td>
<td>{{ script }}</td>
<td>
{% for s_item in script.view(blueprint=True, as_list=True) %}
{% if s_item.startswith('OP_') %}
<a href="{{ url_for('main.op_code', network=network, op_code=s_item.lower()) }}">
{{ s_item }}</a>
{% else %}
{{ s_item }}
{% endif %}
{% endfor %}
</td>
</tr>
</table>

Expand Down
42 changes: 42 additions & 0 deletions blocksmurfer/templates/explorer/op_code.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{% extends "base.html" %}

{% block app_content %}
<p>Opcodes are used in Bitcoin Scripts to represent commands or methods. Below you can find the value of the
{{ op_code }} code and an implementation in Python. A bitcoin script works with a stack of items.
The op_code representing a method, usually takes or puts 1 or more items from the top of the stack.</p>

<table class="pure-table blocksmurfer-table-sf" style="width: 250px">
<thead>
<tr>
<td colspan="2">{{ op_code.upper() }}</td>
</tr>
</thead>
<tr>
<td>Integer value</td>
<td>{{ opcodeint }}</td>
</tr>
<tr>
<td>Hex value</td>
<td>0x{{ '%02x' % opcodeint }}</td>
</tr>
</table>

<h3>Python code representation as used Bitcoinlib</h3>
{% if method_code %}
<pre>{{ method_code }}</pre>
{% else %}
<p>No source code found for this method</p>
{% endif %}

{% if all_methods %}
<h3>Links to related method</h3>
<ul>
{% for method in all_methods %}
<li>
<a href="{{ url_for('main.op_code', network=network, op_code=method) }}">{{ method }}</a>
</li>
{% endfor %}
</ul>
{% endif %}

{% endblock %}

0 comments on commit e8b3249

Please sign in to comment.