To confirm ownership we first have to add a confirmOwnership
method to our smart contract and redeploy it.
Then, we can call that confirmOwnership
method on the connected smart contract within a useEffect
hook in our React dApp.
Instructor: [0:00] Let's add a way to confirm that a wallet address owns one of our NFTs. To do that, we're going to need to update our smart contract and redeploy it to Rinkeby Testnet. Back in our solidity file, let's go to the bottom here.
[0:13] We're going to define a new function, say, function confirm ownership. This is going to receive a wallet address. We'll call it Addy for now. This is going to be a public view function that returns a Boolean. Inside, we'll set the return value.
[0:30] We're going to take the holder token IDs array from our contract state and grab the value whose key matches our address, Addy. Because this value will be an array of token IDs, let's just check that its length is greater than zero. Meaning this address owns an NFT ticket.
[0:48] Before we jump back to the UI, we need to redeploy the contract to Rinkeby. We'll say, yarn deploy network Rinkeby. Once the contract has been deployed, it's important we do two things in our UI repo.
[1:03] First, we need to copy and paste this address into our environment variable file. Second, we need to copy our ABI file, this NFTicks booth JSON to our React app. I'm going to grab this, copy and paste it, go to our UI.
[1:19] I'll open NFTicks booth JSON, remove its contents, and paste the new one. Save it. Open my environment variable file and then paste the new smart contract address. With all that up to date, let's come into the app component.
[1:32] We'll come down to our routes and pass connected contract into our component as a new prop. Let's open check-in. Here we have a new prop called connected contract. We're also going to want to add a new effect hook to this component. We'll import useEffect from React.
[1:53] In the component below, we'll come down and add our new hook, useEffect. For our dependency array, we'll say that whenever the value of our connected contract, or the scanned address change, that we want this hook to run.
[2:08] Inside the hook, we're going to define a new asynchronous function, const confirm ownership equals async. Inside the async function will be a try block with the catch. We'll take the error and just log it out for now.
[2:28] Inside the try, let's confirm we have our connected contract in the first place because if we don't we can't do anything here. We'll return early. Otherwise, const res equals await connected contract.confirm ownership. We're going to pass it the scanned address we got from the QR Reader.
[2:49] Since this is a read-only operation, we do not need to wait for the transaction to resolve. We can just console.log res. Below, inside of the scope of the hook, but outside of the scope of the function, we'll say,
[3:02] If we have a scanned address, let's call confirm ownership and confirm whether this wallet address owns an NFT ticket. If we come into the browser, open the console, scroll down, click Scan QR, and then I scan my mobile wallet QR code. You can see we have a new log that says false.
[3:25] If we close the console, come into the admin panel, open the sale. Go to buy and mint a new NFT ticket. Then go to scan our QR code again. Now it says, true. Back in our component, let's add a new state variable to keep track of this, const has ticket, set has ticket equals useState false.
[3:58] Then we'll come down below into our effect hook. If we receive a value back from the smart contract, we'll say, set has ticket is equal to res. Lastly, let's come down to our markup and add some more conditional rendering.
[4:14] First, let's add a new conditional block and say, if we're not showing a scanner and we have a scanned address and it owns a ticket, let's render out a new text block. We'll have it say, "This wallet owns a NFTicks." We're also going to wrap this in a fragment.
[4:34] Right below the text, we're going to run our new flexbox. Inside, we'll add a button. We'll give it a label, Check-in, and set the size to large. Let's come down to this block that renders when the scanner isn't showing and add some nested conditional rendering.
[4:52] First, we're going to wrap everything in a fragment. Then we're going to add a conditional block here and say when we're not showing a scanner and we don't have a scanned address, let's display this block of text. Below that, we'll add a second block.
[5:07] When the scanner is not showing we have a scanned address, but it doesn't own a ticket, let's add another text block. We'll have it say, "This wallet does not own a NFTicks. Please try again."
[5:25] Finally, we'll add a third conditional block and say that regardless of whether we have a scanned address or not, if we don't have a ticket, let's render another button to allow the user to try again.
[5:36] Add a flexbox. Inside, it will add a button that'll say, Scan QR. It will be size large. We'll also need to give the button an onClick, which will take an anonymous function and set show scanner to true. Since we don't need two scan QR buttons, we'll come down below and remove the duplicate.
[6:05] If we go to the browser, I'll scan my QR code again. You can see it says, "This wallet owns an NFT." If I refresh, then this time scan the QR code of a different wallet, you'll see it says, "This wallet does not own a ticket. Please try again."
[6:24] In summary, we added a new function to our smart contract and then updated the contract address and ABI file in our React application. We also added an effect hook that will call our smart contract to confirm whether or not the scanned wallet address owns one of our NFT tickets.