A Better Digital Asset
Hey friends - a heads up that the following is more technical than usual. It’s my intro to Cadence, the smart contract language used on Flow. I’ll see ya next week if not your jam. Onward.
________
Dapper Labs introduced Cadence to solve problems it faced while building apps on Ethereum like CryptoKitties and Dapper Wallet.
Those problems arose in part because tokens on Ethereum are represented as basically a synchronized mapping of tokens to owners. It’s easy to understand, but opens vulnerabilities to several challenges:
Higher attack risk as all the logic and state is contained in a central contract. Any exploit is likely to affect all users who are involved in the contract.
Centralized public table of asset owners (i.e. maybe you do not want to publicly display every asset you own)
Anyone can send assets to anyone without their permissions (i.e. there is nothing to prevent someone from sending spam tokens to an account)
Cadence on Flow has a different model that allows certain benefits like:
Ownership is decentralized and does not rely on a central ledger
Bugs and exploits present less risk for users and less opportunity for attackers
Users can only send assets to accounts that agree to receive it
Cadence is a new type of language to most developers. The new core concepts are Resources and Capabilities.
Resources are objects like NFTs and FTs. They have important ownership rules that are enforced such as: they can only have one owner, cannot be copied, and cannot be accidentally lost or deleted.
Capabilities are permissions that allow access to interact with a Resource. Capabilities allow others to do things like view token balance, deposit tokens into your account, or withdraw NFTs from your account when sold on a marketplace. Without expressed Capabilities, these actions would be rejected. Capabilities can be public, or private for just those you provide a link.
Ownership
When you own a Resource, it is stored within your account storage. Your storage is like a locker room with many separate lockers for your stuff. Each locker holds items of a specific type (e.g. a type of NFT or a specific cryptocurrency). There’s two categories of lockers:
Vaults are for fungible tokens. It’s main purpose is to manage the token balance.
Collections are for NFTs. They hold an inventory of NFTs and the associated NFT IDs.
Each locker has a location designated in syntax similar to a traditional file system. It could look something like this: /storage/NBAtopshots or /storage/fungibleToken1
Here’s how you set up a Vault for fungible token storage:
Code establishing Capability to receive tokens in the vault:
// Create a public Receiver capability to the Vault
let ReceiverRef = acct.link<&ExampleToken.Vault{ExampleToken.Receiver, ExampleToken.Balance}>(/public/CadenceFungibleTokenTutorialReceiver, target: /storage/CadenceFungibleTokenTutorialVault)
Here’s how you set up a Collection for non-fungible token storage:
Code establishing Capability to receive tokens in the Collection:
// create a public capability for the Collection
acct.link<&{ExampleNFT.NFTReceiver}>(ExampleNFT.CollectionPublicPath, target: ExampleNFT.CollectionStoragePath)
Mint
To mint a FT simply adds to total token supply, then deposits the amount in the recipient’s vault.
Minting an NFT creates a new resource, increments the ID number, and returns the token to be deposited into the recipient’s storage. Below, the first snippet calls the mintNFT function in the next snippet.
Transfer
FT transfer involves a few steps:
Reduce balance in sender’s vault and put that amount into temporary vault
Add temp vault balance to receiver’s vault balance, then delete temp vault
NFT transfers involve a few steps as well. This is the process:
Find sender’s Collection with capability to withdraw
Withdraw NFT from collection
Find receiver collection
Deposit in receiver’s collection
One more important feature is that Resources can own other Resources, which unlocks many use cases. For example a CryptoKitty can own a KittyHat accessory. The KittyHat would be stored within the CryptoKitty storage. This means you can transfer it as one package.
As you can see, the Cadence model operates more closely to how physical items move in the real world, rather than a central ownership ledger. Time will tell if Cadence becomes a mass adopted language for web3.