Token导航 LogoToken导航TokenDH.com
研究检索external-servicegithub未标认证来源可访问许可证需确认审计提醒

cadencecadence 效率

Agent Skill

cadence 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

449

周安装

18

GitHub Stars

公开资料未说明

下载量

145
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:cadence(cadence 效率)
来源仓库:https://github.com/outblock/cadence-lang.org
仓库路径:skills/cadence
安装命令:
npx skills add https://github.com/outblock/cadence-lang.org --skill cadence
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/outblock/cadence-lang.org --skill cadence

简介

cadence 用于查找、检索和筛选相关信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中根据关键词快速定位候选结果。
  • 通过 npx skills add 命令从指定仓库安装,需结合 README 确认具体用法。
  • 安装前建议核实权限范围、维护状态及是否涉及联网或文件操作。
  • cadence 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

Cadence Smart Contract Development

Use this skill whenever you are writing, reviewing, debugging, or auditing Cadence code on the Flow blockchain.

Documentation

Tip: Append .mdx to any cadence-lang.org doc URL to get raw markdown.

AI Tools

Cadence is designed for AI-native development with three integrations:

ToolDescription
SkillsInstall with npx skills add outblock/cadence-lang.org
MCP Serverhttps://cadence-mcp.up.railway.app/mcp — docs search, code checking, type inspection
LLM Endpoints/llms.txt (index) and /llms-full.txt (complete docs)

MCP Quick Start

One-click install:

Claude Code:

claude mcp add cadence-mcp -- npx -y mcp-remote https://cadence-mcp.up.railway.app/mcp

Claude Desktop / Cursor / Antigravity / OpenCode:

{
  "mcpServers": {
    "cadence": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://cadence-mcp.up.railway.app/mcp"]
    }
  }
}

OpenCode (alternative):

{
  "mcp": {
    "cadence": {
      "type": "remote",
      "url": "https://cadence-mcp.up.railway.app/mcp"
    }
  }
}

Local stdio server (requires Flow CLI):

npx @outblock/cadence-mcp

MCP Tools: search_docs, get_doc, browse_docs, cadence_check, cadence_hover, cadence_definition, cadence_symbols. All LSP tools support mainnet/testnet imports.

Agent-Specific Setup

AgentSetup
Claude Codenpx skills add outblock/cadence-lang.org + MCP above
Claude DesktopMCP config in claude_desktop_config.json
CursorSkills + .cursor/rules file + MCP
AntigravitySkills (auto-reads SKILL.md) + MCP config
OpenCodeSkills + MCP config
CodexSkills + AGENTS.md instructions
Gemini CLISkills + GEMINI.md instructions

1. Language Fundamentals

Types at a Glance

TypeExampleNotes
Int42Arbitrary precision
UInt6410064-bit unsigned
UFix641.5Fixed-point, 8 decimals. Use for balances
Booltrue
String"hello"UTF-8
Address0x1234Account address
[T][1, 2, 3]Array
{K: V}{"a": 1}Dictionary
T?nilOptional — nil-coalesce with ??
@TResource — unique, non-copyable
&TReference — borrow without moving

Variables, Optionals, Functions

let x: Int = 42                     // immutable
var name: String = "Cadence"        // mutable

// Optionals
let val: Int? = nil
let result = val ?? 0               // nil-coalescing
if let v = val { }                  // optional binding
let forced = val!                   // force-unwrap — panics, avoid

// Functions
access(all) fun greet(name: String): String {
    return "Hello, \(name)!"
}

// view = read-only (safe in scripts and pre/post)
access(all) view fun getBalance(): UFix64 { return self.balance }

// Pre/post conditions
access(all) fun withdraw(amount: UFix64): @Vault {
    pre  { amount > 0.0:              "Amount must be positive" }
    post { result.balance == amount:  "Withdrawal amount mismatch" }
}

Struct vs Resource

// Struct — copyable value type
struct Point {
    let x: Int; let y: Int
    init(x: Int, y: Int) { self.x = x; self.y = y }
}
let a = Point(x: 1, y: 2)
let b = a   // COPY — both exist independently

// Resource — unique, linear type (cannot copy)
resource Token {
    let id: UInt64
    init() { self.id = self.uuid }
}
let t1 <- create Token()
let t2 <- t1   // MOVE — t1 is no longer valid
destroy t2     // must explicitly destroy if not stored

