---
id: dev-started-helloworld
title: Hello World
keywords:
  - hello world
  - example dapp
  - example project
  - zilliqajs
  - zilpay
  - zilliqa
description: Zilliqa Hello World Example
---

---

import useBaseUrl from "@docusaurus/useBaseUrl";

In this section, we will deploy and interact with a `Hello World` smart contract onto the Zilliqa testnet using [Neo-Savant web IDE](https://ide.zilliqa.com/#/) and [ZilPay wallet](https://zilpay.xyz/).

## Create Testnet Wallet using ZilPay

ZilPay is an [open source](https://github.com/zilpay/zil-pay) browser add-on that manages a user’s Zilliqa wallet and can be used on Chrome, Firefox and Opera browsers.
It does not store any user's private keys on the server. Instead, they are password protected and stored on browser storage.
It is a non-custodial wallet, meaning, only the user has full access and responsibility for their private key.

To create a ZilPay wallet:

1. Visit ZilPay's [website](https://zilpay.xyz/) and download the extension for your respective browser.
2. Open the extension, create a new wallet by verifying your 12 words recovery phrase and selecting a password for your wallet.
   :::note
   Please store your 12 words recovery phrase securely
   :::
3. Click on the `network change` button (shown below) and select the `network` as testnet.

<img
  alt="Change Network Button"
  src={useBaseUrl("img/dev/getting-started/zilpay-change-network-btn.png")}
/>

Voila! You have now successfully set up a testnet ZilPay wallet.

## Request Testnet $ZIL from Faucet

Deploying a contract to zilliqa's testnet will consume gas. As such you will need testnet $ZIL in your ZilPay account to pay for the gas.

To request for testnet $ZIL from the faucet,

1. Visit [Nucleus wallet testnet faucet](https://dev-wallet.zilliqa.com/faucet)
2. Enter and submit your ZilPay address to the faucet, you will receive 300 testnet $ZIL shortly. This will take about 30s to 1 min, as the transactions will need to be confirmed on the blockchain.

<img
  alt="Nucleus Wallet Faucet"
  src={useBaseUrl("img/dev/getting-started/nucleus-faucet.png")}
/>

## Deploying Contract on Testnet

To deploy the `Hello World` contract on the Zilliqa testnet, we will use the Scilla web IDE, [Neo-Savant IDE](https://ide.zilliqa.com/).

1. Change the `network` to testnet and import your wallet by connecting with Zilpay.

<img
  alt="IDE Step1"
  src={useBaseUrl("img/dev/getting-started/neo-savant-step1.png")}
/>

2. Select the `Hello World` contract under the files tab and click on `Check` button to use the [typechecker](https://scilla.readthedocs.io/en/latest/scilla-checker.html) to check for any syntax errors in your contract.

<img
  alt="IDE Step2"
  src={useBaseUrl("img/dev/getting-started/neo-savant-step2.png")}
/>

3. Once the typechecker result is passed, click on `Deploy` button to deploy the contract to testnet. Use your wallet address (Base16 format) for the "owner" initialisation parameter.

<img
  alt="IDE Step3"
  src={useBaseUrl("img/dev/getting-started/neo-savant-step3.png")}
/>

Yay! Your contract is now deployed on the testnet and can be accessed under the "Contracts" tab on the left side of the IDE.

:::tip
To convert from `Bech32` address format into base16 address format, you can use the address converter in the IDE. Click on `Tools > Address converter`.
:::

## Understanding the Hello World Contract

The Hello World contract written in the scilla smart contract programming language essentially consists of two transitions. The transitions of a scilla contract define the public interface for the contract and are a way to define how the state of the contract may change.<br/>
The two transitions in the Hello World are:

1. `setHello()` - `setHello` transition updates the value of the mutable variable - 'welcomeMsg' to the value of the transition parameter.

```ocaml
transition setHello (msg : String)
  is_owner = builtin eq owner _sender;
  match is_owner with
  | False =>
    e = {_eventname : "setHello()"; code : not_owner_code};
    event e
  | True =>
    welcome_msg := msg;
    e = {_eventname : "setHello()"; code : set_hello_code};
    event e
  end
end

```

2. `getHello()` - `getHello` transition fetches the value of the mutable variable - 'welcomeMsg' and emits it as an entry of an emitted event.

```ocaml
transition getHello ()
    r <- welcome_msg;
    e = {_eventname: "getHello()"; msg: r};
    event e
end

```

## Front-End Contract Interaction Using zilliqa-js

Let's interact with the `Hello World` contract using a simple front-end.

Clone the following repository and follow the installation steps: [Hello World Front-End](https://github.com/Zilliqa/dev-portal-examples/tree/master/hello-world).

```bash
git clone https://github.com/Zilliqa/dev-portal-examples.git
```

The above repository builds on the create-react-app starter kit. If you don't have experience working with React, this guide would still be useful for you as the zilliqa-js part of the code is VanillaJS and you can use that as it is in the framework of your choice.

## Change Contract State Using ZilPay

After following the installation steps, you need to run the code locally by using the command
`npm start`

On successfully running the web application locally on your system, enter the address of your Hello World contract deployed on the testnet and connect your ZilPay wallet with the front-end by clicking on the **Connect** button.

To call the transitions from the front-end using ZilPay:

1. `setHello()` - Upon clicking the **Set Hello** button and approving the transaction via ZilPay, the `setHello()` transition will be called and the value of the `welcomeMsg` mutable variable in the contract code will be updated with the new message.

The following code snippet achieves this functionality:

```javascript

  async updateWelcomeMsg(){
    const zilliqa = window.zilPay;
    let setHelloValue = this.state.setHelloValue;
    let contractAddress = localStorage.getItem("contract_address");
    const CHAIN_ID = 333;
    const MSG_VERSION = 1;
    const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION);
    const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions
    contractAddress = contractAddress.substring(2);
    const ftAddr = toBech32Address(contractAddress);
    try {
        const contract = zilliqa.contracts.at(ftAddr);
        const callTx = await contract.call(
            'setHello',
            [
                {
                    vname: 'msg',
                    type: 'String',
                    value: setHelloValue
                }
            ],
            {
                // amount, gasPrice and gasLimit must be explicitly provided
                version: VERSION,
                amount: new BN(0),
                gasPrice: myGasPrice,
                gasLimit: Long.fromNumber(10000),
            }
        );

    } catch (err) {
        console.log(err);
    }
  }
```

2. `getHello()` - Upon clicking the 'Get Hello' button and approving the transaction via ZilPay, the `getHello()` transition will be called and the value of the `welcomeMsg` mutable variable is emitted as part of a contract event.

We will use the Zilliqa WebSocket Server (ZWS) to subscribe to all new event logs generated for our Hello World contract. This allows us to update the Welcome Msg on the web application as soon as the `getHello()` transaction gets confirmed and an event is emitted.

The following code snippet achieves this functionality:

```javascript

  async getWelcomeMsg(){

    const zilliqa = window.zilPay;
    let contractAddress = localStorage.getItem("contract_address");
    const CHAIN_ID = 333;
    const MSG_VERSION = 1;
    const VERSION = bytes.pack(CHAIN_ID, MSG_VERSION);
    const myGasPrice = units.toQa('1000', units.Units.Li); // Gas Price that will be used by all transactions
    contractAddress = contractAddress.substring(2);
    const ftAddr = toBech32Address(contractAddress);
    try {
        const contract = zilliqa.contracts.at(ftAddr);
        const callTx = await contract.call(
            'getHello',
            [
            ],
            {
                // amount, gasPrice and gasLimit must be explicitly provided
                version: VERSION,
                amount: new BN(0),
                gasPrice: myGasPrice,
                gasLimit: Long.fromNumber(10000),
            }
        );
        console.log(JSON.stringify(callTx.TranID));
        this.eventLogSubscription();
    } catch (err) {
        console.log(err);
    }

  }
  // Code that listens to websocket and updates welcome message when getHello() gets called.
  async eventLogSubscription() {
    const zilliqa = new Zilliqa('https://dev-api.zilliqa.com');
    const subscriber = zilliqa.subscriptionBuilder.buildEventLogSubscriptions(
      'wss://dev-ws.zilliqa.com',
      {
        // smart contract address you want to listen on
        addresses: [localStorage.getItem("contract_address")],
      },
    );

    subscriber.emitter.on(StatusType.SUBSCRIBE_EVENT_LOG, (event) => {
      // if subscribe success, it will echo the subscription info
      console.log('get SubscribeEventLog echo : ', event);
    });

    subscriber.emitter.on(MessageType.EVENT_LOG, (event) => {
      console.log('get new event log: ', JSON.stringify(event));
      // updating the welcome msg when a new event log is received related to getHello() transition
      if(event.hasOwnProperty("value")){
        if(event.value[0].event_logs[0]._eventname =="getHello"){
          let welcomeMsg = event.value[0].event_logs[0].params[0].value;
          this.setState({welcomeMsg: welcomeMsg});
          console.log("welcomeMsg", welcomeMsg);
        }
      }
    });
    await subscriber.start();
  }
```

## View Receipt on ViewBlock Explorer

[ViewBlock explorer](https://viewblock.io/zilliqa?network=testnet) is a block explorer that supports both Zilliqa mainnet and testnet. It allows you to look at the status of your transaction, current status of the Zilliqa network, contract source code etc.

For example, this is the ViewBlock's [transaction link](https://viewblock.io/zilliqa/tx/c4030c73d6dae558ff0c9d98237101e342888115f13219a00bb14a8ee46fa3be?network=testnet) for a getHello() transition transaction.
