{ "info": { "author": "David Bolshoy", "author_email": "david.bolshoy@kik.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# ERC20 Token Python SDK \n[![Build Status](https://travis-ci.org/kinfoundation/erc20token-sdk-python.svg)](https://travis-ci.org/kinfoundation/erc20token-sdk-python) [![Coverage Status](https://codecov.io/gh/kinfoundation/erc20token-sdk-python/branch/master/graph/badge.svg?token=dOvV9K8oFe)](https://codecov.io/gh/kinfoundation/erc20token-sdk-python)\n\n## Disclaimer\n\nThe SDK is still in beta. No warranties are given, use on your own discretion.\n\n## Requirements.\n\nMake sure you have Python 2 >=2.7.9.\n\n## Installation \n\n```sh\npip install erc20token\n```\n\n### Installation in Google App Engine Python Standard Environment\n[GAE Python Standard environment](https://cloud.google.com/appengine/docs/standard/) executes Python \napplication code using a pre-loaded Python interpreter in a safe sandboxed environment. The interpreter cannot \nload Python services with C code; it is a \"pure\" Python environment. However, the required\n[web3 package](https://pypi.python.org/pypi/web3/) requires other packages that are natively implemented, namely\n[pysha3](https://pypi.python.org/pypi/pysha3) and [cytoolz](https://pypi.python.org/pypi/cytoolz).\nIn order to overcome this limitation, do the following:\n1. Replace the `sha3.py` installed by pysha3 with the [attached sha3.py](sha3.py.alt).\n2. Replace the installed `cytoolz` package with the `toolz` package.\n\nYou will still not be able to use the functions `monitor_ether_transactions` and `monitor_token_transactions`\nbecause they launch a thread, and GAE Standard applications cannot spawn threads.\n\n\n## Usage\n\n### Initialization\n\nTo initialize the SDK, you need to provide the following parameters:\n- [JSON-RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) endpoint URI of your Ethereum node \n(for example, http://mainnet.infura.io)\n- The address of your token contract\n- The ABI of your token contract as json\n- (optionally) either your private key, or a keyfile+password \n- (optionally) gas price in Gwei\n- (optionally) constant gas limit for your transactions\n\n**NOTE**: if you do not provide a private key or a keyfile, you will NOT be able to use the following functions:\n`get_address`, `get_ether_balance`, `get_token_balance`, `send_ether`, `send_tokens`.\n\n\n```python\nimport erc20token\nimport json\n\n# Init SDK without a private key (for generic blockchain queries)\ntoken_sdk = erc20token.SDK(provider_endpoint_uri='http://localhost:8545', \n contract_address='0x04f72aa40046c5fb3b143aaba3ab64d1a82410a7', \n contract_abi=json.loads(contract_abi))\n\n# Init SDK with a private key\ntoken_sdk = erc20token.SDK(provider_endpoint_uri='http://localhost:8545', \n private_key='a60baaa34ed125af0570a3df7d4cd3e80dd5dc5070680573f8de0ecfc1957575',\n contract_address='0x04f72aa40046c5fb3b143aaba3ab64d1a82410a7', \n contract_abi=json.loads(contract_abi))\n\n# Init SDK with a keyfile\n# First, create a keyfile from my private key\nerc20token.create_keyfile('a60baaa34ed125af0570a3df7d4cd3e80dd5dc5070680573f8de0ecfc1957575', \n 'my password', 'keyfile.json')\n# Then, init SDK with the keyfile\ntoken_sdk = erc20token.SDK(provider_endpoint_uri='http://localhost:8545', \n keyfile='keyfile.json', password='my password',\n contract_address='0x04f72aa40046c5fb3b143aaba3ab64d1a82410a7', \n contract_abi=json.loads(contract_abi))\n\n# Init SDK with custom gas parameters\ntoken_sdk = erc20token.SDK(provider_endpoint_uri='http://localhost:8545', \n private_key='a60baaa34ed125af0570a3df7d4cd3e80dd5dc5070680573f8de0ecfc1957575',\n contract_address='0x04f72aa40046c5fb3b143aaba3ab64d1a82410a7', \n contract_abi=json.loads(contract_abi),\n gas_price=10, gas_limit=50000)\n````\nFor more examples, see the [SDK test file](test/test_sdk.py). The file also contains pre-defined values for testing\nwith testrpc and Ropsten.\n\n\n### Get Wallet Details\n```python\n# Get my public address. The address is derived from the private key the SDK was inited with.\naddress = token_sdk.get_address()\n```\n\n### Get the Number of Issued Tokens\n```python\n# Get total supply of tokens\ntotal_supply = token_sdk.get_token_total_supply()\n```\n\n### Getting Account Balance\n```python\n# Get Ether balance of my account\neth_balance = token_sdk.get_ether_balance()\n\n# Get token balance of my account\ntoken_balance = token_sdk.get_token_balance()\n\n# Get Ether balance of some address\neth_balance = token_sdk.get_address_ether_balance('address')\n\n# Get token balance of some address\ntoken_balance = token_sdk.get_address_token_balance('address')\n```\n\n### Sending Coin\nYou can send Ether or tokens:\n```python\n# Send Ether from my account to some address. The amount is in Ether.\ntx_id = token_sdk.send_ether('address', 10)\n\n# Send tokens from my account to some address. The amount is in tokens.\ntx_id = token_sdk.send_tokens('address', 10)\n```\nIf you do not have enough Ether, `send_ether` will raise an exception.\nHowever, if you do not have enough tokens, `send_tokens` will finish successfully. The transaction will end up as \nFAILED on the blockchain, consuming all your gas.\n\n### Getting Transaction Data\n```python\n# Get transaction status\ntx_status = token_sdk.get_transaction_status(tx_id)\n# Returns one of:\n# erc20token.TransactionStatus.UNKNOWN = 0\n# erc20token.TransactionStatus.PENDING = 1\n# erc20token.TransactionStatus.SUCCESS = 2\n# erc20token.TransactionStatus.FAIL = 3\n\n# Get transaction details\ntx_data = token_sdk.get_transaction_data(tx_id)\n# Returns an erc20token.TransactionData object containing the following fields:\n# from_address - the address this transaction was sent from\n# to_address - the address this transaction was sent to. For token transactions, this is the decoded recipient address.\n# ether_amount - the amount of transferred Ether. 0 for token transactions.\n# token_amount - the amount of transferred tokens. 0 for Ether transactions.\n# status - the transaction status, see above.\n# num_confirmations - the number of confirmations for this transaction:\n# -1 if transaction is not found\n# 0 if transaction is pending\n# >0 if transaction is confirmed\n```\n\n### Transaction Monitoring\n\nYou can monitor Ether and token transactions, either from some address or to some address, or both. Provide a \ncallback to the monitoring function, to be called when the transaction status changes.\nNOTE: PENDING status can be received several times, it means the transaction changes blocks.\n\n```python\n# Setup monitoring callback\ntx_statuses = {}\ndef mycallback(tx_id, status, from_address, to_address, amount):\n tx_statuses[tx_id] = status\n\n# Monitor token transactions from me \ntoken_sdk.monitor_token_transactions(mycallback, from_address=token_sdk.get_address())\n\n# Send tokens\ntx_id = token_sdk.send_tokens('to address', 10)\n\n# In a short while, the transaction enters the pending queue\nfor wait in range(0, 5000):\n if tx_statuses[tx_id] > erc20token.TransactionStatus.UNKNOWN:\n break\n sleep(0.001)\nassert tx_statuses[tx_id] >= erc20token.TransactionStatus.PENDING\n\n# Wait until transaction is confirmed \nfor wait in range(0, 90):\n if tx_statuses[tx_id] > erc20token.TransactionStatus.PENDING:\n break\n sleep(1)\nassert tx_statuses[tx_id] == erc20token.TransactionStatus.SUCCESS\n```\n\n**NOTE**: if you are using a public Ethereum node (for example, http://mainnet.infura.io), it will probably have \nsome of the [JSON-RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) disabled to prevent abuse. Usually, it\nmeans that filter-related calls are blocked, so the SDK functions `monitor_ether_transactions` and \n`monitor_token_transactions` will not work. As a workaround, you can create your own transaction monitor using\nthe function `get_transaction_status` or `get_transaction_data`.\n\n## Limitations\n\n### Ethereum Node\n\nThe SDK requires that some of the features in [JSON-RPC API](https://github.com/ethereum/wiki/wiki/JSON-RPC) \nimplementation of Ethereum node work correctly: specifically handling filters and pending transactions. Due to a very \ndynamic state of development of Ethereum nodes, the support for these features is not yet solid and varies from \nvendor to vendor and from version to version. After some experimentation, we settled on the\n[Parity Ethereum Node](https://www.parity.io/), version **v1.8.3-beta**.\n\nIf you are running several Ethereum nodes behind a load balancer, you should enable \n[connection stickiness](https://stackoverflow.com/questions/10494431/sticky-and-non-sticky-sessions) on the \nload balancer: The SDK keeps a state (running filters) on the node it is using and stickiness ensures that requests \nwill reach the same node. In addition, sending a transaction to one node will not make it immediately visible on \nanother node, so stickiness ensures consistent transaction-state when polling on nodes.\n\n### GAE Standard\n\nAs was mentioned earlier, you will not be able to use the functions `monitor_ether_transactions` and \n`monitor_token_transactions`, because they launch a thread, and GAE Standard applications cannot spawn threads.\n\n### SDK Limitations\n\n1. The SDK only support tokens with 18 decimals, which is the most common number of decimal places. When using tokens\nwith a different number of decimals, you will need to make your own conversions.\n2. The SDK supports only a limited subset of [ERC20 Token Standard](https://theethereum.wiki/w/index.php/ERC20_Token_Standard),\nnamely `totalSupply`, `transfer` and `balanceOf` functions. Additional functionality will be added as needed. \nYour PRs are welcome!\n3. The SDK initialization with keyfile and password is currently supported only in Python 2.7.\n\n## Roadmap\n\n- Use [web3.py v.4](https://github.com/ethereum/web3.py). Currently v.3.16.x is used.\n- Change the license to MIT after removing GPL'ed packages.\n- Add the rest of ERC20 methods if needed.\n- Add support to [ERC223 `transfer` method](https://github.com/ethereum/EIPs/issues/223).\n- Support various token `decimals`.\n- Retrieve contract ABI using [Etherscan Contract API](https://etherscan.io/apis#contracts).\n- Get current USD/BTC/ETH prices using [Coinmarketcap API](https://coinmarketcap.com/api/).\n\n## License\nThe code is currently released under [GPLv2 license](LICENSE) due to some GPL-licensed packages it uses. In the \nfuture, we will make an effort to use a less restrictive license.\n\n## Contributing\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for SDK contributing guidelines. \n\n\n\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/kinfoundation/erc20token-sdk-python", "keywords": "ethereum,erc20,blockchain,cryptocurrency", "license": "GPLv2", "maintainer": "", "maintainer_email": "", "name": "erc20token", "package_url": "https://pypi.org/project/erc20token/", "platform": "", "project_url": "https://pypi.org/project/erc20token/", "project_urls": { "Homepage": "https://github.com/kinfoundation/erc20token-sdk-python" }, "release_url": "https://pypi.org/project/erc20token/0.1.8/", "requires_dist": [ "asn1crypto (>=0.23.0)", "backoff (>=1.4.3)", "certifi (>=2017.11.5)", "cffi (>=1.11.2)", "chardet (>=3.0.4)", "coincurve (>=6.0.0)", "cytoolz (>=0.8.2)", "ethereum (>=2.2.0)", "ethereum-abi-utils (==0.4.4)", "ethereum-keys (==0.1.0a7)", "ethereum-tester (==0.1.0b2)", "ethereum-utils (==0.6.0)", "future (>=0.16.0)", "idna (>=2.6)", "pbkdf2 (>=1.3)", "py (>=1.5.2)", "py-ecc (>=1.4.2)", "pycparser (>=2.18)", "pycryptodome (>=3.4.7)", "pyethash (>=0.1.27)", "pylru (>=1.0.9)", "pysha3 (>=1.0.2)", "PyYAML (>=3.12)", "repoze.lru (>=0.7)", "requests (>=2.18.4)", "rlp (>=0.6.0)", "scrypt (>=0.8.0)", "semantic-version (>=2.6.0)", "toolz (>=0.8.2)", "urllib3 (>=1.22)", "web3 (>=3.16.3)" ], "requires_python": ">=2.7", "summary": "ERC20 token SDK for Python", "version": "0.1.8" }, "last_serial": 3428728, "releases": { "0.1.1": [ { "comment_text": "", "digests": { "md5": "998a35dd1fe6a34b234d10b9553e8218", "sha256": "bc80fde45be0098f2d1d7352a55a06c831a022188a7b5228e157a5f3f3663897" }, "downloads": -1, "filename": "erc20token-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "998a35dd1fe6a34b234d10b9553e8218", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7", "size": 14423, "upload_time": "2017-12-03T15:18:44", "url": "https://files.pythonhosted.org/packages/af/a1/059a641e4f73ed716728beeaada11a5b295413eac91b09a40a1f7c5af78d/erc20token-0.1.1-py2.py3-none-any.whl" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "3b21d50f592577ca081d94470b793c4e", "sha256": "1a297a682220efda420b45c5866d23e179c96c4a7ace88596b6fef39f50f343b" }, "downloads": -1, "filename": "erc20token-0.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3b21d50f592577ca081d94470b793c4e", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7", "size": 15909, "upload_time": "2017-12-04T11:52:45", "url": "https://files.pythonhosted.org/packages/94/c0/7398d539a462da3a4e5b43387df85df1754b3c4e99dfeda6b30a69ee9926/erc20token-0.1.2-py2.py3-none-any.whl" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "154739dd2dd1ce332443fb8e9d44278f", "sha256": "df8b3614dd1ee1002a0ee7a75f186461489845c9fa1a1e5bf7a1a917096b8d46" }, "downloads": -1, "filename": "erc20token-0.1.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "154739dd2dd1ce332443fb8e9d44278f", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7", "size": 16001, "upload_time": "2017-12-05T15:38:10", "url": "https://files.pythonhosted.org/packages/9c/51/a2f1e59d15e61d64b478fe6081cbfeb1fb9a49ddc06c5a1722992f3e1352/erc20token-0.1.3-py2.py3-none-any.whl" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "3dc611b11a7c6680c124c6794ad67389", "sha256": "87121746011ad71a209e5c035a0023510bb941f00c758f8417b686202a30b2f0" }, "downloads": -1, "filename": "erc20token-0.1.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3dc611b11a7c6680c124c6794ad67389", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7", "size": 15919, "upload_time": "2017-12-06T12:06:34", "url": "https://files.pythonhosted.org/packages/b3/48/470dc22ac11db0a78c1421c4a2c03caa60be32704b737d58259e22ab99e3/erc20token-0.1.4-py2.py3-none-any.whl" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "3d7e692b3c8ab3bf5d8826e8cbbfc19e", "sha256": "eec50b1309934c40d3d7ee59f497c0394ea1205ac0767360efff0499bb97187f" }, "downloads": -1, "filename": "erc20token-0.1.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3d7e692b3c8ab3bf5d8826e8cbbfc19e", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7", "size": 18047, "upload_time": "2017-12-13T16:38:48", "url": "https://files.pythonhosted.org/packages/1c/1e/3248dea0c0dc9e62fe7d56e254edd1899ac4c1db3d6deadc7f1ff878a454/erc20token-0.1.5-py2.py3-none-any.whl" } ], "0.1.6": [ { "comment_text": "", "digests": { "md5": "3c73cec70e98d89bd6d327c2903e9005", "sha256": "ce6f73385bbaad7df8b3e18cc455ffb05c2feeda4d0963602c985a871964eef6" }, "downloads": -1, "filename": "erc20token-0.1.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3c73cec70e98d89bd6d327c2903e9005", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7", "size": 18361, "upload_time": "2017-12-14T10:54:01", "url": "https://files.pythonhosted.org/packages/c6/0c/82043481d818a728045731525ba74a4a5e1371ea0ebff3e935640f58f2c2/erc20token-0.1.6-py2.py3-none-any.whl" } ], "0.1.7": [ { "comment_text": "", "digests": { "md5": "0a4d78e01295abd2841ad6d00547535e", "sha256": "0206a9c35b6cdb6e61f17c3db81b3b42e125627e1494f64a44755eec5eb90a9d" }, "downloads": -1, "filename": "erc20token-0.1.7-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0a4d78e01295abd2841ad6d00547535e", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7", "size": 18446, "upload_time": "2017-12-14T14:23:45", "url": "https://files.pythonhosted.org/packages/c5/f2/8b1181f5be7dbe5f202b2d11177af5db617fb3994c2724379317ad987bb2/erc20token-0.1.7-py2.py3-none-any.whl" } ], "0.1.8": [ { "comment_text": "", "digests": { "md5": "3a18a6146f0c069dcbd4ee0be99f700b", "sha256": "67e2ff167a28248549907e19add77d64efa00babb9d0ffffbe99c28462ad71c9" }, "downloads": -1, "filename": "erc20token-0.1.8-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3a18a6146f0c069dcbd4ee0be99f700b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7", "size": 19027, "upload_time": "2017-12-19T15:42:34", "url": "https://files.pythonhosted.org/packages/37/ff/aa8864cfa497cf625df87e933d90b6e7e3e37d23de92f4ce4bb785d0318d/erc20token-0.1.8-py2.py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3a18a6146f0c069dcbd4ee0be99f700b", "sha256": "67e2ff167a28248549907e19add77d64efa00babb9d0ffffbe99c28462ad71c9" }, "downloads": -1, "filename": "erc20token-0.1.8-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3a18a6146f0c069dcbd4ee0be99f700b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7", "size": 19027, "upload_time": "2017-12-19T15:42:34", "url": "https://files.pythonhosted.org/packages/37/ff/aa8864cfa497cf625df87e933d90b6e7e3e37d23de92f4ce4bb785d0318d/erc20token-0.1.8-py2.py3-none-any.whl" } ] }