Resource rules:

  1. Resources exist in exactly one place at a time.
  2. Every resource must be saved, moved, or destroyed before the current scope ends.
  3. Use @ in type annotations: @NFT, @{UInt64: NFT}.
  4. Use <- to move, <-! for force-assign into optional (panics on conflict).

2. Access Control & Entitlements

Access Modifiers

ModifierWho can access
access(all)Everyone (public read, callable by anyone)
access(self)Only within the type itself
access(contract)Same contract
access(account)Contracts within the same account
access(E)Either callers holding the actual object or callers holding a reference to the object authorized with entitlement E

Entitlements Pattern

access(all) entitlement Withdraw
access(all) entitlement Owner

access(all) resource Vault {
    access(self) var balance: UFix64

    // Anyone can read
    access(all) view fun getBalance(): UFix64 { return self.balance }

    // Anyone can deposit into you
    access(all) fun deposit(from: @Vault) {
        self.balance = self.balance + from.balance
        destroy from
    }

    // Only authorized callers can withdraw
    access(Withdraw) fun withdraw(amount: UFix64): @Vault {
        pre { self.balance >= amount: "Insufficient balance" }
        self.balance = self.balance - amount
        return <- create Vault(balance: amount)
    }
}

// Getting an entitled reference
let vaultRef = signer.storage
    .borrow<auth(Withdraw) &Vault>(from: /storage/vault)
    ?? panic("Could not borrow Vault from /storage/vault — capability may be revoked or vault not saved")

References

let ref: &NFT = &myNFT                          // read-only reference
let authRef: auth(Withdraw) &Vault = &myVault   // entitled reference

// From storage
let r = signer.storage.borrow<auth(Withdraw) &Vault>(from: /storage/vault)
    ?? panic("No Vault found at /storage/vault — ensure the account has a vault saved")

Matching Access Modifiers Required for Interface Implementations

Implementation members must use exactly the same access modifier as the interface:

access(all) resource interface I {
    access(account) fun foo()
}

// BAD — access(all) is more permissive than access(account)
access(all) resource R: I {
    access(all) fun foo() {}
}

// GOOD
access(all) resource R: I {
    access(account) fun foo() {}
}

3. Capabilities

Capabilities are the mechanism for sharing access to stored objects. Nothing is public by default.

// 1. Save object to storage
signer.storage.save(<- create Vault(balance: 0.0), to: /storage/vault)

// 2. Issue a capability (creates a tracked controller)
let receiverCap = signer.capabilities.storage
    .issue<&{FungibleToken.Receiver}>(/storage/vault)

// 3. Publish so others can borrow it
signer.capabilities.publish(receiverCap, at: /public/receiver)

// 4. Borrow from another account
let receiver = getAccount(address).capabilities
    .borrow<&{FungibleToken.Receiver}>(/public/receiver)
    ?? panic("Account ".concat(address.toString()).concat(" has no FungibleToken.Receiver capability at path /public/receiver"))

// 5. Revoke when needed
let controller = signer.capabilities.storage
    .getController(byCapabilityID: capID) ?? panic("No StorageCapabilityController found for capability ID ".concat(capID.toString()))
controller.delete()

// Issue an entitled capability (grants Withdraw to holder)
let ownerCap = signer.capabilities.storage
    .issue<auth(Withdraw) &Vault>(/storage/vault)

Public Capability Acquisition Returns Non-Optional

capabilities.get<T> returns an invalid capability (not nil) when no capability exists or when T mismatches. Check validity with .check():

let capability = account.capabilities.get<&MyNFT.Collection>(/public/NFTCollection)
if !capability.check() {
    // Handle invalid capability (ID == 0, borrow returns nil)
}

4. Transactions & Scripts

Transaction Structure

transaction(amount: UFix64, recipient: Address) {

    // Declare fields shared across phases
    let vaultRef: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}

    // Access accounts — the ONLY phase with account access
    prepare(signer: auth(BorrowValue) &Account) {
        self.vaultRef = signer.storage
            .borrow<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>(
                from: /storage/vault
            ) ?? panic("Could not borrow FungibleToken.Vault from /storage/vault for signer")
    }

    pre  { amount > 0.0: "Amount must be positive" }

    execute {
        let tokens <- self.vaultRef.withdraw(amount: amount)
        let receiver = getAccount(recipient).capabilities
            .borrow<&{FungibleToken.Receiver}>(/public/receiver)
            ?? panic("Account ".concat(recipient.toString()).concat(" has no FungibleToken.Receiver capability at /public/receiver"))
        receiver.deposit(from: <- tokens)
    }

    post { /* verify post-conditions */ }
}

