One of the topics discussed recently has been the issue of paywalls. This post describes the problems, and proposes a creative solution that can be turned into a sustainable product for users of the network. I’d love to get some feedback on the idea, refine it, and eventually support anyone that wants to pick it up and build it.
The Problem
Consider the case of a contract offering some asset or content for sale. The contract would set a price in SCRT, sSCRT, or any other SNIP-20 (sETH, sWBTC, etc), and once it received those funds from some sender, it would then send some other funds/NFT/asset to the sender in exchange.
While non-trivial, a very dedicated attacker can create a private fork of the chain where they would send a forged message to the contract with more SCRT than they have in reality (i.e. mainnet). A contract accepting SCRT as payment will then release the funds on sale to the attacker. One example of such a contract is sSCRT, which allows users to deposit SCRT in exchange for sSCRT. These “stolen” tokens can in turn be “sold” to an AMM pair (SecretSwap, SiennaSwap) or an auction to “steal” any number of other tokens, which can in turn be used to steal other assets down the line (such as NFTs).
This sounds scary at first, but it actually isn’t at all, and is the same case in any blockchain out there. The trick is that those assets aren’t real, because they only have value when owned on mainnet. That’s kind of the whole idea of decentralized consensus.
That being said, the issue begins when the content held by the selling contract is a secret in itself. Imagine you wanted to put a private key to some encrypted file up for sale in the Secret Network. Say you offered it in exchange for 2 sETH. An attacker wouldn’t need to pay you, they would just need to trick the contract (with great technical effort!) into giving away the secret.
While this approach is difficult and expensive to execute, it will eventually be worth it for someone to do it, if something valuable enough was put on sale.
The Solution
Fortunately there is a really simple solution to this, which i think can be turned into its own platform, and generally feels closer to how trading valuables works in real life.
The selling contract would allow buyers to deposit funds from any number of payment options listed by the seller in the contract initialization. The seller would then be able to see which addresses have deposited payments for the secret asset. Then, seeing that the deposits have really been made on mainnet, the seller would be able to send an approval transaction with the list of approved buyer addresses. The contract would send the payments made by those buyers to the seller’s account. (it’s important that the approval message contains the address of the buyer, and maybe even the address of the selling contract itself, which would be verified in the contract, to protect against cross-contract replay attacks). That’s all we need to prevent off-chain attacks, as the seller would act as its own contract’s oracle, regarding the state of the chain. You can also automate the sale using a bot acting for the seller. The approved buyers would then be allowed to query the contract for the secret product (using viewing keys for example) and users not approved for the purchase would be able to withdraw their deposit. The contract could also allow the seller to blacklist or whitelist addresses if they want to.
We can then build a UI for this product which would allow a workflow similar to that of platforms that allow artists to accept commissions or sell a limited amount of artifacts to buyers that offer to but them. Put up something for sale, name your minimum prices, review buyers, approve whoever you like, etc. You could even allow buyers to add notes to their deposits which the seller can review. Then tick a checkbox for approved buyers and approve them by clicking a nice big “Approve” button.
Whoever sets this up as a service with a nice UI and everything, can monetize it by setting a small fee (some % of the approved purchases, i.e. the sellers profits) which contracts initialized by the UI would know and send some funds to each time purchases were approved. If someone really didn’t want to pay for the convenience of the website, they could set up their own sale contract.
To recap, this is a sketch of the core functionality:
Init
{
"title": "The answer to life the universe and everything",
"description": "You won't believe it when you see it!",
"product": "It's 42!",
"whitelist": [],
"blacklist": [],
"prices": [
{"token": "uscrt", "amount": 10000000},
{"token": "secret1wuzzjsdhthpvuyeeyhfq2ftsn3mvwf9rxy6ykw", "amount": 10000}
]
}
Handles:
{"deposit": {"note": "Yooooo can't wait to find out that secret"}} // for SCRT purchases
{"receive": {/* SNIP-20 Receive + message has a similar format to above */}} // for SNIP-20 purchases
{"withdraw": {}} // withdraw the deposited funds, forfeit the purchase
{"approve": {"contract": "secret1asdf", buyers: ["secret1dude", "secret1whatshername"]}}
Queries:
{"offers": {/* seller authentication */}} // get buyer list with used payment method
{"redeem": {/* buyer authentication */}} // Try to read the purchased secret
Again, would love to hear your feedback, how we could make this work with NFTs (CC @baedrik) and not just static secret strings, and what other improvements can be made to the concept. Thanks!