Deploying your contract to Phron Testnet

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

Deploying Your Smart Contract to the Phron Testnet: Now it's time to deploy your newly created smart contract to the Phron Testnet. There are multiple ways to interact with the smart contract environment on the Phron blockchain. In this guide, we'll explore two common methods: using the Contracts UI and interacting via the command line with the cargo-contract tool.

Contracts UI

Deploying contracts

To deploy and interact with smart contracts, you'll need to use the Contracts UI, which packages all the necessary tools. Ensure you have created an account with the developer web wallet and obtained some free TPHR from the faucet. Without these steps, some tabs and buttons in the wallet may 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

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":

Select the account you wish to use for deploying the contract (if you have multiple accounts). This account will hold the entire initial supply of the new token created by the mytoken contract. Next, click on the "Upload contract bundle" field below and choose the location of your mytoken.contract file, which you previously generated with cargo contract (it should be in the mytoken/target/ink/ folder). If everything is correct, you should see a message indicating "Valid contract bundle!"

Click "Next." You will be prompted to provide the parameters for the contract's constructor to instantiate it. In this case, you only need to specify the initial supply of your token. You can choose any number for this; it does not need to match your account's TPHR 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's left is to click the "Upload and Instantiate" button to deploy the contract! You'll need to sign the transaction using your preferred account manager (currently, the default is the Polkadot.js extension). Afterward, you'll be directed to a screen with details about your contract, along with a dropdown menu to select a method to call on the 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 want to interact with smart contracts on the Phron blockchain in a more automated and programmable manner, you can use the cargo contract command-line tool, which was used to compile your contract. This tool can also perform all the actions described above. For a brief overview of all extrinsics-related functionalities available in cargo contract, you can refer to the summary provided 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://testnet.phron.ai"

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 include a list of events generated by the chain (such as paying fees, creating the contract's account, etc.) as a result of the deployment transaction. The final event should be System ➜ ExtrinsicSuccess, which indicates that the deployment was successful. It will be followed by information about the address of the contract we just created. Store this address in an environment variable for easier 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 earlier in the web wallet section, there are two types of calls you can make to a smart contract: state queries and executable calls. State queries request information about the contract's state without modifying it, while executable calls alter the state and require submitting a signed transaction and paying a fee. In cargo contract, these two types of actions are distinguished 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)

The argument here can be any valid account address. At this stage, all accounts other than the contract creator (the address associated with the seed phrase stored in $SEED) have 0 tokens, while the creator holds the total supply of 1000 tokens. To distribute tokens, you can transfer some 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 phron.ai.

Last updated