Phases: preparepreexecutepost

Common Signer Authorizations

prepare(signer: auth(SaveValue) &Account)                          // save to storage
prepare(signer: auth(BorrowValue) &Account)                        // borrow from storage
prepare(signer: auth(LoadValue) &Account)                          // load (remove) from storage
prepare(signer: auth(IssueStorageCapabilityController) &Account)   // issue capabilities
prepare(signer: auth(PublishCapability) &Account)                  // publish capabilities
prepare(signer: auth(Contracts) &Account)                          // deploy/update contracts
prepare(signer: auth(Keys) &Account)                               // manage account keys

Scripts (read-only, free, no transaction needed)

access(all) fun main(address: Address): UFix64 {
    return getAccount(address).capabilities
        .borrow<&{FungibleToken.Balance}>(/public/balance)
        ?.balance ?? 0.0
}

5. Account Storage

// Save — moves resource into storage
signer.storage.save(<- create NFT(), to: /storage/myNFT)

// Borrow — get a reference without removing
let ref = signer.storage.borrow<&NFT>(from: /storage/myNFT)

// Load — removes and returns (must handle the resource)
let nft <- signer.storage.load<@NFT>(from: /storage/myNFT)!

// Check existence and type
let t: Type? = signer.storage.type(at: /storage/myNFT)
if t != nil { /* already exists */ }

// Iterate all stored values
signer.storage.forEachStored(fun (path: StoragePath, type: Type): Bool {
    return true  // true = continue, false = stop
})

6. NFT Contract (Production Pattern)

access(all) contract BasicNFT {

    access(all) var totalSupply: UInt64
    access(all) event Minted(id: UInt64)
    access(all) event Withdraw(id: UInt64, from: Address?)
    access(all) event Deposit(id: UInt64, to: Address?)
    access(all) entitlement Withdraw

    access(all) let CollectionStoragePath: StoragePath
    access(all) let CollectionPublicPath: PublicPath

    access(all) resource NFT {
        access(all) let id: UInt64
        access(all) let metadata: {String: String}
        init(metadata: {String: String}) {
            self.id = self.uuid
            BasicNFT.totalSupply = BasicNFT.totalSupply + 1
            emit Minted(id: self.id)
        }
    }

    access(all) resource Collection {
        access(self) var ownedNFTs: @{UInt64: NFT}

        access(all) fun deposit(token: @NFT) {
            emit Deposit(id: token.id, to: self.owner?.address)
            self.ownedNFTs[token.id] <-! token
        }

        access(Withdraw) fun withdraw(id: UInt64): @NFT {
            let token <- self.ownedNFTs.remove(key: id)
                ?? panic("NFT \(id) not found in collection")
            emit Withdraw(id: token.id, from: self.owner?.address)
            return <- token
        }

        access(all) fun getIDs(): [UInt64] { return self.ownedNFTs.keys }
        access(all) view fun borrowNFT(_ id: UInt64): &NFT? {
            return &self.ownedNFTs[id]
        }

        init() { self.ownedNFTs <- {} }
    }

    access(all) fun createEmptyCollection(): @Collection {
        return <- create Collection()
    }

    init() {
        self.totalSupply = 0
        self.CollectionStoragePath = /storage/basicNFTCollection
        self.CollectionPublicPath = /public/basicNFTCollection
    }
}

NFT Setup Transaction

transaction {
    prepare(signer: auth(SaveValue, IssueStorageCapabilityController, PublishCapability) &Account) {
        // Idempotent — skip if already set up
        if signer.storage.type(at: BasicNFT.CollectionStoragePath) != nil { return }

        signer.storage.save(<- BasicNFT.createEmptyCollection(), to: BasicNFT.CollectionStoragePath)
        let cap = signer.capabilities.storage
            .issue<&BasicNFT.Collection>(BasicNFT.CollectionStoragePath)
        signer.capabilities.publish(cap, at: BasicNFT.CollectionPublicPath)
    }
}

Mint & Transfer

