On Fuji Testnet
Learn how to deploy an Avalanche L1 on the Fuji Testnet.
This document describes how to use the new Avalanche-CLI to deploy an Avalanche L1 on Fuji
.
After trying out an Avalanche L1 on a local box by following this tutorial, next step is to try it out on Fuji
Testnet.
In this article, it's shown how to do the following on Fuji
Testnet.
- Create an Avalanche L1.
- Deploy a virtual machine based on Subnet-EVM.
- Join a node to the newly created Avalanche L1.
- Add a node as a validator to the Avalanche L1.
All IDs in this article are for illustration purposes. They can be different in your own run-through of this tutorial.
Prerequisites
- 1+ nodes running and fully bootstrapped on
Fuji
Testnet. Check out the section Nodes on how to run a node and become a validator. Avalanche-CLI
installed
Virtual Machine
Avalanche can run multiple blockchains. Each blockchain is an instance of a Virtual Machine, much like an object in an object-oriented language is an instance of a class. That's, the VM defines the behavior of the blockchain.
Subnet-EVM is the VM that defines the Avalanche L1 Contract Chains. Subnet-EVM is a simplified version of Avalanche C-Chain.
This chain implements the Ethereum Virtual Machine and supports Solidity smart contracts as well as most other Ethereum client features.
Fuji Testnet
For this tutorial, it's recommended that you follow Run an Avalanche Node Manually and this step below particularly to start your node on Fuji
:
To connect to the Fuji Testnet instead of the main net, use argument --network-id=Fuji
Also it's worth pointing out that it only needs 1 AVAX to become a validator on the Fuji Testnet and you can get the test token from the faucet. If you already have an AVAX balance greater than zero on Mainnet, paste your C-Chain address there, and request test tokens. Otherwise, please request a faucet coupon on Guild. Admins and mods on the official Discord can provide testnet AVAX if developers are unable to obtain it from the other two options.
To get the NodeID of this Fuji
node, call the following curl command to info.getNodeID:
The response should look something like:
That portion that says, NodeID-5mb46qkSBj81k9g9e4VFjGGSbaaSLFRzD
is the NodeID, the entire thing. The user is going to need this ID in the later section when calling addValidator.
With more data on Fuji
, it may take a while to bootstrap Fuji
Testnet from scratch. You can use State-Sync to shorten the time for bootstrapping.
Avalanche-CLI
If not yet installed, install Avalanche-CLI
following the tutorial at Avalanche-CLI installation
Private Key
All commands which issue a transaction require either a private key loaded into the tool, or a connected ledger device.
This tutorial focuses on stored key usage and leave ledger operation details for the Mainnet
deploy one, as Mainnet
operations requires ledger usage, while for Fuji
it's optional.
Avalanche-CLI
supports the following key operations:
- create
- delete
- export
- list
You should only use the private key created for this tutorial for testing operations on Fuji
or other testnets. Don't use this key on Mainnet
. CLI is going to store the key on your file system. Whoever gets access to that key is going to have access to all funds secured by that private key. To deploy to Mainnet
, follow this tutorial.
Run create
if you don't have any private key available yet. You can create multiple named keys. Each command requiring a key is going to therefore require the appropriate key name you want to use.
This is going to generate a new key named mytestkey
. The command is going to then also print addresses associated with the key:
You may use the C-Chain address (0x86BB07a534ADF43786ECA5Dd34A97e3F96927e4F
) to fund your key from the faucet. The command also prints P-Chain addresses for both the default local network and Fuji
. The latter (P-fuji1a3azftqvygc4tlqsdvd82wks2u7nx85rhk6zqh
) is the one needed for this tutorial.
The delete
command of course deletes a private key:
Be careful though to always have a key available for commands involving transactions.
The export
command is going to print your private key in hex format to stdout.
This key is intentionally modified.
You can also import a key by using the --file
flag with a path argument and also providing a name to it:
Finally, the list
command is going to list all your keys in your system and their associated addresses (CLI stores the keys in a special directory on your file system, tampering with the directory is going to result in malfunction of the tool).
Funding the Key
Do these steps only to follow this tutorial for Fuji
addresses. To access the wallet for Mainnet
, the use of a ledger device is strongly recommended.
- A newly created key has no funds on it. Send funds via transfer to its correspondent addresses if you already have funds on a different address, or get it from the faucet at
https://core.app/tools/testnet-faucet/
using your C-Chain address. If you already have an AVAX balance greater than zero on Mainnet, paste your C-Chain address there, and request test tokens. Otherwise, please request a faucet coupon on Guild. Admins and mods on the official Discord can provide testnet AVAX if developers are unable to obtain it from the other two options. - Export your key via the
avalanche key export
command. The output is your private key, which will help you import your account into the Core extension. - Connect Core extension to Core web, and move the test funds from C-Chain to the P-Chain by clicking Stake, then Cross-Chain Transfer (find more details on this tutorial).
After following these 3 steps, your test key should now have a balance on the P-Chain on Fuji
Testnet.
Create an EVM Avalanche L1
Creating an Avalanche L1 with Avalanche-CLI
for Fuji
works the same way as with a local network. In fact, the create
commands only creates a specification of your Avalanche L1 on the local file system. Afterwards the Avalanche L1 needs to be deployed. This allows to reuse configs, by creating the config with the create
command, then first deploying to a local network and successively to Fuji
- and eventually to Mainnet
.
To create an EVM Avalanche L1, run the blockchain create
command with a name of your choice:
This is going to start a series of prompts to customize your EVM Avalanche L1 to your needs. Most prompts have some validation to reduce issues due to invalid input. The first prompt asks for the type of the virtual machine (see Virtual Machine).
As you want to create an EVM Avalanche L1, just accept the default Subnet-EVM
. Next, CLI asks for the ChainID. You should provide your own ID. Check chainlist.org to see if the value you'd like is already in use.
Now, provide a symbol of your choice for the token of this EVM:
At this point, CLI prompts the user for the fee structure of the Avalanche L1, so that he can tune the fees to the needs:
You can navigate with the arrow keys to select the suitable setting. Use Low disk use / Low Throughput 1.5 mil gas/s
for this tutorial.
The next question is about the airdrop:
You can accept the default -again, NOT for production-, or customize your airdrop. In the latter case the wizard would continue. Assume the default here.
The final question is asking for precompiles. Precompiles are powerful customizations of your EVM. Read about them at precompiles.
For this tutorial, assume the simple case of no additional precompile. This finalizes the prompt sequence and the command exits:
It's possible to end the process with Ctrl-C at any time.
At this point, CLI creates the specification of the new Avalanche L1 on disk, but isn't deployed yet.
Print the specification to disk by running the describe
command:
Also you can list the available Avalanche L1s:
List deployed information:
Deploy the Avalanche L1
To deploy the Avalanche L1, you will need some testnet AVAX on the P-chain.
To deploy the new Avalanche L1, run:
This is going to start a new prompt series.
This tutorial is about deploying to Fuji
, so navigate with the arrow keys to Fuji
and hit enter. The user is then asked to provide which private key to use for the deployment. The deployment basically consists in running a createSubnet
transaction. Therefore the key needs to have funds.
Also, this tutorial assumes that a node is up running, fully bootstrapped on Fuji
, and runs from the same box.
Avalanche L1s are currently permissioned only. Therefore, the process now requires the user to provide which keys can control the Avalanche L1. CLI prompts the user to provide one or more P-Chain addresses. Only the keys corresponding to these addresses are going to be able to add or remove validators. Make sure to provide Fuji P-Chain addresses -P-Fuji....
-.
Enter at Add control key
and provide at least one key. You can enter multiple addresses, just use one here. When finishing, hit Done
. (The address provided here is intentionally invalid. The address has a checksum and the tool is going to make sure it's a valid address).
Finally, there is a need to define the threshold of how many keys to require for a change to be valid -there is some input validation-. For example, if the is one control key, as preceding, just enter 1. The threshold could be arbitrary depending on the needs, for example 2 of 4 addresses, 1 of 3, 3 of 5, etc., but currently this tool only works if the private key used here owns at least one control key and the threshold is 1.
Here the wizard completes, and CLI attempts the transaction.
If the private key isn't funded or doesn't have enough funds, the error message is going to be:
If the private key has funds, but the control key is incorrect (not controlled by the private key), the CLI is going to create the Avalanche L1, but not the blockchain:
Therefore the user needs to provide a control key which he has indeed control of, and then it succeeds. The output (assuming the node is running on localhost
and the API port set to standard 9650
) is going to look something like this:
Well done. You have just created your own Avalanche L1 with your own Subnet-EVM running on Fuji
.
To get your new Avalanche L1 information, visit the Avalanche L1 Explorer. The search best works by blockchain ID, so in this example, enter 2XDnKyAEr1RhhWpTpMXqrjeejN23vETmDykVzkb4PrU1fQjewh
into the search box and you should see your shiny new blockchain information.
Request to Join an Avalanche L1 as a Validator
The new Avalanche L1 created in the previous steps doesn't have any dedicated validators yet. To request permission to validate an Avalanche L1, the following steps are required:
Before a node can be a validator on an Avalanche L1, the node is required to already be a validator on the primary network, which means that your node has fully bootstrapped.
If the validator is within 24 hours of expiring on the primary network, it can't be added to the Avalanche L1.
See here on how to become a validator.
First, request permission to validate by running the join
command along with the Avalanche L1 name:
Note: Running join
does not guarantee that your node is a validator of the Avalanche L1! The owner of the Avalanche L1 must approve your node to be a validator afterwards by calling addValidator
as described in the next section.
When you call the join
command, you are first prompted with the network selection:
Next, there are two setup choices: Automatic and Manual configurations. As mentioned earlier, "Automatic" is going to attempt at editing a config file and setting up your plugin directory, while "Manual" is going to just print the required config to the screen. See what "Automatic" does:
Provide a path to a config file. If executing this command on the box where your validator is running, then you could point this to the actually used config file, for example /etc/avalanchego/config.json
- just make sure the tool has write access to the file. Or you could just copy the file later. In any case, the tool is going to either try to edit the existing file specified by the given path, or create a new file. Again, set write permissions.
Next, provide the plugin directory. The beginning of this tutorial contains VMs description Virtual Machine. Each VM runs its own plugin, therefore AvalancheGo needs to be able to access the correspondent plugin binary. As this is the join
command, which doesn't know yet about the plugin, there is a need to provide the directory where the plugin resides. Make sure to provide the location for your case:
The tool doesn't know where exactly it's located so it requires the full path. With the path given, it's going to copy the VM binary to the provided location:
Hitting Yes
is going to attempt at writing the config file:
It's required to restart the node.
If choosing "Manual" instead, the tool is going to just print instructions. The user is going to have to follow these instructions and apply them to the node. Note that the IDs for the VM and Avalanche L1s is going to be different in your case.
Add a Validator
If the join
command isn't successfully completed before addValidator
is completed, the Avalanche L1 could experience degraded performance or even halt.
Now that the node has joined the Avalanche L1, an Avalanche L1 control key holder must call addValidator
to grant the node permission to be a validator in your Avalanche L1.
To whitelist a node as a recognized validator on the Avalanche L1, run:
As this operation involves a new transaction, you will need to specify which private key to use:
Choose Fuji
:
Now use the NodeID of the new validator defined at the beginning of this tutorial. For best results make sure the validator is running and synced.
This ID is intentionally modified. The next question requires a bit of thinking. A validator has a weight, which defines how often consensus selects it for decision making. You should think ahead of how many validators you want initially to identify a good value here. The range is 1 to 100, but the minimum for an Avalanche L1 without any validators yet is 20.
Just select 30 for this one:
Then specify when the validator is going to start validating. The time must be in the future. Custom option is going to require to enter a specific date in YYYY-MM-DD HH:MM:SS
format. Just take the default this time:
Finally, specify how long it's going to be validating:
If choosing Custom
here, the user must enter a duration, which is a time span expressed in hours. For example, could say 200 days = 24 \* 200 = 4800 hours
CLI shows an actual date of when that's now:
Confirm if correct. At this point the prompt series is complete and CLI attempts the transaction:
This might take a couple of seconds, and if successful, it's going to print:
This means the node is now a validator on the given Avalanche L1 on Fuji
!
Avalanche L1 Export
This tool is most useful on the machine where a validator is or is going to be running. In order to allow a VM to run on a different machine, you can export the configuration. Just need to provide a path to where to export the data:
The file is in text format and you shouldn't change it. You can then use it to import the configuration on a different machine.
Avalanche L1 Import
To import a VM specification exported in the previous section, just issue the import
command with the path to the file after having copied the file over:
After this the whole Avalanche L1 configuration should be available on the target machine:
Appendix
Connect with Core
To connect Core (or MetaMask) with your blockchain on the new Avalanche L1 running on your local computer, you can add a new network on your Core wallet with the following values:
Unless you deploy your Avalanche L1 on other nodes, you aren't going to be able to use other nodes, including the public API server https://api.avax-test.network/
, to connect to Core.
If you want to open up this node for others to access your Avalanche L1, you should set it up properly with https//node-ip-address
instead of http://127.0.0.1:9650
, however, it's out of scope for this tutorial on how to do that.
Last updated on