{ "info": { "author": "Louie Lu", "author_email": "git@louie.lu", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "IOTA-Python - A Pure-Python implementation of IOTA node\n=======================================================\n\nThe target of this project is to create a pure Python implementation of\nIOTA node.\n\nCurrent Develop Status\n----------------------\n\n- rocksdb readable\n\nGetting Started\n---------------\n\nDependencies\n~~~~~~~~~~~~\n\n- rocksdb\n\nYou can see the rocksdb install guide from `facebook/rocksdb -\nINSTALL.md `__.\n\nFor Arch Linux user, simply typing:\n\n::\n\n $ yaourt -S rocksdb\n\nRequirements\n~~~~~~~~~~~~\n\n- `python-rocksdb-iota `__\n- `pyota `__\n\nInstallation of IOTA-Python\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n$ pipenv install iotapy\n^^^^^^^^^^^^^^^^^^^^^^^\n\nTo install IOTA-Python, simply run this simple command in your terminal\nof choice:\n\n::\n\n $ pipenv install iotapy\n\nGet the Source Code\n^^^^^^^^^^^^^^^^^^^\n\nIOTA-Python is actively developed on GitHub, where the code is `always\navailable `__.\n\nYou can clone the source code from repository:\n\n::\n\n $ git clone https://github.com/mlouielu/iota-python\n\nOnce you have a copy of source code, you can install the package easily:\n\n::\n\n $ cd iota-python\n $ pip install -r requirements.txt\n $ python setup.py install\n\nTutorials - About RocksDBProvider\n---------------------------------\n\nThis is a tutorial of IOTA-Python to read the database from java IRI,\nand this is what IOTA-Python can do now.\n\nOpen IRI rocksdb\n~~~~~~~~~~~~~~~~\n\nRemember, make sure ``db_path`` and ``db_log_path`` is point to *your*\ndatabase path. At this point, IOTA-Python didn't support writing data\nback to the database (also, it have a lock on it, if you want to write\nit), so ``read_only`` should also be ``True``.\n\n.. code:: python\n\n >>> import iota\n >>> import iotapy\n >>> r = iotapy.storage.providers.rocksdb.RocksDBProvider(\n db_path='/var/db/iota/mainnetdb',\n db_log_path='/var/db/iota/mainnetdb.log',\n read_only=True\n )\n >>> r.init() # Absolute remember to init database\n >>>\n\nAccess IRI rocksdb\n~~~~~~~~~~~~~~~~~~\n\nNow you open the database, you can get the data inside it! IRI using\nrocksdb column family to separate the data stored. For column family\nlist, please visit this `blog\npost `__\n\nNow, we can try to open a transaction, here we got an example\ntransaction hash:\n``GTXDTJVUTVSNHYFPJUOWFKTGQTCMNKZPJDJXSWVQWTXYRDZAVZTX9KFBRIMRQEQLMCMVAUKMZWMHA9999``.\n\nYou can check this tx information at this\n`page `__\n\n.. code:: python\n\n >>> txh = iota.TransactionHash('GTXDTJVUTVSNHYFPJUOWFKTGQTCMNKZPJDJXSWVQWTXYRDZAVZTX9KFBRIMRQEQLMCMVAUKMZWMHA9999')\n >>> column_family = 'transaction'\n >>> tx = r.get(txh, column_family)\n >>> tx.tag\n Tag(b'EXAMPLEPYTHONLIB99999999999')\n >>> tx.bundle_hash\n BundleHash(b'CRNTWYOGTYKPAHYHNESJOKLRFYQQGCXXUZIZQFTCCLSTZODTRBPZWTX9TVHNDNNIWTULV9GFLAPPSTCC9')\n >>> tx.signature_message_fragment\n Fragment(b'RBTC9D9DCDFAEACCWCXCGDEAXCGDEAPCEAHDTCGDHDEAUCFDCDADEAZBMDHDWCCDBD999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999')\n >>> tx.signature_message_fragment.as_string()\n 'Hello! This is a test from Python'\n >>> tx.as_json_compatible()\n {\n 'hash_': ...,\n 'signature_message_fragment': ...,\n 'address': Address(b'9TPHVCFLAZTZSDUWFBLCJOZICJKKPVDMAASWJZNFFBKRDDTEOUJHR9JVGTJNI9IYNVISZVXARWJFKUZWC'),\n 'value': 0,\n 'legacy_tag': ...,\n 'timestamp': 1508993435,\n 'current_index': 0,\n 'last_index': 0,\n 'bundle_hash': ...,\n 'trunk_transaction_hash': ...,\n 'branch_transaction_hash': ...,\n 'tag': Tag(b'EXAMPLEPYTHONLIB99999999999'),\n 'attachment_timestamp': 1508993445508,\n 'attachment_timestamp_lower_bound': 0,\n 'attachment_timestamp_upper_bound': 12,\n 'nonce': Nonce(b'HYNAKUFLKW9UZXXIDJFGUMUDDVX')\n }\n >>>\n\nIf you are using method such as ``RocksDBProvider.get``,\n``RocksDBProvider.latest``, please use the following column family name:\n\n::\n\n address\n approvee\n bundle\n milestone\n state_diff\n tag\n transaction\n transaction_metadata\n\nThe full list of column family name can be found at\n``RocksDBProvider.column_family_names``, but this list is used for low\nlevel database access, it only used at ``RocksDBProvider.db``.\n\n::\n\n b'default'\n b'transaction'\n b'transaction-metadata'\n b'milestone'\n b'stateDiff'\n b'address'\n b'approvee'\n b'bundle'\n b'tag'\n\nExample of ``RocksDBProvider`` methods:\n\n.. code:: python\n\n # Get address' transaction record\n >>> adr = iota.Address('9TPHVCFLAZTZSDUWFBLCJOZICJKKPVDMAASWJZNFFBKRDDTEOUJHR9JVGTJNI9IYNVISZVXARWJFKUZWC')\n >>> r.get(adr,'address')\n \n\n # Get next address (in database)\n >>> r.next(adr, 'address')\n (Address(b'9BPQJPGAMDVKAQ9FDPQSVINPMHSIUUXKYMIZQGPBDGGEUZGLEVFIWUYO9MEIPOYUBYVQGJCFYRWTQENCZ'), )\n\n # Get first milestone\n >>> r.first('milestone')\n (243001, (243001, TransactionHash(b'9PPVIKDMKUDXTYJFF9YNWUPPMOYZTYKRBFGLGDCNNNIMWAMGVJGEHOCOUDYRVYPPSDKDKDQXUBMYA9999')))\n\n # Get latest milestone\n >>> r.latest('milestone')\n (265486, (265486, TransactionHash(b'TFWZVEQZGQGBUBKMFA9YKBVDGBWWMXWCGGYYAGPZKGXWKJQRUNSMXJBSVVGYRJKCS9GNWULQSMAGZ9999')))\n\n # Get next milestone\n >>> key, value = r.first('milestone')\n >>> r.next(key, 'milestone')\n (243002, (243002, TransactionHash(b'XHIOO9EJ9H9ULPJM9MIJSTPHNPIUAAJ9NLYHZLHDBCSECCJVRGDWHTRUEUIQXWVLBYOCBNHFWWWPA9999')))\n\nLow level db access (something you don't need to touch at this moment):\n\n.. code:: python\n\n >>> column_handler = r.db.column_family_handles[b'transaction-metadata']\n >>> txh = iota.TransactionHash('GTXDTJVUTVSNHYFPJUOWFKTGQTCMNKZPJDJXSWVQWTXYRDZAVZTX9KFBRIMRQEQLMCMVAUKMZWMHA9999')\n >>> key = iotapy.storage.converter.from_trits_to_binary(txh.as_trits())\n >>> value = r.db.get(key, column_handler)\n b\"6\\x8d\\xd6\\xb2v\\xf7\\xde9\\xcb\\xab\\x07\\x1f\\xb9\\xfc\\x1e@s\\xcfpU\\xb8\\x17\\xad23Wf\\xd52\\xb5\\xe0\\xc4\\xb7\\xd5\\xb6\\xcb\\xb7\\xc1\\xdb$\\xad%\\xd4\\xa2\\xf3\\xefI'\\xd5\\xa7Y\\xe2\\xa5]G\\x9e\\xb82\\xd7\\x1f&\\x9cR4\\xa7\\x13\\xff\\x00\\x00\\x00!\\x0c;\\xa2\\x1b\\xc6-\\xa0\\xd5\\xbe\\xaa*\\xb1\\x95\\xbcUI\\xb5l\\x89\\xa1\\xe3\\xacn\\x90@\\x10\\xdf\\xf9Un\\xb7\\xb1\\x93\\x9b\\xc7\\x017:o\\xba\\xd8\\xfdq\\xff\\xe2\\x00\\x00\\x00\\xb4T\\xa1\\xa01\\xc0\\xb7\\xd8U\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00Y\\xf1i\\x9b\\xb4T\\xa1\\xa01\\xc0\\xb7\\xd8U\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01_W\\x04\\xae\\x84\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\x00\\x00\\x01\\xff\\xff\\xff\\xff\\x00\\x00\\x00\\x00Y\\xf1i\\xa5\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x03\\xd6\\xe0local\"\n >>>\n\nEXPLOSION! An example of exploring the IRI database!\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. figure:: https://pm1.narvii.com/6258/7f113d43b699f954c3d65df5aa5f397936363099_hq.jpg\n :alt: \n\n*EXPLOSION!*\n\nGlade you are here, now you gain the full access power of the IRI\ndatabase.\n\nWe all know that IOTA is a DAG, that is, theoretically speaking, we can\nstart from a transaction, and go to its parent, and its parent, and its\nparent...and we will finally get to the genesis address / node / block\nwhatever.\n\nHere is a small script that I trying to find this answer:\n\n.. code:: python\n\n import time\n import iota\n import iotapy\n\n\n # Initialize the database\n r = iotapy.storage.providers.rocksdb.RocksDBProvider(\n db_path='/var/db/iota/mainnetdb',\n db_log_path='/var/db/iota/mainnetdb.log',\n read_only=True)\n r.init()\n\n\n # We will start from this transaction\n txh = iota.TransactionHash('UNUK99RCIWLUQ9WMUT9MPQSZCHTUMGN9IWOCOXWMNPICCCQKLLNIIE9UIFGKZLHRI9QAOEQXQJLL99999')\n tx = r.get(txh, 'transaction')\n\n # Stop at here\n EMPTY = iota.TransactionHash('9' * 81)\n\n # Go to find the genesis!\n i = 0\n while True:\n i += 1\n if i % 100 == 0:\n print(txh, time.ctime(tx.timestamp))\n\n # Branch is outside the bundle and trunk is in the bundle\n # So we choose branch at here\n if tx.branch_transaction_hash != EMPTY:\n txh = tx.branch_transaction_hash\n tx = r.get(tx.branch_transaction_hash, 'transaction')\n else:\n # This is the end of the journey\n print(\"\\nProbably the genesis?\")\n print(txh)\n break\n\nIt will run like:\n\n::\n\n NQRZKAE9CDFGJUPOMTHCVPOQE9LENTSHNJYDXCWZJ9IRXKLWTGRIHYZCZWSEIOKQFVBBEBNTXHNBA9999 Thu Oct 26 11:23:31 2017\n KMRPH9BVZVFRCEGDEROQBMZTNOQECYRKIJJ9MWGNOUMWVPLFIJ9PRANLDXSTZCVJGHTXTYCWYGJFZ9999 Thu Oct 26 08:40:52 2017\n JQLXELCKS9QSNWZNHJJICAQMGZRTGFPGNRRNJWTBEPZWKEHLJINXVLPOMMQCMQSOEUZGRHSKBNWEA9999 Thu Oct 26 06:40:31 2017\n IOKLUAGDGKSU9RGHZXCQJIBRTFPCNVCIVG9TQNIGE9DVIYIUDCEVTMPYBZQXHNYLNSNFTXDWNH9BA9999 Thu Oct 26 05:41:28 2017\n AUEDLXAJZPW9URCQZABSRNJGYOOSDG9OFHUMXINMVULHOIVWOBDLSSS9DPNTSXHTDKG9MGKMUESD99999 Thu Oct 26 04:38:37 2017\n DZRYEISPEUXXVQMGBSPVMOFFTWPDYQ9EWVYZUQTNX9NPSEWRGNMSZMY9BOTABSLPCTKMIGWAAIPJA9999 Thu Oct 26 03:45:03 2017\n UPAIBMKZEOTUEHHLEYZEEKZFLDGWHWJ9UZLGLRV9NGZPWSGWY9DPITWSDZPQQZDBOYFJDLJYTDKXZ9999 Thu Oct 26 02:51:53 2017\n MZPRET9XVFBK9LQZLFNN9UGQLLBYAVGAKJGODQIKVZWHPDLZQLOTFMMGEAGSGWGPEYBLJLLJJXOEZ9999 Thu Oct 26 02:08:16 2017\n XPMVSHVFNKYSTKPSHLPHDQCKEGWTERKEHTDRUKIQRE9KDDQVAQHUOQHYOPTRZGIIQHLYGYCPTLAEA9999 Thu Oct 26 01:17:58 2017\n MHDQIXDMBOFHCOMLGNHPSJGNIXIDAQQNW9CJKSXPYIOIITQES99KNYTPNPOQBTVZQXYOKBVEIZB999999 Thu Oct 26 00:37:14 2017\n ...\n GXWKBVNFPFX99PGDCH9EQZMLHITMBFAPDQRNNGNGOOXYXEEYYDDDFWJRDQINOEJFSITMEUY9VMVO99999 Tue Oct 24 06:37:13 2017\n UAPTGGCKCGCPWGVQEKBCPKNQUWOPVRBAFAQYHSDU9AJMVINJFVZSM9URBYUAIHCPKOJRBWSOOSHLZ9999 Tue Oct 24 06:16:17 2017\n FPPJWECLHTF9HGGEMNH9FUIAVYJWDOIOXYFRRJ9S9HENTSESTGJYLYOSNNJGKDOUOGXOWFURNDNEZ9999 Tue Oct 24 05:56:10 2017\n HSDV9SKUYCBWNXFIHKLNAXEVPDTGLSPMTMTXCYISS9M9SPL9DERO9GCQLNWY9KBIHOLPYBCTCYECA9999 Tue Oct 24 05:35:44 2017\n LQPVJDHGQPILXVUPCCZGJMCAQHROJLHQKBILEUDBKQAEHMHEOEK9GMRDWEKVRXRB99TOYQQLTZDGZ9999 Tue Oct 24 05:14:13 2017\n FOCMONRMEOBQEBDOJOQPOOPLRIYCI9PMSJXXNEWAZPBRCDGZTZB9KI9SSMKKFBGBDONMILXWOBEFA9999 Tue Oct 24 04:53:03 2017\n BEFSRMKVEWXXHERTONXCQLOAVQYVRPFFZCQIDGUOLLZCFLTRPRHEVYNAPQFKGJOCDAJYNVUJDQIRZ9999 Tue Oct 24 04:32:48 2017\n QVHPAOWGDFTTLYQERDRNBBNCJJCWTJSDBIKBLDYZOLJ9PWFWFWUXP9DGPKTLRZDFZNLFRYXSZF9O99999 Tue Oct 24 04:12:07 2017\n\n Probably the genesis?\n 9PPVIKDMKUDXTYJFF9YNWUPPMOYZTYKRBFGLGDCNNNIMWAMGVJGEHOCOUDYRVYPPSDKDKDQXUBMYA9999\n\nCheck this transaction on\n`thetangle `__\n\nDocumentation\n-------------\n\n[STRIKEOUT:Source code is your best friend]\n\nDocumentation is still under construct.\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/mlouielu/iota-python", "keywords": "", "license": "", "maintainer": "Louie Lu", "maintainer_email": "git@louie.lu", "name": "iotapy", "package_url": "https://pypi.org/project/iotapy/", "platform": "", "project_url": "https://pypi.org/project/iotapy/", "project_urls": { "Homepage": "https://github.com/mlouielu/iota-python" }, "release_url": "https://pypi.org/project/iotapy/0.1.2/", "requires_dist": [ "pyota (>= 2.0.1)", "python-rocksdb-iota (>= 0.7.2)" ], "requires_python": ">= 3", "summary": "A Pure-Python implementation of IOTA node", "version": "0.1.2" }, "last_serial": 3300565, "releases": { "0.1": [], "0.1.1": [ { "comment_text": "", "digests": { "md5": "baada18af4b3c5b7cf726ee2da9dabab", "sha256": "d07481ea4e7e877afac9d5e29f36f978b18b17b4d696a0cce2559ffb72bf7b92" }, "downloads": -1, "filename": "iotapy-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "baada18af4b3c5b7cf726ee2da9dabab", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">= 3", "size": 27483, "upload_time": "2017-11-02T15:36:43", "url": "https://files.pythonhosted.org/packages/85/4f/5df9f3fc54452999b5c6d893c20c221b112712a5a5edbac4f8cb36d51133/iotapy-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c27440ed36448ef357ab9cfcb2902503", "sha256": "5005f8863e7c278f86b8743ce9c2bf1836df289ee6e99e813fbf61d1487a3ede" }, "downloads": -1, "filename": "iotapy-0.1.1.tar.gz", "has_sig": false, "md5_digest": "c27440ed36448ef357ab9cfcb2902503", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3", "size": 13544, "upload_time": "2017-11-02T15:36:45", "url": "https://files.pythonhosted.org/packages/28/40/313124cf0335a9130198e6fe4525a7b5c06221c354f7fa4ca932b23addc9/iotapy-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "d4275e537d27a7a2520bdf48772a6c32", "sha256": "4bddae98c9084fdd785d0b4ef53c94c47678b351bf12a62411c97e30bd8aacdb" }, "downloads": -1, "filename": "iotapy-0.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d4275e537d27a7a2520bdf48772a6c32", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">= 3", "size": 27483, "upload_time": "2017-11-02T15:39:02", "url": "https://files.pythonhosted.org/packages/52/98/f98083cd2beb2180320abdc72a4b132e003484c02828bd9f025cb905fc07/iotapy-0.1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2d037a31e125a06df65ddc02ee422678", "sha256": "93b62b30491b613b05956a1821f6b2087ecd42e53639a19037ee5ffe60beac2d" }, "downloads": -1, "filename": "iotapy-0.1.2.tar.gz", "has_sig": false, "md5_digest": "2d037a31e125a06df65ddc02ee422678", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3", "size": 13541, "upload_time": "2017-11-02T15:39:05", "url": "https://files.pythonhosted.org/packages/52/1e/65bfa96c22859dd73cd04e0e920dc38e40b35df47131cb46445421859cc1/iotapy-0.1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d4275e537d27a7a2520bdf48772a6c32", "sha256": "4bddae98c9084fdd785d0b4ef53c94c47678b351bf12a62411c97e30bd8aacdb" }, "downloads": -1, "filename": "iotapy-0.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d4275e537d27a7a2520bdf48772a6c32", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">= 3", "size": 27483, "upload_time": "2017-11-02T15:39:02", "url": "https://files.pythonhosted.org/packages/52/98/f98083cd2beb2180320abdc72a4b132e003484c02828bd9f025cb905fc07/iotapy-0.1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2d037a31e125a06df65ddc02ee422678", "sha256": "93b62b30491b613b05956a1821f6b2087ecd42e53639a19037ee5ffe60beac2d" }, "downloads": -1, "filename": "iotapy-0.1.2.tar.gz", "has_sig": false, "md5_digest": "2d037a31e125a06df65ddc02ee422678", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3", "size": 13541, "upload_time": "2017-11-02T15:39:05", "url": "https://files.pythonhosted.org/packages/52/1e/65bfa96c22859dd73cd04e0e920dc38e40b35df47131cb46445421859cc1/iotapy-0.1.2.tar.gz" } ] }