8589e63d34
* Update codex-contracts-eth * contracts: update G2Point definition * integration: disable automatic advancing of time reason: makes reasoning about timing in tests harder, because the period is set to 60 seconds in the marketplace configuration, but this code switches to a new period every 500 milliseconds * integration: fix parameters of marketplace payouts test * integration: update test settings * integration: fix typo * integration: workaround for hardhat issue Subscriptions expire after 5 minutes when using websockets. Use http and polling instead. * integration: remove origDatasetSizeInBlocks * integration: fix proof parameters for test * integration: do not log output by default * integration: fix failure rate in test * integration: fix warning * integration: include clock in logs * integration: allow for more periods 5 periods was cutting it close, if we get too much pointer downtime, then the test would fail |
||
---|---|---|
.. | ||
interactions | ||
Readme.md | ||
clock.nim | ||
config.nim | ||
deployment.nim | ||
interactions.nim | ||
market.nim | ||
marketplace.nim | ||
proofs.nim | ||
requests.nim |
Readme.md
Codex Contracts in Nim
Nim API for the Codex smart contracts.
Usage
For a global overview of the steps involved in starting and fulfilling a storage contract, see Codex Contracts.
Smart contract
Connecting to the smart contract on an Ethereum node:
import codex/contracts
import ethers
let address = # fill in address where the contract was deployed
let provider = JsonRpcProvider.new("ws://localhost:8545")
let marketplace = Marketplace.new(address, provider)
Setup client and host so that they can sign transactions; here we use the first two accounts on the Ethereum node:
let accounts = await provider.listAccounts()
let client = provider.getSigner(accounts[0])
let host = provider.getSigner(accounts[1])
Storage requests
Creating a request for storage:
let request : StorageRequest = (
client: # address of the client requesting storage
duration: # duration of the contract in seconds
size: # size in bytes
contentHash: # SHA256 hash of the content that's going to be stored
proofProbability: # require a storage proof roughly once every N periods
maxPrice: # maximum price the client is willing to pay
expiry: # expiration time of the request (in unix time)
nonce: # random nonce to differentiate between similar requests
)
When a client wants to submit this request to the network, it needs to pay the maximum price to the smart contract in advance. The difference between the maximum price and the offered price will be reimbursed later.
Once the payment has been prepared, the client can submit the request to the network:
await storage
.connect(client)
.requestStorage(request)
Storage offers
Creating a storage offer:
let offer: StorageOffer = (
host: # address of the host that is offering storage
requestId: request.id,
price: # offered price (in number of tokens)
expiry: # expiration time of the offer (in unix time)
)
Hosts submits an offer:
await storage
.connect(host)
.offerStorage(offer)
Client selects an offer:
await storage
.connect(client)
.selectOffer(offer.id)
Starting and finishing a storage contract
The host whose offer got selected can start the storage contract once it received the data that needs to be stored:
await storage
.connect(host)
.startContract(offer.id)
Once the storage contract is finished, the host can release payment:
await storage
.connect(host)
.finishContract(id)
Storage proofs
Time is divided into periods, and each period a storage proof may be required from the host. The odds of requiring a storage proof are negotiated through the storage request. For more details about the timing of storage proofs, please refer to the design document.
At the start of each period of time, the host can check whether a storage proof is required:
let isProofRequired = await storage.isProofRequired(offer.id)
If a proof is required, the host can submit it before the end of the period:
await storage
.connect(host)
.submitProof(id, proof)
If a proof is not submitted, then a validator can mark a proof as missing:
await storage
.connect(validator)
.markProofAsMissing(id, period)