Created
October 8, 2023 19:02
-
-
Save SKYBITDev3/57a385d1c7a067de22ab6e6a598bca7e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function main() { | |
const { ethers, network } = require(`hardhat`) | |
const [ wallet1, wallet2 ] = await ethers.getSigners() | |
// const walletToUse = wallet1 // switch between wallet1 & wallet2 to see the difference in addresses | |
const walletToUse = wallet2 // switch between wallet1 & wallet2 to see the difference in addresses | |
console.log(`Using network: ${network.name} (${network.config.chainId}), account: ${walletToUse.address} having ${await ethers.formatUnits(await ethers.provider.getBalance(walletToUse.address), `ether`)} of native currency, RPC url: ${network.config.url}`) | |
// Deploy factory | |
const addressOfFactory = `0xaf45f86eb0bbf0536fa770b699b806f22496d875` // If evmVersion = shanghai. See https://github.com/SKYBITDev3/deterministic-deployment-proxy. Difference with Arachnid's factory is that here user's address is hashed with salt | |
if (await ethers.provider.getCode(addressOfFactory) === `0x`) { | |
// Fund account of signer of transaction that deploys factory. | |
const addressOfSignerToDeployFactory = `0x790bec4474aff8686ab85225584988f9622efff5` // If evmVersion = shanghai | |
let txResponse = await walletToUse.sendTransaction({ to: addressOfSignerToDeployFactory, value: ethers.parseUnits(`0.1`, `ether`) }) | |
await txResponse.wait() | |
const txSserialized = `0xf8858085174876e800830186a08080b4602a80600a5f395ff3fe5f33815280356020526034600c20601f19360180602084378234f5908115602757526014600cf35b80fd1ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222` // If evmVersion = shanghai | |
txResponse = await ethers.provider.broadcastTransaction(txSserialized) | |
const txReceipt = await txResponse.wait() | |
// console.log(`txReceipt: ${JSON.stringify(txReceipt)}`) | |
} | |
console.log(`Address of factory deployed keylessly: ${addressOfFactory}`) | |
// Deploy Contract via factory | |
// get contract bytecode | |
const contractName = `TESTERC20` | |
const constructorArgs = [ | |
`Token 4630`, | |
`TOKEN4630`, | |
100, | |
[ wallet1.address, wallet2.address ], // test array constructor argument | |
{ x: 10, y: 5 }, // test struct constructor argument | |
`0xabcdef`, // test byte constructor argument. bytes have to be 0x-prefixed | |
] | |
const cfToken = await ethers.getContractFactory(contractName) | |
const bytecodeOfContractWithArgs = (await cfToken.getDeployTransaction(...constructorArgs)).data | |
// const salt = ethers.encodeBytes32String(``) // 0x0000000000000000000000000000000000000000000000000000000000000000 | |
const salt = ethers.encodeBytes32String(`XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`) | |
const txData = { | |
from: walletToUse.address, | |
to: addressOfFactory, | |
data: bytecodeOfContractWithArgs.replace(`0x`, salt), | |
} | |
const expectedAddressUsingCall = await walletToUse.call(txData) | |
console.log(`expected address using await walletToUse.call(txData): ${expectedAddressUsingCall}`) | |
const keccak256Calculated = ethers.solidityPackedKeccak256([ `address`, `bytes32` ], [ walletToUse.address, salt ]) | |
const expectedAddressCalculated = ethers.getCreate2Address(addressOfFactory, keccak256Calculated, ethers.keccak256(bytecodeOfContractWithArgs)) | |
console.log(`expected address using ethers.getCreate2Address: ${expectedAddressCalculated}`) | |
console.log(`Now deploying ${contractName} using factory...`) | |
const txReceipt = await walletToUse.sendTransaction(txData) | |
await txReceipt.wait() | |
console.log(`${contractName} was deployed by ${walletToUse.address}`) | |
console.log(`Testing deployed contract by getting contract at address ${expectedAddressUsingCall}:`) | |
const contract = await ethers.getContractAt(contractName, expectedAddressUsingCall, walletToUse) | |
console.log(`${walletToUse.address} calling contract.point(): ${await contract.point()}`) // Test deployed Contract contract at expected address | |
console.log(`${walletToUse.address} calling contract.privilegedFunction(): ${await contract.privilegedFunction()}`) // Test function that only a privileged account can call | |
} | |
main().catch(error => { | |
console.error(error) | |
process.exitCode = 1 | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Using network: hardhat (31337), account: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 having 10000.0 of native currency, RPC url: undefined | |
Address of factory deployed keylessly: 0xaf45f86eb0bbf0536fa770b699b806f22496d875 | |
expected address using await walletToUse.call(txData): 0xe32dcd55a5daee6e5a34b046f759721c76e78291 | |
expected address using ethers.getCreate2Address: 0xE32dcD55a5daEE6E5A34b046F759721C76E78291 | |
Now deploying TESTERC20 using factory... | |
TESTERC20 was deployed by 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 | |
Testing deployed contract by getting contract at address 0xe32dcd55a5daee6e5a34b046f759721c76e78291: | |
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 calling contract.point(): 10,5 | |
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 calling contract.privilegedFunction(): 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Using network: hardhat (31337), account: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 having 10000.0 of native currency, RPC url: undefined | |
Address of factory deployed keylessly: 0xaf45f86eb0bbf0536fa770b699b806f22496d875 | |
expected address using await walletToUse.call(txData): 0xbb1070bb427b517cb6ecfc2b1ef08ec413259277 | |
expected address using ethers.getCreate2Address: 0xbb1070bb427B517Cb6Ecfc2B1ef08ec413259277 | |
Now deploying TESTERC20 using factory... | |
TESTERC20 was deployed by 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 | |
Testing deployed contract by getting contract at address 0xbb1070bb427b517cb6ecfc2b1ef08ec413259277: | |
0x70997970C51812dc3A010C7d01b50e0d17dc79C8 calling contract.point(): 10,5 | |
0x70997970C51812dc3A010C7d01b50e0d17dc79C8 calling contract.privilegedFunction(): 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.21; | |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | |
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; | |
import "@openzeppelin/contracts/access/AccessControl.sol"; | |
// import "hardhat/console.sol"; | |
struct Point { | |
uint x; | |
uint y; | |
} | |
contract TESTERC20 is ERC20, ERC20Permit, AccessControl { | |
Point public point; | |
bytes public b; | |
constructor( | |
string memory name, | |
string memory symbol, | |
uint initialSupply, | |
address[] memory initialHolders, | |
Point memory _point, | |
bytes memory _b | |
) ERC20(name, symbol) ERC20Permit(name) { | |
_mint( | |
initialHolders[0], | |
(10 * (initialSupply * 10 ** decimals())) / 100 | |
); | |
_mint( | |
initialHolders[1], | |
(90 * (initialSupply * 10 ** decimals())) / 100 | |
); | |
point = _point; | |
b = _b; | |
// _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); // if deploying this contract via a factory then msg.sender is factory's address | |
_grantRole( | |
DEFAULT_ADMIN_ROLE, | |
tx.origin | |
); | |
} | |
function privilegedFunction() | |
public | |
view | |
onlyRole(DEFAULT_ADMIN_ROLE) | |
returns (uint8) | |
{ | |
return 1; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment