Skip to content
Documentation
Advanced
Deploy Contract

Deploy Contract

Simple Summary

An RPC method for allowing users to deploy a new smart contract to TON network. ton_deployContract RPC method allow to do it.

This use case apllied in a few different ways. DApp developers may offer to wallet owners to deploy their personal contracts. It's a useful feature allowing owners to store and get information in the contract. Or it can be an option to deploy an NFT contract to reward users after completing a tutorial or course.

Deploy Parameters

interface DeployParams {
    // Smart contract code hexadecimal string
    initCodeCell: string;
    // Smart contract initial data hexadecimal string
    initDataCell: string;
    // Initial mesasge hexadecimal string (optional)
    initMessageCell?: string;
    // Amount to funding smart contract in nanotons, to pay network and storage fee
    amount: string;
}

Example

Please read more about the example in the blog post. You may find information how to build contract code initCodeCell and generate initDataCell or initMessageCell.

import { useState } from "react";
import { beginCell, Address } from "@openproduct/web-sdk";

const initCode =
  "b5ee9c72c1020f01000109000000000d00120017001c0023002800360040004e0053006c0071008701040114ff00f4a413f4bcf2c80b010201620902020120080302014805040009b59f10055002015807060017ad0c76a2687d20699f9818c0000faf607c13b79118400017bffecf6a2687d20699f981840202cd0b0a002dd7c13b7911829815f797033c1044c4b4050895b047800c0201480d0c00271c20063232c15400f3c5807e80b2dab25cfec02001f30cb434c0fe900c005c6c2456f83b51343e9034cfcc00f4c7f4cfcc4860840dd247cbeea7c408d7c0c069321633c5b2cff27b553808608411f550e46ea497c1780860841060da602ea7cc4cd9b1c17cb819807e800c007c01380060840b68e2abeea384d671c17cb819be900c00721633c5b2cff27b553817c1200e0006f2c065ea043d88";

const getInitData = async (ownerAddress, counter) => {
  return await beginCell()
    .storeAddress(new Address(ownerAddress))
    .storeUint(counter, 64) // 64 - mean the counter value take 64 bits in a cell - int64 type
    .endCell()
    .toHex();
};

const getInitMessage = async () => {
  return await beginCell()
    .storeUint(0x37491f2f, 32)
    .storeUint(0, 64)
    .endCell()
    .toHex();
};

export default () => {
  const [disabled, setDisabled] = useState(false);
  const [isSent, setSent] = useState(false);
  const [isConfirm, setConfirm] = useState(false);
  const [address, setAddress] = useState("");

  const send = async () => {
    const provider = window.ton;
    setSent(false);
    setConfirm(false);

    setDisabled(true);
    try {
      const [ownerAddress] = await provider.send("ton_requestAccounts");

      const { walletSeqNo, newContractAddress } = await provider.send(
        "ton_deployContract",
        [
          {
            initCodeCell: initCode,
            initDataCell: await getInitData(ownerAddress, 7),
            initMessageCell: await getInitMessage(),
            amount: "50000000", // 0.05 TON
          },
          ownerAddress,
        ]
      );
      setSent(true);
      await provider.send("ton_confirmWalletSeqNo", [walletSeqNo, ownerAddress]);

      setAddress(newContractAddress);
      setConfirm(true);
    } catch (e) {
      console.error(e);
    } finally {
      setDisabled(false);
    }
  };

  return (
    <div>
      <button disabled={disabled} onClick={send}>
        Deploy Smart Contract
      </button>
      {isSent && (
        <div>
          {isConfirm
            ? "Done. New contract address: " + address
            : "Deploy Pending... ~15 sec"}
        </div>
      )}
    </div>
  );
};

Result

For the counter the correct value is 8. The initial value is 7 and the initial transaction is increment with increment 7 and stored to contract cell.

For the contract owner it has to be your user-friendly bounceable wallet address.