Cadence at a Glance
--
The Cadence programming language accelerates and simplifies secure smart contract programming by introducing resources and capabilities, enabling advanced use cases like resource nesting and composition. At the same time, Cadence powers transactions and queries on Flow.
Resources to manage ownership
Cadence is easy to learn, because it has many similarities with other programming languages like Rust, TypeScript and Swift. The big difference is that Cadence is all about resources.
Resources are easy to understand because they are the actual thing — a vault for tokens, a NBA Topshot moment — and because they are stored right in the account of their owner. That’s why Cadence code is easy to read, maintain and talk about.
pub resource NFT {
pub let id: UInt64
pub var metadata: {String: String}
...
}
In technical terms, resource types are similar to classes — they represent a collection of data and functions. However, they introduce strict rules on how a developer can handle them:
- Resources can only exist in one exact place at one exact time
- Resources cannot be copied
- Resources have to be explicitly destroyed
This prevents harmful duplication and accidental deletion of a resource, making them a good fit for blockchain applications. The move operator, a special operator for transferring resources, provides a visual cue when dealing with resources.
let myResource <- create NFT(...)
Resources also allow for advanced use cases like composition and nesting. To group items, you simply create a collection resource as a wrapper. This makes batch transfers — the transfer of multiple resources at the same time — easy to implement.
Capabilities for access-control
Capabilities are similar to permissions: they control what actions a user can take on a given resource. If you want to call a resource’s method, you need to have a valid capability.
Capabilities are the gateway to resources. Like a REST API, capabilities have a path. If that path lives in the public domain of an account, the capability can be obtained by anyone; capabilities in the private domain are only accessible by the owner of that account.
Regardless if in public or private domain, capabilities always link to a target. This target can be an entire resource or just a subset of its methods. For the latter, interfaces may act as a target for the capability. This is how capabilities allow fine-grained and human-readable access control.
To interact with a resource, you first have to get the specific capability before borrowing its underlying resource. This can be done within transactions.
account.getCapability<...>(/public/MyCapability).borrow()
Interact with transactions and scripts
Transactions allow you to mutate on-chain data. On Flow, transactions are written in Cadence. They usually consist of two stages: Prepare and execute.
transaction {
prepare (acct: AuthAccount) {
...
}
execute {
...
}
}
For each signer of the transaction, the corresponding AuthAccount
is passed to the prepare
phase of the transaction, providing full access to the storage as well as the private and public domains of the signing account.
If you only want to query on-chain data without mutating it you can run a script. In Cadence, scripts consist of a public function main
that is run on execution:
pub fun main () {
log("Hello world!")
}
Further readings
If you want to start building quickly with Cadence, check out the official tutorial series, in which you will code a whole marketplace with integrations for fungible and non-fungible tokens.
When you’re looking for a more comprehensive and in-depth documentation of the language, check out the thorough Cadence reference:
Anytime you want to try Cadence without having to set up a local development environment, take a look at the Cadence Playground: