Intermediate
Deploy a Dapp with Taquito
Welcome to our tutorial on deploying a decentralized application (Dapp) with Taquito, a powerful JavaScript library for interacting with the Tezos blockchain network. In this tutorial, we will cover the process of using Taquito to build and deploy a decentralized application on the Tezos blockchain. We will walk through the process of writing, testing, and deploying a Dapp, as well as explain the key features and advantages of using Taquito.
By the end of this tutorial, you will have a solid understanding of how to use Taquito to build and deploy a decentralized application on the Tezos blockchain. You will also learn best practices for developing Dapps using Taquito and how to interact with them. This tutorial is ideal for developers and researchers interested in building and deploying decentralized applications on the Tezos blockchain using JavaScript and Taquito.
Initializing the deployment
Let’s start by installing the necessary dependencies :
mkdir deploy touch deploy/main.ts cd deploy npx typescript --init --resolveJsonModule yarn add typescript @taquito/taquito @taquito/signer @taquito/utils
Then, Taquito must be initialized and the signer provider set.
The basis of the project, therefore, looks like this :
// main.ts import { TezosToolkit } from '@taquito/taquito'; import { InMemorySigner } from '@taquito/signer'; const RPC_URL = "https://hangzhounet.smartpy.io"; const deploy = async () => { try { const tezos = new TezosToolkit(RPC_URL); tezos.setSignerProvider(InMemorySigner('YOUR_PRIVATE_KEY')); } catch (err) { console.log(err); } } deploy();
Let’s run it with:
npx ts-node main.ts
If Taquito is correctly installed and configured, this should not raise any exception.
Compiling smart contracts
To be deployed with Taquito, the smart-contract must be compiled in Michelson in JSON format.
The ligo compiler allows this by passing the flag --michelson-format
when compiling the contract:
ligo compile contract --michelson-format json raffle.ligo > contracts/raffle.json
The contract is now ready to be deployed. We can import it into our project :
// main.ts ... import raffleJson from './contracts/raffle.json'; ...
Taquito Origination
Defining the initial storage
A smart contract defines storage. When originated, the initial storage must be set and the storage must be compliant with the structure defined in the smart contract to be deployed: the names and types must be respected. It also allows you to work with types specific to Michelson, such as bigmaps.
We, therefore, need to import two additional functions :
import { MichelsonMap } from '@taquito/taquito'; import { buf2hex } from '@taquito/utils';
Below is the matching table between Javascript and LIGO.
List, Tuple, Set |
[] |
Big_map, Map |
const bigMap = new MichelsonMap() |
string, address |
string |
bytes |
|
int, nat, mutez |
number |
record |
Object {} |
timestamp |
Date.now() |
Here is what our initial storage should look like :
// main.ts import { TezosToolkit, MichelsonMap } from '@taquito/taquito'; import { InMemorySigner } from '@taquito/signer'; import { buf2hex } from '@taquito/utils'; import raffleJson from './contracts/raffle.json'; const RPC_URL = "https://hangzhounet.smartpy.io"; const deploy = async () => { try { // Initialize Taquito const tezos = new TezosToolkit(RPC_URL); tezos.setSignerProvider(InMemorySigner('YOUR_PRIVATE_KEY')); // Initial storage definition const admin = 'YOUR_PUBLIC_KEY_HASH'; // Admin address, tz1... const closeDate = Date.now() + 10; const jackpot = 100; const description = "This is an incredible Raffle."; const players = [] as any[]; const soldTickets = new MichelsonMap(); const raffleIsOpen = true; const winningTicketHash = buf2hex(Buffer.from("ec85151eb06e201cebfbb06d43daa1093cb4731285466eeb8ba1e79e7ee3fae3")); const initialStorage = { "admin": admin, "close_date": closeDate.toString(), "jackpot": jackpot, "description": description, "players": players, "sold_tickets": soldTickets, "raffle_is_open": raffleIsOpen, "winning_ticket_number_hash": winningTicketHash } } catch (err) { console.log(err); } } deploy();
Any type and structure change in the LIGO smart contract storage must be mirrored in the initialStorage variable. This way, the evolution of the storage used can be versioned.
Deploying the contract
Originations can be sent with tezos.contract.originate
. It returns a Promise<OriginationOperation<DefaultContractType>>
.
An OriginationOperation
contains the information about this origination. It also has a confirmation method. This method can wait for several confirmations on demand.
Let’s deploy our contract with this function by setting your code in JSON Michelson format and our initial storage :
// main.ts import { TezosToolkit, MichelsonMap } from '@taquito/taquito'; import { InMemorySigner } from '@taquito/signer'; import { buf2hex } from '@taquito/utils'; import raffleJson from './contracts/raffle.json'; const RPC_URL = "https://hangzhounet.smartpy.io"; const deploy = async () => { try { // Initialize Taquito const tezos = new TezosToolkit(RPC_URL); tezos.setSignerProvider(InMemorySigner('YOUR_PRIVATE_KEY')); // Initial storage definition const admin = 'YOUR_PUBLIC_KEY_HASH'; // Admin address, tz1... const closeDate = Date.now() + 10; const jackpot = 100; const description = "This is an incredible Raffle."; const players = [] as any[]; const soldTickets = new MichelsonMap(); const raffleIsOpen = true; const winningTicketHash = buf2hex(Buffer.from("ec85151eb06e201cebfbb06d43daa1093cb4731285466eeb8ba1e79e7ee3fae3")); const initialStorage = { "admin": admin, "close_date": closeDate.toString(), "jackpot": jackpot, "description": description, "players": players, "sold_tickets": soldTickets, "raffle_is_open": raffleIsOpen, "winning_ticket_number_hash": winningTicketHash } const origination = await tezos.contract.originate({ code: raffleJson, storage: initialStorage, }); await origination.confirmation(); const contract = await origination.contract(); console.log(`Operation Hash: ${origination.hash}`); console.log(`Contract Address : ${contract.address}`); } catch (err) { console.log(err); } } deploy();
Run the script and retrieve the operation hash and the contract address :
npx ts-node main.ts Operation Hash: oo9jUpwnfCnNqywT5dqFuoMhWgn9Ve3bKYqivNUy1jn3t2kKTb8 Contract Address : KT1Dkdiju5crR6qQMy9ozzWvTaVHBTA476gb
We can now check the transaction and the contract on an explorer.