Deploying a Contract
Deploying a smart contract on OP_NET requires careful handling of UTXOs and constructing deployment parameters. This guide explains the process of using TransactionFactory to sign and deploy contracts.
If you're in a browser environment, please refer to WalletConnect Documentation for information on deploying contracts.
Steps to Deploy a Contract
1. Obtaining Proper UTXOs
Before building a transaction, you need to gather the required UTXOs for funding. Use the utxoManager from the JSONRpcProvider to fetch UTXOs associated with your address.
const utxos = await provider.utxoManager.getUTXOs({
  address: wallet.p2tr,
});
Ensure you have enough UTXOs to cover the transaction inputs, gas fees, and any additional outputs.
Learn more about UTXO Manager.
2. Fetching Contract Bytecode
Retrieve the contract bytecode (compiled contract code) to be deployed. You can read the bytecode from a compiled .wasm file or use the hex string directly.
const bytecode = fs.readFileSync("your-contract.wasm");
// Or you can use the hex string directly:
// const bytecode = Buffer.from("your-contract-bytecode", "hex");
3. Constructing Deployment Parameters
The IDeploymentParameters interface defines the required parameters for contract deployment. Ensure you provide the signer, network, contract bytecode, and other necessary details.
const gasParameters = await provider.gasParameters();
const challenge = await provider.getChallenge();
const deploymentParameters: IDeploymentParameters = {
  signer: wallet.keypair,
  network: networks.regtest,
  from: wallet.p2tr,
  utxos,
  bytecode,
  challenge,
  feeRate: gasParameters.bitcoin.recommended.medium,
  priorityFee: 0n,
};
4. Signing the Deployment Transaction
Use the signDeployment method from TransactionFactory to sign the deployment transaction. This method returns a DeploymentResult object containing the signed transaction and contract details.
const transactionFactory = new TransactionFactory();
const deploymentResult = await transactionFactory.signDeployment(
  deploymentParameters
);
5. Broadcasting the Transaction
After signing the transaction, broadcast it to the network using the sendRawTransactions method from the provider.
const tx = await provider.sendRawTransactions(deploymentResult.transaction);
if (!tx[1].success) {
  throw new Error(`Transaction failed: ${tx[1].error}`);
}
// Deployment result
console.log("Transaction ID:", tx[1].result);
console.log("Contract Pubkey:", deploymentResult.contractPubKey);
console.log("P2OP Address:", deploymentResult.contractAddress);
Object Definitions
DeploymentResult Object| Property | Type | Description | 
|---|---|---|
| transaction | string | Array of raw transaction strings. | 
| contractAddress | string | Contract's P2OP address. | 
| contractPubKey | string | Contract's tweaked public key. | 
| p2opAddress | string | Contract's P2OP address. | 
| utxos | UTXO[] | Array of new UTXOs after deployment. | 
Full Example
import { networks } from "@btc-vision/bitcoin";
import {
  IDeploymentParameters,
  TransactionFactory,
  Wallet,
} from "@btc-vision/transaction";
import fs from "fs";
import { JSONRpcProvider } from "opnet";
// Initialize provider and wallet
const provider = new JSONRpcProvider(
  "https://regtest.opnet.org",
  networks.regtest
);
const wallet = Wallet.fromWif("your-private-key", networks.regtest);
// Fetch UTXOs for funding the deployment
const utxos = await provider.utxoManager.getUTXOs({
  address: wallet.p2tr,
});
// Contract bytecode (compiled contract code)
// You can get it from your wasm file, for example:
const bytecode = fs.readFileSync("your-contract.wasm");
// Or you can use the hex string directly:
// const bytecode = Buffer.from("your-contract-bytecode", "hex");
// Define deployment parameters
const gasParameters = await provider.gasParameters();
const challenge = await provider.getChallenge();
const deploymentParameters: IDeploymentParameters = {
  signer: wallet.keypair,
  network: networks.regtest,
  from: wallet.p2tr,
  utxos,
  bytecode,
  challenge,
  feeRate: gasParameters.bitcoin.recommended.medium,
  priorityFee: 0n,
};
// Create and sign the deployment transaction
const transactionFactory = new TransactionFactory();
const deploymentResult = await transactionFactory.signDeployment(
  deploymentParameters
);
// Broadcast the transaction
const tx = await provider.sendRawTransactions(deploymentResult.transaction);
if (!tx[1].success) {
  throw new Error(`Transaction failed: ${tx[1].error}`);
}
// Deployment result
console.log("Transaction ID:", tx[1].result);
console.log("Contract Pubkey:", deploymentResult.contractPubKey);
console.log("P2OP Address:", deploymentResult.contractAddress);
Best Practices
- Ensure your wallet has sufficient UTXOs to fund the deployment and associated fees.
- Adjust the feeRateandpriorityFeeparameters based on current network conditions to minimize costs.
- Before deploying on mainnet, test your contract deployment process on regtest or testnet to avoid unnecessary costs.