mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
adding initialized hardhat project with precompiled Lock contrack (compilation script added), and deploy script
This commit is contained in:
parent
e1fd934e27
commit
8cd6a29c5e
13 changed files with 9173 additions and 0 deletions
17
hardhat.tmpl/.gitignore
vendored
Normal file
17
hardhat.tmpl/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
node_modules
|
||||||
|
.env
|
||||||
|
|
||||||
|
# Hardhat files
|
||||||
|
/cache
|
||||||
|
/artifacts
|
||||||
|
|
||||||
|
# TypeChain files
|
||||||
|
/typechain
|
||||||
|
/typechain-types
|
||||||
|
|
||||||
|
# solidity-coverage files
|
||||||
|
/coverage
|
||||||
|
/coverage.json
|
||||||
|
|
||||||
|
# Hardhat Ignition default folder for deployments against a local node
|
||||||
|
ignition/deployments/chain-31337
|
||||||
65
hardhat.tmpl/Lock.abi.json
Normal file
65
hardhat.tmpl/Lock.abi.json
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "_unlockTime",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "payable",
|
||||||
|
"type": "constructor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "when",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Withdrawal",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "owner",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address payable",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "unlockTime",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "withdraw",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
]
|
||||||
1
hardhat.tmpl/Lock.bytecode
Normal file
1
hardhat.tmpl/Lock.bytecode
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
60806040526040516105ac3803806105ac833981810160405281019061002591906100ea565b804210610067576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161005e90610195565b60405180910390fd5b805f819055503360015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101b3565b5f5ffd5b5f819050919050565b6100c9816100b7565b81146100d3575f5ffd5b50565b5f815190506100e4816100c0565b92915050565b5f602082840312156100ff576100fe6100b3565b5b5f61010c848285016100d6565b91505092915050565b5f82825260208201905092915050565b7f556e6c6f636b2074696d652073686f756c6420626520696e20746865206675745f8201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b5f61017f602383610115565b915061018a82610125565b604082019050919050565b5f6020820190508181035f8301526101ac81610173565b9050919050565b6103ec806101c05f395ff3fe608060405234801561000f575f5ffd5b506004361061003f575f3560e01c8063251c1aa3146100435780633ccfd60b146100615780638da5cb5b1461006b575b5f5ffd5b61004b610089565b604051610058919061023e565b60405180910390f35b61006961008e565b005b610073610201565b6040516100809190610296565b60405180910390f35b5f5481565b5f544210156100d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100c990610309565b60405180910390fd5b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610161576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161015890610371565b60405180910390fd5b7fbf2ed60bd5b5965d685680c01195c9514e4382e28e3a5a2d2d5244bf59411b93474260405161019292919061038f565b60405180910390a160015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f193505050501580156101fe573d5f5f3e3d5ffd5b50565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f819050919050565b61023881610226565b82525050565b5f6020820190506102515f83018461022f565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61028082610257565b9050919050565b61029081610276565b82525050565b5f6020820190506102a95f830184610287565b92915050565b5f82825260208201905092915050565b7f596f752063616e277420776974686472617720796574000000000000000000005f82015250565b5f6102f36016836102af565b91506102fe826102bf565b602082019050919050565b5f6020820190508181035f830152610320816102e7565b9050919050565b7f596f75206172656e277420746865206f776e65720000000000000000000000005f82015250565b5f61035b6014836102af565b915061036682610327565b602082019050919050565b5f6020820190508181035f8301526103888161034f565b9050919050565b5f6040820190506103a25f83018561022f565b6103af602083018461022f565b939250505056fea2646970667358221220203fd19cb2aac26a92e1df456e3253bc4a8a4435f19402db540a29154902d5f064736f6c634300081e0033
|
||||||
1
hardhat.tmpl/Lock.bytecode.txt
Normal file
1
hardhat.tmpl/Lock.bytecode.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
0x60806040526040516105d83803806105d8833981810160405281019061002591906100f0565b804210610067576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161005e906101a0565b60405180910390fd5b8060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101c0565b600080fd5b6000819050919050565b6100cd816100ba565b81146100d857600080fd5b50565b6000815190506100ea816100c4565b92915050565b600060208284031215610106576101056100b5565b5b6000610114848285016100db565b91505092915050565b600082825260208201905092915050565b7f556e6c6f636b2074696d652073686f756c6420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b600061018a60238361011d565b91506101958261012e565b604082019050919050565b600060208201905081810360008301526101b98161017d565b9050919050565b610409806101cf6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063251c1aa3146100465780633ccfd60b146100645780638da5cb5b1461006e575b600080fd5b61004e61008c565b60405161005b919061024a565b60405180910390f35b61006c610092565b005b61007661020b565b60405161008391906102a6565b60405180910390f35b60005481565b6000544210156100d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100ce9061031e565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610167576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161015e9061038a565b60405180910390fd5b7fbf2ed60bd5b5965d685680c01195c9514e4382e28e3a5a2d2d5244bf59411b9347426040516101989291906103aa565b60405180910390a1600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610208573d6000803e3d6000fd5b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000819050919050565b61024481610231565b82525050565b600060208201905061025f600083018461023b565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061029082610265565b9050919050565b6102a081610285565b82525050565b60006020820190506102bb6000830184610297565b92915050565b600082825260208201905092915050565b7f596f752063616e27742077697468647261772079657400000000000000000000600082015250565b60006103086016836102c1565b9150610313826102d2565b602082019050919050565b60006020820190508181036000830152610337816102fb565b9050919050565b7f596f75206172656e277420746865206f776e6572000000000000000000000000600082015250565b60006103746014836102c1565b915061037f8261033e565b602082019050919050565b600060208201905081810360008301526103a381610367565b9050919050565b60006040820190506103bf600083018561023b565b6103cc602083018461023b565b939250505056fea26469706673582212202d2006ef26cbefcc4deab66c32f5ff5efb638f080c7490b6633879942caf232764736f6c634300081c0033
|
||||||
13
hardhat.tmpl/README.md
Normal file
13
hardhat.tmpl/README.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Sample Hardhat Project
|
||||||
|
|
||||||
|
This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract.
|
||||||
|
|
||||||
|
Try running some of the following tasks:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npx hardhat help
|
||||||
|
npx hardhat test
|
||||||
|
REPORT_GAS=true npx hardhat test
|
||||||
|
npx hardhat node
|
||||||
|
npx hardhat ignition deploy ./ignition/modules/Lock.js
|
||||||
|
```
|
||||||
36
hardhat.tmpl/compile.js
Normal file
36
hardhat.tmpl/compile.js
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
const solc = require('solc');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
// ✅ Path to the Solidity contract
|
||||||
|
const contractPath = path.resolve(__dirname, 'contracts', 'Lock.sol');
|
||||||
|
|
||||||
|
// ✅ Read contract source
|
||||||
|
const source = fs.readFileSync(contractPath, 'utf8');
|
||||||
|
|
||||||
|
// Solidity compiler input format
|
||||||
|
const input = {
|
||||||
|
language: 'Solidity',
|
||||||
|
sources: {
|
||||||
|
'Lock.sol': {
|
||||||
|
content: source
|
||||||
|
}
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
outputSelection: {
|
||||||
|
'*': {
|
||||||
|
'*': ['abi', 'evm.bytecode.object']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const output = JSON.parse(solc.compile(JSON.stringify(input)));
|
||||||
|
const contract = output.contracts['Lock.sol']['Lock'];
|
||||||
|
|
||||||
|
// Save ABI and bytecode
|
||||||
|
fs.writeFileSync('Lock.abi.json', JSON.stringify(contract.abi, null, 2));
|
||||||
|
fs.writeFileSync('Lock.bytecode', contract.evm.bytecode.object);
|
||||||
|
|
||||||
|
console.log('✅ Contract compiled. ABI and bytecode saved.');
|
||||||
|
|
||||||
34
hardhat.tmpl/contracts/Lock.sol
Normal file
34
hardhat.tmpl/contracts/Lock.sol
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
|
pragma solidity ^0.8.28;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
35
hardhat.tmpl/deploy.js
Normal file
35
hardhat.tmpl/deploy.js
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
const Web3 = require('web3');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
// Connect to local Geth devnet
|
||||||
|
const web3 = new Web3.default('http://localhost:8545');
|
||||||
|
|
||||||
|
// Load compiled contract
|
||||||
|
const abi = JSON.parse(fs.readFileSync('Lock.abi.json'));
|
||||||
|
const bytecode = fs.readFileSync('Lock.bytecode', 'utf8');
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const accounts = await web3.eth.getAccounts();
|
||||||
|
const deployer = accounts[0];
|
||||||
|
|
||||||
|
console.log('Deploying from account:', deployer);
|
||||||
|
|
||||||
|
const unlockTime = Math.floor(Date.now() / 1000) + 60;
|
||||||
|
|
||||||
|
const contract = new web3.eth.Contract(abi);
|
||||||
|
const tx = contract.deploy({
|
||||||
|
data: '0x' + bytecode,
|
||||||
|
arguments: [unlockTime]
|
||||||
|
});
|
||||||
|
|
||||||
|
const deployed = await tx.send({
|
||||||
|
from: deployer,
|
||||||
|
value: web3.utils.toWei('1', 'ether'),
|
||||||
|
gas: 3000000
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Contract deployed at:', deployed.options.address);
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch(console.error);
|
||||||
|
|
||||||
11
hardhat.tmpl/hardhat.config.js
Normal file
11
hardhat.tmpl/hardhat.config.js
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
require("@nomicfoundation/hardhat-toolbox");
|
||||||
|
|
||||||
|
/** @type import('hardhat/config').HardhatUserConfig */
|
||||||
|
module.exports = {
|
||||||
|
solidity: "0.8.28",
|
||||||
|
networks: {
|
||||||
|
localhost: {
|
||||||
|
url: "http://127.0.0.1:8545"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
18
hardhat.tmpl/ignition/modules/Lock.js
Normal file
18
hardhat.tmpl/ignition/modules/Lock.js
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// This setup uses Hardhat Ignition to manage smart contract deployments.
|
||||||
|
// Learn more about it at https://hardhat.org/ignition
|
||||||
|
|
||||||
|
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");
|
||||||
|
|
||||||
|
const JAN_1ST_2030 = 1893456000;
|
||||||
|
const ONE_GWEI = 1_000_000_000n;
|
||||||
|
|
||||||
|
module.exports = buildModule("LockModule", (m) => {
|
||||||
|
const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030);
|
||||||
|
const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI);
|
||||||
|
|
||||||
|
const lock = m.contract("Lock", [unlockTime], {
|
||||||
|
value: lockedAmount,
|
||||||
|
});
|
||||||
|
|
||||||
|
return { lock };
|
||||||
|
});
|
||||||
8443
hardhat.tmpl/package-lock.json
generated
Normal file
8443
hardhat.tmpl/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
373
hardhat.tmpl/package.json
Normal file
373
hardhat.tmpl/package.json
Normal file
|
|
@ -0,0 +1,373 @@
|
||||||
|
{
|
||||||
|
"name": "hardhat",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract.",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
|
||||||
|
"hardhat": "^2.24.0"
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"test": "test"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"abbrev": "^1.0.9",
|
||||||
|
"acorn": "^8.14.1",
|
||||||
|
"acorn-walk": "^8.3.4",
|
||||||
|
"adm-zip": "^0.4.16",
|
||||||
|
"aes-js": "^4.0.0-beta.5",
|
||||||
|
"agent-base": "^6.0.2",
|
||||||
|
"aggregate-error": "^3.1.0",
|
||||||
|
"ajv": "^8.17.1",
|
||||||
|
"amdefine": "^1.0.1",
|
||||||
|
"ansi-align": "^3.0.1",
|
||||||
|
"ansi-colors": "^4.1.3",
|
||||||
|
"ansi-escapes": "^4.3.2",
|
||||||
|
"ansi-regex": "^5.0.1",
|
||||||
|
"ansi-styles": "^4.3.0",
|
||||||
|
"antlr4ts": "^0.5.0-alpha.4",
|
||||||
|
"anymatch": "^3.1.3",
|
||||||
|
"arg": "^4.1.3",
|
||||||
|
"argparse": "^2.0.1",
|
||||||
|
"array-back": "^3.1.0",
|
||||||
|
"array-union": "^2.1.0",
|
||||||
|
"array-uniq": "^1.0.3",
|
||||||
|
"asap": "^2.0.6",
|
||||||
|
"assertion-error": "^1.1.0",
|
||||||
|
"astral-regex": "^2.0.0",
|
||||||
|
"async": "^1.5.2",
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"at-least-node": "^1.0.0",
|
||||||
|
"axios": "^1.9.0",
|
||||||
|
"balanced-match": "^1.0.2",
|
||||||
|
"base-x": "^3.0.11",
|
||||||
|
"bech32": "^1.1.4",
|
||||||
|
"binary-extensions": "^2.3.0",
|
||||||
|
"blakejs": "^1.2.1",
|
||||||
|
"bn.js": "^5.2.2",
|
||||||
|
"boxen": "^5.1.2",
|
||||||
|
"brace-expansion": "^2.0.1",
|
||||||
|
"braces": "^3.0.3",
|
||||||
|
"brorand": "^1.1.0",
|
||||||
|
"browser-stdout": "^1.3.1",
|
||||||
|
"browserify-aes": "^1.2.0",
|
||||||
|
"bs58": "^4.0.1",
|
||||||
|
"bs58check": "^2.1.2",
|
||||||
|
"buffer-from": "^1.1.2",
|
||||||
|
"buffer-xor": "^1.0.3",
|
||||||
|
"bytes": "^3.1.2",
|
||||||
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
|
"call-bound": "^1.0.4",
|
||||||
|
"camelcase": "^6.3.0",
|
||||||
|
"caseless": "^0.12.0",
|
||||||
|
"cbor": "^8.1.0",
|
||||||
|
"chai": "^4.5.0",
|
||||||
|
"chai-as-promised": "^7.1.2",
|
||||||
|
"chalk": "^4.1.2",
|
||||||
|
"charenc": "^0.0.2",
|
||||||
|
"check-error": "^1.0.3",
|
||||||
|
"chokidar": "^4.0.3",
|
||||||
|
"ci-info": "^2.0.0",
|
||||||
|
"cipher-base": "^1.0.6",
|
||||||
|
"clean-stack": "^2.2.0",
|
||||||
|
"cli-boxes": "^2.2.1",
|
||||||
|
"cli-table3": "^0.5.1",
|
||||||
|
"cliui": "^7.0.4",
|
||||||
|
"color-convert": "^2.0.1",
|
||||||
|
"color-name": "^1.1.4",
|
||||||
|
"colors": "^1.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"command-exists": "^1.2.9",
|
||||||
|
"command-line-args": "^5.2.1",
|
||||||
|
"command-line-usage": "^6.1.3",
|
||||||
|
"commander": "^8.3.0",
|
||||||
|
"concat-map": "^0.0.1",
|
||||||
|
"concat-stream": "^1.6.2",
|
||||||
|
"cookie": "^0.4.2",
|
||||||
|
"core-util-is": "^1.0.3",
|
||||||
|
"create-hash": "^1.2.0",
|
||||||
|
"create-hmac": "^1.1.7",
|
||||||
|
"create-require": "^1.1.1",
|
||||||
|
"crypt": "^0.0.2",
|
||||||
|
"death": "^1.1.0",
|
||||||
|
"debug": "^4.4.1",
|
||||||
|
"decamelize": "^4.0.0",
|
||||||
|
"deep-eql": "^4.1.4",
|
||||||
|
"deep-extend": "^0.6.0",
|
||||||
|
"deep-is": "^0.1.4",
|
||||||
|
"delayed-stream": "^1.0.0",
|
||||||
|
"depd": "^2.0.0",
|
||||||
|
"diff": "^5.2.0",
|
||||||
|
"difflib": "^0.2.4",
|
||||||
|
"dir-glob": "^3.0.1",
|
||||||
|
"dunder-proto": "^1.0.1",
|
||||||
|
"elliptic": "^6.6.1",
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"enquirer": "^2.4.1",
|
||||||
|
"env-paths": "^2.2.1",
|
||||||
|
"es-define-property": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"es-object-atoms": "^1.1.1",
|
||||||
|
"es-set-tostringtag": "^2.1.0",
|
||||||
|
"escalade": "^3.2.0",
|
||||||
|
"escape-string-regexp": "^4.0.0",
|
||||||
|
"escodegen": "^1.8.1",
|
||||||
|
"esprima": "^2.7.3",
|
||||||
|
"estraverse": "^1.9.3",
|
||||||
|
"esutils": "^2.0.3",
|
||||||
|
"eth-gas-reporter": "^0.2.27",
|
||||||
|
"ethereum-bloom-filters": "^1.2.0",
|
||||||
|
"ethereum-cryptography": "^1.2.0",
|
||||||
|
"ethereumjs-util": "^7.1.5",
|
||||||
|
"ethers": "^6.14.1",
|
||||||
|
"ethjs-unit": "^0.1.6",
|
||||||
|
"evp_bytestokey": "^1.0.3",
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"fast-glob": "^3.3.3",
|
||||||
|
"fast-levenshtein": "^2.0.6",
|
||||||
|
"fast-uri": "^3.0.6",
|
||||||
|
"fastq": "^1.19.1",
|
||||||
|
"fdir": "^6.4.4",
|
||||||
|
"fill-range": "^7.1.1",
|
||||||
|
"find-replace": "^3.0.0",
|
||||||
|
"find-up": "^5.0.0",
|
||||||
|
"flat": "^5.0.2",
|
||||||
|
"follow-redirects": "^1.15.9",
|
||||||
|
"form-data": "^4.0.2",
|
||||||
|
"fp-ts": "^1.19.3",
|
||||||
|
"fs-extra": "^7.0.1",
|
||||||
|
"fs-readdir-recursive": "^1.1.0",
|
||||||
|
"fs.realpath": "^1.0.0",
|
||||||
|
"function-bind": "^1.1.2",
|
||||||
|
"get-caller-file": "^2.0.5",
|
||||||
|
"get-func-name": "^2.0.2",
|
||||||
|
"get-intrinsic": "^1.3.0",
|
||||||
|
"get-port": "^3.2.0",
|
||||||
|
"get-proto": "^1.0.1",
|
||||||
|
"ghost-testrpc": "^0.0.2",
|
||||||
|
"glob": "^8.1.0",
|
||||||
|
"glob-parent": "^5.1.2",
|
||||||
|
"global-modules": "^2.0.0",
|
||||||
|
"global-prefix": "^3.0.0",
|
||||||
|
"globby": "^10.0.2",
|
||||||
|
"gopd": "^1.2.0",
|
||||||
|
"graceful-fs": "^4.2.11",
|
||||||
|
"handlebars": "^4.7.8",
|
||||||
|
"hardhat-gas-reporter": "^1.0.10",
|
||||||
|
"has-flag": "^4.0.0",
|
||||||
|
"has-symbols": "^1.1.0",
|
||||||
|
"has-tostringtag": "^1.0.2",
|
||||||
|
"hash-base": "^3.1.0",
|
||||||
|
"hash.js": "^1.1.7",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
|
"he": "^1.2.0",
|
||||||
|
"heap": "^0.2.7",
|
||||||
|
"hmac-drbg": "^1.0.1",
|
||||||
|
"http-basic": "^8.1.3",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"http-response-object": "^3.0.2",
|
||||||
|
"https-proxy-agent": "^5.0.1",
|
||||||
|
"iconv-lite": "^0.4.24",
|
||||||
|
"ignore": "^5.3.2",
|
||||||
|
"immer": "^10.0.2",
|
||||||
|
"immutable": "^4.3.7",
|
||||||
|
"indent-string": "^4.0.0",
|
||||||
|
"inflight": "^1.0.6",
|
||||||
|
"inherits": "^2.0.4",
|
||||||
|
"ini": "^1.3.8",
|
||||||
|
"interpret": "^1.4.0",
|
||||||
|
"io-ts": "^1.10.4",
|
||||||
|
"is-binary-path": "^2.1.0",
|
||||||
|
"is-extglob": "^2.1.1",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"is-glob": "^4.0.3",
|
||||||
|
"is-hex-prefixed": "^1.0.0",
|
||||||
|
"is-number": "^7.0.0",
|
||||||
|
"is-plain-obj": "^2.1.0",
|
||||||
|
"is-unicode-supported": "^0.1.0",
|
||||||
|
"isarray": "^1.0.0",
|
||||||
|
"isexe": "^2.0.0",
|
||||||
|
"js-sha3": "^0.8.0",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"json-schema-traverse": "^1.0.0",
|
||||||
|
"json-stream-stringify": "^3.1.6",
|
||||||
|
"json-stringify-safe": "^5.0.1",
|
||||||
|
"json5": "^2.2.3",
|
||||||
|
"jsonfile": "^4.0.0",
|
||||||
|
"jsonschema": "^1.5.0",
|
||||||
|
"keccak": "^3.0.4",
|
||||||
|
"kind-of": "^6.0.3",
|
||||||
|
"kleur": "^3.0.3",
|
||||||
|
"levn": "^0.3.0",
|
||||||
|
"locate-path": "^6.0.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"lodash.camelcase": "^4.3.0",
|
||||||
|
"lodash.clonedeep": "^4.5.0",
|
||||||
|
"lodash.isequal": "^4.5.0",
|
||||||
|
"lodash.truncate": "^4.4.2",
|
||||||
|
"log-symbols": "^4.1.0",
|
||||||
|
"loupe": "^2.3.7",
|
||||||
|
"lru_map": "^0.3.3",
|
||||||
|
"make-error": "^1.3.6",
|
||||||
|
"markdown-table": "^1.1.3",
|
||||||
|
"math-intrinsics": "^1.1.0",
|
||||||
|
"md5.js": "^1.3.5",
|
||||||
|
"memorystream": "^0.3.1",
|
||||||
|
"merge2": "^1.4.1",
|
||||||
|
"micro-eth-signer": "^0.14.0",
|
||||||
|
"micro-ftch": "^0.3.1",
|
||||||
|
"micro-packed": "^0.7.3",
|
||||||
|
"micromatch": "^4.0.8",
|
||||||
|
"mime-db": "^1.52.0",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
|
"minimalistic-assert": "^1.0.1",
|
||||||
|
"minimalistic-crypto-utils": "^1.0.1",
|
||||||
|
"minimatch": "^5.1.6",
|
||||||
|
"minimist": "^1.2.8",
|
||||||
|
"mkdirp": "^0.5.6",
|
||||||
|
"mnemonist": "^0.38.5",
|
||||||
|
"ms": "^2.1.3",
|
||||||
|
"ndjson": "^2.0.0",
|
||||||
|
"neo-async": "^2.6.2",
|
||||||
|
"node-addon-api": "^2.0.2",
|
||||||
|
"node-emoji": "^1.11.0",
|
||||||
|
"node-gyp-build": "^4.8.4",
|
||||||
|
"nofilter": "^3.1.0",
|
||||||
|
"nopt": "^3.0.6",
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"number-to-bn": "^1.7.0",
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"object-inspect": "^1.13.4",
|
||||||
|
"obliterator": "^2.0.5",
|
||||||
|
"once": "^1.4.0",
|
||||||
|
"optionator": "^0.8.3",
|
||||||
|
"ordinal": "^1.0.3",
|
||||||
|
"os-tmpdir": "^1.0.2",
|
||||||
|
"p-limit": "^3.1.0",
|
||||||
|
"p-locate": "^5.0.0",
|
||||||
|
"p-map": "^4.0.0",
|
||||||
|
"parse-cache-control": "^1.0.1",
|
||||||
|
"path-exists": "^4.0.0",
|
||||||
|
"path-is-absolute": "^1.0.1",
|
||||||
|
"path-parse": "^1.0.7",
|
||||||
|
"path-type": "^4.0.0",
|
||||||
|
"pathval": "^1.1.1",
|
||||||
|
"pbkdf2": "^3.1.2",
|
||||||
|
"picocolors": "^1.1.1",
|
||||||
|
"picomatch": "^4.0.2",
|
||||||
|
"pify": "^4.0.1",
|
||||||
|
"prelude-ls": "^1.1.2",
|
||||||
|
"prettier": "^2.8.8",
|
||||||
|
"process-nextick-args": "^2.0.1",
|
||||||
|
"promise": "^8.3.0",
|
||||||
|
"prompts": "^2.4.2",
|
||||||
|
"proxy-from-env": "^1.1.0",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"queue-microtask": "^1.2.3",
|
||||||
|
"randombytes": "^2.1.0",
|
||||||
|
"raw-body": "^2.5.2",
|
||||||
|
"readable-stream": "^3.6.2",
|
||||||
|
"readdirp": "^4.1.2",
|
||||||
|
"rechoir": "^0.6.2",
|
||||||
|
"recursive-readdir": "^2.2.3",
|
||||||
|
"reduce-flatten": "^2.0.0",
|
||||||
|
"req-cwd": "^2.0.0",
|
||||||
|
"req-from": "^2.0.0",
|
||||||
|
"require-directory": "^2.1.1",
|
||||||
|
"require-from-string": "^2.0.2",
|
||||||
|
"resolve": "^1.17.0",
|
||||||
|
"resolve-from": "^3.0.0",
|
||||||
|
"reusify": "^1.1.0",
|
||||||
|
"ripemd160": "^2.0.2",
|
||||||
|
"rlp": "^2.2.7",
|
||||||
|
"run-parallel": "^1.2.0",
|
||||||
|
"safe-buffer": "^5.2.1",
|
||||||
|
"safer-buffer": "^2.1.2",
|
||||||
|
"sc-istanbul": "^0.4.6",
|
||||||
|
"scrypt-js": "^3.0.1",
|
||||||
|
"secp256k1": "^4.0.4",
|
||||||
|
"semver": "^6.3.1",
|
||||||
|
"serialize-javascript": "^6.0.2",
|
||||||
|
"setimmediate": "^1.0.5",
|
||||||
|
"setprototypeof": "^1.2.0",
|
||||||
|
"sha.js": "^2.4.11",
|
||||||
|
"sha1": "^1.1.1",
|
||||||
|
"shelljs": "^0.8.5",
|
||||||
|
"side-channel": "^1.1.0",
|
||||||
|
"side-channel-list": "^1.0.0",
|
||||||
|
"side-channel-map": "^1.0.1",
|
||||||
|
"side-channel-weakmap": "^1.0.2",
|
||||||
|
"sisteransi": "^1.0.5",
|
||||||
|
"slash": "^3.0.0",
|
||||||
|
"slice-ansi": "^4.0.0",
|
||||||
|
"solc": "^0.8.30",
|
||||||
|
"solidity-coverage": "^0.8.16",
|
||||||
|
"source-map": "^0.6.1",
|
||||||
|
"source-map-support": "^0.5.21",
|
||||||
|
"split2": "^3.2.2",
|
||||||
|
"sprintf-js": "^1.0.3",
|
||||||
|
"stacktrace-parser": "^0.1.11",
|
||||||
|
"statuses": "^2.0.1",
|
||||||
|
"string_decoder": "^1.3.0",
|
||||||
|
"string-format": "^2.0.0",
|
||||||
|
"string-width": "^4.2.3",
|
||||||
|
"strip-ansi": "^6.0.1",
|
||||||
|
"strip-hex-prefix": "^1.0.0",
|
||||||
|
"strip-json-comments": "^3.1.1",
|
||||||
|
"supports-color": "^7.2.0",
|
||||||
|
"sync-request": "^6.1.0",
|
||||||
|
"sync-rpc": "^1.3.6",
|
||||||
|
"table": "^6.9.0",
|
||||||
|
"table-layout": "^1.0.2",
|
||||||
|
"then-request": "^6.0.2",
|
||||||
|
"through2": "^4.0.2",
|
||||||
|
"tinyglobby": "^0.2.13",
|
||||||
|
"tmp": "^0.0.33",
|
||||||
|
"to-regex-range": "^5.0.1",
|
||||||
|
"toidentifier": "^1.0.1",
|
||||||
|
"ts-command-line-args": "^2.5.1",
|
||||||
|
"ts-essentials": "^7.0.3",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"tslib": "^1.14.1",
|
||||||
|
"tsort": "^0.0.1",
|
||||||
|
"type-check": "^0.3.2",
|
||||||
|
"type-detect": "^4.1.0",
|
||||||
|
"type-fest": "^0.21.3",
|
||||||
|
"typechain": "^8.3.2",
|
||||||
|
"typedarray": "^0.0.6",
|
||||||
|
"typescript": "^5.8.3",
|
||||||
|
"typical": "^4.0.0",
|
||||||
|
"uglify-js": "^3.19.3",
|
||||||
|
"undici": "^5.29.0",
|
||||||
|
"undici-types": "^6.21.0",
|
||||||
|
"universalify": "^0.1.2",
|
||||||
|
"unpipe": "^1.0.0",
|
||||||
|
"utf8": "^3.0.0",
|
||||||
|
"util-deprecate": "^1.0.2",
|
||||||
|
"uuid": "^8.3.2",
|
||||||
|
"v8-compile-cache-lib": "^3.0.1",
|
||||||
|
"web3": "^4.16.0",
|
||||||
|
"web3-utils": "^1.10.4",
|
||||||
|
"which": "^1.3.1",
|
||||||
|
"widest-line": "^3.1.0",
|
||||||
|
"word-wrap": "^1.2.5",
|
||||||
|
"wordwrap": "^1.0.0",
|
||||||
|
"wordwrapjs": "^4.0.1",
|
||||||
|
"workerpool": "^6.5.1",
|
||||||
|
"wrap-ansi": "^7.0.0",
|
||||||
|
"wrappy": "^1.0.2",
|
||||||
|
"ws": "^7.5.10",
|
||||||
|
"y18n": "^5.0.8",
|
||||||
|
"yargs": "^16.2.0",
|
||||||
|
"yargs-parser": "^20.2.9",
|
||||||
|
"yargs-unparser": "^2.0.0",
|
||||||
|
"yn": "^3.1.1",
|
||||||
|
"yocto-queue": "^0.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
126
hardhat.tmpl/test/Lock.js
Normal file
126
hardhat.tmpl/test/Lock.js
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
const {
|
||||||
|
time,
|
||||||
|
loadFixture,
|
||||||
|
} = require("@nomicfoundation/hardhat-toolbox/network-helpers");
|
||||||
|
const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs");
|
||||||
|
const { expect } = require("chai");
|
||||||
|
|
||||||
|
describe("Lock", function () {
|
||||||
|
// We define a fixture to reuse the same setup in every test.
|
||||||
|
// We use loadFixture to run this setup once, snapshot that state,
|
||||||
|
// and reset Hardhat Network to that snapshot in every test.
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Contracts are deployed using the first signer/account by default
|
||||||
|
const [owner, otherAccount] = await ethers.getSigners();
|
||||||
|
|
||||||
|
const Lock = await ethers.getContractFactory("Lock");
|
||||||
|
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
|
||||||
|
|
||||||
|
return { lock, unlockTime, lockedAmount, owner, otherAccount };
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Deployment", function () {
|
||||||
|
it("Should set the right unlockTime", async function () {
|
||||||
|
const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
|
||||||
|
|
||||||
|
expect(await lock.unlockTime()).to.equal(unlockTime);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should set the right owner", async function () {
|
||||||
|
const { lock, owner } = await loadFixture(deployOneYearLockFixture);
|
||||||
|
|
||||||
|
expect(await lock.owner()).to.equal(owner.address);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should receive and store the funds to lock", async function () {
|
||||||
|
const { lock, lockedAmount } = await loadFixture(
|
||||||
|
deployOneYearLockFixture
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(await ethers.provider.getBalance(lock.target)).to.equal(
|
||||||
|
lockedAmount
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should fail if the unlockTime is not in the future", async function () {
|
||||||
|
// We don't use the fixture here because we want a different deployment
|
||||||
|
const latestTime = await time.latest();
|
||||||
|
const Lock = await ethers.getContractFactory("Lock");
|
||||||
|
await expect(Lock.deploy(latestTime, { value: 1 })).to.be.revertedWith(
|
||||||
|
"Unlock time should be in the future"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Withdrawals", function () {
|
||||||
|
describe("Validations", function () {
|
||||||
|
it("Should revert with the right error if called too soon", async function () {
|
||||||
|
const { lock } = await loadFixture(deployOneYearLockFixture);
|
||||||
|
|
||||||
|
await expect(lock.withdraw()).to.be.revertedWith(
|
||||||
|
"You can't withdraw yet"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should revert with the right error if called from another account", async function () {
|
||||||
|
const { lock, unlockTime, otherAccount } = await loadFixture(
|
||||||
|
deployOneYearLockFixture
|
||||||
|
);
|
||||||
|
|
||||||
|
// We can increase the time in Hardhat Network
|
||||||
|
await time.increaseTo(unlockTime);
|
||||||
|
|
||||||
|
// We use lock.connect() to send a transaction from another account
|
||||||
|
await expect(lock.connect(otherAccount).withdraw()).to.be.revertedWith(
|
||||||
|
"You aren't the owner"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Shouldn't fail if the unlockTime has arrived and the owner calls it", async function () {
|
||||||
|
const { lock, unlockTime } = await loadFixture(
|
||||||
|
deployOneYearLockFixture
|
||||||
|
);
|
||||||
|
|
||||||
|
// Transactions are sent using the first signer by default
|
||||||
|
await time.increaseTo(unlockTime);
|
||||||
|
|
||||||
|
await expect(lock.withdraw()).not.to.be.reverted;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Events", function () {
|
||||||
|
it("Should emit an event on withdrawals", async function () {
|
||||||
|
const { lock, unlockTime, lockedAmount } = await loadFixture(
|
||||||
|
deployOneYearLockFixture
|
||||||
|
);
|
||||||
|
|
||||||
|
await time.increaseTo(unlockTime);
|
||||||
|
|
||||||
|
await expect(lock.withdraw())
|
||||||
|
.to.emit(lock, "Withdrawal")
|
||||||
|
.withArgs(lockedAmount, anyValue); // We accept any value as `when` arg
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Transfers", function () {
|
||||||
|
it("Should transfer the funds to the owner", async function () {
|
||||||
|
const { lock, unlockTime, lockedAmount, owner } = await loadFixture(
|
||||||
|
deployOneYearLockFixture
|
||||||
|
);
|
||||||
|
|
||||||
|
await time.increaseTo(unlockTime);
|
||||||
|
|
||||||
|
await expect(lock.withdraw()).to.changeEtherBalances(
|
||||||
|
[owner, lock],
|
||||||
|
[lockedAmount, -lockedAmount]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue