239 lines
7.2 KiB
Python
239 lines
7.2 KiB
Python
###############################################################################
|
|
#
|
|
# The MIT License (MIT)
|
|
#
|
|
# Copyright (c) Crossbar.io Technologies 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,
|
|
}
|