Deploying your contract to Aleph Zero Testnet

In this tutorial, we will go over the some of the ways of interacting with the smart contract environments on the Aleph Zero blockchain.

We will now deploy our brand new smart contract to the Aleph Zero Testnet. There exist multiple ways of interacting with the smart contracts environment on the the Aleph Zero blockchain. Here we present two of them: using the Contracts UI and using the command line, via the cargo contract tool.

Contracts UI

Deploying contracts

All the required tools for deploying and interacting with the smart contracts are conveniently packaged as the Contracts UI. Make sure you have created an account using the developer web wallet and got some free TZERO from the faucet, otherwise some tabs and buttons in the wallet might not be visible to you.

Go to the Developer tab and click Contracts in the pop-up menu to access the smart contracts contracts UI (you can also directly follow the link above):

Once in the Contracts UI, click "Add new contract" in the side menu to navigate to the deployment page and then select "Upload new contract":

Choose the account you would like to use to deploy the contract (in case you have many). This account is going to hold the whole initial supply of your new token created by mytoken contract. Now click the "Upload contract bundle" field below and choose the location of your mytoken.contract file you have previously generated with cargo contract (it should be located in mytoken/target/ink/ folder). If everything is ok, you should see a "Valid contract bundle!" text.

Click "Next". You will now be asked to supply the parameters to the constructor of your contract in order to instantiate it. In our case this is just the initial supply of our token (you can pick an arbitrary number here: it is not connected in any way to your account's TZERO balance.

There are some custom options that we are going to cover in a later tutorial. Notice the cost estimation on the right. It will, among other things, tell you whether your account has enough balance to create this contract (i.e. cover the gas fees).

If everything goes well you will be presented with the following screen:

All that remains to be done is clicking the "Upload and instantiate" button to deploy the contract! You will need to sign the transaction using the account manager of your choice (the default being the Polkadot.js extension for now). Afterwards, you will see a screen with information about your contract and a dropdown list to choose a method to call on a contract:

You can also select the "Metadata" tab to view the methods callable on your contract:

Interacting with contracts

Now it's finally the time to play around with our new token! Assuming you have selected "mytoken" from the contracts list on the left, we now have a dropdown to select a method to call on our contract.

You will notice that the read-only methods balanceOf and totalSupply return the result immediately in the "Outcome" modal on the right: this is because as read-only, they don't need to create a transaction for the call.

The interesting part is calling the transfer method.

You will need a second account to have a valid recipient of the transfer (actually, as long as the account address has the correct format, it doesn't need to be associated with any existing account to work. However, simply creating another account is the easiest way of obtaining a valid address for testing purposes).

We need to enter the transferred amount (you can experiment what happens if you enter a value larger than the initial supply you chose when creating the contract). Once again we will leave the additional options at their default values.

Similar to contract instantiation, you can find the handy gas estimation on the right side of the screen and use it to verify whether you have enough funds to run this call (gas-fees-wise). You will once again need to sign the transaction and the transfer is done! Using balanceOf, you can now verify whether the transfer has indeed happened.

Command line

Deploying contracts

If you wish to interact with smart contracts on the Aleph Zero blockchain in a more automated and programmable way, the cargo contract command line tool, which we have compiled our contract with, can also be used to perform all the actions described above. A brief summary of all extrinsics-related functionalities of cargo contract can be found here.

Every cargo contract subcommand which interacts with a live chain needs to be invoked with flags defining the chain endpoint address and the user's private key (seed phrase). To make the commands present in this section more concise, let's first define some environmental variables with values that will be used with these flags:

export SEED="[put your 12 words seed phrase here]"
export URL="wss://ws.test.azero.dev"

Deploying our new contract can be done with instantiate subcommand. Make sure you are in mytoken folder, where our contract lives, and execute the following command:

cargo contract instantiate --suri "$SEED" --url "$URL" \
        --constructor new_token \
        --args 1000

The output of this command will contain a list of various events generated by the chain (paying fees, creating contact's account etc.) as a result of our deployment transaction. The last event should be System ➜ ExtrinsicSuccess indicating that the deployment was successful, followed by the information about the address of the contract we just created. Let's store this address in another environmental variable for more convenient interaction with the contract:

export CONTRACT="5GNruCfnGXjSPkW7LkRnB45MiHJJtvc6NBKZnDSnFh4So3ws

The contract address can also be used to import an existing contract into web wallet we used in the previous section. In the smart contracts manager click "Add an existing contract" and paste the address there. You also need to upload the metadata.json file with ABI, which was produced during compilation and should be present in mytoken/target/ink/ folder. After that you can interact with the contract in the same way as described previously.

Interacting with contracts

As mentioned previously in the web wallet section, there are two types of calls that one can perform on a smart contract: state queries, which ask about contract state without modifying it and executable calls, which modify the state and require submitting a signed transaction and paying a fee. These two types of actions are distinguished in cargo contract by the --dry-run flag.

Let's start with performing the simplest argumentless state query to find out the total supply of our token:

cargo contract call --suri "$SEED" --url "$URL" \
        --contract "$CONTRACT" \
        --message total_supply \
        --dry-run

The output will contain, among others, the data returned by our total_supply function:

          Result Success!
        Reverted false
            Data 1000
    Gas Consumed 248300975
    Gas Required 6815744000
 Storage Deposit StorageDeposit::Charge(0)

To perform a state query with arguments, like balance_of, we need to add --args flag, similarly to when we were deploying the contact and and calling its constructor:

cargo contract call --suri "$SEED" --url "$URL" \
        --contract "$CONTRACT" \
        --message balance_of \
        --args 5FWmHxBXH4WfrryA6xdbaQRJALJ549aL11HMyybqDy5iNRtE \
        --dry-run

Output:
          Result Success!
        Reverted false
            Data 1000
    Gas Consumed 322051074
    Gas Required 6815744000
 Storage Deposit StorageDeposit::Charge(0)

Here the argument can be any valid account address. Of course, at this point, all acounts other than the contract creator (the address associated with the seed phrase we have put in $SEED) have 0 tokens and the creator holds the total supply of 1000 tokens. So let's change it by transferring some tokens to another account:

cargo contract call --suri "$SEED" --url "$URL" \
        --contract "$CONTRACT" \
        --message transfer \
        --args 5D853t8wQuHJpfWvtcB3VUyKo8Ki44HQwgTmynGT4i5UVhbr 100

This time we want to send a transaction that modifies the chain state, so the --dry-run flag should be omitted. The output will contain a list of events generated by our transaction ending with familiar System ➜ ExtrinsicSuccess indicating that our call was successful. We can now verify that the transfer of 100 tokens indeed happened:

cargo contract call --suri "$SEED" --url "$URL" \
        --contract "$CONTRACT" \
        --message balance_of \
        --args 5FWmHxBXH4WfrryA6xdbaQRJALJ549aL11HMyybqDy5iNRtE \
        --dry-run

Output:
          Result Success!
        Reverted false
            Data 900
    Gas Consumed 322051074
    Gas Required 6815744000
 Storage Deposit StorageDeposit::Charge(0)
cargo contract call --suri "$SEED" --url "$URL" \
        --contract "$CONTRACT" \
        --message balance_of \
        --args 5D853t8wQuHJpfWvtcB3VUyKo8Ki44HQwgTmynGT4i5UVhbr \
        --dry-run

Output:
          Result Success!
        Reverted false
            Data 100
    Gas Consumed 322051074
    Gas Required 6815744000
 Storage Deposit StorageDeposit::Charge(0)

Next steps

Congratulations! You are now a smart contract developer. If you would like to learn more about ink! smart contracts, we encourage you to take a dive into the excellent ink! documentation. You can also check a collection of example ink! contracts located here. If you have any problems or questions we are always happy to help, just reach us using one of the channels listed on alephzero.org.

Last updated