// Mint (admin transaction)
transaction(recipient: Address, name: String) {
    execute {
        let nft <- create BasicNFT.NFT(metadata: {"name": name})
        getAccount(recipient).capabilities
            .borrow<&BasicNFT.Collection>(BasicNFT.CollectionPublicPath)
            ?.deposit(token: <- nft)
            ?? panic("Account ".concat(recipient.toString()).concat(" has no BasicNFT.Collection capability at ").concat(BasicNFT.CollectionPublicPath.toString()))
    }
}

// Transfer (user transaction)
transaction(recipient: Address, nftID: UInt64) {
    let withdrawRef: auth(BasicNFT.Withdraw) &BasicNFT.Collection
    prepare(signer: auth(BorrowValue) &Account) {
        self.withdrawRef = signer.storage
            .borrow<auth(BasicNFT.Withdraw) &BasicNFT.Collection>(
                from: BasicNFT.CollectionStoragePath
            ) ?? panic("Could not borrow BasicNFT.Collection from signer's storage at ".concat(BasicNFT.CollectionStoragePath.toString()))
    }
    execute {
        let nft <- self.withdrawRef.withdraw(id: nftID)
        getAccount(recipient).capabilities
            .borrow<&BasicNFT.Collection>(BasicNFT.CollectionPublicPath)
            ?.deposit(token: <- nft)
            ?? panic("Account ".concat(recipient.toString()).concat(" has no BasicNFT.Collection capability at ").concat(BasicNFT.CollectionPublicPath.toString()))
    }
}

7. Fungible Token (Production Pattern)

access(all) contract BasicToken {
    access(all) var totalSupply: UFix64
    access(all) entitlement Withdraw

    access(all) resource Vault {
        access(all) var balance: UFix64
        init(balance: UFix64) { self.balance = balance }

        access(all) fun deposit(from: @Vault) {
            self.balance = self.balance + from.balance
            destroy from
        }

        access(Withdraw) fun withdraw(amount: UFix64): @Vault {
            pre { self.balance >= amount: "Insufficient balance" }
            self.balance = self.balance - amount
            return <- create Vault(balance: amount)
        }
    }

    access(all) fun createEmptyVault(): @Vault {
        return <- create Vault(balance: 0.0)
    }

    init() { self.totalSupply = 0.0 }
}

Cadence 1.0 Token Standard Changes

FungibleToken.Vault and NonFungibleToken.NFT / NonFungibleToken.Collection are now interfaces, not concrete types. Update all references:

// Before (Cadence 0.x)
fun deposit(from: @FungibleToken.Vault)

// After (Cadence 1.0)
fun deposit(from: @{FungibleToken.Vault})

Why vaults beat ledgers:

Ledger (Solidity)Vault (Cadence)
Balances in a contract mappingEach user holds their own Vault
Reentrancy attacks possibleResources move atomically
Admin can modify any balanceOnly the holder can access their Vault

8. Security Rules (Non-Negotiable)

S1 — Least Privilege

Start access(self), widen only when justified. Never access(all) on state-modifying functions.

// BAD — anyone drains your vault
access(all) fun withdraw(amount: UFix64): @Vault { ... }

// GOOD — requires entitlement
access(Withdraw) fun withdraw(amount: UFix64): @Vault { ... }

S2 — Never Pass Fully Authorized Account Refs as Parameters

// BAD — gives full storage access to callee
access(all) fun setup(admin: auth(Storage) &Account) { ... }

// GOOD — use a narrowly-scoped capability instead
access(all) fun setup(adminCap: Capability<&Admin>) { ... }

S3 — Always Validate with Pre/Post Conditions

access(Withdraw) fun withdraw(amount: UFix64): @Vault {
    pre  { amount > 0.0:                             "Amount must be positive" }
    pre  { self.balance >= amount:                   "Insufficient balance" }
    post { result.balance == amount:                 "Withdrawal amount mismatch" }
    post { self.balance == before(self.balance) - amount: "Balance accounting error" }
}

S4 — Meaningful Panic Messages (Never Force-Unwrap Silently)

// BAD — silent crash
let ref = cap.borrow()!

// GOOD — actionable message
let ref = cap.borrow()
    ?? panic("Could not borrow Vault — capability may be revoked or incorrect type")

S5 — Private Data Is Not Secret

