[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nend_of_line = lf\ninsert_final_newline = true\ncharset = utf-8\nindent_style = space\nindent_size = 2\ntrim_trailing_whitespace = true\n\n[*.sol]\nindent_size = 4\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto eol=lf\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules/\nartifacts/\ncache/\n.env\n"
  },
  {
    "path": "README.md",
    "content": "# Tutorial for hardhat-deploy based on https://hardhat.org/tutorial/\n\n# 1. Setting up the environment\n\nMost Ethereum libraries and tools are written in JavaScript, and so is **Hardhat**. If you're not familiar with Node.js, it's a JavaScript runtime built on Chrome's V8 JavaScript engine. It's the most popular solution to run JavaScript outside of a web browser and **Hardhat** is built on top of it.\n\n## Installing Node.js\n\nYou can [skip](./creating-a-new-hardhat-project.md) this section if you already have a working Node.js `>=12.0` installation. If not, here's how to install it on Ubuntu, MacOS and Windows.\n\n\n### Linux\n\n#### Ubuntu\n\nCopy and paste these commands in a terminal:\n\n```\nsudo apt update\nsudo apt install curl git\ncurl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -\nsudo apt install nodejs\n```\n\n### MacOS\n\nMake sure you have `git` installed. Otherwise, follow [these instructions](https://www.atlassian.com/git/tutorials/install-git).\n\nThere are multiple ways of installing Node.js on MacOS. We will be using [Node Version Manager (nvm)](http://github.com/creationix/nvm).\n\nCopy and paste these commands in a terminal:\n\n```\ncurl -o- https://raw.githubusercontent.com/creationix/nvm/v0.35.2/install.sh | bash\nnvm install 12\nnvm use 12\nnvm alias default 12\nnpm install npm --global # Upgrade npm to the latest version\n```\n\n### Windows\n\nInstalling Node.js on Windows requires a few manual steps. We'll install git, Node.js 12.x and npm.\n\nDownload and run these:\n1. [Git's installer for Windows](https://git-scm.com/download/win)\n2. `node-v12.XX.XX-x64.msi` from [here](https://nodejs.org/dist/latest-v12.x)\n\n\n## Upgrading your Node.js installation\n\nIf your version of Node.js is older than `12.0` follow the instructions below to upgrade.\n\n### Linux\n\n#### Ubuntu\n\n1. Run `sudo apt remove nodejs` in a terminal to remove Node.js.\n2. Find the version of Node.js that you want to install [here](https://github.com/nodesource/distributions#debinstall) and follow the instructions.\n3. Run `sudo apt update && sudo apt install nodejs` in a terminal to install Node.js again.\n\n### MacOS\n\nYou can change your Node.js version using [nvm](http://github.com/creationix/nvm). To upgrade to Node.js `12.x` run these in a terminal:\n\n```\nnvm install 12\nnvm use 12\nnvm alias default 12\nnpm install npm --global # Upgrade npm to the latest version\n```\n\n### Windows\n\nYou need to follow the [same installation instructions](#windows) as before but choose a different version. You can check the list of all available versions [here](https://nodejs.org/en/download/releases/).\n\n## Installing yarn\n\nFor this tutorial we are going to use [yarn](yarnpkg.com)\n\nTo install it do the following:\n\n```\nnpm install -g yarn\n```\n\n\n# 2. Creating a new Hardhat project\n\nWe'll install **Hardhat** using the npm CLI. The **N**ode.js **p**ackage **m**anager is a package manager and an online repository for JavaScript code.\n\nOpen a new terminal and run these commands:\n\n```\nmkdir hardhat-deploy-tutorial\ncd hardhat-deploy-tutorial\nyarn init --yes\nyarn add -D hardhat\n```\n\n::: tip\nInstalling **Hardhat** will install some Ethereum JavaScript dependencies, so be patient.\n:::\n\nIn the same directory where you installed **Hardhat** add a `hardhat.config.ts` (we are going to use typescript and the Solidity 0.7.6 compiler)\n\n```typescript\nimport {HardhatUserConfig} from 'hardhat/types';\nconst config: HardhatUserConfig = {\n  solidity: {\n    version: '0.7.6',\n  }\n};\nexport default config;\n\n```\n\n## Hardhat's architecture\n\n**Hardhat** is designed around the concepts of **tasks** and **plugins**. The bulk of **Hardhat**'s functionality comes from plugins, which as a developer [you're free to choose](/plugins/) the ones you want to use.\n\n### Tasks\nEvery time you run **Hardhat** from the CLI you're running a task. e.g. `npx hardhat compile` is running the `compile` task. To see the currently available tasks in your project, run `npx hardhat`. Feel free to explore any task by running `npx hardhat help [task]`.\n\n::: tip\nYou can create your own tasks. Check out the [Creating a task](/guides/create-task.md) guide.\n:::\n\n### Plugins\n**Hardhat** is unopinionated in terms of what tools you end up using, but it does come with some built-in defaults, all of which can be overriden. Most of the time the way to use a given tool is by consuming a plugin that integrates it into **Hardhat**.\n\nFor this tutorial we are going to use the `hardhat-deploy` and `hardhat-deploy-ethers` plugins. They'll allow you to interact with Ethereum and to test your contracts. We'll explain how they're used later on. We also install `ethers`, `chai`, `mocha` and `typescript` and extra dependencies. To install them, run the following command in your project directory:\n\n```\nyarn add -D hardhat-deploy hardhat-deploy-ethers ethers chai chai-ethers mocha @types/chai @types/mocha @types/node typescript ts-node dotenv\n```\n\nEdit `hardhat.config.ts` so that it looks like this:\n\n```typescript {1}\nimport {HardhatUserConfig} from 'hardhat/types';\nimport 'hardhat-deploy';\nimport 'hardhat-deploy-ethers';\n\nconst config: HardhatUserConfig = {\n  solidity: {\n    version: '0.7.6',\n  },\n  namedAccounts: {\n    deployer: 0,\n  },\n};\nexport default config;\n\n```\n\nWe also create the following `tsconfig.json` :\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"module\": \"commonjs\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"moduleResolution\": \"node\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\n    \"hardhat.config.ts\",\n    \"./deploy\",\n    \"./test\",\n  ]\n}\n```\n\n\n# 3. Writing and compiling smart contracts\n\nWe're going to create a simple smart contract that implements a token that can be transferred. Token contracts are most frequently used to exchange or store value. We won't go in depth into the Solidity code of the contract on this tutorial, but there's some logic we implemented that you should know:\n\n- There is a fixed total supply of tokens that can't be changed.\n- The entire supply is assigned to the address that deploys the contract.\n- Anyone can receive tokens.\n- Anyone with at least one token can transfer tokens.\n- The token is non-divisible. You can transfer 1, 2, 3 or 37 tokens but not 2.5.\n\n::: tip\nYou might have heard about ERC20, which is a token standard in Ethereum. Tokens such as DAI, USDC, MKR and ZRX follow the ERC20 standard which allows them all to be compatible with any software that can deal with ERC20 tokens. **For simplicity's sake the token we're going to build is _not_ an ERC20.**\n:::\n\n## Writing smart contracts\n\nWhile by default hardhat uses `contracts` as the source folder, we prefer to change it to `src`.\n\nYou then need to edit your `hardhat.config.ts` file with the new config:\n\n```typescript\nimport {HardhatUserConfig} from 'hardhat/types';\nimport 'hardhat-deploy';\nimport 'hardhat-deploy-ethers';\n\nconst config: HardhatUserConfig = {\n  solidity: {\n    version: '0.7.6',\n  },\n  namedAccounts: {\n    deployer: 0,\n  },\n  paths: {\n    sources: 'src',\n  },\n};\nexport default config;\n\n```\n\nStart by creating a new directory called `src` and create a file inside the directory called `Token.sol`.\n\nPaste the code below into the file and take a minute to read the code. It's simple and it's full of comments explaining the basics of Solidity.\n\n::: tip\nTo get syntax highlighting you should add Solidity support to your text editor. Just look for Solidity or Ethereum plugins. We recommend using Visual Studio Code or Sublime Text 3.\n:::\n\n```solidity\n// SPDX-License-Identifier: MIT\n// The line above is recommended and let you define the license of your contract\n// Solidity files have to start with this pragma.\n// It will be used by the Solidity compiler to validate its version.\npragma solidity ^0.7.0;\n\n\n// This is the main building block for smart contracts.\ncontract Token {\n    // Some string type variables to identify the token.\n    // The `public` modifier makes a variable readable from outside the contract.\n    string public name = \"My Hardhat Token\";\n    string public symbol = \"MBT\";\n\n    // The fixed amount of tokens stored in an unsigned integer type variable.\n    uint256 public totalSupply = 1000000;\n\n    // An address type variable is used to store ethereum accounts.\n    address public owner;\n\n    // A mapping is a key/value map. Here we store each account balance.\n    mapping(address => uint256) balances;\n\n    /**\n     * Contract initialization.\n     *\n     * The `constructor` is executed only once when the contract is created.\n     */\n    constructor(address _owner) {\n        // The totalSupply is assigned to transaction sender, which is the account\n        // that is deploying the contract.\n        balances[_owner] = totalSupply;\n        owner = _owner;\n    }\n\n    /**\n     * A function to transfer tokens.\n     *\n     * The `external` modifier makes a function *only* callable from outside\n     * the contract.\n     */\n    function transfer(address to, uint256 amount) external {\n        // Check if the transaction sender has enough tokens.\n        // If `require`'s first argument evaluates to `false` then the\n        // transaction will revert.\n        require(balances[msg.sender] >= amount, \"Not enough tokens\");\n\n        // Transfer the amount.\n        balances[msg.sender] -= amount;\n        balances[to] += amount;\n    }\n\n    /**\n     * Read only function to retrieve the token balance of a given account.\n     *\n     * The `view` modifier indicates that it doesn't modify the contract's\n     * state, which allows us to call it without executing a transaction.\n     */\n    function balanceOf(address account) external view returns (uint256) {\n        return balances[account];\n    }\n}\n```\n\n::: tip\n`*.sol` is used for Solidity files. We recommend matching the file name to the contract it contains, which is a common practice.\n:::\n\n## Compiling contracts\n\nTo compile the contract run `yarn hardhat compile` in your terminal. The `compile` task is one of the built-in tasks.\n\n```\n$ yarn hardhat compile\nCompiling 1 file with 0.7.3\nCompilation finished successfully\n```\n\nThe contract has been successfully compiled and is ready to be used.\n\n# 4. Deployment Scripts\n\nBefore you will be able to test or deploy your contract, you must set up the deployment process that can then be used both in testing as well as deployment to various live networks.\nThis allow you to focus on what the contracts will be in their final form, setup their parameters and dependencies, and ensure your tests are running against the exact code that will be deployed.\n\nThis also removes the need to duplicate the deployment procedures. This is made possible thanks to the `hardhat-deploy` plugin.\n\n## Writing deployment scripts\nCreate a new directory called `deploy` in the project root, and in that directory create a new file called `001_deploy_token.ts`.\n\nLet's start with the code below. We'll explain it soon, but for now paste this code into `001_deploy_token.ts`:\n\n```typescript\nimport {HardhatRuntimeEnvironment} from 'hardhat/types';\nimport {DeployFunction} from 'hardhat-deploy/types';\n\nconst func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {\n  const {deployments, getNamedAccounts} = hre;\n  const {deploy} = deployments;\n\n  const {deployer, tokenOwner} = await getNamedAccounts();\n\n  await deploy('Token', {\n    from: deployer,\n    args: [tokenOwner],\n    log: true,\n  });\n};\nexport default func;\nfunc.tags = ['Token'];\n\n```\n\nNotice the mention of `getNamedAccounts`?\n\nThe plugin `hardhat-deploy` allows you to name your accounts. Here there are 2 named accounts:\n- `deployer` will be the account used to deploy the contract.\n- `tokenOwner` which is passed to the constructor of Token.sol and which will receive the initial supply.\n\nThese accounts need to be setup in hardhat.config.ts\n\nModifiy it so it looks like this:\n\n```typescript\nimport {HardhatUserConfig} from 'hardhat/types';\nimport 'hardhat-deploy';\nimport 'hardhat-deploy-ethers';\n\nconst config: HardhatUserConfig = {\n  solidity: {\n    version: '0.7.6',\n  },\n  namedAccounts: {\n    deployer: 0,\n    tokenOwner: 1,\n  },\n  paths: {\n    sources: 'src',\n  },\n};\nexport default config;\n\n```\n\n`deployer` was already there and is setup to use the first account (index = 0).\n\n`tokenOwner` is the second account.\n\nNote that instead of index you can use hard-coded addresses or even references other named accounts. You can also have different addresses based on each network. See `hardhat-deploy` documentation [here](https://github.com/wighawag/hardhat-deploy#1-namedaccounts-ability-to-name-addresses)\n\nIn your terminal, run `yarn hardhat deploy`. You should see the following output:\n\n```\nNothing to compile\ndeploying \"Token\" (tx: 0x259d19f33819ec8d3bd994f82912aec6af1a18ec5d74303cfb28d793a10ff683)...: deployed at 0x5FbDB2315678afecb367f032d93F642f64180aa3 with 592983 gas\nDone in 3.66s.\n```\n\nYour contract was deployed to the `in-memory` Hardhat network and the output indicates that deployment was successful.\n\nWe can now write tests against this contract.\n\nFirst we will add comments to the deploy script above to explain each line that matters:\n\n```typescript\nimport {HardhatRuntimeEnvironment} from 'hardhat/types'; // This adds the type from hardhat runtime environment.\nimport {DeployFunction} from 'hardhat-deploy/types'; // This adds the type that a deploy function is expected to fulfill.\n\nconst func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // the deploy function receives the hardhat runtime env as an argument\n  const {deployments, getNamedAccounts} = hre; // we get the deployments and getNamedAccounts which are provided by hardhat-deploy.\n  const {deploy} = deployments; // The deployments field itself contains the deploy function.\n\n  const {deployer, tokenOwner} = await getNamedAccounts(); // Fetch the accounts. These can be configured in hardhat.config.ts as explained above.\n\n  await deploy('Token', { // This will create a deployment called 'Token'. By default it will look for an artifact with the same name. The 'contract' option allows you to use a different artifact.\n    from: deployer, // Deployer will be performing the deployment transaction.\n    args: [tokenOwner], // tokenOwner is the address used as the first argument to the Token contract's constructor.\n    log: true, // Display the address and gas used in the console (not when run in test though).\n  });\n};\nexport default func;\nfunc.tags = ['Token']; // This sets up a tag so you can execute the script on its own (and its dependencies).\n\n```\n\n\nNot as mentioned in the comment, the name of the deployed contract is set to be the same name as the contract name: `Token`. You can deploy different version of it by simply using a different name for it, like so:\n\n\n```typescript\nawait deploy('MyToken_1', { // name of the deployed contract\n  contract: 'Token', // name of the token source\n  from: deployer,\n  args: [tokenOwner],\n  log: true,\n});\n```\n\n# 5. Testing contracts\n\nWriting automated tests when building smart contracts is of crucial importance, as your user's money is what's at stake. For this we're going to use **Hardhat Network**, a local Ethereum network designed for development that is built-in and acts as the default network in **Hardhat**. You don't need to set anything up to use it. In our tests we're going to use ethers.js to interact with the Ethereum contract we built in the previous section, and [Mocha](https://mochajs.org/) will be our test runner.\n\n## Writing tests\nCreate a new directory called `test` in the project root directory and in that `test` directory, create a new file called `Test.test.ts`.\n\nLet's start with the code below. We'll explain it shortly, but for now just paste the following code into `Test.test.ts`:\n\n```typescript\nimport {expect} from \"./chai-setup\";\n\nimport {ethers, deployments, getNamedAccounts} from 'hardhat';\n\ndescribe(\"Token contract\", function() {\n  it(\"Deployment should assign the total supply of tokens to the owner\", async function() {\n    await deployments.fixture([\"Token\"]);\n    const {tokenOwner} = await getNamedAccounts();\n    const Token = await ethers.getContract(\"Token\");\n    const ownerBalance = await Token.balanceOf(tokenOwner);\n    const supply = await Token.totalSupply();\n    expect(ownerBalance).to.equal(supply);\n  });\n});\n\n```\n\nWe also create a new file called `chai-setup.ts` in the test folder:\n\n```typescript\nimport chaiModule from 'chai';\nimport {chaiEthers} from 'chai-ethers';\nchaiModule.use(chaiEthers);\nexport = chaiModule;\n\n```\n\nThis will use chai matchers from `chai-ethers` but also allows you to easily add more.\n\n\nThen in your terminal run `npx hardhat test`. You should see the following output:\n\n```\n$ npx hardhat test\n\n  Token contract\n    ✓ Deployment should assign the total supply of tokens to the owner (654ms)\n\n\n  1 passing (663ms)\n```\n\nThis means the test passed sucessfully. Now Let's examine each line.\n\n```typescript\nawait deployments.fixture([\"Token\"]);\n```\n\nRemember the deploy script we wrote earlier? This line allow to execute it prior to the test. It also generates an evm_snapshot automatically so if you write many tests, and they all refer to that fixture, the deployment will not be reexecuted. Indeed, behind the scene it does not redeploy it again and again, instead it automatically reverts to a previous state, speeding up your tests significantly!\n\n\n```typescript\nconst {tokenOwner} = await getNamedAccounts();\n```\n\nThis gives you access to the tokenOwner address, the same address that was used in the deploy script.\n\n\n```typescript\nconst Token = await ethers.getContract(\"Token\");\n```\n\nSince we already ran the deploy script, we can easily access the deployed contract by name. This is what this line does, and thanks to `hardhat-deploy-ethers` plugin, you get an ethers contract ready to be invoked. If you needed that contract to be associated to a specific signer, you can pass the address as the extra argument like `const TokenAsOwner = await ethers.getContract('Token', tokenOwner);`\n\n\n```typescript\nconst ownerBalance = await Token.balanceOf(tokenOwner);\n```\n\nNow we can call contract methods on `Token`. To get the balance of the owner account, we can call `balanceOf()`.\n\n```typescript\nconst supply = await Token.totalSupply();\n```\n\nHere we will again use our `Contract` instance to call a smart contract function. `totalSupply()` returns the token's supply amount.\n\n```typescript\nexpect(ownerBalance).to.equal(supply);\n```\n\nFinally we're checking that it's equal to `ownerBalance`, which it should be.\n\n\nTo do this we're using [Chai](https://www.chaijs.com/) which is an assertions library. These assertion functions are called \"matchers\", and the ones we're using here actually come from `chai-ethers` npm package (which itself is a fork of [Waffle chai matchers](https://getwaffle.io/) without unecessary dependencies).\n\n### Using a different account\n\n While testing your code, you may need to send a transaction from an account other than the default one. To do this you can use the second argument to `getContract` :\n\n```typescript\nimport {expect} from \"./chai-setup\";\n\nimport {ethers, deployments, getNamedAccounts, getUnnamedAccounts} from 'hardhat';\n\ndescribe(\"Token contract\", function() {\n  it(\"Deployment should assign the total supply of tokens to the owner\", async function() {\n    await deployments.fixture([\"Token\"]);\n    const {tokenOwner} = await getNamedAccounts();\n    const users = await getUnnamedAccounts();\n    const TokenAsOwner = await ethers.getContract(\"Token\", tokenOwner);\n    await TokenAsOwner.transfer(users[0], 50);\n    expect(await TokenAsOwner.balanceOf(users[0])).to.equal(50);\n\n    const TokenAsUser0 = await ethers.getContract(\"Token\", users[0]);\n    await TokenAsUser0.transfer(users[1], 50);\n    expect(await TokenAsOwner.balanceOf(users[1])).to.equal(50);\n  });\n});\n```\n\n### Full coverage\n\nNow that we've covered the basics you'll need for testing your contracts, here's a full test suite for the token with a lot of additional information about Mocha and how to structure your tests. We recommend reading through.\n\n\nBut first we add some utility functions that we will use in the test suite.\n\nCreate a folder called `utils` in the `test` folder and inside it, create a file called `index.ts` with the following content:\n\n```typescript\nimport {Contract} from 'ethers';\nimport {ethers} from 'hardhat';\n\nexport async function setupUsers<T extends {[contractName: string]: Contract}>(\n  addresses: string[],\n  contracts: T\n): Promise<({address: string} & T)[]> {\n  const users: ({address: string} & T)[] = [];\n  for (const address of addresses) {\n    users.push(await setupUser(address, contracts));\n  }\n  return users;\n}\n\nexport async function setupUser<T extends {[contractName: string]: Contract}>(\n  address: string,\n  contracts: T\n): Promise<{address: string} & T> {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const user: any = {address};\n  for (const key of Object.keys(contracts)) {\n    user[key] = contracts[key].connect(await ethers.getSigner(address));\n  }\n  return user as {address: string} & T;\n}\n\n```\n\nThis approach will allow you to have succinct and easy to read tests as you can see from the following example.\n\nHere is the test suite. Overwrite Test.test.ts with the following content:\n\n```typescript\n// We import Chai to use its assertion functions here.\nimport {expect} from \"./chai-setup\";\n\n// we import our utilities\nimport {setupUsers, setupUser} from './utils';\n\n// We import the hardhat environment field we are planning to use\nimport {ethers, deployments, getNamedAccounts, getUnnamedAccounts} from 'hardhat';\n\n// we create a setup function that can be called by every test and setup variable for easy to read tests\nasync function setup () {\n  // it first ensures the deployment is executed and reset (use of evm_snapshot for faster tests)\n  await deployments.fixture([\"Token\"]);\n\n  // we get an instantiated contract in the form of a ethers.js Contract instance:\n  const contracts = {\n    Token: (await ethers.getContract('Token')),\n  };\n\n  // we get the tokenOwner\n  const {tokenOwner} = await getNamedAccounts();\n\n  // Get the unnammedAccounts (which are basically all accounts not named in the config,\n  // This is useful for tests as you can be sure they have noy been given tokens for example)\n  // We then use the utilities function to generate user objects\n  // These object allow you to write things like `users[0].Token.transfer(....)`\n  const users = await setupUsers(await getUnnamedAccounts(), contracts);\n  // finally we return the whole object (including the tokenOwner setup as a User object)\n  return {\n    ...contracts,\n    users,\n    tokenOwner: await setupUser(tokenOwner, contracts),\n  };\n}\n\n// `describe` is a Mocha function that allows you to organize your tests. It's\n// not actually needed, but having your tests organized makes debugging them\n// easier. All Mocha functions are available in the global scope.\n\n// `describe` receives the name of a section of your test suite, and a callback.\n// The callback must define the tests of that section. This callback can't be\n// an async function.\ndescribe(\"Token contract\", function() {\n\n  // You can nest describe calls to create subsections.\n  describe(\"Deployment\", function () {\n    // `it` is another Mocha function. This is the one you use to define your\n    // tests. It receives the test name, and a callback function.\n\n    // If the callback function is async, Mocha will `await` it.\n    it(\"Should set the right owner\", async function () {\n      // Expect receives a value, and wraps it in an Assertion object. These\n      // objects have a lot of utility methods to assert values.\n\n      // before the test, we call the fixture function.\n      // while mocha have hooks to perform these automatically, they force you to declare the variable in greater scope which can introduce subttle errors\n      // as such we prefers to have the setup called right at the beginning of the test. this also allow yout o name it accordingly for easier to read tests.\n      const {Token} = await setup();\n\n\n      // This test expects the owner variable stored in the contract to be equal to our configured owner\n      const {tokenOwner} = await getNamedAccounts();\n      expect(await Token.owner()).to.equal(tokenOwner);\n    });\n\n    it(\"Should assign the total supply of tokens to the owner\", async function () {\n      const {Token, tokenOwner} = await setup();\n      const ownerBalance = await Token.balanceOf(tokenOwner.address);\n      expect(await Token.totalSupply()).to.equal(ownerBalance);\n    });\n  });\n\n  describe(\"Transactions\", function () {\n    it(\"Should transfer tokens between accounts\", async function () {\n      const {Token, users, tokenOwner} = await setup();\n      // Transfer 50 tokens from owner to users[0]\n      await tokenOwner.Token.transfer(users[0].address, 50);\n      const users0Balance = await Token.balanceOf(users[0].address);\n      expect(users0Balance).to.equal(50);\n\n      // Transfer 50 tokens from users[0] to users[1]\n      // We use .connect(signer) to send a transaction from another account\n      await users[0].Token.transfer(users[1].address, 50);\n      const users1Balance = await Token.balanceOf(users[1].address);\n      expect(users1Balance).to.equal(50);\n    });\n\n    it(\"Should fail if sender doesn’t have enough tokens\", async function () {\n      const {Token, users, tokenOwner} = await setup();\n      const initialOwnerBalance = await Token.balanceOf(tokenOwner.address);\n\n      // Try to send 1 token from users[0] (0 tokens) to owner (1000 tokens).\n      // `require` will evaluate false and revert the transaction.\n      await expect(users[0].Token.transfer(tokenOwner.address, 1)\n      ).to.be.revertedWith(\"Not enough tokens\");\n\n      // Owner balance shouldn't have changed.\n      expect(await Token.balanceOf(tokenOwner.address)).to.equal(\n        initialOwnerBalance\n      );\n    });\n\n    it(\"Should update balances after transfers\", async function () {\n      const {Token, users, tokenOwner} = await setup();\n      const initialOwnerBalance = await Token.balanceOf(tokenOwner.address);\n\n      // Transfer 100 tokens from owner to users[0].\n      await tokenOwner.Token.transfer(users[0].address, 100);\n\n      // Transfer another 50 tokens from owner to users[1].\n      await tokenOwner.Token.transfer(users[1].address, 50);\n\n      // Check balances.\n      const finalOwnerBalance = await Token.balanceOf(tokenOwner.address);\n      expect(finalOwnerBalance).to.equal(initialOwnerBalance - 150);\n\n      const users0Balance = await Token.balanceOf(users[0].address);\n      expect(users0Balance).to.equal(100);\n\n      const users1Balance = await Token.balanceOf(users[1].address);\n      expect(users1Balance).to.equal(50);\n    });\n  });\n});\n\n```\n\nThis is what the output of `yarn hardhat test` should look like after running the full test suite:\n\n```\n$ yarn hardhat test\n\n  Token contract\n    Deployment\n      ✓ Should set the right owner\n      ✓ Should assign the total supply of tokens to the owner\n    Transactions\n      ✓ Should transfer tokens between accounts (199ms)\n      ✓ Should fail if sender doesn’t have enough tokens\n      ✓ Should update balances after transfers (111ms)\n\n\n  5 passing (1s)\n```\n\nKeep in mind that when you run `yarn hardhat test`, your contracts will be compiled if they've changed since the last time you ran your tests.\n\n\n# 6. Debugging with Hardhat Network\n**Hardhat** comes built-in with **Hardhat Network**, a local Ethereum network designed for development. It allows you to deploy your contracts, run your tests, and debug your code. It's the default network **Hardhat** connects to, so you don't need to set anything up for it to work, you just run your tests.\n\n## Solidity `console.log`\nWhen running your contracts and tests on **Hardhat Network** you can print logging messages and contract variables calling `console.log()` from your Solidity code. To use it you have to import **Hardhat**'s`console.log` in your contract code.\n\nThis is what it looks like:\n\n```solidity\npragma solidity 0.7.6;\n\nimport \"hardhat/console.sol\";\n\ncontract Token {\n  //...\n}\n```\n\nTry adding some `console.log` statments to the `transfer()` function as if you were using it in JavaScript:\n\n```solidity {2,3}\nfunction transfer(address to, uint256 amount) external {\n  console.log(\"Sender balance is %s tokens\", balances[msg.sender]);\n  console.log(\"Trying to send %s tokens to %s\", amount, to);\n\n  require(balances[msg.sender] >= amount, \"Not enough tokens\");\n\n  balances[msg.sender] -= amount;\n  balances[to] += amount;\n}\n```\n\nThe logging output will show when you run your tests:\n\n```{8-11,14-17}\n$ yarn hardhat test\n\n  Token contract\n    Deployment\n      ✓ Should set the right owner\n      ✓ Should assign the total supply of tokens to the owner\n    Transactions\nSender balance is 1000 tokens\nTrying to send 50 tokens to 0xead9c93b79ae7c1591b1fb5323bd777e86e150d4\nSender balance is 50 tokens\nTrying to send 50 tokens to 0xe5904695748fe4a84b40b3fc79de2277660bd1d3\n      ✓ Should transfer tokens between accounts (373ms)\n      ✓ Should fail if sender doesn’t have enough tokens\nSender balance is 1000 tokens\nTrying to send 100 tokens to 0xead9c93b79ae7c1591b1fb5323bd777e86e150d4\nSender balance is 900 tokens\nTrying to send 100 tokens to 0xe5904695748fe4a84b40b3fc79de2277660bd1d3\n      ✓ Should update balances after transfers (187ms)\n\n\n  5 passing (2s)\n```\nCheck out the [documentation](/hardhat-network/README.md#console-log) to learn more about this feature.\n\n# 7. Deploying to a live network\nOnce you're ready to share your app with other people, you may want to deploy it to a live network! This way others can access an instance that's not running locally on your system.\n\nThe Ethereum network that deals with real money is called \"mainnet\", and then there are other live networks that don't deal with real money but do mimic the real world scenario well, and can be used by others as a shared staging environment. These are called \"testnets\" and Ethereum has several of them: *Ropsten*, *Kovan*, *Rinkeby* and *Goerli*.\n\nAt the software level, deploying to a testnet is the same as deploying to mainnet. The only difference is which network you connect to.\n\nSince we use `hardhat-deploy` plugin and we already set up our deployment procedures for the tests, we are ready to deploy to a live network, we just need to add some configuration for the network we intend to deploy to.\n\nAs explained in our deployment section you can execute `yarn hardhat deploy` which will give you the following output, but does not actually deploy your contract anywhere except the default \"in-memory\" network (`hardhat`)\n\n```\nNothing to compile\ndeploying \"Token\" (tx: 0x259d19f33819ec8d3bd994f82912aec6af1a18ec5d74303cfb28d793a10ff683)...: deployed at 0x5FbDB2315678afecb367f032d93F642f64180aa3 with 592983 gas\nDone in 3.79s.\n```\n\nTo deploy to a specific network, you need to add `--network <network-name>` like this:\n\n```\nyarn hardhat --network <network-name> deploy\n```\n\n## Deploying to remote networks\nTo deploy to a remote network such as mainnet or any testnet, you need to add a `network` entry to your `hardhat.config.js` file. We’ll use Rinkeby for this example, but you can add any network.\n\nTo make it easier to handle the private keys and network configuration, we create a new folder at the root of your project `utils`\n\nIn it we create a file `network.ts` with the following content:\n\n```typescript\nimport 'dotenv/config';\nexport function node_url(networkName: string): string {\n  if (networkName) {\n    const uri = process.env['ETH_NODE_URI_' + networkName.toUpperCase()];\n    if (uri && uri !== '') {\n      return uri;\n    }\n  }\n\n  let uri = process.env.ETH_NODE_URI;\n  if (uri) {\n    uri = uri.replace('{{networkName}}', networkName);\n  }\n  if (!uri || uri === '') {\n    if (networkName === 'localhost') {\n      return 'http://localhost:8545';\n    }\n    return '';\n  }\n  if (uri.indexOf('{{') >= 0) {\n    throw new Error(\n      `invalid uri or network not supported by node provider : ${uri}`\n    );\n  }\n  return uri;\n}\n\nexport function getMnemonic(networkName?: string): string {\n  if (networkName) {\n    const mnemonic = process.env['MNEMONIC_' + networkName.toUpperCase()];\n    if (mnemonic && mnemonic !== '') {\n      return mnemonic;\n    }\n  }\n\n  const mnemonic = process.env.MNEMONIC;\n  if (!mnemonic || mnemonic === '') {\n    return 'test test test test test test test test test test test junk';\n  }\n  return mnemonic;\n}\n\nexport function accounts(networkName?: string): {mnemonic: string} {\n  return {mnemonic: getMnemonic(networkName)};\n}\n```\n\nThen we can modifiy our `hardhat.config.ts` file to contain the following:\n\n```typescript {5,11,15-20}\nimport {HardhatUserConfig} from 'hardhat/types';\nimport 'hardhat-deploy';\nimport 'hardhat-deploy-ethers';\nimport {node_url, accounts} from './utils/network';\n\nconst config: HardhatUserConfig = {\n  solidity: {\n    version: '0.7.6',\n  },\n  networks: {\n    rinkeby: {\n      url: node_url('rinkeby'),\n      accounts: accounts('rinkeby'),\n    },\n  },\n  namedAccounts: {\n    deployer: 0,\n    tokenOwner: 1,\n  },\n  paths: {\n    sources: 'src',\n  },\n};\nexport default config;\n\n```\n\nFinally we need to setup the environment variable that `utils/networks.ts` reads automatically from `.env`\n\ncreate a `.env` with the following content. This is where you write your own alchemy api key and mnemonic for rinkeby\n\n```\nETH_NODE_URI_RINKEBY=https://eth-rinkeby.alchemyapi.io/v2/<alchmey api key>\nMNEMONIC_RINKEBY=<mnemonic for rinkeby>\n```\n\nWe're using [Alchemy](https://www.alchemyapi.io), but pointing `url` to any Ethereum node or gateway would work. Go grab your api key and come back.\n\nTo deploy on Rinkeby you need to send rinkeby-ETH into the address that's going to be making the deployment. You can get some ETH for testnets from a faucet, a service that distributes testing ETH for free. [Here's the one for Rinkeby](https://faucet.metamask.io/). You'll have to change Metamask's network to Rinkeby before transacting.\n\n::: tip\nYou can get some ETH for other testnets following these links:\n\n* [Kovan faucet](https://faucet.kovan.network/)\n* [Rinkeby faucet](https://faucet.rinkeby.io/)\n* [Goerli faucet](https://goerli-faucet.slock.it/)\n:::\n\nFinally, run:\n```\nyarn hardhat --network rinkeby deploy\n```\n\nIf everything went well, you should see something like:\n\n```\nNothing to compile\ndeploying \"Token\" (tx: 0xb40879c3162e6a924cfadfc1027c4629dd57ee4ba08a5f8af575be1c751cd515)...: deployed at 0x8bDFEf5f67685725BC0eD9f54f20A2A4d3FEDA98 with 475842 gas\n```\n\nYou will also see that some files have been created in the `deployments/rinkeby` folder.\n\nMost notably you'll see `deployments/rinkeby/Token.json` which contains useful information about your deployed contract, including the address, abi, and the solidity input used to create it.\n\nYou can then verify it using sourcify or etherscan.\n\nFor sourcify you can execute the following:\n\n```\nyarn hardhat --network rinkeby sourcify\n```\n\nthis should give you the following output (with different address) :\n\n```\nverifying Token (0x8bDFEf5f67685725BC0eD9f54f20A2A4d3FEDA98 on chain 4) ...\n => contract Token is now verified\n```\n\nFor etherscan you can do the following:\n\n(Note you can also specify the api key via the env variable ETHERSCAN_API_KEY)\n\n```\nyarn hardhat --network rinkeby etherscan-verify --api-key <api-key>\n```\n\nYou should then see:\n\n```\nverifying Token (0x8bDFEf5f67685725BC0eD9f54f20A2A4d3FEDA98) ...\nwaiting for result...\n => contract Token is now verified\n```\n"
  },
  {
    "path": "deploy/001_deploy_token.ts",
    "content": "import {HardhatRuntimeEnvironment} from 'hardhat/types';\nimport {DeployFunction} from 'hardhat-deploy/types';\n\nconst func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {\n  const {deployments, getNamedAccounts} = hre;\n  const {deploy} = deployments;\n\n  const {deployer, tokenOwner} = await getNamedAccounts();\n\n  await deploy('Token', {\n    from: deployer,\n    args: [tokenOwner],\n    log: true,\n  });\n};\nexport default func;\nfunc.tags = ['Token'];\n"
  },
  {
    "path": "deployments/rinkeby/.chainId",
    "content": "4"
  },
  {
    "path": "deployments/rinkeby/Token.json",
    "content": "{\n  \"address\": \"0x8bDFEf5f67685725BC0eD9f54f20A2A4d3FEDA98\",\n  \"abi\": [\n    {\n      \"inputs\": [\n        {\n          \"internalType\": \"address\",\n          \"name\": \"_owner\",\n          \"type\": \"address\"\n        }\n      ],\n      \"stateMutability\": \"nonpayable\",\n      \"type\": \"constructor\"\n    },\n    {\n      \"inputs\": [\n        {\n          \"internalType\": \"address\",\n          \"name\": \"account\",\n          \"type\": \"address\"\n        }\n      ],\n      \"name\": \"balanceOf\",\n      \"outputs\": [\n        {\n          \"internalType\": \"uint256\",\n          \"name\": \"\",\n          \"type\": \"uint256\"\n        }\n      ],\n      \"stateMutability\": \"view\",\n      \"type\": \"function\"\n    },\n    {\n      \"inputs\": [],\n      \"name\": \"name\",\n      \"outputs\": [\n        {\n          \"internalType\": \"string\",\n          \"name\": \"\",\n          \"type\": \"string\"\n        }\n      ],\n      \"stateMutability\": \"view\",\n      \"type\": \"function\"\n    },\n    {\n      \"inputs\": [],\n      \"name\": \"owner\",\n      \"outputs\": [\n        {\n          \"internalType\": \"address\",\n          \"name\": \"\",\n          \"type\": \"address\"\n        }\n      ],\n      \"stateMutability\": \"view\",\n      \"type\": \"function\"\n    },\n    {\n      \"inputs\": [],\n      \"name\": \"symbol\",\n      \"outputs\": [\n        {\n          \"internalType\": \"string\",\n          \"name\": \"\",\n          \"type\": \"string\"\n        }\n      ],\n      \"stateMutability\": \"view\",\n      \"type\": \"function\"\n    },\n    {\n      \"inputs\": [],\n      \"name\": \"totalSupply\",\n      \"outputs\": [\n        {\n          \"internalType\": \"uint256\",\n          \"name\": \"\",\n          \"type\": \"uint256\"\n        }\n      ],\n      \"stateMutability\": \"view\",\n      \"type\": \"function\"\n    },\n    {\n      \"inputs\": [\n        {\n          \"internalType\": \"address\",\n          \"name\": \"to\",\n          \"type\": \"address\"\n        },\n        {\n          \"internalType\": \"uint256\",\n          \"name\": \"amount\",\n          \"type\": \"uint256\"\n        }\n      ],\n      \"name\": \"transfer\",\n      \"outputs\": [],\n      \"stateMutability\": \"nonpayable\",\n      \"type\": \"function\"\n    }\n  ],\n  \"transactionHash\": \"0xb40879c3162e6a924cfadfc1027c4629dd57ee4ba08a5f8af575be1c751cd515\",\n  \"receipt\": {\n    \"to\": null,\n    \"from\": \"0x61c461EcC993aaDEB7e4b47E96d1B8cC37314B20\",\n    \"contractAddress\": \"0x8bDFEf5f67685725BC0eD9f54f20A2A4d3FEDA98\",\n    \"transactionIndex\": 10,\n    \"gasUsed\": \"475842\",\n    \"logsBloom\": \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n    \"blockHash\": \"0xf365b798b73289c5e04a94792bf08ef91fffdc748b96398bf58092264038bbe9\",\n    \"transactionHash\": \"0xb40879c3162e6a924cfadfc1027c4629dd57ee4ba08a5f8af575be1c751cd515\",\n    \"logs\": [],\n    \"blockNumber\": 8284846,\n    \"cumulativeGasUsed\": \"2575320\",\n    \"status\": 1,\n    \"byzantium\": true\n  },\n  \"args\": [\n    \"0xE53cd71271AcAdbeb0f64d9c8C62bBdDc8cA9e66\"\n  ],\n  \"solcInputHash\": \"a51ea66d3b3abe8ca5d0ce048c409140\",\n  \"metadata\": \"{\\\"compiler\\\":{\\\"version\\\":\\\"0.7.6+commit.7338295f\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_owner\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"account\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"balanceOf\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"name\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"owner\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"symbol\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"totalSupply\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"amount\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"transfer\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"balanceOf(address)\\\":{\\\"notice\\\":\\\"Read only function to retrieve the token balance of a given account. The `view` modifier indicates that it doesn't modify the contract's state, which allows us to call it without executing a transaction.\\\"},\\\"constructor\\\":{\\\"notice\\\":\\\"Contract initialization. The `constructor` is executed only once when the contract is created.\\\"},\\\"transfer(address,uint256)\\\":{\\\"notice\\\":\\\"A function to transfer tokens. The `external` modifier makes a function *only* callable from outside the contract.\\\"}},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/Token.sol\\\":\\\"Token\\\"},\\\"evmVersion\\\":\\\"istanbul\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"ipfs\\\",\\\"useLiteralContent\\\":true},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[]},\\\"sources\\\":{\\\"src/Token.sol\\\":{\\\"content\\\":\\\"// SPDX-License-Identifier: MIT\\\\n// The line above is recommended and let you define the license of your contract\\\\n// Solidity files have to start with this pragma.\\\\n// It will be used by the Solidity compiler to validate its version.\\\\npragma solidity ^0.7.6;\\\\n\\\\n\\\\n// This is the main building block for smart contracts.\\\\ncontract Token {\\\\n    // Some string type variables to identify the token.\\\\n    // The `public` modifier makes a variable readable from outside the contract.\\\\n    string public name = \\\\\\\"My Hardhat Token\\\\\\\";\\\\n    string public symbol = \\\\\\\"MBT\\\\\\\";\\\\n\\\\n    // The fixed amount of tokens stored in an unsigned integer type variable.\\\\n    uint256 public totalSupply = 1000000;\\\\n\\\\n    // An address type variable is used to store ethereum accounts.\\\\n    address public owner;\\\\n\\\\n    // A mapping is a key/value map. Here we store each account balance.\\\\n    mapping(address => uint256) balances;\\\\n\\\\n    /**\\\\n     * Contract initialization.\\\\n     *\\\\n     * The `constructor` is executed only once when the contract is created.\\\\n     */\\\\n    constructor(address _owner) {\\\\n        // The totalSupply is assigned to transaction sender, which is the account\\\\n        // that is deploying the contract.\\\\n        balances[_owner] = totalSupply;\\\\n        owner = _owner;\\\\n    }\\\\n\\\\n    /**\\\\n     * A function to transfer tokens.\\\\n     *\\\\n     * The `external` modifier makes a function *only* callable from outside\\\\n     * the contract.\\\\n     */\\\\n    function transfer(address to, uint256 amount) external {\\\\n        // Check if the transaction sender has enough tokens.\\\\n        // If `require`'s first argument evaluates to `false` then the\\\\n        // transaction will revert.\\\\n        require(balances[msg.sender] >= amount, \\\\\\\"Not enough tokens\\\\\\\");\\\\n\\\\n        // Transfer the amount.\\\\n        balances[msg.sender] -= amount;\\\\n        balances[to] += amount;\\\\n    }\\\\n\\\\n    /**\\\\n     * Read only function to retrieve the token balance of a given account.\\\\n     *\\\\n     * The `view` modifier indicates that it doesn't modify the contract's\\\\n     * state, which allows us to call it without executing a transaction.\\\\n     */\\\\n    function balanceOf(address account) external view returns (uint256) {\\\\n        return balances[account];\\\\n    }\\\\n}\\\\n\\\",\\\"keccak256\\\":\\\"0x4a79698f82e8618dbcb912a8bc25804ce07bb5520e7c872c1a0bf71c75b48123\\\",\\\"license\\\":\\\"MIT\\\"}},\\\"version\\\":1}\",\n  \"bytecode\": \"0x60806040526040518060400160405280601081526020017f4d79204861726468617420546f6b656e000000000000000000000000000000008152506000908051906020019061004f929190610170565b506040518060400160405280600381526020017f4d425400000000000000000000000000000000000000000000000000000000008152506001908051906020019061009b929190610170565b50620f42406002553480156100af57600080fd5b506040516107c93803806107c9833981810160405260208110156100d257600080fd5b8101908080519060200190929190505050600254600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505061021b565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826101a657600085556101ed565b82601f106101bf57805160ff19168380011785556101ed565b828001600101855582156101ed579182015b828111156101ec5782518255916020019190600101906101d1565b5b5090506101fa91906101fe565b5090565b5b808211156102175760008160009055506001016101ff565b5090565b61059f8061022a6000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806306fdde031461006757806318160ddd146100ea57806370a08231146101085780638da5cb5b1461016057806395d89b4114610194578063a9059cbb14610217575b600080fd5b61006f610265565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100af578082015181840152602081019050610094565b50505050905090810190601f1680156100dc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100f2610303565b6040518082815260200191505060405180910390f35b61014a6004803603602081101561011e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610309565b6040518082815260200191505060405180910390f35b610168610352565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61019c610378565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101dc5780820151818401526020810190506101c1565b50505050905090810190601f1680156102095780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102636004803603604081101561022d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610416565b005b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102fb5780601f106102d0576101008083540402835291602001916102fb565b820191906000526020600020905b8154815290600101906020018083116102de57829003601f168201915b505050505081565b60025481565b6000600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561040e5780601f106103e35761010080835404028352916020019161040e565b820191906000526020600020905b8154815290600101906020018083116103f157829003601f168201915b505050505081565b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156104cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f4e6f7420656e6f75676820746f6b656e7300000000000000000000000000000081525060200191505060405180910390fd5b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550505056fea2646970667358221220b3aca42ddc58972eb854cf2b30bcaae8aec0cda09ffe78f55aff3201615d192064736f6c63430007060033\",\n  \"deployedBytecode\": \"0x608060405234801561001057600080fd5b50600436106100625760003560e01c806306fdde031461006757806318160ddd146100ea57806370a08231146101085780638da5cb5b1461016057806395d89b4114610194578063a9059cbb14610217575b600080fd5b61006f610265565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100af578082015181840152602081019050610094565b50505050905090810190601f1680156100dc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100f2610303565b6040518082815260200191505060405180910390f35b61014a6004803603602081101561011e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610309565b6040518082815260200191505060405180910390f35b610168610352565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61019c610378565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101dc5780820151818401526020810190506101c1565b50505050905090810190601f1680156102095780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102636004803603604081101561022d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610416565b005b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102fb5780601f106102d0576101008083540402835291602001916102fb565b820191906000526020600020905b8154815290600101906020018083116102de57829003601f168201915b505050505081565b60025481565b6000600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561040e5780601f106103e35761010080835404028352916020019161040e565b820191906000526020600020905b8154815290600101906020018083116103f157829003601f168201915b505050505081565b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156104cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f4e6f7420656e6f75676820746f6b656e7300000000000000000000000000000081525060200191505060405180910390fd5b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550505056fea2646970667358221220b3aca42ddc58972eb854cf2b30bcaae8aec0cda09ffe78f55aff3201615d192064736f6c63430007060033\",\n  \"devdoc\": {\n    \"kind\": \"dev\",\n    \"methods\": {},\n    \"version\": 1\n  },\n  \"userdoc\": {\n    \"kind\": \"user\",\n    \"methods\": {\n      \"balanceOf(address)\": {\n        \"notice\": \"Read only function to retrieve the token balance of a given account. The `view` modifier indicates that it doesn't modify the contract's state, which allows us to call it without executing a transaction.\"\n      },\n      \"constructor\": {\n        \"notice\": \"Contract initialization. The `constructor` is executed only once when the contract is created.\"\n      },\n      \"transfer(address,uint256)\": {\n        \"notice\": \"A function to transfer tokens. The `external` modifier makes a function *only* callable from outside the contract.\"\n      }\n    },\n    \"version\": 1\n  },\n  \"storageLayout\": {\n    \"storage\": [\n      {\n        \"astId\": 4,\n        \"contract\": \"src/Token.sol:Token\",\n        \"label\": \"name\",\n        \"offset\": 0,\n        \"slot\": \"0\",\n        \"type\": \"t_string_storage\"\n      },\n      {\n        \"astId\": 7,\n        \"contract\": \"src/Token.sol:Token\",\n        \"label\": \"symbol\",\n        \"offset\": 0,\n        \"slot\": \"1\",\n        \"type\": \"t_string_storage\"\n      },\n      {\n        \"astId\": 10,\n        \"contract\": \"src/Token.sol:Token\",\n        \"label\": \"totalSupply\",\n        \"offset\": 0,\n        \"slot\": \"2\",\n        \"type\": \"t_uint256\"\n      },\n      {\n        \"astId\": 12,\n        \"contract\": \"src/Token.sol:Token\",\n        \"label\": \"owner\",\n        \"offset\": 0,\n        \"slot\": \"3\",\n        \"type\": \"t_address\"\n      },\n      {\n        \"astId\": 16,\n        \"contract\": \"src/Token.sol:Token\",\n        \"label\": \"balances\",\n        \"offset\": 0,\n        \"slot\": \"4\",\n        \"type\": \"t_mapping(t_address,t_uint256)\"\n      }\n    ],\n    \"types\": {\n      \"t_address\": {\n        \"encoding\": \"inplace\",\n        \"label\": \"address\",\n        \"numberOfBytes\": \"20\"\n      },\n      \"t_mapping(t_address,t_uint256)\": {\n        \"encoding\": \"mapping\",\n        \"key\": \"t_address\",\n        \"label\": \"mapping(address => uint256)\",\n        \"numberOfBytes\": \"32\",\n        \"value\": \"t_uint256\"\n      },\n      \"t_string_storage\": {\n        \"encoding\": \"bytes\",\n        \"label\": \"string\",\n        \"numberOfBytes\": \"32\"\n      },\n      \"t_uint256\": {\n        \"encoding\": \"inplace\",\n        \"label\": \"uint256\",\n        \"numberOfBytes\": \"32\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "deployments/rinkeby/solcInputs/a51ea66d3b3abe8ca5d0ce048c409140.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"src/Token.sol\": {\n      \"content\": \"// SPDX-License-Identifier: MIT\\n// The line above is recommended and let you define the license of your contract\\n// Solidity files have to start with this pragma.\\n// It will be used by the Solidity compiler to validate its version.\\npragma solidity ^0.7.6;\\n\\n\\n// This is the main building block for smart contracts.\\ncontract Token {\\n    // Some string type variables to identify the token.\\n    // The `public` modifier makes a variable readable from outside the contract.\\n    string public name = \\\"My Hardhat Token\\\";\\n    string public symbol = \\\"MBT\\\";\\n\\n    // The fixed amount of tokens stored in an unsigned integer type variable.\\n    uint256 public totalSupply = 1000000;\\n\\n    // An address type variable is used to store ethereum accounts.\\n    address public owner;\\n\\n    // A mapping is a key/value map. Here we store each account balance.\\n    mapping(address => uint256) balances;\\n\\n    /**\\n     * Contract initialization.\\n     *\\n     * The `constructor` is executed only once when the contract is created.\\n     */\\n    constructor(address _owner) {\\n        // The totalSupply is assigned to transaction sender, which is the account\\n        // that is deploying the contract.\\n        balances[_owner] = totalSupply;\\n        owner = _owner;\\n    }\\n\\n    /**\\n     * A function to transfer tokens.\\n     *\\n     * The `external` modifier makes a function *only* callable from outside\\n     * the contract.\\n     */\\n    function transfer(address to, uint256 amount) external {\\n        // Check if the transaction sender has enough tokens.\\n        // If `require`'s first argument evaluates to `false` then the\\n        // transaction will revert.\\n        require(balances[msg.sender] >= amount, \\\"Not enough tokens\\\");\\n\\n        // Transfer the amount.\\n        balances[msg.sender] -= amount;\\n        balances[to] += amount;\\n    }\\n\\n    /**\\n     * Read only function to retrieve the token balance of a given account.\\n     *\\n     * The `view` modifier indicates that it doesn't modify the contract's\\n     * state, which allows us to call it without executing a transaction.\\n     */\\n    function balanceOf(address account) external view returns (uint256) {\\n        return balances[account];\\n    }\\n}\\n\"\n    }\n  },\n  \"settings\": {\n    \"optimizer\": {\n      \"enabled\": false,\n      \"runs\": 200\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"abi\",\n          \"evm.bytecode\",\n          \"evm.deployedBytecode\",\n          \"evm.methodIdentifiers\",\n          \"metadata\",\n          \"devdoc\",\n          \"userdoc\",\n          \"storageLayout\",\n          \"evm.gasEstimates\"\n        ],\n        \"\": [\n          \"ast\"\n        ]\n      }\n    },\n    \"metadata\": {\n      \"useLiteralContent\": true\n    }\n  }\n}"
  },
  {
    "path": "hardhat.config.ts",
    "content": "import {HardhatUserConfig} from 'hardhat/types';\nimport 'hardhat-deploy';\nimport 'hardhat-deploy-ethers';\nimport {node_url, accounts} from './utils/network';\n\nconst config: HardhatUserConfig = {\n  solidity: {\n    version: '0.7.6',\n  },\n  networks: {\n    rinkeby: {\n      url: node_url('rinkeby'),\n      accounts: accounts('rinkeby'),\n    },\n  },\n  namedAccounts: {\n    deployer: 0,\n    tokenOwner: 1,\n  },\n  paths: {\n    sources: 'src',\n  },\n};\nexport default config;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"hardhat-tutorial\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"@types/chai\": \"^4.2.15\",\n    \"@types/mocha\": \"^8.2.2\",\n    \"@types/node\": \"^14.14.35\",\n    \"chai\": \"^4.3.4\",\n    \"chai-ethers\": \"^0.0.1\",\n    \"dotenv\": \"^8.2.0\",\n    \"ethers\": \"^5.0.32\",\n    \"hardhat\": \"^2.1.1\",\n    \"hardhat-deploy\": \"^0.7.0-beta.50\",\n    \"hardhat-deploy-ethers\": \"^0.3.0-beta.7\",\n    \"mocha\": \"^8.3.2\",\n    \"ts-node\": \"^9.1.1\",\n    \"typescript\": \"^4.2.3\"\n  }\n}\n"
  },
  {
    "path": "src/Token.sol",
    "content": "// SPDX-License-Identifier: MIT\n// The line above is recommended and let you define the license of your contract\n// Solidity files have to start with this pragma.\n// It will be used by the Solidity compiler to validate its version.\npragma solidity ^0.7.6;\n\n\n// This is the main building block for smart contracts.\ncontract Token {\n    // Some string type variables to identify the token.\n    // The `public` modifier makes a variable readable from outside the contract.\n    string public name = \"My Hardhat Token\";\n    string public symbol = \"MBT\";\n\n    // The fixed amount of tokens stored in an unsigned integer type variable.\n    uint256 public totalSupply = 1000000;\n\n    // An address type variable is used to store ethereum accounts.\n    address public owner;\n\n    // A mapping is a key/value map. Here we store each account balance.\n    mapping(address => uint256) balances;\n\n    /**\n     * Contract initialization.\n     *\n     * The `constructor` is executed only once when the contract is created.\n     */\n    constructor(address _owner) {\n        // The totalSupply is assigned to transaction sender, which is the account\n        // that is deploying the contract.\n        balances[_owner] = totalSupply;\n        owner = _owner;\n    }\n\n    /**\n     * A function to transfer tokens.\n     *\n     * The `external` modifier makes a function *only* callable from outside\n     * the contract.\n     */\n    function transfer(address to, uint256 amount) external {\n        // Check if the transaction sender has enough tokens.\n        // If `require`'s first argument evaluates to `false` then the\n        // transaction will revert.\n        require(balances[msg.sender] >= amount, \"Not enough tokens\");\n\n        // Transfer the amount.\n        balances[msg.sender] -= amount;\n        balances[to] += amount;\n    }\n\n    /**\n     * Read only function to retrieve the token balance of a given account.\n     *\n     * The `view` modifier indicates that it doesn't modify the contract's\n     * state, which allows us to call it without executing a transaction.\n     */\n    function balanceOf(address account) external view returns (uint256) {\n        return balances[account];\n    }\n}\n"
  },
  {
    "path": "test/Test.test.ts",
    "content": "// We import Chai to use its asserting functions here.\nimport {expect} from \"./chai-setup\";\n\n// we import our utilities\nimport {setupUsers, setupUser} from './utils';\n\n// We import the hardhat environment field we are planning to use\nimport {ethers, deployments, getNamedAccounts, getUnnamedAccounts} from 'hardhat';\n\n// we create a stup function that can be called by every test and setup variable for easy to read tests\nasync function setup () {\n  // it first ensure the deployment is executed and reset (use of evm_snaphost for fast test)\n  await deployments.fixture([\"Token\"]);\n\n  // we get an instantiated contract in the form of a ethers.js Contract instance:\n  const contracts = {\n    Token: (await ethers.getContract('Token')),\n  };\n\n  // we get the tokenOwner\n  const {tokenOwner} = await getNamedAccounts();\n  // get fet unnammedAccounts (which are basically all accounts not named in the config, useful for tests as you can be sure they do not have been given token for example)\n  // we then use the utilities function to generate user object/\n  // These object allow you to write things like `users[0].Token.transfer(....)`\n  const users = await setupUsers(await getUnnamedAccounts(), contracts);\n  // finally we return the whole object (including the tokenOwner setup as a User object)\n  return {\n    ...contracts,\n    users,\n    tokenOwner: await setupUser(tokenOwner, contracts),\n  };\n}\n\n// `describe` is a Mocha function that allows you to organize your tests. It's\n// not actually needed, but having your tests organized makes debugging them\n// easier. All Mocha functions are available in the global scope.\n\n// `describe` receives the name of a section of your test suite, and a callback.\n// The callback must define the tests of that section. This callback can't be\n// an async function.\ndescribe(\"Token contract\", function() {\n\n  // You can nest describe calls to create subsections.\n  describe(\"Deployment\", function () {\n    // `it` is another Mocha function. This is the one you use to define your\n    // tests. It receives the test name, and a callback function.\n\n    // If the callback function is async, Mocha will `await` it.\n    it(\"Should set the right owner\", async function () {\n      // Expect receives a value, and wraps it in an Assertion object. These\n      // objects have a lot of utility methods to assert values.\n\n      // before the test, we call the fixture function.\n      // while mocha have hooks to perform these automatically, they force you to declare the variable in greater scope which can introduce subttle errors\n      // as such we prefers to have the setup called right at the beginning of the test. this also allow you to name it accordingly for easier to read tests.\n      const {Token} = await setup();\n\n\n      // This test expects the owner variable stored in the contract to be equal to our configured owner\n      const {tokenOwner} = await getNamedAccounts();\n      expect(await Token.owner()).to.equal(tokenOwner);\n    });\n\n    it(\"Should assign the total supply of tokens to the owner\", async function () {\n      const {Token, tokenOwner} = await setup();\n      const ownerBalance = await Token.balanceOf(tokenOwner.address);\n      expect(await Token.totalSupply()).to.equal(ownerBalance);\n    });\n  });\n\n  describe(\"Transactions\", function () {\n    it(\"Should transfer tokens between accounts\", async function () {\n      const {Token, users, tokenOwner} = await setup();\n      // Transfer 50 tokens from owner to users[0]\n      await tokenOwner.Token.transfer(users[0].address, 50);\n      const users0Balance = await Token.balanceOf(users[0].address);\n      expect(users0Balance).to.equal(50);\n\n      // Transfer 50 tokens from users[0] to users[1]\n      // We use .connect(signer) to send a transaction from another account\n      await users[0].Token.transfer(users[1].address, 50);\n      const users1Balance = await Token.balanceOf(users[1].address);\n      expect(users1Balance).to.equal(50);\n    });\n\n    it(\"Should fail if sender doesn’t have enough tokens\", async function () {\n      const {Token, users, tokenOwner} = await setup();\n      const initialOwnerBalance = await Token.balanceOf(tokenOwner.address);\n\n      // Try to send 1 token from users[0] (0 tokens) to owner (1000 tokens).\n      // `require` will evaluate false and revert the transaction.\n      await expect(users[0].Token.transfer(tokenOwner.address, 1)\n      ).to.be.revertedWith(\"Not enough tokens\");\n\n      // Owner balance shouldn't have changed.\n      expect(await Token.balanceOf(tokenOwner.address)).to.equal(\n        initialOwnerBalance\n      );\n    });\n\n    it(\"Should update balances after transfers\", async function () {\n      const {Token, users, tokenOwner} = await setup();\n      const initialOwnerBalance = await Token.balanceOf(tokenOwner.address);\n\n      // Transfer 100 tokens from owner to users[0].\n      await tokenOwner.Token.transfer(users[0].address, 100);\n\n      // Transfer another 50 tokens from owner to users[1].\n      await tokenOwner.Token.transfer(users[1].address, 50);\n\n      // Check balances.\n      const finalOwnerBalance = await Token.balanceOf(tokenOwner.address);\n      expect(finalOwnerBalance).to.equal(initialOwnerBalance - 150);\n\n      const users0Balance = await Token.balanceOf(users[0].address);\n      expect(users0Balance).to.equal(100);\n\n      const users1Balance = await Token.balanceOf(users[1].address);\n      expect(users1Balance).to.equal(50);\n    });\n  });\n});\n"
  },
  {
    "path": "test/chai-setup.ts",
    "content": "import chaiModule from 'chai';\nimport {chaiEthers} from 'chai-ethers';\nchaiModule.use(chaiEthers);\nexport = chaiModule;\n"
  },
  {
    "path": "test/utils/index.ts",
    "content": "import {Contract} from 'ethers';\nimport {ethers} from 'hardhat';\n\nexport async function setupUsers<T extends {[contractName: string]: Contract}>(\n  addresses: string[],\n  contracts: T\n): Promise<({address: string} & T)[]> {\n  const users: ({address: string} & T)[] = [];\n  for (const address of addresses) {\n    users.push(await setupUser(address, contracts));\n  }\n  return users;\n}\n\nexport async function setupUser<T extends {[contractName: string]: Contract}>(\n  address: string,\n  contracts: T\n): Promise<{address: string} & T> {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const user: any = {address};\n  for (const key of Object.keys(contracts)) {\n    user[key] = contracts[key].connect(await ethers.getSigner(address));\n  }\n  return user as {address: string} & T;\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"module\": \"commonjs\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"moduleResolution\": \"node\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\n    \"hardhat.config.ts\",\n    \"./scripts\",\n    \"./deploy\",\n    \"./test\",\n    \"typechain/**/*\"\n  ]\n}\n"
  },
  {
    "path": "utils/network.ts",
    "content": "import 'dotenv/config';\nexport function node_url(networkName: string): string {\n  if (networkName) {\n    const uri = process.env['ETH_NODE_URI_' + networkName.toUpperCase()];\n    if (uri && uri !== '') {\n      return uri;\n    }\n  }\n\n  let uri = process.env.ETH_NODE_URI;\n  if (uri) {\n    uri = uri.replace('{{networkName}}', networkName);\n  }\n  if (!uri || uri === '') {\n    if (networkName === 'localhost') {\n      return 'http://localhost:8545';\n    }\n    // throw new Error(`environment variable \"ETH_NODE_URI\" not configured `);\n    return '';\n  }\n  if (uri.indexOf('{{') >= 0) {\n    throw new Error(\n      `invalid uri or network not supported by nod eprovider : ${uri}`\n    );\n  }\n  return uri;\n}\n\nexport function getMnemonic(networkName?: string): string {\n  if (networkName) {\n    const mnemonic = process.env['MNEMONIC_' + networkName.toUpperCase()];\n    if (mnemonic && mnemonic !== '') {\n      return mnemonic;\n    }\n  }\n\n  const mnemonic = process.env.MNEMONIC;\n  if (!mnemonic || mnemonic === '') {\n    return 'test test test test test test test test test test test junk';\n  }\n  return mnemonic;\n}\n\nexport function accounts(networkName?: string): {mnemonic: string} {\n  return {mnemonic: getMnemonic(networkName)};\n}\n"
  }
]