UPDATE: So far this is looking feasible and multifunctional. I created a FAQ at the github repo where I’m going to try to address challenges and answer some common questions I’ve received on reddit: CATs-CardanoAccessTokens/FAQ.md at main · MadeWithLovelace/CATs-CardanoAccessTokens · GitHub
I’m still amateur with haskell and plutus, so maybe I’m wrong about this technically working as I believe it would, so at this point it’s conceptual and I’ll be working to prove the concept the next days.
Imagine this problem: Alice locks funds at a script for a DEX and wants to cancel the order. The smartcontract checks that her pubkeyhash was saved in her datum upon locking, matching the unlock transaction signer with the datum-stored pubkey. The limitation/weakness/vulnerability in this approach means you must trust that the datum was entered as you expected at the time of transaction being built. Datum could be deliberately altered on the back end of a webapp, putting a different pubkeyhash into the datum.
To solve this in a way where we lean nearly entirely on the smartcontract validator, even if using a webapp where we don’t want to be forced to entirely trust the datum entry not being altered, we have to use something that is both available to the smartcontract and irrefutably provable. To be visible it must be in this unlocking transaction script context…like a utxo, a txin or txout, etc. We can also know who signed this unlock from the script context, which is being used to match against datum in the other example.
The solution/concept/proposal I’m working on is “CATs” or Cardano Access Tokens.
To validate this in a way that does not rely on datum having been entered as you expected, and to do so very transparently and irrefutably, Cardano Access Tokens would be a custom token you mint from the relevant wallet, via a minting script which enforces that the name of the token is your pubkeyhash and embeds into the token’s metadata useful information, including this token’s policy hash and locking height for other forms of ownership validation.
How this works in a smartcontract, wherein you don’t need to trust the datum, is as follows:
- Alice includes one of her CATs in the locking transaction (note, I’m calling them CAT as a generalization, the actual token name would match the wallet owners pubkeyhash)
- When Alice goes to retrieve her utxo from the smartcontract, she signs a tx that includes another of her CATs and spends both CATs to her own wallet. The script validates this by comparing:
ScriptContext Signedby == name of CAT in tx-in from wallet == name of CAT in tx-in from script
and that the CATs are being returned to their owner - It can additionally compare against an expected-stored datum value of the pubkeyhash if that were useful in some way.
In addition, smartcontracts could be written to not compare agains the signer for various reasons/usecases, but return the CATs to the owner. And on that note, there would be no issue with a non-owner having a CAT, if the smart contract is written to only allow the unlocking TX if the signer has a matching CAT, it wouldn’t validate a non-owner if it shouldn’t. So a CAT is pretty much useless to a non-owner for nefarious gain, rather useful for a known/trusted CAT “sitter”.
Here is a github I started where I’ll be updating, fielding this concept out more, and posting any progress on testing and proof of concept: GitHub - MadeWithLovelace/CATs-CardanoAccessTokens
I’m pretty new to Haskell and Plutus so I may be missing something about coding it in, so as I said I’ll be testing, but curious to hear from more experienced coders who might know.
Update I was unaware of the token name byte limitation of 32. What this means IMO for this idea/proposal is that the implementation does rely on the datum afterall, and in just as effective a way like so → pubkeyhash is split up, 32 bytes goes to the CAT name, the other 24 bytes from the pubkeyhash are stored in the datum, or vise versa (we’d need a standardized/expected format). Then upon validation the smart contract will check that the CAT name + Datum stored pubkey portion, are equal to the transaction signer for this unlock… and that both CATs are matched/from same policy and being spent to the owner. Updated the git: Native Token name length restriction of 32 bytes · Issue #1 · MadeWithLovelace/CATs-CardanoAccessTokens · GitHub
(edited for clarity)