I guess this pattern is ready to be shown to the world. I call it Security (as we’re implementing financial securities at dfinance.
Module code is here (link).
Managing permissions isn’t easy, given borrow checker limitations and inability to read structure outside of its module, and unless you want to let people to copy anything stored inside
Permission<For>, you have to use a resource in it. Even more - to check this resource you’d need to unpack and then re-pack the resource after the check is done. This statement requires a lot of explanation which I’ll skip in this text.
If there’s an alternative (and cheaper) way to do it, I’ll be glad to hear about it @sam.
Another problem (which is solved by this pattern) is that some systems (such as dfinance) may require more gas on CRUD operations with the resource and it’s cheaper to carry/store representation of a resource instead of actually moving resource to its owner. It also solves the problem of tracking resources inside the system.
Example (a bit complicated):
- You have a debt contract and both lender and borrower need to know where the deal resource is stored. Howewer you want to allow borrower to sell his debt to another user who then becomes another borrower. Tracking this deal resource may become impossible if someone puts a bunch of debts into another resource and sells it as a pack. All the assets stored in this deal are locked unless the pack is unpacked (huh).
Security pattern - a resource pair where one is
Security<For: copyable> and the other one is the
Proof for this security. Both resources hold unique identifier of a security - a pair
(address, id) which cannot be compomised as for getting address a
signer type is used and ID is incremental for each each user.
If you’re new to move, see what is signer (link).
Security can be proved only by its Proof. Why? Because they both hold unique ID which cannot be compromised.
Proving operation automatically destroys both Proof and Security and confirms that Security can be applied in specific case.
Security<For: copyable>can only hold copyable type which means that no one can lock their resources inside Security while being unable to prove.
Proof is stored on the side of the prover (say, inside a Deal resource) while Security is can be passed/sold freely over the network.
Security is meant to be lightweight resource -
<For>generic inside may point to Deal address and maybe to deal_id.
One can issue as many securitites as he wants for any purpose. The only thing he should care about is putting the right
Forstructure in it.
Alice creates a bank - she gives curr A for collateral B.
Bob wants to lend some money from Alice in exchange for collateral.
Bob puts his collateral (B) into a bank and gets: Security and some amount of A.
Proof for this security is stored in the bank.
Whenever Bob (or anyone else who bought this security) wants to return money, he passes his Security into a bank, where it’s being checked/proved. If that results in success, he pays back the loan and gets the collateral.
What is important - Security becomes a single pass for some financial action at specific place. If someone buys/gets resource of kind
Security<0x1::Bank::Debt>, he knows that it can be returned to the bank. And if conditions are met, this paper is destroyed-exchanged for an action.
Alice created a new token, but she only wants to allow some users to buy it (create an Option to buy this token). She issues 100 Securities of kind
Security<TokenSale>and gives/sells them to some people.
These people then (including Bob) are free to move/sell/buy these securities. And when the time of crowdsale comes, they can use this Option to buy the tokens.
Also an example for Collateral Debt Position (CDP) module. Careful - not an easy one to understand.
It is possible that Security will never find its Proof. There can be multiple reasons for that. And to not store (but also not to oblige) Security can be issued with expiration date after which both Security and Proof can be freely destroyed. This is a minor issue because it is impossible to lock an asset inside.
I’ll be glad to hear any feedback on this. Spent some time trying this concept out in different ways. Yet I may not see something useful/harmful in any way.
And if there’s no RFC source for Move, maybe we should start one?