Skip to content

Commit

Permalink
Improve READMEs to fix #1255 and to fix #1161 part (3) (#1256)
Browse files Browse the repository at this point in the history
  • Loading branch information
trentmc authored Jan 4, 2023
1 parent 6eae2ec commit b5b6dcd
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 21 deletions.
17 changes: 17 additions & 0 deletions READMEs/df.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,20 @@ We leave this as an exercise to the reader:)

Happy Data Farming!


## Appendix.

At the beginning of this flows, we created an `ocean` object, which is an instance of class [`Ocean`](https://github.com/oceanprotocol/ocean.py/blob/main/ocean_lib/ocean/ocean.py).

It provides convenient access to [DF](https://github.com/oceanprotocol/ocean.py/tree/main/ocean_lib/models/df) & [VE](https://github.com/oceanprotocol/ocean.py/tree/main/ocean_lib/models/ve) Python objects that which wrap [DF](https://github.com/oceanprotocol/contracts/tree/main/contracts/df) & [VE](https://github.com/oceanprotocol/contracts/tree/main/contracts/ve) Solidity contracts:
- `ocean.ve_ocean` or `ocean.veOCEAN -> VeOcean`
- `ocean.df_rewards -> DFRewards`
- `ocean.df_strategy_v1 -> DFStrategyV1`
- `ocean.smart_wallet_checker -> SmartWalletChecker`
- `ocean.ve_allocate -> VeAllocate`
- `ocean.ve_delegation -> VeDelegation`
- `ocean.ve_delegation_proxy -> VeDelegationProxy`
- `ocean.ve_fee_distributor -> VeFeeDistributor`
- `ocean.ve_fee_estimate(self) -> VeFeeEstimate`


135 changes: 114 additions & 21 deletions READMEs/main-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ datatoken.mint(bob, to_wei(1), {"from": alice})
datatoken.mint(alice, to_wei(1), {"from": alice})
datatoken.transfer(bob, to_wei(1), {"from": alice})

#Approach C: Alice posts for free, via a faucet; Bob requests & gets
#Approach C: Alice posts for free, via a dispenser / faucet; Bob requests & gets
datatoken.create_dispenser({"from": alice})
datatoken.dispense(to_wei(1), {"from": bob})

Expand All @@ -81,7 +81,7 @@ ocean.OCEAN_token.approve(exchange.address, OCEAN_needed, {"from":bob})
exchange.buy_DT(to_wei(1), consume_market_fee=0, tx_dict={"from": bob})
````

(For more info, see [Appendix: Faucet Details](#appendix-faucet-details) and [Exchange Details](#appendix-exchange-details).)
(For more info, see [Appendix: Dispenser / Faucet Details](#appendix-faucet-details) and [Exchange Details](#appendix-exchange-details).)

## 3. Bob consumes the dataset

Expand Down Expand Up @@ -141,17 +141,17 @@ datatoken = Datatoken(config, datatoken_address)

### Data NFT Interface

Data NFTs implement ERC721 functionality, and ERC725 which extends it.
Data NFTs implement ERC721 functionality, ERC725 which extends it, and data management functionality on top.

ERC721:
- Basic spec of a non-fungible token (NFT)
- Official spec is at [erc721.org](https://erc721.org/)
- Solidity interface is in Ocean contracts repo as [IERC721Template.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/interfaces/IERC721Template.sol)
- Solidity interface: [IERC721Template.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/interfaces/IERC721Template.sol)

ERC725:
- ERC725X is execution, and Y is key-value store
- Official spec is at [eips.ethereum.org](https://eips.ethereum.org/EIPS/eip-725)
- Solidity interface is in Ocean contracts repo as [IERC725X.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/interfaces/IERC725X.sol) (execution) and [IERC725Y.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/interfaces/IERC725Y.sol) (key-value store)
- Solidity interface: [IERC725X.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/interfaces/IERC725X.sol) (execution) and [IERC725Y.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/interfaces/IERC725Y.sol) (key-value store)

The `data_nft` is a Python object of class [DataNFT](https://github.com/oceanprotocol/ocean.py/blob/main/ocean_lib/models/data_nft.py). Thanks to Brownie, the DataNFT class directly exposes the Solidity ERC721 & ERC725 interfaces. This means your `data_nft` object has a Python method for every Solidity method! Thank you, Brownie :)

Expand All @@ -163,18 +163,26 @@ Ocean's architecture allows for >1 implementations of ERC721, each with its own

### Datatoken Interface

Datatokens implement ERC20 (fungible token standard) functionality:
Datatokens implement ERC20 functionality, and data management functionality on top.

ERC20:
- Basic spec of a fungible token standard
- Official spec is at [eips.ethereum.org](https://eips.ethereum.org/EIPS/eip-20)
- Solidity interface is in Ocean contracts repo as [IERC20Template.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/interfaces/IERC20Template.sol)
- Solidity interface: [IERC20Template.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/interfaces/IERC20Template.sol)

Python `datatoken` objects are of Python class [Datatoken](https://github.com/oceanprotocol/ocean.py/blob/main/ocean_lib/models/datatoken.py). Thanks to Brownie, these classes have a Python method for every Solidity method.
Ocean's architecture allows for >1 implementations of ERC20, each with its own "template". Here are the templates so far (we can expect more over time).

Besides that, Datatoken class implements more methods like `start_order()`, `create_exchange()`, and `create_dispenser()` to enhance developer experience.
Template 1:
- Solidity: [ERC20Template.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/templates/ERC20Template.sol)
- Python wrapper: [Datatoken](https://github.com/oceanprotocol/ocean.py/blob/main/ocean_lib/models/datatoken.py). It has a Python method for every Solidity method, via Brownie.
- Implements methods like `start_order()`, `create_exchange()`, and `create_dispenser()` to enhance developer experience.

Ocean's architecture allows for >1 implementations of ERC20, each with its own "template". Here are the templates:
- Template 1: [ERC20Template.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/templates/ERC20Template.sol), exposed as Python class [Datatoken](https://github.com/oceanprotocol/ocean.py/blob/main/ocean_lib/models/datatoken.py)
- Template 2: [ERC20TemplateEnterprise.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/templates/ERC20TemplateEnterprise.sol), exposed as Python class [DatatokenEnterprise](https://github.com/oceanprotocol/ocean.py/blob/main/ocean_lib/models/datatoken_enterprise.py). It inherits from template 1 in Solidity and in Python. It adds new methods: a single tx for "dispense & order", and single tx for "buy and order".
- (we can expect more templates in the future)
Template 2:
- Inherits from template 1 in both Solidity and Python.
- Solidity: [ERC20TemplateEnterprise.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/templates/ERC20TemplateEnterprise.sol)
- Python wrapper: [DatatokenEnterprise](https://github.com/oceanprotocol/ocean.py/blob/main/ocean_lib/models/datatoken_enterprise.py)
- New method: [`buy_DT_and_order()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/datatoken_enterprise.py#L20). This uses just 1 tx to do both actions at once (versus 2 txs for template 1).
- New method: [`dispense_and_order()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/datatoken_enterprise.py#L70). Similarly, uses just 1 tx.


### DIDs and DDOs
Expand Down Expand Up @@ -256,18 +264,37 @@ datatoken = data_nft.create_datatoken(DatatokenArguments("Datatoken 1", "DT1"),

If you call `create()` after this, you can pass in an argument `deployed_datatokens:List[Datatoken]` and it will use those datatokens during creation.

<h2 id="appendix-faucet-details">Appendix: Faucet Details</h4>
<h2 id="appendix-faucet-details">Appendix: Dispenser / Faucet Details</h4>


### Dispenser Interface

We access dispenser (faucet) functionality from two complementary places: datatokens, and `Dispenser` object.

### Faucet Flexibility
A given datatoken can create exactly one dispenser for that datatoken.

`create_dispenser()` can take these optional arguments:
**Interface via datatokens:**
- [`datatoken.create_dispenser()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/datatoken.py#L337) - implemented in Datatoken, inherited by DatatokenEnterprise
- [`datatoken.dispense()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/datatoken.py#L380) - ""
- [`datatoken.dispense_and_order()` - implemented in Datatoken](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/datatoken.py#L439) and [in DatatokenEnterprise](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/datatoken_enterprise.py#L70). The latter only needs one tx to dispense and order.
- [`datatoken.dispenser_status()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/datatoken.py#L403) - returns a [`DispenserStatus`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/dispenser.py#L16) object

**Interface via [`Dispenser`](https://github.com/oceanprotocol/ocean.py/blob/main/ocean_lib/models/dispenser.py) Python class:**
- You can access its instance via `ocean.dispenser`.
- `Dispenser` wraps [Dispenser.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/pools/dispenser/Dispenser.sol) Solidity implementation, to expose `Dispenser.sol`'s methods as Python methods (via Brownie).
- Note that `Dispenser` is _global_ across all datatokens. Therefore calls to the Solidity contract - or Python calls that pass through - provide the datatoken address as an argument.
- Example call: `ocean.dispenser.setAllowedSwapper(datatoken_addr, ZERO_ADDRESS, {"from": alice})`

### Flexibility in Creating a Dispenser

`datatoken.create_dispenser()` can take these optional arguments:
- `max_tokens` - maximum number of tokens to dispense. The default is a large number.
- `max_balance` - maximum balance of requester. The default is a large number.

A call with both would look like `create_dispenser({"from": alice}, max_tokens=max_tokens, max_balance=max_balance)`
A call with both would look like `create_dispenser({"from": alice}, max_tokens=max_tokens, max_balance=max_balance)`.


### Faucet Tips & Tricks
### Dispenser Status

To learn about dispenser status:

Expand All @@ -290,15 +317,51 @@ DispenserStatus:
allowed_swapper = anyone can request
```

### Who can request tokens from a faucet

Template 1 (`Datatoken`):
- Anyone can call `datatoken.dispense()` to request tokens.

Template 2 (`DatatokenEnterprise`):
- Option A. Anyone can `datatoken.dispense_and_order()` to request tokens, and order.
- Option B. Not anyone can call `datatoken.dispense()` by default. To allow anyone, the publisher does: `ocean.dispenser.setAllowedSwapper(datatoken_address, ZERO_ADDRESS, {"from" : publisher_wallet})`, where `ZERO_ADDRESS` is `0x00..00`.

Details: `Dispenser.sol` has an attribute `allowed_swapper` to govern who can call `dispense()`. A value of `0x00...0` allows anyone. Template 1 has `ZERO_ADDRESS` as a default value; template 2 does not. However, template 2 allows anyone to call `dispense_and_order()`, independent of the value of `allowed_swapper`.

<h2 id="appendix-exchange-details">Appendix: Exchange Details</h4>

### Exchange Flexibility
### Exchange Interface

When Alice posted the dataset for sale via `create_exchange()`, she used OCEAN. Alternatively, she could have used H2O, the OCEAN-backed stable asset. Or, she could have used USDC, DAI, RAI, WETH, or other, for a slightly higher fee (0.2% vs 0.1%).
We access exchange functionality from three complementary places: datatokens, [`OneExchange`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/fixed_rate_exchange.py#L117) object, and (if needed) [`FixedRateExchange`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/fixed_rate_exchange.py#L106) object.

A given datatoken can create one or more `OneExchange` objects.

**Interface via datatokens:**
- [`datatoken.create_exchange()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/datatoken.py#L237) - Returns a `OneExchange` object.
- [`datatoken.get_Exchanges()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/datatoken.py#L312) - Returns a list of `OneExchange` objects.

Once you've got a `OneExchange` object, most interactions are with it.

**Interface via [`OneExchange`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/fixed_rate_exchange.py#L117) Python class:**
- [`BT_needed()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/fixed_rate_exchange.py#L150) - # basetokens (BTs) needed, to buy target # datatokens (DTs)
- [`BT_received()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/fixed_rate_exchange.py#L167) - # BTs you receive, in selling given # DTs
- [`buy_DT()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/fixed_rate_exchange.py#L184) - spend BTs to buy DTs
- [`sell_DT()`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/fixed_rate_exchange.py#L230) - sell DTs, receive back BTs
- and more, including get/set rate (price), toggle on/off, get/set fees, update balances

While most interactions are with `OneExchange` described above, sometimes we may want to access the `FixedRateExchange` object.

### Exchange Tips & Tricks
**Interface via [`FixedRateExchange`](https://github.com/oceanprotocol/ocean.py/blob/4aa12afd8a933d64bc2ed68d1e5359d0b9ae62f9/ocean_lib/models/fixed_rate_exchange.py#L106) Python class:**
- You can access its instance via `ocean.fixed_rate_exchange`.
- `FixedRateExchange` wraps [FixedRateExchange.sol](https://github.com/oceanprotocol/contracts/blob/main/contracts/pools/fixedRate/FixedRateExchange.sol) Solidity implementation, to expose `Dispenser.sol`'s methods as Python methods (via Brownie).
- Note that `FixedRateExchange` is _global_ across all datatokens. Therefore calls to the Solidity contract - or Python calls that pass through - provide the exchange id address as an argument. It's exchange id, and not datatoken, because there may be >1 exchange for a given datatoken.
- Example call: `ocean.fixed_rate_exchange.getRate(exchange_id)` returns rate (price).

### Flexibility in Creating an Exchange

When Alice posted the dataset for sale via `create_exchange()`, she used OCEAN. Alternatively, she could have used H2O, the OCEAN-backed stable asset. Or, she could have used USDC, DAI, RAI, WETH, or other, for a slightly higher fee (0.2% vs 0.1%).

### Exchange Status

Here's how to see all the exchanges that list the datatoken. In the Python console:
```python
Expand Down Expand Up @@ -341,6 +404,12 @@ ExchangeFeeInfo:

<h2 id="appendix-consume-details">Appendix: Consume Details</h4>

### Consume General

To "consume" an asset typically means placing an "order", where you pass in 1.0 datatokens and get back a url. Then, you typically download the asset from the url.

For more information, search for "order" in this README or related code.

### About ARFF format

The file is in ARFF format, used by some AI/ML tools. Our example has two input variables (x0, x1) and one output.
Expand All @@ -361,3 +430,27 @@ The file is in ARFF format, used by some AI/ML tools. Our example has two input
-3.9286,0.0000,206.1783
...
```

<h2 id="appendix-consume-details">Appendix: Ocean Instance</h4>

At the beginning of most flows, we create an `ocean` object, which is an instance of class [`Ocean`](https://github.com/oceanprotocol/ocean.py/blob/main/ocean_lib/ocean/ocean.py). It exposes useful information, including the following.

Config dict attribute:
- `ocean.config_dict` or `ocean.config -> dict`

OCEAN token:
- `ocean.OCEAN_address -> str`
- `ocean.OCEAN_token` or `ocean.OCEAN -> Datatoken`

Ocean smart contracts:
- `ocean.data_nft_factory -> DataNFTFactoryContract`
- `ocean.dispenser -> Dispenser` - faucets for free data
- `ocean.fixed_rate_exchange -> FixedRateExchange` - exchanges for priced data

Simple getters:
- `ocean.get_nft_token(self, token_address: str) -> DataNFT`
- `ocean.get_datatoken(self, token_address: str) -> Datatoken`
- `ocean.def get_user_orders(self, address: str, datatoken: str)`
- (and some others that are more complex)

It also provides Python wrappers to veOCEAN and Data Farming contracts. See [df.md](df.md) for details.

0 comments on commit b5b6dcd

Please sign in to comment.