123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- ###############################################################################
- #
- # The MIT License (MIT)
- #
- # Copyright (c) typedef int GmbH
- #
- # Permission is hereby granted, free of charge, to any person obtaining a copy
- # of this software and associated documentation files (the "Software"), to deal
- # in the Software without restriction, including without limitation the rights
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- # copies of the Software, and to permit persons to whom the Software is
- # furnished to do so, subject to the following conditions:
- #
- # The above copyright notice and this permission notice shall be included in
- # all copies or substantial portions of the Software.
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- # THE SOFTWARE.
- #
- ###############################################################################
-
- import web3
- import txaio
- from autobahn import xbr
-
-
- class SimpleBlockchain(object):
- """
- Simple Ethereum blockchain XBR client.
- """
- DomainStatus_NULL = 0
- DomainStatus_ACTIVE = 1
- DomainStatus_CLOSED = 2
-
- NodeType_NULL = 0
- NodeType_MASTER = 1
- NodeType_CORE = 2
- NodeType_EDGE = 3
-
- NodeLicense_NULL = 0
- NodeLicense_INFINITE = 1
- NodeLicense_FREE = 2
-
- log = None
- backgroundCaller = None
-
- def __init__(self, gateway=None):
- """
-
- :param gateway: Optional explicit Ethereum gateway URL to use.
- If no explicit gateway is specified, let web3 auto-choose.
- :type gateway: str
- """
- self.log = txaio.make_logger()
- self._gateway = gateway
- self._w3 = None
- assert self.backgroundCaller is not None
-
- def start(self):
- """
- Start the blockchain client using the configured blockchain gateway.
- """
- assert self._w3 is None
-
- if self._gateway:
- w3 = web3.Web3(web3.Web3.HTTPProvider(self._gateway))
- else:
- # using automatic provider detection:
- from web3.auto import w3
-
- # check we are connected, and check network ID
- if not w3.isConnected():
- emsg = 'could not connect to Web3/Ethereum at: {}'.format(self._gateway or 'auto')
- self.log.warn(emsg)
- raise RuntimeError(emsg)
- else:
- print('connected to network {} at provider "{}"'.format(w3.version.network,
- self._gateway or 'auto'))
-
- self._w3 = w3
-
- # set new provider on XBR library
- xbr.setProvider(self._w3)
-
- def stop(self):
- """
- Stop the blockchain client.
- """
- assert self._w3 is not None
-
- self._w3 = None
-
- async def get_market_status(self, market_id):
- """
-
- :param market_id:
- :return:
- """
- def _get_market_status(_market_id):
- owner = xbr.xbrnetwork.functions.getMarketOwner(_market_id).call()
- if not owner or owner == '0x0000000000000000000000000000000000000000':
- return None
- else:
- return {
- 'owner': owner,
- }
- return self.backgroundCaller(_get_market_status, market_id)
-
- async def get_domain_status(self, domain_id):
- """
-
- :param domain_id:
- :type domain_id: bytes
-
- :return:
- :rtype: dict
- """
- def _get_domain_status(_domain_id):
- status = xbr.xbrnetwork.functions.getDomainStatus(_domain_id).call()
- if status == SimpleBlockchain.DomainStatus_NULL:
- return None
- elif status == SimpleBlockchain.DomainStatus_ACTIVE:
- return {'status': 'ACTIVE'}
- elif status == SimpleBlockchain.DomainStatus_CLOSED:
- return {'status': 'CLOSED'}
- return self.backgroundCaller(_get_domain_status, domain_id)
-
- def get_node_status(self, delegate_adr):
- """
-
- :param delegate_adr:
- :type delegate_adr: bytes
-
- :return:
- :rtype: dict
- """
- raise NotImplementedError()
-
- def get_actor_status(self, delegate_adr):
- """
-
- :param delegate_adr:
- :type delegate_adr: bytes
-
- :return:
- :rtype: dict
- """
- raise NotImplementedError()
-
- def get_delegate_status(self, delegate_adr):
- """
-
- :param delegate_adr:
- :type delegate_adr: bytes
-
- :return:
- :rtype: dict
- """
- raise NotImplementedError()
-
- def get_channel_status(self, channel_adr):
- """
-
- :param channel_adr:
- :type channel_adr: bytes
-
- :return:
- :rtype: dict
- """
- raise NotImplementedError()
-
- async def get_member_status(self, member_adr):
- """
-
- :param member_adr:
- :type member_adr: bytes
-
- :return:
- :rtype: dict
- """
- assert type(member_adr) == bytes and len(member_adr) == 20
-
- def _get_member_status(_member_adr):
- level = xbr.xbrnetwork.functions.getMemberLevel(member_adr).call()
- if not level:
- return None
- else:
- eula = xbr.xbrnetwork.functions.getMemberEula(member_adr).call()
- if not eula or eula.strip() == '':
- return None
- profile = xbr.xbrnetwork.functions.getMemberProfile(member_adr).call()
- if not profile or profile.strip() == '':
- profile = None
- return {
- 'eula': eula,
- 'profile': profile,
- }
- return self.backgroundCaller(_get_member_status, member_adr)
-
- async def get_balances(self, account_adr):
- """
- Return current ETH and XBR balances of account with given address.
-
- :param account_adr: Ethereum address of account to get balances for.
- :type account_adr: bytes
-
- :return: A dictionary with ``"ETH"`` and ``"XBR"`` keys and respective
- current on-chain balances as values.
- :rtype: dict
- """
- assert type(account_adr) == bytes and len(account_adr) == 20
-
- def _get_balances(_adr):
- balance_eth = self._w3.eth.getBalance(_adr)
- balance_xbr = xbr.xbrtoken.functions.balanceOf(_adr).call()
- return {
- 'ETH': balance_eth,
- 'XBR': balance_xbr,
- }
- return self.backgroundCaller(_get_balances, account_adr)
-
- def get_contract_adrs(self):
- """
- Get XBR smart contract addresses.
-
- :return: A dictionary with ``"XBRToken"`` and ``"XBRNetwork"`` keys and Ethereum
- contract addresses as values.
- :rtype: dict
- """
- return {
- 'XBRToken': xbr.xbrtoken.address,
- 'XBRNetwork': xbr.xbrnetwork.address,
- }
|