Last active
December 14, 2023 14:49
-
-
Save chasefleming/0d5e21606cf8c9a3d5584a0625544c29 to your computer and use it in GitHub Desktop.
Cadence Cheatsheet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Cadence is a resource-oriented programming language for smart contracts on the Flow blockchain. | |
/////////////// | |
// 1. Basics // | |
/////////////// | |
// This is a single-line comment | |
/* | |
This is a multi-line comment | |
*/ | |
// Declare a constant | |
let x: Int = 42 | |
// Declare a variable | |
var y: Int = 5 | |
y = 10 // Re-assign the variable | |
// Strings | |
let hello: String = "Hello, World!" | |
// Arrays | |
let numbers: [Int] = [1, 2, 3, 4, 5] | |
// Dictionaries | |
let fruits: {String: Int} = {"apple": 5, "banana": 8} | |
// Optionals: Cadence supports optionals, which can either hold a value or be nil. | |
var maybeInt: Int? = nil | |
maybeInt = 42 | |
// To safely access the value inside an optional, you can use conditional unwrapping: | |
if let actualInt = maybeInt { | |
log(actualInt) // This will log the value 42 | |
} | |
//////////////////////// | |
// 2. Functions & Types// | |
//////////////////////// | |
// Define a function | |
pub fun add(a: Int, b: Int): Int { | |
return a + b | |
} | |
// Structs | |
pub struct Point { | |
pub var x: Int | |
pub var y: Int | |
init(x: Int, y: Int) { | |
self.x = x | |
self.y = y | |
} | |
} | |
// Enums | |
pub enum Direction: UInt8 { | |
pub case north | |
pub case south | |
pub case east | |
pub case west | |
} | |
//////////////////////// | |
// 3. Resources & Contracts // | |
//////////////////////// | |
// Resources are a special type in Cadence, representing a unique value. | |
// They have to be carefully managed, as they can only exist in one place at a time. | |
// The purpose of resources is to represent a unique ownable asset, such as an NFT. | |
pub resource R { | |
pub var n: Int | |
init(n: Int) { | |
self.n = n | |
} | |
} | |
// Contracts are the top-level declarations in Cadence. | |
// They can declare multiple types, resources, and functions, as well as storing value. | |
// They are like digital programs that can be deployed and executed by anyone on the Flow blockchain. | |
pub contract C { | |
pub var count: Int | |
init() { | |
self.count = 0 | |
} | |
pub fun increment() { | |
self.count = self.count + 1 | |
} | |
} | |
//////////////////////// | |
// 4. Scripts // | |
//////////////////////// | |
// Scripts are submited to the network to read the state of the blockchain. | |
// They can be executed by anyone, but they cannot mutate the global state. | |
pub fun main(a: Int, b: Int): Int { | |
// This is where the main logic of the script goes | |
} | |
//////////////////////// | |
// 5. Transactions // | |
//////////////////////// | |
// Transactions are submitted to the network to mutate state. | |
// Signer is an account that authorizes this transaction and allows it to modify its account assets. | |
import Foo from 0xABC123 | |
transaction(a: Int, b: Int) { | |
prepare(signer: AuthAccount) { | |
// This is where resources can be withdrawn from accounts | |
} | |
execute { | |
// This is where the main logic of the transaction goes | |
Foo.bar(a, b) // This calls a function on another contract | |
} | |
} | |
//////////////////////// | |
// 6. Events // | |
//////////////////////// | |
// Events allow smart contracts to log information about changes in their state. | |
pub event NewValueSet(value: Int) | |
//////////////////////// | |
// 7. Capabilities // | |
//////////////////////// | |
// A contract or a resource can have an interface that declares a certain set of functions. | |
pub resource interface Readable { | |
pub fun read(): Int | |
} | |
// A contract or resource that wants to be "Readable" must conform to this interface. | |
pub resource ReadableResource: Readable { | |
pub var data: Int | |
init(initData: Int) { | |
self.data = initData | |
} | |
pub fun read(): Int { | |
return self.data | |
} | |
} | |
// In Cadence, accounts have storage that is organized through paths. | |
// There are three types of paths: storage, private, and public. | |
// - /storage/ : Used to store and manage values, particularly resources. | |
// - /private/ : Used to store private capabilities. | |
// - /public/ : Used to store public capabilities. | |
// In a real-world scenario, you'd typically have an account that stores an instance of `ReadableResource` in storage. | |
// Then, it can publish a capability that allows others to borrow a reference to that instance with the restrictions | |
// imposed by the `Readable` interface. This way, other accounts can only invoke the methods allowed by the interface, not all methods on the resource. | |
// Store a resource in an account's storage | |
account.save(<- create ReadableResource(initData: 10), to: /storage/MyResource) | |
// Link a public capability so others can borrow a reference (note: in this example `Test` is the name of the contract) | |
account.link<&Test.ReadableResource{Test.Readable}>(/public/Readable, target: /storage/MyResource) | |
// An external account can then borrow a reference using the capability: | |
// (note: "getAccount" is a Cadence function that returns an account by address) | |
let publicAccount = getAccount(address) | |
let readerRef: &{Test.Readable}? = publicAccount.getCapability(/public/Readable).borrow<&{Test.Readable}>() | |
if let ref = readerRef { | |
let value = ref.read() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can I store a borrowed capability in my account?
Can I allow other accounts to use a capability my account has borrowed?
What is the pattern for revoking a capability?