Placeholder contract addresses in source code

This question is about how to represent token addresses in source code.

We’re trying to make sure my project is organized and can be easily used by the Flow CLI, the Go SDK, and Flow FCL. We want our project to be testable on the emulator and testnet with minimal duplicate code.

A main challenge is the contract addresses in the .cdc files themselves, which seem to be handled slightly differently across the tooling.

Go SDK

Right now, Go has been the focus so we’ve been using templates, as below, and then injecting the right address to e.g. run a script.

import ExampleToken from 0x{{.ExampleToken}}

Flow FCL

FCL handles this for you provides a very nice feature via config, that automatically transliterates something like 0xEXAMPLETOKEN into the correct address.

From the config section of the Flow FCL tutorial:

import {config} from "@onflow/fcl"

config()
  .put("0xProfile", process.env.REACT_APP_CONTRACT_PROFILE)

The core contracts also seem to follow this model, with some helper functions around the templates.

Flow CLI

Finally, the Flow CLI upon deployment and compilation seems to take filesystem paths and then transliterate them based on the contents of the flow.json file and its own internal bookkeeping of addresses.

import FungibleToken from "./FungibleToken.cdc"
import ExampleToken from "./ExampleToken.cdc"

So, in the code above, it seems like the flow CLI:

  1. Reads the contracts.FungibleToken.alias from flow.json for the first line
  2. Deploys ./ExampleToken.cdc, stores the address in memory, and then uses that when compiling the final contract.

If there’s something consistent we can do, or even just a planned standard to work towards, we can build the extra tooling needed on our end to support it.

Thank you!

Hey @aphelionz, I’m actually really glad you brought this up!

The standard I’d like to work towards is the pattern currently used by the Flow CLI, simply because it allows the developer to write their Cadence source files in a way that feels natural – import your local dependencies by their filesystem path.

However, it’s missing an elegant solution for external dependencies and currently requires you to copy all external contracts (e.g. FungibleToken.cdc) into your project. This is also required to get the VS Code editor to parse files correctly, since it also doesn’t support remote file imports.

Would you be interested in helping us bring this functionality to the Go SDK? The core logic is implemented as part of the flowkit/contracts package in the CLI: https://github.com/onflow/flow-cli/blob/master/pkg/flowkit/contracts/resolver.go

Definitely would be interested in helping out. Taking a closer look today and then let’s discuss further.