NFT (non-fungible token), as a non-fungible token as its name implies, is very suitable for use as an identity authentication tool.
Next, let’s explore the feasibility of using NFT as a registration credential through a simple example.
Preface
Before we get started, let me introduce the tools we will be using.
SPL Token
We can write a new Solana contract from scratch, but for our current purposes, we can directly use the general implementation provided by Solana: Token Program.
The Token Program is part of the Solana Program Library (SPL, https://spl.solana.com/). SPL provides multiple common program implementations including Token, Swap, and Memo, as well as complete client libraries, CLI and other tools, which greatly facilitates Solana developers.
The Token Program project source code is located at: https://github.com/solana-labs/solana-program-library/tree/master/token/program
Solana Playground
Solpy (https://beta.solpg.io/) provides an online environment for writing and deploying Solana contracts, and includes some commonly used tools by default, including the SPL Token introduced in the previous section. It allows us to easily create and manage tokens through spl-token-cli.
Auth Token
In this section, we will create an NFT Token. If the user mints the Token, it is considered that the wallet address has been registered in our system. Otherwise, the user will be prompted to register first.
Now, lets start with the On-chain part:
Creating a Token
We use spl-token to create a new token, and use --decimals to specify that it is an indivisible token (like an NFT)
The following log will be output:
The 69yXraTu3FqXZkATg6MiRnWT2qHd4tRzWsfCHHE9j2XE is often referred to as the Mint Address, which is also the ID of the Token we created.
The token address is:
https://solscan.io/token/69yXraTu3FqXZkATg6MiRnWT2qHd4tRzWsfCHHE9j2XE?cluster=devnet
Create Token Account
Next we need to create a Token Account for the Token created in the previous step.
mint
Before minting new tokens with other wallet addresses, lets try to mint a token unit for the token account created in the previous step. Just enter:
The following log will be output:
Or you can:
You can also try mint other values, such as 1.9:
Looking at the transaction details, we can see that: since we specified --decimals as 0 when creating the token in the first step, the decimal part will be discarded when mint is actually executed, so the mint amount will still be 1.
You can also try to mint tokens directly to a wallet address. Here we use 4wztJ4CAH4GbAUopZrVk7nLvoAC3KAF6ttMMWfnBRG1t to demonstrate:
Mint the wallet address
The target of the above mint operation is the Token Mint Address, but according to our original idea, we should mint other wallet addresses that do not belong to us.
Next, let’s complete the mint step above using the Web3 user’s wallet address.
Token we directly use the above 69yXraTu3FqXZkATg6MiRnWT2qHd4tRzWsfCHHE9j2XE
Wallet Address: Use 4wztJ4CAH4GbAUopZrVk7nLvoAC3KAF6ttMMWfnBRG1t
But when we simply replace the parameters, we get unexpected results:
The address does exist, but the address required by Mint is not the original wallet address, but the Token Account that needs to be associated with it.
We need to follow the same process as above: create a Token Account for the wallet address, and then use the created Token Account to mint a new Token unit.
In other words, if we want to mint a Token unit for a certain wallet address, we must first create a Token Account for this wallet address. As for why we need to do this, one of the reasons is that we do not have the authority to directly modify the data of a certain address.
In Solana’s documentation, you will sometimes see two similar concepts: Token Account and Associated Token Account (ATA). The documentation seems to have some connection between the two, but it does not explain this, which is very confusing.
However, if you look at the Metaplex documentation, you will find that it clearly states: Associated token accounts, sometimes referred to as token accounts for short.
We won’t delve into the two here, just imagine that the token account is the medium between the token and the wallet address.
We use the following command to create a Token Account for the wallet address:
Duplicate creation will result in an error:
It can also be seen in the log that the Token Account derived from the determined Mint Account and wallet address is certain (3JocyxV4LX4VbNU248CvNozZphgRW5JTyxn7FPWrF8bx), but the error message is printed because it already exists.
Get Token Account
We need to use the RPC interface to get whether a wallet address has minted the NFT we created. Specifically, use the getTokenAccountsByOwner method to query the data. The following are the parameters required by the interface:
You need to replace _YOUR_RPC_PROVIDER_ with the address provided by the RPC provider of your choice.
You can use the address provided by Solana, or you can find the public free RPC network here: https://zan.top/service/public-rpc/solana
Note: The public address may be unstable. If you need a stable RPC service, it is recommended to create your own API Key.
For the wallet address above, this is what it looks like:
In addition to manually filling in request parameters through code, you can also use the getParsedTokenAccountsByOwner method on the Connection provided in @solana/web3.js. Internally, it actually calls the getParsedTokenAccountsByOwner method through the RPC interface provided when creating the Connection.
If it is a wallet that has already created an Account Token, it will return:
Deleted the data that was not useful to us.
accomplish
Through the above attempts, we can see that we can use the existing capabilities to achieve the functions we want. Then, we will start writing the client code.
The following codes are all in https://github.com/gin-lsl/my-sol-token-auth-example
You can preview it here: https://my-sol-token-auth-example.vercel.app/
I will implement this by creating a simple Nextjs project and using Ant Design Web3 to connect the wallet:
Initialize Nextjs project
All options use default values:
To get started quickly, we will directly use @ant-design/web3-solana to connect the wallet and use @solana/spl-token to interact with the Token Program.
Add related dependencies:
We need to include 3 pages on the homepage, creating app/sign-in/page.tsx and app/sign-on/page.tsx. They are used to connect to the wallet and check whether the user has registered (whether to mint NFT), and let the user go through the registration process (mint NFT).
After opening the demo page, the first thing you see is a welcome message and a link to the Sign in page:
After entering the page, you need to sign in first:
Click “Continue with Solana” and the wallet will be launched.
If you have not registered before, you will be prompted to register first:
This is because in the logic of /api/sign-in, the associated Token Account will be searched based on the connected wallet address. Since we have not used it before, the data cannot be found, so the system will think that this wallet address has not been registered.
Then we follow the prompts and come to the Sign on page. The registration page is similar to the login page, except that the processing logic on the server is different:
In fact, the two logics can be merged, but they are separated here just for the sake of demonstration.
Anyway, let’s click “Start with Solana” and connect the wallet. Then, if everything goes well, you will see a success message:
Lets go to Solscan and see whats going on. Go to https://solscan.io/?cluster=devnet and query your wallet address. Alternatively, you can check this address: 79reVF46NyuuH7PADR3i6RpQ7hmBZgYkiieXNYPM1oLF
There is a transaction data:
Note that in Instructions, you can see that the CreateAccount instruction is executed inside the transaction. Click the link to enter the details and you will find that it creates a TokenAccount: EXfDYkHw3UQw2VqiSLsRAfLMsxkgqnd3nhxbB4V5HAvA. The isOnCurve value is False, indicating that it is an associated account without a private key.
Go back to the previous page and go to Portfolio -> NFTs. You can see the Mint operation we just did inside sign-on, as well as the NFT we minted:
Summarize
Lets summarize the whole process. We use spl-token-cli to create an NFT, and then check whether a wallet address has a Token Account and mints the Token to determine whether it has been registered on our website.
When a Web3 user connects to the wallet, we will automatically send a sign-on to the backend, create a Token Account internally, and mint a Token unit as the users registered credential.
In the future, users can log in to our website again with the same wallet address.
This article was written by gin-lsl from ZAN Team (X account @zan_team ).