# Komorebi No Sekai smart contract
###### tags: `Ethereum` `Solidity` `ERC721A` `Chainlink`
[ToC]
## ERC721A
Our smart contract us an extension of [ERC721A](https://www.erc721a.org/) from [Azuki](https://www.azuki.com/) team.
ERC721A is an improved implementation of the IERC721 standard that supports minting multiple tokens for close to the cost of one.
It is a great addition to the NFT ecosystem since it improves the user experience during minting periods, especially during global network congestion phases.
## Chainlink VRF
From Chainlink documentation:
`
Chainlink VRF (Verifiable Random Function) is a provably-fair and verifiable source of randomness designed for smart contracts. Smart contract developers can use Chainlink VRF as a tamper-proof random number generator (RNG) to build reliable smart contracts for any applications which rely on unpredictable outcomes
`
It is a powerful feature when you need to generate random numbers in your smart contracts. And that's great because we needed such feature.
We wanted to reward a random person from the minters of the primary sale. However,it was obvious to the team that an off chain selection of the winner was not an option.
Indeed, we strongly believe in decentralization and transparency. This is why we decided to use Chainlink VRF capability to implement the selection of the winner.
The process of the winner selection and gifting is the following:
```sequence
KNS Dev-> KNS Contract: select random winner
KNS Contract-> Chainlink VRF: request randomness
Chainlink VRF-> KNS Contract: fullfill randomness(random_value)
Chainlink VRF-> Chainlink VRF: derive random_value to\n get a winning ticket id
Chainlink VRF-> Chainlink VRF: get the owner of the winning ticket
Chainlink VRF-> Winner address: transfer NFT gifts
```
Select random winner function:

Send gifts to winner function:

## Mock time
Using time to control processes in smart contract makes harder testing. Indeed, you need to be able to mock the time to test specific behaviours, especially edge cases.
A NFT smart contract usually deals with the primary mint phase, which involves to deal time. For instance, you may want to open the sale at a specific time only.
To make easier testing we decided to create a function to retrieve the time instead of directly using `block.timestamp` when we need to get the current timestamp.
The function is the following:

Nothing crazy here, right ? Indeed this is a basic function that returns the timestamp using `block.timestamp`.
The interesting part is the `virtual` keyword. It allows an inheriting contract to override its behavior.
Then we created an inheriting contract to leverage this function for testing purpose:

And we use this contract instead of the parent one when we run our tests. This enable us to be able to mock the time and tests specific part of the code.
For example:

We can easily check that it is impossible to mint before the sale start time.
If you are interested in learning more about the project, please check the following resources.
## Resources
- [Website](https://komorebinosekai.com/)
- [Twitter](https://twitter.com/KomorebiNoSekai)
- [OpenSea](https://opensea.io/collection/komorebi-no-sekai)
- [Etherscan](https://etherscan.io/address/0x675CDdAc819D41C37331644047508822D764aBed#code)
> Leave in-line comments! [color=#3b75c6]