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 parts and having a faucet activated. Although this chapter takes up these elements, they will not be explained in detail.

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. Remember that the faucet imported must be activated.

The basis of the project therefore looks like this :

// main.ts
import { TezosToolkit } from '@taquito/taquito';
import { InMemorySigner } from '@taquito/signer';

import * as faucet from './faucet.json';

const RPC_URL = "https://hangzhounet.smartpy.io";

const deploy = async () => {
try {
const tezos = new TezosToolkit(RPC_URL);
tezos.setSignerProvider(InMemorySigner.fromFundraiser(faucet.email, faucet.password, faucet.mnemonic.join(' ')));



} 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 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 * as faucet from './faucet.json';
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.fromFundraiser(faucet.email, faucet.password, faucet.mnemonic.join(' ')));

// Initial storage definition
const admin = faucet.pkh; // Admin address.
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 * as faucet from './faucet.json';
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.fromFundraiser(faucet.email, faucet.password, faucet.mnemonic.join(' ')));

// Initial storage definition
const admin = faucet.pkh; // Admin address.
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.

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.