Введение
Благодаря недавнему обновлению совместимости плагина Hardhat hardhat-web3-v4[2] Web3.Js теперь можно использовать в качестве плагина в Hardhat.
Из этого туториала вы узнаете, как использовать Web3js в качестве плагина для взаимодействия с блокчейном.
В этом руководстве предполагается, что все знают, как использовать «Написание смарт-контрактов», и умеют использовать JavaScript/TypeScript. Версия NodeJS[3] выше, чем v16.
Уведомление насиспользовать
NPM
для установки зависимостей。
Инициализировать проект защитного шлема[4] Установите необходимые зависимости(включатьhardhat-web3-v4
)[5] Написание смарт-контрактов[6] Компилируйте, тестируйте и развертывайте контракты[7] Контракты на тестирование и вызовы[8]
Создайте новую папку проекта:
$ mkdir myproject
$ cd myproject
Установите и инициализируйте Hardhat в текущем каталоге:
$ npm install hardhat
$ npx hardhat init
hardhat-web3-v4
)выбиратьTypeScript
,Выбери все остальноеYes
。Вам будет предложено установить необходимые зависимости.。отвечатьyes
Вы можете завершить установку。УстановитьHardhat-web3-v4
плагин,насиспользоватьnpm
:
npm install --save-dev @nomicfoundation/hardhat-web3-v4 'web3@4'
Это будет сделано путем включения его вnode_modules
папкаWeb3.Jsдобавить внасв проекте。хотетьиспользоватьэтотплагин РасширятьHardhatфункция,насдолженсуществоватьHardhatКонфигурационный файлhardhat.config.ts
Импортировать вweb3-v4
плагин。пожалуйстасуществовать Конфигурационный файл Топ импортаэтотсодержание。
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@nomicfoundation/hardhat-web3-v4"; // <================
const config: HardhatUserConfig = {
solidity: "0.8.19",
};
export default config;
По умолчанию,hardhat-toolbox
будет добавлено в этот файл。наснуждатьсяхотетьявновызовэтотплагин。Это изменитHardhatсреда выполнения - HRE и включает классы Web3 и созданные объекты Web3. В последнем случае мы получаем модифицированный, готовый к использованию объект web3 с инициализированным локальным/жестким хэтом. провайдер. Этот объект можно использовать в любом месте проекта, например в тестах и файлах развертывания.
Когда мы начинаем новый проект,Hardhatобеспечивает простойLock
договор。нас Можно обратиться кmyproject/contracts/Lock.sol
документ。
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
// Uncomment this line to use console.log
// import "hardhat/console.sol";
contract Lock {
uint public unlockTime;
address payable public owner;
event Withdrawal(uint amount, uint when);
constructor(uint _unlockTime) payable {
require(
block.timestamp < _unlockTime,
"Unlock time should be in the future"
);
unlockTime = _unlockTime;
owner = payable(msg.sender);
}
function withdraw() public {
// Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
// console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);
require(block.timestamp >= unlockTime, "You can't withdraw yet");
require(msg.sender == owner, "You aren't the owner");
emit Withdrawal(address(this).balance, block.timestamp);
owner.transfer(address(this).balance);
}
}
Lock.sol
это простойчасблокировка временидоговор,существоватьразвертыватьпринять любое количествоEther
,и ожидатьсуществоватьразвертыватьбудет присвоено параметрам переменной состояния。только еслиunlockTime
Нетсуществоватьбудущеечас,отмечен какowner
Адрес может пройтиwithdraw
извлечение функциидоговорвесь баланс。
•Составлять и развертывать контракты
$ npx hardhat compile
Выполнение приведенной выше команды создаст файл с именемartifacts
документпапка,Он содержит информацию о сборке и скомпилированные контракты. из этого каталога,Во время тестирования и развертывания нам понадобится так называемый Application Binary Interface — ABI.
развертыватьсмарт-контрактслова,наснуждатьсяхотеть Измените следующим образомscript/deploy.ts
。
Сначала нам нужно импортировать уже инициализированный объект web3. Затем получите артефакт:
import { web3 } from "hardhat";
import artifacts from "../artifacts/contracts/Lock.sol/Lock.json";
async function main() {
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
существоватьmain
в функции,Мы используем некоторые функции web3.js.,Например.utils
и.eth
Модуль готовразвертывать:
async function main() {
const currentTimestampInSeconds = Math.round(Date.now() / 1000);
const unlockTime = currentTimestampInSeconds + 60;
const lockedAmount = web3.utils.toWei("0.001", 'ether');
const [deployer] = await web3.eth.getAccounts();
const lockContract = new web3.eth.Contract(artifacts.abi);
const rawContract = lockContract.deploy({
data: artifacts.bytecode,
arguments: [unlockTime],
});
const lock = await rawContract.send({
from: deployer,
gasPrice: "10000000000",
value: lockedAmount.toString()
});
console.log(
`Lock with ${web3.utils.toWei(
lockedAmount,
'ether'
)}ETH and unlock timestamp ${unlockTime} deployed to ${lock.options.address}`
);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Выполнение следующей команды поместитLock
договорразвертыватьвстроить вHardhatна локальном блокчейне。насиспользоватьWeb3.jsОбщайтесь с блокчейном,Передайте данные нашего смарт-контракта в сеть.
$ npx hardhat run scripts/deploy.ts
шагом выше,Мы загрузили скомпилированный смарт-контрактразвертывание в локальную сеть блокчейна. Теперь пришло время проверить, соответствует ли наш контракт тому, что мы ожидали. Потому что мы используем Web3.js для трансляции и хранения данных в блокчейне.,Поэтому мы также используем тот же протокол для запроса и изменения данных.
использовать Замените код нижеmyproject/test/Lock.ts
содержание:
import {
time,
loadFixture,
} from "@nomicfoundation/hardhat-toolbox/network-helpers";
import { expect } from "chai";
import { web3 } from "hardhat";
import artifacts from "../artifacts/contracts/Lock.sol/Lock.json";
describe("Lock", function () {
async function deployOneYearLockFixture() {
const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
const ONE_GWEI = 1_000_000_000;
const lockedAmount = ONE_GWEI;
const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS;
const lockContract = new web3.eth.Contract(artifacts.abi);
lockContract.handleRevert = true;
const [deployer, otherAccount] = await web3.eth.getAccounts();
const rawContract = lockContract.deploy({
data: artifacts.bytecode,
arguments: [unlockTime],
});
// To know how much gas will be consumed, we can estimate it first.
const estimateGas = await rawContract.estimateGas({
from: deployer,
value: lockedAmount.toString()
});
const lock = await rawContract.send({
from: deployer,
gas: estimateGas.toString(),
gasPrice: "10000000000",
value: lockedAmount.toString()
});
console.log("Lock contract deployed to: ", lock.options.address);
return { lock, unlockTime, lockedAmount, deployer, otherAccount, rawContract };
}
describe("Deployment", function () {
it("Should set the right unlockTime", async function () {
const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
const setTime = await lock.methods.unlockTime().call();
console.log("SetTime", setTime);
expect(setTime).to.equal(unlockTime);
});
it("Should set the right deployer", async function () {
const { lock, deployer } = await loadFixture(deployOneYearLockFixture);
expect(await lock.methods.owner().call()).to.equal(deployer);
});
it("Should receive and store the funds to lock", async function () {
const { lock, lockedAmount } = await loadFixture(
deployOneYearLockFixture
);
const balance = await web3.eth.getBalance(String(lock.options.address));
expect(balance).to.equal(lockedAmount);
});
it("Shouldn't fail if the unlockTime has arrived and the deployer calls it", async function () {
const { lock, unlockTime, deployer } = await loadFixture(
deployOneYearLockFixture
);
await time.increaseTo(unlockTime);
await expect(lock.methods.withdraw().send({from: deployer})).not.to.be.reverted;
});
});
});
в этом файле,Мы выполнили тот же шаг, что и в скрипте развертывания.,использоватьdeployOneYearLockFixture()
вABI
иbytecode
Подготовитьиразвертыватьдоговор。Чтение из блокчейнаowner
данные,У нас есть пример контракта на развертывание,Прямо сейчасlock.methods.owner().call()
。вызов.call()
Не меняет состояние блокчейна,Поэтому подпись кошелька не требуется.
Чтобы изменить состояние данных, которые мы ранее сохранили,Нам нужно получить доступ к контейнеру методов нашей необходимой функциональности.,ивызов.send
Трансляция сети Лайсяннаснамерениеlock.methods.withdraw().send({from: deployer})
。
Уведомление использовать
.send()
час,насдолженсуществоватьfrom
Отправитель транзакции явно указывается в поле(существовать В приведенном выше примере эторазвертывать Адрес учетной записи пользователя)。
Для выполнения теста мы можем использовать следующую команду:
$ npx hardhat test test/Lock.ts
После этого мы получим аналогичные результаты:
/*
Lock
Deployment
Lock contract deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
SetTime 1739193193n
✔ Should set the right unlockTime (884ms)
✔ Should set the right deployer (54ms)
✔ Should receive and store the funds to lock
✔ Shouldn't fail if the unlockTime has arrived and the deployer calls it
*/
Отказ от ответственности: эта работа распространяется под лицензией Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)[9]. Пожалуйста, укажите источник при ее использовании. Автор: мэнбин[10] блог: мэнбин[11] Github: mengbin92[12] cnblogs: Непреднамеренно полюбила воду[13] Сообщество разработчиков Tencent Cloud: Мюнстер[14]
[1]
здесь: https://docs.web3js.org/guides/hardhat_tutorial/
[2]
hardhat-web3-v4: https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-web3-v4
[3]
NodeJS: https://nodejs.org/en
[4]
Инициализируйте проект защитного шлема: #Инициализируем проект защитного шлема
[5]
Установите необходимые зависимости(включатьhardhat-web3-v4
): #Установим необходимые зависимости, включая hardhat-web3-v4
[6]
Написание смарт-контрактов: #Написание смарт-контрактов
[7]
Компилируйте, тестируйте и развертывайте контракты: #Компилируем, тестируем и развертываем контракты
[8]
Протестируйте и вызовите контракт: #Проверка контракта на вызов
[9]
С указанием авторства-Некоммерческая-ShareAlike 4.0 интернациональность (CC BY-NC-SA 4.0): https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh
[10]
mengbin: mengbin1992@outlook.com
[11]
mengbin: https://mengbin.top
[12]
mengbin92: https://mengbin92.github.io/
[13]
Влюбляюсь в воду нечаянно: https://www.cnblogs.com/lianshuiwuyi/
[14]
Мюнстер: https://cloud.tencent.com/developer/user/6649301