71cd35112b
* [docs] fix two client scenario: add missing collateral * [integration] separate step to wait for node to be started * [cli] add option to specify ethereum private key * Remove unused imports * Fix warnings * [integration] move type definitions to correct place * [integration] wait a bit longer for a node to start in debug mode When e.g. running against Taiko test net rpc, the node start takes longer * [integration] simplify handling of codex node and client * [integration] add Taiko integration test * [contracts] await token approval confirmation before next tx * [contracts] deployment address of marketplace on Taiko * [cli] --eth-private-key now takes a file name Instead of supplying the private key on the command line, expect the private key to be in a file with the correct permissions. * [utils] Fixes undeclared `activeChroniclesStream` on Windows * [build] update nim-ethers to include PR #52 Co-authored-by: Eric Mastro <eric.mastro@gmail.com> * [cli] Better error messages when reading eth private key Co-authored-by: Eric Mastro <eric.mastro@gmail.com> * [integration] simplify reading of cmd line arguments Co-authored-by: Eric Mastro <eric.mastro@gmail.com> * [build] update to latest version of nim-ethers * [contracts] updated contract address for Taiko L2 * [build] update codex contracts to latest version --------- Co-authored-by: Eric Mastro <eric.mastro@gmail.com> |
||
---|---|---|
.. | ||
interactions | ||
Readme.md | ||
clock.nim | ||
config.nim | ||
deployment.nim | ||
interactions.nim | ||
market.nim | ||
marketplace.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)