References

References help us get access to types.

They are most helpful for resources, since we do not want to move a resource out of its stored location just to read or mutate its data.

Reference types are prefixed with &.

When creating a reference, you must follow it with a casting expression.

cadence
		
			// Contract file: Test.cdc
// Deployed to 0x01
access(all) contract Test {

   access(all) let nfts: @{UInt64: NFT}

   access(all) resource NFT {
      access(all) let id: UInt64
      access(all) let rarity: String
      access(all) var name: String

      access(all) fun changeName(newName: String) {
         self.name = newName
      }
      
      init(rarity: String, name: String) {
         self.id = self.uuid
         self.rarity = rarity
         self.name = name
      }
   }

   access(all) fun createNFT(rarity: String, name: String) {
      let nft <- create NFT(rarity: rarity, name: name)
      self.nfts[nft.id] <-! nft
   }

   access(all) fun getNFTRef(id: UInt64): &NFT? {
      // Here we add the `as &NFT?` casting expression.
      // The reference is an optional because it is coming from
      // a dictionary.
      return &self.nfts[id] as &NFT?
   }

   init() {
      self.nfts <- {}
   }
}
		 
	
cadence
		
			// Transaction file: change_nft_name.cdc
import Test from 0x01

transaction(id: UInt64, newName: String) {

   prepare(signer: &Account) {}

   execute {
      let nftRef: &Test.NFT = Test.getNFTRef(id: id) 
               ?? panic("This NFT does not exist.") // unwrap the optional with a `panic`
      nftRef.changeName(newName: newName)
   }
}
		 
	
cadence
		
			// Script file: read_nft.cdc
import Test from 0x01

access(all) fun main(id: UInt64): NFTData {
   let nftRef: &Test.NFT = Test.getNFTRef(id: id) 
               ?? panic("This NFT does not exist.") // unwrap the optional with a `panic`
   return NFTData(nftRef.id, nftRef.rarity, nftRef.name)
}

access(all) struct NFTData {
   access(all) let id: UInt64
   access(all) let rarity: String
   access(all) let name: String

   init(_ i: UInt64, _ r: String, _ n: String) {
      self.id = i
      self.rarity = r
      self.name = n
   }
}