Deploying a Contract
Deploying a smart contract on OP_NET using WalletConnect requires careful handling of UTXOs and constructing deployment parameters. This guide explains the process of using walletWindowInstance to sign and deploy contracts.
Ensure you are using the OP_WALLET for deploying a smart contract. The walletWindowInstance should be initialized with the OP_WALLET provider to access the web3 methods.
const { walletWindowInstance } = useWallet();
if (!walletWindowInstance.web3) {
throw new Error("Web3 not found (use OP_WALLET)");
}
Steps to Deploy a Contract
1. Get Required Parameters
Before deploying a contract, ensure you have the following parameters:
account: Wallet account for transaction signing.walletWindowInstance: The instance of the wallet window for signing transactions.connect: Function to connect to the wallet.disconnect: Function to disconnect from the wallet.
import { useWallet } from "@btc-vision/walletconnect";
const { account, walletWindowInstance, connect, disconnect } = useWallet();
2. 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 account.provider.utxoManager.getUTXOs({
address: account.addressTyped,
});
Ensure you have enough UTXOs to cover the transaction inputs, gas fees, and any additional outputs.
Learn more about UTXO Manager.
3. 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 bytecodeArrayBuffer = await fetch("contract.wasm").then((res) =>
res.arrayBuffer()
);
// OR directly define the bytecode as a hex string
// const bytecode = Buffer.from(`your-contract-bytecode`, "hex");
4. Constructing Deployment Parameters
The IDeploymentParametersWithoutSigner interface defines the required parameters for contract deployment. Ensure you provide the contract bytecode, and other necessary details.
const gasParameters = await provider.gasParameters();
const deploymentParameters: IDeploymentParametersWithoutSigner = {
from: account.addressTyped,
bytecode: Buffer.from(bytecodeArrayBuffer),
utxos: utxos,
feeRate: gasParameters.bitcoin.recommended.medium, // <- use the result from provider.gasParameters()
priorityFee: 0n,
gasSatFee: gasParameters.gasPerSat,
};
5. Signing the Deployment Transaction
Use the walletWindowInstance to sign the deployment transaction. The deployContract method will handle the signing process and return a DeploymentResult object.
const deploymentResult = await walletWindowInstance.web3.deployContract(
deploymentParameters
);
if (!deploymentResult) throw new Error("Failed to deploy contract");
console.log("Deployment Result:", deploymentResult);
6. Broadcasting the Transaction
After signing the deployment transaction, you can broadcast it to the network using the sendRawTransactions method. This step finalizes the contract deployment process.
const transactionReceipt = await account.provider.sendRawTransactions(
deploymentResult.transaction
);
const txId = transactionReceipt[1].result;
console.log("Deploy Transaction:", txId);
console.log("Contract Address:", deploymentResult.contractPubKey);
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 { IDeploymentParametersWithoutSigner } from "@btc-vision/transaction";
import { SupportedWallets, useWallet } from "@btc-vision/walletconnect";
function DeployContract() {
const { account, walletWindowInstance, connect, disconnect } = useWallet();
async function deployContract() {
if (!account || !walletWindowInstance)
throw new Error("Connect wallet first");
if (!walletWindowInstance.web3)
throw new Error("Web3 not found (use OP_WALLET)");
const utxos = await account.provider.utxoManager.getUTXOs({
address: account.addressTyped,
});
const bytecodeArrayBuffer = await fetch("contract.wasm").then((res) =>
res.arrayBuffer()
);
const gasParameters = await provider.gasParameters();
const deploymentParameters: IDeploymentParametersWithoutSigner = {
from: account.addressTyped,
bytecode: Buffer.from(bytecodeArrayBuffer),
utxos: utxos,
feeRate: gasParameters.bitcoin.recommended.medium,
priorityFee: 0n,
gasSatFee: gasParameters.gasPerSat,
};
const deploymentResult = await walletWindowInstance.web3.deployContract(
deploymentParameters
);
if (!deploymentResult) throw new Error("Failed to deploy contract");
console.log("Deployment Result:", deploymentResult);
const transactionReceipt = await account.provider.sendRawTransactions(
deploymentResult.transaction
);
const txId = transactionReceipt[1].result;
console.log("Deploy Transaction:", txId);
console.log("Contract Address:", deploymentResult.contractPubKey);
}
return (
<div>
{account ? (
<div>
<p>Connected Address: {account.addressTyped}</p>
<button onClick={deployContract}>Deploy Contract</button>
<button onClick={disconnect}>Disconnect</button>
</div>
) : (
<button onClick={() => connect(SupportedWallets.OP_WALLET)}>
Connect Wallet
</button>
)}
</div>
);
}
export default DeployContract;
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.