NFT QR Dispenser

Nifty

We’ve all seen the CryptoKitty craze and subsequent explosion of NFT collectibles in the Ethereum ecosystem. NFTs, or non-fungible tokens, are a set of contracts that represent a collection of limited and unique tokens. Unlike the ERC20 standard where each token is fungible and represented simply by an account balance, ERC721 treats each token as an indivisible and unique asset. Each token is represented by its own owner, token ID, and metadata URL. Here’s an example of a token that I’ve created with some simple metadata:

The meta-data defines the image, the type of sticker (temporary tattoo), and the stickiness (65%).

NFT Generator

I wanted to build a simple user experience that allowed people new to cryptocurrency to collect NFTs. Since acquiring cryptocurrency is a high barrier to entry, I had to come up with an approach that didn’t require the user to pay for gas fees. I landed on building an automated job that gets triggered via a QR code.

The QR code navigates the user to the website. The website detects the web3 provider and makes a backend request to the Logic App webhook passing along the user’s Ethereum address. The Logic App generates a new NFT by using its funded Ethereum account and returns the URL to the freshly created NFT. The website then redirects the user to view the NFT on OpenSea.

Try it out yourself:

  1. Download Opera (android) or imToken mobile app
  2. Open the following QR code in the app
Demo of the user experience

You could imagine novel use-cases for a QR NFT generator:

  • NFT scavenger hunt with limited scans per QR code
  • Digital swag to give out at conferences, demos, or meetups
  • Loyalty collectibles for the readers of your blog

The rest of this post will walk you through how to create your own QR code NFT generator.

Deploy your NFT

The ERC721 contract acts as a collection of non-fungible tokens. The actual NFTs can be minted after the contract has been deployed. The contract is extremely simple since we’re letting the OpenZeppelin library do the heavy lifting.

pragma solidity ^0.5.0;
import 'openzeppelin-solidity/contracts/token/ERC721/ERC721MetadataMintable.sol';
import 'openzeppelin-solidity/contracts/ownership/Ownable.sol';
/**
* @title Sticker Collectible
* Sticker NFT - a contract for non-fungible stickers.
*/
contract StickerCollectible is ERC721Metadata("CryptoStickers", "CS"), Ownable, ERC721MetadataMintable {}

To deploy it, I found truffle-flattener to be helpful to flatten it down to a single file so that it could be viewed easily on Etherscan.

truffle-flattener ./contracts/StickerCollectible.sol > StickerCollectibleFlattened.sol

Deploy the contract using your contract deployer of choice. I just dropped it in Remix and used my MetaMask wallet.

Register the contract on OpenSea

OpenSea provides a nice browser for viewing your NFTs. After you register the contract address you can view the contract by navigating to:

https://rinkeby.opensea.io/assets/<name>

Example: https://rinkeby.opensea.io/assets/crypto-stickers

Using the same Ethereum account that deployed the contract, you can update your listing’s metadata.

Create your Logic App

Logic Apps is a platform in Azure that provides an incredibly simple way to build automation (think IFTTT). Logic Apps has a marketplace of over 200 different connectors ranging from consumer (Twitter, Twilio, Instagram) to enterprise (SAP, GitHub, Excel) and everything in between. Recently we published a handful of Ethereum connectors to make blockchain automation even easier. In this tutorial, we’re going to use one of these Ethereum connectors to call a smart contract when triggered by an HTTP Request.

  1. Create a new Logic App resource
  2. Select “Blank Logic App”
  3. Create an Http Request Trigger
  • Method: GET
  • Relative Path: /address/{address}
  • This allows us to use the path parameter to collect the user’s Ethereum address to send the NFT to.

Next we’ll initialize some variables for convenience (connector “Initialize variable”)

4. Add a variable for your contract address

  • Name: contract_address
  • Type: string
  • Value: <the address of your deployed contract>

5. Set the metadata_url

Each NFT that’s created points to a metadata JSON file that describes its characteristics (image, description, properties). Each NFT can have a different metadata URL. For now let’s set it to a static value. Later, we can see how to randomly generate these.

6. Generate the token_id

  • Name: token_id
  • Type: string
  • Value is and expression: rand(0,2147483647)

7. Create the Ethereum transaction

  • Search for Ethereum and add the connector Execute smart contract function (incurring gas cost)
  • Setup the connection (think of this like your database connection string). Provide an RPC endpoint (I recommend Infura for public networks). Add the private key from the same account you used to deploy the contract — this will grant us the mint capability.
  • Set the following snippet as the contract ABI. Note that we are only adding the ABI for the function that we’re interested in calling.
[
{
"constant": false,
"inputs": [
{
"name": "to",
"type": "address"
},
{
"name": "tokenId",
"type": "uint256"
},
{
"name": "tokenURI",
"type": "string"
}
],
"name": "mintWithTokenURI",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
]
  • Fill in the rest of the parameters with the variables we setup

8. Set the response

  • Here I’m returning the link to newly created NFT on OpenSea in the response body

9. Test it! Navigate to the URL from the Request connector and replace the {address} in the path with your Ethereum address.

If you get stuck, you can reference this Logic App code for comparison.

Web Proxy

We ultimately want a QR code to trigger this Logic App and then navigate the user to the NFT on OpenSea to view it. To do this we’ll setup a simple website to act as a proxy. Here’s a snippet of HTML/JS that will grab the web3 Ethereum address and construct a request to the Logic App endpoint. If the response is a success, it will redirect the page to the asset on OpenSea.

Generate the QR

Then we simply generate a QR code that points to our website. The QR needs to be scanned by an app that injects a Web3 provider. A couple phone apps that support Ethereum and QR scanning are Status, imToken, and Opera.

Note: Status requires you to prefix the QR URL with “https://get.status.im/browse/

Bonus

You can write a simple script to randomly generate the NFT metadata so that each NFT is unique. I found it easiest to generate the metadata using nodejs and upload the metadata to IPFS. I then take each IPFS url and store it in an Azure Storage Queue. Instead of pulling the metadata url from a static variable, I dequeue a message and use it for the metadata url when calling the mintWithTokenURI function.

Did you build your own NFT QR code? Share it in the comments below!