Skip to main content

Deploy with Taquito

About Taquito

Taquito is TypeScript library suite for development on the Tezos blockchain. An entire chapter is dedicated to this library.

Before starting this chapter, it is important to have done the chapter on Taquito, especially the installation and the configuration. Although this chapter takes up these elements, they will not be explained in detail.

We're also going to use the raffle.ligo contract from the LIGO tutorial. The LIGO compiler is required to compile the contract. If you did not follow the LIGO tutorial, you can copy the complete contract from the last section.

Initializing the deployment

Let's start by installing the necessary dependencies :

mkdir deploy
touch deploy/main.ts
cd deploy
npx tsc --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://ghostnet.tezos.marigold.dev";

const deploy = async () => {
try {
const tezos = new TezosToolkit(RPC_URL);
tezos.setSignerProvider(new 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. Let's reuse the raffle.ligo contract from the Raffle example.

The ligo compiler allows this by passing the flag --michelson-format when compiling the contract:

mkdir contracts
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';
...

Origination with Taquito

Defining the initial storage

A smart contract defines a 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.

LIGOJavascript
List, Tuple, Set[]
Big_map, Mapconst bigMap = new MichelsonMap()
bigMap.set(key, values)
(from taquito module)
string, addressstring
bytesbuf2hex(Buffer.from(string_to_convert))
int, nat, muteznumber
recordObject {}
timestampDate.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://ghostnet.tezos.marigold.dev";

const deploy = async () => {
try {
// Initialize Taquito
const tezos = new TezosToolkit(RPC_URL);
tezos.setSignerProvider(new 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>>.

A 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://ghostnet.tezos.marigold.dev";

const deploy = async () => {
try {
// Initialize Taquito
const tezos = new TezosToolkit(RPC_URL);
tezos.setSignerProvider(new 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: onqm8fpox7aeTSV6TkLYSEKL9u2UWq5widZa5yFbgPLA2ji3EtV
Contract Address: KT1BvzBtpTNsB43mNTaEP1H4tgBx9Tfa4v3M

We can now check the transaction and the contract on an explorer.

Conclusion

The first step in developing a Dapp is to deploy the smart contracts. Taquito takes Michelson code and deploys it onto any public or private network.

Each origination needs an initial storage that is compliant with the storage type of the Michelson code.