The Erasure Protocol builds on the three primitives of an economic relationship: Track-Record, Payment, and Recourse.
Erasure_Posts
keep track of the hash and timestamp of all the data submitted to the protocol. This serves as a proof of existence on which a track-record can be built. Creating a Post
instance is as simple as submitting a hash of your data to your Feed
smart contract. At first the data is hidden, but it can be publicly revealed at a later point by uploading it to decentralized storage. A Feed
allows for a user to establish credibility through an ordered history of Post
submissions. Since these posts are in a single append-only array, it is not possible to erase or reorder them once submitted. A single post works great for one time submissions and a feed is designed for use-cases with continuous predictions.
The hash which is submitted to Erasure is called a ProofHash
. A proofhash should be generated by taking the SHA-256 hash of the submitted data prepended with a user address and a user generated salt to avoid potential impersonation or snooping attacks.
For v1.2.0 of the protocol, the proofhash should follow the following format:
proofhash_v120 = sha256(JSON({
creator: userAddress,
datahash: multihashformat(sha256(rawdata)),
keyhash: multihashformat(sha256(SymKey)),
encryptedDatahash: multihashformat(sha256(SymKey.encrypt(rawdata))),
}))
The Erasure Protocol is designed to support any Ethereum-native cryptocurrencies such as ETH, WBTC and NMR within its programmable escrow smart contracts. The first escrow template called CountdownGriefingEscrow
supports payments in NMR. All Erasure escrows are registered in the Erasure_Escrows
registry which contributes to the single source of truth.
Recourse is achieved when a party is punished for wrongdoing. In the world of Erasure, this translates directly to staking and burning. When two parties decide to engage, they begin by staking NMR and agreeing on a set of conditions for punishment. We call this combination of skin in the game and rules of engagement an Erasure_Agreements
.
The first type of agreement used on Erasure is called Griefing
. Griefing allows a party to come to a resolution without a third party arbitrator through punishing their counterparty at a cost. This follows research in neuroeconomics which observes that cooperation evolves in populations where altruistic punishment such as griefing is possible.
Creating a Griefing agreement is as simple as having two parties agree on their respective “ratio” and amount to stake. Your ratio represents some amount of NMR that your counterparty can spend (“cost”) to burn 1 NMR of yours (“punishment”). When griefing occurs, both the cost and the punishment are burned from the NMR supply forever.
Take for example an agreement between Alice and Bob. Alice is anonymous and has not built a track record. She stakes 500 NMR and selects a ratio of 0.5. Bob, however, has revealed his real-world identity and has an excellent track record. As such, he stakes 100 NMR and selects a ratio of 1.0.
Please note: punishments are paid from pre-committed NMR stake but costs are paid from liquid NMR tokens.
Action | Resulting Alice stake | Resulting Bob stake |
---|---|---|
Alice stakes 500 NMR with ratio 0.5 | 500 | 0 |
Bob stakes 100 NMR with ratio 1.0 | 500 | 100 |
Bob pays 5 NMR to punish Alice for 10 NMR | 490 | 100 |
Alice pays 10 NMR to punish Bob for 10 NMR | 490 | 90 |
Griefing avoids relying on a centralized oracle or a trusted third party to perform arbitration over the terms of the agreement and instead allows the parties to come to a resolution on their own. As new techniques for resolution like decentralized oracles are built on Ethereum, it will be possible to add them to the set of Erasure_Agreements
.
Every agreement, user, entry, whatever may have its own account, and those accounts (or the factories that deploy them) can report back to simple, shared registries that establish a single source of truth for the Erasure Protocol. This grants individual agents in the system the authority to opt-in to new changes, gives rise to a diversity of options for how to interact with the system, and makes the system more decentralized.
So far, the registries developed are:
Erasure_Agreements
Erasure_Posts
Erasure_Users
Erasure_Escrows
Using the Spawner library, every item on Erasure is created as a clone of a previously deployed template. We call these Clone Factories. Every clone is also registered in a registry which provides a single source of truth on the status of the protocol.
New User Registration
- New user connects to
ErasureClient
ErasureClient
generates asymmetric encryption keysPubKey
,PrivKey
ErasureClient
uploadsPubKey
toErasure_Users
Creating a Post
Seller
creates aFeed
usingFeed_Factory.create()
with optional paramsSeller
uploadsrawdata
toErasureClient_Seller
ErasureClient_Seller
generates symmetric encryption keySymKey
ErasureClient_Seller
computesencryptedData = SymKey.encrypt(rawdata)
ErasureClient_Seller
computeskeyhash = sha256(SymKey)
ErasureClient_Seller
computesdatahash = sha256(rawdata)
ErasureClient_Seller
computesencryptedDatahash = sha256(encryptedData)
ErasureClient_Seller
computesjson_proofhash_v120 = JSON(address_seller, multihashformat(datahash), multihashformat(keyhash), multihashformat(encryptedDatahash))
ErasureClient_Seller
computesproofhash = sha256(json_proofhash_v120)
ErasureClient_Seller
submitsproofhash
to hisFeed
contractErasureClient_Seller
uploadsjson_proofhash_v120
to ipfs atmultihashformat(proofhash)
ErasureClient_Seller
uploadsencryptedData
to ipfs atmultihashformat(encryptedDatahash)
ErasureClient_Seller
creates aPost
usingFeed.submitHash(proofhash)
Selling a Post
Seller
createsEscrow
usingCountdownGriefingEscrow_Factory.create()
with mandatory paramsErasureClient_Seller
deposits the required stake usingEscrow.depositStake()
Buyer
deposits the required payment usingEscrow.depositPayment()
ErasureClient_Seller
retrievesPubKey_Buyer
fromErasure_Users
contractErasureClient_Seller
computesencryptedSymKey_Buyer = PubKey_Buyer.encrypt(SymKey)
ErasureClient_Seller
computesjson_selldata_v120 = JSON(encryptedSymKey_Buyer, multihashformat(proofhash))
ErasureClient_Seller
finalizes the escrow usingEscrow.finalize()
with creates a griefing agreementAgreement
ErasureClient_Seller
uploadsjson_selldata_v120
to ipfs atmultihashformat(sha256(json_selldata_v120))
ErasureClient_Seller
submitsjson_selldata_v120
to buyer usingEscrow.submitData(multihashformat(sha256(json_selldata_v120)))
ErasureClient_Buyer
retrievesencryptedSymKey_Buyer
fromEscrow
contractErasureClient_Buyer
retrievesencryptedData
fromipfs.proofhash.encryptedDatahash
ErasureClient_Buyer
retrievesdatahash
fromipfs.proofhash.datahash
ErasureClient_Buyer
retrieveskeyhash
fromipfs.proofhash.keyhash
ErasureClient_Buyer
computesSymKey = PrivKey_Buyer.decrypt(encryptedSymKey_Buyer)
ErasureClient_Buyer
computesrawdata = SymKey.decrypt(encryptedData)
ErasureClient_Buyer
validateskeyhash
matchessha256(SymKey)
ErasureClient_Buyer
validatesdatahash
matchessha256(rawdata)
Revealing a Post
ErasureClient_Seller
uploadsSymKey
to ipfs atmultihashformat(keyhash)
ErasureClient_Seller
uploadsrawdata
to ipfs atmultihashformat(datahash)
See latest release.