Deploying a Contract in the Browser
Deploying a smart contract on OP_NET through a browser leverages the opnet.web3.deployContract()
method from the wallet's Web3Provider
. This guide walks you through deploying a contract directly using OP_WALLET in a browser environment.
For a detailed guide on interacting with OP_WALLET, refer to Interacting with a Browser Wallet that Directly Supports OP_NET.
Steps to Deploy a Contract
1. Request Public Key and UTXOs
First, you must fetch the connected wallet's public key and UTXOs to fund the transaction.
import { networks } from "@btc-vision/bitcoin";
import { Address } from "@btc-vision/transaction";
const pubKey = await opnet.getPublicKey();
const account = Address.fromString(pubKey); // Sender's address
const utxos = await provider.utxoManager.getUTXOs({
address: account.p2tr(networks.regtest), // Sender's address (P2TR)
});
Ensure you have enough UTXOs to cover the transaction inputs, gas fees, and any additional outputs.
Learn more about UTXO Manager.
2. Fetch the Contract Bytecode
Retrieve the contract bytecode from a file or define it directly as a hex string.
// Fetch the bytecode from a file and convert it to a Buffer
const bytecodeArrayBuffer = await fetch("contract.wasm").then((res) =>
res.arrayBuffer()
);
const bytecodeBuffer = Buffer.from(new Uint8Array(bytecodeArrayBuffer));
// OR directly define the bytecode as a hex string
// const bytecodeBuffer = Buffer.from("your-contract-bytecode", "hex");
3. Using opnet.web3.deployContract()
The deployContract()
method simplifies the deployment process by combining UTXO management, bytecode inclusion, and gas calculations.
const deployTx = await opnet.web3.deployContract({
from: account.p2tr(networks.regtest), // Sender's address (P2TR)
bytecode: bytecodeBuffer, // Contract bytecode
utxos, // UTXOs for funding
feeRate: Number((await provider.gasParameters()).baseGas * 2n), // Gas fee rate (satoshis per byte)
priorityFee: 5000n, // Priority fee for faster processing
// calldata: Buffer.from([]), // Optional initialization calldata
// optionalOutputs: [ // Optional additional outputs
// {
// address: "optional-address",
// value: 1000, // satoshis
// },
// ],
});
Full Example
import { networks } from "@btc-vision/bitcoin";
import { Address } from "@btc-vision/transaction";
import { JSONRpcProvider } from "opnet";
// Initialize the provider and OP_NET instance
const provider = new JSONRpcProvider(
"https://regtest.opnet.org",
networks.regtest
);
const opnet = window.opnet;
if (!opnet || !opnet.web3) {
throw new Error("OP_WALLET is not available in this browser.");
}
const pubKey = await opnet.getPublicKey();
const account = Address.fromString(pubKey); // Sender's address
const utxos = await provider.utxoManager.getUTXOs({
address: account.p2tr(networks.regtest), // Sender's address (P2TR)
});
if (!utxos || utxos.length === 0) {
throw new Error("No UTXOs available.");
}
// Fetch the bytecode from a file and convert it to a Buffer
const bytecodeArrayBuffer = await fetch("contract.wasm").then((res) =>
res.arrayBuffer()
);
const bytecodeBuffer = Buffer.from(new Uint8Array(bytecodeArrayBuffer));
// OR directly define the bytecode as a hex string
// const bytecodeBuffer = Buffer.from("your-contract-bytecode", "hex");
// Deploy the contract
const deployTx = await opnet.web3.deployContract({
from: account.p2tr(networks.regtest), // Sender's address (P2TR)
bytecode: bytecodeBuffer, // Contract bytecode
utxos, // UTXOs for funding
feeRate: Number((await provider.gasParameters()).baseGas * 2n), // Gas fee rate (satoshis per byte)
priorityFee: 5000n, // Priority fee for faster processing
// calldata: Buffer.from([]), // Optional initialization calldata
// optionalOutputs: [ // Optional additional outputs
// {
// address: "optional-address",
// value: 1000, // satoshis
// },
// ],
});
console.log("Deployed contract:", deployTx);
Deployment Result
The deployContract()
method returns a DeploymentResult
object:
export interface DeploymentResult {
readonly transaction: [string, string]; // Array of raw transaction strings
readonly contractAddress: string; // Contract's address
readonly contractPubKey: string; // Contract's tweaked public key
readonly p2trAddress: string; // Contract's P2TR address
readonly utxos: UTXO[]; // Array of new UTXOs after deployment
}
Best Practices
- Always verify that the selected UTXOs can cover the transaction's cost, including fees.
- Avoid deploying directly on mainnet without thorough testing on regtest or testnet.
- Handle private keys and sensitive information securely in your browser environment.