Cadence Scripts

What is cadence ?

Cadence is a programming language designed for developing smart contracts in a blockchain environment. It introduces new features to smart contract programming that help developers ensure that their code is safe, secure, clear, and approachable. Cadence utilizes a strong static type system, resource-oriented programming, built-in pre- and post-conditions for functions and transactions, and capability-based security. Its syntax is inspired by popular modern general-purpose programming languages such as Swift, Kotlin, and Rust. Cadence aims to be safe and secure, clear, approachable, and developer-friendly. It makes use of resources to intuit ownership, which is tied to the account that owns it, ensuring that assets can only exist in one location at a time and cannot be copied or lost due to a coding mistake. The language addresses challenges with existing languages, such as safety and security concerns due to the immutable nature of blockchains and the lack of support for modifying or updating smart contracts.

Cadence Capabilities

In the Flow blockchain, the concept of "capabilities" is used to enforce access control and ensure security. A capability is an object that represents a specific permission to access a resource, such as a smart contract or a resource stored in an account.

In Flow, capabilities are created and owned by the resource itself, and can only be passed to other accounts or contracts through a special "borrow" mechanism. This mechanism ensures that access to a resource can only be granted by the owner of the resource, and that the permission to access the resource is explicitly granted on a per-resource basis.

Capabilities are also used to limit the scope of access to a resource. For example, a capability can be created that allows read-only access to a resource, or that only allows access to a specific function or method within a resource. By limiting the scope of access in this way, capabilities help to prevent unintended or malicious access to resources and reduce the risk of attacks.

Overall, the use of capabilities in Flow provides a flexible and secure access control mechanism that is well-suited to the needs of decentralized applications and smart contracts.

NFTs on Flow Blockchain

NFTs are digital assets that represent ownership of a unique asset and are indivisible. Cadence, the smart contract language on Flow blockchain, represents NFTs as a resource object stored in user accounts. This ensures NFTs benefit from resource ownership rules, protecting them from accidental or malicious programming errors.

NFTs allow for the trading of assets and proving of ownership, and on Flow, NFTs are interoperable across different smart contracts and app contexts. All NFTs on Flow implement the NFT Token Standard, defining a basic set of properties.

Core features

The NonFungibleToken contract defines the following set of functionality that must be included in each implementation.

Contracts that implement the NonFungibleToken interface are required to implement two resource interfaces:

  • NFT - A resource that describes the structure of a single NFT.

  • Collection - A resource that can hold multiple NFTs of the same type.

    Users typically store one collection per NFT type, saved at a well-known location in their account storage.

    For example, all NBA Top Shot Moments owned by a single user are held in a TopShot.Collection stored in their account at the path /storage/MomentCollection.

List NFTs in an account

Return a list of NFTs in a Collection using the getIDs function.

This function is available on the NonFungibleToken.CollectionPublic interface, which accounts publish as public capability.

let collection = account.getCapability(/public/ExampleNFTCollection)
    .borrow<&{NonFungibleToken.CollectionPublic}>()
    ?? panic("Could not borrow a reference to the receiver's collection")

let ids = collection.getIDs()

NFT Metadata

NFT metadata is represented in a flexible and modular way using the standard proposed in FLIP-0636.

When writing an NFT contract, you should implement the MetadataViews.Resolverinterface, which allows your NFT to implement one or more metadata types called views.

Each view represents a different type of metadata, such as an on-chain creator biography or an off-chain video clip. Views do not specify or require how to store your metadata, they only specify the format to query and return them, so projects can still be flexible with how they store their data.

The NonFungibleToken and MetadataViews contracts are already deployed on various networks. You can import them in your contracts from these addresses. There is no need to deploy them yourself.

Note: With the emulator, you must use the -contracts flag to deploy these contracts.

NetworkContract Address

Emulator/Canary

0xf8d6e0586b0a20c7

Testnet

0x631e88ae7f1d7c20

Mainnet

0x1d7e57aa55817448

How to read metadata

This example shows how to read basic information about an NFT including the name, description, image and owner.

Source: get_nft_metadata.cdc

import ExampleNFT from "..."
import MetadataViews from "..."

// ...

// Get the regular public capability
let collection = account.getCapability(ExampleNFT.CollectionPublicPath)
    .borrow<&{ExampleNFT.ExampleNFTCollectionPublic}>()
    ?? panic("Could not borrow a reference to the collection")

// Borrow a reference to the NFT as usual
let nft = collection.borrowExampleNFT(id: 42)
    ?? panic("Could not borrow a reference to the NFT")

// Call the resolveView method
// Provide the type of the view that you want to resolve
// View types are defined in the MetadataViews contract
// You can see if an NFT supports a specific view type by using the `getViews()` method
if let view = nft.resolveView(Type<MetadataViews.Display>()) {
    let display = view as! MetadataViews.Display

    log(display.name)
    log(display.description)
    log(display.thumbnail)
}

// The owner is stored directly on the NFT object
let owner: Address = nft.owner!.address!

// Inspect the type of this NFT to verify its origin
let nftType = nft.getType()

// `nftType.identifier` is `A.e03daebed8ca0615.ExampleNFT.NFT`

Core views

The views categorized as "Core views" are deemed as the essential views that must be included to offer a comprehensive representation of an NFT. If you intend to have your NFT displayed on the Flow NFT Catalog, it is mandatory to have all of these views implemented.

NFT Catalog

The NFT Catalog is a registry that resides on the blockchain and catalogs the NFT collections available on Flow blockchain that conform to the NFT metadata standard. This enables developers of decentralized applications to conveniently develop on top of and find compatible NFT collections on Flow.

NFTCatalog.cdc: This contract contains the NFT Catalog

NetworkAddress

Mainnet

0x49a7cda3a1eecc29

Testnet

0x324c34e1c517e4db

NFTRetrieval.cdc: This contract contains helper functions to make it easier to discover NFTs within accounts and from the catalog

NetworkAddress

Mainnet

0x49a7cda3a1eecc29

Testnet

0x324c34e1c517e4db

Last updated