| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- from flask import Flask, request, jsonify
- from json import JSONEncoder
- # Here are Iroha dependencies.
- # Python library generally consists of 3 parts:
- # Iroha, IrohaCrypto and IrohaGrpc which we need to import:
- import os
- import binascii
- from iroha import IrohaCrypto
- from iroha import Iroha, IrohaGrpc
- from werkzeug.wrappers import response
- # Here is the information about the environment and admin account information:
- IROHA_HOST_ADDR = os.getenv('IROHA_HOST_ADDR', '127.0.0.1')
- IROHA_PORT = os.getenv('IROHA_PORT', '50051')
- ADMIN_ACCOUNT_ID = os.getenv('ADMIN_ACCOUNT_ID', 'admin@test')
- ADMIN_PRIVATE_KEY = os.getenv(
- 'ADMIN_PRIVATE_KEY', 'f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70')
- # Here we will create user keys
- user_private_key = IrohaCrypto.private_key()
- user_public_key = IrohaCrypto.derive_public_key(user_private_key)
- iroha = Iroha(ADMIN_ACCOUNT_ID)
- net = IrohaGrpc('{}:{}'.format(IROHA_HOST_ADDR, IROHA_PORT))
- class MyEncoder(JSONEncoder):
- def default(self, o):
- if isinstance(o, bytes):
- return str(o, encoding='utf-8')
- return o.__dict__
- app = Flask(__name__)
- app.json_encoder = MyEncoder
- class Asset:
- assetId = ""
- balance = 0
- def __init__(self, assetId = "", balance = 0):
- self.assetId = assetId
- self.balance = balance
- class Assets:
- assets = []
- class StatefulValidationError:
- name = ""
- description = ""
- solution = ""
- def __init__(self, name = "", description = "", solution = ""):
- self.name = name
- self.description = description
- self.solution = solution
- transferAssetsValidationErrors = [
- StatefulValidationError("Could not transfer asset", "Internal error happened", "Try again or contact developers"),
- StatefulValidationError("No such permissions", "Command's creator does not have permission to transfer asset from his account", "Grant the necessary permission"),
- StatefulValidationError("No such source account", "Cannot find account with such id to transfer money from", "Make sure source account id is correct"),
- StatefulValidationError("No such destination account", "Cannot find account with such id to transfer money to", "Make sure destination account id is correct"),
- StatefulValidationError("No such asset found", "Cannot find such asset", "Make sure asset name and precision are correct"),
- StatefulValidationError("Not enough balance", "Source account's balance is too low to perform the operation", "Add asset to account or choose lower value to subtract"),
- StatefulValidationError("Too much asset to transfer", "Resulting asset quantity of destination account would exceed the allowed maximum", "Make sure that the final destination value is less than 2^256 / 10^asset_precision"),
- StatefulValidationError("Too long description", "Too long description", "Ensure that description length matches the criteria above (or just shorten it)")
- ]
- @app.route("/accounts/<string:accountId>/assets/", methods=['GET'])
- def get_account_assets(accountId): #TODO: add validation and error handling
- query = iroha.query('GetAccountAssets', account_id=accountId)
- IrohaCrypto.sign_query(query, ADMIN_PRIVATE_KEY)
- iroha_response = net.send_query(query)
- data = iroha_response.account_assets_response.account_assets
-
- response = Assets()
- response.assets = []
- if len(data) < 1:
- return '', 204
- for asset in data:
- response.assets.append(Asset(asset.asset_id, asset.balance))
- return jsonify(response)
- @app.route("/assets/transfer/", methods=['POST'])
- def transfer_assets():
- data = request.get_json()
- if data["transfers"] and len(data["transfers"]) > 0:
- commands = []
- for transfer in data["transfers"]:
- commands.append(
- iroha.command('TransferAsset', src_account_id = transfer["source"], dest_account_id = transfer["destination"],
- asset_id = transfer["asset"], description = transfer["description"], amount = str(transfer["amount"]))
- )
-
- transaction = iroha.transaction(commands)
- hex_hash = binascii.hexlify(IrohaCrypto.hash(transaction))
- IrohaCrypto.sign_transaction(transaction, ADMIN_PRIVATE_KEY)
- net.send_tx(transaction)
- #TODO speed up status reading
- transactionStates = []
- for status in net.tx_status_stream(transaction):
- transactionStates.append(status)
- if(status[0] == "STATEFUL_VALIDATION_SUCCESS"):
- break
- if(status[0] == "STATEFUL_VALIDATION_FAILED"):
- return jsonify({
- "transactionHash" : hex_hash,
- "error" : transferAssetsValidationErrors[status[2] - 1]
- }), 400
- #TODO send URL to newly created transaction in Content-Location header
- return jsonify({
- "transactionHash" : hex_hash,
- # "transactionStates" : transactionStates
- })
|