Linking an Application to an NFD

This requires NFDs at contract 2.11 or higher

Contracts can now verify their account address with an NFD. There is no direct API for this as the contract that wants to verify its address must make the actual call via an inner transaction to the NFD.

The verification process is a 2-step process.

  • First, the OWNER of the NFD needs to update the user-defined property (u.cav.algo.a) with the raw 32-byte PK of the contract's account address (the Algorand GetApplicationAddress SDK for eg). The NFD API can be used to get the transaction for this, or you can update it directly using a contract call.

  • Second, once u.cav.algo.a is set, you next need to call the NFD Registry contract (see Registry Application IDs) to 'verify' the address in the NFD FROM THE CONTRACT BEING VERIFIED. The NFD can verify its own vault contract address if desired. In this case, the Owner of the NFD is allowed to verify the vault address.

    • The call to the NFD registry contract consists of the following 4 arguments:

      • str: verify_nfd_addr (the Registry method being called)

      • str: {nfd name} (the full NFD name, ie: nfdomains.algo)

      • int: nfd app id (the Application ID of the NFD which has u.cav.algo.a set in it)

      • addr: address being verified [must be txn sender]

        • str, int, addr prefixes will be familiar to goal CLI users. These just indicate the format of the bytes being passed in that argument. str]ing just represent the raw (ascii in this case) bytes. int represents an 8-byte Big-Endian value. addr is the raw 32-byte PK of an Algorand address.

      • Foreign references that must be set in Outer Transaction call (to your own contract which then calls the NFD Registry Contract):

        • Accounts: nil

        • Applications:

          • NFD App ID

        • Assets: nil

        • Box References:

          • [0, get_address_boxname(32-byte address being verified)]

          • [0, ""] (to increase box storage availability)

          • [0, get_name_boxname(name being referenced)]

          • [NFD App ID, "u.cav.algo"]

          • [NFD App ID, "v.caAlgo.0.as"]

PyTeal representations of the get_name / get_address calls

@Subroutine(TealType.bytes)
def get_address_boxname(address):
    return Sha256(Concat(Bytes("addr/algo/"), address))
    
@Subroutine(TealType.bytes)
def get_name_boxname(nfd_name):
    return Sha256(Concat(Bytes("name/"), nfd_name))

Go versions of the get name / address box name calls

import (
	"crypto/sha256"
	"github.com/algorand/go-algorand-sdk/v2/types"
)

func GetRegistryBoxNameForNFD(nfdName string) []byte {
	hash := sha256.Sum256([]byte("name/" + nfdName))
	return hash[:]
}

func GetRegistryBoxNameForAddress(algoAddress types.Address) []byte {
	hash := sha256.Sum256(bytes.Join([][]byte{[]byte("addr/algo/"), algoAddress[:]}, nil))
	return hash[:]
}

Last updated