access(self) controls *programmatic access*, not blockchain visibility. All storage is publicly readable off-chain. Never store secrets, private keys, or PII on-chain.

S6 — Never Hard-Code Addresses

// BAD
import FungibleToken from 0xf233dcee88fe0abe

// GOOD (uses flow.json aliases, resolved at deployment)
import "FungibleToken"

S7 — Check Before Setup (Idempotent Transactions)

transaction {
    prepare(signer: auth(SaveValue) &Account) {
        if signer.storage.type(at: /storage/vault) != nil { return }
        signer.storage.save(<- MyToken.createEmptyVault(), to: /storage/vault)
    }
}

9. Testing

Tests are Cadence files using the Test standard library, executed via Flow CLI.

import Test

let blockchain = Test.newEmulatorBlockchain()
let admin = blockchain.createAccount()

access(all) fun setup() {
    let err = blockchain.deployContract(
        name: "MyNFT",
        code: Test.readFile("../contracts/MyNFT.cdc"),
        account: admin,
        arguments: []
    )
    Test.expect(err, Test.beNil())
}

access(all) fun testMint() {
    let tx = Test.Transaction(
        code: Test.readFile("../transactions/mint.cdc"),
        authorizers: [admin.address],
        signers: [admin],
        arguments: ["My NFT"]
    )
    Test.expect(blockchain.executeTransaction(tx), Test.beSucceeded())

    let events = Test.eventsOfType(Type<MyNFT.Minted>())
    Test.assertEqual(1, events.length)
}

access(all) fun testQuery() {
    let result = blockchain.executeScript(
        Test.readFile("../scripts/get_ids.cdc"),
        [admin.address]
    )
    let ids = result.returnValue! as! [UInt64]
    Test.assertEqual(1, ids.length)
}

Common assertions:

Test.assertEqual(expected, actual)
Test.assert(condition, message: "reason")
Test.expect(result, Test.beSucceeded())
Test.expect(result, Test.beFailed())
Test.expect(err, Test.beNil())

Run tests:

flow test tests/my_test.cdc
flow test --cover tests/my_test.cdc

10. Naming Conventions

ConstructConventionExample
Contract, Resource, Struct, Interface, EventPascalCaseFlowToken, TokenVault
Function, variable, parametercamelCasegetBalance(), totalSupply
Storage/public pathslet fields on the contractlet VaultStoragePath: StoragePath
EntitlementsPascalCaseentitlement Withdraw

Never hardcode path strings in transactions — always reference the contract's published path constants.


11. Anti-Patterns

A1 — Never Pass Fully Authorized Account Refs as Parameters

A function accepting auth(Storage) &Account can access *all* storage — drain vaults, steal NFTs.

// BAD — callee can withdraw FLOW or modify anything
access(all) fun transferNFT(id: UInt64, owner: auth(Storage) &Account) { ... }

// GOOD — authenticate via resources/capabilities
access(all) fun transferNFT(id: UInt64, collectionCap: Capability<auth(Withdraw) &Collection>) { ... }

A2 — Public Functions Should Be Read-Only or Explicitly Entitled

Only view functions and functions everyone should call should be access(all). State-modifying functions require entitlements.

A3 — Capability-Typed Public Fields Are Security Holes

Capabilities are value types — a public field can be copied by anyone:

// BAD — anyone copies the capability and calls its functions
access(all) var adminCap: Capability<&Admin>

// GOOD
access(self) var adminCap: Capability<&Admin>
access(Owner) fun getAdminCap(): Capability<&Admin> { return self.adminCap }

A4 — Never Make Admin Creation Functions Public

// BAD — anyone mints admin access
access(all) fun createAdmin(): @Admin { return <- create Admin() }

// GOOD — create once in init, existing admins create new ones
init() {
    self.account.storage.save(<- create Admin(), to: /storage/currencyAdmin)
}

A5 — Never Emit Events or Modify Contract State in Struct Initializers

Structs are public and can be created by anyone. Side effects in init() can be exploited:

// BAD — anyone spams events and overflows nextPlayID
access(all) struct Play {
    init() {
        TopShot.nextPlayID = TopShot.nextPlayID + 1  // BAD
        emit PlayCreated(id: self.playID)             // BAD
    }
}

// GOOD — state changes happen only inside admin resource
access(all) resource Admin {
    access(all) fun createPlay() {
        var newPlay = Play()
        TopShot.nextPlayID = TopShot.nextPlayID + UInt32(1)
        emit PlayCreated(id: newPlay.playID)
    }
}

