Last active
May 7, 2022 21:25
-
-
Save bbjubjub2494/e8aa99f84ac42305ff18855dae083e2f to your computer and use it in GitHub Desktop.
Transaction_louis.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"nbformat": 4, | |
"nbformat_minor": 0, | |
"metadata": { | |
"colab": { | |
"name": "Transaction_louis.ipynb", | |
"provenance": [], | |
"toc_visible": true, | |
"collapsed_sections": [], | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3" | |
}, | |
"language_info": { | |
"name": "python" | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/lourkeur/e8aa99f84ac42305ff18855dae083e2f/transaction_louis.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# POPstellar: transaction id example implementation\n", | |
"This is a simple, general-purpose implementation of the transaction hashing algorithm for documentation purposes. The algorithm receives a transaction in JSON representation and outputs a SHA-256 digest of it." | |
], | |
"metadata": { | |
"id": "Jr3iEbQ9f0Tr" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"def collect_strings(obj):\n", | |
" '''retrieve the string representation of every field in obj.\n", | |
"\n", | |
" The resulting fields are ordered following the specification.\n", | |
" '''\n", | |
" if isinstance(obj, str):\n", | |
" yield obj\n", | |
" elif isinstance(obj, int):\n", | |
" # use decimal representation for integers\n", | |
" yield str(obj)\n", | |
" elif isinstance(obj, list):\n", | |
" # recurse into array elements in array order\n", | |
" for e in obj:\n", | |
" yield from collect_strings(e)\n", | |
" elif isinstance(obj, dict):\n", | |
" # recurse into JSON object fields in order of field names\n", | |
" for k, v in sorted(obj.items()):\n", | |
" yield from collect_strings(v)\n", | |
" else:\n", | |
" raise TypeError(f\"do not know how to collect strings from a {type(obj)}\")" | |
], | |
"metadata": { | |
"id": "ZKz-kvIf0tG0" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"import base64, hashlib\n", | |
"\n", | |
"def hash_len(strings):\n", | |
" '''hash a sequence of strings in accordance with the POPstellar protocol spec.\n", | |
"\n", | |
" https://github.com/dedis/popstellar/blob/master/docs/protocol.md\n", | |
" '''\n", | |
" payload = ''.join(f\"{len(s)}{s}\" for s in strings)\n", | |
" return base64.urlsafe_b64encode(hashlib.sha256(payload.encode(\"utf-8\")).digest())" | |
], | |
"metadata": { | |
"id": "ouUhhWXYdI3R" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"def compute_transaction_id(transaction):\n", | |
" return hash_len(collect_strings(transaction))" | |
], | |
"metadata": { | |
"id": "qj9NGGZ700Tz" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "r6zHfxAg0hBh" | |
}, | |
"outputs": [], | |
"source": [ | |
"import json\n", | |
"\n", | |
"example = json.loads(\"\"\"{\n", | |
"\t \"Version\": 1,\n", | |
"\t \"TxIn\": [{\n", | |
"\t\t \"TxOutHash\": \"47DEQpj8HBSa--TImW-5JCeuQeRkm5NMpJWZG3hSuFU=\",\n", | |
"\t\t \"TxOutIndex\": 0,\n", | |
"\t\t \"Script\": {\n", | |
"\t\t\t \"Type\": \"P2PKH\",\n", | |
"\t\t\t \"Pubkey\": \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n", | |
"\t\t\t \"Sig\": \"CAFEBABE\"\n", | |
"\t\t }\n", | |
"\t }],\n", | |
"\t \"TxOut\": [{\n", | |
"\t\t \"Value\": 32,\n", | |
"\t\t \"Script\": {\n", | |
"\t\t\t \"Type\": \"P2PKH\",\n", | |
"\t\t\t \"PubkeyHash\": \"2jmj7l5rSw0yVb-vlWAYkK-YBwk=\"\n", | |
"\t\t }\n", | |
"\t }],\n", | |
"\t \"LockTime\": 0\n", | |
"}\"\"\")\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"list(collect_strings(example))" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "3sDRRNUYd3lJ", | |
"outputId": "2626154b-d046-4178-a7fd-0fee82fca48d" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": [ | |
"['0',\n", | |
" 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',\n", | |
" 'CAFEBABE',\n", | |
" 'P2PKH',\n", | |
" '47DEQpj8HBSa--TImW-5JCeuQeRkm5NMpJWZG3hSuFU=',\n", | |
" '0',\n", | |
" '2jmj7l5rSw0yVb-vlWAYkK-YBwk=',\n", | |
" 'P2PKH',\n", | |
" '32',\n", | |
" '1']" | |
] | |
}, | |
"metadata": {}, | |
"execution_count": 5 | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"assert compute_transaction_id(example) == b'dBGU54vni3deHEebvJC2LcZbm0chV1GrJDGfMlJSLRc='" | |
], | |
"metadata": { | |
"id": "VR5nNYdpd1qD" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"" | |
], | |
"metadata": { | |
"id": "MMDsrEO3eAer" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment