<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: 565.ee</title>
    <description>The latest articles on Forem by 565.ee (@565ee).</description>
    <link>https://forem.com/565ee</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F863913%2Feb261045-1bae-4a82-ba7a-131a146de5d1.png</url>
      <title>Forem: 565.ee</title>
      <link>https://forem.com/565ee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/565ee"/>
    <language>en</language>
    <item>
      <title>121 ethereum truffle : Writing automated smart contract tests</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Mon, 12 Sep 2022 18:34:23 +0000</pubDate>
      <link>https://forem.com/565ee/121-ethereum-truffle-writing-automated-smart-contract-tests-2c9f</link>
      <guid>https://forem.com/565ee/121-ethereum-truffle-writing-automated-smart-contract-tests-2c9f</guid>
      <description>&lt;p&gt;• introduce&lt;br&gt;&lt;br&gt;
• About testing&lt;br&gt;&lt;br&gt;
• Setting up a testing environment&lt;br&gt;&lt;br&gt;
• Writing unit tests&lt;br&gt;&lt;br&gt;
• Performing complex assertions&lt;br&gt;&lt;br&gt;
• truffle Tutorials 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式  &lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• introduce&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;In a blockchain environment, a single mistake could cost you all of your funds - or even worse, your users' funds! This guide will help you develop robust applications by writing automated tests that verify your application behaves exactly as you intended.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• About testing&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;There is a wide range of testing techniques, from simple manual verifications to complex end-to-end setups, all of them useful in their own way.&lt;/p&gt;

&lt;p&gt;When it comes to smart contract development though, practice has shown that contract unit testing is exceptionally worthwhile. These tests are simple to write and quick to run, and let you add features and fix bugs in your code with confidence.&lt;/p&gt;

&lt;p&gt;Smart contract unit testing consists of multiple small, focused tests, which each check a small part of your contract for correctness. They can often be expressed in single sentences that make up a specification, such as 'the admin is able to pause the contract', 'transferring tokens emits an event' or 'non-admins cannot mint new tokens'.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Setting up a testing environment&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;You may be wondering how we’re going to run these tests, since smart contracts are executed inside a blockchain. Using the actual Ethereum network would be very expensive, and while testnets are free, they are also slow (with blocktimes between 5 and 20 seconds). If we intend to run hundreds of tests whenever we make a change to our code, we need something better.&lt;/p&gt;

&lt;p&gt;What we will use is called a local blockchain: a slimmed down version of the real thing, disconnected from the Internet, running on your machine. This will simplify things quite a bit: you won’t need to get Ether, and new blocks will be mined instantly.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Writing unit tests&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;We’ll use Chai assertions for our unit tests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save-dev chai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will keep our test files in a test directory. Tests are best structured by mirroring the contracts directory: for each .sol file there, create a corresponding test file.&lt;/p&gt;

&lt;p&gt;Time to write our first tests! These will test properties of the Box contract from previous guides: a simple contract that lets you retrieve a value the owner previously store d.&lt;/p&gt;

&lt;p&gt;We will save the test as test/Box.test.js. Each .test.js file should have the tests for a single contract, and be named after it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// test/Box.test.js
// Load dependencies
const { expect } = require('chai');

// Load compiled artifacts
const Box = artifacts.require('Box');

