Open5

Cadenceのメモや疑問点

shunshun
// public account objectを取得
let nftOwner = getAccount(0x01)
// Capabilityを取得
let capability = nftOwner.getCapability<&{ExampleNFT.NFTReceiver}>(ExampleNFT.CollectionPublicPath)
// Capabilityからrefをborrowする
let receiverRef = capability.borrow()
        ?? panic("Could not borrow receiver reference")

getCapabilityでborrowまでしてしまわないのはなぜ?
getCapabilityにはborrow以外の使い方もあるから?

shunshun

interfaceはなぜ必要?withdrawなどの関数に直接interfaceの内容を書く、じゃダメなのか?

shunshun

MarketPlaceのチュートリアルの SetupAccount2Transaction.cdc

  • 0x02 の署名で実行
  • Vault を生成し、0x02 のストレージに保存
  • Capability も格納
    • この capability を ReceiverRef 変数で受け取っているのはなぜ???(受け取らなくても動くのに)
  • NFTMinter の Capability を borrow
  • NFTMinter を使って NFT を mint
  • 0x01 のアカウントの Receiver を使って mint した NFT を deposit
import ExampleToken from 0x01
import ExampleNFT from 0x02

transaction {
  let minterRef: &ExampleNFT.NFTMinter
  prepare(acct: AuthAccount) {
    let vaultA <- ExampleToken.createEmptyVault()
    acct.save<@ExampleToken.Vault>(<-vaultA, to: /storage/CadenceFungibleTokenTutorialVault)
    // なぜReceiverRefで受け取ってる???
    let ReceiverRef = acct.link<&ExampleToken.Vault{ExampleToken.Receiver, ExampleToken.Balance}>(/public/CadenceFungibleTokenTutorialReceiver, target: /storage/CadenceFungibleTokenTutorialVault)
    log("Created a Vault and published a reference")

    self.minterRef = acct.borrow<&ExampleNFT.NFTMinter>(from: ExampleNFT.MinterStoragePath)
        ?? panic("Could not borrow owner's NFT minter reference")
  }
  execute {
    let recipient = getAccount(0x01)
    let receiverRef = recipient.getCapability(ExampleNFT.CollectionPublicPath)
                               .borrow<&{ExampleNFT.NFTReceiver}>()
                               ?? panic("Could not borrow nft receiver reference")

    receiverRef.deposit(token: <-self.minterRef.mintNFT())
    log("New NFT minted for account 1")
  }
}
shunshun

interface と pub の違い

  • 利用できる関数を interface で制限するんじゃなくて pub は外す、じゃだめなのか?
    • interface に入っている関数は AuthAccount ではなくても実行できる(scripts などから利用できる)
    • 入っていない関数はトランザクションで署名したアカウントだけが使える
    • 一方で pub はコントラクトコード以外からでも関数を使えるようにするための接頭語
    • 例えば withdraw を pub ではなく priv にすると、コントラクトのオーナーであってもトランザクションで withdraw を使えなくなる
    • その場合、cannot access `withdraw`: function has private accessというエラーが発生する
    • つまり、pub/priv などの接頭語はスコープの制限をしている
    • interface は Capability で利用できる関数の制限をしている
shunshun
  • no arguement label
    関数呼び出し時にラベルを指定する必要がない
fun double(_ x: Int): Int {
    return x * 2
}

let result = double(4)

使わない例:

fun double(input_num x: Int): Int {
    return x * 2
}

let result = double(input_num=4)