├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── request-for-help.md ├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── LICENSE ├── Makefile ├── Pipfile ├── README.md ├── ontology ├── __init__.py ├── account │ ├── __init__.py │ └── account.py ├── claim │ ├── __init__.py │ ├── claim.py │ ├── header.py │ ├── payload.py │ └── proof.py ├── common │ ├── __init__.py │ ├── address.py │ ├── define.py │ └── wallet_qr.py ├── contract │ ├── __init__.py │ ├── native │ │ ├── __init__.py │ │ ├── aio_asset.py │ │ ├── aio_ong.py │ │ ├── aio_ont.py │ │ ├── aio_ontid.py │ │ ├── asset.py │ │ ├── ong.py │ │ ├── ont.py │ │ ├── ontid.py │ │ └── vm.py │ ├── neo │ │ ├── __init__.py │ │ ├── abi │ │ │ ├── __init__.py │ │ │ ├── abi_event.py │ │ │ ├── abi_function.py │ │ │ ├── abi_info.py │ │ │ ├── parameter.py │ │ │ └── struct_type.py │ │ ├── aio_oep4.py │ │ ├── claim_record.py │ │ ├── invoke_function.py │ │ ├── oep.py │ │ ├── oep4.py │ │ ├── oep5.py │ │ ├── params_builder.py │ │ └── vm.py │ └── wasm │ │ ├── __init__.py │ │ ├── invoke_function.py │ │ ├── params_builder.py │ │ └── vm.py ├── core │ ├── __init__.py │ ├── base_invoke_func.py │ ├── base_params_builder.py │ ├── deploy_transaction.py │ ├── invoke_transaction.py │ ├── program.py │ ├── program_info.py │ ├── sig.py │ └── transaction.py ├── crypto │ ├── __init__.py │ ├── aes_handler.py │ ├── curve.py │ ├── digest.py │ ├── ecies.py │ ├── hd_key.py │ ├── hd_private_key.py │ ├── hd_public_key.py │ ├── kdf.py │ ├── key_type.py │ ├── mnemonic.py │ ├── scrypt.py │ ├── signature.py │ ├── signature_handler.py │ └── signature_scheme.py ├── exception │ ├── __init__.py │ ├── error_code.py │ └── exception.py ├── io │ ├── __init__.py │ ├── binary_reader.py │ ├── binary_writer.py │ └── memory_stream.py ├── merkle │ ├── __init__.py │ ├── merkle_verifier.py │ └── tx_verifier.py ├── network │ ├── __init__.py │ ├── aiorestful.py │ ├── aiorpc.py │ ├── restful.py │ ├── rpc.py │ └── websocket.py ├── sdk.py ├── service │ ├── __init__.py │ └── service.py ├── sigsvr │ ├── __init__.py │ └── sigsvr.py ├── utils │ ├── __init__.py │ ├── arguments.py │ ├── crypto.py │ ├── event.py │ ├── neo.py │ ├── transaction.py │ ├── utils.py │ └── wasm.py ├── vm │ ├── __init__.py │ ├── build_params.py │ ├── build_vm.py │ ├── op_code.py │ └── vm_type.py └── wallet │ ├── __init__.py │ ├── account.py │ ├── account_info.py │ ├── control.py │ ├── identity.py │ ├── wallet.py │ └── wallet_manager.py ├── requirements.txt ├── setup.py └── tests ├── __init__.py ├── cyano_wallet.json ├── test_abi_info.py ├── test_account.py ├── test_address.py ├── test_aes_handler.py ├── test_aio_oep4.py ├── test_aio_ong.py ├── test_aio_ont.py ├── test_aio_ontid.py ├── test_aio_restful.py ├── test_aio_rpc.py ├── test_binary_reader.py ├── test_binary_writer.py ├── test_claim.py ├── test_claim_record.py ├── test_contract_data_parser.py ├── test_curve.py ├── test_digest.py ├── test_ecies.py ├── test_error_code.py ├── test_exception.py ├── test_hd_wallet.py ├── test_invoke_function.py ├── test_key_type.py ├── test_merkle_verifier.py ├── test_native_vm.py ├── test_neo_vm.py ├── test_oep4.py ├── test_oep5.py ├── test_ong.py ├── test_ont.py ├── test_ontid.py ├── test_ontology_sdk.py ├── test_program_builder.py ├── test_restful.py ├── test_rpc.py ├── test_scrypt.py ├── test_signature_handler.py ├── test_signature_scheme.py ├── test_sigsvr.py ├── test_transaction.py ├── test_tx_verifier.py ├── test_utils.py ├── test_vm_type.py ├── test_wallet.json ├── test_wallet_data.py ├── test_wallet_manager.py ├── test_wasm_params_builder.py ├── test_wasm_utils.py ├── test_wasm_vm.py ├── test_websocket.py ├── wallet.json └── wasm ├── api.wasm ├── basic_test_case.wasm ├── hello_world.wasm ├── oep4.wasm ├── oep5.wasm ├── oep8.wasm └── red_envlope.wasm /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: NashMiao 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | 12 | A clear and concise description of what the bug is. 13 | 14 | **Expected Result** 15 | 16 | A clear and concise description of what you expected to happen. 17 | 18 | **Actual Result** 19 | 20 | What happened instead. 21 | 22 | **Screenshots** 23 | 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Reproduction Steps** 27 | 28 | ```python 29 | 30 | ``` 31 | 32 | **Version Information (please complete the following information):** 33 | 34 | - python version: [e.g. Python 3.7] 35 | - ontology-python-sdk version: [e.g. v2.0.0] 36 | 37 | **Additional context** 38 | 39 | Add any other context about the problem here. 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: NashMiao 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/request-for-help.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Request for Help 3 | about: Guidance on using ontology-python-sdk 4 | title: '' 5 | labels: Documentation 6 | assignees: NashMiao 7 | 8 | --- 9 | 10 | Please refer to our [API documentation](https://nashmiao.github.io/ontology-python-sdk-docs/#introduction) for guidance firstly. If this can't handle your issue, then create this issue. 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | venv-*/ 90 | *-venv/ 91 | ENV/ 92 | env.bak/ 93 | venv.bak/ 94 | 95 | # Spyder project settings 96 | .spyderproject 97 | .spyproject 98 | 99 | # Rope project settings 100 | .ropeproject 101 | 102 | # mkdocs documentation 103 | /site 104 | 105 | # mypy 106 | .mypy_cache/ 107 | 108 | dist 109 | build 110 | ontology_dapp_box.egg-info 111 | .idea 112 | .vscode 113 | 114 | *.dat 115 | *.json 116 | coverage.xml 117 | coverage/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: true 2 | dist: xenial 3 | language: python 4 | python: 5 | - '3.6' 6 | - 3.6-dev 7 | - '3.7' 8 | - 3.7-dev 9 | cache: pip 10 | env: 11 | global: 12 | - secure: hmihvVrUjcBdEYRF79/XXACDShn2kvkmcKzQgSo6M1UAbvnl+26WUiKiGc4nlgDJfY6WaEN8UasArWWvxN3rzpRygSPhmMjcV3aZsBhKuRgMy2spEM7K3Z4/VTVOqndo+MDjC1ke/vdSqlDnpc6yFWZK3Tci4gx0CAyyu0+MgPaysxfxOVuuyEZzj/3V6fPKKrVjJnJ042giMSuSW3IjZeZf5Yqo0NI+UGrrPU/pniyiaXS8OAL1MML7o+0iiGORJrcBfBAhAS67GrPhVR6EOFXWu03tZEl3MXTPRZ2WR6m+64ZOO+UKiW5lxAg1MTCbcJCvJsmbYD2RThRfH6/r0/nRbNiz5x2T+GAKgbFwL0wNZjaWAKiQzPVXMvEed9NlY7/YzqrPx8Q581DdCirx2jX4SgD4/rSiRZcbjEwfXTB9vQBO7DJwPAP5IAtBkpQr8tDZ12mtA7asPm5+8V2eqlwpuro/dYARAziKM821s+22GExyFpbHPpjrkWeYD7HMwXC+MPUFTJvLdZzQ38gjeMliK2+O89AzeKpfudJCt0J85aXSMqXH2LJ4iAdoHcm4t6L3wRjyns1R4i2NKop/MbA7pctUevDkrsh5+Pm5vmbZUcw4LB3PQZ1r/mDJJoq/ilPORnMCv65PmsYEKCd/vIuaEE/Z/4iB7qOnvSUkWqY= 13 | - secure: IV7CV9UrJa2cv1HlecgZljFcQ18Wo9jGN7X65vuhtFwtvfjreqKGQ/LRCXAIyOHziaoHy3CjhFUcdnAn5ihmbT5Wj4GeEnNmk+75df886UnoAikiXwJNcyRnS8jPu6JCHiF64kjsRpvpIcuWJaD+Qbnn/YSQFN5UMLvmQBsn0RsoWzisl2AP5dPqggB9TrLZSdmvbRuPmlox3GCZQpVvHwYYdmhlBfkevSFHI4aGjb8NPp3YmnW0cclhZwHnLz5wOce6H5LN91QTveiB9wq1vWluWCxxarfM9MbpuUC1Hs3c19Q78MiM7WRFmHuO9Fk2E233hORujhvhV6Z2R30p5r2t7kPOfeElwg73NQsCC6x0stvpZSJmneKIcbQdJoRqHWIyNHsLylHSrF+IsSGsAKiYFWb5caXUaVGZMiJbfC1URPheNZVtc93UXAWCqzKTSa6+hccJjEwLrxmZxzbKBoFUNoVZi7lt4rU5tAA9amUmgNjFcIivZjjsxVIR8Bh9f+sb4IGypi59HBTZVnS1Zu0ufKB/m+9y0dAXNLzzFFMfzX56w71e++DuCThJPeKf4duhJzeeoiusyXNYfN1f048+sjG1g5HLVPqfP2ITSQ428CkvQKwE6G0haCYk+qfmI+X0ugpsBR8w48Vardh2lc6fvMV/f0y3gfURKMN5BMk= 14 | - secure: Xvsl5k7IRZ5KOtVBjdFITxvZqxNIB8lx/UVoTYCLXOkY28Ql+9Igi9JV6UTTTQZpiPemhEEiLGrJyc+N3J/pFrI2ftdyK/gwdb6s1cwuuVAWe/cthrUyKPpEtnYusBfnFJyNCtm5x0BL/B1DARBRAUBO4dsnTJ4mwzAWiMpn4xQsYiZaLxhnY73hWRXHBd9xZbCH3ujU7PuaGzHWkClJPaWuVZD+FT/JYdLgAICY+tXSb/gHkFimwCMHHOhzA3M7vtpUUQwF1W81RY3cvyAFOZskDehP13ZDe74EVTn+MTckj4AUq/QpSXelTs1QstZtRP5O3atWVZ9kbLwnV5Hrn22ndu5o+Z8y4ZlsrFoMdymBU1D8uVuhHVEDZesnxl90ulpDCav/e668KNLOmnvxiY6k4FdfsyyS2Of1WmD+/3AxBpL8Hnhp1irMQyZvs2JRH+tTYTlM4iFo32uNPM5ZsI0fFCF8RPjx2bxGzkO+b4FvxhhMmgGEUUcW4bOiOzD4a3nAG3RZzb2+5Qn9r7sFGUb2Yv4LN6ukFWw3bYR09CuiKR+mwmsBa5akBrOZ+cSn1cXexFF8mobRpCGM/P93IvsbzVp7/pHH4g0vM1w1U7H+0MU83SbDW0YUzgoXPTcCCl3ErJXtwtgqcMgLL3Uph8czSbExXMvVsHfzTup+UDk= 15 | install: 16 | - pip install -r requirements.txt 17 | - sudo apt-get install build-essential 18 | - sudo apt install wget 19 | - sudo apt install unzip 20 | - wget https://github.com/ontio/ontology/releases/download/v1.6.0/tool-linux.zip --no-check-certificate 21 | - unzip tool-linux.zip 22 | - "./tool-linux/sigsvr-linux-amd64 --abi ./tool-linux/abi &" 23 | script: 24 | - make ci-coverage 25 | - make ci-build 26 | deploy: 27 | provider: pypi 28 | user: NashMiao 29 | password: 30 | secure: kI22zgh0F7CZr1CMjB33BTIqfpRQBxdIsTchxdR3Ooq0LBCwp7RKL5F7Ijdc0SuK7pYsZT3t5UUBiltJLvjw+bxVegcqSHXvzN+LibEJZMagM2RujBADbNgai1xBUkcjfoDtiEKvPoJh8CQndjfOQgAQ6O97Y2o0kBS7ryLsHX+2ytUKhS/GSOSLw1sdlH3PIxCinzruLrMecgZgkUDxe6Co6N+l3IUklaOeqcANv9SobWAuNWS6ZdKD8e4gWZrmgxSVb/+CXnk0OfR2JB+w28xMSXrTS4hNdw+OVtefnuSmgKRCfJu2tiYXRG7aUQPHWnBnFZNdwjgK2puYdHUIDUsQ6wI1k4FrOIP3DDZPQ1RMCPI59l+lr9FG7wWjD/wKmtneYlT8VMz7GWKLDJjyeZwdWAt3kYeALQOG0a2eWwlf9yKcc4x+cKI6pOb9IkO8t4Uy0mwova/ztWeHhXbptL2othYDvlnfB9pIiDZYQUdHrdd3r9y9vK0BoE2xJ/f9xRfN1QCx0cJZpq797POHlL3NQgXKX3yRL8aYwYuHWWdjleZjajFRzyY2cfzKDgZGgSOKwAGzKHVJQhY4eX25tX9onl/37xua3glmQONHObRgqHRBgIgALy527LgxGD5j0gLhatC8A+IBtg8PUG8tlxaMEi5tPbQpO5/bGJlCEc4= 31 | on: 32 | python: 3.7 33 | brance: master 34 | tags: true 35 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at contact@ont.io. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build 2 | 3 | install: 4 | pip install --user pipenv 5 | pipenv install 6 | pipenv shell 7 | 8 | install-mirror: 9 | pip3 install --user pipenv 10 | pipenv install --pypi-mirror https://mirrors.aliyun.com/pypi/simple 11 | pipenv shell 12 | 13 | test: 14 | pipenv shell 15 | python -m unittest discover 16 | 17 | ci-test: 18 | python -m unittest discover 19 | 20 | coverage: 21 | pipenv shell 22 | pipenv install codacy-coverage --dev 23 | pipenv install coverage --dev 24 | coverage run -m unittest discover 25 | coverage xml --include=ontology/* --omit=tests/* 26 | python-codacy-coverage -r coverage.xml 27 | 28 | ci-coverage: 29 | pip3 install codacy-coverage 30 | pip3 install coverage 31 | coverage run -m unittest discover 32 | coverage xml --include=ontology/* --omit=tests/* 33 | python-codacy-coverage -r coverage.xml 34 | 35 | build: 36 | python3 -m pip install -U twine wheel setuptools -i https://mirrors.aliyun.com/pypi/simple 37 | python3 setup.py bdist_wheel --python-tag py3 38 | 39 | ci-build: 40 | pip3 install wheel 41 | python3 setup.py bdist_wheel --python-tag py3 42 | 43 | publish: 44 | pipenv shell 45 | pipenv install twine --dev --pypi-mirror https://mirrors.aliyun.com/pypi/simple 46 | twine upload dist/* -u NashMiao -p %PYPI_PASSWORD 47 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | wheel = "*" 8 | twine = "*" 9 | 10 | [packages] 11 | aiohttp = "*" 12 | base58 = "*" 13 | cryptography = "*" 14 | ecdsa = "*" 15 | mnemonic = "*" 16 | pycryptodomex = "* 17 | requests = "*" 18 | websockets = "*" 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ontology Python SDK 2 | 3 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/9078ef6584424280b8d6b75556976f94)](https://www.codacy.com/app/NashMiao/ontology-python-sdk?utm_source=github.com&utm_medium=referral&utm_content=ontio/ontology-python-sdk/&utm_campaign=Badge_Grade) 4 | [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/9078ef6584424280b8d6b75556976f94)](https://www.codacy.com/app/NashMiao/ontology-python-sdk?utm_source=github.com&utm_medium=referral&utm_content=ontio/ontology-python-sdk/&utm_campaign=Badge_Coverage) 5 | [![Build Status](https://travis-ci.com/ontio/ontology-python-sdk.svg?branch=master)](https://travis-ci.com/ontio/ontology-python-sdk) 6 | [![pypi-w](https://img.shields.io/pypi/wheel/ontology-python-sdk.svg)](https://pypi.org/project/ontology-python-sdk/) 7 | [![docs](https://img.shields.io/badge/docs-yes-brightgreen.svg)](https://nashmiao.github.io/ontology-python-sdk-docs/) 8 | [![pypi-pyversions](https://img.shields.io/pypi/pyversions/ontology-python-sdk.svg)](https://pypi.org/project/ontology-python-sdk/) 9 | [![pypi-v](https://img.shields.io/pypi/v/ontology-python-sdk.svg)](https://pypi.org/project/ontology-python-sdk/) 10 | [![Downloads](https://pepy.tech/badge/ontology-python-sdk)](https://pepy.tech/project/ontology-python-sdk) 11 | 12 | Official Python implementation of the Ontology SDK. 13 | 14 | ## Installation 15 | 16 | Installation requires a `Python 3.6` or later environment. 17 | 18 | ```bash 19 | pyhton3 -m pip install ontology-python-sdk 20 | ``` 21 | 22 | ## Documentation 23 | 24 | Read a beautiful, responsive API documentation in [here](https://nashmiao.github.io/ontology-python-sdk-docs/). 25 | 26 | ## License 27 | 28 | The Ontology library (i.e. all code outside of the cmd directory) is licensed under the GNU Lesser General Public License v3.0, also included in our repository in the License file. 29 | -------------------------------------------------------------------------------- /ontology/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/account/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/claim/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/claim/payload.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import json 20 | import base64 21 | 22 | from ontology.crypto.digest import Digest 23 | from ontology.exception.error_code import ErrorCode 24 | from ontology.exception.exception import SDKException 25 | 26 | 27 | class Payload(object): 28 | def __init__(self, ver: str, iss_ont_id: str, sub_ont_id: str, iat: int, exp: int, context: str, clm: dict, 29 | clm_rev: dict, jti: str = ''): 30 | if not isinstance(ver, str): 31 | raise SDKException(ErrorCode.require_str_params) 32 | if not isinstance(iss_ont_id, str): 33 | raise SDKException(ErrorCode.require_str_params) 34 | if not isinstance(sub_ont_id, str): 35 | raise SDKException(ErrorCode.require_str_params) 36 | if not isinstance(iat, int): 37 | raise SDKException(ErrorCode.require_int_params) 38 | if not isinstance(clm, dict): 39 | raise SDKException(ErrorCode.require_dict_params) 40 | if not isinstance(clm_rev, dict): 41 | raise SDKException(ErrorCode.require_dict_params) 42 | if not isinstance(jti, str): 43 | raise SDKException(ErrorCode.require_str_params) 44 | self.__version = ver 45 | self.__issuer_ont_id = iss_ont_id 46 | self.__subject = sub_ont_id 47 | self.__issued_at = iat 48 | self.__exp = exp 49 | self.__context = context 50 | self.__claim = clm 51 | self.__claim_revoke = clm_rev 52 | self.__jwt_id = jti 53 | if self.__jwt_id == '': 54 | self.__jwt_id = Digest.sha256(json.dumps(dict(self)).encode('utf-8'), is_hex=True) 55 | 56 | def __iter__(self): 57 | payload = dict(ver=self.__version, iss=self.__issuer_ont_id, sub=self.__subject, iat=self.__issued_at, 58 | exp=self.__exp, jti=self.__jwt_id) 59 | payload['@context'] = self.__context 60 | payload['clm'] = self.__claim 61 | payload['clm-rev'] = self.__claim_revoke 62 | for value, key in payload.items(): 63 | yield (value, key) 64 | 65 | @property 66 | def ver(self): 67 | return self.__version 68 | 69 | @property 70 | def iss(self): 71 | return self.__issuer_ont_id 72 | 73 | @property 74 | def sub(self): 75 | return self.__subject 76 | 77 | @property 78 | def iat(self): 79 | return self.__issued_at 80 | 81 | @property 82 | def exp(self): 83 | return self.__exp 84 | 85 | @property 86 | def jti(self): 87 | return self.__jwt_id 88 | 89 | @property 90 | def context(self): 91 | return self.__context 92 | 93 | @property 94 | def clm(self): 95 | return self.__claim 96 | 97 | @property 98 | def clm_rev(self): 99 | return self.__claim_revoke 100 | 101 | def to_json_str(self): 102 | return json.dumps(dict(self)) 103 | 104 | def to_bytes(self): 105 | return self.to_json_str().encode('utf-8') 106 | 107 | def to_base64(self): 108 | return base64.b64encode(self.to_bytes()).decode('ascii') 109 | 110 | @staticmethod 111 | def from_base64(b64_payload: str): 112 | json_payload = base64.b64decode(b64_payload).decode('utf-8') 113 | dict_payload = json.loads(json_payload) 114 | try: 115 | payload = Payload(dict_payload['ver'], dict_payload['iss'], dict_payload['sub'], dict_payload['iat'], 116 | dict_payload['exp'], dict_payload['@context'], dict_payload['clm'], 117 | dict_payload['clm-rev'], dict_payload['jti']) 118 | except KeyError: 119 | raise SDKException(ErrorCode.invalid_b64_claim_data) 120 | return payload 121 | -------------------------------------------------------------------------------- /ontology/common/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/common/address.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import base58 20 | 21 | from typing import List, Union 22 | 23 | from ontology.core.base_params_builder import BaseParamsBuilder 24 | from ontology.vm.op_code import CHECKSIG 25 | from ontology.crypto.digest import Digest 26 | from ontology.core.program import ProgramBuilder 27 | from ontology.exception.error_code import ErrorCode 28 | from ontology.crypto.hd_public_key import HDPublicKey 29 | from ontology.exception.exception import SDKException 30 | 31 | 32 | class Address(object): 33 | __COIN_VERSION = b'\x17' 34 | 35 | def __init__(self, script_hash: Union[bytes, bytearray]): 36 | if not isinstance(script_hash, bytes): 37 | try: 38 | script_hash = bytes(script_hash) 39 | except TypeError: 40 | raise SDKException(ErrorCode.other_error('Invalid script hash.')) 41 | if len(script_hash) != 20: 42 | raise SDKException(ErrorCode.other_error('Invalid script hash.')) 43 | self.ZERO = script_hash 44 | 45 | @classmethod 46 | def __from_byte_script(cls, byte_script: bytes, little_endian: bool = True): 47 | if not little_endian: 48 | return cls(Digest.hash160(msg=byte_script, is_hex=False)[::-1]) 49 | return cls(Digest.hash160(msg=byte_script, is_hex=False)) 50 | 51 | @classmethod 52 | def from_public_key(cls, public_key: bytes): 53 | builder = BaseParamsBuilder() 54 | builder.push_bytearray(bytearray(public_key)) 55 | builder.emit(CHECKSIG) 56 | return cls.__from_byte_script(builder.to_bytes()) 57 | 58 | @classmethod 59 | def from_hd_public_key(cls, hd_public_key: HDPublicKey): 60 | return cls.from_public_key(hd_public_key.to_bytes()) 61 | 62 | @classmethod 63 | def from_multi_pub_keys(cls, m: int, pub_keys: List[bytes]): 64 | return cls.__from_byte_script(ProgramBuilder.program_from_multi_pubkey(m, pub_keys)) 65 | 66 | @classmethod 67 | def from_hex_contract_code(cls, code: str): 68 | """ 69 | generate contract address from avm bytecode. 70 | """ 71 | try: 72 | return cls.__from_byte_script(bytes.fromhex(code), little_endian=False) 73 | except ValueError: 74 | raise SDKException(ErrorCode.other_error('Invalid avm code.')) 75 | 76 | def b58encode(self): 77 | data = Address.__COIN_VERSION + self.ZERO 78 | checksum = Digest.hash256(data)[0:4] 79 | return base58.b58encode(data + checksum).decode('utf-8') 80 | 81 | def to_bytes(self): 82 | return self.ZERO 83 | 84 | def to_bytearray(self) -> bytearray: 85 | return bytearray(self.ZERO) 86 | 87 | def hex(self, little_endian: bool = True): 88 | if little_endian: 89 | return self.ZERO.hex() 90 | bytearray_zero = bytearray(self.ZERO) 91 | bytearray_zero.reverse() 92 | return bytearray_zero.hex() 93 | 94 | @classmethod 95 | def b58decode(cls, address: str): 96 | if isinstance(address, Address): 97 | return address 98 | if isinstance(address, bytes): 99 | return cls(address) 100 | data = base58.b58decode(address) 101 | if len(data) != 25: 102 | raise SDKException(ErrorCode.param_error) 103 | if data[0] != int.from_bytes(Address.__COIN_VERSION, "little"): 104 | raise SDKException(ErrorCode.param_error) 105 | checksum = Digest.hash256(data[0:21]) 106 | if data[21:25] != checksum[0:4]: 107 | raise SDKException(ErrorCode.param_error) 108 | return cls(data[1:21]) 109 | -------------------------------------------------------------------------------- /ontology/common/define.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | DID_ONT = 'did:ont:' 20 | -------------------------------------------------------------------------------- /ontology/common/wallet_qr.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import json 20 | import base64 21 | 22 | from ontology.account.account import Account 23 | from ontology.wallet.wallet import WalletData 24 | from ontology.wallet.identity import Identity 25 | from ontology.wallet.account import AccountData 26 | from ontology.crypto.signature_scheme import SignatureScheme 27 | 28 | 29 | class WalletQR(object): 30 | @staticmethod 31 | def export_identity_qr_code(wallet_file_or_scrypt, identity: Identity): 32 | control = identity.controls[0] 33 | address = identity.ont_id[8:] 34 | 35 | if isinstance(wallet_file_or_scrypt, WalletData): 36 | scrypt = json.dumps(wallet_file_or_scrypt.scrypt, default=lambda obj: obj.__dict__, sort_keys=True, 37 | indent=4) 38 | else: 39 | scrypt = json.dumps(wallet_file_or_scrypt, default=lambda obj: obj.__dict__, sort_keys=True, indent=4) 40 | data = dict(type='I', label=identity.label, key=control.key, parameters=control.parameters, algorithm='ECDSA', 41 | scrypt=scrypt, address=address, salt=control.salt) 42 | return data 43 | 44 | @staticmethod 45 | def export_account_qr_code(wallet_file_or_scrypt, account: AccountData): 46 | if isinstance(wallet_file_or_scrypt, WalletData): 47 | scrypt = json.dumps(wallet_file_or_scrypt.scrypt, default=lambda obj: obj.__dict__, sort_keys=True, 48 | indent=4) 49 | else: 50 | scrypt = json.dumps(wallet_file_or_scrypt, default=lambda obj: obj.__dict__, sort_keys=True, indent=4) 51 | data = dict(type='I', label=account.label, key=account.key, parameters=account.parameters, algorithm="ECDSA", 52 | scrypt=scrypt, address=account.b58_address, salt=account.salt) 53 | return data 54 | 55 | @staticmethod 56 | def get_private_key_from_qr_code(qr_code: str, password: str): 57 | data = json.loads(qr_code) 58 | key = data['key'] 59 | address = data['address'] 60 | salt = data['salt'] 61 | n = json.loads(data['scrypt'])['n'] 62 | acct = Account.get_gcm_decoded_private_key(key, password, address, base64.b64decode(salt), int(n), 63 | SignatureScheme.SHA256withECDSA) 64 | return acct 65 | -------------------------------------------------------------------------------- /ontology/contract/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | -------------------------------------------------------------------------------- /ontology/contract/native/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | -------------------------------------------------------------------------------- /ontology/contract/native/aio_ong.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from typing import Union 20 | 21 | from ontology.common.address import Address 22 | from ontology.account.account import Account 23 | from ontology.contract.native.ong import Ong 24 | from ontology.exception.error_code import ErrorCode 25 | from ontology.exception.exception import SDKException 26 | from ontology.contract.native.aio_asset import AioAsset 27 | 28 | 29 | class AioOng(Ong, AioAsset): 30 | def __init__(self, sdk): 31 | super().__init__(sdk) 32 | 33 | async def unbound(self, address: Union[str, Address]) -> int: 34 | """ 35 | This interface is used to query the amount of account's unbound ong. 36 | """ 37 | ont_contract = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' 38 | if isinstance(address, Address): 39 | address = address.b58encode() 40 | return int(await self._sdk.default_aio_network.get_allowance('ong', Address(ont_contract).b58encode(), address)) 41 | 42 | async def withdraw(self, claimer: Account, receiver: Union[str, Address], amount: int, payer: Account, 43 | gas_price: int, gas_limit: int) -> str: 44 | """ 45 | This interface is used to withdraw a amount of ong and transfer them to receive address. 46 | """ 47 | if amount <= 0: 48 | raise SDKException(ErrorCode.other_error('the amount should be greater than than zero.')) 49 | tx = self.new_withdraw_tx(claimer.get_address(), receiver, amount, payer.get_address(), gas_price, gas_limit) 50 | tx.sign_transaction(claimer) 51 | if claimer.get_address_base58() != payer.get_address_base58(): 52 | tx.add_sign_transaction(payer) 53 | return await self._sdk.default_aio_network.send_raw_transaction(tx) 54 | -------------------------------------------------------------------------------- /ontology/contract/native/aio_ont.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.contract.native.ont import Ont 20 | from ontology.contract.native.aio_asset import AioAsset 21 | 22 | 23 | class AioOnt(Ont, AioAsset): 24 | def __init__(self, sdk): 25 | super().__init__(sdk) 26 | -------------------------------------------------------------------------------- /ontology/contract/native/ong.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from typing import Union 20 | 21 | from ontology.common.address import Address 22 | from ontology.account.account import Account 23 | from ontology.exception.error_code import ErrorCode 24 | from ontology.exception.exception import SDKException 25 | from ontology.vm.build_vm import build_native_invoke_code 26 | from ontology.core.invoke_transaction import InvokeTransaction 27 | from ontology.contract.native.asset import Asset 28 | 29 | 30 | class Ong(Asset): 31 | def __init__(self, sdk): 32 | super().__init__(sdk) 33 | self._contract_address = b'\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 34 | self._invoke_address = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02' 35 | 36 | def new_withdraw_tx(self, claimer: Union[str, Address], receiver: Union[str, Address], amount: int, 37 | payer: Union[str, Address], gas_price: int, gas_limit: int) -> InvokeTransaction: 38 | """ 39 | This interface is used to generate a Transaction object that 40 | allow one account to withdraw an amount of ong and transfer them to receive address. 41 | """ 42 | if amount <= 0: 43 | raise SDKException(ErrorCode.other_error('the amount should be greater than than zero.')) 44 | payer = Address.b58decode(payer) 45 | ont_contract = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' 46 | args = dict(claimer=Address.b58decode(claimer), from_address=ont_contract, 47 | to_address=Address.b58decode(receiver), value=amount) 48 | invoke_code = build_native_invoke_code(self._invoke_address, self._version, 'transferFrom', args) 49 | return InvokeTransaction(payer, gas_price, gas_limit, invoke_code) 50 | 51 | def unbound(self, address: Union[str, Address]) -> int: 52 | """ 53 | This interface is used to query the amount of account's unbound ong. 54 | """ 55 | ont_contract = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' 56 | if isinstance(address, Address): 57 | address = address.b58encode() 58 | return int(self._sdk.default_network.get_allowance('ong', Address(ont_contract).b58encode(), address)) 59 | 60 | def withdraw(self, claimer: Account, receiver: Union[str, Address], amount: int, payer: Account, gas_price: int, 61 | gas_limit: int) -> str: 62 | """ 63 | This interface is used to withdraw a amount of ong and transfer them to receive address. 64 | """ 65 | if amount <= 0: 66 | raise SDKException(ErrorCode.other_error('the amount should be greater than than zero.')) 67 | tx = self.new_withdraw_tx(claimer.get_address(), receiver, amount, payer.get_address(), gas_price, gas_limit) 68 | tx.sign_transaction(claimer) 69 | if claimer.get_address_bytes() != payer.get_address_bytes(): 70 | tx.add_sign_transaction(payer) 71 | return self._sdk.default_network.send_raw_transaction(tx) 72 | -------------------------------------------------------------------------------- /ontology/contract/native/ont.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.contract.native.asset import Asset 20 | 21 | 22 | class Ont(Asset): 23 | def __init__(self, sdk=None): 24 | super().__init__(sdk) 25 | self._contract_address = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 26 | self._invoke_address = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' 27 | -------------------------------------------------------------------------------- /ontology/contract/native/vm.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.contract.native.ont import Ont 20 | from ontology.contract.native.ong import Ong 21 | from ontology.contract.native.ontid import OntId 22 | from ontology.contract.native.aio_ont import AioOnt 23 | from ontology.contract.native.aio_ong import AioOng 24 | from ontology.contract.native.aio_ontid import AioOntId 25 | 26 | 27 | class NativeVm(object): 28 | def __init__(self, sdk): 29 | self.__sdk = sdk 30 | 31 | def ont(self): 32 | return Ont(self.__sdk) 33 | 34 | def aio_ont(self): 35 | return AioOnt(self.__sdk) 36 | 37 | def aio_ong(self): 38 | return AioOng(self.__sdk) 39 | 40 | def aio_ont_id(self): 41 | return AioOntId(self.__sdk) 42 | 43 | def ong(self): 44 | return Ong(self.__sdk) 45 | 46 | def ont_id(self): 47 | return OntId(self.__sdk) 48 | 49 | -------------------------------------------------------------------------------- /ontology/contract/neo/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/contract/neo/abi/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/contract/neo/abi/abi_event.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.exception.error_code import ErrorCode 20 | from ontology.exception.exception import SDKException 21 | 22 | 23 | class AbiEvent(object): 24 | def __init__(self, name: str, return_type: str, parameters: []): 25 | self.name = name 26 | self.return_type = return_type 27 | self.parameters = parameters 28 | 29 | def get_parameters(self): 30 | return self.parameters 31 | 32 | def set_params_value(self, *objs): 33 | if len(self.parameters) != len(objs): 34 | raise SDKException(ErrorCode.other_error('Param error.')) 35 | for i, v in enumerate(objs): 36 | self.parameters[i].set_value(v) 37 | -------------------------------------------------------------------------------- /ontology/contract/neo/abi/abi_function.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.exception.error_code import ErrorCode 20 | from ontology.exception.exception import SDKException 21 | from ontology.contract.neo.abi.parameter import Parameter 22 | 23 | 24 | class AbiFunction(object): 25 | def __init__(self, name: str, parameters: list, return_type: str = ''): 26 | self.name = name 27 | self.return_type = return_type 28 | self.parameters = parameters 29 | 30 | def set_params_value(self, *params): 31 | """ 32 | This interface is used to set parameter value for an function in abi file. 33 | """ 34 | if len(params) != len(self.parameters): 35 | raise Exception("parameter error") 36 | for i, p in enumerate(params): 37 | self.parameters[i] = Parameter(self.parameters[i]['name'], self.parameters[i]['type'], p) 38 | 39 | def get_parameter(self, param_name: str) -> Parameter: 40 | """ 41 | This interface is used to get a Parameter object from an AbiFunction object 42 | which contain given function parameter's name, type and value. 43 | 44 | :param param_name: a string used to indicate which parameter we want to get from AbiFunction. 45 | :return: a Parameter object which contain given function parameter's name, type and value. 46 | """ 47 | for p in self.parameters: 48 | if p.name == param_name: 49 | return p 50 | raise SDKException(ErrorCode.param_err('get parameter failed.')) 51 | -------------------------------------------------------------------------------- /ontology/contract/neo/abi/abi_info.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.contract.neo.abi.abi_function import AbiFunction 20 | 21 | 22 | class AbiInfo(object): 23 | def __init__(self, hash_value: str = '', entry_point: str = '', functions: list = None, events: list = None): 24 | self.hash = hash_value 25 | self.entry_point = entry_point 26 | if functions is None: 27 | self.functions = list() 28 | else: 29 | self.functions = functions 30 | if events is None: 31 | self.events = list() 32 | else: 33 | self.events = events 34 | 35 | def get_function(self, name: str) -> AbiFunction or None: 36 | """ 37 | This interface is used to get an AbiFunction object from AbiInfo object by given function name. 38 | 39 | :param name: the function name in abi file 40 | :return: if succeed, an AbiFunction will constructed based on given function name 41 | """ 42 | for func in self.functions: 43 | if func['name'] == name: 44 | return AbiFunction(func['name'], func['parameters'], func.get('returntype', '')) 45 | return None 46 | -------------------------------------------------------------------------------- /ontology/contract/neo/abi/parameter.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | 20 | class Parameter(object): 21 | def __init__(self, name: str, type_value: str, value=None): 22 | self.name = name 23 | self.type = type_value 24 | self.value = value 25 | 26 | def set_value(self, obj): 27 | self.value = obj 28 | -------------------------------------------------------------------------------- /ontology/contract/neo/abi/struct_type.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | class Struct(object): 20 | def __init__(self, struct: list): 21 | self.param_list = struct 22 | 23 | def add(self, *objs): 24 | for obj in objs: 25 | self.param_list.append(obj) 26 | 27 | -------------------------------------------------------------------------------- /ontology/contract/neo/invoke_function.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.vm.build_params import BuildParams 20 | from ontology.core.base_invoke_func import BaseInvokeFunc 21 | 22 | 23 | class NeoInvokeFunction(BaseInvokeFunc): 24 | def __init__(self, func_name: str, parameters: list = None, return_type: str = ''): 25 | super().__init__(func_name, parameters, return_type) 26 | 27 | def create_invoke_code(self): 28 | param_list = list() 29 | param_list.append(self.func_name.encode('utf-8')) 30 | param_list.append(self.parameters) 31 | return BuildParams.create_neo_vm_invoke_code(param_list) 32 | 33 | -------------------------------------------------------------------------------- /ontology/contract/neo/oep.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.exception.error_code import ErrorCode 20 | from ontology.exception.exception import SDKException 21 | 22 | 23 | class Oep(object): 24 | def __init__(self, hex_contract_address: str = '', sdk=None): 25 | self._contract_address = hex_contract_address 26 | self._sdk = sdk 27 | 28 | @property 29 | def hex_contract_address(self): 30 | return self._contract_address 31 | 32 | @hex_contract_address.setter 33 | def hex_contract_address(self, hex_contract_address: str): 34 | if not isinstance(hex_contract_address, str) and len(hex_contract_address) == 40: 35 | raise SDKException(ErrorCode.require_str_params) 36 | hex_contract_address.replace(' ', '') 37 | self._contract_address = hex_contract_address 38 | -------------------------------------------------------------------------------- /ontology/contract/neo/oep5.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | from typing import Union 19 | 20 | from ontology.utils.neo import NeoData 21 | from ontology.contract.neo.oep import Oep 22 | from ontology.common.address import Address 23 | from ontology.exception.error_code import ErrorCode 24 | from ontology.exception.exception import SDKException 25 | from ontology.core.invoke_transaction import InvokeTransaction 26 | from ontology.contract.neo.invoke_function import NeoInvokeFunction 27 | 28 | 29 | class Oep5(Oep): 30 | def __init__(self, hex_contract_address: str = '', sdk=None): 31 | super().__init__(hex_contract_address, sdk) 32 | 33 | def __new_token_setting_tx(self, func_name: str) -> InvokeTransaction: 34 | func = NeoInvokeFunction(func_name) 35 | tx = InvokeTransaction() 36 | tx.add_invoke_code(self._contract_address, func) 37 | return tx 38 | 39 | def new_name_tx(self) -> InvokeTransaction: 40 | """ 41 | This interface is used to generate transaction which can get the name of the token. 42 | """ 43 | return self.__new_token_setting_tx('name') 44 | 45 | def name(self): 46 | """ 47 | This interface is used to get the name of the token synchronously. E.g. "DXToken". 48 | """ 49 | tx = self.new_name_tx() 50 | response = self._sdk.default_network.send_raw_transaction_pre_exec(tx) 51 | return NeoData.to_utf8_str(response.get('Result', '')) 52 | 53 | def new_symbol_tx(self) -> InvokeTransaction: 54 | """ 55 | This interface is used to generate transaction which can get the symbol of the token. 56 | """ 57 | return self.__new_token_setting_tx('symbol') 58 | 59 | def symbol(self): 60 | """ 61 | This interface is used to get the symbol of the token synchronously. E.g. “DX”. 62 | """ 63 | tx = self.new_symbol_tx() 64 | response = self._sdk.default_network.send_raw_transaction_pre_exec(tx) 65 | return NeoData.to_utf8_str(response.get('Result', '')) 66 | 67 | def new_balance_of_tx(self, owner: Union[str, bytes, Address]) -> InvokeTransaction: 68 | """ 69 | This interface is used to generate transaction which can get the account balance of another account with owner address. 70 | """ 71 | func = NeoInvokeFunction('balanceOf') 72 | func.set_params_value(Address.b58decode(owner)) 73 | tx = InvokeTransaction() 74 | tx.add_invoke_code(self._contract_address, func) 75 | return tx 76 | 77 | def balance_of(self, owner: str) -> int: 78 | """ 79 | This interface is used to get the account balance of another account with owner address synchronously. 80 | """ 81 | tx = self.new_balance_of_tx(owner) 82 | result = self._sdk.default_network.send_raw_transaction_pre_exec(tx) 83 | try: 84 | balance = NeoData.to_int(result['Result']) 85 | except SDKException: 86 | balance = 0 87 | return balance 88 | -------------------------------------------------------------------------------- /ontology/contract/neo/vm.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from typing import Union 20 | 21 | from ontology.common.address import Address 22 | from ontology.contract.neo.oep4 import Oep4 23 | from ontology.contract.neo.aio_oep4 import AioOep4 24 | from ontology.contract.neo.claim_record import ClaimRecord 25 | from ontology.contract.neo.oep5 import Oep5 26 | from ontology.core.deploy_transaction import DeployTransaction 27 | from ontology.core.invoke_transaction import InvokeTransaction 28 | from ontology.contract.neo.abi.abi_function import AbiFunction 29 | from ontology.contract.neo.invoke_function import NeoInvokeFunction 30 | from ontology.vm.vm_type import VmType 31 | 32 | 33 | class NeoVm(object): 34 | def __init__(self, sdk): 35 | self.__sdk = sdk 36 | 37 | def oep4(self, hex_contract_address: str = '') -> Oep4: 38 | return Oep4(hex_contract_address, self.__sdk) 39 | 40 | def oep5(self, hex_contract_address: str = '') -> Oep5: 41 | return Oep5(hex_contract_address, self.__sdk) 42 | 43 | def aio_oep4(self, hex_contract_address: str = '') -> AioOep4: 44 | return AioOep4(hex_contract_address, self.__sdk) 45 | 46 | def claim_record(self) -> ClaimRecord: 47 | return ClaimRecord(self.__sdk) 48 | 49 | @staticmethod 50 | def address_from_avm_code(avm_code: str) -> Address: 51 | return Address.from_hex_contract_code(avm_code) 52 | 53 | @staticmethod 54 | def make_deploy_transaction(code: str, 55 | name: str, 56 | code_version: str, 57 | author: str, 58 | email: str, 59 | description: str, 60 | gas_price: int, 61 | gas_limit: int, 62 | payer: Union[str, bytes, Address]) -> DeployTransaction: 63 | tx = DeployTransaction(code, VmType.Neo, name, code_version, author, email, description, gas_price, gas_limit, 64 | payer) 65 | return tx 66 | 67 | @staticmethod 68 | def make_invoke_transaction(contract_address: Union[str, bytes, bytearray, Address], 69 | func: Union[AbiFunction, NeoInvokeFunction], 70 | payer: Union[str, bytes, Address] = b'', 71 | gas_price: int = 0, 72 | gas_limit: int = 0) -> InvokeTransaction: 73 | tx = InvokeTransaction(payer, gas_price, gas_limit) 74 | tx.add_invoke_code(contract_address, func) 75 | return tx 76 | -------------------------------------------------------------------------------- /ontology/contract/wasm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ontio/ontology-python-sdk/ebe3dcb7fe4148b131f79bfc46d70b4359263316/ontology/contract/wasm/__init__.py -------------------------------------------------------------------------------- /ontology/contract/wasm/invoke_function.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.vm.build_params import BuildParams 20 | from ontology.core.base_invoke_func import BaseInvokeFunc 21 | 22 | 23 | class WasmInvokeFunction(BaseInvokeFunc): 24 | def __init__(self, func_name: str, parameters: list = None, return_type: str = ''): 25 | super().__init__(func_name, parameters, return_type) 26 | 27 | def create_invoke_code(self) -> bytearray: 28 | param_list = list() 29 | param_list.append(self.func_name) 30 | param_list += self.parameters 31 | return BuildParams.create_wasm_vm_invoke_code(param_list) 32 | -------------------------------------------------------------------------------- /ontology/contract/wasm/vm.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from os import path 20 | from typing import Union 21 | 22 | from ontology.utils.transaction import ensure_bytearray_contract_address 23 | 24 | from ontology.vm.vm_type import VmType 25 | from ontology.common.address import Address 26 | from ontology.core.transaction import TxType 27 | from ontology.exception.error_code import ErrorCode 28 | from ontology.exception.exception import SDKException 29 | from ontology.core.deploy_transaction import DeployTransaction 30 | from ontology.core.invoke_transaction import InvokeTransaction 31 | from ontology.contract.wasm.invoke_function import WasmInvokeFunction 32 | 33 | 34 | class WasmVm(object): 35 | def __init__(self, sdk): 36 | self.__sdk = sdk 37 | 38 | @staticmethod 39 | def open_wasm(wasm_file_path: str) -> str: 40 | if not path.isfile(wasm_file_path): 41 | raise SDKException(ErrorCode.require_file_path_params) 42 | with open(wasm_file_path, 'rb') as f: 43 | content = f.read() 44 | return content.hex() 45 | 46 | @staticmethod 47 | def address_from_wasm_code(wasm_code: str) -> Address: 48 | return Address.from_hex_contract_code(wasm_code) 49 | 50 | @staticmethod 51 | def make_deploy_transaction(code: str, 52 | name: str, 53 | code_version: str, 54 | author: str, 55 | email: str, 56 | description: str, 57 | gas_price: int, 58 | gas_limit: int, 59 | payer: Union[str, bytes, Address]) -> DeployTransaction: 60 | tx = DeployTransaction(code, VmType.Wasm, name, code_version, author, email, description, gas_price, gas_limit, 61 | payer) 62 | return tx 63 | 64 | @staticmethod 65 | def make_invoke_transaction(contract_address: Union[str, bytes, bytearray, Address], 66 | func: WasmInvokeFunction, 67 | payer: Union[str, bytes, Address] = b'', 68 | gas_price: int = 0, 69 | gas_limit: int = 0) -> InvokeTransaction: 70 | payload = InvokeTransaction.generate_wasm_vm_invoke_code(contract_address, func) 71 | tx = InvokeTransaction(payer, gas_price, gas_limit, payload, TxType.InvokeWasmVm) 72 | return tx 73 | -------------------------------------------------------------------------------- /ontology/core/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | -------------------------------------------------------------------------------- /ontology/core/base_invoke_func.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | 20 | class BaseInvokeFunc(object): 21 | def __init__(self, func_name: str, parameters: list = None, return_type: str = ''): 22 | self._func_name = func_name 23 | if parameters is None: 24 | parameters = list() 25 | self._parameters = parameters 26 | self._return_type = return_type 27 | 28 | @property 29 | def func_name(self): 30 | return self._func_name 31 | 32 | @property 33 | def parameters(self): 34 | return self._parameters 35 | 36 | @property 37 | def return_type(self): 38 | return self._return_type 39 | 40 | def set_params_value(self, *params): 41 | if len(self._parameters) != 0: 42 | self._parameters = list() 43 | for param in params: 44 | self._parameters.append(param) 45 | 46 | def add_params_value(self, *params): 47 | if self._parameters is None: 48 | self._parameters = list() 49 | for param in params: 50 | self._parameters.append(param) 51 | -------------------------------------------------------------------------------- /ontology/core/base_params_builder.py: -------------------------------------------------------------------------------- 1 | from typing import Union 2 | 3 | from ontology.vm.op_code import PUSHBYTES75, PUSHDATA1, PUSHDATA2, PUSHDATA4 4 | 5 | from ontology.exception.error_code import ErrorCode 6 | 7 | from ontology.exception.exception import SDKException 8 | 9 | from ontology.io.memory_stream import MemoryStream 10 | 11 | 12 | class BaseParamsBuilder(object): 13 | def __init__(self, *args, **kwargs): 14 | self.ms = MemoryStream(*args, **kwargs) 15 | 16 | def set_buffer(self, value: Union[bytes, str]): 17 | if isinstance(value, str): 18 | value = bytes.fromhex(value) 19 | self.ms = MemoryStream(value) 20 | 21 | def clear_up(self): 22 | self.ms.clean_up() 23 | 24 | def read_byte(self) -> bytes: 25 | return self.ms.read(1) 26 | 27 | def read_bytes(self, size: int) -> bytes: 28 | return self.ms.read(size) 29 | 30 | def write_bytes(self, value: bytearray or bytes or str or int): 31 | if isinstance(value, bytearray) or isinstance(value, bytes): 32 | self.ms.write(value) 33 | elif isinstance(value, str): 34 | self.ms.write(value.encode('utf-8')) 35 | elif isinstance(value, int): 36 | self.ms.write(bytes([value])) 37 | else: 38 | raise SDKException(ErrorCode.param_err('type error, write byte failed.')) 39 | 40 | def emit(self, op): 41 | self.write_bytes(op) 42 | 43 | def push_bytearray(self, data: Union[bytes, bytearray]): 44 | data_len = len(data) 45 | if data_len < int.from_bytes(PUSHBYTES75, 'little'): 46 | self.write_bytes(bytearray([data_len])) 47 | elif data_len < 0x100: 48 | self.emit(PUSHDATA1) 49 | self.write_bytes(bytearray([data_len])) 50 | elif data_len < 0x10000: 51 | self.emit(PUSHDATA2) 52 | self.write_bytes(len(data).to_bytes(2, "little")) 53 | else: 54 | self.emit(PUSHDATA4) 55 | self.write_bytes(len(data).to_bytes(4, "little")) 56 | self.write_bytes(data) 57 | 58 | def to_bytes(self) -> bytes: 59 | return self.ms.to_bytes() 60 | 61 | def to_bytearray(self) -> bytearray: 62 | return bytearray(self.ms.to_bytes()) 63 | -------------------------------------------------------------------------------- /ontology/core/deploy_transaction.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from typing import Union 20 | 21 | from ontology.exception.error_code import ErrorCode 22 | 23 | from ontology.exception.exception import SDKException 24 | 25 | from ontology.common.address import Address 26 | from ontology.io.binary_writer import BinaryWriter 27 | from ontology.core.transaction import Transaction, TxType 28 | from ontology.vm.vm_type import VmType 29 | 30 | 31 | class DeployTransaction(Transaction): 32 | def __init__(self, code: bytearray or str, vm_type: VmType, name: str = '', version: str = '', author: str = '', 33 | email: str = '', description: str = '', gas_price: int = 0, gas_limit: int = 0, 34 | payer: Union[str, bytes, Address, None] = b''): 35 | super().__init__(0, TxType.Deploy, gas_price, gas_limit, payer) 36 | if isinstance(code, str): 37 | code = bytearray.fromhex(code) 38 | self.__code = code 39 | if not isinstance(vm_type, VmType): 40 | raise SDKException(ErrorCode.other_error('invalid vm type')) 41 | self.__vm_type = vm_type 42 | self.__name = name 43 | self.__code_version = version 44 | self.__author = author 45 | self.__email = email 46 | self.__description = description 47 | 48 | def serialize_exclusive_data(self, writer: BinaryWriter): 49 | writer.write_var_bytes(self.__code) 50 | writer.write_byte(self.__vm_type.value) 51 | writer.write_var_str(self.__name) 52 | writer.write_var_str(self.__code_version) 53 | writer.write_var_str(self.__author) 54 | writer.write_var_str(self.__email) 55 | writer.write_var_str(self.__description) 56 | -------------------------------------------------------------------------------- /ontology/core/invoke_transaction.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from typing import Union 20 | 21 | from ontology.vm.op_code import APPCALL 22 | 23 | from ontology.utils.transaction import ensure_bytearray_contract_address 24 | 25 | from ontology.exception.error_code import ErrorCode 26 | 27 | from ontology.exception.exception import SDKException 28 | 29 | from ontology.vm.build_params import BuildParams 30 | 31 | from ontology.common.address import Address 32 | from ontology.core.transaction import Transaction, TxType 33 | from ontology.contract.neo.abi.abi_function import AbiFunction 34 | from ontology.contract.neo.invoke_function import NeoInvokeFunction 35 | from ontology.contract.wasm.invoke_function import WasmInvokeFunction 36 | 37 | 38 | class InvokeTransaction(Transaction): 39 | def __init__(self, payer: Union[str, bytes, Address] = b'', gas_price: int = 0, gas_limit: int = 0, 40 | payload: bytearray = None, tx_type: TxType = TxType.InvokeNeoVm, version: int = 0): 41 | super().__init__(version, tx_type, gas_price, gas_limit, payer, payload) 42 | 43 | def add_invoke_code(self, contract_address: Union[str, bytes, bytearray, Address], 44 | func: Union[NeoInvokeFunction, WasmInvokeFunction]): 45 | if self.tx_type == TxType.InvokeNeoVm.value: 46 | self.payload = self.generate_neo_vm_invoke_code(contract_address, func) 47 | if self.tx_type == TxType.InvokeWasmVm.value: 48 | self.payload = self.generate_wasm_vm_invoke_code(contract_address, func) 49 | 50 | @staticmethod 51 | def generate_neo_vm_invoke_code(contract_address: Union[str, bytes, bytearray, Address], 52 | func: Union[AbiFunction, NeoInvokeFunction]): 53 | if isinstance(func, AbiFunction): 54 | params = BuildParams.serialize_abi_function(func) 55 | elif isinstance(func, NeoInvokeFunction): 56 | params = func.create_invoke_code() 57 | else: 58 | raise SDKException(ErrorCode.other_error('the type of func is error')) 59 | contract_address = ensure_bytearray_contract_address(contract_address) 60 | params.append(int.from_bytes(APPCALL, byteorder='little')) 61 | for i in contract_address: 62 | params.append(i) 63 | return params 64 | 65 | @staticmethod 66 | def generate_wasm_vm_invoke_code(contract_address: Union[str, bytes, bytearray, Address], 67 | func: WasmInvokeFunction) -> bytearray: 68 | return ensure_bytearray_contract_address(contract_address) + func.create_invoke_code() 69 | -------------------------------------------------------------------------------- /ontology/core/program_info.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | 20 | class ProgramInfo(object): 21 | 22 | def __init__(self): 23 | self.pubkeys = [] 24 | self.m = 0 25 | 26 | def set_pubkey(self, pubkeys: []): 27 | self.pubkeys = pubkeys 28 | 29 | def set_m(self, m): 30 | self.m = m 31 | -------------------------------------------------------------------------------- /ontology/core/sig.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | from typing import List 19 | 20 | from ontology.core.program import ProgramBuilder 21 | from ontology.exception.error_code import ErrorCode 22 | from ontology.exception.exception import SDKException 23 | from ontology.io.binary_reader import BinaryReader 24 | from ontology.io.binary_writer import BinaryWriter 25 | from ontology.io.memory_stream import StreamManager 26 | from ontology.utils.utils import bytes_reader 27 | 28 | 29 | class Sig(object): 30 | def __init__(self, public_keys: List[bytes] = None, m: int = 0, sig_data: List[bytes] = None): 31 | self.public_keys = public_keys # a list to save public keys 32 | self.m = m 33 | if sig_data is None: 34 | sig_data = list() 35 | self.__sig_data = sig_data 36 | 37 | def __iter__(self): 38 | data = dict(M=self.m, publicKeys=list(), sigData=list()) 39 | for key in self.public_keys: 40 | data['publicKeys'].append(bytes.hex(key)) 41 | for s_data in self.__sig_data: 42 | data['sigData'].append(bytes.hex(s_data)) 43 | for key, value in data.items(): 44 | yield (key, value) 45 | 46 | @property 47 | def sig_data(self): 48 | return self.__sig_data 49 | 50 | @sig_data.setter 51 | def sig_data(self, sig_data): 52 | self.__sig_data = sig_data 53 | 54 | def serialize(self) -> bytes: 55 | invoke_script = ProgramBuilder.program_from_params(self.__sig_data) 56 | if len(self.public_keys) == 0: 57 | raise SDKException(ErrorCode.other_error('Public key in sig is empty.')) 58 | 59 | if len(self.public_keys) == 1: 60 | verification_script = ProgramBuilder.program_from_pubkey(self.public_keys[0]) 61 | else: 62 | verification_script = ProgramBuilder.program_from_multi_pubkey(self.m, self.public_keys) 63 | ms = StreamManager.get_stream() 64 | writer = BinaryWriter(ms) 65 | writer.write_var_bytes(invoke_script) 66 | writer.write_var_bytes(verification_script) 67 | ms.flush() 68 | res = ms.hexlify() 69 | res = bytes_reader(res) 70 | StreamManager.release_stream(ms) 71 | return res 72 | 73 | @staticmethod 74 | def deserialize_from(sig_bytes: bytes): 75 | ms = StreamManager.get_stream(sig_bytes) 76 | reader = BinaryReader(ms) 77 | return Sig.deserialize(reader) 78 | 79 | @staticmethod 80 | def deserialize(reader: BinaryReader): 81 | invocation_script = reader.read_var_bytes() 82 | verification_script = reader.read_var_bytes() 83 | sig = Sig() 84 | sig.__sig_data = ProgramBuilder.get_param_info(invocation_script) 85 | info = ProgramBuilder.get_program_info(verification_script) 86 | 87 | sig.public_keys = info.pubkeys 88 | sig.m = info.m 89 | return sig 90 | -------------------------------------------------------------------------------- /ontology/crypto/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/crypto/aes_handler.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from Cryptodome import Random 20 | from Cryptodome.Cipher import AES 21 | from Cryptodome.Util.Padding import pad, unpad 22 | 23 | 24 | class AESHandler(object): 25 | @staticmethod 26 | def generate_iv() -> bytes: 27 | return Random.new().read(AES.block_size) 28 | 29 | @staticmethod 30 | def generate_key(): 31 | key = Random.get_random_bytes(32) 32 | return key 33 | 34 | @staticmethod 35 | def aes_gcm_encrypt_with_iv(plain_text: bytes, hdr: bytes, key: bytes, iv: bytes): 36 | cipher = AES.new(key=key, mode=AES.MODE_GCM, nonce=iv) 37 | cipher.update(hdr) 38 | cipher_text, mac_tag = cipher.encrypt_and_digest(plain_text) 39 | return mac_tag, cipher_text 40 | 41 | @staticmethod 42 | def aes_gcm_decrypt_with_iv(cipher_text: bytes, hdr: bytes, mac_tag: bytes, key: bytes, iv: bytes) -> bytes: 43 | cipher = AES.new(key=key, mode=AES.MODE_GCM, nonce=iv) 44 | cipher.update(hdr) 45 | try: 46 | plain_text = cipher.decrypt_and_verify(cipher_text, mac_tag) 47 | except ValueError: 48 | plain_text = b"" 49 | except KeyError: 50 | plain_text = b"" 51 | return plain_text 52 | 53 | @staticmethod 54 | def aes_gcm_encrypt(plain_text: bytes, hdr: bytes, key: bytes): 55 | cipher = AES.new(key=key, mode=AES.MODE_GCM) 56 | cipher.update(hdr) 57 | cipher_text, mac_tag = cipher.encrypt_and_digest(plain_text) 58 | nonce = cipher.nonce 59 | return nonce, mac_tag, cipher_text 60 | 61 | @staticmethod 62 | def aes_gcm_decrypt(cipher_text: bytes, hdr: bytes, nonce: bytes, mac_tag: bytes, key: bytes): 63 | cipher = AES.new(key=key, mode=AES.MODE_GCM, nonce=nonce) 64 | cipher.update(hdr) 65 | try: 66 | plain_text = cipher.decrypt_and_verify(cipher_text, mac_tag) 67 | except ValueError: 68 | plain_text = b"" 69 | except KeyError: 70 | plain_text = b"" 71 | return plain_text 72 | 73 | @staticmethod 74 | def aes_ctr_encrypt(plain_text: bytes, key: bytes): 75 | cipher = AES.new(key=key, mode=AES.MODE_CTR) 76 | cipher_text = cipher.encrypt(plain_text) 77 | nonce = cipher.nonce 78 | return nonce, cipher_text 79 | 80 | @staticmethod 81 | def aes_ctr_decrypt(cipher_text: bytes, nonce: bytes, key: bytes): 82 | cipher = AES.new(key=key, mode=AES.MODE_CTR, nonce=nonce) 83 | plain_text = cipher.decrypt(cipher_text) 84 | return plain_text 85 | 86 | @staticmethod 87 | def aes_cbc_encrypt(plain_text: bytes, key: bytes, iv: bytes = b''): 88 | if len(iv) == 0: 89 | iv = AESHandler.generate_iv() 90 | cipher = AES.new(key=key, mode=AES.MODE_CBC, iv=iv) 91 | return cipher.IV, cipher.encrypt(pad(plain_text, AES.block_size)) 92 | 93 | @staticmethod 94 | def aes_cbc_decrypt(cipher_text: bytes, iv: bytes, key: bytes): 95 | cipher = AES.new(key=key, mode=AES.MODE_CBC, iv=iv) 96 | return unpad(cipher.decrypt(cipher_text), AES.block_size, style='pkcs7') 97 | -------------------------------------------------------------------------------- /ontology/crypto/curve.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from enum import Enum, unique 20 | from cryptography.hazmat.primitives.asymmetric import ec 21 | 22 | from ontology.exception.error_code import ErrorCode 23 | from ontology.exception.exception import SDKException 24 | 25 | 26 | @unique 27 | class Curve(Enum): 28 | P224 = ec.SECP224R1() 29 | P256 = ec.SECP256R1() 30 | P384 = ec.SECP384R1() 31 | P521 = ec.SECP521R1() 32 | 33 | @staticmethod 34 | def from_label(label: int) -> str: 35 | if label == 1: 36 | return Curve.P224.name 37 | elif label == 2: 38 | return Curve.P256.name 39 | elif label == 3: 40 | return Curve.P384.name 41 | elif label == 4: 42 | return Curve.P521.name 43 | else: 44 | raise SDKException(ErrorCode.unknown_curve_label) 45 | -------------------------------------------------------------------------------- /ontology/crypto/digest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import hashlib 20 | 21 | 22 | class Digest(object): 23 | @staticmethod 24 | def __sha256(msg: bytes, is_hex: bool = False) -> bytes or str: 25 | m = hashlib.sha256() 26 | m.update(msg) 27 | if is_hex: 28 | return m.hexdigest() 29 | else: 30 | return m.digest() 31 | 32 | @staticmethod 33 | def ripemd160(msg: bytes, is_hex: bool = False) -> bytes or str: 34 | h = hashlib.new('ripemd160') 35 | h.update(msg) 36 | if is_hex: 37 | return h.hexdigest() 38 | else: 39 | return h.digest() 40 | 41 | @staticmethod 42 | def sha256(msg: bytes, offset: int = 0, length: int = 0, is_hex: bool = False) -> bytes or str: 43 | if offset != 0 and len(msg) > offset + length: 44 | msg = msg[offset:offset + length] 45 | return Digest.__sha256(msg, is_hex) 46 | 47 | @staticmethod 48 | def hash256(msg: bytes, is_hex: bool = False) -> bytes or str: 49 | digest = Digest.sha256(Digest.sha256(msg), is_hex=is_hex) 50 | return digest 51 | 52 | @staticmethod 53 | def hash160(msg: bytes, is_hex: bool = False) -> bytes or str: 54 | digest = Digest.ripemd160(Digest.__sha256(msg), is_hex) 55 | return digest 56 | -------------------------------------------------------------------------------- /ontology/crypto/kdf.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.crypto.digest import Digest 20 | from ontology.utils.crypto import to_bytes 21 | 22 | 23 | def pbkdf2(seed: str or bytes, dk_len: int) -> bytes: 24 | """ 25 | Derive one key from a seed. 26 | 27 | :param seed: the secret pass phrase to generate the keys from. 28 | :param dk_len: the length in bytes of every derived key. 29 | :return: 30 | """ 31 | key = b'' 32 | index = 1 33 | bytes_seed = to_bytes(seed) 34 | while len(key) < dk_len: 35 | key += Digest.sha256(b''.join([bytes_seed, index.to_bytes(4, 'big', signed=True)])) 36 | index += 1 37 | return key[:dk_len] 38 | -------------------------------------------------------------------------------- /ontology/crypto/key_type.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from enum import Enum, unique 20 | 21 | from ontology.crypto.signature_scheme import SignatureScheme 22 | from ontology.exception.error_code import ErrorCode 23 | from ontology.exception.exception import SDKException 24 | 25 | 26 | @unique 27 | class KeyType(Enum): 28 | ECDSA = b'\x12' 29 | SM2 = b'\x13' 30 | EDDSA = b'\x14' 31 | 32 | def __init__(self, b: int): 33 | self.label = b 34 | 35 | def get_label(self): 36 | return self.label 37 | 38 | @staticmethod 39 | def from_label(label: int): 40 | label = bytes([label]) 41 | if KeyType.ECDSA.value == label: 42 | return KeyType.ECDSA 43 | elif KeyType.SM2.value == label: 44 | return KeyType.SM2 45 | elif KeyType.EDDSA.value == label: 46 | return KeyType.EDDSA 47 | 48 | @staticmethod 49 | def from_pubkey(pubkey: bytes): 50 | if len(pubkey) == 33: 51 | return KeyType.ECDSA 52 | else: 53 | return KeyType.from_label(pubkey[0]) 54 | 55 | @staticmethod 56 | def from_str_type(str_type: str): 57 | if not isinstance(str_type, str): 58 | raise SDKException(ErrorCode.require_str_params) 59 | if str_type == 'ECDSA': 60 | return KeyType.ECDSA 61 | elif str_type == 'SM2': 62 | return KeyType.SM2 63 | elif str_type == 'EDDSA': 64 | return KeyType.ECDSA 65 | else: 66 | raise SDKException(ErrorCode.unknown_asymmetric_key_type) 67 | 68 | @staticmethod 69 | def from_signature_scheme(scheme: SignatureScheme): 70 | if scheme == SignatureScheme.SHA224withECDSA: 71 | return KeyType.ECDSA 72 | elif scheme == SignatureScheme.SHA256withECDSA: 73 | return KeyType.ECDSA 74 | elif scheme == SignatureScheme.SHA384withECDSA: 75 | return KeyType.ECDSA 76 | elif scheme == SignatureScheme.SHA384withECDSA: 77 | return KeyType.ECDSA 78 | elif scheme == SignatureScheme.SHA512withECDSA: 79 | return KeyType.ECDSA 80 | elif scheme == SignatureScheme.SHA3_224withECDSA: 81 | return KeyType.ECDSA 82 | elif scheme == SignatureScheme.SHA3_256withECDSA: 83 | return KeyType.ECDSA 84 | elif scheme == SignatureScheme.SHA3_384withECDSA: 85 | return KeyType.ECDSA 86 | elif scheme == SignatureScheme.SHA3_512withECDSA: 87 | return KeyType.ECDSA 88 | elif scheme == SignatureScheme.RIPEMD160withECDSA: 89 | return KeyType.ECDSA 90 | elif scheme == SignatureScheme.SM3withSM2: 91 | return KeyType.SM2 92 | else: 93 | raise SDKException(ErrorCode.other_error('invalid signature scheme.')) 94 | -------------------------------------------------------------------------------- /ontology/crypto/mnemonic.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import mnemonic 20 | 21 | 22 | class Mnemonic(mnemonic.Mnemonic): 23 | def __init__(self, language: str = 'english'): 24 | super().__init__(language) 25 | -------------------------------------------------------------------------------- /ontology/crypto/scrypt.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from Cryptodome.Protocol import KDF 20 | 21 | from ontology.exception.error_code import ErrorCode 22 | from ontology.exception.exception import SDKException 23 | 24 | 25 | class Scrypt: 26 | def __init__(self, n=16384, r=8, p=8, dk_len=64): 27 | self.__n = n 28 | self.__r = r 29 | self.__p = p 30 | self.__dk_len = dk_len 31 | 32 | def __iter__(self): 33 | data = dict() 34 | data['n'] = self.__n 35 | data['r'] = self.__r 36 | data['p'] = self.__p 37 | data['dkLen'] = self.__dk_len 38 | for key, value in data.items(): 39 | yield (key, value) 40 | 41 | @property 42 | def dk_len(self): 43 | return self.__dk_len 44 | 45 | @dk_len.setter 46 | def dk_len(self, dk_len: int): 47 | if not isinstance(dk_len, int): 48 | raise SDKException(ErrorCode.other_error('Invalid dkLen in scrypt.')) 49 | self.__dk_len = dk_len 50 | 51 | @property 52 | def n(self): 53 | return self.__n 54 | 55 | @n.setter 56 | def n(self, n: int): 57 | if not isinstance(n, int): 58 | raise SDKException(ErrorCode.other_error('Invalid n in scrypt.')) 59 | self.__n = n 60 | 61 | @property 62 | def r(self): 63 | return self.__r 64 | 65 | @r.setter 66 | def r(self, r: int): 67 | self.__r = r 68 | 69 | @property 70 | def p(self): 71 | return self.__p 72 | 73 | @p.setter 74 | def p(self, p): 75 | self.__p = p 76 | 77 | def generate_kd(self, password: bytes or str, salt: bytes or str) -> bytes: 78 | dk = KDF.scrypt(password, salt, self.__dk_len, self.__n, self.__r, self.__p) 79 | return dk 80 | -------------------------------------------------------------------------------- /ontology/crypto/signature.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ecdsa import util, curves, SigningKey 20 | 21 | from ontology.crypto.curve import Curve 22 | from ontology.exception.error_code import ErrorCode 23 | from ontology.exception.exception import SDKException 24 | from ontology.crypto.signature_scheme import SignatureScheme 25 | 26 | 27 | class Signature(object): 28 | def __init__(self, signature_scheme: SignatureScheme, signature_value): 29 | self.__scheme = signature_scheme 30 | self.__value = signature_value 31 | 32 | @staticmethod 33 | def ec_get_public_key_by_private_key(private_key: bytes, curve_name) -> bytes: 34 | if curve_name == Curve.P256: 35 | private_key = SigningKey.from_string(string=private_key, curve=curves.NIST256p) 36 | verifying_key = private_key.get_verifying_key() 37 | order = verifying_key.pubkey.order 38 | x_int = verifying_key.pubkey.point.x() 39 | y_int = verifying_key.pubkey.point.y() 40 | x_str = util.number_to_string(x_int, order) 41 | if y_int % 2 == 0: 42 | point_str = util.b('\x02') + x_str 43 | else: 44 | point_str = util.b('\x03') + x_str 45 | elif curve_name == Curve.P224: 46 | raise SDKException(ErrorCode.unsupported_key_type) 47 | elif curve_name == Curve.P384: 48 | raise SDKException(ErrorCode.unsupported_key_type) 49 | elif curve_name == Curve.P521: 50 | raise SDKException(ErrorCode.unsupported_key_type) 51 | else: 52 | raise SDKException(ErrorCode.unsupported_key_type) 53 | return point_str 54 | 55 | def to_bytes(self): 56 | if self.__scheme != SignatureScheme.SHA256withECDSA: 57 | raise SDKException(ErrorCode.unsupported_signature_scheme) 58 | return bytes.fromhex(self.__value) -------------------------------------------------------------------------------- /ontology/crypto/signature_scheme.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from enum import IntEnum, unique 20 | 21 | from ontology.exception.error_code import ErrorCode 22 | from ontology.exception.exception import SDKException 23 | 24 | 25 | @unique 26 | class SignatureScheme(IntEnum): 27 | SHA224withECDSA = 0 28 | SHA256withECDSA = 1 29 | SHA384withECDSA = 2 30 | SHA512withECDSA = 3 31 | SHA3_224withECDSA = 4 32 | SHA3_256withECDSA = 5 33 | SHA3_384withECDSA = 6 34 | SHA3_512withECDSA = 7 35 | RIPEMD160withECDSA = 8 36 | SM3withSM2 = 9 37 | EDDSAwithSHA256 = 10 38 | 39 | @staticmethod 40 | def from_claim_alg(alg: str): 41 | if not isinstance(alg, str): 42 | raise SDKException(ErrorCode.require_str_params) 43 | if alg == 'ES224' or alg == 'ONT-ES224': 44 | return SignatureScheme.SHA224withECDSA 45 | elif alg == 'ES256' or alg == 'ONT-ES256': 46 | return SignatureScheme.SHA256withECDSA 47 | elif alg == 'ES384' or alg == 'ONT-ES384': 48 | return SignatureScheme.SHA384withECDSA 49 | elif alg == 'ES512' or alg == 'ONT-ES512': 50 | return SignatureScheme.SHA512withECDSA 51 | elif alg == 'ES3-224' or alg == 'ONT-ES3-224': 52 | return SignatureScheme.SHA3_224withECDSA 53 | elif alg == 'ES3-256' or alg == 'ONT-ES3-256': 54 | return SignatureScheme.SHA3_256withECDSA 55 | elif alg == 'ES3-384' or alg == 'ONT-ES3-384': 56 | return SignatureScheme.SHA3_384withECDSA 57 | elif alg == 'ER160' or alg == 'ONT-ER160': 58 | return SignatureScheme.RIPEMD160withECDSA 59 | elif alg == 'SM' or alg == 'ONT-SM': 60 | return SignatureScheme.SM3withSM2 61 | elif alg == 'EDS512' or alg == 'ONT-EDS512': 62 | return SignatureScheme.EDDSAwithSHA256 63 | else: 64 | raise SDKException(ErrorCode.unknown_asymmetric_key_type) 65 | -------------------------------------------------------------------------------- /ontology/exception/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/exception/exception.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | 20 | class SDKException(Exception): 21 | def __init__(self, error_code: dict): 22 | super().__init__(error_code['error'], error_code['desc']) 23 | 24 | 25 | class SDKRuntimeException(RuntimeError): 26 | def __init__(self, error_code: dict): 27 | super().__init__(error_code['error'], error_code['desc']) 28 | -------------------------------------------------------------------------------- /ontology/io/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/io/memory_stream.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from io import BytesIO 20 | from binascii import hexlify 21 | 22 | __mstreams__ = [] 23 | __mstreams_available__ = [] 24 | 25 | 26 | class StreamManager: 27 | 28 | @staticmethod 29 | def TotalBuffers(): 30 | """ 31 | Get the total number of buffers stored in the StreamManager. 32 | 33 | Returns: 34 | int: 35 | """ 36 | return len(__mstreams__) 37 | 38 | @staticmethod 39 | def get_stream(data=None): 40 | """ 41 | Get a MemoryStream instance. 42 | 43 | Args: 44 | data (bytes, bytearray, BytesIO): (Optional) data to create the stream from. 45 | 46 | Returns: 47 | MemoryStream: instance. 48 | """ 49 | if len(__mstreams_available__) == 0: 50 | if data: 51 | mstream = MemoryStream(data) 52 | mstream.seek(0) 53 | else: 54 | mstream = MemoryStream() 55 | __mstreams__.append(mstream) 56 | return mstream 57 | 58 | mstream = __mstreams_available__.pop() 59 | 60 | if data is not None and len(data): 61 | mstream.clean_up() 62 | mstream.write(data) 63 | 64 | mstream.seek(0) 65 | 66 | return mstream 67 | 68 | @staticmethod 69 | def release_stream(mstream): 70 | """ 71 | Release the memory stream 72 | Args: 73 | mstream (MemoryStream): instance. 74 | """ 75 | mstream.clean_up() 76 | __mstreams_available__.append(mstream) 77 | 78 | 79 | class MemoryStream(BytesIO): 80 | """ 81 | Description: 82 | MemoryStream 83 | 84 | Usage: 85 | from ontology.io.memory_stream import MemoryStream 86 | """ 87 | 88 | def __init__(self, *args, **kwargs): 89 | """ 90 | Create an instance. 91 | 92 | Args: 93 | *args: 94 | **kwargs: 95 | """ 96 | super().__init__(*args, **kwargs) 97 | 98 | def readable(self): 99 | """ 100 | Get readable status. 101 | 102 | Returns: 103 | bool: True if the stream can be read from. False otherwise. 104 | """ 105 | return self.readable() 106 | 107 | def seekable(self): 108 | """ 109 | Get random access support status. 110 | 111 | Returns: 112 | bool: True if random access is supported. False otherwise. 113 | """ 114 | return self.seekable 115 | 116 | def writable(self): 117 | """ 118 | Get writeable status. 119 | 120 | Returns: 121 | bool: True if the stream is writeable. False otherwise. 122 | """ 123 | return self.writable() 124 | 125 | def to_bytes(self) -> bytes: 126 | return self.getvalue() 127 | 128 | def hexlify(self) -> bytes: 129 | """ 130 | Hexlify the stream data. 131 | 132 | Returns: 133 | bytes: b"" object containing the data. 134 | """ 135 | data = self.to_bytes() 136 | return hexlify(data) 137 | 138 | def clean_up(self): 139 | """ 140 | clean_up the stream by truncating it to size 0. 141 | """ 142 | self.seek(0) 143 | self.truncate(0) 144 | -------------------------------------------------------------------------------- /ontology/merkle/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/merkle/merkle_verifier.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from typing import List 20 | 21 | from ontology.utils.neo import NeoData 22 | from ontology.crypto.digest import Digest 23 | from ontology.exception.error_code import ErrorCode 24 | from ontology.exception.exception import SDKException 25 | 26 | 27 | class MerkleVerifier(object): 28 | @staticmethod 29 | def get_proof(tx_block_height: int, target_hash_list: List[str], current_block_height: int): 30 | proof_node = list() 31 | last_node = current_block_height 32 | pos = 0 33 | while last_node > 0: 34 | if tx_block_height % 2 == 1: 35 | dict_node = dict(Direction='Left', TargetHash=target_hash_list[pos]) 36 | proof_node.append(dict_node) 37 | pos += 1 38 | elif tx_block_height < last_node: 39 | dict_node = dict(Direction='Right', TargetHash=target_hash_list[pos]) 40 | proof_node.append(dict_node) 41 | pos += 1 42 | tx_block_height //= 2 43 | last_node //= 2 44 | return proof_node 45 | 46 | @staticmethod 47 | def validate_proof(proof: List[dict], hex_target_hash: str, hex_merkle_root: str, is_big_endian: bool = False): 48 | if is_big_endian: 49 | hex_merkle_root = NeoData.to_reserve_hex_str(hex_merkle_root) 50 | hex_target_hash = NeoData.to_reserve_hex_str(hex_target_hash) 51 | if len(proof) == 0: 52 | return hex_target_hash == hex_merkle_root 53 | else: 54 | hex_proof_hash = hex_target_hash 55 | for node in proof: 56 | if is_big_endian: 57 | sibling = NeoData.to_reserve_hex_str(node['TargetHash']) 58 | else: 59 | sibling = node['TargetHash'] 60 | try: 61 | direction = node['Direction'].lower() 62 | except KeyError: 63 | raise SDKException(ErrorCode.other_error('Invalid proof')) 64 | if direction == 'left': 65 | value = bytes.fromhex('01' + sibling + hex_proof_hash) 66 | hex_proof_hash = Digest.sha256(value, is_hex=True) 67 | elif direction == 'right': 68 | value = bytes.fromhex('01' + hex_proof_hash + sibling) 69 | hex_proof_hash = Digest.sha256(value, is_hex=True) 70 | else: 71 | raise SDKException(ErrorCode.other_error('Invalid proof.')) 72 | return hex_proof_hash == hex_merkle_root 73 | -------------------------------------------------------------------------------- /ontology/merkle/tx_verifier.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import threading 20 | 21 | from ontology.merkle.merkle_verifier import MerkleVerifier 22 | 23 | 24 | class TxVerifier(object): 25 | _instance_lock = threading.Lock() 26 | 27 | def __init__(self, sdk): 28 | self.__sdk = sdk 29 | 30 | def __new__(cls, *args, **kwargs): 31 | if not hasattr(TxVerifier, '_instance'): 32 | with TxVerifier._instance_lock: 33 | if not hasattr(TxVerifier, '_instance'): 34 | TxVerifier._instance = object.__new__(cls) 35 | return TxVerifier._instance 36 | 37 | def verify_by_tx_hash(self, tx_hash: str): 38 | merkle_proof = self.__sdk.default_network.get_merkle_proof(tx_hash) 39 | tx_block_height = merkle_proof['BlockHeight'] 40 | current_block_height = merkle_proof['CurBlockHeight'] 41 | target_hash_list = merkle_proof['TargetHashes'] 42 | target_hash = merkle_proof['TransactionsRoot'] 43 | merkle_root = merkle_proof['CurBlockRoot'] 44 | proof_node = MerkleVerifier.get_proof(tx_block_height, target_hash_list, current_block_height) 45 | result = MerkleVerifier.validate_proof(proof_node, target_hash, merkle_root, True) 46 | return result 47 | -------------------------------------------------------------------------------- /ontology/network/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/service/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/service/service.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.claim.claim import Claim 20 | from ontology.sigsvr.sigsvr import SigSvr 21 | from ontology.claim.proof import BlockchainProof 22 | from ontology.merkle.tx_verifier import TxVerifier 23 | 24 | 25 | class Service(object): 26 | def __init__(self, sdk): 27 | self.__sdk = sdk 28 | self.__sig_svr = None 29 | self.__claim = None 30 | self.__tx_verifier = None 31 | self.__blockchain_proof = None 32 | 33 | def tx_verifier(self): 34 | if self.__tx_verifier is None: 35 | self.__tx_verifier = TxVerifier(self.__sdk) 36 | return self.__tx_verifier 37 | 38 | def blockchain_proof(self): 39 | if self.__blockchain_proof is None: 40 | self.__blockchain_proof = BlockchainProof(self.__sdk) 41 | return self.__blockchain_proof 42 | 43 | def claim(self): 44 | if self.__claim is None: 45 | self.__claim = Claim(self.__sdk) 46 | return self.__claim 47 | 48 | @property 49 | def sig_svr(self): 50 | if self.__sig_svr is None: 51 | self.__sig_svr = SigSvr() 52 | return self.__sig_svr 53 | -------------------------------------------------------------------------------- /ontology/sigsvr/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | -------------------------------------------------------------------------------- /ontology/sigsvr/sigsvr.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import json 20 | import platform 21 | 22 | import requests 23 | 24 | from sys import maxsize 25 | 26 | from Cryptodome.Random.random import randint 27 | 28 | from ontology.exception.error_code import ErrorCode 29 | from ontology.exception.exception import SDKException 30 | 31 | 32 | class SigSvr(object): 33 | def __init__(self, url: str = ''): 34 | self.__url = url 35 | self.__header = {'Content-type': 'application/json'} 36 | 37 | def set_address(self, url: str): 38 | self.__url = url 39 | 40 | def get_address(self): 41 | return self.__url 42 | 43 | def connect_to_localhost(self): 44 | self.set_address('http://localhost:20000/cli') 45 | 46 | def __post(self, method, b58_address: str or None, pwd: str or None, params): 47 | payload = dict(qid=str(randint(0, maxsize)), method=method, params=params) 48 | if isinstance(b58_address, str): 49 | payload['account'] = b58_address 50 | if isinstance(pwd, str): 51 | payload['pwd'] = pwd 52 | try: 53 | response = requests.post(self.__url, json=payload, headers=self.__header, timeout=10) 54 | except requests.exceptions.MissingSchema as e: 55 | raise SDKException(ErrorCode.connect_err(e.args[0])) from None 56 | except (requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError): 57 | raise SDKException(ErrorCode.other_error(''.join(['ConnectionError: ', self.__url]))) from None 58 | except requests.exceptions.ReadTimeout: 59 | raise SDKException(ErrorCode.other_error(''.join(['ReadTimeout: ', self.__url]))) from None 60 | try: 61 | content = response.content.decode('utf-8') 62 | except Exception as e: 63 | raise SDKException(ErrorCode.other_error(e.args[0])) from None 64 | if response.status_code != 200: 65 | raise SDKException(ErrorCode.other_error(content)) 66 | try: 67 | content = json.loads(content) 68 | except json.decoder.JSONDecodeError as e: 69 | raise SDKException(ErrorCode.other_error(e.args[0])) from None 70 | if content['error_code'] != 0: 71 | if content['error_info'] != '': 72 | raise SDKException(ErrorCode.other_error(content['error_info'])) 73 | else: 74 | raise SDKException(ErrorCode.other_error(content['result'])) 75 | return content 76 | 77 | def create_account(self, pwd: str, is_full: bool = False) -> dict or str: 78 | response = self.__post('createaccount', None, pwd, dict()) 79 | if is_full: 80 | return response 81 | return response['result'] 82 | 83 | def export_account(self, wallet_path: str = '', is_full: bool = False) -> dict or str: 84 | params = dict() 85 | if len(wallet_path) != 0: 86 | params['wallet_path'] = wallet_path 87 | response = self.__post('exportaccount', None, None, params) 88 | if 'Windows' in platform.platform(): 89 | response['result']['wallet_file'] = response['result']['wallet_file'].replace('/', '\\') 90 | if is_full: 91 | return response 92 | return response['result'] 93 | 94 | def sig_data(self, hex_data: str, b58_address: str, pwd: str, is_full: bool = False) -> dict or str: 95 | params = dict(raw_data=hex_data) 96 | response = self.__post('sigdata', b58_address, pwd, params) 97 | if is_full: 98 | return response 99 | return response['result'] 100 | -------------------------------------------------------------------------------- /ontology/utils/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/utils/arguments.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from functools import wraps 20 | from inspect import signature 21 | 22 | from ontology.common.define import DID_ONT 23 | from ontology.exception.error_code import ErrorCode 24 | from ontology.exception.exception import SDKException 25 | 26 | 27 | def check_ont_id(func): 28 | if __debug__ is False: 29 | return func 30 | 31 | sig = signature(func) 32 | 33 | @wraps(func) 34 | def wrapper(*args, **kwargs): 35 | bound_values = sig.bind(*args, **kwargs) 36 | ont_id = bound_values.arguments.get('ont_id') 37 | if not isinstance(ont_id, str): 38 | raise SDKException(ErrorCode.require_str_params) 39 | if not ont_id.startswith(DID_ONT): 40 | raise SDKException(ErrorCode.invalid_ont_id_format(ont_id)) 41 | return func(*args, **kwargs) 42 | 43 | return wrapper 44 | 45 | 46 | def type_assert(*ty_args, **ty_kwargs): 47 | def decorate(func): 48 | if __debug__ is False: 49 | return func 50 | sig = signature(func) 51 | bound_types = sig.bind_partial(*ty_args, **ty_kwargs).arguments 52 | 53 | @wraps(func) 54 | def wrapper(*args, **kwargs): 55 | bound_values = sig.bind(*args, **kwargs) 56 | for name, value in bound_values.arguments.items(): 57 | if name in bound_types: 58 | type_name = bound_types[name] 59 | if not isinstance(value, type_name): 60 | raise SDKException(ErrorCode.params_type_error(f'the type of parameter should be {type_name}')) 61 | return func(*args, **kwargs) 62 | 63 | return wrapper 64 | 65 | return decorate 66 | -------------------------------------------------------------------------------- /ontology/utils/crypto.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from typing import Union 20 | 21 | 22 | def to_bytes(s: Union[bytes, str]) -> bytes: 23 | if isinstance(s, bytes): 24 | return s 25 | elif isinstance(s, str): 26 | return s.encode('latin-1') 27 | else: 28 | return bytes(list(s)) 29 | -------------------------------------------------------------------------------- /ontology/utils/transaction.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from typing import Union 20 | 21 | from ontology.common.address import Address 22 | from ontology.account.account import Account 23 | from ontology.exception.error_code import ErrorCode 24 | from ontology.exception.exception import SDKException 25 | 26 | 27 | def ensure_bytearray_contract_address(contract_address: Union[str, bytes, bytearray, Address]) -> bytearray: 28 | if isinstance(contract_address, str) and len(contract_address) == 40: 29 | contract_address = bytearray.fromhex(contract_address) 30 | contract_address.reverse() 31 | if isinstance(contract_address, bytes): 32 | contract_address = bytearray(contract_address) 33 | elif isinstance(contract_address, Address): 34 | contract_address = contract_address.to_bytearray() 35 | elif isinstance(contract_address, bytearray): 36 | pass 37 | else: 38 | raise SDKException(ErrorCode.params_type_error('Invalid type of contract address.')) 39 | return contract_address 40 | 41 | 42 | def ensure_bytes_address(*objs: str or bytes or Account): 43 | result = list() 44 | for obj in objs: 45 | if isinstance(obj, bytes): 46 | result.append(obj) 47 | elif isinstance(obj, str): 48 | result.append(Address.b58decode(obj).to_bytes()) 49 | elif isinstance(obj, Account): 50 | result.append(obj.get_address_bytes()) 51 | else: 52 | raise SDKException(ErrorCode.param_error) 53 | return tuple(result) 54 | -------------------------------------------------------------------------------- /ontology/utils/utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from Cryptodome import Random 20 | 21 | 22 | def get_random_bytes(length: int) -> bytes: 23 | """ 24 | This interface is used to get a random byte string of the desired length. 25 | 26 | :param length: the desired length of a random byte string. 27 | :return: a random byte string of the desired length. 28 | """ 29 | return Random.get_random_bytes(length) 30 | 31 | 32 | def get_random_hex_str(length: int) -> str: 33 | """ 34 | 35 | :param length: 36 | :return: a random hexadecimal string of the desired length. 37 | """ 38 | return Random.get_random_bytes(length).hex()[:length] 39 | 40 | 41 | def hex_to_bytes(value: str) -> bytearray: 42 | return bytearray.fromhex(value) 43 | 44 | 45 | def to_array_reverse(arr: bytearray) -> bytearray: 46 | bytearray.reverse(arr) 47 | return arr 48 | 49 | 50 | def bytes_reader(b): 51 | res = bytearray() 52 | for i in range(len(b) // 2): 53 | res += bytearray.fromhex(b[2 * i:2 * i + 2].decode()) 54 | return res 55 | -------------------------------------------------------------------------------- /ontology/utils/wasm.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from typing import Union 20 | 21 | from ontology.common.address import Address 22 | from ontology.contract.wasm.params_builder import WasmParamsBuilder 23 | 24 | 25 | class WasmData(object): 26 | @staticmethod 27 | def to_int(value: Union[str, bytes]): 28 | if isinstance(value, str): 29 | value = bytes.fromhex(value) 30 | return int.from_bytes(value, byteorder='little', signed=True) 31 | 32 | @staticmethod 33 | def detect_to_utf8(value: Union[str, bytes]): 34 | if isinstance(value, str): 35 | value = bytes.fromhex(value) 36 | builder = WasmParamsBuilder(value) 37 | return builder.pop_str() 38 | 39 | @staticmethod 40 | def to_utf8(value: Union[str, bytes]): 41 | if isinstance(value, str): 42 | value = bytes.fromhex(value) 43 | return value.decode('utf-8') 44 | 45 | @staticmethod 46 | def to_b58_address(value: Union[str, bytes]) -> str: 47 | if isinstance(value, str): 48 | value = bytes.fromhex(value) 49 | return Address(value).b58encode() 50 | -------------------------------------------------------------------------------- /ontology/vm/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/vm/build_params.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from enum import Enum 20 | from typing import List 21 | 22 | from ontology.contract.neo.abi.abi_function import AbiFunction 23 | from ontology.contract.neo.params_builder import NeoParamsBuilder 24 | from ontology.contract.wasm.params_builder import WasmParamsBuilder 25 | 26 | 27 | class BuildParams(object): 28 | class Type(Enum): 29 | bytearray_type = 0x00 30 | bool_type = 0x01 31 | int_type = 0x02 32 | array_type = 0x80 33 | struct_type = 0x81 34 | dict_type = 0x82 35 | 36 | @staticmethod 37 | def serialize_abi_function(abi_func: AbiFunction): 38 | param_list = list() 39 | param_list.append(bytes(abi_func.name.encode('utf-8'))) 40 | temp_list = list() 41 | for param in abi_func.parameters: 42 | try: 43 | if isinstance(param.value, list): 44 | temp_param_list = [] 45 | for item in param.value: 46 | if isinstance(item, list): 47 | temp_list.append(item) 48 | else: 49 | temp_param_list.append(item) 50 | if len(temp_param_list) != 0: 51 | temp_list.append(temp_param_list) 52 | else: 53 | temp_list.append(param.value) 54 | except AttributeError: 55 | pass 56 | param_list.append(temp_list) 57 | return BuildParams.create_neo_vm_invoke_code(param_list) 58 | 59 | @staticmethod 60 | def create_neo_vm_invoke_code(param_list: List) -> bytearray: 61 | builder = NeoParamsBuilder() 62 | length = len(param_list) 63 | for j in range(length): 64 | i = length - 1 - j 65 | builder.push_vm_param(param_list[i]) 66 | return builder.to_bytearray() 67 | 68 | @staticmethod 69 | def create_wasm_vm_invoke_code(param_list: List) -> bytearray: 70 | builder = WasmParamsBuilder() 71 | for param in param_list: 72 | builder.push_vm_param(param) 73 | return builder.pack_as_bytearray() 74 | -------------------------------------------------------------------------------- /ontology/vm/build_vm.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.vm.op_code import * 20 | from ontology.common.address import Address 21 | from ontology.exception.error_code import ErrorCode 22 | from ontology.exception.exception import SDKException 23 | from ontology.contract.neo.params_builder import NeoParamsBuilder 24 | 25 | 26 | def build_native_invoke_code(contract_address: bytes, version: bytes, method: str, params): 27 | builder = NeoParamsBuilder() 28 | build_neo_vm_param(builder, params) 29 | builder.push_bytearray(method.encode()) 30 | builder.push_bytearray(contract_address) 31 | builder.push_int(int.from_bytes(version, 'little')) 32 | builder.emit(SYSCALL) 33 | builder.push_bytearray(b'Ontology.Native.Invoke') 34 | return builder.to_bytes() 35 | 36 | 37 | def build_neo_vm_param(builder, params): 38 | if isinstance(params, dict): 39 | builder.push_int(0) 40 | builder.emit(NEWSTRUCT) 41 | builder.emit(TOALTSTACK) 42 | for i in params.values(): 43 | build_neo_vm_param(builder, i) 44 | builder.emit(DUPFROMALTSTACK) 45 | builder.emit(SWAP) 46 | builder.emit(APPEND) 47 | builder.emit(FROMALTSTACK) 48 | elif isinstance(params, str): 49 | builder.push_bytearray(params.encode('utf-8')) 50 | elif isinstance(params, bytes): 51 | builder.push_bytearray(params) 52 | elif isinstance(params, bytearray): 53 | builder.push_bytearray(params) 54 | elif isinstance(params, int): 55 | builder.push_int(params) 56 | elif isinstance(params, Address): 57 | builder.push_bytearray(params.to_bytes()) 58 | elif isinstance(params, list): 59 | for p in params: 60 | build_neo_vm_param(builder, p) 61 | builder.push_int(len(params)) 62 | builder.emit(PACK) 63 | else: 64 | raise SDKException(ErrorCode.param_error) 65 | -------------------------------------------------------------------------------- /ontology/vm/vm_type.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from enum import IntEnum, unique 20 | 21 | from ontology.exception.error_code import ErrorCode 22 | 23 | from ontology.exception.exception import SDKException 24 | 25 | 26 | @unique 27 | class VmType(IntEnum): 28 | Neo = 1 29 | Wasm = 3 30 | 31 | @classmethod 32 | def from_int(cls, value: int): 33 | if value == 1: 34 | return cls.Neo 35 | if value == 3: 36 | return cls.Wasm 37 | raise SDKException(ErrorCode.unknown_vm_type) 38 | -------------------------------------------------------------------------------- /ontology/wallet/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | -------------------------------------------------------------------------------- /ontology/wallet/account_info.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | class AccountInfo: 20 | def __init__(self): 21 | self.address_base58 = '' 22 | self.public_key = '' 23 | self.encrypted_pri_key = '' 24 | self.address_u160 = '' 25 | self.private_key = '' 26 | self.pri_key_wif = '' 27 | -------------------------------------------------------------------------------- /ontology/wallet/control.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from ontology.exception.error_code import ErrorCode 20 | from ontology.exception.exception import SDKException 21 | 22 | 23 | class Control(object): 24 | def __init__(self, kid: str = '', address='', enc_alg="aes-256-gcm", key='', algorithm='ECDSA', salt='', param=None, 25 | hash_value='sha256', public_key=''): 26 | if param is None: 27 | param = dict(curve='P-256') 28 | if not isinstance(kid, str): 29 | raise SDKException(ErrorCode.require_str_params) 30 | self.__address = address 31 | self.algorithm = algorithm 32 | self.enc_alg = enc_alg 33 | self.hash = hash_value 34 | self.__kid = kid 35 | self.__key = key 36 | self.parameters = param 37 | self.__salt = salt 38 | self.__public_key = public_key 39 | 40 | def __iter__(self): 41 | data = dict() 42 | data['address'] = self.__address 43 | data['algorithm'] = self.algorithm 44 | data['enc-alg'] = self.enc_alg 45 | data['hash'] = self.hash 46 | data['id'] = self.__kid 47 | data['key'] = self.key 48 | data['parameters'] = self.parameters 49 | data['salt'] = self.__salt 50 | data['publicKey'] = self.__public_key 51 | for key, value in data.items(): 52 | yield (key, value) 53 | 54 | @property 55 | def kid(self): 56 | return self.__kid 57 | 58 | @kid.setter 59 | def kid(self, kid: str): 60 | if not isinstance(kid, str): 61 | raise SDKException(ErrorCode.require_str_params) 62 | self.__kid = kid 63 | 64 | @property 65 | def key(self): 66 | return self.__key 67 | 68 | @key.setter 69 | def key(self, key: str): 70 | if not isinstance(key, str): 71 | raise SDKException(ErrorCode.require_str_params) 72 | self.__key = key 73 | 74 | @property 75 | def b58_address(self): 76 | return self.__address 77 | 78 | @b58_address.setter 79 | def b58_address(self, b58_address: str): 80 | if not isinstance(b58_address, str): 81 | raise SDKException(ErrorCode.require_str_params) 82 | self.__address = b58_address 83 | 84 | @property 85 | def public_key(self): 86 | return self.__public_key 87 | 88 | @public_key.setter 89 | def public_key(self, b64_pub_key: str): 90 | if not isinstance(b64_pub_key, str): 91 | raise SDKException(ErrorCode.other_error('Invalid public key.')) 92 | self.__public_key = b64_pub_key 93 | 94 | @property 95 | def salt(self): 96 | return self.__salt 97 | 98 | @salt.setter 99 | def salt(self, salt: str): 100 | if not isinstance(salt, str): 101 | raise SDKException(ErrorCode.require_str_params) 102 | self.__salt = salt 103 | -------------------------------------------------------------------------------- /ontology/wallet/identity.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | from typing import List 20 | 21 | from ontology.common.define import DID_ONT 22 | from ontology.wallet.control import Control 23 | from ontology.exception.error_code import ErrorCode 24 | from ontology.exception.exception import SDKException 25 | 26 | 27 | class Identity(object): 28 | def __init__(self, ont_id: str = '', label: str = '', lock: bool = False, controls: List[Control] = None, 29 | is_default=False): 30 | if controls is None: 31 | controls = list() 32 | if not isinstance(ont_id, str): 33 | raise SDKException(ErrorCode.require_str_params) 34 | if len(ont_id) != 0 and not ont_id.startswith(DID_ONT): 35 | raise SDKException(ErrorCode.invalid_ont_id_format(ont_id)) 36 | self.__ont_id = ont_id 37 | self.label = label 38 | self.lock = lock 39 | self.__controls = controls 40 | self.is_default = is_default 41 | 42 | def __iter__(self): 43 | data = dict() 44 | data['ontid'] = self.__ont_id 45 | data['label'] = self.label 46 | data['lock'] = self.lock 47 | data['controls'] = list() 48 | for ctrl in self.__controls: 49 | data['controls'].append(dict(ctrl)) 50 | data['isDefault'] = self.is_default 51 | for key, value in data.items(): 52 | yield (key, value) 53 | 54 | @property 55 | def ont_id(self): 56 | return self.__ont_id 57 | 58 | @ont_id.setter 59 | def ont_id(self, ont_id: str): 60 | if not isinstance(ont_id, str): 61 | raise SDKException(ErrorCode.require_str_params) 62 | if len(ont_id) != 0 and not ont_id.startswith(DID_ONT): 63 | raise SDKException(ErrorCode.invalid_ont_id_format(ont_id)) 64 | self.__ont_id = ont_id 65 | 66 | @property 67 | def controls(self): 68 | return self.__controls 69 | 70 | @controls.setter 71 | def controls(self, ctrl_lst: List[Control]): 72 | if not isinstance(ctrl_lst, list): 73 | raise SDKException(ErrorCode.require_list_params) 74 | for ctrl in ctrl_lst: 75 | if not isinstance(ctrl, Control): 76 | raise SDKException(ErrorCode.require_control_params) 77 | self.__controls = ctrl_lst 78 | 79 | def add_control(self, ctrl: Control): 80 | if not isinstance(ctrl, Control): 81 | raise SDKException(ErrorCode.require_control_params) 82 | index = int(self.__controls[-1].kid.split('-')[1]) 83 | index += 1 84 | ctrl.kid = f'keys-{index}' 85 | self.__controls.append(ctrl) 86 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ontio/ontology-python-sdk/ebe3dcb7fe4148b131f79bfc46d70b4359263316/requirements.txt -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Copyright (C) 2018-2019 The ontology Authors 6 | This file is part of The ontology library. 7 | 8 | The ontology is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU Lesser General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | The ontology is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with The ontology. If not, see . 20 | """ 21 | 22 | import codecs 23 | 24 | from os import path, getcwd 25 | from setuptools import setup, find_packages 26 | 27 | with codecs.open(path.join(getcwd(), 'README.md')) as f: 28 | long_description = f.read() 29 | 30 | setup( 31 | name='ontology-python-sdk', 32 | version='2.1.0.RC4', 33 | description='Comprehensive Python library for the Ontology BlockChain.', 34 | long_description=long_description, 35 | long_description_content_type="text/markdown", 36 | author='Ontology', 37 | author_email='contact@ont.io', 38 | maintainer='NashMiao', 39 | maintainer_email='wdx7266@outlook.com', 40 | license='GNU Lesser General Public License v3 (LGPLv3)', 41 | packages=find_packages(exclude=['test_*.py', 'tests']), 42 | install_requires=[ 43 | 'aiohttp>=3.5.4', 44 | 'base58>=1.0.3', 45 | 'cryptography>=2.6.1', 46 | 'ecdsa>=0.13', 47 | 'mnemonic>=0.18', 48 | 'pycryptodomex>=3.7', 49 | 'requests>=2.21.0', 50 | 'websockets>=7.0' 51 | ], 52 | python_requires='>=3.6', 53 | platforms=["all"], 54 | url='https://github.com/ontio/ontology-python-sdk', 55 | classifiers=[ 56 | 'Development Status :: 4 - Beta', 57 | 'Operating System :: OS Independent', 58 | 'Intended Audience :: Developers', 59 | 'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)', 60 | 'Programming Language :: Python :: 3.6', 61 | 'Programming Language :: Python :: 3.7', 62 | 'Programming Language :: Python :: 3.8', 63 | ], 64 | ) 65 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Copyright (C) 2018-2019 The ontology Authors 6 | This file is part of The ontology library. 7 | 8 | The ontology is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU Lesser General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | The ontology is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with The ontology. If not, see . 20 | """ 21 | 22 | from os import path, environ 23 | 24 | from ontology.exception.exception import SDKException 25 | from ontology.sdk import Ontology 26 | 27 | sdk = Ontology() 28 | sdk.rpc.connect_to_test_net() 29 | sdk.aio_rpc.connect_to_test_net() 30 | sdk.restful.connect_to_test_net() 31 | sdk.aio_restful.connect_to_test_net() 32 | sdk.websocket.connect_to_test_net() 33 | 34 | password = environ['SDK_TEST_PASSWORD'] 35 | wallet_path = path.join(path.dirname(__file__), 'test_wallet.json') 36 | wallet_manager = sdk.wallet_manager 37 | wallet_manager.open_wallet(wallet_path, is_create=False) 38 | acct1 = wallet_manager.get_account_by_b58_address('ANDfjwrUroaVtvBguDtrWKRMyxFwvVwnZD', password) 39 | acct2 = wallet_manager.get_account_by_b58_address('Af1n2cZHhMZumNqKgw9sfCNoTWu9de4NDn', password) 40 | acct3 = wallet_manager.get_account_by_b58_address('AXJZrP1jBRo398ebfyemsDxDaThsxcXGMk', password) 41 | acct4 = wallet_manager.get_account_by_b58_address('APvHaLmJUMdAHiVbFHGi11gnFpuK6ozD5j', password) 42 | ont_id_1 = 'did:ont:ANDfjwrUroaVtvBguDtrWKRMyxFwvVwnZD' 43 | identity1 = wallet_manager.get_identity_by_ont_id(ont_id_1) 44 | identity1_ctrl_acct = wallet_manager.get_control_account_by_index(ont_id_1, 0, password) 45 | ont_id_2 = 'did:ont:AP8XfCUo7w3qM4b5gyQU8AEyRSwgtDFSzp' 46 | identity2 = wallet_manager.get_identity_by_ont_id(ont_id_2) 47 | identity2_ctrl_acct = wallet_manager.get_control_account_by_index(ont_id_2, 0, password) 48 | wallet_manager.save() 49 | 50 | not_panic = ['balance insufficient', 'ConnectionError', 'unknown transaction', 'Notify not found in {}'] 51 | 52 | 53 | def not_panic_exception(func): 54 | def wrapper(*args, **kwargs): 55 | try: 56 | func(*args, **kwargs) 57 | except SDKException as e: 58 | if not any(x in e.args[1] for x in not_panic): 59 | raise e 60 | 61 | return wrapper 62 | -------------------------------------------------------------------------------- /tests/cyano_wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"1c35d553-ff15-4d31-976c-6a76d995e289", 3 | "defaultOntid":"", 4 | "defaultAccountAddress":"ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6", 5 | "createTime":"2018-09-06T02:59:04.326Z", 6 | "version":"1.0", 7 | "scrypt":{ 8 | "n":4096, 9 | "r":8, 10 | "p":8, 11 | "dkLen":64 12 | }, 13 | "identities":[], 14 | "accounts":[ 15 | { 16 | "address":"ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6", 17 | "isDefault":false, 18 | "label":"9a95379b-84d4-4b90-bb87-9531f152c41d", 19 | "lock":false, 20 | "algorithm":"ECDSA", 21 | "parameters":{ 22 | "curve":"P-256" 23 | }, 24 | "key":"T7CPOClm9+HRnqw0qiTBFAtnhfuaW681kqhm0+00WRmWv96FzOZPp2R0qMKUu1E5", 25 | "enc-alg":"aes-256-gcm", 26 | "salt":"xZ1hFY4dafDe0lH7ootcbQ==", 27 | "publicKey":"03036c12be3726eb283d078dff481175e96224f0b0c632c7a37e10eb40fe6be889", 28 | "signatureScheme":"SHA256withECDSA" 29 | } 30 | ], 31 | "extra":null 32 | } -------------------------------------------------------------------------------- /tests/test_abi_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Copyright (C) 2018-2019 The ontology Authors 6 | This file is part of The ontology library. 7 | 8 | The ontology is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU Lesser General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | The ontology is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with The ontology. If not, see . 20 | """ 21 | 22 | import json 23 | import unittest 24 | 25 | from ontology.contract.neo.abi.abi_info import AbiInfo 26 | 27 | 28 | class TestAbiInfo(unittest.TestCase): 29 | def setUp(self): 30 | self.func_name = 'Hello' 31 | str_abi = '{"hash":"0x362cb5608b3eca61d4846591ebb49688900fedd0","entrypoint":"Main","functions":' \ 32 | '[{"name":"Main","parameters":[{"name":"operation","type":"String"},{"name":"args",' \ 33 | '"type":"Array"}],"returntype":"Any"},{"name":"Hello","parameters":[{"name":"msg",' \ 34 | '"type":"String"}],"returntype":"Void"}],"events":[]}' 35 | dict_abi = json.loads(str_abi) 36 | self.abi_info = AbiInfo(dict_abi['hash'], dict_abi['entrypoint'], dict_abi['functions'], dict_abi['events']) 37 | 38 | def test_init(self): 39 | self.assertTrue(isinstance(self.abi_info, AbiInfo)) 40 | 41 | def test_get_function(self): 42 | func = self.abi_info.get_function(self.func_name) 43 | self.assertEqual(self.func_name, func.name) 44 | 45 | def test_set_params_value(self): 46 | func = self.abi_info.get_function(self.func_name) 47 | func.set_params_value('Value') 48 | self.assertEqual('Value', func.parameters[0].value) 49 | 50 | def test_get_parameter(self): 51 | func = self.abi_info.get_function(self.func_name) 52 | func.set_params_value('Value') 53 | param_name = 'msg' 54 | parameter = func.get_parameter(param_name) 55 | self.assertEqual(param_name, parameter.name) 56 | self.assertEqual('String', parameter.type) 57 | self.assertEqual('Value', parameter.value) 58 | 59 | 60 | if __name__ == '__main__': 61 | unittest.main() 62 | -------------------------------------------------------------------------------- /tests/test_address.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.crypto.hd_public_key import HDPublicKey 22 | from tests import sdk 23 | 24 | from ontology.utils import utils 25 | from ontology.common.address import Address 26 | 27 | 28 | class TestAddress(unittest.TestCase): 29 | def setUp(self): 30 | self.bip32_pubkey = b'xpub6CbjoChWbA9TdLQKghCH5GzRrvjPxTiz6kYkW3frXyyN6vfbR7wGkYqd9jyEqkpYRe33oe5sQbamndiWQjc' \ 31 | b'9X3mr29HdKWqgjwb6G3xYXFo' 32 | 33 | def test_address_from_vm_code(self): 34 | code = '55c56b6a00527ac46a51527ac46a00c30548656c6c6f7d9c7c756419006a51c300c36a52527ac46a52c3650d006c7' \ 35 | '566620300006c756652c56b6a00527ac46a00c3681553797374656d2e52756e74696d652e4e6f74696679516c7566' 36 | contract_address = 'f2b6efc3e4360e69b8ff5db8ce8ac73651d07a12' 37 | self.assertEqual(contract_address, sdk.neo_vm.address_from_avm_code(code).hex()) 38 | 39 | def test_b58decode(self): 40 | length = 20 41 | rand_code = utils.get_random_bytes(length) 42 | address = Address(rand_code) 43 | b58_address = address.b58encode() 44 | zero = Address.b58decode(b58_address).to_bytes() 45 | self.assertEqual(rand_code, zero) 46 | decode_address = Address.b58decode(b58_address).to_bytes() 47 | self.assertEqual(rand_code, decode_address) 48 | 49 | def test_from_hd_pubkey(self): 50 | hd_pub_key = HDPublicKey.b58decode(self.bip32_pubkey) 51 | address = Address.from_hd_public_key(hd_pub_key) 52 | self.assertEqual('AW8Tf5R4kyURy6LQ8Th181Z5GpTovWGLg6', address.b58encode()) 53 | child_address_lst = ['ARXRQog4iZazp5YfXRyDZvU6ahrt3c2bb7', 'APXh8MqcARUgafqvUNnpECzwKDtipkf3Zr', 54 | 'ASpmd1MpFSpQ5rhicjRDqBpE1inP3Z7tus', 'APA3M4BRqjBsHXRkeTFiFVb4X1u8FiEgAr', 55 | 'AKq5SBTCzHBaqWWDUTGvekbsNJKKtf4ff5', 'APzMnHqrGF1cGZyAdFCwEL29TnAgCuBrY6', 56 | 'AJ8LEkLGeNsWvVrP7SgK9szoZ1MGgUTq1s', 'AJo49LSK6rQEwc6qTYMsAZmvLPRrb6qcWa', 57 | 'AYzCcNY3PwV432iXVREpDHvpX166KN45xP', 'AbL1wvGCnbzywHBuX1VwQev8xuhJxbPE4P'] 58 | for index, child_address in enumerate(child_address_lst): 59 | child_pks = HDPublicKey.from_path(hd_pub_key, f'0/{index}') 60 | address = Address.from_hd_public_key(child_pks[-1]) 61 | self.assertEqual(child_address, address.b58encode()) 62 | 63 | 64 | if __name__ == '__main__': 65 | unittest.main() 66 | -------------------------------------------------------------------------------- /tests/test_aes_handler.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from Cryptodome import Random 22 | from Cryptodome.Cipher import AES 23 | 24 | from ontology.crypto.aes_handler import AESHandler 25 | 26 | 27 | class TestAesHandler(unittest.TestCase): 28 | def test_aes_cbc(self): 29 | key = b'Sixteen byte key' 30 | plain_text = b'Attack at dawn' 31 | iv, cipher_text = AESHandler.aes_cbc_encrypt(plain_text, key) 32 | decrypt_out = AESHandler.aes_cbc_decrypt(cipher_text, iv, key) 33 | self.assertEqual(plain_text, decrypt_out) 34 | 35 | def test_aes_gcm(self): 36 | key = b'Sixteen byte key' 37 | plain_text = b'Attack at dawn' 38 | hdr = b'To your eyes only' 39 | nonce, mac, cipher_text = AESHandler.aes_gcm_encrypt(plain_text, hdr, key) 40 | decrypt_out = AESHandler.aes_gcm_decrypt(cipher_text, hdr, nonce, mac, key) 41 | self.assertEqual(plain_text, decrypt_out) 42 | 43 | def test_aes_gcm_with_iv(self): 44 | key = b'Sixteen byte key' 45 | plain_text = b'Attack at dawn' 46 | hdr = b'To your eyes only' 47 | iv = Random.new().read(AES.block_size) 48 | mac, cipher_text = AESHandler.aes_gcm_encrypt_with_iv(plain_text, hdr, key, iv) 49 | decrypt_out = AESHandler.aes_gcm_decrypt_with_iv(cipher_text, hdr, mac, key, iv) 50 | self.assertEqual(plain_text, decrypt_out) 51 | 52 | def test_aes_gcm_with_iv_wrong_iv(self): 53 | key = b'Sixteen byte key' 54 | plain_text = b'Attack at dawn' 55 | hdr = b'To your eyes only' 56 | iv = Random.new().read(AES.block_size) 57 | mac, cipher_text = AESHandler.aes_gcm_encrypt_with_iv(plain_text, hdr, key, iv) 58 | iv = Random.new().read(AES.block_size) 59 | decrypt_out = AESHandler.aes_gcm_decrypt_with_iv(cipher_text, hdr, mac, key, iv) 60 | self.assertNotEqual(plain_text, decrypt_out) 61 | 62 | def test_aes_ctr(self): 63 | key = b'Sixteen byte key' 64 | plain_text = b'Attack at dawn' 65 | nonce, cipher_text = AESHandler.aes_ctr_encrypt(plain_text, key) 66 | decrypt_out = AESHandler.aes_ctr_decrypt(cipher_text, nonce, key) 67 | self.assertEqual(plain_text, decrypt_out) 68 | 69 | 70 | if __name__ == '__main__': 71 | unittest.main() 72 | -------------------------------------------------------------------------------- /tests/test_binary_reader.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.io.binary_reader import BinaryReader 22 | from ontology.io.binary_writer import BinaryWriter 23 | from ontology.io.memory_stream import StreamManager 24 | 25 | 26 | class TestBinaryReader(unittest.TestCase): 27 | def test_read_var_int(self): 28 | value = 123 29 | writer_stream = StreamManager.get_stream() 30 | writer = BinaryWriter(writer_stream) 31 | writer.write_var_int(value) 32 | reader_stream = StreamManager.get_stream(writer_stream.getbuffer()) 33 | reader = BinaryReader(reader_stream) 34 | self.assertEqual(reader.read_var_int(), value) 35 | 36 | 37 | if __name__ == '__main__': 38 | unittest.main() 39 | -------------------------------------------------------------------------------- /tests/test_binary_writer.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.io.binary_writer import BinaryWriter 22 | 23 | from ontology.io.memory_stream import StreamManager 24 | 25 | 26 | class TestBinaryWriter(unittest.TestCase): 27 | def setUp(self): 28 | self.stream = StreamManager.get_stream() 29 | self.writer = BinaryWriter(self.stream) 30 | 31 | def test_write_byte(self): 32 | values = [15, 255, 'a', 'z', b'a', 'byte'] 33 | results = [b'0f', b'ff', b'61', b'7a', b'61', b'62'] 34 | for i, v in enumerate(values): 35 | self.writer.write_byte(v) 36 | self.assertEqual(results[i], self.stream.hexlify()) 37 | self.stream.clean_up() 38 | 39 | def test_write_uint8(self): 40 | values = [15, 255, 15, 255] 41 | results = [b'0f', b'ff', b'0f', b'ff'] 42 | little_endian_lst = [True, True, False, False] 43 | for i, v in enumerate(values): 44 | self.writer.write_uint8(v, little_endian=little_endian_lst[i]) 45 | self.assertEqual(results[i], self.stream.hexlify()) 46 | self.stream.clean_up() 47 | 48 | 49 | if __name__ == '__main__': 50 | unittest.main() 51 | -------------------------------------------------------------------------------- /tests/test_claim_record.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | from time import time, sleep 21 | 22 | from ontology.exception.exception import SDKException 23 | from tests import sdk, identity1, identity2, identity2_ctrl_acct, acct1, not_panic_exception 24 | 25 | 26 | class TestClaimRecord(unittest.TestCase): 27 | def setUp(self): 28 | self.gas_price = 500 29 | self.gas_limit = 20000 30 | 31 | @staticmethod 32 | def generate_claim(): 33 | pub_keys = sdk.native_vm.ont_id().get_public_keys(identity1.ont_id) 34 | try: 35 | pk = pub_keys[0] 36 | kid = pk['PubKeyId'] 37 | except IndexError: 38 | kid = '03d0fdb54acba3f81db3a6e16fa02e7ea3678bd205eb4ed2f1cfa8ab5e5d45633e#keys-1' 39 | iss_ont_id = identity2.ont_id 40 | sub_ont_id = identity1.ont_id 41 | exp = int(time()) + 100 42 | context = 'https://github.com/NashMiao' 43 | clm = dict(Name='NashMiao', Position='Mars', Birthday=str(time())) 44 | clm_rev = dict(type='AttestContract', addr='8055b362904715fd84536e754868f4c8d27ca3f6') 45 | 46 | claim = sdk.service.claim() 47 | claim.set_claim(kid, iss_ont_id, sub_ont_id, exp, context, clm, clm_rev) 48 | try: 49 | claim.generate_signature(identity2_ctrl_acct) 50 | except SDKException as e: 51 | if 'get key failed' or 'ConnectionError' not in e.args[1]: 52 | raise e 53 | claim.generate_signature(identity2_ctrl_acct, verify_kid=False) 54 | return claim 55 | 56 | def query_commit_event_create_test_case(self, tx_hash: str, claim_id: str): 57 | event = sdk.neo_vm.claim_record().query_commit_event(tx_hash) 58 | self.assertEqual('Push', event['States'][0]) 59 | self.assertEqual(identity2_ctrl_acct.get_address_base58(), event['States'][1]) 60 | self.assertEqual(' create new claim: ', event['States'][2]) 61 | self.assertEqual(claim_id, event['States'][3]) 62 | 63 | def query_commit_event_exist_test_case(self, tx_hash: str, claim_id: str): 64 | event = sdk.neo_vm.claim_record().query_commit_event(tx_hash) 65 | self.assertEqual('ErrorMsg', event['States'][0]) 66 | self.assertEqual(claim_id, event['States'][1]) 67 | self.assertEqual(' existed!', event['States'][2]) 68 | 69 | def query_revoke_event_test_case(self, tx_hash: str, claim_id: str): 70 | event = sdk.neo_vm.claim_record().query_revoke_event(tx_hash) 71 | self.assertEqual('Push', event['States'][0]) 72 | self.assertEqual(identity2_ctrl_acct.get_address_base58(), event['States'][1]) 73 | self.assertEqual(' revoke claim: ', event['States'][2]) 74 | self.assertEqual(claim_id, event['States'][3]) 75 | 76 | @not_panic_exception 77 | def test_claim_record(self): 78 | claim = self.generate_claim() 79 | status = sdk.neo_vm.claim_record().get_status(claim.claim_id) 80 | self.assertFalse(status) 81 | record = sdk.neo_vm.claim_record() 82 | 83 | tx_hash = record.commit(claim.claim_id, identity2_ctrl_acct, identity1.ont_id, acct1, self.gas_price, 84 | self.gas_limit) 85 | sleep(12) 86 | self.query_commit_event_create_test_case(tx_hash, claim.claim_id) 87 | 88 | status = record.get_status(claim.claim_id) 89 | self.assertTrue(status) 90 | 91 | tx_hash = record.commit(claim.claim_id, identity2_ctrl_acct, identity1.ont_id, acct1, self.gas_price, 92 | self.gas_limit) 93 | sleep(12) 94 | self.query_commit_event_exist_test_case(tx_hash, claim.claim_id) 95 | 96 | tx_hash = record.revoke(claim.claim_id, identity2_ctrl_acct, acct1, self.gas_price, self.gas_limit) 97 | sleep(12) 98 | self.query_revoke_event_test_case(tx_hash, claim.claim_id) 99 | 100 | status = record.get_status(claim.claim_id) 101 | self.assertFalse(status) 102 | 103 | 104 | if __name__ == '__main__': 105 | unittest.main() 106 | -------------------------------------------------------------------------------- /tests/test_contract_data_parser.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.utils.neo import NeoData 22 | from ontology.contract.neo.params_builder import NeoParamsBuilder 23 | 24 | 25 | class TestContractDataParser(unittest.TestCase): 26 | def test_bigint_to_neo_bytes(self): 27 | value_list = [9175052165852779861, -9175052165852779861, 9199634313818843819, -9199634313818843819, 8380656, 28 | -8380656, 8446192, -8446192, 0] 29 | for value in value_list: 30 | neo_bytearray = NeoData.big_int_to_neo_bytearray(value) 31 | self.assertTrue(isinstance(neo_bytearray, bytearray)) 32 | neo_value = NeoData.neo_bytearray_to_big_int(neo_bytearray) 33 | self.assertEqual(value, neo_value) 34 | 35 | def test_op_code_to_int(self): 36 | builder = NeoParamsBuilder() 37 | for num in range(100000): 38 | builder.push_int(num) 39 | op_code = builder.to_bytes().hex() 40 | builder.clear_up() 41 | value = NeoData.op_code_to_int(op_code) 42 | self.assertEqual(num, value) 43 | -------------------------------------------------------------------------------- /tests/test_curve.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.crypto.curve import Curve 22 | from ontology.exception.exception import SDKException 23 | 24 | 25 | class CurveTest(unittest.TestCase): 26 | def test_from_label(self): 27 | self.assertRaises(SDKException, Curve.from_label, 0) 28 | curve_lst = ['P224', 'P256', 'P384', 'P521'] 29 | label_lst = [1, 2, 3, 4] 30 | for index, label in enumerate(label_lst): 31 | self.assertEqual(curve_lst[index], Curve.from_label(label)) 32 | 33 | 34 | if __name__ == '__main__': 35 | unittest.main() 36 | -------------------------------------------------------------------------------- /tests/test_digest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.crypto.digest import Digest 22 | 23 | 24 | class TestDigest(unittest.TestCase): 25 | def test_sha256(self): 26 | msg = b'Nobody inspects the spammish repetition' 27 | sha256_digest = b'\x03\x1e\xdd}Ae\x15\x93\xc5\xfe\\\x00o\xa5u+7\xfd\xdf\xf7\xbcN\x84:\xa6\xaf\x0c\x95\x0fK\x94\x06' 28 | hex_sha256_digest = '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406' 29 | self.assertEqual(sha256_digest, Digest.sha256(msg)) 30 | self.assertEqual(hex_sha256_digest, Digest.sha256(msg, is_hex=True)) 31 | 32 | def test_hash256(self): 33 | msg = b'Nobody inspects the spammish repetition' 34 | hash256_digest = b"\x9f>\x9eV\xb0\xe6K\x8a\xd0\xd8\xfd\xb4\x87\xfb\x0b\xfc\xfc\xd2\xb2x\xa3\xf2\x04\xdb\xc6t\x10\xdbL@\x90'" 35 | hex_hash256_digest = '9f3e9e56b0e64b8ad0d8fdb487fb0bfcfcd2b278a3f204dbc67410db4c409027' 36 | self.assertEqual(hash256_digest, Digest.hash256(msg)) 37 | self.assertEqual(hex_hash256_digest, Digest.hash256(msg, is_hex=True)) 38 | 39 | def test_hash160(self): 40 | msg = b'Nobody inspects the spammish repetition' 41 | hash160_digest = b'\x1c\x9b{H\x04\x9a\x8f\x98i\x9b\xca"\xa5\x85l^\xf5q\xcdh' 42 | hex_hash160_digest = '1c9b7b48049a8f98699bca22a5856c5ef571cd68' 43 | self.assertEqual(hash160_digest, Digest.hash160(msg)) 44 | self.assertEqual(hex_hash160_digest, Digest.hash160(msg, is_hex=True)) 45 | 46 | def test_sha256_xor(self): 47 | h1 = Digest.sha256(int.to_bytes(1000, 2, 'little'), is_hex=True) 48 | h2 = Digest.sha256(int.to_bytes(89, 1, 'little'), is_hex=True) 49 | h = hex(int(h1, 16) ^ int(h2, 16))[2::] 50 | self.assertEqual('4307fbbb7e5b7c8f0339b060d171c49c881901d78ab712e60d805af9f9dc4ca1', h1) 51 | self.assertEqual('18f5384d58bcb1bba0bcd9e6a6781d1a6ac2cc280c330ecbab6cb7931b721552', h2) 52 | self.assertEqual('5bf2c3f626e7cd34a38569867709d986e2dbcdff86841c2da6eced6ae2ae59f3', h) 53 | 54 | 55 | if __name__ == '__main__': 56 | unittest.main() 57 | -------------------------------------------------------------------------------- /tests/test_error_code.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.exception.error_code import ErrorCode 22 | 23 | 24 | class TestErrorCode(unittest.TestCase): 25 | def test_get_error(self): 26 | code = 123 27 | msg = 'test' 28 | error_code = ErrorCode.get_error(code, msg) 29 | self.assertEqual(error_code["error"], code) 30 | self.assertEqual(error_code["desc"], msg) 31 | 32 | def test_constructed_root_hash_err(self): 33 | msg = 'TEST' 34 | desc = "Other Error, " + msg 35 | value = ErrorCode.constructed_root_hash_err(msg) 36 | self.assertEqual(value["desc"], desc) 37 | 38 | def test_connect_url_err(self): 39 | msg = 'TEST' 40 | desc = "connect error: " + msg 41 | value = ErrorCode.connect_err(msg) 42 | self.assertEqual(value["desc"], desc) 43 | 44 | def test_other_error(self): 45 | msg = 'TEST' 46 | desc = "Other Error, " + msg 47 | value = ErrorCode.other_error(msg) 48 | self.assertEqual(value["desc"], desc) 49 | 50 | def test_param_err(self): 51 | msg = 'TEST' 52 | value = ErrorCode.param_err(msg) 53 | self.assertEqual(value["desc"], msg) 54 | 55 | def test_invalid_acct_params(self): 56 | desc = "Account Error, invalid private key." 57 | value = ErrorCode.invalid_private_key 58 | self.assertEqual(type(value), dict) 59 | self.assertEqual(value["desc"], desc) 60 | 61 | def test_param_length_not_same(self): 62 | desc = "OntAsset Error, param length is not the same" 63 | value = ErrorCode.param_length_not_same 64 | self.assertEqual(type(value), dict) 65 | self.assertEqual(value["desc"], desc) 66 | 67 | 68 | if __name__ == '__main__': 69 | unittest.main() 70 | -------------------------------------------------------------------------------- /tests/test_exception.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.exception.error_code import ErrorCode 22 | from ontology.exception.exception import SDKException 23 | from ontology.exception.exception import SDKRuntimeException 24 | 25 | 26 | class TestSDKException(unittest.TestCase): 27 | def test_sdk_exception(self): 28 | try: 29 | raise SDKException(ErrorCode.param_error) 30 | except SDKException as e: 31 | self.assertEqual('param error', e.args[1]) 32 | 33 | try: 34 | raise SDKException(ErrorCode.asset_name_error) 35 | except SDKException as e: 36 | self.assertEqual('OntAsset Error, asset name error', e.args[1]) 37 | 38 | def test_sdk_runtime_exception(self): 39 | try: 40 | raise SDKRuntimeException(ErrorCode.encrypted_pri_key_error) 41 | except SDKRuntimeException as e: 42 | self.assertEqual("Account Error, Prikey length error", e.args[1]) 43 | 44 | try: 45 | raise SDKRuntimeException(ErrorCode.left_tree_full) 46 | except SDKRuntimeException as e: 47 | self.assertEqual("left tree always full", e.args[1]) 48 | 49 | 50 | if __name__ == '__main__': 51 | unittest.main() 52 | -------------------------------------------------------------------------------- /tests/test_key_type.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.crypto.key_type import KeyType 22 | from ontology.crypto.signature_scheme import SignatureScheme 23 | 24 | 25 | class TestKeyType(unittest.TestCase): 26 | def test_from_signature_scheme(self): 27 | key_type = KeyType.from_signature_scheme(SignatureScheme.SM3withSM2) 28 | self.assertTrue(key_type is KeyType.SM2) 29 | ecdsa_scheme = [SignatureScheme.SHA224withECDSA, SignatureScheme.SHA256withECDSA, 30 | SignatureScheme.SHA384withECDSA, SignatureScheme.SHA384withECDSA, 31 | SignatureScheme.SHA512withECDSA, SignatureScheme.SHA3_224withECDSA, 32 | SignatureScheme.SHA3_256withECDSA, SignatureScheme.SHA3_384withECDSA, 33 | SignatureScheme.SHA3_512withECDSA, SignatureScheme.RIPEMD160withECDSA] 34 | for scheme in ecdsa_scheme: 35 | key_type = KeyType.from_signature_scheme(scheme) 36 | self.assertTrue(key_type is KeyType.ECDSA) 37 | -------------------------------------------------------------------------------- /tests/test_native_vm.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from tests import sdk, acct1, acct2, not_panic_exception 22 | 23 | 24 | class TestNativeVm(unittest.TestCase): 25 | @not_panic_exception 26 | def test_native_vm_transaction(self): 27 | amount = 1 28 | tx = sdk.native_vm.ont().new_transfer_tx(acct2.get_address_base58(), acct1.get_address_base58(), amount, 29 | acct1.get_address_base58(), 500, 20000) 30 | tx.sign_transaction(acct1) 31 | tx.add_sign_transaction(acct2) 32 | tx_hash = sdk.rpc.send_raw_transaction(tx) 33 | self.assertEqual(64, len(tx_hash)) 34 | tx = sdk.native_vm.ont().new_transfer_tx(acct1.get_address_base58(), acct2.get_address_base58(), amount, 35 | acct1.get_address_base58(), 500, 20000) 36 | tx.sign_transaction(acct2) 37 | tx.add_sign_transaction(acct1) 38 | tx_hash = sdk.rpc.send_raw_transaction(tx) 39 | self.assertEqual(64, len(tx_hash)) 40 | 41 | @not_panic_exception 42 | def test_native_vm_withdraw_ong(self): 43 | payer = acct2 44 | b58_payer_address = payer.get_address_base58() 45 | amount = 1 46 | tx = sdk.native_vm.ong().new_withdraw_tx(b58_payer_address, b58_payer_address, amount, b58_payer_address, 500, 47 | 20000) 48 | tx.sign_transaction(payer) 49 | tx_hash = sdk.rpc.send_raw_transaction(tx) 50 | self.assertEqual(64, len(tx_hash)) 51 | 52 | 53 | if __name__ == '__main__': 54 | unittest.main() 55 | -------------------------------------------------------------------------------- /tests/test_oep5.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from tests import sdk, not_panic_exception 22 | 23 | 24 | class TestOep5(unittest.TestCase): 25 | def setUp(self): 26 | sdk.default_network = sdk.rpc 27 | self.networks = [sdk.rpc, sdk.restful] 28 | self.contract_address = '48a27da37954437481d915f636419b88e5bac50c' 29 | 30 | def test_set_contract_address(self): 31 | oep4 = sdk.neo_vm.oep5(self.contract_address) 32 | self.assertEqual(self.contract_address, oep4.hex_contract_address) 33 | 34 | @not_panic_exception 35 | def test_query_name(self): 36 | for network in self.networks: 37 | sdk.default_network = network 38 | oep5 = sdk.neo_vm.oep5(self.contract_address) 39 | self.assertEqual('CryptoKitties', oep5.name()) 40 | 41 | @not_panic_exception 42 | def test_get_symbol(self): 43 | for network in self.networks: 44 | sdk.default_network = network 45 | oep5 = sdk.neo_vm.oep5(self.contract_address) 46 | self.assertEqual('CK', oep5.symbol()) 47 | 48 | @not_panic_exception 49 | def test_balance_of(self): 50 | for network in self.networks: 51 | sdk.default_network = network 52 | oep5 = sdk.neo_vm.oep5(self.contract_address) 53 | self.assertGreaterEqual(oep5.balance_of('ANDfjwrUroaVtvBguDtrWKRMyxFwvVwnZD'), 0) 54 | -------------------------------------------------------------------------------- /tests/test_ontology_sdk.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.sdk import Ontology 22 | from tests import acct1, acct2, acct3, sdk, not_panic_exception 23 | 24 | from ontology.common.address import Address 25 | from ontology.core.program import ProgramBuilder 26 | 27 | 28 | class TestOntologySdk(unittest.TestCase): 29 | def test_singleton(self): 30 | for _ in range(10): 31 | new_sdk = Ontology() 32 | self.assertEqual(sdk, new_sdk) 33 | 34 | @not_panic_exception 35 | def test_add_multi_sign_transaction(self): 36 | pub_keys = [acct1.get_public_key_bytes(), acct2.get_public_key_bytes(), acct3.get_public_key_bytes()] 37 | m = 2 38 | b58_multi_address = Address.from_multi_pub_keys(m, pub_keys).b58encode() 39 | amount = 1 40 | gas_price = 500 41 | gas_limit = 20000 42 | tx_hash = sdk.native_vm.ont().transfer(acct2, b58_multi_address, amount, acct2, gas_price, gas_limit) 43 | self.assertEqual(64, len(tx_hash)) 44 | tx_hash = sdk.native_vm.ong().transfer(acct2, b58_multi_address, amount, acct2, gas_price, gas_limit) 45 | self.assertEqual(64, len(tx_hash)) 46 | b58_acct1_address = acct1.get_address_base58() 47 | b58_acct2_address = acct2.get_address_base58() 48 | self.assertEqual('ATyGGJBnANKFbf2tQMp4muUEZK7KuZ52k4', b58_multi_address) 49 | tx = sdk.native_vm.ong().new_transfer_tx(b58_acct1_address, b58_multi_address, amount, b58_acct1_address, 50 | gas_price, gas_limit) 51 | tx.add_sign_transaction(acct1) 52 | 53 | tx = sdk.native_vm.ont().new_transfer_tx(b58_multi_address, b58_acct2_address, amount, b58_acct1_address, 54 | gas_price, gas_limit) 55 | tx.sign_transaction(acct1) 56 | tx.add_multi_sign_transaction(m, pub_keys, acct1) 57 | tx.add_multi_sign_transaction(m, pub_keys, acct2) 58 | tx_hash = sdk.rpc.send_raw_transaction(tx) 59 | self.assertEqual(64, len(tx_hash)) 60 | 61 | def test_sort_public_key(self): 62 | pub_keys = [acct1.get_public_key_bytes(), acct2.get_public_key_bytes(), acct3.get_public_key_bytes()] 63 | builder = ProgramBuilder() 64 | sort_pub_keys = builder.sort_public_keys(pub_keys) 65 | self.assertEqual("023cab3b268c4f268456a972c672c276d23a9c3ca3dfcfc0004d786adbf1fb9282", sort_pub_keys[0].hex()) 66 | self.assertEqual("03d0fdb54acba3f81db3a6e16fa02e7ea3678bd205eb4ed2f1cfa8ab5e5d45633e", sort_pub_keys[1].hex()) 67 | self.assertEqual("02e8e84be09b87985e7f9dfa74298f6bb7f70f85515afca7e041fe964334e4b6c1", sort_pub_keys[2].hex()) 68 | 69 | 70 | if __name__ == '__main__': 71 | unittest.main() 72 | -------------------------------------------------------------------------------- /tests/test_program_builder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Copyright (C) 2018-2019 The ontology Authors 6 | This file is part of The ontology library. 7 | 8 | The ontology is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU Lesser General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | The ontology is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with The ontology. If not, see . 20 | """ 21 | 22 | import unittest 23 | 24 | from ontology.core.program import ProgramBuilder 25 | 26 | 27 | class TestProgramBuilder(unittest.TestCase): 28 | def test_sort_public_keys(self): 29 | pub_keys = ['02035b015221686aef1054b02605da2c3958885670b8298d36706593d3c451fa7e', 30 | '022b06295115ef825b8a17524815d77cd79a44c9c8980288e35bab542792425fc2', 31 | '03616dbe28eb6f2efdebe6a7b8fd824a56cf3e2ea5e03f802e19e686cb347d986f', 32 | '0364c210b769c73ffc2782c74beb881581148023e42562a53d6dd8273e26845901', 33 | '0296b60945cdbe44e9c8cfbeef7f6e462cb638dc65a5424e364ab0304063043950', 34 | '02a2d9e83c40303a3439db54e55052c0133cbbc61580f008197d2d9c03abc2a8ef', 35 | '02f7ec18df95f869e475361923105b9511dd8491d06ec0072530c174783a837846'] 36 | pub_keys = ProgramBuilder.sort_public_keys(pub_keys) 37 | self.assertEqual(7, len(pub_keys)) 38 | 39 | 40 | if __name__ == '__main__': 41 | unittest.main() 42 | -------------------------------------------------------------------------------- /tests/test_scrypt.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.crypto.scrypt import Scrypt 22 | 23 | 24 | class TestScrypt(unittest.TestCase): 25 | def test_set_dk_len(self): 26 | dk_len = 64 27 | scrypt = Scrypt() 28 | scrypt.dk_len = dk_len 29 | self.assertEqual(dk_len, scrypt.dk_len) 30 | 31 | def test_set_n(self): 32 | n = 5 33 | scrypt = Scrypt() 34 | scrypt.n = n 35 | self.assertEqual(n, scrypt.n) 36 | 37 | def test_set_p(self): 38 | n = 5 39 | scrypt = Scrypt() 40 | scrypt.n = n 41 | self.assertEqual(n, scrypt.n) 42 | 43 | def test_set_r(self): 44 | r = 5 45 | scrypt = Scrypt(r) 46 | scrypt.r = r 47 | self.assertEqual(r, scrypt.r) 48 | 49 | def test_generate_kd(self): 50 | scrypt = Scrypt() 51 | salt = ''.join(map(chr, bytes([0xfa, 0xa4, 0x88, 0x3d]))) 52 | kd = scrypt.generate_kd('passwordtest', salt) 53 | target_kd = '9f0632e05eab137baae6e0a83300341531e8638612a08042d3a4074578869af1' \ 54 | 'ccf5008e434d2cae9477f9e6e4c0571ab65a60e32e8c8fc356d95f64dd9717c9' 55 | target_kd = bytes.fromhex(target_kd) 56 | self.assertEqual(target_kd, kd) 57 | 58 | 59 | if __name__ == '__main__': 60 | unittest.main() 61 | -------------------------------------------------------------------------------- /tests/test_signature_handler.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from tests import sdk, acct1, acct2 22 | 23 | from ontology.crypto.signature_scheme import SignatureScheme 24 | from ontology.crypto.signature_handler import SignatureHandler 25 | 26 | 27 | class TestSignatureHandler(unittest.TestCase): 28 | def test_tx_signature(self): 29 | b58_from_address = acct1.get_address_base58() 30 | b58_to_address = acct2.get_address_base58() 31 | tx = sdk.native_vm.ont().new_transfer_tx(b58_from_address, b58_to_address, 10, b58_from_address, 0, 20000) 32 | tx.sign_transaction(acct1) 33 | self.assertTrue(acct1.verify_signature(tx.hash256(), tx.sig_list[0].sig_data[0])) 34 | self.assertFalse(acct2.verify_signature(tx.hash256(), tx.sig_list[0].sig_data[0])) 35 | tx.add_sign_transaction(acct2) 36 | self.assertTrue(acct2.verify_signature(tx.hash256(), tx.sig_list[1].sig_data[0])) 37 | 38 | def test_generate_signature(self): 39 | msg = b'Attack!' 40 | signature = acct1.generate_signature(msg) 41 | result = acct1.verify_signature(msg, signature) 42 | self.assertTrue(result) 43 | result = acct2.verify_signature(msg, signature) 44 | self.assertFalse(result) 45 | 46 | def test_verify_cyano_signature(self): 47 | msg = b'123' 48 | sign = '0b6912568942a1e646b3a532dc904e965eb1085bab877bc34fe06768257f07b3' \ 49 | '079af3fa69fc759b51fa2bf894a7fd748ab5bc326c8663a01f90dcc518184e65' 50 | pk = '03036c12be3726eb283d078dff481175e96224f0b0c632c7a37e10eb40fe6be889' 51 | handler = SignatureHandler(SignatureScheme.SHA256withECDSA) 52 | result = handler.verify_signature(bytes.fromhex(pk), msg, bytes.fromhex(sign)) 53 | self.assertTrue(result) 54 | sign = '010b6912568942a1e646b3a532dc904e965eb1085bab877bc34fe06768257f07b' \ 55 | '3079af3fa69fc759b51fa2bf894a7fd748ab5bc326c8663a01f90dcc518184e65' 56 | handler = SignatureHandler(SignatureScheme.SHA256withECDSA) 57 | result = handler.verify_signature(bytes.fromhex(pk), msg, bytes.fromhex(sign)) 58 | self.assertTrue(result) 59 | -------------------------------------------------------------------------------- /tests/test_signature_scheme.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.exception.exception import SDKException 22 | from ontology.crypto.signature_scheme import SignatureScheme 23 | 24 | 25 | class SignatureSchemeTest(unittest.TestCase): 26 | def test_from_claim_alg(self): 27 | self.assertRaises(SDKException, SignatureScheme.from_claim_alg, '') 28 | alg_lst = ['ES224', 'ES256', 'ES384', 'ES512', 'ES3-224', 'ES3-256', 'ES3-384', 'ER160', 'SM', 'EDS512', 29 | 'ONT-ES224', 'ONT-ES256', 'ONT-ES384', 'ONT-ES512', 'ONT-ES3-224', 'ONT-ES3-256', 'ONT-ES3-384', 30 | 'ONT-ER160', 'ONT-SM', 'ONT-EDS512'] 31 | scheme_lst = [SignatureScheme.SHA224withECDSA, SignatureScheme.SHA256withECDSA, SignatureScheme.SHA384withECDSA, 32 | SignatureScheme.SHA512withECDSA, SignatureScheme.SHA3_224withECDSA, 33 | SignatureScheme.SHA3_256withECDSA, SignatureScheme.SHA3_384withECDSA, 34 | SignatureScheme.RIPEMD160withECDSA, SignatureScheme.SM3withSM2, SignatureScheme.EDDSAwithSHA256] 35 | p = len(scheme_lst) 36 | for index, alg in enumerate(alg_lst): 37 | self.assertEqual(scheme_lst[index % p], SignatureScheme.from_claim_alg(alg)) 38 | 39 | 40 | if __name__ == '__main__': 41 | unittest.main() 42 | -------------------------------------------------------------------------------- /tests/test_sigsvr.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from os import path 22 | 23 | from tests import sdk, password 24 | 25 | from ontology.crypto.signature_handler import SignatureHandler 26 | 27 | 28 | class TestSigSvr(unittest.TestCase): 29 | def test_create_account(self): 30 | sdk.service.sig_svr.connect_to_localhost() 31 | result = sdk.service.sig_svr.create_account(password) 32 | self.assertTrue(isinstance(result, dict)) 33 | self.assertEqual(34, len(result.get('account', ''))) 34 | 35 | def test_export_account(self): 36 | sdk.service.sig_svr.connect_to_localhost() 37 | export_path = path.dirname(__file__) 38 | result = sdk.service.sig_svr.export_account(export_path) 39 | wm = sdk.wallet_manager 40 | wm.open_wallet(result['wallet_file']) 41 | try: 42 | self.assertEqual(result['account_num'], len(wm.get_acct_data_list())) 43 | finally: 44 | wm.del_wallet_file() 45 | 46 | def test_sig_data(self): 47 | sdk.service.sig_svr.connect_to_localhost() 48 | export_path = path.dirname(__file__) 49 | result = sdk.service.sig_svr.export_account(export_path) 50 | wm = sdk.wallet_manager 51 | wm.open_wallet(result['wallet_file']) 52 | try: 53 | self.assertEqual(result['account_num'], len(wm.get_acct_data_list())) 54 | acct = wm.get_wallet().get_account_by_index(0) 55 | b58_address = acct.b58_address 56 | scheme = acct.signature_scheme 57 | msg = b'Hello, world!' 58 | result = sdk.service.sig_svr.sig_data(bytes.hex(msg), b58_address, password) 59 | signature = bytes.fromhex(result.get('signed_data', '')) 60 | handler = SignatureHandler(scheme) 61 | is_valid = handler.verify_signature(acct.public_key, msg, signature) 62 | self.assertTrue(is_valid) 63 | finally: 64 | wm.del_wallet_file() 65 | -------------------------------------------------------------------------------- /tests/test_tx_verifier.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from tests import sdk, not_panic_exception 22 | 23 | 24 | class TestMerkleVerifier(unittest.TestCase): 25 | def check_tx_in_block(self, height: int): 26 | block = sdk.rpc.get_block_by_height(height) 27 | for tx in block.get('Transactions', dict()): 28 | result = sdk.service.tx_verifier().verify_by_tx_hash(tx['Hash']) 29 | self.assertTrue(result) 30 | 31 | @not_panic_exception 32 | def test_verifier(self): 33 | try: 34 | sdk.rpc.connect_to_main_net() 35 | self.check_tx_in_block(0) 36 | sdk.rpc.connect_to_test_net() 37 | self.check_tx_in_block(0) 38 | finally: 39 | sdk.rpc.connect_to_test_net() 40 | 41 | @not_panic_exception 42 | def test_verify_by_tx_hash(self): 43 | tx_hash = 'bf74e9208c0a20ec417de458ab6c9d29c12c614e77fb943be4566c95fab61454' 44 | self.assertTrue(sdk.service.tx_verifier().verify_by_tx_hash(tx_hash)) 45 | tx_hash_lst = ['c17e574dda17f268793757fab0c274d44427fa1b67d63113bd31e39b31d1a026', 46 | '7e8c19fdd4f9ba67f95659833e336eac37116f74ea8bf7be4541ada05b13503e'] 47 | for tx_hash in tx_hash_lst: 48 | try: 49 | sdk.rpc.connect_to_main_net() 50 | self.assertTrue(sdk.service.tx_verifier().verify_by_tx_hash(tx_hash)) 51 | finally: 52 | sdk.rpc.connect_to_test_net() 53 | 54 | 55 | if __name__ == '__main__': 56 | unittest.main() 57 | -------------------------------------------------------------------------------- /tests/test_utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018-2019 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.utils import utils 22 | from ontology.utils.neo import NeoData 23 | 24 | 25 | class TestUtil(unittest.TestCase): 26 | def test_get_random_bytes(self): 27 | self.assertRaises(ValueError, utils.get_random_bytes, -1) 28 | len_list = [0, 1, 64, 256, 1024, 2048] 29 | for length in len_list: 30 | self.assertEqual(len(utils.get_random_bytes(length)), length) 31 | 32 | def test_get_random_hex_str(self): 33 | self.assertRaises(ValueError, utils.get_random_hex_str, -1) 34 | len_list = [0, 1, 64, 256, 1024, 2048] 35 | for length in len_list: 36 | self.assertEqual(len(utils.get_random_hex_str(length)), length) 37 | 38 | def test_to_bool(self): 39 | self.assertTrue(NeoData.to_bool('01')) 40 | self.assertFalse(NeoData.to_bool('00')) 41 | 42 | 43 | if __name__ == '__main__': 44 | unittest.main() 45 | -------------------------------------------------------------------------------- /tests/test_vm_type.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2018 The ontology Authors 3 | This file is part of The ontology library. 4 | 5 | The ontology is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The ontology is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with The ontology. If not, see . 17 | """ 18 | 19 | import unittest 20 | 21 | from ontology.exception.exception import SDKException 22 | 23 | from ontology.vm.vm_type import VmType 24 | 25 | 26 | class TestVmType(unittest.TestCase): 27 | def test_from_int(self): 28 | self.assertEqual(VmType.Neo, VmType.from_int(VmType.Neo.value)) 29 | self.assertEqual(VmType.Wasm, VmType.from_int(VmType.Wasm.value)) 30 | self.assertRaises(SDKException, VmType.from_int, 0) 31 | -------------------------------------------------------------------------------- /tests/test_wasm_utils.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from ontology.utils.wasm import WasmData 4 | 5 | 6 | class TestWasmVm(unittest.TestCase): 7 | def test_to_int(self): 8 | wasm_hex_data = ['ffffffffffffffffffffffffffffff7f', '00000000000000000000000000000080', 9 | 'feffffffffffffffffffffffffffffff', '00000000000000000000000000000000', 10 | '01000000000000000000000000000000', '02000000000000000000000000000000'] 11 | int_data = [2 ** 127 - 1, -2 ** 127, -2, 0, 1, 2] 12 | for index, hex_data in enumerate(wasm_hex_data): 13 | self.assertEqual(int_data[index], WasmData.to_int(hex_data)) 14 | 15 | def test_to_utf8(self): 16 | str_list = [ 17 | 'Hello, world!', 18 | 'Ontology', 19 | '!@#$%^&*()_+1234567890-=', 20 | '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' 21 | ] 22 | wasm_str_list = [ 23 | '0d48656c6c6f2c20776f726c6421', 24 | '084f6e746f6c6f6779', 25 | '1821402324255e262a28295f2b313233343536373839302d3d', 26 | '3e313233343536373839304142434445464748494a4b4c4d4e4f50515253545' 27 | '5565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a' 28 | ] 29 | for index, wasm_str in enumerate(wasm_str_list): 30 | self.assertEqual(str_list[index], WasmData.detect_to_utf8(wasm_str)) 31 | -------------------------------------------------------------------------------- /tests/wasm/api.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ontio/ontology-python-sdk/ebe3dcb7fe4148b131f79bfc46d70b4359263316/tests/wasm/api.wasm -------------------------------------------------------------------------------- /tests/wasm/basic_test_case.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ontio/ontology-python-sdk/ebe3dcb7fe4148b131f79bfc46d70b4359263316/tests/wasm/basic_test_case.wasm -------------------------------------------------------------------------------- /tests/wasm/hello_world.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ontio/ontology-python-sdk/ebe3dcb7fe4148b131f79bfc46d70b4359263316/tests/wasm/hello_world.wasm -------------------------------------------------------------------------------- /tests/wasm/oep4.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ontio/ontology-python-sdk/ebe3dcb7fe4148b131f79bfc46d70b4359263316/tests/wasm/oep4.wasm -------------------------------------------------------------------------------- /tests/wasm/oep5.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ontio/ontology-python-sdk/ebe3dcb7fe4148b131f79bfc46d70b4359263316/tests/wasm/oep5.wasm -------------------------------------------------------------------------------- /tests/wasm/oep8.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ontio/ontology-python-sdk/ebe3dcb7fe4148b131f79bfc46d70b4359263316/tests/wasm/oep8.wasm -------------------------------------------------------------------------------- /tests/wasm/red_envlope.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ontio/ontology-python-sdk/ebe3dcb7fe4148b131f79bfc46d70b4359263316/tests/wasm/red_envlope.wasm --------------------------------------------------------------------------------