Deploy a contract

Deploy a Clarity smart contract to the Stacks blockchain using Stacks.js


import { STACKS_TESTNET } from "@stacks/network";
import {
makeContractDeploy,
broadcastTransaction,
AnchorMode,
PostConditionMode
} from "@stacks/transactions";
const contractCode = `
(define-data-var counter uint u0)
(define-public (increment)
(ok (var-set counter (+ (var-get counter) u1))))
(define-read-only (get-counter)
(ok (var-get counter)))
`;
const txOptions = {
contractName: "my-counter",
codeBody: contractCode,
senderKey: "753b7cc01a1a2e86221266a154af739463fce51219d97e4f856cd7200c3bd2a601",
network: STACKS_TESTNET,
anchorMode: AnchorMode.Any,
postConditionMode: PostConditionMode.Allow,
fee: 100000n, // Set an appropriate fee
};
const transaction = await makeContractDeploy(txOptions);
const broadcastResponse = await broadcastTransaction({ transaction });
console.log("Contract deployed!");
console.log("Transaction ID:", broadcastResponse.txid);

Use cases

  • Deploying new smart contracts to mainnet or testnet
  • Automating contract deployments in CI/CD pipelines
  • Programmatic contract deployment for dApp initialization
  • Deploying contract upgrades or new versions

Key concepts

Contract deployment requires:

  • Contract name: Unique identifier for your contract (letters, numbers, hyphens)
  • Code body: The Clarity contract code as a string
  • Sender key: Private key of the account deploying the contract
  • Network: Target network (mainnet, testnet, or devnet)

Deployment with initialization

// Deploy a token contract with initial configuration
const tokenContract = `
(define-fungible-token my-token u1000000)
(define-constant contract-owner tx-sender)
(define-public (transfer (amount uint) (recipient principal))
(ft-transfer? my-token amount tx-sender recipient))
(define-read-only (get-balance (account principal))
(ok (ft-get-balance my-token account)))
`;
const deployOptions = {
contractName: "my-token-v1",
codeBody: tokenContract,
senderKey: privateKey,
network: STACKS_TESTNET,
fee: 200000n, // Higher fee for larger contract
};

Reading contract source from file

import { readFileSync } from 'fs';
import { makeContractDeploy, broadcastTransaction } from "@stacks/transactions";
import { STACKS_TESTNET } from "@stacks/network";
// Read contract from file
const contractCode = readFileSync('./contracts/my-contract.clar', 'utf-8');
const txOptions = {
contractName: "my-contract",
codeBody: contractCode,
senderKey: process.env.DEPLOYER_KEY,
network: STACKS_TESTNET,
};
const transaction = await makeContractDeploy(txOptions);
const result = await broadcastTransaction({ transaction });

Deployment validation

// Check deployment status
async function checkDeployment(txId: string) {
const response = await fetch(
`https://api.testnet.hiro.so/extended/v1/tx/${txId}`
);
const txData = await response.json();
if (txData.tx_status === "success") {
console.log("Contract deployed successfully!");
console.log("Contract ID:", txData.smart_contract.contract_id);
} else if (txData.tx_status === "pending") {
console.log("Transaction pending...");
} else {
console.error("Deployment failed:", txData.tx_result);
}
}
// After broadcasting
await checkDeployment(broadcastResponse.txid);

Package installation

Terminal
$
npm install @stacks/network @stacks/transactions