21 KiB
description |
---|
Technical details about Datatoken functions |
Datatoken Interface Tech Details
Datatoken contract interface
is like the superhero that kicks off the action-packed adventure of contract calls! It's here to save the day by empowering us to unleash the mighty powers of dispensers, fixed rate exchanges, and initializing orders. For this page, we present the utilitary functions that embark you on the Ocean journey.
Create Dispenser
- create_dispenser(
self
,tx_dict: dict
,max_tokens: Optional[Union[int, str]] = None
,max_balance: Optional[Union[int, str]] = None
,with_mint: Optional[bool] = True
)
Through datatoken, you can deploy a new dispenser schema which is used for creating free assets, because its behaviour is similar with a faucet. ⛲
It is implemented in DatatokenBase, inherited by Datatoken2, so it can be called within both instances.
Parameters
tx_dict
- is the configurationdictionary
for that specific transaction. Usually fordevelopment
we include just thefrom
wallet, but for remote networks, you can provide gas fees, required confirmations for that block etc.max_tokens
- maximum amount of tokens to dispense in wei. The default is a large number.max_balance
- maximum balance of requester in wei. The default is a large number.with_mint
- boolean,true
if we want to allow the dispenser to be a minter as default value
Returns
str
Return value is a hex string which denotes the transaction hash of dispenser deployment.
Defined in
Source code
@enforce_types
def create_dispenser(
self,
tx_dict: dict,
max_tokens: Optional[Union[int, str]] = None,
max_balance: Optional[Union[int, str]] = None,
with_mint: Optional[bool] = True,
):
"""
For this datataken, create a dispenser faucet for free tokens.
This wraps the smart contract method Datatoken.createDispenser()
with a simpler interface.
:param: max_tokens - max # tokens to dispense, in wei
:param: max_balance - max balance of requester
:tx_dict: e.g. {"from": alice_wallet}
:return: tx
"""
# already created, so nothing to do
if self.dispenser_status().active:
return
# set max_tokens, max_balance if needed
max_tokens = max_tokens or MAX_UINT256
max_balance = max_balance or MAX_UINT256
# args for contract tx
dispenser_addr = get_address_of_type(self.config_dict, "Dispenser")
with_mint = with_mint # True -> can always mint more
allowed_swapper = ZERO_ADDRESS # 0 -> so anyone can call dispense
# do contract tx
tx = self.createDispenser(
dispenser_addr,
max_tokens,
max_balance,
with_mint,
allowed_swapper,
tx_dict,
)
return tx
Dispense Datatokens
- dispense(
self
,amount: Union[int, str]
,tx_dict: dict
)
This function is used to retrieve funds or datatokens for an user who wants to start an order.
It is implemented in DatatokenBase, so it can be called within Datatoken class.
Parameters
amount
- amount of datatokens to be dispensed in wei (int or string format)tx_dict
- is the configurationdictionary
for that specific transaction. Usually fordevelopment
we include just thefrom
wallet, but for remote networks, you can provide gas fees, required confirmations for that block etc.
Returns
str
Return value is a hex string which denotes the transaction hash of dispensed datatokens, like a proof.
Defined in
Source code
@enforce_types
def dispense(self, amount: Union[int, str], tx_dict: dict):
"""
Dispense free tokens via the dispenser faucet.
:param: amount - number of tokens to dispense, in wei
:tx_dict: e.g. {"from": alice_wallet}
:return: tx
"""
# args for contract tx
datatoken_addr = self.address
from_addr = (
tx_dict["from"].address
if hasattr(tx_dict["from"], "address")
else tx_dict["from"]
)
# do contract tx
tx = self._ocean_dispenser().dispense(
datatoken_addr, amount, from_addr, tx_dict
)
return tx
Dispense Datatokens & Order
- dispense_and_order(
self
,consumer: str
,service_index: int
,provider_fees: dict
,transaction_parameters: dict
,consume_market_fees=None
) ->str
This function is used to retrieve funds or datatokens for an user who wants to start an order.
It is implemented in Datatoken2
, so it can be called within Datatoken2
class (using the enterprise template).
Parameters
consumer
- address of the consumer wallet that needs fundingservice_index
- service index as int for identifying the service that you want to further callstart_order
.transaction_parameters
- is the configurationdictionary
for that specific transaction. Usually fordevelopment
we include just thefrom
wallet, but for remote networks, you can provide gas fees, required confirmations for that block etc.consume_market_fees
-TokenInfo
object which contains the consume market fee amount, address & token address. If it is not explicitly specified, by default it has an emptyTokenInfo
object.
Returns
str
Return value is a hex string which denotes the transaction hash of dispensed datatokens, like a proof of starting order.
Defined in
Source code
{% code overflow="wrap" %}
def dispense_and_order(
self,
consumer: str,
service_index: int,
provider_fees: dict,
transaction_parameters: dict,
consume_market_fees=None,
) -> str:
if not consume_market_fees:
consume_market_fees = TokenFeeInfo()
buyer_addr = (
transaction_parameters["from"].address
if hasattr(transaction_parameters["from"], "address")
else transaction_parameters["from"]
)
bal = from_wei(self.balanceOf(buyer_addr))
if bal < 1.0:
dispenser_addr = get_address_of_type(self.config_dict, "Dispenser")
from ocean_lib.models.dispenser import Dispenser # isort: skip
dispenser = Dispenser(self.config_dict, dispenser_addr)
# catch key failure modes
st = dispenser.status(self.address)
active, allowedSwapper = st[0], st[6]
if not active:
raise ValueError("No active dispenser for datatoken")
if allowedSwapper not in [ZERO_ADDRESS, buyer_addr]:
raise ValueError(f"Not allowed. allowedSwapper={allowedSwapper}")
# Try to dispense. If other issues, they'll pop out
dispenser.dispense(
self.address, "1 ether", buyer_addr, transaction_parameters
)
return self.start_order(
consumer=ContractBase.to_checksum_address(consumer),
service_index=service_index,
provider_fees=provider_fees,
consume_market_fees=consume_market_fees,
transaction_parameters=transaction_parameters,
)
{% endcode %}
Dispenser Status
- dispenser_status(
self
) ->DispenserStatus
Returns
DispenserStatus
Returns a DispenserStatus
object returned from Dispenser.sol::status(dt_addr)
which is composed of:
- bool active
- address owner
- bool isMinter
- uint256 maxTokens
- uint256 maxBalance
- uint256 balance
- address allowedSwapper
These are Solidity return values & types, but uint256
means int in Python and address
is a string
instance.
For tips & tricks, check this section from the README.
It is implemented in DatatokenBase
, inherited by Datatoken2
, so it can be called within both instances.
Defined in
Source code
@enforce_types
def dispenser_status(self):
""":return: DispenserStatus object"""
# import here to avoid circular import
from ocean_lib.models.dispenser import DispenserStatus
status_tup = self._ocean_dispenser().status(self.address)
return DispenserStatus(status_tup)
Create Fixed Rate Exchange
- create_exchange(
self
,rate: Union[int, str]
,base_token_addr: str
,tx_dict: dict
,owner_addr: Optional[str] = None
,publish_market_fee_collector: Optional[str] = None, publish_market_fee: Union[int, str] = 0
,with_mint: bool = False
,allowed_swapper: str = ZERO_ADDRESS
,full_info: bool = False
) ->Union[OneExchange, tuple]
It is implemented in DatatokenBase
, inherited by Datatoken2
, so it can be called within both instances.
For this datatoken, create a single fixed-rate exchange (OneExchange
).
This wraps the smart contract method Datatoken.createFixedRate()
with a simpler interface.
Parameters
rate
- how many base tokens does 1 datatoken cost? In wei or stringbase_token_addr
- e.g. OCEAN addresstx_dict
- is the configurationdictionary
for that specific transaction. Usually fordevelopment
we include just thefrom
wallet, but for remote networks, you can provide gas fees, required confirmations for that block etc.
Optional parameters
owner_addr
- owner of the datatokenpublish_market_fee_collector
- fee going to publish market addresspublish_market_fee
- in wei or string, e.g.int(1e15)
or"0.001 ether"
with_mint
- should the exchange mint datatokens as needed (True
), or do they need to be supplied/allowed by participants like base token (False
)?allowed_swapper
- ifZERO_ADDRESS
, anyone can swapfull_info
- return justOneExchange
, or(OneExchange, <other info>)
Returns
exchange
- OneExchange- (maybe)
tx_receipt
Defined in
Source code
{% code overflow="wrap" %}
@enforce_types
def create_exchange(
self,
rate: Union[int, str],
base_token_addr: str,
tx_dict: dict,
owner_addr: Optional[str] = None,
publish_market_fee_collector: Optional[str] = None,
publish_market_fee: Union[int, str] = 0,
with_mint: bool = False,
allowed_swapper: str = ZERO_ADDRESS,
full_info: bool = False,
) -> Union[OneExchange, tuple]:
# import now, to avoid circular import
from ocean_lib.models.fixed_rate_exchange import OneExchange
FRE_addr = get_address_of_type(self.config_dict, "FixedPrice")
from_addr = (
tx_dict["from"].address
if hasattr(tx_dict["from"], "address")
else tx_dict["from"]
)
BT = Datatoken(self.config_dict, base_token_addr)
owner_addr = owner_addr or from_addr
publish_market_fee_collector = publish_market_fee_collector or from_addr
tx = self.contract.createFixedRate(
checksum_addr(FRE_addr),
[
checksum_addr(BT.address),
checksum_addr(owner_addr),
checksum_addr(publish_market_fee_collector),
checksum_addr(allowed_swapper),
],
[
BT.decimals(),
self.decimals(),
rate,
publish_market_fee,
with_mint,
],
tx_dict,
)
exchange_id = tx.events["NewFixedRate"]["exchangeId"]
FRE = self._FRE()
exchange = OneExchange(FRE, exchange_id)
if full_info:
return (exchange, tx)
return exchange
{% endcode %}
Buy Datatokens & Order
- buy_DT_and_order(
self
,consumer: str
,service_index: int
,provider_fees: dict
,exchange: Any
,transaction_parameters: dict
,consume_market_fees=None
) ->str
This function is used to retrieve funds or datatokens for an user who wants to start an order.
It is implemented in Datatoken
class and it is also inherited in Datatoken2
class.
Parameters
consumer
- address of the consumer wallet that needs fundingservice_index
- service index as int for identifying the service that you want to further callstart_order
.transaction_parameters
- is the configurationdictionary
for that specific transaction. Usually fordevelopment
we include just thefrom
wallet, but for remote networks, you can provide gas fees, required confirmations for that block etc.consume_market_fees
-TokenInfo
object which contains the consume market fee amount, address & token address. If it is not explicitly specified, by default it has an emptyTokenInfo
object.
Returns
str
Return value is a hex string for transaction hash which denotes the proof of starting order.
Defined in
Source code
@enforce_types
def buy_DT_and_order(
self,
consumer: str,
service_index: int,
provider_fees: dict,
exchange: Any,
transaction_parameters: dict,
consume_market_fees=None,
) -> str:
fre_address = get_address_of_type(self.config_dict, "FixedPrice")
# import now, to avoid circular import
from ocean_lib.models.fixed_rate_exchange import OneExchange
if not consume_market_fees:
consume_market_fees = TokenFeeInfo()
if not isinstance(exchange, OneExchange):
exchange = OneExchange(fre_address, exchange)
exchange.buy_DT(
datatoken_amt=to_wei(1),
consume_market_fee_addr=consume_market_fees.address,
consume_market_fee=consume_market_fees.amount,
tx_dict=transaction_parameters,
)
return self.start_order(
consumer=ContractBase.to_checksum_address(consumer),
service_index=service_index,
provider_fees=provider_fees,
consume_market_fees=consume_market_fees,
transaction_parameters=transaction_parameters,
)
Get Exchanges
- get_exchanges(
self
) ->list
Returns
list
Returns List[OneExchange]
- all the exchanges for this datatoken.
It is implemented in DatatokenBase
, inherited by Datatoken2
, so it can be called within both instances.
Defined in
Source code
{% code overflow="wrap" %}
@enforce_types
def get_exchanges(self) -> list:
"""return List[OneExchange] - all the exchanges for this datatoken"""
# import now, to avoid circular import
from ocean_lib.models.fixed_rate_exchange import OneExchange
FRE = self._FRE()
addrs_and_exchange_ids = self.getFixedRates()
exchanges = [
OneExchange(FRE, exchange_id) for _, exchange_id in addrs_and_exchange_ids
]
return exchanges
{% endcode %}
Start Order
- start_order(
self
,consumer: str
,service_index: int
,provider_fees: dict
,transaction_parameters: dict
,consume_market_fees=None
) ->str
Starting order of a certain datatoken.
It is implemented in Datatoken class and it is also inherited in Datatoken2 class.
Parameters
consumer
- address of the consumer wallet that needs fundingservice_index
- service index as int for identifying the service that you want to applystart_order
.provider_fees
- dictionary which includes provider fees generated wheninitialize
endpoint fromProvider
was called.transaction_parameters
- is the configurationdictionary
for that specific transaction. Usually fordevelopment
we include just thefrom
wallet, but for remote networks, you can provide gas fees, required confirmations for that block etc.consume_market_fees
-TokenInfo
object which contains the consume market fee amount, address & token address. If it is not explicitly specified, by default it has an emptyTokenInfo
object.
Returns
str
Return value is a hex string for transaction hash which denotes the proof of starting order.
Defined in
Source code
@enforce_types
def start_order(
self,
consumer: str,
service_index: int,
provider_fees: dict,
transaction_parameters: dict,
consume_market_fees=None,
) -> str:
if not consume_market_fees:
consume_market_fees = TokenFeeInfo()
return self.contract.startOrder(
checksum_addr(consumer),
service_index,
(
checksum_addr(provider_fees["providerFeeAddress"]),
checksum_addr(provider_fees["providerFeeToken"]),
int(provider_fees["providerFeeAmount"]),
provider_fees["v"],
provider_fees["r"],
provider_fees["s"],
provider_fees["validUntil"],
provider_fees["providerData"],
),
consume_market_fees.to_tuple(),
transaction_parameters,
)
Reuse Order
- reuse_order(
self
,order_tx_id: Union[str, bytes]
,provider_fees: dict
,transaction_parameters: dict
) ->str
Reusing an order from a certain datatoken.
It is implemented in Datatoken class and it is also inherited in Datatoken2 class.
Parameters
order_tx_id
- transaction hash of a previous order, string or bytes format.provider_fees
- dictionary which includes provider fees generated wheninitialize
endpoint fromProvider
was called.transaction_parameters
- is the configurationdictionary
for that specific transaction. Usually fordevelopment
we include just thefrom
wallet, but for remote networks, you can provide gas fees, required confirmations for that block etc.
Returns
str
Return value is a hex string for transaction hash which denotes the proof of reusing order.
Defined in
Source code
@enforce_types
def reuse_order(
self,
order_tx_id: Union[str, bytes],
provider_fees: dict,
transaction_parameters: dict,
) -> str:
return self.contract.reuseOrder(
order_tx_id,
(
checksum_addr(provider_fees["providerFeeAddress"]),
checksum_addr(provider_fees["providerFeeToken"]),
int(provider_fees["providerFeeAmount"]),
provider_fees["v"],
provider_fees["r"],
provider_fees["s"],
provider_fees["validUntil"],
provider_fees["providerData"],
),
transaction_parameters,
)