// Start test block
contract('Box', function () {
  beforeEach(async function () {
    // Deploy a new Box contract for each test
    this.box = await Box.new();
  });

  // Test case
  it('retrieve returns a value previously stored', async function () {
    // Store a value
    await this.box.store(42);

    // Test if the returned value is the same one
    // Note that we need to use strings to compare the 256 bit integers
    expect((await this.box.retrieve()).toString()).to.equal('42');
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many books have been written about how to structure unit tests. Check out the Moloch Testing Guide for a set of principles designed for testing Solidity smart contracts.&lt;br&gt;
We are now ready to run our tests!&lt;/p&gt;

&lt;p&gt;Running npx truffle test will execute all tests in the test directory, checking that your contracts work the way you meant them to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx truffle test
Using network 'development'.


Compiling your contracts...
===========================
&amp;gt; Everything is up to date, there is nothing to compile.



  Contract: Box
    ✓ retrieve returns a value previously stored (38ms)


  1 passing (117ms)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s also a very good idea at this point to set up a Continuous Integration service such as CircleCI to make your tests run automatically every time you commit your code to GitHub.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Performing complex assertions&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Many interesting properties of your contracts may be hard to capture, such as:&lt;br&gt;
verifying that the contract reverts on errors&lt;br&gt;
measuring by how much an account’s Ether balance changed&lt;br&gt;
checking that the proper events are emitted&lt;/p&gt;

&lt;p&gt;OpenZeppelin Test Helpers is a library designed to help you test all of these properties. It will also simplify the tasks of simulating time passing on the blockchain and handling very large numbers.&lt;/p&gt;

&lt;p&gt;OpenZeppelin Test Helpers is web3.js based, thus Hardhat users should use the Truffle plugin for compatibility, or use Waffle with ethers.js, which offers similar functionality.&lt;/p&gt;

&lt;p&gt;To install the OpenZeppelin Test Helpers, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save-dev @openzeppelin/test-helpers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then update our tests to use OpenZeppelin Test Helpers for very large number support, to check for an event being emitted and to check that a transaction reverts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// test/Box.test.js
// Load dependencies
const { expect } = require('chai');

// Import utilities from Test Helpers
const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');

// Load compiled artifacts
const Box = artifacts.require('Box');

// Start test block
contract('Box', function ([ owner, other ]) {
  // Use large integers ('big numbers')
  const value = new BN('42');

  beforeEach(async function () {
    this.box = await Box.new({ from: owner });
  });

  it('retrieve returns a value previously stored', async function () {
    await this.box.store(value, { from: owner });

    // Use large integer comparisons
    expect(await this.box.retrieve()).to.be.bignumber.equal(value);
  });

  it('store emits an event', async function () {
    const receipt = await this.box.store(value, { from: owner });

    // Test that a ValueChanged event was emitted with the new value
    expectEvent(receipt, 'ValueChanged', { value: value });
  });

  it('non owner cannot store a value', async function () {
    // Test a transaction reverts
    await expectRevert(
      this.box.store(value, { from: other }),
      'Ownable: caller is not the owner',
    );
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These will test properties of the Ownable Box contract from previous guides: a simple contract that lets you retrieve a value the owner previously stored.&lt;/p&gt;

&lt;p&gt;Run your tests again to see the Test Helpers in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx truffle test
...
  Contract: Box
    ✓ retrieve returns a value previously stored
    ✓ store emits an event
    ✓ non owner cannot store a value (588ms)


  3 passing (753ms)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Test Helpers will let you write powerful assertions without having to worry about the low-level details of the underlying Ethereum libraries. To learn more about what you can do with them, head to their API reference.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• truffle Tutorials 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/truffle_CN"&gt;truffle 教程 : github.com/565ee/truffle_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_12007659.html"&gt;truffle 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/truffle_EN"&gt;truffle Tutorials : github.com/565ee/truffle_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>openzeppelin</category>
      <category>truffle</category>
    </item>
    <item>
      <title>11Z ethereum truffle : Deploying and interacting with smart contracts</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Mon, 12 Sep 2022 17:24:38 +0000</pubDate>
      <link>https://forem.com/565ee/11z-ethereum-truffle-deploying-and-interacting-with-smart-contracts-311l</link>
      <guid>https://forem.com/565ee/11z-ethereum-truffle-deploying-and-interacting-with-smart-contracts-311l</guid>
      <description>&lt;p&gt;• Setting up a Local Blockchain&lt;br&gt;&lt;br&gt;
• Deploying a Smart Contract&lt;br&gt;&lt;br&gt;
• Sending transactions&lt;br&gt;&lt;br&gt;
• Querying state&lt;br&gt;&lt;br&gt;
• Setup&lt;br&gt;&lt;br&gt;
• Getting a contract instance&lt;br&gt;&lt;br&gt;
• Calling the contract&lt;br&gt;&lt;br&gt;
• Sending a transaction&lt;br&gt;&lt;br&gt;
• truffle Tutorials 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式  &lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• Setting up a Local Blockchain&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Before we begin, we first need an environment where we can deploy our contracts. The Ethereum blockchain (often called "mainnet", for "main network") requires spending real money to use it, in the form of Ether (its native currency). This makes it a poor choice when trying out new ideas or tools.&lt;/p&gt;

&lt;p&gt;To solve this, a number of "testnets" (for "test networks") exist: these include the Ropsten, Rinkeby, Kovan and Goerli blockchains. They work very similarly to mainnet, with one difference: you can get Ether for these networks for free, so that using them doesn’t cost you a single cent. However, you will still need to deal with private key management, blocktimes in the range of 5 to 20 seconds, and actually getting this free Ether.&lt;/p&gt;

&lt;p&gt;During development, it is a better idea to instead use a local blockchain. It runs on your machine, requires no Internet access, provides you with all the Ether that you need, and mines blocks instantly. These reasons also make local blockchains a great fit for automated tests.&lt;/p&gt;

&lt;p&gt;The most popular local blockchain is Ganache. To install it on your project, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save-dev ganache-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upon startup, Ganache will create a random set of unlocked accounts and give them Ether. In order to get the same addresses that will be used in this guide, you can start Ganache in deterministic mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx ganache-cli --deterministic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ganache will print out a list of available accounts and their private keys, along with some blockchain configuration values. Most importantly, it will display its address, which we’ll use to connect to it. By default, this will be 127.0.0.1:8545.&lt;/p&gt;

&lt;p&gt;Keep in mind that every time you run Ganache, it will create a brand new local blockchain - the state of previous runs is not preserved. This is fine for short-lived experiments, but it means that you will need to have a window open running Ganache for the duration of these guides. Alternatively, you can run Ganache with the --db option, providing a directory to store its data in between runs.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• Deploying a Smart Contract&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;In the Developing Smart Contracts guide we set up our development environment.&lt;/p&gt;

&lt;p&gt;If you don’t already have this setup, please create and setup the project and then create and compile our Box smart contract.&lt;/p&gt;

&lt;p&gt;With our project setup complete we’re now ready to deploy a contract. We’ll be deploying Box, from the Developing Smart Contracts guide. Make sure you have a copy of Box in contracts/Box.sol.&lt;/p&gt;

&lt;p&gt;Truffle uses migrations to deploy contracts. Migrations consist of JavaScript files and a special Migrations contract to track migrations on-chain.&lt;/p&gt;

&lt;p&gt;We will create a JavaScript migration to deploy our Box contract. We will save this file as migrations/2_deploy.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// migrations/2_deploy.js
const Box = artifacts.require('Box');

module.exports = async function (deployer) {
  await deployer.deploy(Box);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we deploy we need to configure the connection to ganache. We need to add a development network for localhost and port 8545 which is what our local blockchain is using.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// truffle-config.js
module.exports = {
...
  networks: {
...
    development: {
     host: "127.0.0.1",     // Localhost (default: none)
     port: 8545,            // Standard Ethereum port (default: none)
     network_id: "*",       // Any network (default: none)
    },
    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the migrate command, we can deploy the Box contract to the development network (Ganache):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// truffle-config.js
module.exports = {
...
  networks: {
...
    development: {
     host: "127.0.0.1",     // Localhost (default: none)
     port: 8545,            // Standard Ethereum port (default: none)
     network_id: "*",       // Any network (default: none)
    },
    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;使用该migrate命令，我们可以将Box合约部署到development网络（Ganache）：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx truffle migrate --network development

Compiling your contracts...
===========================
&amp;gt; Everything is up to date, there is nothing to compile.



Starting migrations...
======================
&amp;gt; Network name:    'development'
&amp;gt; Network id:      1619762548805
&amp;gt; Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================

   Deploying 'Migrations'
   ----------------------
...

2_deploy.js
===========

   Deploying 'Box'
   ---------------
   &amp;gt; transaction hash:    0x25b0a326bfc9aa64be13efb5a4fb3f784ffa845c36d049547eeb0f78e0a3108d
   &amp;gt; Blocks: 0            Seconds: 0
   &amp;gt; contract address:    0xCfEB869F69431e42cdB54A4F4f105C19C080A601
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Truffle will keep track of your deployed contracts, but it also displays their addresses when deploying (in our example, 0xCfEB869F69431e42cdB54A4F4f105C19C080A601). These values will be useful when interacting with them programmatically.&lt;br&gt;
All done! On a real network this process would’ve taken a couple of seconds, but it is near instant on local blockchains.&lt;/p&gt;

&lt;p&gt;Remember that local blockchains do not persist their state throughout multiple runs! If you close your local blockchain process, you’ll have to re-deploy your contracts.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Sending transactions&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Box's first function, store, receives an integer value and stores it in the contract storage. Because this function modifies the blockchain state, we need to send a transaction to the contract to execute it.&lt;/p&gt;

&lt;p&gt;We will send a transaction to call the store function with a numeric value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;truffle(development)&amp;gt; await box.store(42)
{ tx:
   '0x5d4cc78f5d5eac3650214740728192ac760978e261962736289b10da0ec0ea43',
...
       event: 'ValueChanged',
       args: [Result] } ] }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the transaction receipt also shows that Box emitted a ValueChanged event.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Querying state&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Box's other function is called retrieve, and it returns the integer value stored in the contract. This is a query of blockchain state, so we don’t need to send a transaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;truffle(development)&amp;gt; await box.retrieve()
&amp;lt;BN: 2a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because queries only read state and don’t send a transaction, there is no transaction hash to report. This also means that using queries doesn’t cost any Ether, and can be used for free on any network.&lt;/p&gt;

&lt;p&gt;Our Box contract returns uint256 which is too large a number for JavaScript so instead we get returned a big number object. We can display the big number as a string using (await box.retrieve()).toString().&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;truffle(development)&amp;gt; (await box.retrieve()).toString()
'42'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Setup&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Let’s start coding in a new scripts/index.js file, where we’ll be writing our JavaScript code, beginning with some boilerplate, including for writing async code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// scripts/index.js
module.exports = async function main (callback) {
  try {
    // Our code will go here

    callback(0);
  } catch (error) {
    console.error(error);
    callback(1);
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can test our setup by asking the local node something, such as the list of enabled accounts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Retrieve accounts from the local node
const accounts = await web3.eth.getAccounts();
console.log(accounts)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We won’t be repeating the boilerplate code on every snippet, but make sure to always code inside the main function we defined above!&lt;br&gt;
Run the code above using truffle exec, and check that you are getting a list of available accounts in response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx truffle exec --network development ./scripts/index.js
Using network 'development'.

[ '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1',
  '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0',
...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These accounts should match the ones displayed when you started the local blockchain earlier. Now that we have our first code snippet for getting data out of a blockchain, let’s start working with our contract. Remember we are adding our code inside the main function we defined above.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index6"&gt;• Getting a contract instance&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;In order to interact with the Box contract we deployed, we’ll use the Truffle contract abstraction, a JavaScript object that represents our contract on the blockchain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Set up a Truffle contract, representing our deployed Box instance
const Box = artifacts.require('Box');
const box = await Box.deployed();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now use this JavaScript object to interact with our contract.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index7"&gt;• Calling the contract&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Let’s start by displaying the current value of the Box contract.&lt;/p&gt;

&lt;p&gt;We’ll need to call the retrieve() public method of the contract, and await the response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Call the retrieve() function of the deployed Box contract
const value = await box.retrieve();
console.log('Box value is', value.toString());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This snippet is equivalent to the query we ran earlier from the console. Now, make sure everything is running smoothly by running the script again and checking the printed value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx truffle exec --network development ./scripts/index.js
Using network 'development'.

Box value is 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index8"&gt;• Sending a transaction&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;We’ll now send a transaction to store a new value in our Box.&lt;/p&gt;

&lt;p&gt;Let’s store a value of 23 in our Box, and then use the code we had written before to display the updated value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Send a transaction to store() a new value in the Box
await box.store(23);

// Call the retrieve() function of the deployed Box contract
const value = await box.retrieve();
console.log('Box value is', value.toString());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a real-world application, you may want to estimate the gas of your transactions, and check a gas price oracle to know the optimal values to use on every transaction.&lt;br&gt;
We can now run the snippet, and check that the box’s value is updated!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx truffle exec --network development ./scripts/index.js
Using network 'development'.

Box value is 23
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• truffle Tutorials 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/truffle_CN"&gt;truffle 教程 : github.com/565ee/truffle_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_12007659.html"&gt;truffle 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/truffle_EN"&gt;truffle Tutorials : github.com/565ee/truffle_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>truffle</category>
    </item>
    <item>
      <title>11X ethereum truffle : Developing smart contracts</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Sun, 11 Sep 2022 18:39:54 +0000</pubDate>
      <link>https://forem.com/565ee/11x-ethereum-truffle-developing-smart-contracts-153m</link>
      <guid>https://forem.com/565ee/11x-ethereum-truffle-developing-smart-contracts-153m</guid>
      <description>&lt;p&gt;• Setting up a Project&lt;br&gt;&lt;br&gt;
• First contract&lt;br&gt;&lt;br&gt;
• Compiling Solidity&lt;br&gt;&lt;br&gt;
• Using OpenZeppelin Contracts&lt;br&gt;&lt;br&gt;
• Importing OpenZeppelin Contracts&lt;br&gt;&lt;br&gt;
• truffle Tutorials 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式   &lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• Setting up a Project&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;The first step after creating a project is to install a development tool.&lt;/p&gt;

&lt;p&gt;The most popular development framework for Ethereum is Hardhat, and we cover its most common use with ethers.js. The next most popular is Truffle which uses web3.js. Each has their strengths and it is useful to be comfortable using all of them.&lt;/p&gt;

&lt;p&gt;In these guides we will show how to develop, test and deploy smart contracts using Truffle and Hardhat.&lt;/p&gt;

&lt;p&gt;To get started with Truffle we will install it in our project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save-dev truffle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, we can initialize Truffle. This will create an empty Truffle project in our project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx truffle init

Starting init...
================

&amp;gt; Copying project files to /home/openzeppelin/learn

Init successful, sweet!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• First contract&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;We store our Solidity source files (.sol) in a contracts directory. This is equivalent to the src directory you may be familiar with from other languages.&lt;/p&gt;

&lt;p&gt;We can now write our first simple smart contract, called Box: it will let people store a value that can be later retrieved.&lt;/p&gt;

&lt;p&gt;We will save this file as contracts/Box.sol. Each .sol file should have the code for a single contract, and be named after it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Box {
    uint256 private _value;

    // Emitted when the stored value changes
    event ValueChanged(uint256 value);

    // Stores a new value in the contract
    function store(uint256 value) public {
        _value = value;
        emit ValueChanged(value);
    }

    // Reads the last stored value
    function retrieve() public view returns (uint256) {
        return _value;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Compiling Solidity&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;The Ethereum Virtual Machine (EVM) cannot execute Solidity code directly: we first need to compile it into EVM bytecode.&lt;/p&gt;

&lt;p&gt;Our Box.sol contract uses Solidity 0.8 so we need to first configure Truffle to use an appropriate solc version.&lt;/p&gt;

&lt;p&gt;We specify a Solidity 0.8 solc version in our truffle-config.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// truffle-config.js
  ...

  // Configure your compilers
  compilers: {
    solc: {
      version: "0.8.4",    // Fetch exact version from solc-bin (default: truffle's version)
      // docker: true,        // Use "0.5.1" you've installed locally with docker (default: false)
      // settings: {          // See the solidity docs for advice about optimization and evmVersion
      //  optimizer: {
      //    enabled: false,
      //    runs: 200
      //  },
      //  evmVersion: "byzantium"
      // }
    }
  },

  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compiling can then be achieved by running a single compile command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx truffle compile

Compiling your contracts...
===========================
✔ Fetching solc version list from solc-bin. Attempt #1
✔ Downloading compiler. Attempt #1.
&amp;gt; Compiling ./contracts/Box.sol
&amp;gt; Compiling ./contracts/Migrations.sol
&amp;gt; Artifacts written to /home/openzeppelin/learn/build/contracts
&amp;gt; Compiled successfully using:
   - solc: 0.8.4+commit.c7e474f2.Emscripten.clang
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compile command will automatically look for all contracts in the contracts directory, and compile them using the Solidity compiler using the configuration in truffle-config.js.&lt;/p&gt;

&lt;p&gt;You will notice a build/contracts directory was created: it holds the compiled artifacts (bytecode and metadata), which are .json files. It’s a good idea to add this directory to your .gitignore.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Using OpenZeppelin Contracts&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Reusable modules and libraries are the cornerstone of great software. OpenZeppelin Contracts contains lots of useful building blocks for smart contracts to build on. And you can rest easy when building on them: they’ve been the subject of multiple audits, with their security and correctness battle-tested.&lt;/p&gt;

&lt;p&gt;Many of the contracts in the library are not standalone, that is, you’re not expected to deploy them as-is. Instead, you will use them as a starting point to build your own contracts by adding features to them. Solidity provides multiple inheritance as a mechanism to achieve this: take a look at the Solidity documentation for more details.&lt;/p&gt;

&lt;p&gt;For example, the Ownable contract marks the deployer account as the contract’s owner, and provides a modifier called onlyOwner. When applied to a function, onlyOwner will cause all function calls that do not originate from the owner account to revert. Functions to transfer and renounce ownership are also available.&lt;/p&gt;

&lt;p&gt;When used this way, inheritance becomes a powerful mechanism that allows for modularization, without forcing you to deploy and manage multiple contracts.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Importing OpenZeppelin Contracts&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;The latest published release of the OpenZeppelin Contracts library can be downloaded by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install @openzeppelin/contracts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should always use the library from these published releases: copy-pasting library source code into your project is a dangerous practice that makes it very easy to introduce security vulnerabilities in your contracts.&lt;/p&gt;

&lt;p&gt;To use one of the OpenZeppelin Contracts, import it by prefixing its path with @openzeppelin/contracts. For example, in order to replace our own Auth contract, we will import @openzeppelin/contracts/access/Ownable.sol to add access control to Box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Import Ownable from the OpenZeppelin Contracts library
import "@openzeppelin/contracts/access/Ownable.sol";

// Make Box inherit from the Ownable contract
contract Box is Ownable {
    uint256 private _value;

    event ValueChanged(uint256 value);

    // The onlyOwner modifier restricts who can call the store function
    function store(uint256 value) public onlyOwner {
        _value = value;
        emit ValueChanged(value);
    }

    function retrieve() public view returns (uint256) {
        return _value;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The OpenZeppelin Contracts documentation is a great place to learn about developing secure smart contract systems. It features both guides and a detailed API reference: see for example the Access Control guide to know more about the Ownable contract used in the code sample above.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• truffle Tutorials 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/truffle_CN"&gt;truffle 教程 : github.com/565ee/truffle_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_12007659.html"&gt;truffle 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/truffle_EN"&gt;truffle Tutorials : github.com/565ee/truffle_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>truffle</category>
    </item>
    <item>
      <title>11V ethereum OpenZeppelin : Upgrading smart contracts</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Sat, 10 Sep 2022 08:37:00 +0000</pubDate>
      <link>https://forem.com/565ee/11v-ethereum-openzeppelin-upgrading-smart-contracts-3anb</link>
      <guid>https://forem.com/565ee/11v-ethereum-openzeppelin-upgrading-smart-contracts-3anb</guid>
      <description>&lt;p&gt;• What’s in an upgrade&lt;br&gt;&lt;br&gt;
• Upgrading using the Upgrades Plugins&lt;br&gt;&lt;br&gt;
• How upgrades work&lt;br&gt;&lt;br&gt;
• Initialization&lt;br&gt;&lt;br&gt;
• Upgrading&lt;br&gt;&lt;br&gt;
• Testing&lt;br&gt;&lt;br&gt;
• OpenZeppelin Tutorials 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• What’s in an upgrade&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Smart contracts deployed using OpenZeppelin Upgrades Plugins can be upgraded to modify their code, while preserving their address, state, and balance. This allows you to iteratively add new features to your project, or fix any bugs you may find in production.&lt;/p&gt;

&lt;p&gt;Smart contracts in Ethereum are immutable by default. Once you create them there is no way to alter them, effectively acting as an unbreakable contract among participants.&lt;/p&gt;

&lt;p&gt;However, for some scenarios, it is desirable to be able to modify them. Think of a traditional contract between two parties: if they both agreed to change it, they would be able to do so. On Ethereum, they may desire to alter a smart contract to fix a bug they found (which might even lead to a hacker stealing their funds!), to add additional features, or simply to change the rules enforced by it.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• Upgrading using the Upgrades Plugins&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Whenever you deploy a new contract using deployProxy in the OpenZeppelin Upgrades Plugins, that contract instance can be upgraded later. By default, only the address that originally deployed the contract has the rights to upgrade it.&lt;/p&gt;

&lt;p&gt;deployProxy will create the following transactions:&lt;br&gt;
Deploy the implementation contract (our Box contract)&lt;br&gt;
Deploy the ProxyAdmin contract (the admin for our proxy).&lt;br&gt;
Deploy the proxy contract and run any initializer function.&lt;/p&gt;

&lt;p&gt;Let’s see how it works, by deploying an upgradeable version of our Box contract, using the same setup as when we deployed earlier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Box {
    uint256 private _value;

    // Emitted when the stored value changes
    event ValueChanged(uint256 value);

    // Stores a new value in the contract
    function store(uint256 value) public {
        _value = value;
        emit ValueChanged(value);
    }

    // Reads the last stored value
    function retrieve() public view returns (uint256) {
        return _value;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the Hardhat Upgrades plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev @openzeppelin/hardhat-upgrades
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then need to configure Hardhat to use our @openzeppelin/hardhat-upgrades plugin. To do this add the plugin in your hardhat.config.js file as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// hardhat.config.js
...
require('@nomiclabs/hardhat-ethers');
require('@openzeppelin/hardhat-upgrades');
...
module.exports = {
...
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to upgrade a contract like Box we need to first deploy it as an upgradeable contract, which is a different deployment procedure than we’ve seen so far. We will initialize our Box contract by calling store with the value 42.&lt;/p&gt;

&lt;p&gt;Hardhat doesn’t currently have a native deployment system, instead we use scripts to deploy contracts.&lt;/p&gt;

&lt;p&gt;We will create a script to deploy our upgradeable Box contract using deployProxy. We will save this file as scripts/deploy_upgradeable_box.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// scripts/deploy_upgradeable_box.js
const { ethers, upgrades } = require('hardhat');

async function main () {
  const Box = await ethers.getContractFactory('Box');
  console.log('Deploying Box...');
  const box = await upgrades.deployProxy(Box, [42], { initializer: 'store' });
  await box.deployed();
  console.log('Box deployed to:', box.address);
}

main();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then deploy our upgradeable contract.&lt;/p&gt;

&lt;p&gt;Using the run command, we can deploy the Box contract to the development network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat run --network localhost scripts/deploy_upgradeable_box.js
Deploying Box...
Box deployed to: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then interact with our Box contract to retrieve the value that we stored during initialization.&lt;/p&gt;

&lt;p&gt;We will use the Hardhat console to interact with our upgraded Box contract.&lt;/p&gt;

&lt;p&gt;We need to specify the address of our proxy contract from when we deployed our Box contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat console --network localhost
Welcome to Node.js v12.22.1.
Type ".help" for more information.
&amp;gt; const Box = await ethers.getContractFactory('Box');
undefined
&amp;gt; const box = await Box.attach('0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0');
undefined
&amp;gt; (await box.retrieve()).toString();
'42'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating the Solidity file, we can now upgrade the instance we had deployed earlier using the upgradeProxy function.&lt;/p&gt;

&lt;p&gt;upgradeProxy will create the following transactions:&lt;br&gt;
Deploy the implementation contract (our BoxV2 contract)&lt;br&gt;
Call the ProxyAdmin to update the proxy contract to use the new implementation.&lt;/p&gt;

&lt;p&gt;We will create a script to upgrade our Box contract to use BoxV2 using upgradeProxy. We will save this file as scripts/upgrade_box.js. We need to specify the address of our proxy contract from when we deployed our Box contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// scripts/upgrade_box.js
const { ethers, upgrades } = require('hardhat');

async function main () {
  const BoxV2 = await ethers.getContractFactory('BoxV2');
  console.log('Upgrading Box...');
  await upgrades.upgradeProxy('0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0', BoxV2);
  console.log('Box upgraded');
}

main();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then deploy our upgradeable contract.&lt;/p&gt;

&lt;p&gt;Using the run command, we can upgrade the Box contract on the development network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx hardhat run --network localhost scripts/upgrade_box.js
Compiling 1 file with 0.8.4
Compilation finished successfully
Upgrading Box...
Box upgraded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done! Our Box instance has been upgraded to the latest version of the code, while keeping its state and the same address as before. We didn’t need to deploy a new one at a new address, nor manually copy the value from the old Box to the new one.&lt;/p&gt;

&lt;p&gt;Let’s try it out by invoking the new increment function, and checking the value afterwards:&lt;/p&gt;

&lt;p&gt;We need to specify the address of our proxy contract from when we deployed our Box contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat console --network localhost
Welcome to Node.js v12.22.1.
Type ".help" for more information.
&amp;gt; const BoxV2 = await ethers.getContractFactory('BoxV2');
undefined
&amp;gt; const box = await BoxV2.attach('0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0');
undefined
&amp;gt; await box.increment();
...
&amp;gt; (await box.retrieve()).toString();
'43'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! Notice how the value of the Box was preserved throughout the upgrade, as well as its address. And this process is the same regardless of whether you are working on a local blockchain, a testnet, or the main network.&lt;/p&gt;

&lt;p&gt;Let’s see how the OpenZeppelin Upgrades Plugins accomplish this.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• How upgrades work&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;This section will be more theory-heavy than others: feel free to skip over it and return later if you are curious.&lt;/p&gt;

&lt;p&gt;When you create a new upgradeable contract instance, the OpenZeppelin Upgrades Plugins actually deploys three contracts:&lt;br&gt;
The contract you have written, which is known as the implementation contract containing the logic.&lt;br&gt;
A ProxyAdmin to be the admin of the proxy.&lt;br&gt;
A proxy to the implementation contract, which is the contract that you actually interact with.&lt;/p&gt;

&lt;p&gt;Here, the proxy is a simple contract that just delegates all calls to an implementation contract. A delegate call is similar to a regular call, except that all code is executed in the context of the caller, not of the callee. Because of this, a transfer in the implementation contract’s code will actually transfer the proxy’s balance, and any reads or writes to the contract storage will read or write from the proxy’s own storage.&lt;/p&gt;

&lt;p&gt;This allows us to decouple a contract’s state and code: the proxy holds the state, while the implementation contract provides the code. And it also allows us to change the code by just having the proxy delegate to a different implementation contract.&lt;/p&gt;

&lt;p&gt;You can have multiple proxies using the same implementation contract, so you can save gas using this pattern if you plan to deploy multiple copies of the same contract.&lt;br&gt;
Any user of the smart contract always interacts with the proxy, which never changes its address. This allows you to roll out an upgrade or fix a bug without requesting your users to change anything on their end - they just keep interacting with the same address as always.&lt;/p&gt;

&lt;p&gt;If you want to learn more about how OpenZeppelin proxies work, check out Proxies.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Initialization&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Upgradeable contracts cannot have a constructor. To help you run initialization code, OpenZeppelin Contracts provides the Initializable base contract that allows you to tag a method as initializer, ensuring it can be run only once.&lt;/p&gt;

&lt;p&gt;As an example, let’s write a new version of the Box contract with an initializer, storing the address of an admin who will be the only one allowed to change its contents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/AdminBox.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract AdminBox is Initializable {
    uint256 private _value;
    address private _admin;

    // Emitted when the stored value changes
    event ValueChanged(uint256 value);

    function initialize(address admin) public initializer {
        _admin = admin;
    }

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() initializer {}

    // Stores a new value in the contract
    function store(uint256 value) public {
        require(msg.sender == _admin, "AdminBox: not admin");
        _value = value;
        emit ValueChanged(value);
    }

    // Reads the last stored value
    function retrieve() public view returns (uint256) {
        return _value;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When deploying this contract, we will need to specify the initializer function name (only when the name is not the default of initialize) and provide the admin address that we want to use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// scripts/deploy_upgradeable_adminbox.js
const { ethers, upgrades } = require('hardhat');

async function main () {
  const AdminBox = await ethers.getContractFactory('AdminBox');
  console.log('Deploying AdminBox...');
  const adminBox = await upgrades.deployProxy(AdminBox, ['0xACa94ef8bD5ffEE41947b4585a84BdA5a3d3DA6E'], { initializer: 'initialize' });
  await adminBox.deployed();
  console.log('AdminBox deployed to:', adminBox.address);
}

main();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For all practical purposes, the initializer acts as a constructor. However, keep in mind that since it’s a regular function, you will need to manually call the initializers of all base contracts (if any).&lt;/p&gt;

&lt;p&gt;You may have noticed that we included a constructor as well as an initializer. This constructor serves the purpose of leaving the implementation contract in an initialized state, which is a mitigation against certain potential attacks.&lt;/p&gt;

&lt;p&gt;To learn more about this and other caveats when writing upgradeable contracts, check out our Writing Upgradeable Contracts guide.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Upgrading&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Due to technical limitations, when you upgrade a contract to a new version you cannot change the storage layout of that contract.&lt;/p&gt;

&lt;p&gt;This means that, if you have already declared a state variable in your contract, you cannot remove it, change its type, or declare another variable before it. In our Box example, it means that we can only add new state variables after value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/Box.sol
contract Box {
    uint256 private _value;

    // We can safely add a new variable after the ones we had declared
    address private _owner;

    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fortunately, this limitation only affects state variables. You can change the contract’s functions and events as you wish.&lt;/p&gt;

&lt;p&gt;If you accidentally mess up with your contract’s storage layout, the Upgrades Plugins will warn you when you try to upgrade.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index6"&gt;• Testing&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;To test upgradeable contracts we should create unit tests for the implementation contract, along with creating higher level tests for testing interaction via the proxy. We can use deployProxy in our tests just like we do when we deploy.&lt;/p&gt;

&lt;p&gt;When we want to upgrade, we should create unit tests for the new implementation contract, along with creating higher level tests for testing interaction via the proxy after we upgrade using upgradeProxy, checking that state is maintained across upgrades.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• OpenZeppelin Tutorials 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/OpenZeppelin_CN"&gt;OpenZeppelin 教程 : github.com/565ee/OpenZeppelin_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_11997496.html"&gt;OpenZeppelin 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/OpenZeppelin_EN"&gt;OpenZeppelin Tutorials : github.com/565ee/OpenZeppelin_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>openzeppelin</category>
    </item>
    <item>
      <title>11T ethereum OpenZeppelin : Connecting to public test networks</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Wed, 07 Sep 2022 18:47:03 +0000</pubDate>
      <link>https://forem.com/565ee/11t-ethereum-openzeppelin-connecting-to-public-test-networks-eg1</link>
      <guid>https://forem.com/565ee/11t-ethereum-openzeppelin-connecting-to-public-test-networks-eg1</guid>
      <description>&lt;p&gt;• introduce&lt;br&gt;&lt;br&gt;
• Accessing a testnet node&lt;br&gt;&lt;br&gt;
• Creating a new account&lt;br&gt;&lt;br&gt;
• Configuring the network&lt;br&gt;&lt;br&gt;
• Funding the testnet account&lt;br&gt;&lt;br&gt;
• Working on a testnet&lt;br&gt;&lt;br&gt;
• OpenZeppelin Tutorials 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• introduce&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;After you have written your contracts, and tried them out locally and tested them thoroughly, it’s time to move to a persistent public testing environment, where you and your beta users can start interacting with your application.&lt;/p&gt;

&lt;p&gt;We will use public testing networks (aka testnets) for this, which are networks that operate similar to the main Ethereum network, but where Ether has no value and is free to acquire - making them ideal for testing your contracts at no cost.&lt;/p&gt;

&lt;p&gt;Remember that deploying to a public test network is a necessary step when developing an Ethereum project. They provide a safe environment for testing that closely mimics the main network - you don’t want to take out your project for a test drive in a network where mistakes will cost you and your users money!&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• Accessing a testnet node&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;While you can spin up your own Geth or OpenEthereum node connected to a testnet, the easiest way to access a testnet is via a public node service such as Alchemy or Infura. Alchemy and Infura provide access to public nodes for all testnets and the main network, via both free and paid plans.&lt;/p&gt;

&lt;p&gt;We say a node is public when it can be accessed by the general public, and manages no accounts. This means that it can reply to queries and relay signed transactions, but cannot sign transactions on its own.&lt;/p&gt;

&lt;p&gt;In this guide we will use Alchemy, though you can use Infura, or another public node provider of your choice.&lt;/p&gt;

&lt;p&gt;Head over to Alchemy (includes referral code), sign up, and jot down your assigned API key - we will use it later to connect to the network.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Creating a new account&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;To send transactions in a testnet, you will need a new Ethereum account. There are many ways to do this: here we will use the mnemonics package, which will output a fresh mnemonic (a set of 12 words) we will use to derive our accounts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx mnemonics
drama film snack motion ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to keep your mnemonic secure. Do not commit secrets to version control. Even if it is just for testing purposes, there are still malicious users out there who will wreak havoc on your testnet deployment for fun!&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Configuring the network&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Since we are using public nodes, we will need to sign all our transactions locally. We will configure the network with our mnemonic and an Alchemy endpoint.&lt;/p&gt;

&lt;p&gt;We need to update our configuration file with a new network connection to the testnet. Here we will use Rinkeby, but you can use whichever you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// hardhat.config.js
+ const { alchemyApiKey, mnemonic } = require('./secrets.json');
...
  module.exports = {
+    networks: {
+     rinkeby: {
+       url: `https://eth-rinkeby.alchemyapi.io/v2/${alchemyApiKey}`,
+       accounts: { mnemonic: mnemonic },
+     },
+   },
...
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note in the first line that we are loading the project id and mnemonic from a secrets.json file, which should look like the following, but using your own values. Make sure to .gitignore it to ensure you don’t commit secrets to version control!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "mnemonic": "drama film snack motion ...",
  "alchemyApiKey": "JPV2..."
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now test out that this configuration is working by listing the accounts we have available for the Rinkeby network. Remember that yours will be different, as they depend on the mnemonic you used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat console --network rinkeby
Welcome to Node.js v12.22.1.
Type ".help" for more information.
&amp;gt; accounts = await ethers.provider.listAccounts()
[
  '0xEce6999C6c5BDA71d673090144b6d3bCD21d13d4',
  '0xC1310ade58A75E6d4fCb8238f9559188Ea3808f9',
...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Funding the testnet account&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Most public testnets have a faucet: a site that will provide you with a small amount of test Ether for free. If you are on Rinkeby, head on to the Rinkeby Authenticated Faucet to get funds by authenticating with your Twitter or Facebook account. Alternatively, you can also use MetaMask’s faucet to ask for funds directly to your MetaMask accounts.&lt;/p&gt;

&lt;p&gt;Armed with a funded account, let’s deploy our contracts to the testnet!&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index6"&gt;• Working on a testnet&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;With a project configured to work on a public testnet, we can now finally deploy our Box contract. The command here is exactly the same as if you were on your local development network, though it will take a few seconds to run as new blocks are mined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat run --network rinkeby scripts/deploy.js
Deploying Box...
Box deployed to: 0xD7fBC6865542846e5d7236821B5e045288259cf0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! Your Box contract instance will be forever stored in the testnet, and publicly accessible to anyone.&lt;/p&gt;

&lt;p&gt;You can see your contract on a block explorer such as Etherscan. Remember to access the explorer on the testnet where you deployed your contract, such as rinkeby.etherscan.io for Rinkeby.&lt;/p&gt;

&lt;p&gt;You can also interact with your instance as you regularly would, either using the console, or programmatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat console --network rinkeby
Welcome to Node.js v12.22.1.
Type ".help" for more information.
&amp;gt; const Box = await ethers.getContractFactory('Box');
undefined
&amp;gt; const box = await Box.attach('0xD7fBC6865542846e5d7236821B5e045288259cf0');
undefined
&amp;gt; await box.store(42);
{
  hash: '0x330e331d30ee83f96552d82b7fdfa6156f9f97d549a612eeef7283d18b31d107',
...
&amp;gt; (await box.retrieve()).toString()
'42'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep in mind that every transaction will cost some gas, so you will eventually need to top up your account with more funds.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• OpenZeppelin Tutorials 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/OpenZeppelin_CN"&gt;OpenZeppelin 教程 : github.com/565ee/OpenZeppelin_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_11997496.html"&gt;OpenZeppelin 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/OpenZeppelin_EN"&gt;OpenZeppelin Tutorials : github.com/565ee/OpenZeppelin_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>openzeppelin</category>
    </item>
    <item>
      <title>11R ethereum OpenZeppelin : Writing automated smart contract tests</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Tue, 06 Sep 2022 11:11:16 +0000</pubDate>
      <link>https://forem.com/565ee/11r-ethereum-openzeppelin-writing-automated-smart-contract-tests-42ml</link>
      <guid>https://forem.com/565ee/11r-ethereum-openzeppelin-writing-automated-smart-contract-tests-42ml</guid>
      <description>&lt;p&gt;• introduce&lt;br&gt;&lt;br&gt;
• About testing&lt;br&gt;&lt;br&gt;
• Setting up a testing environment&lt;br&gt;&lt;br&gt;
• Writing unit tests&lt;br&gt;&lt;br&gt;
• Performing complex assertions&lt;br&gt;&lt;br&gt;
• OpenZeppelin Tutorials 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• introduce&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;In a blockchain environment, a single mistake could cost you all of your funds - or even worse, your users' funds! This guide will help you develop robust applications by writing automated tests that verify your application behaves exactly as you intended.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• About testing&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;There is a wide range of testing techniques, from simple manual verifications to complex end-to-end setups, all of them useful in their own way.&lt;/p&gt;

&lt;p&gt;When it comes to smart contract development though, practice has shown that contract unit testing is exceptionally worthwhile. These tests are simple to write and quick to run, and let you add features and fix bugs in your code with confidence.&lt;/p&gt;

&lt;p&gt;Smart contract unit testing consists of multiple small, focused tests, which each check a small part of your contract for correctness. They can often be expressed in single sentences that make up a specification, such as 'the admin is able to pause the contract', 'transferring tokens emits an event' or 'non-admins cannot mint new tokens'.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Setting up a testing environment&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;You may be wondering how we’re going to run these tests, since smart contracts are executed inside a blockchain. Using the actual Ethereum network would be very expensive, and while testnets are free, they are also slow (with blocktimes between 5 and 20 seconds). If we intend to run hundreds of tests whenever we make a change to our code, we need something better.&lt;/p&gt;

&lt;p&gt;What we will use is called a local blockchain: a slimmed down version of the real thing, disconnected from the Internet, running on your machine. This will simplify things quite a bit: you won’t need to get Ether, and new blocks will be mined instantly.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Writing unit tests&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;We’ll use Chai assertions for our unit tests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save-dev chai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will keep our test files in a test directory. Tests are best structured by mirroring the contracts directory: for each .sol file there, create a corresponding test file.&lt;/p&gt;

&lt;p&gt;Time to write our first tests! These will test properties of the Box contract from previous guides: a simple contract that lets you retrieve a value the owner previously store d.&lt;/p&gt;

&lt;p&gt;Create a test directory in your project root. We will save the test as test/Box.test.js. Each test .js file commonly has the tests for a single contract, and is named after it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// test/Box.test.js
// Load dependencies
const { expect } = require('chai');

// Start test block
describe('Box', function () {
  before(async function () {
    this.Box = await ethers.getContractFactory('Box');
  });

  beforeEach(async function () {
    this.box = await this.Box.deploy();
    await this.box.deployed();
  });

  // Test case
  it('retrieve returns a value previously stored', async function () {
    // Store a value
    await this.box.store(42);

    // Test if the returned value is the same one
    // Note that we need to use strings to compare the 256 bit integers
    expect((await this.box.retrieve()).toString()).to.equal('42');
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are now ready to run our tests!&lt;/p&gt;

&lt;p&gt;Running npx hardhat test will execute all tests in the test directory, checking that your contracts work the way you meant them to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat test


  Box
    ✓ retrieve returns a value previously stored


  1 passing (578ms)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s also a very good idea at this point to set up a Continuous Integration service such as CircleCI to make your tests run automatically every time you commit your code to GitHub.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Performing complex assertions&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Many interesting properties of your contracts may be hard to capture, such as:&lt;/p&gt;

&lt;p&gt;verifying that the contract reverts on errors&lt;/p&gt;

&lt;p&gt;measuring by how much an account’s Ether balance changed&lt;/p&gt;

&lt;p&gt;checking that the proper events are emitted&lt;/p&gt;

&lt;p&gt;OpenZeppelin Test Helpers is a library designed to help you test all of these properties. It will also simplify the tasks of simulating time passing on the blockchain and handling very large numbers.&lt;/p&gt;

&lt;p&gt;To install the OpenZeppelin Test Helpers, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save-dev @openzeppelin/test-helpers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then update our tests to use OpenZeppelin Test Helpers for very large number support, to check for an event being emitted and to check that a transaction reverts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// test/Box.test.js
// Load dependencies
const { expect } = require('chai');

// Import utilities from Test Helpers
const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');

// Load compiled artifacts
const Box = artifacts.require('Box');

// Start test block
contract('Box', function ([ owner, other ]) {
  // Use large integers ('big numbers')
  const value = new BN('42');

  beforeEach(async function () {
    this.box = await Box.new({ from: owner });
  });

  it('retrieve returns a value previously stored', async function () {
    await this.box.store(value, { from: owner });

    // Use large integer comparisons
    expect(await this.box.retrieve()).to.be.bignumber.equal(value);
  });

  it('store emits an event', async function () {
    const receipt = await this.box.store(value, { from: owner });

    // Test that a ValueChanged event was emitted with the new value
    expectEvent(receipt, 'ValueChanged', { value: value });
  });

  it('non owner cannot store a value', async function () {
    // Test a transaction reverts
    await expectRevert(
      this.box.store(value, { from: other }),
      'Ownable: caller is not the owner',
    );
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These will test properties of the Ownable Box contract from previous guides: a simple contract that lets you retrieve a value the owner previously stored.&lt;/p&gt;

&lt;p&gt;Run your tests again to see the Test Helpers in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx truffle test
...
  Contract: Box
    ✓ retrieve returns a value previously stored
    ✓ store emits an event
    ✓ non owner cannot store a value (588ms)


  3 passing (753ms)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Test Helpers will let you write powerful assertions without having to worry about the low-level details of the underlying Ethereum libraries. To learn more about what you can do with them, head to their API reference.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• OpenZeppelin Tutorials 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/OpenZeppelin_CN"&gt;OpenZeppelin 教程 : github.com/565ee/OpenZeppelin_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_11997496.html"&gt;OpenZeppelin 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/OpenZeppelin_EN"&gt;OpenZeppelin Tutorials : github.com/565ee/OpenZeppelin_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>openzeppelin</category>
    </item>
    <item>
      <title>11P ethereum OpenZeppelin : Deploying and interacting with smart contracts</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Mon, 05 Sep 2022 17:19:13 +0000</pubDate>
      <link>https://forem.com/565ee/11p-ethereum-openzeppelin-deploying-and-interacting-with-smart-contracts-34f</link>
      <guid>https://forem.com/565ee/11p-ethereum-openzeppelin-deploying-and-interacting-with-smart-contracts-34f</guid>
      <description>&lt;p&gt;• Setting up a Local Blockchain&lt;br&gt;&lt;br&gt;
• Deploying a Smart Contract&lt;br&gt;&lt;br&gt;
• Interacting from the Console&lt;br&gt;&lt;br&gt;
• Interacting programmatically&lt;br&gt;&lt;br&gt;
• Getting a contract instance&lt;br&gt;&lt;br&gt;
• Calling the contract&lt;br&gt;&lt;br&gt;
• Sending a transaction&lt;br&gt;&lt;br&gt;
• OpenZeppelin Tutorials 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• Setting up a Local Blockchain&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Before we begin, we first need an environment where we can deploy our contracts. The Ethereum blockchain (often called "mainnet", for "main network") requires spending real money to use it, in the form of Ether (its native currency). This makes it a poor choice when trying out new ideas or tools.&lt;/p&gt;

&lt;p&gt;To solve this, a number of "testnets" (for "test networks") exist: these include the Ropsten, Rinkeby, Kovan and Goerli blockchains. They work very similarly to mainnet, with one difference: you can get Ether for these networks for free, so that using them doesn’t cost you a single cent. However, you will still need to deal with private key management, blocktimes in the range of 5 to 20 seconds, and actually getting this free Ether.&lt;/p&gt;

&lt;p&gt;During development, it is a better idea to instead use a local blockchain. It runs on your machine, requires no Internet access, provides you with all the Ether that you need, and mines blocks instantly. These reasons also make local blockchains a great fit for automated tests.&lt;/p&gt;

&lt;p&gt;Hardhat comes with a local blockchain built-in, the Hardhat Network.&lt;/p&gt;

&lt;p&gt;Upon startup, Hardhat Network will create a set of unlocked accounts and give them Ether.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx hardhat node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hardhat Network will print out its address, &lt;a href="http://127.0.0.1:8545"&gt;http://127.0.0.1:8545&lt;/a&gt;, along with a list of available accounts and their private keys.&lt;/p&gt;

&lt;p&gt;Keep in mind that every time you run Hardhat Network, it will create a brand new local blockchain - the state of previous runs is not preserved. This is fine for short-lived experiments, but it means that you will need to have a window open running Hardhat Network for the duration of these guides.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• Deploying a Smart Contract&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;In the Developing Smart Contracts guide we set up our development environment.&lt;/p&gt;

&lt;p&gt;If you don’t already have this setup, please create and setup the project and then create and compile our Box smart contract.&lt;/p&gt;

&lt;p&gt;With our project setup complete we’re now ready to deploy a contract. We’ll be deploying Box, from the Developing Smart Contracts guide. Make sure you have a copy of Box in contracts/Box.sol.&lt;/p&gt;

&lt;p&gt;Hardhat doesn’t currently have a native deployment system, instead we use scripts to deploy contracts.&lt;/p&gt;

&lt;p&gt;We will create a script to deploy our Box contract. We will save this file as scripts/deploy.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// scripts/deploy.js
async function main () {
  // We get the contract to deploy
  const Box = await ethers.getContractFactory('Box');
  console.log('Deploying Box...');
  const box = await Box.deploy();
  await box.deployed();
  console.log('Box deployed to:', box.address);
}

main()
  .then(() =&amp;gt; process.exit(0))
  .catch(error =&amp;gt; {
    console.error(error);
    process.exit(1);
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use ethers in our script, so we need to install it and the @nomiclabs/hardhat-ethers plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save-dev @nomiclabs/hardhat-ethers ethers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to add in our configuration that we are using the @nomiclabs/hardhat-ethers plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// hardhat.config.js
require('@nomiclabs/hardhat-ethers');

...
module.exports = {
...
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All done! On a real network this process would’ve taken a couple of seconds, but it is near instant on local blockchains.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Interacting from the Console&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;With our Box contract deployed, we can start using it right away.&lt;/p&gt;

&lt;p&gt;We will use the Hardhat console to interact with our deployed Box contract on our localhost network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat console --network localhost
Welcome to Node.js v12.22.1.
Type ".help" for more information.
&amp;gt; const Box = await ethers.getContractFactory('Box');
undefined
&amp;gt; const box = await Box.attach('0x5FbDB2315678afecb367f032d93F642f64180aa3')
undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sending transactions&lt;br&gt;
Box's first function, store, receives an integer value and stores it in the contract storage. Because this function modifies the blockchain state, we need to send a transaction to the contract to execute it.&lt;/p&gt;

&lt;p&gt;We will send a transaction to call the store function with a numeric value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; await box.store(42)
{
  hash: '0x3d86c5c2c8a9f31bedb5859efa22d2d39a5ea049255628727207bc2856cce0d3',
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Querying state&lt;br&gt;
Box's other function is called retrieve, and it returns the integer value stored in the contract. This is a query of blockchain state, so we don’t need to send a transaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; await box.retrieve()
BigNumber { _hex: '0x2a', _isBigNumber: true }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Interacting programmatically&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;The console is useful for prototyping and running one-off queries or transactions. However, eventually you will want to interact with your contracts from your own code.&lt;/p&gt;

&lt;p&gt;In this section, we’ll see how to interact with our contracts from JavaScript, and use Hardhat to run our script with our Hardhat configuration.&lt;/p&gt;

&lt;p&gt;Setup&lt;br&gt;
Let’s start coding in a new scripts/index.js file, where we’ll be writing our JavaScript code, beginning with some boilerplate, including for writing async code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// scripts/index.js
async function main () {
  // Our code will go here
}

main()
  .then(() =&amp;gt; process.exit(0))
  .catch(error =&amp;gt; {
    console.error(error);
    process.exit(1);
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can test our setup by asking the local node something, such as the list of enabled accounts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Retrieve accounts from the local node
const accounts = await ethers.provider.listAccounts();
console.log(accounts);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the code above using hardhat run, and check that you are getting a list of available accounts in response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx hardhat run --network localhost ./scripts/index.js
[
  '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
  '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These accounts should match the ones displayed when you started the local blockchain earlier. Now that we have our first code snippet for getting data out of a blockchain, let’s start working with our contract. Remember we are adding our code inside the main function we defined above.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Getting a contract instance&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;In order to interact with the Box contract we deployed, we’ll use an ethers contract instance.&lt;/p&gt;

&lt;p&gt;An ethers contract instance is a JavaScript object that represents our contract on the blockchain, which we can use to interact with our contract. To attach it to our deployed contract we need to provide the contract address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Set up an ethers contract, representing our deployed Box instance
const address = '0x5FbDB2315678afecb367f032d93F642f64180aa3';
const Box = await ethers.getContractFactory('Box');
const box = await Box.attach(address);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index6"&gt;• Calling the contract&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Let’s start by displaying the current value of the Box contract.&lt;/p&gt;

&lt;p&gt;We’ll need to call the read only retrieve() public method of the contract, and await the response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Call the retrieve() function of the deployed Box contract
const value = await box.retrieve();
console.log('Box value is', value.toString());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This snippet is equivalent to the query we ran earlier from the console. Now, make sure everything is running smoothly by running the script again and checking the printed value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat run --network localhost ./scripts/index.js
Box value is 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index7"&gt;• Sending a transaction&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;We’ll now send a transaction to store a new value in our Box.&lt;/p&gt;

&lt;p&gt;Let’s store a value of 23 in our Box, and then use the code we had written before to display the updated value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Send a transaction to store() a new value in the Box
await box.store(23);

// Call the retrieve() function of the deployed Box contract
const value = await box.retrieve();
console.log('Box value is', value.toString());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now run the snippet, and check that the box’s value is updated!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx hardhat run --network localhost ./scripts/index.js
Box value is 23
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• OpenZeppelin Tutorials 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/OpenZeppelin_CN"&gt;OpenZeppelin 教程 : github.com/565ee/OpenZeppelin_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_11997496.html"&gt;OpenZeppelin 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/OpenZeppelin_EN"&gt;OpenZeppelin Tutorials : github.com/565ee/OpenZeppelin_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>openzeppelin</category>
    </item>
    <item>
      <title>11N ethereum OpenZeppelin : Developing smart contracts</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Sun, 04 Sep 2022 16:40:00 +0000</pubDate>
      <link>https://forem.com/565ee/11n-ethereum-openzeppelin-developing-smart-contracts-3ckg</link>
      <guid>https://forem.com/565ee/11n-ethereum-openzeppelin-developing-smart-contracts-3ckg</guid>
      <description>&lt;p&gt;• Setting up a Project&lt;br&gt;&lt;br&gt;
• First contract&lt;br&gt;&lt;br&gt;
• Compiling Solidity&lt;br&gt;&lt;br&gt;
• Adding more contracts&lt;br&gt;&lt;br&gt;
• Using OpenZeppelin Contracts&lt;br&gt;&lt;br&gt;
• OpenZeppelin Tutorials 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• Setting up a Project&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;The first step after creating a project is to install a development tool.&lt;/p&gt;

&lt;p&gt;The most popular development framework for Ethereum is Hardhat, and we cover its most common use with ethers.js. The next most popular is Truffle which uses web3.js. Each has their strengths and it is useful to be comfortable using all of them.&lt;/p&gt;

&lt;p&gt;In these guides we will show how to develop, test and deploy smart contracts using Truffle and Hardhat.&lt;/p&gt;

&lt;p&gt;To get started with Hardhat we will install it in our project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save-dev hardhat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, we can run npx hardhat. This will create a Hardhat config file (hardhat.config.js) in our project directory.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• First contract&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;We store our Solidity source files (.sol) in a contracts directory. This is equivalent to the src directory you may be familiar with from other languages.&lt;/p&gt;

&lt;p&gt;We can now write our first simple smart contract, called Box: it will let people store a value that can be later retrieved.&lt;/p&gt;

&lt;p&gt;We will save this file as contracts/Box.sol. Each .sol file should have the code for a single contract, and be named after it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Box {
    uint256 private _value;

    // Emitted when the stored value changes
    event ValueChanged(uint256 value);

    // Stores a new value in the contract
    function store(uint256 value) public {
        _value = value;
        emit ValueChanged(value);
    }

    // Reads the last stored value
    function retrieve() public view returns (uint256) {
        return _value;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Compiling Solidity&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;The Ethereum Virtual Machine (EVM) cannot execute Solidity code directly: we first need to compile it into EVM bytecode.&lt;/p&gt;

&lt;p&gt;Our Box.sol contract uses Solidity 0.8 so we need to first configure Hardhat to use an appropriate solc version.&lt;/p&gt;

&lt;p&gt;We specify a Solidity 0.8 solc version in our hardhat.config.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// hardhat.config.js

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
 module.exports = {
  solidity: "0.8.4",
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re unfamiliar with the npx command, check out our Node project setup guide.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat compile
Solidity 0.8.4 is not fully supported yet. You can still use Hardhat, but some features, like stack traces, might not work correctly.

Learn more at https://hardhat.org/reference/solidity-support"

Compiling 1 file with 0.8.4
Compilation finished successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compile built-in task will automatically look for all contracts in the contracts directory, and compile them using the Solidity compiler using the configuration in hardhat.config.js.&lt;/p&gt;

&lt;p&gt;You will notice an artifacts directory was created: it holds the compiled artifacts (bytecode and metadata), which are .json files. It’s a good idea to add this directory to your .gitignore.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Adding more contracts&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;As your project grows, you will begin to create more contracts that interact with each other: each one should be stored in its own .sol file.&lt;/p&gt;

&lt;p&gt;To see how this looks, let’s add a simple access control system to our Box contract: we will store an administrator address in a contract called Auth, and only let Box be used by those accounts that Auth allows.&lt;/p&gt;

&lt;p&gt;Because the compiler will pick up all files in the contracts directory and subdirectories, you are free to organize your code as you see fit. Here, we’ll store the Auth contract in an access-control subdirectory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/access-control/Auth.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Auth {
    address private _administrator;

    constructor(address deployer) {
        // Make the deployer of the contract the administrator
        _administrator = deployer;
    }

    function isAdministrator(address user) public view returns (bool) {
        return user == _administrator;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Separating concerns across multiple contracts is a great way to keep each one simple, and is generally a good practice.&lt;/p&gt;

&lt;p&gt;However, this is not the only way to split your code into modules. You can also use inheritance for encapsulation and code reuse in Solidity, as we’ll see next.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Using OpenZeppelin Contracts&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Reusable modules and libraries are the cornerstone of great software. OpenZeppelin Contracts contains lots of useful building blocks for smart contracts to build on. And you can rest easy when building on them: they’ve been the subject of multiple audits, with their security and correctness battle-tested.&lt;/p&gt;

&lt;p&gt;Importing OpenZeppelin Contracts&lt;br&gt;
The latest published release of the OpenZeppelin Contracts library can be downloaded by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install @openzeppelin/contracts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use one of the OpenZeppelin Contracts, import it by prefixing its path with @openzeppelin/contracts. For example, in order to replace our own Auth contract, we will import @openzeppelin/contracts/access/Ownable.sol to add access control to Box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Import Ownable from the OpenZeppelin Contracts library
import "@openzeppelin/contracts/access/Ownable.sol";

// Make Box inherit from the Ownable contract
contract Box is Ownable {
    uint256 private _value;

    event ValueChanged(uint256 value);

    // The onlyOwner modifier restricts who can call the store function
    function store(uint256 value) public onlyOwner {
        _value = value;
        emit ValueChanged(value);
    }

    function retrieve() public view returns (uint256) {
        return _value;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The OpenZeppelin Contracts documentation is a great place to learn about developing secure smart contract systems. It features both guides and a detailed API reference: see for example the Access Control guide to know more about the Ownable contract used in the code sample above.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• OpenZeppelin Tutorials 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/OpenZeppelin_CN"&gt;OpenZeppelin 教程 : github.com/565ee/OpenZeppelin_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_11997496.html"&gt;OpenZeppelin 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/OpenZeppelin_EN"&gt;OpenZeppelin Tutorials : github.com/565ee/OpenZeppelin_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>openzeppelin</category>
    </item>
    <item>
      <title>11L ethereum hardhat : Mining Modes</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Wed, 27 Jul 2022 18:00:24 +0000</pubDate>
      <link>https://forem.com/565ee/11l-ethereum-hardhat-mining-modes-3nae</link>
      <guid>https://forem.com/565ee/11l-ethereum-hardhat-mining-modes-3nae</guid>
      <description>&lt;p&gt;• introduce&lt;br&gt;&lt;br&gt;
• Mempool behavior&lt;br&gt;&lt;br&gt;
• Mining transactions in FIFO order&lt;br&gt;&lt;br&gt;
• Removing and replacing transactions&lt;br&gt;&lt;br&gt;
• Using RPC methods&lt;br&gt;&lt;br&gt;
• hardhat Tutorials , hardhat 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• introduce&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Hardhat Network can be configured to &lt;strong&gt;automine&lt;/strong&gt; blocks, immediately upon receiving each transaction, or it can be configured for &lt;strong&gt;interval mining&lt;/strong&gt;, where a new block is mined periodically, incorporating as many pending transactions as possible.&lt;/p&gt;

&lt;p&gt;You can use one of these modes, both or neither. By default, only the automine mode is enabled.&lt;/p&gt;

&lt;p&gt;When automine is disabled, every sent transaction is added to the mempool, which contains all the transactions that could be mined in the future. By default, Hardhat Network's mempool follows the same rules as Geth. This means, among other things, that transactions are prioritized by fees paid to the miner (and then by arrival time), and that invalid transactions are dropped. In addition to the default mempool behavior, an &lt;a href="//../reference/index.md#transaction-ordering"&gt;alternative FIFO behavior is also available&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When automine is disabled, pending transactions can be queried via the &lt;code&gt;eth_getBlockByNumber&lt;/code&gt; RPC method (with &lt;code&gt;"pending"&lt;/code&gt; as the block number argument), they can be removed using the &lt;code&gt;hardhat_dropTransaction&lt;/code&gt; RPC method, and they can be replaced by submitting a new transaction with the same nonce but with a 10+% increase in fees paid to the miner.&lt;/p&gt;

&lt;p&gt;If neither mining mode is enabled, no new blocks will be mined, but you can manually mine new blocks using the &lt;code&gt;evm_mine&lt;/code&gt; RPC method. This will generate a new block that will include as many pending transactions as possible.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• Mempool behavior&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;When automine is disabled, every sent transaction is added to the mempool, which contains all the transactions that could be mined in the future. By default, Hardhat Network's mempool follows the same rules as Geth. This means, among other things, that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transactions with a higher gas price are included first&lt;/li&gt;
&lt;li&gt;If two transactions can be included and both are offering the miner the same total fees, the one that was received first is included first&lt;/li&gt;
&lt;li&gt;If a transaction is invalid (for example, its nonce is lower than the nonce of the address that sent it), the transaction is dropped.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can get the list of pending transactions that will be included in the next block by using the "pending" block tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pendingBlock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eth_getBlockByNumber&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Mining transactions in FIFO order&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;The way Hardhat Network's mempool orders transactions is customizable. By default, they are prioritized following Geth's rules, but you can enable a FIFO behavior instead, which ensures that transactions are added to blocks in the same order they are sent, and which is useful to recreate blocks from other networks.&lt;/p&gt;

&lt;p&gt;You can enable the FIFO behavior in your config with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;networks:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;hardhat:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;mining:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;mempool:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;order:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fifo"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Removing and replacing transactions&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Transactions in the mempool can be removed using the &lt;a href="https://dev.to/hardhat-network-helpers/docs/reference#droptransaction(txhash)"&gt;&lt;code&gt;dropTransaction&lt;/code&gt;&lt;/a&gt; network helper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;txHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xabc...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;helpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dropTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;txHash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also replace a transaction by sending a new one with the same nonce as the one that it's already in the mempool but with a higher gas price. Keep in mind that, like in Geth, for this to work the new gas/fees prices have to be at least 10% higher than the gas price of the current transaction.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Using RPC methods&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;You can change the mining behavior at runtime using two RPC methods: &lt;code&gt;evm_setAutomine&lt;/code&gt; and &lt;code&gt;evm_setIntervalMining&lt;/code&gt;. For example, to disable automining:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;evm_setAutomine&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to enable interval mining:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;evm_setIntervalMining&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• hardhat Tutorials , hardhat 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/hardhat_CN"&gt;hardhat 教程 : github.com/565ee/hardhat_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_11923442.html"&gt;hardhat 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/hardhat_EN"&gt;hardhat Tutorials : github.com/565ee/hardhat_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>hardhat</category>
    </item>
    <item>
      <title>11J ethereum hardhat : Forking other networks</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Wed, 27 Jul 2022 16:08:42 +0000</pubDate>
      <link>https://forem.com/565ee/11j-ethereum-hardhat-forking-other-networks-433e</link>
      <guid>https://forem.com/565ee/11j-ethereum-hardhat-forking-other-networks-433e</guid>
      <description>&lt;p&gt;• Forking from mainnet&lt;br&gt;&lt;br&gt;
• Pinning a block&lt;br&gt;&lt;br&gt;
• Custom HTTP headers&lt;br&gt;&lt;br&gt;
• Impersonating accounts&lt;br&gt;&lt;br&gt;
• Resetting the fork&lt;br&gt;&lt;br&gt;
• Using a custom hardfork history&lt;br&gt;&lt;br&gt;
• hardhat Tutorials , hardhat 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• Forking from mainnet&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;The easiest way to try this feature is to start a node from the command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat node --fork https://eth-mainnet.alchemyapi.io/v2/&amp;lt;key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also configure Hardhat Network to always do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;hardhat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;forking&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://eth-mainnet.alchemyapi.io/v2/&amp;lt;key&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note that you'll need to replace the &lt;code&gt;&amp;lt;key&amp;gt;&lt;/code&gt; component of the URL with your personal Alchemy API key.)&lt;/p&gt;

&lt;p&gt;By accessing any state that exists on mainnet, Hardhat Network will pull the data and expose it transparently as if it was available locally.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• Pinning a block&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Hardhat Network will by default fork from the latest mainnet block. While this might be practical depending on the context, to set up a test suite that depends on forking we recommend forking from a specific block number.&lt;/p&gt;

&lt;p&gt;There are two reasons for this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The state your tests run against may change between runs. This could cause your tests or scripts to behave differently.&lt;/li&gt;
&lt;li&gt;Pinning enables caching. Every time data is fetched from mainnet, Hardhat Network caches it on disk to speed up future access. If you don't pin the block, there's going to be new data with each new block and the cache won't be useful. We measured up to 20x speed improvements with block pinning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;You will need access to a node with archival data for this to work.&lt;/strong&gt; This is why we recommend [Alchemy], since their free plans include archival data.&lt;/p&gt;

&lt;p&gt;To pin the block number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;hardhat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;forking&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://eth-mainnet.alchemyapi.io/v2/&amp;lt;key&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;blockNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14390000&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using the &lt;code&gt;node&lt;/code&gt; task, you can also specify a block number with the &lt;code&gt;--fork-block-number&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat node --fork https://eth-mainnet.alchemyapi.io/v2/&amp;lt;key&amp;gt; --fork-block-number 14390000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Custom HTTP headers&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;You can add extra HTTP headers that will be used in any request made to the forked node. One reason to do this is for authorization: instead of including your credentials in the URL, you can use a bearer token via a custom HTTP header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;hardhat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;forking&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://ethnode.example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;httpHeaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bearer &amp;lt;key&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Impersonating accounts&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Hardhat Network allows you to impersonate any address. This lets you send transactions from that account even if you don't have access to its private key.&lt;/p&gt;

&lt;p&gt;The easiest way to do this is with the &lt;code&gt;ethers.getImpersonatedSigner&lt;/code&gt; method, which is added to the &lt;code&gt;ethers&lt;/code&gt; object by the &lt;a href="https://dev.to/hardhat-runner/plugins/nomiclabs-hardhat-ethers"&gt;&lt;code&gt;hardhat-ethers&lt;/code&gt;&lt;/a&gt; plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;impersonatedSigner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getImpersonatedSigner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x1234567890123456789012345678901234567890&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;impersonatedSigner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendTransaction&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can use the &lt;a href="https://dev.to/hardhat-network-helpers/docs/reference#impersonateaccount(address)"&gt;&lt;code&gt;impersonateAccount&lt;/code&gt;&lt;/a&gt; helper and then obtain the signer for that address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;helpers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@nomicfoundation/hardhat-network-helpers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x1234567890123456789012345678901234567890&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;helpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;impersonateAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;impersonatedSigner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getSigner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Resetting the fork&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;You can manipulate forking during runtime to reset back to a fresh forked state, fork from another block number or disable forking by calling &lt;code&gt;hardhat_reset&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat_reset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;forking&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;jsonRpcUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://eth-mainnet.alchemyapi.io/v2/&amp;lt;key&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;blockNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14390000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can disable forking by passing empty params:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hardhat_reset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will reset Hardhat Network, starting a new instance in the state described &lt;a href="//../reference/#initial-state"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index6"&gt;• Using a custom hardfork history&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;If you're forking an unusual network, and if you want to execute EVM code in the context of a historical block retrieved from that network, then you will need to configure Hardhat Network to know which hardforks to apply to which blocks. (If you're forking a well-known network, Hardhat Network will automatically choose the right hardfork for the execution of your EVM code, based on known histories of public networks, so you can safely ignore this section.)&lt;/p&gt;

&lt;p&gt;To supply Hardhat Network with a hardfork activation history for your custom chain, use the &lt;code&gt;networks.hardhat.chains&lt;/code&gt; config field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;hardhat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;chains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;hardforkHistory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;berlin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;london&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this context, a "historical block" is one whose number is prior to the block you forked from. If you try to run code in the context of a historical block, &lt;em&gt;without&lt;/em&gt; having a hardfork history, then an error will be thrown. The known hardfork histories of most public networks are assumed as defaults.&lt;/p&gt;

&lt;p&gt;If you run code in the context of a &lt;em&gt;non&lt;/em&gt;-historical block, then Hardhat Network will simply use the hardfork specified by the &lt;code&gt;hardfork&lt;/code&gt; field on its config, eg &lt;code&gt;networks: { hardhat: { hardfork: "london" } }&lt;/code&gt;, rather than consulting the hardfork history configuration.&lt;/p&gt;

&lt;p&gt;See also &lt;a href="//../reference/#chains"&gt;the &lt;code&gt;chains&lt;/code&gt; entry in the Hardhat Network configuration reference&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• hardhat Tutorials , hardhat 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/hardhat_CN"&gt;hardhat 教程 : github.com/565ee/hardhat_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_11923442.html"&gt;hardhat 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/hardhat_EN"&gt;hardhat Tutorials : github.com/565ee/hardhat_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>hardhat</category>
    </item>
    <item>
      <title>11H ethereum hardhat : Hardhat Network</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Tue, 26 Jul 2022 18:33:34 +0000</pubDate>
      <link>https://forem.com/565ee/11h-ethereum-hardhat-hardhat-network-42md</link>
      <guid>https://forem.com/565ee/11h-ethereum-hardhat-hardhat-network-42md</guid>
      <description>&lt;p&gt;• How does it work?&lt;br&gt;&lt;br&gt;
• How can I use it?&lt;br&gt;&lt;br&gt;
• Running stand-alone in order to support wallets and other software&lt;br&gt;&lt;br&gt;
• Solidity stack traces&lt;br&gt;&lt;br&gt;
• Automatic error messages&lt;br&gt;&lt;br&gt;
• Mainnet forking&lt;br&gt;&lt;br&gt;
• Mining modes&lt;br&gt;&lt;br&gt;
• Logging&lt;br&gt;&lt;br&gt;
• hardhat Tutorials , hardhat 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• How does it work?&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;It runs as either an in-process or stand-alone daemon, servicing JSON-RPC and WebSocket requests.&lt;/p&gt;

&lt;p&gt;By default, it mines a block with each transaction that it receives, in order and with no delay.&lt;/p&gt;

&lt;p&gt;It's backed by the &lt;code&gt;@ethereumjs/vm&lt;/code&gt; EVM implementation, the same one used by ganache, Remix and Ethereum Studio.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• How can I use it?&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;By default, if you're using Hardhat, then you're already using Hardhat Network.&lt;/p&gt;

&lt;p&gt;When Hardhat executes your tests, scripts or tasks, an in-process Hardhat Network node is started automatically, and all of Hardhat's plugins (ethers.js, web3.js, Waffle, Truffle, etc) will connect directly to this node's provider.&lt;/p&gt;

&lt;p&gt;There's no need to make any changes to your tests or scripts.&lt;/p&gt;

&lt;p&gt;Hardhat Network is simply another network. If you wanted to be explicit, you could run, for example, &lt;code&gt;npx hardhat run --network hardhat scripts/my-script.js&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Running stand-alone in order to support wallets and other software&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Alternatively, Hardhat Network can run in a stand-alone fashion so that external clients can connect to it. This could be MetaMask, your Dapp front-end, or a script. To run Hardhat Network in this way, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx hardhat node
Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/

Accounts
========
Account #0: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 (10000 ETH)
Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

Account #1: 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 (10000 ETH)
Private Key: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start Hardhat Network, and expose it as a JSON-RPC and WebSocket server.&lt;/p&gt;

&lt;p&gt;Then, just connect your wallet or application to &lt;code&gt;http://127.0.0.1:8545&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want to connect Hardhat to this node, you just need to run using &lt;code&gt;--network localhost&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Solidity stack traces&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Hardhat Network has first-class Solidity support. It always knows which smart contracts are being run, what they do exactly and why they fail.&lt;/p&gt;

&lt;p&gt;If a transaction or call fails, Hardhat Network will throw an exception. This exception will have a combined JavaScript and Solidity stack trace: stack traces that start in JavaScript/TypeScript up to your call to the contract, and continue with the full Solidity call stack.&lt;/p&gt;

&lt;p&gt;This is an example of a Hardhat Network exception using &lt;code&gt;TruffleContract&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Transaction reverted: function selector was not recognized and there's no fallback function
  at ERC721Mock.&amp;lt;unrecognized-selector&amp;gt; (contracts/mocks/ERC721Mock.sol:9)
  at ERC721Mock._checkOnERC721Received (contracts/token/ERC721/ERC721.sol:334)
  at ERC721Mock._safeTransferFrom (contracts/token/ERC721/ERC721.sol:196)
  at ERC721Mock.safeTransferFrom (contracts/token/ERC721/ERC721.sol:179)
  at ERC721Mock.safeTransferFrom (contracts/token/ERC721/ERC721.sol:162)
  at TruffleContract.safeTransferFrom (node_modules/@nomiclabs/truffle-contract/lib/execute.js:157:24)
  at Context.&amp;lt;anonymous&amp;gt; (test/token/ERC721/ERC721.behavior.js:321:26)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last two lines correspond to the JavaScript test code that executed a failing transaction. The rest is the Solidity stack trace. This way you know exactly why your tests aren't passing.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Automatic error messages&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Hardhat Network always knows why your transaction or call failed, and it uses this information to make debugging your contracts easier.&lt;/p&gt;

&lt;p&gt;When a transaction fails without a reason, Hardhat Network will create a clear error message in the following cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Calling a non-payable function with ETH&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sending ETH to a contract without a payable fallback or receive function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calling a non-existent function when there's no fallback function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calling a function with incorrect parameters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calling an external function that doesn't return the right amount of data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calling an external function on a non-contract account&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Failing to execute an external call because of its parameters (e.g. trying to send too much ETH)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calling a library without &lt;code&gt;DELEGATECALL&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incorrectly calling a precompiled contract&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trying to deploy a contract that exceeds the bytecode size limit imposed by &lt;a href="https://eips.ethereum.org/EIPS/eip-170"&gt;EIP-170&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;span id="index6"&gt;• Mainnet forking&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Hardhat Network has the ability to copy the state of the mainnet blockchain into your local environment, including all balances and deployed contracts. This is known as "forking mainnet."&lt;/p&gt;

&lt;p&gt;In a local environment forked from mainnet, you can execute transactions to invoke mainnet-deployed contracts, or interact with the network in any other way that you would with mainnet. In addition, you can do anything supported by a non-forked Hardhat Network: see console logs, get stack traces, or use the default accounts to deploy new contracts.&lt;/p&gt;

&lt;p&gt;More generally, Hardhat Network can be used to fork &lt;strong&gt;any&lt;/strong&gt; network, not just mainnet. Even further, Hardhat Network can be used to fork &lt;strong&gt;any EVM-compatible blockchain&lt;/strong&gt;, not just Ethereum.&lt;/p&gt;

&lt;p&gt;There are other things you can do with a forked Hardhat Network. Check &lt;a href="//guides/forking-other-networks.md"&gt;our guide&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index7"&gt;• Mining modes&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Hardhat Network can be configured to &lt;strong&gt;automine&lt;/strong&gt; blocks, immediately upon receiving each transaction, or it can be configured for &lt;strong&gt;interval mining&lt;/strong&gt;, where a new block is mined periodically, incorporating as many pending transactions as possible.&lt;/p&gt;

&lt;p&gt;You can use one of these modes, both or neither. By default, only the automine mode is enabled.&lt;/p&gt;

&lt;p&gt;If neither mining mode is enabled, no new blocks will be mined, but you can manually mine new blocks using the &lt;code&gt;evm_mine&lt;/code&gt; RPC method. This will generate a new block that will include as many pending transactions as possible.&lt;/p&gt;

&lt;p&gt;For more details on mining modes and mempool behavior, see &lt;a href="//explanation/mining-modes.md"&gt;Mining Modes&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index8"&gt;• Logging&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Hardhat Network uses its tracing infrastructure to offer rich logging that will help you develop and debug smart contracts.&lt;/p&gt;

&lt;p&gt;For example, a successful transaction and a failed call would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eth_sendTransaction
  Contract deployment: Greeter
  Contract address: 0x8858eeb3dfffa017d4bce9801d340d36cf895ccf
  Transaction: 0x7ea2754e53f09508d42bd3074046f90595bedd61fcdf75a4764453454733add0
  From: 0xc783df8a850f42e7f7e57013759c285caa701eb6
  Value: 0 ETH
  Gas used: 568851 of 2844255
  Block: #2 - Hash: 0x4847b316b12170c576999183da927c2f2056aa7d8f49f6e87430e6654a56dab0

  console.log:
    Deploying a Greeter with greeting: Hello, world!

eth_call
  Contract call: Greeter#greet
  From: 0xc783df8a850f42e7f7e57013759c285caa701eb6

  Error: VM Exception while processing transaction: revert Not feeling like it
      at Greeter.greet (contracts/Greeter.sol:14)
      at process._tickCallback (internal/process/next_tick.js:68:7)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This logging is enabled by default when using Hardhat Network's node (i.e. &lt;code&gt;npx hardhat node&lt;/code&gt;), but disabled when using the in-process Hardhat Network provider. See &lt;a href="//./reference#config"&gt;Hardhat Network's config&lt;/a&gt; to learn more about how to control its logging.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• hardhat Tutorials , hardhat 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/hardhat_CN"&gt;hardhat 教程 : github.com/565ee/hardhat_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_11923442.html"&gt;hardhat 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/hardhat_EN"&gt;hardhat Tutorials : github.com/565ee/hardhat_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>hardhat</category>
    </item>
    <item>
      <title>11F ethereum hardhat : Building plugins</title>
      <dc:creator>565.ee</dc:creator>
      <pubDate>Mon, 25 Jul 2022 17:24:15 +0000</pubDate>
      <link>https://forem.com/565ee/11f-ethereum-hardhat-building-plugins-1lm4</link>
      <guid>https://forem.com/565ee/11f-ethereum-hardhat-building-plugins-1lm4</guid>
      <description>&lt;p&gt;• introduce&lt;br&gt;&lt;br&gt;
• Extending the Hardhat Runtime Environment&lt;br&gt;&lt;br&gt;
• Using the Hardhat TypeScript plugin boilerplate&lt;br&gt;&lt;br&gt;
• Throwing errors from your plugins&lt;br&gt;&lt;br&gt;
• Optimizing your plugin for better startup time&lt;br&gt;&lt;br&gt;
• Hooking into the user's workflow&lt;br&gt;&lt;br&gt;
• hardhat Tutorials , hardhat 教程&lt;br&gt;&lt;br&gt;
• Contact 联系方式&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index1"&gt;• introduce&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;In this section, we will explore the creation of plugins for Hardhat, which are the key component for integrating other tools and extending the built-in functionality.&lt;/p&gt;

&lt;p&gt;Plugins are bits of reusable configuration. Anything that you can do in a plugin can also be done in your config file. You can test your ideas in a config file and then move them into a plugin when ready.&lt;/p&gt;

&lt;p&gt;When developing a plugin the main tools available to integrate new functionality are extending the &lt;a href="///advanced/hardhat-runtime-environment.md"&gt;Hardhat Runtime Environment&lt;/a&gt;, extending the Hardhat config, defining new tasks and overriding existing ones, which are all configuration actions achieved through code.&lt;/p&gt;

&lt;p&gt;Some examples of things you could achieve by creating a plugin are: running a linter when the &lt;code&gt;check&lt;/code&gt; task runs, using different compiler versions for different files or generating an UML diagram for your contracts.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;span id="index2"&gt;• Extending the Hardhat Runtime Environment&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Let’s go through the process of creating a plugin that adds new functionality to the Hardhat Runtime Environment. By doing this, we make sure our new feature is available everywhere. This means your plugin users can access it from tasks, tests, scripts, and the Hardhat console.&lt;/p&gt;

&lt;p&gt;The Hardhat Runtime Environment (HRE) is configured through a queue of extension functions that you can add to using the &lt;code&gt;extendEnvironment()&lt;/code&gt; function. It receives one parameter which is a callback which will be executed after the HRE is initialized. If &lt;code&gt;extendEnvironment&lt;/code&gt; is called multiple times, its callbacks will be executed in order.&lt;/p&gt;

&lt;p&gt;For example, adding the following to &lt;code&gt;hardhat.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;extendEnvironment&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;hre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;hre&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, Hardhat!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will make &lt;code&gt;hi&lt;/code&gt; available everywhere where the environment is accessible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;extendEnvironment&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;hre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;hre&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, Hardhat!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;envtest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hre&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hi&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will yield:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx hardhat envtest
Hello, Hardhat!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is literally all it takes to put together a plugin for Hardhat. Now &lt;code&gt;hi&lt;/code&gt; is available to be used in the Hardhat console, your tasks, tests and other plugins.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index3"&gt;• Using the Hardhat TypeScript plugin boilerplate&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;For a complete example of a plugin you can take a look at the &lt;a href="https://github.com/nomiclabs/hardhat-ts-plugin-boilerplate/"&gt;Hardhat TypeScript plugin boilerplate project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Plugins don't need to be written in TypeScript, but we recommend doing it, as many of our users use it. Creating a plugin in JavaScript can lead to a subpar experience for them.&lt;/p&gt;

&lt;p&gt;• Extending the HRE&lt;/p&gt;

&lt;p&gt;To learn how to successfully extend the &lt;a href="//./hardhat-runtime-environment.md"&gt;HRE&lt;/a&gt; in TypeScript, and to give your users type information about your extension, take a look at &lt;a href="https://github.com/nomiclabs/hardhat-ts-plugin-boilerplate/blob/master/src/index.ts"&gt;&lt;code&gt;src/index.ts&lt;/code&gt;&lt;/a&gt; in the boilerplate repo and read the &lt;a href="//./hardhat-runtime-environment.md#extending-the-hre"&gt;Extending the HRE&lt;/a&gt; documentation.&lt;/p&gt;

&lt;p&gt;Make sure to keep the type extension in your main file, as that convention is used across different plugins.&lt;/p&gt;

&lt;p&gt;• Extending the Hardhat config&lt;/p&gt;

&lt;p&gt;The boilerplate project also has an example on how to extend the Hardhat config.&lt;/p&gt;

&lt;p&gt;We strongly recommend doing this in TypeScript and properly extending the config types.&lt;/p&gt;

&lt;p&gt;An example on how to add fields to the Hardhat config can be found in &lt;a href="https://github.com/nomiclabs/hardhat-ts-plugin-boilerplate/blob/master/src/index.ts"&gt;&lt;code&gt;src/index.ts&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index4"&gt;• Throwing errors from your plugins&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;To show better stack traces to your users when an error is meant to interrupt a task's execution, please consider throwing &lt;code&gt;HardhatPluginError&lt;/code&gt; errors, which can be found in &lt;code&gt;hardhat/plugins&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If your error originated in your user's code, like a test or script calling one of your functions, you shouldn't use &lt;code&gt;HardhatPluginError&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index5"&gt;• Optimizing your plugin for better startup time&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Keeping startup time short is vital to give a good user experience.&lt;/p&gt;

&lt;p&gt;To do so, Hardhat and its plugins delay any slow import or initialization until the very last moment. To do so, you can use &lt;code&gt;lazyObject&lt;/code&gt;, and &lt;code&gt;lazyFunction&lt;/code&gt; from &lt;code&gt;hardhat/plugins&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;An example on how to use them is present in &lt;a href="https://github.com/nomiclabs/hardhat-ts-plugin-boilerplate/blob/master/src/index.ts"&gt;&lt;code&gt;src/index.ts&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes on dependencies
&lt;/h2&gt;

&lt;p&gt;Knowing when to use a &lt;code&gt;dependency&lt;/code&gt; or a &lt;code&gt;peerDependency&lt;/code&gt; can be tricky. We recommend &lt;a href="https://yarnpkg.com/blog/2018/04/18/dependencies-done-right/"&gt;these&lt;/a&gt; &lt;a href="https://lexi-lambda.github.io/blog/2016/08/24/understanding-the-npm-dependency-model/"&gt;articles&lt;/a&gt; to learn about their distinctions.&lt;/p&gt;

&lt;p&gt;If you are still in doubt, these can be helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule of thumb #1:&lt;/strong&gt; Hardhat MUST be a peer dependency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule of thumb #2:&lt;/strong&gt; If your plugin P depends on another plugin P2, P2 should be a peer dependency of P, and P2's peer dependencies should be peer dependencies of P.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule of thumb #3:&lt;/strong&gt; If you have a non-Hardhat dependency that your users may &lt;code&gt;require()&lt;/code&gt;, it should be a peer dependency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule of thumb #4:&lt;/strong&gt; Every &lt;code&gt;peerDependency&lt;/code&gt; should also be a &lt;code&gt;devDependency&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;span id="index6"&gt;• Hooking into the user's workflow&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;To integrate into your users' existing workflow, we recommend that plugin authors override built-in tasks whenever it makes sense.&lt;/p&gt;

&lt;p&gt;Examples of suggested overrides are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preprocessing smart contracts should override one of the &lt;code&gt;compile&lt;/code&gt; subtasks.&lt;/li&gt;
&lt;li&gt;Linter integrations should override the &lt;code&gt;check&lt;/code&gt; task.&lt;/li&gt;
&lt;li&gt;Plugins generating intermediate files should override the &lt;code&gt;clean&lt;/code&gt; task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a list of all the built-in tasks and subtasks please take a look at &lt;a href="https://github.com/nomiclabs/hardhat/blob/master/packages/hardhat-core/src/builtin-tasks/task-names.ts"&gt;&lt;code&gt;task-names.ts&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index98"&gt;• hardhat Tutorials , hardhat 教程&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;CN 中文 Github  &lt;a href="https://github.com/565ee/hardhat_CN"&gt;hardhat 教程 : github.com/565ee/hardhat_CN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CN 中文 CSDN    &lt;a href="https://blog.csdn.net/wx468116118/category_11923442.html"&gt;hardhat 教程 : blog.csdn.net/wx468116118&lt;/a&gt;&lt;br&gt;&lt;br&gt;
EN 英文 Github  &lt;a href="https://github.com/565ee/hardhat_EN"&gt;hardhat Tutorials : github.com/565ee/hardhat_EN&lt;/a&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;span id="index99"&gt;• Contact 联系方式&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;Homepage   : &lt;a href="https://565.ee"&gt;565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub     : &lt;a href="https://github.com/565ee"&gt;github.com/565ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Email      : &lt;a href="mailto:565.eee@gmail.com"&gt;565.eee@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Facebook   : &lt;a href="https://facebook.com/565.ee"&gt;facebook.com/565.ee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Twitter    : &lt;a href="https://twitter.com/565_eee"&gt;twitter.com/565_eee&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Telegram   : &lt;a href="https://t.me/ee_565"&gt;t.me/ee_565&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>hardhat</category>
    </item>
  </channel>
</rss>
