This README shows how to do steps in Ocean Data Farming (DF), where you curate data assets to earn rewards. It also helps to democratize "wash consume" until it becomes unprofitable.
Here are the steps:
- Setup, in Ganache
- Lock OCEAN for veOCEAN
- Publish dataset & exchange
- Allocate veOCEAN to dataset
- Fake-consume data
- Collect OCEAN rewards
- Repeat steps 1-6, for Eth mainnet
Let's go through each step.
Ensure that you've already (a) installed Ocean, and (b) set up locally.
First, let's set some key parameters for veOCEAN and DF. On Ganache, you can use these values as-is. But on Eth mainnet, you must choose your own. In the same Python console:
# On your asset, your DCV = DT_price * num_consumes
# Your asset gets rewards pro-rata for its DCV compared to other assets' DCVs.
DT_price = 100.0 # number of OCEAN needed to buy one datatoken
num_consumes = 3
# This is how much OCEAN to lock into veOCEAN. It can be small if you're
# the only staker on your asset. If others stake on your asset, your
# rewards are pro-rate compared to others' stake in your asset.
amt_OCEAN_lock = 10.0
Now, let's lock OCEAN for veOCEAN. In the same Python console:
# simulate passage of time, until next Thursday, the start of DF(X)
web3 = ocean.config_dict["web3_instance"]
provider = web3.provider
latest_block = web3.eth.get_block("latest")
WEEK = 7 * 86400 # seconds in a week
t0 = latest_block.timestamp
t1 = t0 // WEEK * WEEK + WEEK # this is a Thursday, because Jan 1 1970 was
t2 = t1 + WEEK
provider.make_request("evm_increaseTime", [(t1 - t0)])
#we're now at the beginning of the week. So, lock
veOCEAN = ocean.veOCEAN
OCEAN.approve(veOCEAN.address, to_wei(amt_OCEAN_lock), {"from" : alice})
import math
web3 = ocean.config_dict["web3_instance"]
latest_block = web3.eth.get_block("latest")
veOCEAN.withdraw({
"from": alice,
"gas": latest_block.gasLimit,
"gasPrice": math.ceil(latest_block["baseFeePerGas"] * 1.2),
}) # withdraw old tokens first
latest_block = web3.eth.get_block("latest")
veOCEAN.create_lock(
to_wei(amt_OCEAN_lock),
t2,
{
"from": alice,
"gas": latest_block.gasLimit,
"gasPrice": math.ceil(latest_block["baseFeePerGas"] * 1.2),
})
In the same Python console:
#data info
name = "Branin dataset"
url = "https://raw.githubusercontent.com/trentmc/branin/main/branin.arff"
#create data asset
(data_NFT, DT, ddo) = ocean.assets.create_url_asset(name, url, {"from": alice}, wait_for_aqua=False)
print(f"Just published asset, with data_NFT.address={data_NFT.address}")
#create exchange
exchange = DT.create_exchange({"from": alice}, to_wei(DT_price), OCEAN.address)
#make datatokens available on the exchange
DT.mint(alice, to_wei(num_consumes), {"from": alice})
DT.approve(exchange.address, to_wei(num_consumes), {"from": alice})
To stake, you allocate veOCEAN to dataset. In the same Python console:
amt_allocate = 100 #total allocation must be <= 10000 (wei)
ocean.ve_allocate.setAllocation(amt_allocate, data_NFT.address, web3.eth.chain_id, {"from": alice})
"Wash consuming" is when the publisher fake-consumes data to drive data consume volume (DCV) to get more rewards. Not healthy for the ecosystem long-term. Good news: if consume fee > weekly rewards, then wash consume becomes unprofitable. DF is set up to make this happen by DF29 (if not sooner). Details.
In the meantime, this README helps level the playing field around wash consume. This step shows how to do fake-consume.
# Alice buys datatokens from herself
OCEAN_pay = DT_price * num_consumes
OCEAN_alice = from_wei(OCEAN.balanceOf(alice))
assert OCEAN_alice >= OCEAN_pay, f"Have just {OCEAN_alice} OCEAN"
OCEAN.approve(exchange.address, to_wei(OCEAN_alice), {"from": alice})
exchange.buy_DT(to_wei(num_consumes), {"from": alice})
DT_bal = from_wei(DT.balanceOf(alice))
assert DT_bal >= num_consumes, \
f"Have {DT_bal} datatokens, too few for {num_consumes} consumes"
# Alice sends datatokens to the service, to get access. This is the "consume".
for i in range(num_consumes):
print(f"Consume #{i+1}/{num_consumes}...")
ocean.assets.pay_for_access_service(ddo, {"from": alice})
#don't need to call e.g. ocean.assets.download_asset() since wash-consuming
In the same Python console:
#simulate passage of time, until next Thursday, which is the start of DF(X+1)
WEEK = 7 * 86400 # seconds in a week
latest_block = web3.eth.get_block("latest")
t0 = latest_block.timestamp
t1 = t0 // WEEK * WEEK + WEEK
t2 = t1 + WEEK
provider.make_request("evm_increaseTime", [(t1 - t0)])
#Rewards can be claimed via code or webapp, at your leisure. Let's do it now.
OCEAN_before = from_wei(OCEAN.balanceOf(alice))
ocean.ve_fee_distributor.claim({
"from": alice,
"gas": latest_block.gasLimit,
"gasPrice": math.ceil(latest_block["baseFeePerGas"] * 1.2),
})
OCEAN_after = from_wei(OCEAN.balanceOf(alice))
print(f"Just claimed {OCEAN_after - OCEAN_before} OCEAN rewards")
First, you'll need to set up remotely. This will be like setup-remote.md, but for Eth mainnet.
We leave this as an exercise to the reader:)
Happy Data Farming!
At the beginning of this flows, we created an ocean
object, which is an instance of class Ocean
.
It provides convenient access to DF & VE Python objects that which wrap DF & VE Solidity contracts:
ocean.ve_ocean
orocean.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_fee_distributor -> VeFeeDistributor
ocean.ve_fee_estimate(self) -> VeFeeEstimate