A6 — Complex/Capability Fields Must Be access(self)

access(all) on arrays, dictionaries, structs, resources, or capabilities allows direct mutation:

// BAD
access(all) var adminCap: Capability<&Admin>

// GOOD
access(self) var adminCap: Capability<&Admin>

12. Capability Bootstrapping (Inbox API)

When account A needs to send a capability to account B, a single transaction cannot be signed by both accounts simultaneously. Use the Inbox API:

Step 1 — Provider publishes the capability to recipient's inbox:

import "BasicNFT"

transaction(receiver: Address, name: String) {
    prepare(signer: auth(IssueStorageCapabilityController, PublishInboxCapability) &Account) {
        let capability = signer.capabilities.storage
            .issue<&BasicNFT.Minter>(BasicNFT.minterPath)

        let controller = signer.capabilities.storage
            .getController(byCapabilityID: capability.id)
            ?? panic("No StorageCapabilityController found for capability ID ".concat(capability.id.toString()))
        controller.setTag(name)

        signer.inbox.publish(capability, name: name, recipient: receiver)
    }
}

Step 2 — Recipient claims the capability:

import "BasicNFT"

transaction(provider: Address, name: String) {
    prepare(signer: auth(ClaimInboxCapability, SaveValue) &Account) {
        let capability = signer.inbox.claim<&BasicNFT.Minter>(name, provider: provider)
            ?? panic("No capability named '\(name)' from \(provider)")
        signer.storage.save(capability, to: BasicNFT.minterPath)
    }
}
The provider can call signer.inbox.unpublish(name) to retract before the recipient claims.

13. Performance: Prefer borrow Over load/save

load() moves the resource out of storage (expensive), save() moves it back (expensive again). borrow() returns an in-place reference — always prefer it.

// BAD — unnecessary round-trip moves the entire resource
transaction {
    prepare(acct: auth(LoadValue, SaveValue) &Account) {
        let vault <- acct.storage.load<@ExampleToken.Vault>(from: /storage/exampleToken)!
        let burned <- vault.withdraw(amount: 10)
        destroy burned
        acct.storage.save(<- vault, to: /storage/exampleToken)
    }
}

// GOOD — borrow a reference, mutate in-place, no save needed
transaction {
    prepare(acct: auth(BorrowValue) &Account) {
        let vault = acct.storage.borrow<&ExampleToken.Vault>(from: /storage/exampleToken)!
        let burned <- vault.withdraw(amount: 10)
        destroy burned
    }
}

14. Measuring Time

Flow produces blocks approximately every 0.8 seconds. Both block timestamp and block height are available on-chain.

let block = getCurrentBlock()
block.timestamp   // Unix timestamp (UFix64, seconds)
block.height      // Block number (UInt64)

let pastBlock = getBlock(at: 70001)
pastBlock?.timestamp
pastBlock?.height
MethodUse when
getCurrentBlock().timestampAcceptable for events lasting hours/days. Accurate to ~10 seconds.
getCurrentBlock().heightMore manipulation-resistant. Requires off-chain rate estimation.

Rules:

  • Timestamps cannot go backwards and cannot be more than 10 seconds ahead of the previous block.
  • Never hardcode an assumed block rate — it changes over time.
  • Auctions and time-locks should have an extension mechanism.

15. Contract Upgrades

Compatible Changes (Preferred)

Cadence supports in-place upgrades for additive changes: adding new fields (with defaults), new functions, new events. Use flow contracts update.

Incompatible Changes

Option A — New address (safest):

  1. Deploy new contract to a new account.
  2. Increment path suffixes (/public/MyVault002).
  3. Write upgrade transactions to migrate users' resources.

Option B — Same address (risky, last resort):

  1. Delete all resources in the contract account (e.g., Admin resource).
  2. Delete the contract from the account.
  3. Deploy the new contract.
⚠️ If any user account holds structs or resources from the old contract version, those will **fail to

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

35.22%
按下载量换算51

Claude

28.36%
按下载量换算41

Cursor

18.82%
按下载量换算27

Gemini CLI

8.91%
按下载量换算13

安全审计

Gen Agent Trust Hub

通过

Socket

可疑

Snyk

可疑

权限和风险

external-service

该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills