Created
August 30, 2024 10:51
-
-
Save ChypherC0d3/d8e2817a97fe10a1c4e1b15d27e2333a to your computer and use it in GitHub Desktop.
Random_Derivation_ETH_Wallets.ipynb
This file contains 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": { | |
"provenance": [], | |
"authorship_tag": "ABX9TyOLhhYy2cmMonToKhEwfV9v", | |
"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/CY0xZ/d8e2817a97fe10a1c4e1b15d27e2333a/random_derivation_eth_wallets.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "kXRHaexcJj5D", | |
"outputId": "e8cae678-fd85-4e9f-b08d-00a6fb1c1228" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Collecting mnemonic\n", | |
" Downloading mnemonic-0.21-py3-none-any.whl.metadata (3.4 kB)\n", | |
"Collecting bip44\n", | |
" Downloading bip44-0.1.4-py3-none-any.whl.metadata (2.5 kB)\n", | |
"Collecting bip32<4.0,>=3.1 (from bip44)\n", | |
" Downloading bip32-3.4-py3-none-any.whl.metadata (4.6 kB)\n", | |
"Collecting mnemonic\n", | |
" Downloading mnemonic-0.20-py3-none-any.whl.metadata (2.9 kB)\n", | |
"Collecting pycryptodome<4.0.0,>=3.16.0 (from bip44)\n", | |
" Downloading pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.4 kB)\n", | |
"Collecting base58~=2.0 (from bip32<4.0,>=3.1->bip44)\n", | |
" Downloading base58-2.1.1-py3-none-any.whl.metadata (3.1 kB)\n", | |
"Collecting coincurve<19,>=15.0 (from bip32<4.0,>=3.1->bip44)\n", | |
" Downloading coincurve-18.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.8 kB)\n", | |
"Requirement already satisfied: asn1crypto in /usr/local/lib/python3.10/dist-packages (from coincurve<19,>=15.0->bip32<4.0,>=3.1->bip44) (1.5.1)\n", | |
"Requirement already satisfied: cffi>=1.3.0 in /usr/local/lib/python3.10/dist-packages (from coincurve<19,>=15.0->bip32<4.0,>=3.1->bip44) (1.17.0)\n", | |
"Requirement already satisfied: pycparser in /usr/local/lib/python3.10/dist-packages (from cffi>=1.3.0->coincurve<19,>=15.0->bip32<4.0,>=3.1->bip44) (2.22)\n", | |
"Downloading bip44-0.1.4-py3-none-any.whl (5.1 kB)\n", | |
"Downloading mnemonic-0.20-py3-none-any.whl (62 kB)\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m62.0/62.0 kB\u001b[0m \u001b[31m2.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[?25hDownloading bip32-3.4-py3-none-any.whl (10 kB)\n", | |
"Downloading pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB)\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.1/2.1 MB\u001b[0m \u001b[31m20.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[?25hDownloading base58-2.1.1-py3-none-any.whl (5.6 kB)\n", | |
"Downloading coincurve-18.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB)\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.4/1.4 MB\u001b[0m \u001b[31m21.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[?25hInstalling collected packages: pycryptodome, mnemonic, base58, coincurve, bip32, bip44\n", | |
"Successfully installed base58-2.1.1 bip32-3.4 bip44-0.1.4 coincurve-18.0.0 mnemonic-0.20 pycryptodome-3.20.0\n" | |
] | |
} | |
], | |
"source": [ | |
"pip install mnemonic bip44 web3 eth-utils pandas openpyxl" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"######################################################################################################\n", | |
"######################################################################################################\n", | |
"############### How random is the random generation of wallets? ##########################\n", | |
"######################################################################################################\n", | |
"######################################################################################################" | |
], | |
"metadata": { | |
"id": "_nz7oKIH6RTq" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from mnemonic import Mnemonic\n", | |
"from bip44 import Wallet\n", | |
"from eth_utils import to_checksum_address, keccak\n", | |
"\n", | |
"# Function to convert public key to Ethereum address\n", | |
"def public_key_to_eth_address(public_key):\n", | |
" # Ethereum address is the last 20 bytes of the keccak-256 hash of the public key\n", | |
" return to_checksum_address(keccak(public_key[1:])[-20:])\n", | |
"\n", | |
"# Define the mnemonics provided earlier\n", | |
"mnemonics = [\n", | |
" \"border summer salt divorce muscle palm ahead predict mimic enroll west secret\",\n", | |
" \"trouble enforce giant bright trend climb gather mean jungle account window offer\",\n", | |
" \"eagle waste honey local raise mystery rent guard swing clever addict walnut\",\n", | |
" \"cement spawn uphold village thunder envelope cry scatter inquiry voyage recipe manual\",\n", | |
" \"garage rapid carbon broken merge blue sword include execute dove equip trigger\",\n", | |
" \"basic comic puppy aware sound private market elbow galaxy mean dragon floor\",\n", | |
" \"lab bullet lonely lunch achieve hobby genre shrimp title tiger release faculty\",\n", | |
" \"view piano duty goddess owner decline bless cargo output medal torch grid\",\n", | |
" \"clip shift rigid useful hub spatial badge solid guilt modify craft edit\",\n", | |
" \"wreck empty coconut hidden silent alter refuse lottery fatal mystery brave treat\"\n", | |
"]\n", | |
"\n", | |
"# Function to derive addresses from mnemonic\n", | |
"def derive_addresses(mnemonic, num_addresses=10):\n", | |
" wallet = Wallet(mnemonic)\n", | |
" addresses = []\n", | |
" for i in range(num_addresses):\n", | |
" account = wallet.derive_account(\"eth\", account=0, change=0, address_index=i + 1)\n", | |
" public_key = account[1] # Get the public key from the tuple\n", | |
" address = public_key_to_eth_address(public_key)\n", | |
" addresses.append(address)\n", | |
" return addresses\n", | |
"\n", | |
"# Derive addresses for each mnemonic\n", | |
"derived_addresses = {mnemonic: derive_addresses(mnemonic) for mnemonic in mnemonics}\n", | |
"\n", | |
"# Display the derived addresses\n", | |
"for mnemonic, addresses in derived_addresses.items():\n", | |
" print(f\"Mnemonic: {mnemonic}\")\n", | |
" for idx, address in enumerate(addresses):\n", | |
" print(f\" Address {idx + 1}: {address}\")\n", | |
" print(\"\\n\")\n" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "S4C1CpCpJkoB", | |
"outputId": "06f26886-43f2-4010-f148-5c2924aec3da" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Mnemonic: border summer salt divorce muscle palm ahead predict mimic enroll west secret\n", | |
" Address 1: 0xe07a4ed98baf83Ccd17922471Abb9962e0242339\n", | |
" Address 2: 0x0a285873DBE0dBC997549F29E6f60F3671AE1945\n", | |
" Address 3: 0x2D094eb4bb7185c0BeCcfd7cbd190B4aE83D93dc\n", | |
" Address 4: 0x7ECbF7EeCA5b042c9EcD9e6f3ACA61459DD98a80\n", | |
" Address 5: 0xBD7ba6b0A9a1c0ce6A8322473C795749CB1DD955\n", | |
" Address 6: 0x36401f40E384804Ff8D42A786F896945B29BE22F\n", | |
" Address 7: 0xf881EA148E00a9B566C3967D1f5Ca8844E18EE58\n", | |
" Address 8: 0x95fB68Bd8d9b5b3FA9eb39665689D99Ed81C7bfB\n", | |
" Address 9: 0xC06D0Bb04F15b8ccF859bA905fA67A05fe130392\n", | |
" Address 10: 0x5F78bb71EbA3433E3a59bbA1a8ae98c67BdC12D1\n", | |
"\n", | |
"\n", | |
"Mnemonic: trouble enforce giant bright trend climb gather mean jungle account window offer\n", | |
" Address 1: 0x05DC9948942c30c9e6Aa60B9b9CD124444754455\n", | |
" Address 2: 0x8b6AcA4f6633733d3A12C9600ca1ce10686082Af\n", | |
" Address 3: 0x854c710673B0B4067050d41f6b46e0e717d83dC4\n", | |
" Address 4: 0x4FeedcfF19763444D8BAD089afaC659C9cfee6cc\n", | |
" Address 5: 0x307F78970d4fd0AC14c510C67dDbA443563f840b\n", | |
" Address 6: 0xdF661C6fc03CFfaf7f585152B99564c9a0287492\n", | |
" Address 7: 0x5DD81b2B98dfe6b840c112569307f596018C963d\n", | |
" Address 8: 0xf3F952a9a60fA18afdb789716044E027138D8CBa\n", | |
" Address 9: 0xeb571765c0700e041c3A478E8a46B0bb4936Ea79\n", | |
" Address 10: 0xC248D7FB46Ef9e518E16D63e6bf8f1c9A0869eB2\n", | |
"\n", | |
"\n", | |
"Mnemonic: eagle waste honey local raise mystery rent guard swing clever addict walnut\n", | |
" Address 1: 0xAF0a784F1c2f6e5b47098aE0F4775BfD4c08c786\n", | |
" Address 2: 0xB72042C12Edf0BF3BdEF0c300fbDB3f63a7f29A1\n", | |
" Address 3: 0x9e445D270411720139326C673Fd94E3fc169BCf9\n", | |
" Address 4: 0x6559d1F21f1E0E2A60fc11F69323AFc911Ff7144\n", | |
" Address 5: 0x0621094A0E0999Ac0cAF833731Ff4742377cEc76\n", | |
" Address 6: 0xd3080a83A81be48fc684c4277d09e0d584Bb1886\n", | |
" Address 7: 0x625154Ab7DA47eFa2A26Cf9D3F7fC4e0B2e3ee7e\n", | |
" Address 8: 0x17D1843Cc8a81685032d94D92a9dd987Bf1Dd97c\n", | |
" Address 9: 0x8E8C6D22AA3b4c7448E797F97f8F7a12e3FB0bF6\n", | |
" Address 10: 0xa916827626B19D6BD7e2515fA27eC06cf2e12292\n", | |
"\n", | |
"\n", | |
"Mnemonic: cement spawn uphold village thunder envelope cry scatter inquiry voyage recipe manual\n", | |
" Address 1: 0x3AF18f825107B23c9d178b7E2c7A4bD955DbD1fB\n", | |
" Address 2: 0x323b925b2eC338FFeB07EE37947f2bDC1A0b8f11\n", | |
" Address 3: 0xA95C9e89bE32e842907c4c54fab2967a6D25F484\n", | |
" Address 4: 0x2A37Fc59982B588A92d46533eCA16A5C347E32F7\n", | |
" Address 5: 0x2478fc740807e8091E2c883a09487B782D2ED7a6\n", | |
" Address 6: 0x635290d58e30A73DF54610D2281700cA76a5a120\n", | |
" Address 7: 0x1a0f1fEa44260B9740DA21CF42c4E6CE01E915C9\n", | |
" Address 8: 0xb158F812dbdAf1480393eb4617088324b2C28351\n", | |
" Address 9: 0xb0646122094d8eD11802fb90700Aebddd8bc36da\n", | |
" Address 10: 0xc353b843419359764a9dfA0ba0b701A0F1cAF5cc\n", | |
"\n", | |
"\n", | |
"Mnemonic: garage rapid carbon broken merge blue sword include execute dove equip trigger\n", | |
" Address 1: 0x5b1019144653A6EBA786f935C72B19F73b0b581d\n", | |
" Address 2: 0xcCbDf432aD1A8c4C915B1c5D6d21Fc63D994b5a7\n", | |
" Address 3: 0xaCB08BB3c9B91F77C7E72dd0e0D18a1AF18C6EB8\n", | |
" Address 4: 0xD4e4D1ee1f857fDE52977933e3efb28948FcE91D\n", | |
" Address 5: 0x0a36Ab11C8904aF4F88ec824151ff961dF7315Bf\n", | |
" Address 6: 0xe65d787Fb56Fde22170B6c527998673ac2aCbbCd\n", | |
" Address 7: 0xEd54346348d288347a2AaB9EAf2a384d62dB8650\n", | |
" Address 8: 0x23ed7D5c2d5dCf234Fc9D9E058Aaf72f22672b6e\n", | |
" Address 9: 0x523ba137c46c712e8e20F225B514D7C718d7b4d0\n", | |
" Address 10: 0x464490fbafaCae901c92ebBe0d7bC1109B29e8e1\n", | |
"\n", | |
"\n", | |
"Mnemonic: basic comic puppy aware sound private market elbow galaxy mean dragon floor\n", | |
" Address 1: 0xc59E06f0FE3F45EAB800F0B3b0063E6A2DeC4C4F\n", | |
" Address 2: 0x5D37c0ea01042cf8D753F13Abb9c1674f020512F\n", | |
" Address 3: 0x19533EEbE95f522aBDF9A6b1392354C7426264CD\n", | |
" Address 4: 0xf10B59fcea74B3a69040e2BaE87b01a3A904faa6\n", | |
" Address 5: 0x30dC612764AdAC30aE06DF0F63D0e8f801B78FAB\n", | |
" Address 6: 0x3Dc958c2a3E93232F2cCd1270d4c8bFE684427e7\n", | |
" Address 7: 0x63d9aC69710619c340037fc0D1D5170674732411\n", | |
" Address 8: 0x921483Ab2d2a18015a05fb21a9DC48BE1B77D6cb\n", | |
" Address 9: 0x5D4b04405d3b99c7278ef307CD6F51d4452D5181\n", | |
" Address 10: 0x0634044ea49ba82D055d5E699324b7618093aB11\n", | |
"\n", | |
"\n", | |
"Mnemonic: lab bullet lonely lunch achieve hobby genre shrimp title tiger release faculty\n", | |
" Address 1: 0x35B44e7103F99b0ab4D8eAEf39864c413fBAf378\n", | |
" Address 2: 0xA03F78302078E9872aBBf0518221996baB50E889\n", | |
" Address 3: 0x33eB2d2e60268771946913F9F9E6ebaED6179f20\n", | |
" Address 4: 0xc8ec209F1f71884e397635BD82b2aD901A10b6E7\n", | |
" Address 5: 0xaD05BA998A861E19E3c75e78D22c98AF99c16aFA\n", | |
" Address 6: 0x8F9d6fA182Ec0F214ef6894069d98F55Ef7E8fa9\n", | |
" Address 7: 0x7f0f9054EBDeAab5490a9DCa1a1EA2cF880917aB\n", | |
" Address 8: 0xa88228fb2fdE57Ba9A67A16B75A9661eC3A6e08A\n", | |
" Address 9: 0xfBd4fE134973715cbb8e364B6B2b127F0b753b5E\n", | |
" Address 10: 0x0E1523b410C2b7E0B150591E70Cf67833ea1F382\n", | |
"\n", | |
"\n", | |
"Mnemonic: view piano duty goddess owner decline bless cargo output medal torch grid\n", | |
" Address 1: 0x96bc0F5E93cad4C90eB0eB282f62779F248f913B\n", | |
" Address 2: 0x98effea26910ebEA48f7F3e90D8F3eb053a9934c\n", | |
" Address 3: 0xC8b6c1F2A025386E4Da31aFe946D2908913423Da\n", | |
" Address 4: 0x05A53a1dA897e9155957e50CE3365EeC25A3c499\n", | |
" Address 5: 0x99b4f3722BAaF783051154993819993f8314Ad96\n", | |
" Address 6: 0x804dCc9A4424cD283a7D3eE3EF1dB67c6896A112\n", | |
" Address 7: 0x90844aD31d3cab1692e682f9f8001c46abEa7715\n", | |
" Address 8: 0x7aF171Dd7808A747293850accbc47b53015b4279\n", | |
" Address 9: 0x97B2B07Be9c5eFA05Ee82Fe91Ac922a9aFB849De\n", | |
" Address 10: 0x1EE4fb39bf91Ef7438E0e588F7e7162707BB8536\n", | |
"\n", | |
"\n", | |
"Mnemonic: clip shift rigid useful hub spatial badge solid guilt modify craft edit\n", | |
" Address 1: 0x5387221C6B4E739EE9265B472CBfC7eE4D7bD6ED\n", | |
" Address 2: 0x7CB5eB03986350D9ADF24cDfCFcc4B185C713dF3\n", | |
" Address 3: 0xf6c25e514FA4a60Cfc4c22dC58DDA65E119C2E9A\n", | |
" Address 4: 0xbc6C75916a311D6537851eA557ab29f1f3432C40\n", | |
" Address 5: 0x59988B385750CAA1eCc3c2605539Cc2caf8f5cF2\n", | |
" Address 6: 0x3901C4293F9c93ab5cd6166Ea98bF12cd0bb1c76\n", | |
" Address 7: 0x1b5A1B7174C30DC6A765cC1c57031F807a93cfE4\n", | |
" Address 8: 0x7B9c69412c33eECe103CD21EFD399f3770c81d16\n", | |
" Address 9: 0xC45b56c46bDdCC9d5bFbe6c34a30e287dF5B29a1\n", | |
" Address 10: 0xf08a87589E8A8d38149B21Dcc84DdAB83e1D0744\n", | |
"\n", | |
"\n", | |
"Mnemonic: wreck empty coconut hidden silent alter refuse lottery fatal mystery brave treat\n", | |
" Address 1: 0xF029f99B780F0FbA1D345C67Ca2153ae3C129A03\n", | |
" Address 2: 0xe7479eeDbf24f0f7e08723D459A4634ae0F9c241\n", | |
" Address 3: 0xac9e0F383163FA9c1aef50Ad013Ed23C7c8FCC2E\n", | |
" Address 4: 0x64C3a1659c1A3fddBA6deCfFaD49596C9b6499e3\n", | |
" Address 5: 0x9F9DA53D0cd131Ca9caeBdFac2527e61A5421a2b\n", | |
" Address 6: 0xaB1FB5CaCBCa03DDCDd642D253172690f8945663\n", | |
" Address 7: 0x1fa02bA82841E4E0b93B9A043C8182C8a637223e\n", | |
" Address 8: 0x441ad8e3F61Ae54DB3D545baF749A85058dfCbF4\n", | |
" Address 9: 0x7D0c7Ecd3ef5166Abb7E8506D27B8D11afa4620d\n", | |
" Address 10: 0xeDADB17deAB70532Fc693FD5152186326aeFa58e\n", | |
"\n", | |
"\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"pip install" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "SapgJWHJJvy9", | |
"outputId": "6559732b-588b-4289-8f80-49020007c2c3" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Requirement already satisfied: mnemonic in /usr/local/lib/python3.10/dist-packages (0.20)\n", | |
"Requirement already satisfied: bip44 in /usr/local/lib/python3.10/dist-packages (0.1.4)\n", | |
"Requirement already satisfied: eth-utils in /usr/local/lib/python3.10/dist-packages (5.0.0)\n", | |
"Requirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (2.1.4)\n", | |
"Requirement already satisfied: openpyxl in /usr/local/lib/python3.10/dist-packages (3.1.5)\n", | |
"Requirement already satisfied: bip32<4.0,>=3.1 in /usr/local/lib/python3.10/dist-packages (from bip44) (3.4)\n", | |
"Requirement already satisfied: pycryptodome<4.0.0,>=3.16.0 in /usr/local/lib/python3.10/dist-packages (from bip44) (3.20.0)\n", | |
"Requirement already satisfied: eth-hash>=0.3.1 in /usr/local/lib/python3.10/dist-packages (from eth-utils) (0.7.0)\n", | |
"Requirement already satisfied: eth-typing>=5.0.0 in /usr/local/lib/python3.10/dist-packages (from eth-utils) (5.0.0)\n", | |
"Requirement already satisfied: hexbytes>=1.0.0 in /usr/local/lib/python3.10/dist-packages (from eth-utils) (1.2.1)\n", | |
"Requirement already satisfied: cytoolz>=0.10.1 in /usr/local/lib/python3.10/dist-packages (from eth-utils) (0.12.3)\n", | |
"Requirement already satisfied: numpy<2,>=1.22.4 in /usr/local/lib/python3.10/dist-packages (from pandas) (1.26.4)\n", | |
"Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas) (2.8.2)\n", | |
"Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas) (2024.1)\n", | |
"Requirement already satisfied: tzdata>=2022.1 in /usr/local/lib/python3.10/dist-packages (from pandas) (2024.1)\n", | |
"Requirement already satisfied: et-xmlfile in /usr/local/lib/python3.10/dist-packages (from openpyxl) (1.1.0)\n", | |
"Requirement already satisfied: base58~=2.0 in /usr/local/lib/python3.10/dist-packages (from bip32<4.0,>=3.1->bip44) (2.1.1)\n", | |
"Requirement already satisfied: coincurve<19,>=15.0 in /usr/local/lib/python3.10/dist-packages (from bip32<4.0,>=3.1->bip44) (18.0.0)\n", | |
"Requirement already satisfied: toolz>=0.8.0 in /usr/local/lib/python3.10/dist-packages (from cytoolz>=0.10.1->eth-utils) (0.12.1)\n", | |
"Requirement already satisfied: typing-extensions>=4.5.0 in /usr/local/lib/python3.10/dist-packages (from eth-typing>=5.0.0->eth-utils) (4.12.2)\n", | |
"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.2->pandas) (1.16.0)\n", | |
"Requirement already satisfied: asn1crypto in /usr/local/lib/python3.10/dist-packages (from coincurve<19,>=15.0->bip32<4.0,>=3.1->bip44) (1.5.1)\n", | |
"Requirement already satisfied: cffi>=1.3.0 in /usr/local/lib/python3.10/dist-packages (from coincurve<19,>=15.0->bip32<4.0,>=3.1->bip44) (1.17.0)\n", | |
"Requirement already satisfied: pycparser in /usr/local/lib/python3.10/dist-packages (from cffi>=1.3.0->coincurve<19,>=15.0->bip32<4.0,>=3.1->bip44) (2.22)\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from itertools import permutations\n", | |
"from mnemonic import Mnemonic\n", | |
"from bip44 import Wallet\n", | |
"from eth_utils import to_checksum_address, keccak\n", | |
"import pandas as pd\n", | |
"\n", | |
"# Function to convert public key to Ethereum address\n", | |
"def public_key_to_eth_address(public_key):\n", | |
" return to_checksum_address(keccak(public_key[1:])[-20:])\n", | |
"\n", | |
"# Original mnemonic words\n", | |
"mnemonic_words = \"wreck empty coconut hidden silent alter refuse lottery fatal mystery brave treat\".split()\n", | |
"\n", | |
"# Get all possible permutations of the mnemonic words\n", | |
"mnemonic_permutations = list(permutations(mnemonic_words))\n", | |
"\n", | |
"# Function to derive addresses from mnemonic\n", | |
"def derive_addresses(mnemonic, num_addresses=3):\n", | |
" wallet = Wallet(mnemonic)\n", | |
" addresses = []\n", | |
" for i in range(num_addresses):\n", | |
" account = wallet.derive_account(\"eth\", account=0, change=0, address_index=i)\n", | |
" public_key = account[1] # Get the public key from the tuple\n", | |
" address = public_key_to_eth_address(public_key)\n", | |
" addresses.append(address)\n", | |
" return addresses\n", | |
"\n", | |
"# Prepare data for Excel export\n", | |
"data = []\n", | |
"\n", | |
"for permutation in mnemonic_permutations:\n", | |
" mnemonic = \" \".join(permutation)\n", | |
" addresses = derive_addresses(mnemonic)\n", | |
" data.append([mnemonic, *addresses])\n", | |
"\n", | |
"# Create a DataFrame\n", | |
"df = pd.DataFrame(data, columns=[\"Mnemonic\", \"ETH Address 1\", \"ETH Address 2\", \"ETH Address 3\"])\n", | |
"\n", | |
"# Export to Excel\n", | |
"output_path = \"eth_addresses_permutations.xlsx\"\n", | |
"df.to_excel(output_path, index=False)\n", | |
"\n", | |
"print(f\"Excel file has been created: {output_path}\")\n" | |
], | |
"metadata": { | |
"id": "TNW6s_bBMnG_" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from math import factorial\n", | |
"\n", | |
"# Calculate the number of permutations of 12 words\n", | |
"num_words = 12\n", | |
"num_permutations = factorial(num_words)\n", | |
"\n", | |
"num_permutations" | |
], | |
"metadata": { | |
"id": "RXEiTaH0Mx2X" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# Calculate the number of combinations for a 12-word mnemonic phrase from a set of 2048 words\n", | |
"num_words_total = 2048\n", | |
"num_combinations = num_words_total ** 12\n", | |
"\n", | |
"num_combinations" | |
], | |
"metadata": { | |
"id": "4KXzG1FjN4Qh" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"import itertools\n", | |
"import numpy as np\n", | |
"from numba import cuda\n", | |
"from eth_utils import to_checksum_address, keccak\n", | |
"\n", | |
"# Number of words in mnemonic\n", | |
"num_words = 12\n", | |
"\n", | |
"# Hypothetical function to derive addresses on GPU (simplified example)\n", | |
"@cuda.jit\n", | |
"def derive_addresses_on_gpu(permutations, addresses):\n", | |
" idx = cuda.grid(1)\n", | |
" if idx < permutations.shape[0]:\n", | |
" mnemonic = permutations[idx]\n", | |
" # Convert mnemonic to Ethereum address (simplified)\n", | |
" addresses[idx] = keccak(mnemonic.encode('utf-8'))[-20:]\n", | |
"\n", | |
"# Generate permutations (this step is still CPU-bound and needs optimization)\n", | |
"words = [\"wreck\", \"empty\", \"coconut\", \"hidden\", \"silent\", \"alter\", \"refuse\", \"lottery\", \"fatal\", \"mystery\", \"brave\", \"treat\"]\n", | |
"permutations = list(itertools.permutations(words)) # This will still be CPU-bound\n", | |
"\n", | |
"# Convert permutations to numpy array for GPU processing\n", | |
"permutations_np = np.array([' '.join(p) for p in permutations], dtype=np.object)\n", | |
"\n", | |
"# Allocate memory on GPU\n", | |
"addresses_gpu = cuda.device_array(len(permutations_np), dtype=np.object)\n", | |
"\n", | |
"# Launch kernel\n", | |
"threads_per_block = 256\n", | |
"blocks_per_grid = (len(permutations_np) + (threads_per_block - 1)) // threads_per_block\n", | |
"derive_addresses_on_gpu[blocks_per_grid, threads_per_block](permutations_np, addresses_gpu)\n", | |
"\n", | |
"# Copy back results\n", | |
"addresses = addresses_gpu.copy_to_host()\n", | |
"\n", | |
"# Print some of the results\n", | |
"print(addresses[:10])\n" | |
], | |
"metadata": { | |
"id": "zaGA7FvfOYo6" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"import secrets\n", | |
"import numpy as np\n", | |
"import matplotlib.pyplot as plt\n", | |
"from scipy.stats import chisquare\n", | |
"\n", | |
"# Generate a large number of private keys\n", | |
"def generate_private_keys(num_keys=1000000):\n", | |
" keys = []\n", | |
" for _ in range(num_keys):\n", | |
" key = secrets.token_bytes(32) # 32 bytes for a 256-bit private key\n", | |
" keys.append(int.from_bytes(key, byteorder='big'))\n", | |
" return keys\n", | |
"\n", | |
"# Perform a frequency test on the keys\n", | |
"def frequency_test(keys):\n", | |
" bit_counts = [0] * 256\n", | |
" for key in keys:\n", | |
" for i in range(256):\n", | |
" if key & (1 << i):\n", | |
" bit_counts[i] += 1\n", | |
" return bit_counts\n", | |
"\n", | |
"# Generate and analyze private keys\n", | |
"private_keys = generate_private_keys()\n", | |
"bit_counts = frequency_test(private_keys)\n", | |
"\n", | |
"# Plot the results\n", | |
"plt.bar(range(256), bit_counts)\n", | |
"plt.title('Bit Frequency in Private Keys')\n", | |
"plt.xlabel('Bit Position')\n", | |
"plt.ylabel('Frequency')\n", | |
"plt.show()\n", | |
"\n", | |
"# Perform a chi-square test to check uniform distribution\n", | |
"chi2, p = chisquare(bit_counts)\n", | |
"print(f\"Chi-square statistic: {chi2}, p-value: {p}\")\n" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 490 | |
}, | |
"id": "zIVBXRW8OZNt", | |
"outputId": "5a8e0939-7d50-4d90-b54a-a20e5decea9f" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": [ | |
"<Figure size 640x480 with 1 Axes>" | |
], | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAlUAAAHHCAYAAACWQK1nAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABHqUlEQVR4nO3deVyVdf7//+dhO4AKuAGSG7mGG4VJjGkujGjkZDqFZolLlgWTStrkTF+3FstcGzGnRbHUccml1NIUt0rcUEbTctQ0LFnMBRQTEK7fH/04H48gIF4G6ON+u51bnuv9ut7X67zPEZ9d5zoHi2EYhgAAAHBTHMq7AQAAgNsBoQoAAMAEhCoAAAATEKoAAABMQKgCAAAwAaEKAADABIQqAAAAExCqAAAATECoAgAAMAGhCqjALBaLxo8fX95toBQGDhyohg0blncbdsaPHy+LxVLebQB3DEIV8AeKi4uTxWKxu3l7e6tz58768ssvS9x/+/btGj9+vM6fP1+q4w0cOLDQ8Qpu69atu8lHg1tpy5Ytds+Xs7Oz7r77bg0YMEA//vhjebdn8+abb2rVqlWmz9uwYUM98sgjhbZ/8skncnR0VPfu3XX58mXTjwvcDKfybgC4E02cOFH+/v4yDENpaWmKi4vTww8/rNWrV9v9Q/Lbb7/Jyen//ppu375dEyZM0MCBA+Xl5VWqY1mtVn344YeFtrdp0+amHwf+zwcffKD8/HzT533xxRd1//33Kzc3V3v37tX777+vtWvX6sCBA/Lz8yt231dffVWvvPKK6T1d7c0339Rf//pX9erV65YeR5IWLlyogQMHKjQ0VKtWrZKrq+stPyZwIwhVQDno0aOH2rZta7s/ZMgQ+fj46D//+Y9dqDLjHw0nJyc99dRTpa7PyspSlSpVbvq4dxpnZ+dbMm+HDh3017/+VZI0aNAgNW3aVC+++KLmz5+vMWPGFLlPwXPo5ORkF8ors8WLFysyMlJdunTRZ599RqBChcTbf0AF4OXlJTc3t0L/AF59TdX48eM1evRoSZK/v7/tbaETJ06U+bgF19wcOnRITz75pKpXr64HH3zQNr5gwQIFBQXJzc1NNWrUUN++fXXy5MlC87z//vtq1KiR3Nzc1K5dO3399dfq1KmTOnXqZKspeOvz2n4L3ubasmWL3fadO3eqe/fu8vT0lLu7ux566CF9++23RfZ/9OhR29k7T09PDRo0SJcuXSrU54IFC9SuXTu5u7urevXq6tixo7766itJUmRkpGrVqqXc3NxC+3Xr1k3NmjUrdi2vvabqxIkTslgsmjJlim19rFar7r//fu3evbvYuYrTpUsXSdLx48clFf8cXntNVcuWLdW5c+dCc+bn5+uuu+6yhTdJmjJliv70pz+pZs2acnNzU1BQkD799FO7/SwWi7KysjR//nzb63HgwIG28V9++UWDBw+Wj4+PrFarWrRooblz597wY166dKmeeuopderUSZ9//nmhQFXS63TcuHFydnbW6dOnC8397LPPysvLy/ZW4p49exQWFqZatWrJzc1N/v7+Gjx48A33jDsToQooBxkZGfr11191+vRpHTx4UM8//7wuXrxY7Bml3r17q1+/fpKk6dOn65NPPtEnn3yi2rVrl3i8X3/91e6WkZFhN/7444/r0qVLevPNNzV06FBJ0htvvKEBAwaoSZMmmjZtmkaMGKH4+Hh17NjR7pqujz76SM8995x8fX01efJktW/fXn/5y1+KDF+ltWnTJnXs2FGZmZkaN26c3nzzTZ0/f15dunTRrl27CtU/8cQTunDhgiZNmqQnnnhCcXFxmjBhgl3NhAkT9PTTT8vZ2VkTJ07UhAkTVK9ePW3atEmS9PTTT+vMmTNav3693X6pqanatGnTDZ3tu9qiRYv0zjvv6LnnntPrr7+uEydOqHfv3kWGt9I4duyYJKlmzZp224t6Dq8VERGhbdu2KTU11W77N998o1OnTqlv3762bTNnztS9996riRMn6s0335STk5Mef/xxrV271lbzySefyGq1qkOHDrbX43PPPSdJSktL0wMPPKCNGzcqOjpaM2fOVOPGjTVkyBDNmDGj1I93+fLl6t+/vzp27KjVq1fLzc3Nbrw0r9Onn35aV65c0ZIlS+z2zcnJ0aeffqo+ffrI1dVV6enp6tatm06cOKFXXnlF//rXv9S/f3/t2LGj1P3iDmcA+MPMmzfPkFToZrVajbi4uEL1koxx48bZ7r/zzjuGJOP48eOlOl5kZGSRx3vooYcMwzCMcePGGZKMfv362e134sQJw9HR0XjjjTfsth84cMBwcnKybc/JyTG8vb2NwMBAIzs721b3/vvv2x3n6sd+be+bN282JBmbN282DMMw8vPzjSZNmhhhYWFGfn6+re7SpUuGv7+/8ec//9m2raD/wYMH28352GOPGTVr1rTdP3LkiOHg4GA89thjRl5enl1twTHy8vKMunXrGhEREXbj06ZNMywWi/Hjjz8axYmMjDQaNGhgu3/8+HFDklGzZk3j7Nmztu2fffaZIclYvXp1sfMVrMvcuXON06dPG6dOnTLWrl1rNGzY0LBYLMbu3bvt1uDa5/DqsQKHDx82JBn/+te/7OpeeOEFo2rVqsalS5ds267+s2H8/ly3bNnS6NKli932KlWqGJGRkYWOPWTIEKNOnTrGr7/+are9b9++hqenZ6H5r9WgQQPDz8/PcHJyMjp16mRkZWUVqint69QwDCMkJMQIDg62q1uxYoXda2/lypWGJNvaAjeKM1VAOYiNjdWGDRu0YcMGLViwQJ07d9YzzzyjFStWmH4sV1dX27EKblOnTrWrGTZsmN39FStWKD8/X0888YTdGS5fX181adJEmzdvlvT7WyXp6ekaNmyYXFxcbPsPHDhQnp6eZeo3KSlJR44c0ZNPPqkzZ87Yjp2VlaWuXbtq27ZthS4Iv7b/Dh066MyZM8rMzJQkrVq1Svn5+Ro7dqwcHOx/7BW8Pebg4KD+/fvr888/14ULF2zjCxcu1J/+9Cf5+/uX6fFERESoevXqdr1JKvUn+AYPHqzatWvLz89P4eHhtrfbrr4mTyq8BkVp2rSpAgMD7c7Y5OXl6dNPP1XPnj3tzgJd/edz584pIyNDHTp00N69e0s8jmEYWr58uXr27CnDMOxeQ2FhYcrIyCjVPGfPntWVK1dUt27dQmeopNK/TiVpwIAB2rlzp+1Mn/T7c1uvXj099NBDkmT78MeaNWvKfCYRd7bb4wpGoJJp166d3T+K/fr107333qvo6Gg98sgjdgHlZjk6Oio0NLTYmmsDw5EjR2QYhpo0aVJkfcFF2T/99JMkFaor+Ph/WRw5ckTS79c4XU9GRoZdUKlfv77deMHYuXPn5OHhoWPHjsnBwUEBAQHFHnvAgAF6++23tXLlSg0YMECHDx9WYmKi5syZU6bHUlJvpTF27Fh16NBBjo6OqlWrlu65554iLz4vbeiLiIjQP/7xD/3yyy+66667tGXLFqWnpysiIsKubs2aNXr99deVlJSk7Oxs2/bSfO/V6dOndf78eb3//vt6//33i6xJT08vcZ6uXbuqfv36eu+991SjRg3NnDnTbry0r1Pp98c9YsQILVy4UGPHjlVGRobWrFmjkSNH2h7TQw89pD59+mjChAmaPn26OnXqpF69eunJJ5+U1WotsV+AUAVUAA4ODurcubNmzpypI0eOqEWLFn/o8a89C5Cfny+LxaIvv/xSjo6OheqrVq16w8e43j/GeXl5hY4tSe+8844CAwOL3Ofa4xfVo/T7GZMbERAQoKCgIC1YsEADBgzQggUL5OLioieeeOKG5jGzt1atWpUYiqXCz+H1REREaMyYMVq2bJlGjBihpUuXytPTU927d7fVfP311/rLX/6ijh07avbs2apTp46cnZ01b948LVq0qMRjFDyHTz311HXDcevWrUvV76xZs3Tu3Dm9++67ql69ut2X4d7I67R69ep65JFHbKHq008/VXZ2tt21chaLRZ9++ql27Nih1atXa/369Ro8eLCmTp2qHTt2lOl1jzsLoQqoIK5cuSJJunjx4nVr/qhvx27UqJEMw5C/v7+aNm163boGDRpI+v2MQcGn0iQpNzdXx48ft/surIIzNNd+cWnB2a6rjy1JHh4epQoTpdGoUSPl5+fr0KFD1w1qBQYMGKCYmBilpKRo0aJFCg8PtzsrVtn5+/urXbt2WrJkiaKjo7VixQr16tXL7kzM8uXL5erqqvXr19ttnzdvXqH5inpN1q5dW9WqVVNeXt5NP4cODg76+OOPlZGRoQkTJqhGjRp68cUXJZX+dVpgwIABevTRR7V7924tXLhQ9957b5H/A/PAAw/ogQce0BtvvKFFixapf//+Wrx4sZ555pmbeiy4/XFNFVAB5Obm6quvvpKLi4vuueee69YVfH9Uab9Rvax69+4tR0dHTZgwodAZFcMwdObMGUlS27ZtVbt2bc2ZM0c5OTm2mri4uEI9FoSlbdu22bbl5eUVensoKChIjRo10pQpU4oMmEV9LL4kvXr1koODgyZOnFjoeqxrH1+/fv1ksVg0fPhw/fjjj2X+1F9FFhERoR07dmju3Ln69ddfC7315+joKIvFYncW8cSJE0V+c3qVKlUKPdeOjo7q06ePli9fru+++67QPjf6HDo7O+vTTz9V+/btNWLECH3yySeSSv86LdCjRw/VqlVLb7/9trZu3VrouT137lyheQpC+NVvgQLXw5kqoBx8+eWX+uGHHyT9fm3JokWLdOTIEb3yyivy8PC4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AIAJCFUAAAAmIFQBAACYoEyh6scffzS7DwAAgEqtTKGqcePG6ty5sxYsWKDLly+b3RMAAEClU6ZQtXfvXrVu3VoxMTHy9fXVc889p127dpndGwAAQKVRplAVGBiomTNn6tSpU5o7d65SUlL04IMPqmXLlpo2bZpOnz5dqnnee+89tW7dWh4eHvLw8FBISIi+/PJL2/jly5cVFRWlmjVrqmrVqurTp4/S0tLs5khOTlZ4eLjc3d3l7e2t0aNH68qVK3Y1W7Zs0X333Ser1arGjRsrLi6uUC+xsbFq2LChXF1dFRwcXCgklqYXAABw57qpC9WdnJzUu3dvLVu2TG+//baOHj2qUaNGqV69ehowYIBSUlKK3b9u3bp66623lJiYqD179qhLly569NFHdfDgQUnSyJEjtXr1ai1btkxbt27VqVOn1Lt3b9v+eXl5Cg8PV05OjrZv36758+crLi5OY8eOtdUcP35c4eHh6ty5s5KSkjRixAg988wzWr9+va1myZIliomJ0bhx47R37161adNGYWFhSk9Pt9WU1AsAALiz3VSo2rNnj1544QXVqVNH06ZN06hRo3Ts2DFt2LBBp06d0qOPPlrs/j179tTDDz+sJk2aqGnTpnrjjTdUtWpV7dixQxkZGfroo480bdo0denSRUFBQZo3b562b9+uHTt2SJK++uorHTp0SAsWLFBgYKB69Oih1157TbGxscrJyZEkzZkzR/7+/po6daruueceRUdH669//aumT59u62PatGkaOnSoBg0apICAAM2ZM0fu7u6aO3euJJWqFwAAcGcrU6iaNm2aWrVqpT/96U86deqUPv74Y/300096/fXX5e/vrw4dOiguLk579+4t9Zx5eXlavHixsrKyFBISosTEROXm5io0NNRW07x5c9WvX18JCQmSpISEBLVq1Uo+Pj62mrCwMGVmZtrOdiUkJNjNUVBTMEdOTo4SExPtahwcHBQaGmqrKU0vRcnOzlZmZqbdDQAA3J6cyrLTe++9p8GDB2vgwIGqU6dOkTXe3t766KOPSpzrwIEDCgkJ0eXLl1W1alWtXLlSAQEBSkpKkouLi7y8vOzqfXx8lJqaKklKTU21C1QF4wVjxdVkZmbqt99+07lz55SXl1dkzQ8//GCbo6ReijJp0iRNmDChxDUAAACVX5lC1ZEjR0qscXFxUWRkZIl1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2/aIiAitW7fOtOYAAAAqizJdU/XVV19p/fr1qlu3rt32Jk2a6KeffjKlMQAAgMqkTGeqsrKy7M5QFTh79qysVutNNwUAAFDZlClUdejQQR9//LHtvsViUX5+viZPnqzOnTub1hwAAEBlUaa3/yZPnqyuXbtqz549ysnJ0csvv6yDBw/q7Nmz+vbbb83uEQAAoMIr05mqli1b6n//+58efPBBPfroo8rKylLv3r21b98+NWrUyOweAQAAKrwbPlOVm5ur7t27a86cOfrnP/95K3oCAACodG74TJWzs7P2799/K3oBAACotMr09t9TTz2ljz76yOxeAAAAKq0yXah+5coVzZ07Vxs3blRQUFCh3/k3bdo0U5oDAACoLG4oVP34449q2LChvvvuO913332SpP/97392NRaLxbzuAAAAKokbClVNmjRRSkqKNm/eLOn3X0vz7rvvysfH55Y0BwAAUFnc0DVVhmHY3f/yyy+VlZVlakMAAACVUZkuVC9wbcgCAAC4U91QqLJYLIWumeIaKgAAgBu8psowDA0cOND2S5MvX76sYcOGFfr034oVK8zrEAAAoBK4oVAVGRlpd/+pp54ytRkAAIDK6oZC1bx5825VHwAAAJXaTV2oDgAAgN8RqgAAAExQrqFq0qRJuv/++1WtWjV5e3urV69eOnz4sF3N5cuXFRUVpZo1a6pq1arq06eP0tLS7GqSk5MVHh4ud3d3eXt7a/To0bpy5YpdzZYtW3TffffJarWqcePGiouLK9RPbGysGjZsKFdXVwUHB2vXrl033AsAALgzlWuo2rp1q6KiorRjxw5t2LBBubm56tatm90Xio4cOVKrV6/WsmXLtHXrVp06dUq9e/e2jefl5Sk8PFw5OTnavn275s+fr7i4OI0dO9ZWc/z4cYWHh6tz585KSkrSiBEj9Mwzz2j9+vW2miVLligmJkbjxo3T3r171aZNG4WFhSk9Pb3UvQAAgDtXmX6hslnWrVtndz8uLk7e3t5KTExUx44dlZGRoY8++kiLFi1Sly5dJP1+sfw999yjHTt26IEHHtBXX32lQ4cOaePGjfLx8VFgYKBee+01/f3vf9f48ePl4uKiOXPmyN/fX1OnTpUk3XPPPfrmm280ffp0hYWFSfr9l0APHTpUgwYNkiTNmTNHa9eu1dy5c/XKK6+UqhcAAHDnqlDXVGVkZEiSatSoIUlKTExUbm6uQkNDbTXNmzdX/fr1lZCQIElKSEhQq1at7H7/YFhYmDIzM3Xw4EFbzdVzFNQUzJGTk6PExES7GgcHB4WGhtpqStPLtbKzs5WZmWl3AwAAt6cKE6ry8/M1YsQItW/fXi1btpQkpaamysXFRV5eXna1Pj4+Sk1NtdVc+wudC+6XVJOZmanffvtNv/76q/Ly8oqsuXqOknq51qRJk+Tp6Wm71atXr5SrAQAAKpsKE6qioqL03XffafHixeXdimnGjBmjjIwM2+3kyZPl3RIAALhFyvWaqgLR0dFas2aNtm3bprp169q2+/r6KicnR+fPn7c7Q5SWliZfX19bzbWf0iv4RN7VNdd+Si8tLU0eHh5yc3OTo6OjHB0di6y5eo6SermW1Wq1/UofAABweyvXM1WGYSg6OlorV67Upk2b5O/vbzceFBQkZ2dnxcfH27YdPnxYycnJCgkJkSSFhITowIEDdp/S27Bhgzw8PBQQEGCruXqOgpqCOVxcXBQUFGRXk5+fr/j4eFtNaXoBAAB3rnI9UxUVFaVFixbps88+U7Vq1WzXJnl6esrNzU2enp4aMmSIYmJiVKNGDXl4eOhvf/ubQkJCbJ+269atmwICAvT0009r8uTJSk1N1auvvqqoqCjbWaJhw4Zp1qxZevnllzV48GBt2rRJS5cu1dq1a229xMTEKDIyUm3btlW7du00Y8YMZWVl2T4NWJpeAADAnatcQ9V7770nSerUqZPd9nnz5mngwIGSpOnTp8vBwUF9+vRRdna2wsLCNHv2bFuto6Oj1qxZo+eff14hISGqUqWKIiMjNXHiRFuNv7+/1q5dq5EjR2rmzJmqW7euPvzwQ9vXKUhSRESETp8+rbFjxyo1NVWBgYFat26d3cXrJfUCAADuXOUaqgzDKLHG1dVVsbGxio2NvW5NgwYN9MUXXxQ7T6dOnbRv375ia6KjoxUdHX1TvQAAgDtThfn0HwAAQGVGqAIAADABoQoAAMAEhCoAAAATEKoAAABMQKgCAAAwAaEKAADABIQqAAAAExCqAAAATECoAgAAMAGhCgAAwASEKgAAABMQqgAAAExAqAIAADABoQoAAMAEhCoAAAATEKoAAABMQKgCAAAwAaEKAADABIQqAAAAExCqAAAATECoAgAAMAGhCgAAwASEKgAAABMQqgAAAExAqAIAADABoQoAAMAEhCoAAAATEKoAAABMQKgCAAAwAaEKAADABIQqAAAAExCqAAAATECoAgAAMAGhCgAAwASEKgAAABMQqgAAAExAqAIAADABoQoAAMAEhCoAAAATEKoAAABMQKgCAAAwAaEKAADABIQqAAAAExCqAAAATECoAgAAMAGhCgAAwASEKgAAABMQqgAAAExAqAIAADABoQoAAMAEhCoAAAATEKoAAABMQKgCAAAwAaEKAADABIQqAAAAExCqAAAATECoAgAAMAGhCgAAwATlGqq2bdumnj17ys/PTxaLRatWrbIbNwxDY8eOVZ06deTm5qbQ0FAdOXLErubs2bPq37+/PDw85OXlpSFDhujixYt2Nfv371eHDh3k6uqqevXqafLkyYV6WbZsmZo3by5XV1e1atVKX3zxxQ33AgAA7lzlGqqysrLUpk0bxcbGFjk+efJkvfvuu5ozZ4527typKlWqKCwsTJcvX7bV9O/fXwcPHtSGDRu0Zs0abdu2Tc8++6xtPDMzU926dVODBg2UmJiod955R+PHj9f7779vq9m+fbv69eunIUOGaN++ferVq5d69eql77777oZ6AQAAdy6n8jx4jx491KNHjyLHDMPQjBkz9Oqrr+rRRx+VJH388cfy8fHRqlWr1LdvX33//fdat26ddu/erbZt20qS/vWvf+nhhx/WlClT5Ofnp4ULFyonJ0dz586Vi4uLWrRooaSkJE2bNs0WvmbOnKnu3btr9OjRkqTXXntNGzZs0KxZszRnzpxS9QIAAO5sFfaaquPHjys1NVWhoaG2bZ6engoODlZCQoIkKSEhQV5eXrZAJUmhoaFycHDQzp07bTUdO3aUi4uLrSYsLEyHDx/WuXPnbDVXH6egpuA4pekFAADc2cr1TFVxUlNTJUk+Pj522318fGxjqamp8vb2tht3cnJSjRo17Gr8/f0LzVEwVr16daWmppZ4nJJ6KUp2drays7Nt9zMzM4t5xAAAoDKrsGeqbgeTJk2Sp6en7VavXr3ybgkAANwiFTZU+fr6SpLS0tLstqelpdnGfH19lZ6ebjd+5coVnT171q6mqDmuPsb1aq4eL6mXoowZM0YZGRm228mTJ0t41AAAoLKqsKHK399fvr6+io+Pt23LzMzUzp07FRISIkkKCQnR+fPnlZiYaKvZtGmT8vPzFRwcbKvZ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f39/NWrUSNWqVbPbfs899+jbb7+12/btt98qICDAdt/NzU09e/bUu+++qy1btighIUEHDhwo8jjOzs7F9uTh4SE/P78Sjwmg/HFNFYBKKTs7W6mpqZKkc+fOadasWbp48aJ69uxZZH2DBg1ksVi0Zs0aPfzww3Jzc7Ndk3UjRo8erSeeeEL33nuvQkNDtXr1aq1YsUIbN26UJMXFxSkvL0/BwcFyd3fXggUL5ObmpgYNGhQ5X8OGDRUfH6/27dvLarWqevXqRR5z3LhxatSokQIDAzVv3jwlJSVp4cKFN9w/gFuHM1UAKqV169apTp06qlOnjoKDg7V7924tW7ZMnTp1KrL+rrvu0oQJE/TKK6/Ix8dH0dHRZTpur169NHPmTE2ZMkUtWrTQv//9b82bN892XC8vL33wwQdq3769WrdurY0bN2r16tXX/d6pqVOnasOGDapXr57uvffeImtefPFFxcTE6KWXXlKrVq20bt06ff7552rSpEmZHgOAW8NiGIZR3k0AAABUdpypAgAAMAGhCgAAwASEKgAAABMQqgAAAExAqAIAADABoQoAAMAEhCoAAAATEKoAAABMQKgCAAAwAaEKAADABIQqAAAAExCqAAAATPD/Abi0wwPkx9n6AAAAAElFTkSuQmCC\n" | |
}, | |
"metadata": {} | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Chi-square statistic: 126.51910364694623, p-value: 0.9999999999991498\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from web3 import Web3\n", | |
"\n", | |
"# Conectar a un nodo de Ethereum usando Infura\n", | |
"infura_url = 'https://mainnet.infura.io/v3/{\"YOUR INFURA APY KEY}'\n", | |
"web3 = Web3(Web3.HTTPProvider(infura_url))\n", | |
"\n", | |
"# Verificar la conexión\n", | |
"if web3.is_connected():\n", | |
" print(\"Connected to Ethereum\")\n", | |
"else:\n", | |
" print(\"Not connected\")\n", | |
"\n", | |
"# Rango de bloques para extraer datos\n", | |
"start_block = 1000000\n", | |
"end_block = 1010000\n", | |
"\n", | |
"# Extraer claves públicas\n", | |
"public_keys = []\n", | |
"\n", | |
"for block_number in range(start_block, end_block):\n", | |
" block = web3.eth.get_block(block_number, full_transactions=True)\n", | |
" for tx in block.transactions:\n", | |
" try:\n", | |
" # Verificar si la transacción tiene los campos necesarios\n", | |
" if hasattr(tx, 'v') and hasattr(tx, 'r') and hasattr(tx, 's') and hasattr(tx, 'rawTransaction'):\n", | |
" # Intentar recuperar la clave pública\n", | |
" public_key = web3.eth.account.recover_transaction(tx.rawTransaction)\n", | |
" public_keys.append(public_key)\n", | |
" except Exception as e:\n", | |
" print(f\"Error processing transaction {tx.hash}: {str(e)}\")\n", | |
" continue\n", | |
"\n", | |
"# Analizar claves públicas para encontrar agrupamientos\n", | |
"from collections import Counter\n", | |
"\n", | |
"# Contar la frecuencia de cada clave pública\n", | |
"key_counts = Counter(public_keys)\n", | |
"\n", | |
"# Identificar claves repetidas\n", | |
"repeated_keys = [key for key, count in key_counts.items() if count > 1]\n", | |
"\n", | |
"# Mostrar resultados\n", | |
"print(f\"Total number of unique public keys: {len(public_keys)}\")\n", | |
"print(f\"Number of repeated public keys: {len(repeated_keys)}\")\n", | |
"\n", | |
"# Si hay claves repetidas, imprimir algunas de ellas\n", | |
"if repeated_keys:\n", | |
" print(\"Some repeated public keys:\")\n", | |
" for key in repeated_keys[:10]: # Mostrar las primeras 10 claves repetidas\n", | |
" print(key)\n" | |
], | |
"metadata": { | |
"id": "E_1dcvfZP_0i", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "8180b893-682c-4d93-a7e7-f16bdda19552" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Connected to Ethereum\n", | |
"Total number of unique public keys: 0\n", | |
"Number of repeated public keys: 0\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"import numpy as np\n", | |
"from sklearn.model_selection import train_test_split\n", | |
"from sklearn.preprocessing import StandardScaler\n", | |
"\n", | |
"# Assuming public_keys is a list of hexadecimal strings\n", | |
"public_key_values = [int(key, 16) for key in public_keys]\n", | |
"public_key_values = np.array(public_key_values).reshape(-1, 1)\n", | |
"\n", | |
"# Optional: Normalize the data\n", | |
"scaler = StandardScaler()\n", | |
"public_key_values_normalized = scaler.fit_transform(public_key_values)\n", | |
"\n", | |
"# Split the data into training and test sets\n", | |
"X_train, X_test = train_test_split(public_key_values_normalized, test_size=0.2, random_state=42)\n" | |
], | |
"metadata": { | |
"id": "YQrIRe6aQ-aQ" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from sklearn.cluster import KMeans\n", | |
"\n", | |
"# Perform K-Means clustering\n", | |
"kmeans = KMeans(n_clusters=3, random_state=42)\n", | |
"kmeans.fit(X_train)\n", | |
"\n", | |
"# Predict cluster labels for the test set\n", | |
"labels = kmeans.predict(X_test)\n", | |
"\n", | |
"# Visualize the clusters\n", | |
"plt.scatter(X_test, np.zeros_like(X_test), c=labels, cmap='viridis')\n", | |
"plt.title('K-Means Clustering of Public Keys')\n", | |
"plt.xlabel('Normalized Public Key Value')\n", | |
"plt.ylabel('Cluster')\n", | |
"plt.show()\n" | |
], | |
"metadata": { | |
"id": "Db8jlJhBRCfz" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from sklearn.neural_network import MLPClassifier\n", | |
"\n", | |
"# Create a simple neural network\n", | |
"mlp = MLPClassifier(hidden_layer_sizes=(100, 50), max_iter=300, random_state=42)\n", | |
"\n", | |
"# Fit the model\n", | |
"mlp.fit(X_train, labels)\n", | |
"\n", | |
"# Evaluate the model\n", | |
"accuracy = mlp.score(X_test, labels)\n", | |
"print(f\"Model accuracy: {accuracy * 100:.2f}%\")\n" | |
], | |
"metadata": { | |
"id": "7gvgFgHHRFOI" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment