How to manage contracts
⚠️ Required: Your project must follow the required structure and it must be initialized to use the following functions.
Deploys contract code located inside a Cadence file. Returns the transaction result.
Props object accepts the following fields:
Name | Type | Optional | Description |
---|---|---|---|
name | string | name of the file in contracts folder (with .cdc extension) and name of the contract (please note those should be the same) | |
to | Address | ✅ | (optional) account address, where contract will be deployed. If this is not specified, framework will create new account with randomized alias. |
addressMap | AddressMap | ✅ | (optional) object to use for address mapping of existing deployed contracts |
args | [Any] | ✅ | (optional) arguments, which will be passed to contract initializer. (optional) if template does not expect any arguments. |
update | boolean | ✅ | (optional) whether to update deployed contract. Default: false |
transformers | [CadenceTransformer] | ✅ | an array of operators to modify the code, before submitting it to network |
Type | Description |
---|---|
ResponseObject | Result of the deploying transaction. |
1import path from "path";2import { init, emulator, deployContractByName } from "@onflow/flow-js-testing";34const main = async () => {5const basePath = path.resolve(__dirname, "../cadence");67await init(basePath);8await emulator.start();910// We will deploy our contract to the address that corresponds to "Alice" alias11const to = await getAccountAddress("Alice");1213// We assume there is a file on "../cadence/contracts/Wallet.cdc" path14const name = "Wallet";1516// Arguments will be processed and type matched in the same order as they are specified17// inside of a contract template18const args = [1337, "Hello", { name: "Alice" }];1920const [deploymentResult, err] = await deployContractByName({ to, name });21console.log({ deploymentResult }, { err });22}2324await emulator.stop();25};2627main();
In a bit more rare case you would want to deploy contract code not from existing template file, but rather
from string representation of it. deployContract
method will help you achieve this.
Deploys contract code specified as string. Returns the transaction result.
Props object accepts the following fields:
Name | Type | Optional | Description |
---|---|---|---|
contractCode | string | string representation of contract | |
name | string | name of the contract to be deployed. Should be the same as the name of the contract provided in contractCode | |
to | Address | ✅ | account address, where contract will be deployed. If this is not specified, framework will create new account with randomized alias. |
addressMap | AddressMap | ✅ | object to use for import resolver. Default: {} |
args | [Any] | ✅ | arguments, which will be passed to contract initializer. Default: [] |
update | boolean | ✅ | whether to update deployed contract. Default: false |
transformers | [CadenceTransformer] | ✅ | an array of operators to modify the code, before submitting it to network |
Type | Description |
---|---|
ResponseObject | Result of the deploying transaction. |
1import path from "path"2import {3init,4emulator,5getAccountAddress,6deployContract,7executeScript,8} from "@onflow/flow-js-testing"9;(async () => {10const basePath = path.resolve(__dirname, "../cadence")1112await init(basePath)13await emulator.start()1415// We can specify, which account will hold the contract16const to = await getAccountAddress("Alice")1718const name = "Wallet"19const code = `20pub contract Wallet{21pub let balance: UInt22init(balance: UInt){23self.balance = balance24}25}26`27const args = [1337]2829await deployContract({to, name, code, args})3031const [balance, err] = await executeScript({32code: `33import Wallet from 0x0134pub fun main(): UInt{35return Wallet.balance36}37`,38})39console.log({balance}, {err})4041await emulator.stop()42})()
While framework have automatic import resolver for Contracts you might want to know where it's currently deployed.
We provide a method getContractAddress
for this.
Returns address of the account where the contract is currently deployed.
Name | Type | Description |
---|---|---|
name | string | name of the contract |
Type | Description |
---|---|
Address | 0x prefixed address |
1import path from "path"2import {init, emulator, deployContractByName, getContractAddress} from "../src"3;(async () => {4const basePath = path.resolve(__dirname, "./cadence")56await init(basePath)7await emulator.start()89// if we omit "to" it will be deployed to Service Account10// but let's pretend we don't know where it will be deployed :)11await deployContractByName({name: "Hello"})1213const contractAddress = await getContractAddress("Hello")14console.log({contractAddress})1516await emulator.stop()17})()
📣 Framework does not support contracts with identical names deployed to different accounts. While you can deploy contract to a new address, the internal system, which tracks where contracts are deployed, will only store last address.