Knowledge Base & Projects
๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฆ๏ธโก๏ธ๐ฅ๐๐ฅโพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด
- ๐ก๏ธ Smart Contract Hacking Instructions โ Summary
- Coding Style
- dev.md, dev.md text
- Miki, Miki-Sum
- ์์ ํ๊ฒฝ ์ธํ
- Poohnet & Betelgeuse
- Code - Projects
- Error - Trend
- Pooh-Chain
๐ code
ignition
- Refer to
contracts/ignitionfolder - Refer to
ignition/modulesfolder - Run deploy script
hardhat ignition deploy ignition/modules/apollo.ts --network localnet
- Check
ignition/deploymentsfolder - Remove
ignition/deploymentsfolder if you want to deploy contract from start.
OpenSea fulfillOrder parameter ABI encode
function fulfillOrder(
/**
* @custom:name order
*/
Order calldata,
bytes32 fulfillerConduitKey
) external payable override returns (bool fulfilled)
+------------------------------------------+
| 0x00..0x03 : Function Selector |
+------------------------------------------+
| 0x04..0x23 : offset To Order = 0x80 | (for param1: Order)
+------------------------------------------+
| 0x24..0x43 : fulfillerConduitKey | (for param2: conduitKey)
+------------------------------------------+
| 0x44(68)..0x63 : offset to acutal data = 0x40| (start of `parameters` of `AdvancedOrder`)
+------------------------------------------+
| 0x64..0x83 : (unused or ...) |
+------------------------------------------+
| 0x84(132)..0xA3 : offerer | (start of `offer`)
| 0xA4..0xC3 : zone |
+------------------------------------------+
| 0xC4..0xE3 : offset to parameters = 0x40|
| 0xE4..0x103 : (unused or ...) |
+------------------------------------------+
[ array length of offer ] // 32 bytes
[ pointerToElem0StructData ] // 32 bytes
[ pointerToElem1StructData ] // 32 bytes
...
(Then in the tail region)
Elem0 struct data
Elem1 struct data
...
+------------------------------------------+
| `consideration` part
+------------------------------------------+
struct AdvancedOrder {
OrderParameters parameters;
uint120 numerator;
uint120 denominator;
bytes signature;
bytes extraData;
}
struct OrderParameters {
address offerer; // 0x00
address zone; // 0x20
OfferItem[] offer; // 0x40
ConsiderationItem[] consideration; // 0x60
OrderType orderType; // 0x80
uint256 startTime; // 0xa0
uint256 endTime; // 0xc0
bytes32 zoneHash; // 0xe0
uint256 salt; // 0x100
bytes32 conduitKey; // 0x120
uint256 totalOriginalConsiderationItems; // 0x140
// offer.length // 0x160
}
openzeppelin ๊ฐ์ ์ธ๋ถ ํ๋ก์ ํธ ์ ์ฉ
flux-financeํ๋ก์ ํธ ์ฒ๋ผopenzeppelin๊ฐ์ ์ธ๋ถ ํ๋ก์ ํธ๋ฅผ ์ฝ๋์ ์ง์ ํฌํจ์ํค๋ ๊ฒ๋ ๋ฐฉ๋ฒcontracts/external/openzeppelin, ์ฌ๊ธฐ๋src๋์contractsํด๋๋ฅผ ์ฌ์ฉ.
Random Key ์์ฑ (#ํค์์ฑ #ํค ์์ฑ #Key Generation)
yarn keys
Python ์ฐธ๊ณ ์ฝ๋
์ฌ๊ธฐ์ 0x๋ฅผ ์ฐ๋ฉด ์๋จ.
hex_string = "48656c6c6f20576f726c64" # Hex encoded string for "Hello World" byte_string = bytes.fromhex(hex_string) regular_string = byte_string.decode("utf-8")
from datetime import datetime datetime.fromtimestamp(7214123987)
print(f"{a:08x}{b:016x}{c:08x}") 0000006400000000000227b200000005
Python์์ Ethereum ํธ์ถ
w3 = Web3(Web3.HTTPProvider('https://eth-sepolia.g.alchemy.com/v2/73I-qvN9yqtRcajnfvEarwA2FNHM4Nph')
ethers v5
(ethersv5) "ethers-v5": "npm:ethers@5",
Private key๋ก keystore ํ์ผ ๋ง๋ค๊ธฐ
(keystore, decrypt, encrypt)
account import
- Create
mykeyfileand set private key in the file (0x๋ ๋ถ์ด๋ฉด ์๋จ) geth --datadir ./mykeystore account import mykeyfilemykeystoreํด๋์ ํ์ผ ์์ฑ๋จ
decrypt
const data = JSON.parse(
fs.readFileSync(path.resolve(Utils.getInitCWD(), this.key), "utf-8")
);
const account = hre.web3.eth.accounts.decrypt(data, "pooh2024");
this.key = account.privateKey;
Deploy factory contract (Deterministic deployment proxy)
Reference
pooh-geth/poohnet/deploy-deployer.shonpooh-gethnpx hardhat test test/all-basic.ts --grep CREATE2onwebnpx hardhat run scripts/deploy-with-create2.ts --network localnetonweb
Check if the factory exists
The Create2 factory contract will be deployed at the address 0x4e59b44847b379578588920cA78FbF26c0B4956C. You can check if this contract has already been deployed to your L1 network with a block explorer or by running the following command:
cast codesize 0x4e59b44847b379578588920cA78FbF26c0B4956C --rpc-url $L1_RPC_URL
If the command returns 0 then the contract has not been deployed yet. If the command returns 69 then the contract has been deployed and you can safely skip this section.
Fund the factory deployer
You will need to send some ETH to the address that will be used to deploy the factory contract, 0x3fAB184622Dc19b6109349B94811493BF2a45362. This address can only be used to deploy the factory contract and will not be used for anything else. Send at least 1 ETH to this address on your L1 chain.
Deploy the factory
Using cast, deploy the factory contract to your L1 chain:
cast publish --rpc-url $L1_RPC_URL 0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222
Wait for the transaction to be mined
Make sure that the transaction is included in a block on your L1 chain before continuing.
Verify that the factory was deployed
Run the code size check again to make sure that the factory was properly deployed:
cast codesize 0x4e59b44847b379578588920cA78FbF26c0B4956C --rpc-url $L1_RPC_URL
oz contract test
- web ๋๋ ํ ๋ฆฌ์์ ์คํ
- ์ํ๋ ํ ์คํธ ํ์ผ ๊ณจ๋ผ์ ๋ค์๊ณผ ๊ฐ์ด ์คํ
yarn hardhat test test/oz/access/Ownable.test.js
seaport contract test
- ex5 ๋๋ ํ ๋ฆฌ๋ก ์ด๋
- ์ํ๋ ํ ์คํธ ํ์ผ ๊ณจ๋ผ์ ๋ค์๊ณผ ๊ฐ์ด ์คํ
yarn hardhat test /Users/jay/work/web/ex/test/seaport/basic.spec.ts
yarn sea
test๋ฅผ pooh-geth๋ก localnet์์ ํ ์คํธํ ๋ ์ฃผ์์
pooh-geth๋ cancun ๋น๋๊ฐ ์๋๊ธฐ ๋๋ฌธ์,.envํ์ผ์์ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํ๊ณ ํด์ผํจ.
EVM_VERSION=london
๐ Projects
External repositiries
webferc6900-reference: erc-6900 foundry ํ๋ก์ ํธ- forge test --match-path test/account/UpgradeableModularAccount.t.sol
efoundry-course: foundry ๊ฐ์ by Patrick Collins- cd ~/work/web/ecourse-foundry/L7-foundry-fund-me
- make install
- forge test
exf: foundry ํ ์คํธ- forge test Counter
web_cairo: Cairo ํ ์คํธ ํ๋ก์ ํธ- README ์ฐธ๊ณ
smart-contract-hacking: Solidity smart contract security- README ์ฐธ๊ณ
eopenzeppelin-contracts: openzeppelin contracts
๐ Trend
25.02.20
@ ์ ์ฒด
- ์๋๋ ์๋์ฐจ๋ฅผ ํตํด์ ๊ฒฝํ์ ํ๊ฒ ๋ค.
- ๋์ด์ ์ด์ ํ๋ฉด์ ์๊ฐ์ ๋ญ๋นํ ์ผ์ ์์ ๊ฒ์.
- OnDevice AI (์ธํฐ๋ท์ด ์๋๋ ๋จ)
- Land-Air-Craft
@ ์นผ๋ฆฌ๋ฒ์ค
- ๊ณต๊ฐ์ํฅ์ ๋ง๋๋ ๊ฒ๋ GenAI๋ฅผ ์ฌ์ฉํจ.
- ์ค๋งํธ ํฐ์ผ๋ก ์ฌ์ง์ ์ฐ์ผ๋ฉด Unreal ์์ง์ผ๋ก ์์ฑ๋ ์ค๋ธ์ ํธ๊ฐ ์์ฑ๋๋ ์ ํ. ์ผํ์์ ํ์ฉ ๊ฐ๋ฅ
- ์ฌ๋์ ์ค์บ๋ํด์ ๊ฐ์๊ณต๊ฐ์์ ์ฌ์ฉ๋จ.
@ TCL
- 10๋ ์ ์ CES์์ ์ข ์ด ์์๋ก ์๊ฒฝ์ ๋ง๋๋ ๊ฑธ 3D ์๊ฒฝ์ ๋ณด์ฌ์ค.
- ์ค๋งํธ๊ธ๋์ค๋ฅผ ํตํด์ ๋ค๋ฅธ ์ฑ๋ฅ์ ํ๋ฉด์ ๋ณผ ์ ์์.
- ์ค์๊ฐ ๋ฒ์ญ๊ธฐ๋ฅ์ด ์๋๋ฐ, ์ผ๋ง๋ ์ฐ๊ธฐ ํธํ ์ง... ์๋ฌธ.
๋ง์ค๋ฅธ '์ธ์ ๋ง๋ฌผ ํฌ์' ํ ํฐ์ฆ๊ถโฆ๋ด๋ ๋ณธ๊ฒฉ ๊ถค๋ ์ค๋ฅด๋
- ์ ๋ ฅ 2024.12.25.
- ํ ํฐ์ฆ๊ถ์ ์ข ์ ์ ๋์ ๋ฃ๊ธฐ ์ด๋ ค์ ๋ ์์ฐ์ ์๊ฒ ์ชผ๊ฐ ๊ธํฌ์ํ์ผ๋ก ์ ํํ๋๋ฐ ์๊ธดํ๋ค.
- ์ด ๋๋ฌธ์ ์ด๋ฒ 22๋ ๊ตญํ์ ๋ฐ์๋ ๋ฒ์(์๋ณธ์์ฅ๋ฒยท์ ์์ฆ๊ถ๋ฒ ๊ฐ์ ์)์ ๋น์ ํ ์ฆ๊ถ์ ๋ฐํ ๋ฐ ์ ํต์ ๋ฒ์ ํํด ๋ถํ์ค์ฑ์ ์กฑ์๋ฅผ ์์ ๋ ๋ฐ ์ด์ ์ ๋ง์ท๋ค.
- ์ ๊ณ์์๋ ๋งจ ๋จผ์ ๋ณดํธํํ ํ ํฐ์ฆ๊ถ์ผ๋ก ๋ถ๋์ฐ ์กฐ๊ฐํฌ์ ์ํ์ ๊ผฝ๋ ์ด๋ค์ด ๋ง๋ค.
- ๋ฏธ์ ํ๊ณผ ์ ์๊ถ ๋ฑ ์์ฐ์ ๊ฐ์น ํ๊ฐ๊ฐ ๊น๋ค๋กญ์ง๋ง ๋ถ๋์ฐ์ ๊ฐ์น ์ฐ์ ๊ณผ ๊ฑฐ๋ ์๊ธฐ ์์ธก์ด ๋น๊ต์ ์ฝ๊ณ , ์ค์ ๊ฑด๋ฌผยทํ ์ง๋ฅผ ํ ๋๋ก ํ๋ ๋งํผ ๋ฐฐ๋น ์์ ์ฑ๊ณผ ํ๊ธ์ฑ ๋ฉด์์ ๋ ์ ๋ฆฌํ๊ธฐ ๋๋ฌธ์ด๋ค.
ChatGPT o1, o3
- o3: private chain of thought
- o1: ๋
ผ๋ฆฌ์ ์ค๋ฅ ๊ฒฐํฉ์ ์ง์ผ์ค. ์ถ๋ก ์ ์ํจ.
- ๋ณํ๋ฅผ ์ ์ถํ๋๋ก ํจ. ์ถ๋ก ์ฑ๋ฅ
- xml ํ๊ทธ๋ฅผ ์ฐ๋ฉด ์ข๋ค.
CES & TTimes
- Grader๋ฅผ ํตํ ๋๋ง์ FineTuning
- ์นด๋ฉ๋ผ๋ก ์ํฉ์ ๋ณด๊ณ ๊ฐ์ด๋ํด์ฃผ๋ ๊ฒ(์๋ฅผ๋ค์ด ๊ธฐ๊ณ ๊ณ ์น๋๋ฒ)
- NVidia๋ ํ๋์จ์ด/์ํํธ์จ์ด ํคํธ. ํ๋์จ์ด ํ์ฌ๊ฐ ์งํฅ์ ์ ์๋.
- ์ค๊ตญ ๋ก๋ด์ ๊ฐ๊ฒฉ๊ฒฝ์๋ ฅ.
- NVidia Cosmos. ๊ฐ์ํ์ค์์ ํ์ตํ๊ธฐ ์ํ ๊ฒ. ํ๋กฌํํธ๋ก ๊ฐ์ํ์ค ๋ง๋ฌ. (๋์งํธ ํธ์) ==> ๋ฉํ๋ฒ์ค
- 2๋ ์ ์ ์ฑ๋น์๋ ๊ณ์ฐ์ ๋ชปํ๊ณ ์ด์ ๊ณ์ฐ์ ํจ. ๋ค์ 2๋ ์ ์ด๋ป๊ฒ ๋ด๋์ง.
- ์์ ์ปดํจํฐ์นฉ. ์๋ก์ฐ
- ๊ฐ์๋ฅผ ๊ฒฝ์ฒญํํ์ ๋ ธํ ์ ํ๋ผ.
- P2P ๊ฐ๋ , ์ด์ ๋ฉดํ๊ฐ ํ์์๊ฒ ๋จ.
- ํ์ ๊ธฐ์ฌ, ์ฐ๋ฒ ๊ธฐ์ฌ ๊ณ ์ฉ๋ฅ ๋จ์ด์ง ๊ฒ์. ์ ์น๋ ๊ฒฝ์ ๋ ๋์ ์๋ ์ฐ๋ฆฌ๋๋ผ ์ฐ๋ฒ ์ฌํ
- AI Agent
- ๋ก๋ด๊ฐ๊ฐ ์ฐ๋ ๊ธฐ ์ฒ๋ฆฌ ๋ฐ ๋ก๋ด ๊ตฐ์ฌ๊ฐ ํ๋๋ ๊ฒ์.
- ์ปจํ์คํธ ์ค์์นญ์ ์ ํด์ผํจ.
- ์ธ๋ถ ์คํ ์ ์ ์ด๋๊ณ ์ผ์ ์์ํ๋ ๊ฒ. (๋ณต์กํ ๋ฌธ์ ๊ฐ ์๋๋ผ, To do list ์)
- ์ค๊ฐ์ ๋ค๋ฅธ ์ง๋ฌธ์ ๋ค์ด์ค๋ฉด ๋ด ํ์ฌ ์์ ์ ๋ง์น๊ณ ๋๋ต. ์ชผ๊ฐ๋์ผ๋ฉด ๋์์ค๊ธฐ ์ฝ๋ค. ์ฒดํฌํฌ์ธํธ๋ฅผ ๊ธฐ๋ก
- ์ด๊ธฐ ์ปค๋ฐ์ ๋ค ๋ ๋ฆด ์๋ ์์.
- 2000์ค์ ์ฝ๋์ฒด์ธ์ง๊ฐ ์ผ์ด๋์ผํ๋ค๋ฉด ์คํํน์ ์ ํด์ผํจ.
- 100์ค ์ดํ ์ฒด์ธ์ง๋ก ๋ณด๋ด๊ธฐ. ์ ๋ํ ์คํธ, ๋ฆฌํฉํ ๋ง์ ๊ทธ๊ฒ๋ง.
- ์์์ , ์ ์ธ๊ณ์ ๊ฒฝ์์ค. (๋ฒ ํธ๋จ ์๊ตญ์)
- ์ ๊ฒ ํ์๋ ์ํ๋น ๋ณดํฌ์ด ๋๋ฉด ๋ฌด์ธ๊ฐ๊ฒ๊ฐ ๋์ด๋จ.
๐ ์์ฑํ AI์์ AGI๊น์งใ ฃ์นด์ด์คํธ ๊น๋์ ๊ต์
- ๋ฉํฐ๋ชจ๋ฌ, ํด๋ํฐ์ผ๋ก ์ธ๊ณต์ง๋ฅ์ ์ฐ์ง๋ ์์ ๊ฒ
- ํด๋ํฐ์ ์๋๊ฐ ๋๋๋ค.: ๊ทธ๋ ๊ฒ ํ๋ค๊ณ ํ๋ฉด ๊ทธ๋ ๊ฒ ๋๋ค. Self-fullfilling process
- New formfactor, ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ์ฐพ์๋ผ.
- 2~3๋ ํ์ ์ธ๊ณต์ง๋ฅ๊ณผ ์ด๋ผ๊ฒ ๋งํ๊ฒ ๋ ๊ฒ.
- ๋ชจ๋ธ์ด ์ปค์ง๋ฉด์ ๊ฐ์๊ธฐ ์๋กญ๊ฒ ํด๊ฒฐ๋๋ ํ์์ด ๋ฐ์ํจ.
- 5๋ ํ 100์กฐ ๋ชจ๋ธ์ AGI
- AI Pilot
๐ CES 2025
- Intent based์ ๋์์ ํ๊ฒ ํ๋ค.
- AI MPC in ๊ฒ์.
- ๋ฌผ๋ฆฌ ์ธ๊ณต์ง๋ฅ
- AGI - ASI (super intelligence)
- Lipsync ์ ํ
- ์ด๋ฏธ์ง๋ฅผ 3D๋ก ๋ฐ๊ฟ.
- AI Agent: ๋ณต์กํ ์์ ์คํ. ๊ตฌ๊ธ์ด ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ์ ์ฉ(Universal Assistent, Javis)
- Copilot Studio, AI Agent Studio
- ์ ๋ฌด ์๋ํ
- Fabrix: LLM์ ๋ณด์๊ณผ ํจ๊ป ๋์. ํด๋ผ์ฐ๋ ํํ.
- MultiAgent: ๋ฆฌ๋์์ด์ ํธ๊ฐ ํ์ ์์ด์ ํธ์ ํต์ ํจ.
- Personal Agent: ๋์ ์ญํ ์ ๋์ ํจ.
- Brity Automation
ethers v5 vs ethers v6 issue
- all-basic.ts๋ฅผ ๋๊ฐ๋ก ๋ถ๋ฆฌํจ
all-basic.ts
yarn test:basic๋ก ํ ์คํธ- ํน์ดํ๊ฒ,
ethers.provider.send('eth_sendRawTransaction', ...)ํจ์๋ฅผ ethers v6 ํ๊ฒฝ์์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ฉด ์๋์ ์๋ฌ๊ฐ ๋ธInvalidArgumentsError: Trying to send a raw transaction with an invalid chainId. The expected chainId is 31337 at EdrProviderWrapper.request (/Users/jay/work/web/ex/node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:453:19) at async Context.<anonymous> (/Users/jay/work/web/ex/test/all-basic-sign.ts:171:19)
all-balic-ethers5.ts
yarn test:basic5๋ก ํ ์คํธethers.provider.send('eth_sendRawTransaction', ...)ethers.provider.send('eth_call', ...)- ์ด๋ฐ ๋ณต์กํ ์ฒ๋ฆฌ๋ฅผ ํ ๋๋ ์ด์ฉ์ ์์ด ethers v5๋ฅผ ์ด์ฉํ ์์ค๋ฅผ ์จ์ผ ํ ๋ฏํจ.
- ์ด๋ฏธ ์ฐธ๊ณ ์์ค๊ฐ ์กด์ฌํ๊ณ , ํ ์คํธ ์ฝ๋์ ๋ณต์ก์ฑ์ ๋ฐ๋ก ํ์ผ๋ก ๋ถ๋ฆฌ์ํจ๋ค๋ฉด ๋ฌธ์ ์์ ๊ฒ์ผ๋ก ๋ณด์.
Issues
pooh-geth cancun ๋ฏธ์ ์ฉ ๋ฌธ์
- contract-dencun๊ณผ contract-seaport ์ปจํธ๋ํธ๋ฅผ ์ฌ์ฉํ ๋, localnet์์๋ ํ ์คํธ๊ฐ ์๋จ.
- ์๋๋ contracts ํด๋ ์์ ์์ผ๋, localnet๊ณผ ์ฐ๋์์๋ ๋ฐ๊นฅ์ผ๋ก ์ฎ๊ฒจ์ผํ๋ ๋ถํธํจ์ด ์์.
- localnet์ผ๋ก ์ฐ๋ pooh-geth๊ฐ Cancun evm์ผ๋ก ๋น๋๋์ด ์์ง ์๊ธฐ ๋๋ฌธ์.
- ๋ค์์ ์ฝ๋ ์ฐธ๊ณ (hardhat.config.ts)
{ version: "0.8.24", settings: { evmVersion: process.env.EVM_VERSION || "cancun", ... } ... } - ํ๊ฒฝ๋ณ์ ๊ฐ์ ๋ฐ๋ผ์ ์ปดํ์ผ ๋์์ ๋ณ๊ฒฝํ ์๋ ์๋ ๊ฒ์ผ๋ก ๋ณด์.
- ์ฐธ๊ณ ๋ก, ํ ์คํธ๋๋ ํ์ผ์ ์์น๋ ์ด๋ฆ์ผ๋ก ํ๊ฒฝ๋ณ์ ๊ฐ์ ๋ฐ๊ฟ ์๋ ์์.
- 24.11.01 solved
- Added the following configurations into
genesis_testnet.json"shanghaiTime": 0, "cancunTime": 0,
- Added the following configurations into
Foundry
Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
Foundry consists of:
- Forge: Ethereum testing framework (like Truffle, Hardhat and DappTools).
- Cast: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
- Anvil: Local Ethereum node, akin to Ganache, Hardhat Network.
- Chisel: Fast, utilitarian, and verbose solidity REPL.
Documentation
Usage
Build
$ forge build
Test
$ forge test
Format
$ forge fmt
Gas Snapshots
$ forge snapshot
Anvil
$ anvil
Deploy
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
Cast
$ cast <subcommand>
Help
$ forge --help
$ anvil --help
$ cast --help
๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐ฅโพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐ฅโพ๏ธ๐ถ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐โพ๏ธ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฆ๏ธโก๏ธ๐ฅ๐๐ฅโพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฆ๏ธโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐โพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐โพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฆ๏ธโก๏ธ๐ฅ๐๐ฅโพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฆ๏ธโก๏ธ๐ฅ๐๐ฅโพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐นโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐โพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐ฅโพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐ฅโพ๏ธ๐ถ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐โพ๏ธ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฆ๏ธโก๏ธ๐ฅ๐๐ฅโพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฆ๏ธโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐โพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐โพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฆ๏ธโก๏ธ๐ฅ๐๐ฅโพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ฆ๐๐นโฆ๏ธโก๏ธ๐ฅ๐๐ฅโพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐๐๐๐นโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ผ๐ธ๐โพ๏ธ๐ถ๐ฆโ๏ธ๐๐ฑ๐๐ด๐ผ๐๐ฆโพ๏ธ๐ฅ๐โฝ๏ธ๐๐
Solidity
function type ๋ฐ๊พธ๊ธฐ
function _getManifest() internal view returns (PluginManifest memory) {
PluginManifest memory m = abi.decode(_manifest, (PluginManifest));
return m;
}
function _castToPure(
function() internal view returns (PluginManifest memory) fnIn
)
internal
pure
returns (function() internal pure returns (PluginManifest memory) fnOut)
{
assembly ("memory-safe") {
fnOut := fnIn
}
}
function pluginManifest() external pure returns (PluginManifest memory) {
return _castToPure(_getManifest)();
}
getContractFactory & ContractFactory
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract Greeter {
string internal _greeting;
constructor(string memory newGreeting) {
_greeting = newGreeting;
}
function setGreeting(string memory newGreeting) public {
_greeting = newGreeting;
}
function greet() public view returns (string memory) {
return _greeting;
}
}
import { ethers } from "hardhat";
import { expect } from "chai";
import Greeter from "../artifacts/contracts/Greeter.sol/Greeter.json";
describe("ContractFactory", function () {
async function greeterFixture() {
const [owner, otherAccount] = await ethers.getSigners();
return { owner, otherAccount };
}
it("Should return the new contract instance", async function () {
const Factory = await ethers.getContractFactory("Greeter");
const greeter = await Factory.deploy("Hello, Hardhat!");
console.log("Greeter deployed to:", greeter.target);
expect(await greeter.greet()).to.equal("Hello, Hardhat!");
});
it("Should create a new contract instance with ethers.ContractFactory", async function () {
const { owner } = await greeterFixture();
const greeter = await new ethers.ContractFactory(
Greeter.abi, Greeter.bytecode, owner).
deploy("Hello, Hardhat!");
const contract = await ethers.getContractAt('Greeter', greeter.target, owner);
expect(await contract.greet()).to.equal("Hello, Hardhat!");
});
});
Smart Contract/Hardhat
๐๐๐ฆโพ๏ธ๐ณ๐๐ผ๐ธ๐๐๐๐ถ๐ฆโ๏ธ๐โป
Hardhat config defaultNetwork
create2 ํจ์
์๋ ํจ์๋ UniswapV2Factory์์ ์ฌ์ฉ๋๋ ์ฝ๋์
bytes memory bytecode = type(UniswapV2Pair).creationCode;
bytes32 salt = keccak256(abi.encodePacked(token0, token1));
assembly {
pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
}
Unlike create, which generates the contract address based on the address of the creator and how many contracts it has created (nonce), create2 generates the address using the creator's address, a provided salt, and the hash of the initialization code. This allows for predictable computation of the contract's address before the contract is actually deployed.
Endowment (0): This is the amount of Ether, in wei, that is sent to the new contract upon creation. In this case, it's set to 0, meaning no Ether is sent.
Memory Start (add(bytecode, 32)): bytecode is the initialization code for the contract you want to create. In Solidity, contract bytecode is often stored in an array, and this array includes a 32-byte length prefix. add(bytecode, 32) calculates the starting point of the actual bytecode, skipping the first 32 bytes which represent the length of the bytecode. This is necessary because create2 requires a pointer to the start of the actual code, not the length prefix. Size of Code (mload(bytecode)):
mload(bytecode) is used to load the first 32 bytes of bytecode, which, as mentioned, contain its size. This tells create2 how much of the memory starting from add(bytecode, 32) it should read and use as the initialization code. Salt (salt):
The salt is a 32-byte value that you provide. It's part of the formula used to calculate the address of the new contract. In your code, salt is generated from the hash of two token addresses, which helps ensure that each pair of tokens gets a unique contract address.
ํธ๋์ญ์ ์ทจ์ํ๋ ๋ฐฉ๋ฒ
- https://support.metamask.io/hc/en-us/articles/360015489251-How-to-speed-up-or-cancel-a-pending-transaction
- MetaMask์ ์ค์ ์ ๊ณ ๊ธ์ ๋ค์ด๊ฐ์ "ํ๋ ๋ฐ ๋ ผ์ค ๋ฐ์ดํฐ ์ง์ฐ๊ธฐ"
Nonce ์ป์ด๋ด๊ธฐ
- docker exec -it pow-node geth attach data/geth.ipc
- eth.getTransactionCount("0x8B595d325485a0Ca9d41908cAbF265E23C172847")
- ์ฌ๊ธฐ์ ๋ํ๋๋ Nonce๋ฅผ ํธ๋์ญ์ ์์ ์ฌ์ฉํ๋ ๊ฒ์.
- ๋ค๋ฅธ ๋ฐฉ๋ฒ
- const nonce = await provider.getTransactionCount(admin.address);
Type error: Cannot find module '../typechain-types' or its corresponding type declarations.
๊ทธ๋ฅ typechain-types ํด๋๋ฅผ ์ฐ์ง ์๊ธฐ๋ก ํจ
Error HH412: Invalid import
Error HH412: Invalid import @poohnet/pooh-swap-v2-core/contracts/interfaces/IUniswapV2Factory.sol from contracts/periphery/UniswapV2Router01.sol. Trying to import file using the own package's name.
- import ๋์์ธ @poohnet/pooh-swap-v2-core๊ณผ package.json์ name์ด ๋์ผํด์ ์๊ธด ๋ฌธ์
- chatGPT์๊ฒ ๋ฌผ์ด์ ํด๊ฒฐ๋จ.
Error: network does not support ENS
๋ค์๊ณผ ๊ฐ์ด VAULT_CONTRACT ์ฃผ์ ์๋ชป๋จ, ์ฆ, 0x๊ฐ ๋๋ฒ ์ฐ์ด๊ณ ์์์. VAULT_CONTRACT=0x0x7f28F281d57AC7d99A8C2FAd2d37271c2c9c67D6
L1-governance ๋ฐฐํฌ ์๋ฌ
L1-governance git:(main) โ yarn hardhat run --network localnet ./scripts/deploy.ts
yarn run v1.22.19
warning package.json: No license field
$ /Users/hyunjaelee/work/tutorials/L1-governance/node_modules/.bin/hardhat run --network localnet ./scripts/deploy.ts
TypeError: (0 , ethers_1.getAddress) is not a function
๐ ๋ค์์ ์ธ๋จ๊ณ ํ์
- yarn add --dev hardhat @nomiclabs/hardhat-ethers@npm:hardhat-deploy-ethers ethers
- const deployed = await contract.waitForDeployment();
- console.log(
Governance contract was successfully deployed at ${await deployed.getAddress()});
๐ ์์ธ
- ethers ๋ฒ์ ์ด 6์ผ๋ก ์ ๊ทธ๋ ์ด๋๋๋ฉด์ ํจ์๋ช ์ด ๋ฐ๋์์
- ๊ธฐํ
- 0xAe9Bc22B80D98aD3350a35118F723d36d8E4e141
wait ํจ์์ ์ธ์
The wait() function of ContractTransaction takes a single optional argument, which is the timeout in blocks. The default timeout is 10 blocks. This means that the wait() function will block for up to 10 blocks before throwing an error if the transaction has not been confirmed. You can increase the timeout period by passing a higher number to the wait() function. For example, the following code will block for up to 20 blocks before throwing an error:
Contract Size
https://ethereum.stackexchange.com/questions/31515/how-to-check-the-size-of-a-contract-in-solidity
Exceeds Gas Limit ์๋ฌ
- Genesis.json์์ gasLimit๋ฅผ ์๋ฌ ๋ด์ฉ์
- ์๋ฌ๋ด์ฉ "gasLimit: BigNumber { _hex: '0x989680', _isBigNumber: true }" ๋งํผ์ผ๋ก ๋๋ ค์ค.
Error: Error: processing response error (body="{\"jsonrpc\":\"2.0\",\"id\":151,\"error\":{\"code\":-32000,\"message\":\"exceeds block gas limit\"}}\n", error={"code":-32000}, requestBody="{\"method\":\"eth_sendRawTransaction\",\"params\":[\"0x02f90fd382300d0284461bffd584461bffd58398968094572b9410d9a14fa729f3af92cb83a07aaa472de080b90f644af63f020000000000000000000000000000000000000000000000000000000000000040fe07c7c6f88cdf003f00c1e47076de3576e136c7114496823271143b3d46e97e0000000000000000000000000000000000000000000000000000000000000ef9608060405234801561001057600080fd5b50610ed9806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bb7565b61014d610148366004610a85565b6104ef565b604051610111929190610bd1565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c59565b610690565b60405161011193929190610cb3565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610cdb565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c59565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d11565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d2a565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d59565b6020026020010151905087878381811061035d5761035d610d59565b905060200281019061036f9190610d88565b6040810135958601959093506103886020850185610cdb565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dc6565b6040516103ba929190610e2b565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d2a565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d59565b90506020028101906105749190610e3b565b92506105836020840184610cdb565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dc6565b6040516105b4929190610e2b565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d59565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d2a565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d59565b6020026020010151905086868381811061074c5761074c610d59565b905060200281019061075e9190610e6f565b925061076d6020840184610cdb565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dc6565b60405161079e929190610e2b565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d2a565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d59565b602002602001015190508686838181106108fb576108fb610d59565b905060200281019061090d9190610e3b565b925061091c6020840184610cdb565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dc6565b60405161094d929190610e2b565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600082825180855260208086019550808260051b84010181860160005b84811015610baa578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9681860183610ac7565b9a86019a9450505090830190600101610b48565b5090979650505050505050565b602081526000610bca6020830184610b2b565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c4b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c39868351610ac7565b95509284019290840190600101610bff565b509398975050505050505050565b600080600060408486031215610c6e57600080fd5b83358015158114610c7e57600080fd5b9250602084013567ffffffffffffffff811115610c9a57600080fd5b610ca686828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd26060830184610b2b565b95945050505050565b600060208284031215610ced57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bca57600080fd5b600060208284031215610d2357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dbc57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610dfb57600080fd5b83018035915067ffffffffffffffff821115610e1657600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dbc57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dbc57600080fdfea2646970667358221220eca0cb14f4322010c8eb410ba0738474f94c966328e9db21a580ada159aa6c8564736f6c6343000811003300000000000000c080a086a949d9a5e6c0fca3315b4363c12e9a3953b20445bf0fbe3f659212e7792c92a02e2e4680f844eab38c40aa61874bc199fc45d96ac3d91fe668039df54e060786\"],\"id\":151,\"jsonrpc\":\"2.0\"}", requestMethod="POST", url="http://localhost:8545", code=SERVER_ERROR, version=web/5.7.1)
at Logger.makeError (/Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/logger/src.ts/index.ts:269:28)
at Logger.throwError (/Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/logger/src.ts/index.ts:281:20)
at /Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/web/src.ts/index.ts:341:28
at step (/Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/web/lib/index.js:33:23)
at Object.next (/Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/web/lib/index.js:14:53)
at fulfilled (/Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/web/lib/index.js:5:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
reason: 'processing response error',
code: 'SERVER_ERROR',
body: '{"jsonrpc":"2.0","id":151,"error":{"code":-32000,"message":"exceeds block gas limit"}}\n',
error: Error: exceeds block gas limit
at getResult (/Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:142:28)
at processJsonFunc (/Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/web/src.ts/index.ts:383:22)
at /Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/web/src.ts/index.ts:320:42
at step (/Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/web/lib/index.js:33:23)
at Object.next (/Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/web/lib/index.js:14:53)
at fulfilled (/Users/hyunjaelee/work/zksync-era/node_modules/@ethersproject/web/lib/index.js:5:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
code: -32000,
data: undefined
},
requestBody: '{"method":"eth_sendRawTransaction","params":["0x02f90fd382300d0284461bffd584461bffd58398968094572b9410d9a14fa729f3af92cb83a07aaa472de080b90f644af63f020000000000000000000000000000000000000000000000000000000000000040fe07c7c6f88cdf003f00c1e47076de3576e136c7114496823271143b3d46e97e0000000000000000000000000000000000000000000000000000000000000ef9608060405234801561001057600080fd5b50610ed9806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bb7565b61014d610148366004610a85565b6104ef565b604051610111929190610bd1565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c59565b610690565b60405161011193929190610cb3565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610cdb565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c59565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d11565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d2a565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d59565b6020026020010151905087878381811061035d5761035d610d59565b905060200281019061036f9190610d88565b6040810135958601959093506103886020850185610cdb565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dc6565b6040516103ba929190610e2b565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d2a565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d59565b90506020028101906105749190610e3b565b92506105836020840184610cdb565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dc6565b6040516105b4929190610e2b565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d59565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d2a565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d59565b6020026020010151905086868381811061074c5761074c610d59565b905060200281019061075e9190610e6f565b925061076d6020840184610cdb565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dc6565b60405161079e929190610e2b565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d2a565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d59565b602002602001015190508686838181106108fb576108fb610d59565b905060200281019061090d9190610e3b565b925061091c6020840184610cdb565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dc6565b60405161094d929190610e2b565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600082825180855260208086019550808260051b84010181860160005b84811015610baa578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9681860183610ac7565b9a86019a9450505090830190600101610b48565b5090979650505050505050565b602081526000610bca6020830184610b2b565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c4b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c39868351610ac7565b95509284019290840190600101610bff565b509398975050505050505050565b600080600060408486031215610c6e57600080fd5b83358015158114610c7e57600080fd5b9250602084013567ffffffffffffffff811115610c9a57600080fd5b610ca686828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd26060830184610b2b565b95945050505050565b600060208284031215610ced57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bca57600080fd5b600060208284031215610d2357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dbc57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610dfb57600080fd5b83018035915067ffffffffffffffff821115610e1657600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dbc57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dbc57600080fdfea2646970667358221220eca0cb14f4322010c8eb410ba0738474f94c966328e9db21a580ada159aa6c8564736f6c6343000811003300000000000000c080a086a949d9a5e6c0fca3315b4363c12e9a3953b20445bf0fbe3f659212e7792c92a02e2e4680f844eab38c40aa61874bc199fc45d96ac3d91fe668039df54e060786"],"id":151,"jsonrpc":"2.0"}',
requestMethod: 'POST',
url: 'http://localhost:8545',
transaction: {
type: 2,
chainId: 12301,
nonce: 2,
maxPriorityFeePerGas: BigNumber { _hex: '0x461bffd5', _isBigNumber: true },
maxFeePerGas: BigNumber { _hex: '0x461bffd5', _isBigNumber: true },
gasPrice: null,
gasLimit: BigNumber { _hex: '0x989680', _isBigNumber: true },
to: '0x572b9410D9a14Fa729F3af92cB83A07aaA472dE0',
value: BigNumber { _hex: '0x00', _isBigNumber: true },
data: '0x4af63f020000000000000000000000000000000000000000000000000000000000000040fe07c7c6f88cdf003f00c1e47076de3576e136c7114496823271143b3d46e97e0000000000000000000000000000000000000000000000000000000000000ef9608060405234801561001057600080fd5b50610ed9806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bb7565b61014d610148366004610a85565b6104ef565b604051610111929190610bd1565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c59565b610690565b60405161011193929190610cb3565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610cdb565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c59565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d11565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d2a565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d59565b6020026020010151905087878381811061035d5761035d610d59565b905060200281019061036f9190610d88565b6040810135958601959093506103886020850185610cdb565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dc6565b6040516103ba929190610e2b565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d2a565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d59565b90506020028101906105749190610e3b565b92506105836020840184610cdb565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dc6565b6040516105b4929190610e2b565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d59565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d2a565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d59565b6020026020010151905086868381811061074c5761074c610d59565b905060200281019061075e9190610e6f565b925061076d6020840184610cdb565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dc6565b60405161079e929190610e2b565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d2a565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d59565b602002602001015190508686838181106108fb576108fb610d59565b905060200281019061090d9190610e3b565b925061091c6020840184610cdb565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dc6565b60405161094d929190610e2b565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600082825180855260208086019550808260051b84010181860160005b84811015610baa578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9681860183610ac7565b9a86019a9450505090830190600101610b48565b5090979650505050505050565b602081526000610bca6020830184610b2b565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c4b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c39868351610ac7565b95509284019290840190600101610bff565b509398975050505050505050565b600080600060408486031215610c6e57600080fd5b83358015158114610c7e57600080fd5b9250602084013567ffffffffffffffff811115610c9a57600080fd5b610ca686828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd26060830184610b2b565b95945050505050565b600060208284031215610ced57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bca57600080fd5b600060208284031215610d2357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dbc57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610dfb57600080fd5b83018035915067ffffffffffffffff821115610e1657600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dbc57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dbc57600080fdfea2646970667358221220eca0cb14f4322010c8eb410ba0738474f94c966328e9db21a580ada159aa6c8564736f6c6343000811003300000000000000',
accessList: [],
hash: '0x7893259b825674bcb88e9fe491b4390d5f70b8a807cdc57169470db07f431c6c',
v: 0,
r: '0x86a949d9a5e6c0fca3315b4363c12e9a3953b20445bf0fbe3f659212e7792c92',
s: '0x2e2e4680f844eab38c40aa61874bc199fc45d96ac3d91fe668039df54e060786',
from: '0x52312AD6f01657413b2eaE9287f6B9ADaD93D5FE',
confirmations: 0
},
transactionHash: '0x7893259b825674bcb88e9fe491b4390d5f70b8a807cdc57169470db07f431c6c'
}
error Command failed with exit code 1.
hardhat-gas-reporter
hardhat.config.ts ์ฐธ๊ณ : https://github.com/poohgithub/zksync-era/blob/main/poohnet/paymaster-examples/contracts/hardhat.config.ts
Git
๐๐๐ฆโพ๏ธ๐ณ๐๐ผ๐ธ๐๐๐๐ถ๐ฆโ๏ธ๐โป
error: cannot run delta: No such file or directory
๐ ํด๊ฒฐ
brew install git-delta
sudo apt install git-extras
์ด๋ ๊ฒ ํด๋ git diff๋ ์๋๊ธฐ ๋๋ฌธ์ git-delta ๋ช ๋ น๋ง ์ฌ์ฉํ๊ธฐ
fatal: Not possible to fast-forward, aborting.
๐ ํด๊ฒฐ
git fetch origin
git rebase origin/main
Dev Errors
๐๐๐ฆโพ๏ธ๐ณ๐๐ผ๐ธ๐๐๐๐ถ๐ฆโ๏ธ๐โป
failed to compute cache key: "/target/debug/zksync_server" not found: not found
Error: Child process exited with code 1
๐ ํด๊ฒฐ
- .dockerignore์์ ํฌํจ๋์ด ์๋ ๊ฒ์ ์๋์ง ํ์ธ ํ์
- ๋ง์ฝ ๋ก์ปฌ ์์คํ ์์ ๋ณต์ฌ๋๋ ๊ฒ์ด๋ผ๋ฉด ์๋ ์๋ ๊ฒ์ผ ์๋ ์์. ์๋ฅผ ๋ค์ด ์ปดํ์ผ์ ํด์ผ ๋์ค๋ ํ์ผ์ด๋๊ฐ ํ๋ฉด ๊ทธ๋ฐ์ผ์ด ๋ฐ์
Errors
1. Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation underflowed or overflowed outside of an unchecked block)
- ์ฐ์ฐ์ด ์์๊ฐ ๋ ๋, ์ฐฌ๋ฐํ ๊ณ์ฐ์ ๋ฐ์
2. Error: cannot estimate gas; transaction may fail or may require manual gas limit (error="Error: VM Exception while processing transaction: reverted with reason string 'E004'"
Error: cannot estimate gas; transaction may fail or may require manual gas limit (error="Error: VM Exception while processing transaction: reverted with reason string 'E004'", tx={"data":"0x1e28886e3a38e54d9c9b01a63cae0476c624f670359871e7b1463a777cba3247240e31fd76129d005b6f526cbaaf1e1e37494d8091c109bfcf47881a612190af683c1e27000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000412dcb94cce59dd93b63aae7cedc6f7f0b64083b6a29b6f8ce403b2b8f862d8a5a17a797b880310346766ca58d2b9a01b4060b3bfcd7ad02c9aec7da9cd41f77431b00000000000000000000000000000000000000000000000000000000000000","to":{},"from":"0x0e1eE98EDF5BDbc5caaFed491526A0Cd3eD31fad","type":2,"maxFeePerGas":{"type":"BigNumber","hex":"0xa650c80c"},"maxPriorityFeePerGas":{"type":"BigNumber","hex":"0x9502f900"},"nonce":{},"gasLimit":{},"chainId":{}}, code=UNPREDICTABLE_GAS_LIMIT, version=abstract-signer/5.5.0)
3. Error: cannot estimate gas; transaction may fail or may require manual gas limit
Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (error={"reason":"VM Exception while processing transaction: reverted with reason string 'E000'","code":"UNPREDICTABLE_GAS_LIMIT","method":"estimateGas","transaction":{"from":"0x3287f4b4953471234DbeAFf7d2F9EA58dFedD7fd","maxPriorityFeePerGas":{"type":"BigNumber","hex":"0x59682f00"},"maxFeePerGas":{"type":"BigNumber","hex":"0xa80d7dfe"},"to":"0xeEdC2Ac65dF232AB6d229EBD4E3F564e194ffe7D","value":{"type":"BigNumber","hex":"0x056bc75e2d63100000"},
- ์ด์ฝ๋์์ ๋ฐ์ "IVoteraVote(voteAddress).init("
- ์ด ํจ์๋ฅผ CommonsBudget์์ ํธ์ถ๋์ด์ผํ๋๋ฐ, CommonsStorage์์ ํธ์ถ๋์ด์ initVote์์ ๋ฌธ์ ๊ฐ ๋ฐ์.
4. AssertionError: Expected transaction to be reverted with E001, but other exception was thrown: RangeError: Maximum call stack size exceeded
a. typechain ๋ชจ๋ ์
๊ทธ๋ ์ด๋
b. ์ด ์ปค๋ฐ ์ฐธ์กฐ
5. TypeError: Cannot read property 'eth' of undefined [closed]
โ ์ด ์ฝ๋ ์คํ์ ๋ฐ์
ยง hre.web3.eth.accounts.decrypt(data,"boa2022!@");
โ ๋ค์ ์ค์น ํ์
ยง npm install -s web3
ยง npm install -s @nomiclabs/hardhat-web3
โ hardhat.config.ts์์ ๋ค์ ์ถ๊ฐ
ยง import"@nomiclabs/hardhat-web3";
โ ๊ฒฐ๊ตญ hardhat๊ณผ web3๋ฅผ ์ฐ๊ฒฐํ๋ ์์
์ด ํ์ํจ.
6. HardhatError: HH103: Account 0x3e29aefa7af16625691a9fca4a7fff0624aabc6f is not managed by the node you are connected to.
hardhat.config.ts์ getAccountsํจ์์ ํด๋น ๊ณ์ข๋ฅผ ์ถ๊ฐํด์ผํจ.
ยง accounts:[process.env.ADMIN_KEY||"",process.env.VOTE_KEY||"",process.env.USER_KEY||"",process.env.MANAGER_KEY||""],
7. docker: Got permission denied while trying to connect to the Docker daemon socket
- ์ด๊ฑด screen์ ๋ค์ด๊ฐ์ ์คํํด์ค์ผ ํจ.
1.Create the docker group if it does not exist
$ sudo groupadd docker
2.Add your user to the docker group.
$ sudo usermod -aG docker $USER
3.Run the following command or Logout and login again and run (that doesn't work you may need to reboot your machine first)
$ newgrp docker
8. Authority๋ ธ๋๋ฅผ ์คํ์ํฌ๋, block number๊ฐ ๋์ด๋์ง ์์๋
- run_node๋ฅผ ํตํด์ ์คํ์ํค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ด๋ถ IP์ ๋ํ ๋ก๊ทธ๊ฐ ๋์๋ ๋ฌธ์ ๋ ์๋.
self=enode://6d59a1ce195d9251e8f5234b3dbd486cf15eeac6cb8199898af3e11b9b7f5c54e334317d1cc3ab8077360383bc08b8aa93299ccb169b55dbea59414847dbce2d@127.0.0.1:30303
- run_node ์คํฌ๋ฆฝํธ์ bootnode ํญ๋ชฉ์ ๋ค์ด๊ฐ๋ enode์ IP๊ฐ์ด ๋ง์์ผ ํจ.
- static_node.json์ enode ์ ๋ณด๋ฅผ ์ ํํ ์จ์ค์ผ ํจ.
- Node1์ ์ธ๋ถ IP๋ฅผ ํ ๋นํ์๋ ์ฌ๋ถํ ํ์ํจ.
- ์ฑํฌํ๋๋ฐ ์๊ฐ์ด ์ข ๊ฑธ๋ฆผ.
9. Merge pull request #1 from linked0/initial-code
ยฎ ๋๋ฒ์งธ ์ปค๋ฐ์ <Hyunjae Lee>์ด๊ณ , ์ธ๋ฒ์งธ ์ปค๋ฐ์ <Jay>๋ก ๋์ด ์์.
10. ์ด๋ฏธ ์ํฌํธ๋ ๊ณ์ ์ด ์๋๋ฐ ๋ค์ ์ํฌํธ๋ฅผ ํ๋ ค๊ณ ํ ๋ ์๋ฌ๊ฐ ๋จ๋๋ฐ ๊ด๋ จ ์ค๋ช
Imported Accounts are accounts you import using a private key string or a private key JSON file, and were not created with the same Secret Recovery Phrase as your wallet and accounts. For this reason, these accounts will not appear automatically when you restore your MetaMask account with your Secret Recovery Phrase. The data associated with your MetaMask Secret Recovery Phrase cannot be added or extended to the imported account.
11. An unexpected error occurred:
Error: Cannot find module './IERC165__factory' โข ํด๊ฒฐ: typechain-types์ artifacts ํด๋ ์ญ์ โข ์์ธ ๋ด์ฉ
Require stack:
- /Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/@openzeppelin/contracts/utils/introspection/index.ts
- /Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/@openzeppelin/contracts/utils/index.ts
- /Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/@openzeppelin/contracts/index.ts
- /Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/@openzeppelin/index.ts
- /Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/index.ts
- /Users/hyunjaelee/work/commons-budget-contract/typechain-types/index.ts
- /Users/hyunjaelee/work/commons-budget-contract/test/VoteHelper.ts
- /Users/hyunjaelee/work/commons-budget-contract/test/AdminAction.test.ts
- /Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/node_modules/mocha/lib/mocha.js
- /Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/node_modules/mocha/index.js
- /Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/builtin-tasks/test.js
- /Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/internal/core/tasks/builtin-tasks.js
- /Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/internal/core/config/config-loading.js
- /Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/internal/cli/cli.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as _resolveFilename] (/Users/hyunjaelee/work/commons-budget-contract/node_modules/@cspotcode/source-map-support/source-map-support.js:679:30)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/@openzeppelin/contracts/utils/introspection/index.ts:4:1)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Module.m._compile (/Users/hyunjaelee/work/commons-budget-contract/node_modules/ts-node/src/index.ts:1459:23)
at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Object.require.extensions.<computed> [as .ts] (/Users/hyunjaelee/work/commons-budget-contract/node_modules/ts-node/src/index.ts:1462:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/@openzeppelin/contracts/utils/introspection/index.ts',
'/Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/@openzeppelin/contracts/utils/index.ts',
'/Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/@openzeppelin/contracts/index.ts',
'/Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/@openzeppelin/index.ts',
'/Users/hyunjaelee/work/commons-budget-contract/typechain-types/factories/index.ts',
'/Users/hyunjaelee/work/commons-budget-contract/typechain-types/index.ts',
'/Users/hyunjaelee/work/commons-budget-contract/test/VoteHelper.ts',
'/Users/hyunjaelee/work/commons-budget-contract/test/AdminAction.test.ts',
'/Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/node_modules/mocha/lib/mocha.js',
'/Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/node_modules/mocha/index.js',
'/Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/builtin-tasks/test.js',
'/Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/internal/core/tasks/builtin-tasks.js',
'/Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/internal/core/config/config-loading.js',
'/Users/hyunjaelee/work/commons-budget-contract/node_modules/hardhat/internal/cli/cli.js'
]
}
12. Unexpected end of JSON input ์๋ฌ
npx hardhat run scripts/deploy.ts --network devnet ์คํ์ ๋ฐ์
ํด๊ฒฐ๋ฐฉ๋ฒ: Delete currupted find, hardhat clean & reinstall
- cd /home/ubuntu/.cache/hardhat-nodejs/compilers/linux-amd64
- rm list.json
- npx hardhat clean <-- ์๋ ํด๋๋ก ๋์์์.
- yarn install
- yarn build
์๋ฌ ๋ด์ฉ I
An unexpected error occurred:
SyntaxError: /Users/hyunjaelee/work/commons-budget-contract/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.dbg.json: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at /Users/hyunjaelee/work/commons-budget-contract/node_modules/jsonfile/index.js:33:18
at /Users/hyunjaelee/work/commons-budget-contract/node_modules/graceful-fs/graceful-fs.js:123:16
at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3)
- ์๋ฌ ๋ด์ฉ II
yarn run v1.22.22
$ hardhat run --network devnet scripts/deploy-factory.js
An unexpected error occurred:
SyntaxError: /home/ubuntu/.cache/hardhat-nodejs/compilers/linux-amd64/list.json: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at /home/ubuntu/tigger-swap/node_modules/jsonfile/index.js:33:18
at /home/ubuntu/tigger-swap/node_modules/graceful-fs/graceful-fs.js:123:16
at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read/context:68:3)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
13. HardhatError: HH103: Account 0x3e29aefa7af16625691a9fca4a7fff0624aabc6f is not managed by the node you are connected to.
- ๋ฐ์์์ : npx hardhat run scripts/set_owner.ts --network testnet
- ํด๊ฒฐ: hardhat.config.ts์์๋ง ์ธํ ํ ๊ณ์ ๋ง ์ฌ์ฉํ ์ ์์.
14. TypeError: Cannot read properties of undefined (reading 'sourceName')
- ๋ฐ์์์ :
yarn test๋ก fulfillOrder ํ ์คํธ - ํด๊ฒฐ: yarn add --dev hardhat@ir
- ์๋ฌ ์์ธ๋ด์ฉ
/Users/hyunjaelee/work/seaport/node_modules/hardhat/internal/hardhat-network/stack-traces/solidity-errors.js:111
return new SolidityCallSite(sourceReference.sourceName, sourceReference.contract, sourceReference.function !== undefined
^
TypeError: Cannot read properties of undefined (reading 'sourceName')
(Use `node --trace-uncaught ...` to show where the exception was thrown)
error Command failed with exit code 7.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
15. .
- Seaport ํ ์คํธ ์ฝ๋ ์์ฑ์ ๋ฌธ์ ์๊น
- ํ ์คํธ์ฝ๋์์ ์ปจํธ๋ํธ ํจ์ ํธ์ถ์ signer๋ก connectํด์ผํ๋๋ฐ ๊ทธ๋ฅ wallet์ผ๋ก connect ํจ
- Hardhat ๋คํธ์ํฌ์์ ์ฌ์ฉํ ๊ณ์ ์ hardhat.config.ts์ getAccountํจ์์์ ์ถ๊ฐํ๋ฉด ๋จ.
16. Uncaught ReferenceError: Buffer is not defined
์ฌ๊ธฐ ์คํ ์ค๋ฒํ๋ก์ฐ ์ฐธ์กฐ
import{ Buffer} from'buffer';
// @ts-ignorewindow.Buffer= Buffer;
- Error HH700: Artifact for contract "hardhat/console.sol:console" not found.
- npx hardhat clean ์คํ
- TestNet์์ Contract ๋ฐฐํฌ์ UND_ERR_CONNECT_TIMEOUT์ด ๋ฐ์
- ๋ค์๊ณผ ๊ฐ์ด ์ฒ๋ฆฌ๋จ
- RPC๋ฅผ ๋ค๋ฅธ ๋ ธ๋์ ๋ถ์
- ๋ฌธ์ ๊ฐ ์๊ธด ๋ ธ๋๋ฅผ ํธ๋์ญ์ ํ์ ๋ ๋ ค๋ฒ๋ฆผ
19. TestNet์์ Contract ๋ฐฐํฌ ์คํฌ๋ฆฝํธ ์คํ์ ๋ค์ ํ๋กฌํํธ๋ก ์ ๋จ์ด์ง๊ณ ๋จนํต]
- Nonce๊ฐ์ด ๊ผฌ์ฌ์ ๊ทธ๋ ๊ฒ ๋จ
- Nonce๊ฐ์ด ๊ผฌ์ธ ์ด์ ๋ ๋ด ๊ฐ์ธ ํ๋ก์ ํธ์ธ web2/nft-market์์ NonceManager๋ฅผ ์ฌ์ฉํ์ง ์์์ ์๊ธด ๋ฌธ์
- ์ผ๋จ ๋ฌธ์ ๊ฐ ์๊ธด ๊ณ์ (์ฆ Contract๋ฅผ ๋ฐฐํฌํ๋ ์ฃผ์)์์ ๋ค์ดํฐ๋ธ ํ ํฐ์ ๋ณด๋ด๊ธฐ ๋ช๋ฒํ๋ฉด ๋จ.
20. npm ERR! code EINTEGRITY
npm ERR! sha1-UzRK2xRhehP26N0s4okF0cC6MhU=sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== integrity checksum failed when using sha1: wanted sha1-UzRK2xRhehP26N0s4okF0cC6MhU=sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== but got sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== sha1-UzRK2xRhehP26N0s4okF0cC6MhU=. (42300 bytes)
- yarn install์ ์จ์ผํ๋ ๊ณณ์์ npm install์ ์ผ์๋ ๋ํ๋จ
21. Error: error:0308010C:digital envelope routines::unsupported
์๋ฌ ๋ด์ฉ
- hardhat compile --config ./hardhat.config.ts
- An unexpected error occurred:
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:67:19)
at createHash (node:crypto:133:10)
at ripemd160 (/Users/hyunjaelee/work/pooh-land/node_modules/@ethersproject/sha2/src.ts/sha2.ts:14:29)
at new HDNode (/Users/hyunjaelee/work/pooh-land/node_modules/@ethersproject/hdnode/src.ts/index.ts:115:67)
at Function.HDNode._fromSeed (/Users/hyunjaelee/work/pooh-land/node_modules/@ethersproject/hdnode/src.ts/index.ts:258:16)
at Function.HDNode.fromMnemonic (/Users/hyunjaelee/work/pooh-land/node_modules/@ethersproject/hdnode/src.ts/index.ts:269:23)
at Function.Wallet.fromMnemonic (/Users/hyunjaelee/work/pooh-land/node_modules/@ethersproject/wallet/src.ts/index.ts:192:34)
at Function.Wallet.createRandom (/Users/hyunjaelee/work/pooh-land/node_modules/@ethersproject/wallet/src.ts/index.ts:177:23)
at getAccounts (/Users/hyunjaelee/work/pooh-land/hardhat.config.ts:35:26)
at Object.<anonymous> (/Users/hyunjaelee/work/pooh-land/hardhat.config.ts:116:17) {
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'
ํด๊ฒฐ
export NODE_OPTIONS=--openssl-legacy-provider
22. jiyoungminjung์ผ๋ก ์ฒ์์ push๋ฅผ ํ๋ ค๊ณ ํ ๋ ๊ถํ ๋ฌธ์ ๋ฐ์
- ์๋ฌ ๋ด์ฉ To github.com:jiyoungminjung/pooh-land-js.git ! [remote rejected] readme -> readme (permission denied) error: failed to push some refs to 'git@github.com:jiyoungminjung/pooh-land-js.git'
- ํด๊ฒฐ
- jiyoungminjung์ ๊ณ์ setting์์ SSH key๋ฅผ ๋ฑ๋กํจ.
23. BigInt ์ธ์ ๋ชปํ๋ ๋ฌธ์
๊ด๋ จ github repo: github.com:poohgithub/pooh-swap-v2-core.git
const swapTestCases: BigInt[][] = [
[1, 5, 10, '1662497915624478906'],
[1, 10, 5, '453305446940074565'],
[2, 5, 10, '2851015155847869602'],
[2, 10, 5, '831248957812239453'],
[1, 10, 10, '906610893880149131'],
[1, 100, 100, '987158034397061298'],
[1, 1000, 1000, '996006981039903216']
].map(a => a.map(n => (typeof n === 'string' ? BigInt(n) : BigInt(n * 10 ** 18))));
swapTestCases.forEach((swapTestCase, i) => {
it(`getInputPrices:${i}`, async () => {
const swapAmount = BigInt(swapTestCase[0].toString());
const token0Amount = BigInt(swapTestCase[1].toString());
const token1Amount = BigInt(swapTestCase[2].toString());
const expectedOutputAmount = BigInt(swapTestCase[3].toString());
await addLiquidity(token0Amount, token1Amount);
await token0.transfer(pair.target, swapAmount);
await expect(pair.swap(0, expectedOutputAmount + 1n, admin.address, '0x', overrides)).to.be.revertedWith('UniswapV2: K');
await pair.swap(0, expectedOutputAmount, admin.address, '0x', overrides);
});
});
Codes
Solidity์ address type์ด TypeScript์์๋ string
TypeScript ํ๋ก๊ทธ๋จ์ ํ๋ผ๋ฏธํฐ ์ถ๊ฐ
async function main() {
const parameter = process.env.PARAMETER;
console.log("Received parameter:", parameter);
// Your deployment or other script logic here
}
PARAMETER=value npx hardhat run deploy.ts
Agora Locanet ์คํ
- ์ฌ์ฉ์ root ํด๋์ git@github.com:bosagora/agoranet.git ์์ค ๋ค์ด๋ก๋((์ฌ์ฉ์ ๋ฃจํธ ํด๋์ ํด๋ก๋ ํด์ผํจ)
- cd ~/agoranet/michal/
- docker ์คํ
- cmd/el/init_node 1 ์คํ
- sudo๊ฐ ๋ค์ด๊ฐ ์์ด์ ๊ฐ์ธ PC ์ํธ๊ฐ ํ์ํจ.
- cmd/el/run_node 1
- LOCALNET_URL=http://127.0.0.1:8545 ยท chain id: 34559 ยท Admin์ ๋์ ๋ฃ์ด์ฃผ๊ธฐ
- ๋ฐฉ๋ฒ: ๋์ ์ด๋ฏธ ๊ฐ์ง๊ณ ์๋ ํค๋ฅผ ์ฃผ์ ๋ค๊ณ ํจ.
- 0xb16ae920b229e39555024802925f663071625a998cb1c0ecf88878841fa748e6 ยท CommonsBudget ๋ฐฐํฌ ยท config/el/genesis_bosagora.json์ ๋ค์๊ณผ ๊ฐ ์ธํ
- bosagoraBlock: ์ปค๋จผ์ค ๋ฒ์ง ๋ฐํ์ ์์๋ ๋ธ๋ญ, ๋ฐฐํฌ๋ ๋ธ๋ญ์ 20~30๊ฐ ์ดํ ์ ๋น.
- commonsBudget: ๋ฐฐํฌ๋ CommonsBudget Address
Subgraph ๊ฐ๋ฐ์ ๊ฑธ๋ฆฐ ์๊ฐ: ๋ฑ 10์ผ
๊ฐ์: ๋ฌธ์ ํ์ ์ด 3์ผ, ํ ์คํธ๊ฐ 4์ผ, ์ค์ ๊ฐ๋ฐ: 3์ผ Post Mortem
- ๋ฌธ์์ ๋ํ ์ข ๋ ๊ผผ๊ผผํ ๋ถ์์ด ํ์ ํ์.
- chatGPT๋ก ์ธํด์ ๊ฐ๋ฐ๊ธฐ๊ฐ์ด 1/3๋ก ๋จ์ถ๋จ
- ๋ชฉ/๊ธ/ํ(2/9~10, 2/14): Graph ๊ตฌ์กฐ ํ์
- ์(2/15): ์ค์ ์คํ ๊ด๋ จ ์๋ฃ ์กฐ์ฌ
- ๋ชฉ/๊ธ(2/16~17): Goerli/local ๋ ธ๋์์ ์์ ๋๋ ค๋ณด๊ธฐ
- ์(20): ํ ์คํธ๋ท ์์ ์ปจํธ๋ํธ ํ ์คํธ
- ํ/์(21~22): ERC1155/ERC721/AssetContract์ ๋ํ ํ ์คํธ ์๋ฃ
- ๋ชฉ(23): ํ ์คํธ๋ท์์ ์คํค๋ง ๋ฐ ๋งคํ 1์ฐจ ๊ฐ๋ฐ ์๋ฃ
hardhat ํ๋ก์ ํธ ๊ฐ๋ฐ์ ์ฐธ๊ณ
๊ฐ๋
- const receipt = await (await tx).wait(); ยง tx๋ sendTransaction()์์ ๋ฆฌํดํ Promise์ด๋ค.
Solidity version
ยท ๊ฐ์ฅ ํ์คํ ํํ โ pragma solidity >=0.8.0 <=0.8.10; ยท pragma solidity ^0.5.2; โ 0.5.2 ์ด์ ๋ฒ์ ์ปดํ์ผ๋ฌ๋ก๋ ์ปดํ์ผ ์๋จ โ 0.6.0 ์ผ๋ก ์์๋๋ ๋ฒ์ ์๋ ์ปดํ์ผ ์๋จ (^๊ฐ ๊ทธ๋ฐ ์๋ฏธ์)
harthat ํ๋ก์ ํธ ๋ง๋ค๊ธฐ
In our case we created the folder named ProjetoLivroNFTERC1155OZ.
- Start npm in standard mode. npm init -y
- Install the hardhat. npm install --save-dev hardhat yarn add --dev hardhat <== yarn์ผ๋ก ์ธ์คํจํ ๊ฒฝ์ฐ.
- Install OpenZeppelin smart contracts. npm install @openzeppelin/contracts
- Install required modules and dependencies. npm install --save-dev @nomiclabs/hardhat-waffle npm install --save-dev "@nomiclabs/hardhat-ethers@^2.0.0" "ethereum- waffle@^3.4.0" "ethers@^5.0.0"
- Install the dotenv module. npm install dotenv
- Start the hardhat. npx hardhat
delegatecall ๊ดํ์ฌ
Medium delegatecall Preventing Vulnerabilities in Solidity - Delegate Call Stackexchange Solidity storage Storage slot in Inheritance
pragma solidity ^0.8.0; import "hardhat/console.sol";
contract Executor { uint256 public luckyNumber; address public sender; uint256 public value;
function setLuckyNumber(uint256 _luckyNumber) public payable { luckyNumber = _luckyNumber; sender = msg.sender; value = msg.value; }
function showNumber() public { console.log("luckeyNumber:", luckyNumber); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "hardhat/console.sol"; contract Caller { function setLuckyNumber(address executor, uint256 _luckyNumber) public payable { (bool success, bytes memory data) = executor.delegatecall( abi.encodeWithSignature("setLuckyNumber(uint256)", _luckyNumber) ); } function showNumber(address executor) public { (bool success, bytes memory data) = executor.delegatecall( abi.encodeWithSignature("showNumber()") ); } }
static call
staticcall works in a similar way as a normal call (without any value (sending eth) as this would change state). But when staticcall is used, the EVM has a STATIC flag set to true. Then, if any state modification is attempted, an exception is thrown. Once the staticcall returns, the flag is turned off.
npm publish, NPM module ๋ฐฐํฌ, ๋ชจ๋ ๋ฐฐํฌ
- ๋ณธ์ธ์ npm node ํ๋ก์ ํธ ๋ฃจํธ ํด๋๋ฅผ ๋ค์ด๊ฐ์ "npm login" ๋ช ๋ น ์คํ
- NPM ํ์ด์ง์์ ๋ก๊ทธ์ธ ์งํ, Google Authenticator ํ์
- ๋ค์ ํ๋ก์ ํธ ๋ฃจํธ ํด๋์์ "npm publish" ๋ช ๋ น ์คํ
- NPM ํ์ด์ง์์ ๋ฐฐํฌ ์งํ, Google Authenticator ํ์
Transaction์ ํํ
transaction: { hash: '0x4508d350b89655c9452d527ff1b3d307ed566228661b0a805567561ebc7590f1', type: 2, accessList: [], blockHash: '0xb0f9792fbe40b2b9c85fbdabb90e7f0e4ee08f82f9f82ef485814d3002a34c8f', blockNumber: 59, transactionIndex: 0, confirmations: 1, from: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC', gasPrice: BigNumber { value: "1000591199" }, maxPriorityFeePerGas: BigNumber { value: "1000000000" }, maxFeePerGas: BigNumber { value: "1001182398" }, gasLimit: BigNumber { value: "211019" }, to: '0x09635F643e140090A9A8Dcd712eD6285858ceBef', value: BigNumber { value: "0" }, nonce: 3, data: '0xe7acab24000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000063be212dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea4da12fc3f3f34300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000006509f2a854ba7441039fce3b959d5badd2ffcfcd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000033c0024ebc7a8989c1ae32988d5402295c8fd42b3c44cdddb6a900fa2b585dd299e03d12fa4293bc000000000000010000000064000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000010000000000000000000000006509f2a854ba7441039fce3b959d5badd2ffcfcd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003782dace9d9000000000000000000000000000000000000000000000000000003782dace9d9000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c800000000000000000000000000000000000000000000000000000000000000401fb0dfbaf5bce7c5a92402efbcec0e173531b3e3378e7b236a83eda892e6ac0603ef19202e3b2217622f4a881609e592f598fde0d14849af8b0fb024b71de187000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f688786', r: '0xe41292838da7454d5932feef08cb49c12e56721edfab2df873d79abaf35fed26', s: '0x2a9cf276597a3559d1784c95234ff0c0805e4b29e846ccbe13e59fb3f0874f2a', v: 0, creates: null, chainId: 1, wait: [Function (anonymous)] }
sendTransaction - hardhat ํ ์คํธ ์ฝ๋
const encodedData = feeCollectorContract.interface.encodeFunctionData( "unwrapAndWithdraw", [ feeAdmin.address.toString(), wboaContract.address, BigNumber.from("10") ] ); const result = await ownerSigner.sendTransaction({ to: proxyContract.address, data: encodedData });
- ๊ด๋ จ ์ฌ์ดํธ https://ethereum.stackexchange.com/questions/54845/calling-contract-function-via-web3-eth-sendtransaction-doesnt-work https://stackoverflow.com/questions/72584559/how-to-test-the-solidity-fallback-function-via-hardhat https://github.com/ethers-io/ethers.js/issues/478 https://ethereum.stackexchange.com/questions/114146/how-do-i-manually-encode-and-send-transaction-data https://github.com/ethers-io/ethers.js/issues/3522
Predicted Address
contract C {
functioncreateDSalted(bytes32 salt, uint arg) public {
// This complicated expression just tells you how the address
// can be pre-computed. It is just there for illustration.
// You actually only need new D{salt: salt}(arg).
address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
bytes1(0xff),
address(this),
salt,
keccak256(abi.encodePacked(
type(D).creationCode,
abi.encode(arg)
))
)))));
D d = newD{salt: salt}(arg);
require(address(d) == predictedAddress);
}
}
}
์ปจํธ๋ํธ ์ฌ์ด์ฆ
1. npm install --dev hardhat-contract-sizer
2. hardhat.config.ts์ ๋ค์ ๋ผ์ธ ์ถ๊ฐ
โ import "hardhat-contract-sizer";
3. npx hardhat size-contracts
์๋ ๋ฐฉ์
solc-select install 0.8.0
truffle-config.js module.exports = { networks: { development: { host: "127.0.0.1", port: 8545, network_id: "*" // Match any network id } }, compilers: { solc: { version: "^0.8.0" } } };
data = fs.readFileSync('/Users/hyunjaelee/work/commons-budget-contract/build/contracts/VoteraVote.json'); obj = JSON.parse(data); size = Buffer.byteLength(obj.deployedBytecode) / 2;
Nonce ์ค๋ฅ ๊ด๋ จํด์ ํจ๋ฆฌ๋์ด ์๊ธฐํด์ค๊ฒ
private async resetTransactionCount() { this.manager_signer.setTransactionCount(await this.manager_signer.getTransactionCount()); } 3:42 nonce-manager.ts setTransactionCount(transactionCount: ethers.BigNumberish | Promise<ethers.BigNumberish>): void { this._initialPromise = Promise.resolve(transactionCount).then((nonce) => { return ethers.BigNumber.from(nonce).toNumber(); }); this._deltaCount = 0;
TODO: boa-space-contracts conduit ๊ด๋ จ assembly ์ฝ๋ (#conduit.spec.ts)
- ๊ด๋ จ์๋ฌ
Error: call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="getDomain(bytes4,uint256)")
`boa-space-contracts` ํ๋ก์ ํธ, conduit.spec.ts 1079๋ผ์ธ ์๋ฌ. ์์ธํ ๋ด์ฉ์ web/solidity.html์์ `#conduit.spec.ts`๋ก ๊ฒ์ => test.yml ์๋ณตํด์ ํด๋ณด๊ธฐ(Run Linters, Run Reference Tests, Run "
- conduit.spec.ts ์๋ ์ฝ๋์์ ์๋ฌ๋จ
it.only("Reverts when attempting to execute transfers on a conduit when not called from a channel", async () => {
const expectedRevertReason =
getCustomRevertSelector("ChannelClosed(address)") +
owner.address.slice(2).padStart(64, "0").toLowerCase();
const tx = await conduitOne.connect(owner).populateTransaction.execute([]);
const returnData = await provider.call(tx);
expect(returnData).to.equal(expectedRevertReason);
await expect(conduitOne.connect(owner).execute([])).to.be.reverted;
});
- Conduit.sol
modifier onlyOpenChannel() {
console.log("onlyOpenChannel");
// Utilize assembly to access channel storage mapping directly.
assembly {
// Write the caller to scratch space.
mstore(ChannelKey_channel_ptr, caller())
// Write the storage slot for _channels to scratch space.
mstore(ChannelKey_slot_ptr, _channels.slot)
// Derive the position in storage of _channels[msg.sender]
// and check if the stored value is zero.
if iszero(
sload(keccak256(ChannelKey_channel_ptr, ChannelKey_length))
) {
// The caller is not an open channel; revert with
// ChannelClosed(caller). First, set error signature in memory.
mstore(ChannelClosed_error_ptr, ChannelClosed_error_signature)
// Next, set the caller as the argument.
mstore(ChannelClosed_channel_ptr, caller())
// Finally, revert, returning full custom error with argument.
revert(ChannelClosed_error_ptr, ChannelClosed_error_length)
}
}
console.log("onlyOpenChannel return");
// Continue with function execution.
_;
}
#2. Jay's code sneppets
latest forge
yarn cache clean --force
vm.expectRever(
abi.encodeWithSelector(
Raffle.Raffle__UpkeepNotNeeded.selector,
...
)
}
vm.recordLogs();
Vm.Log[] memory entries = vm.getRecordedLogs();
forge sanpshot -m testWithrawFromMultipleFunders
vm.txGasPrice(GAS_PRICE);
uint256 gasStart = gasleft();
uint256 gasEnd = gasleft();
uint256 gasUsed = (gasStart - gasEnd) * tx.gasprice;
forge inspect FundMe storageLayout
cast storage 0x...(Contract address) ์จ๋ณด๊ธฐ
cast --to-wei 15
cast balance 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
๋ฐฐํฌ ์คํฌ๋ฆฝํธ ์คํ์์๋ --broadcast๋ฅผ ์จ์ผ ํจ.
cast --calldata-decode "fund()" 0xa7ea5e4e
ํ์ด์ ์ธํฐํ๋ฌํฐ ๋ชจ๋ ๊ฐ์ ๊ฒ.
chisel - Test and receive verbose feedback on Solidity inputs within a REPL environment.
latest hardhat
๊ธฐํ: reset array ๋ฑ
uint16 ํ์
๋ ์์.
constructor (..., vrfCoordinator, ...) VRFConsumerBaseV2(vrfCoordinator) {
...
}
% ์ฐ์ฐ์๋ ์์.
address payable winner = s_players[indexOfWinner];
resetting!
s_players = new address payable[](0);
event WinnerPicked(address indexed winner);
This allows these parameters to be searchable when looking through the blockchain logs.
abi.decode
function addPerson(bytes calldata data) external {
// Assuming `data` is ABI-encoded with (string, uint8)
(string memory name, uint8 age) = abi.decode(data, (string, uint8));
// Store the information in the contract's state
people[msg.sender] = Person(name, age);
// Emit an event to log the addition
emit PersonAdded(msg.sender, name, age);
}
slot.value
function upgrade(address implementation_) external virtual {
require(_isValidSigner(msg.sender), "Caller is not owner");
require(implementation_ != address(0), "Invalid implementation address");
++state;
StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = implementation_;
}
Promise.all && map
await Promise.all(Array.from({ length: 14 }, (_, i) => i).map((i) => claimTopicsRegistry.addClaimTopic(i)));
signMessage
// ์ด๊ฑด ethers v5์ฉ์ด๋ผ ์ฐธ๊ณ ์ฉ
claimForBob.signature = await claimIssuerSigningKey.signMessage(
ethers.utils.arrayify(
ethers.utils.keccak256(
ethers.utils.defaultAbiCoder.encode(['address', 'uint256', 'bytes'], [claimForBob.identity, claimForBob.topic, claimForBob.data]),
),
),
);
// ethers v6
const signature = await signer.signMessage(
ethers.toBeArray(
ethers.solidityPackedKeccak256(
["bytes32", "address", "uint256"],
[
SIGNATURE_DELEGATION_HASH_TYPE,
delegates[index]!.address,
endTimestamp,
],
),
),
);
์ฐธ๊ณ ํ ๋ด์ฉ ๋ง์
function cheaperWithdraw() public onlyOwner {
address[] memory funders = s_funders;
// mappings can't be in memory, sorry!
for (uint256 funderIndex = 0; funderIndex < funders.length; funderIndex++) {
address funder = funders[funderIndex];
s_addressToAmountFunded[funder] = 0;
}
s_funders = new address[](0);
// payable(msg.sender).transfer(address(this).balance);
(bool success,) = i_owner.call{value: address(this).balance}("");
require(success);
}
CALLDATA
CALLDATACOPY(t, f, s): msg.data ์ f๋ฒ์งธ ์์น์์ s๊ฐ์ ๋ฐ์ดํธ๋ฅผ ์ฝ์ด ๋ฉ๋ชจ๋ฆฌ์ t๋ฒ์งธ ์์น์ ์ ์ฅํฉ๋๋ค.
create2(
callvalue(), // wei sent with current call
// Actual code starts after skipping the first 32 bytes
add(bytecode, 0x20),
(bytecode), // Load the size of code contained in the first 32 bytes
_salt // Salt from function arguments
)
Make sure that we can transfer out token 200
vm.prank(owner4);
IERC6551Executable(account4).execute(
address(account3),
0,
abi.encodeWithSignature(
"execute(address,uint256,bytes,uint8)",
address(nft),
0,
abi.encodeWithSignature(
"safeTransferFrom(address,address,uint256)", account3, newTokenOwner, 200
),
0
),
0
);
function callTransfer(address _token, address _to, uint256 _amount) external {
// This will encode the function call to `transfer(address,uint256)` with the specified arguments
bytes memory data = abi.encodeWithSignature("transfer(address,uint256)", _to, _amount);
// Making the actual call to the token contract's transfer function
(bool success, ) = _token.call(data);
require(success, "Transfer failed");
}
Nick's Factory
The registry MUST be deployed at address 0x000000006551c19487814612e58FE06813775758 using Nickโs Factory (0x4e59b44847b379578588920cA78FbF26c0B4956C) with salt 0x0000000000000000000000000000000000000000fd8eb4e1dca713016c518e31.
The registry can be deployed to any EVM-compatible chain using the following transaction:
{
"to": "0x4e59b44847b379578588920ca78fbf26c0b4956c",
"value": "0x0",
"data": "0x0000000000000000000000000000000000000000fd8eb4e1dca713016c518e31608060405234801561001057600080fd5b5061023b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063246a00211461003b5780638a54c52f1461006a575b600080fd5b61004e6100493660046101b7565b61007d565b6040516001600160a01b03909116815260200160405180910390f35b61004e6100783660046101b7565b6100e1565b600060806024608c376e5af43d82803e903d91602b57fd5bf3606c5285605d52733d60ad80600a3d3981f3363d3d373d3d3d363d7360495260ff60005360b76055206035523060601b60015284601552605560002060601b60601c60005260206000f35b600060806024608c376e5af43d82803e903d91602b57fd5bf3606c5285605d52733d60ad80600a3d3981f3363d3d373d3d3d363d7360495260ff60005360b76055206035523060601b600152846015526055600020803b61018b578560b760556000f580610157576320188a596000526004601cfd5b80606c52508284887f79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf887226060606ca46020606cf35b8060601b60601c60005260206000f35b80356001600160a01b03811681146101b257600080fd5b919050565b600080600080600060a086880312156101cf57600080fd5b6101d88661019b565b945060208601359350604086013592506101f46060870161019b565b94979396509194608001359291505056fea2646970667358221220ea2fe53af507453c64dd7c1db05549fa47a298dfb825d6d11e1689856135f16764736f6c63430008110033",
}
assembly ๊ตฌ์กฐ
# Asssembly ๊ตฌ์กฐ
// Memory Layout:
// ----
// 0x00 0xff (1 byte)
// 0x01 registry (address) (20 bytes)
// 0x15 salt (bytes32) (32 bytes)
// 0x35 Bytecode Hash (bytes32) (32 bytes)
// ----
// 0x55 ERC-1167 Constructor + Header (20 bytes)
// 0x69 implementation (address) (20 bytes)
// 0x5D ERC-1167 Footer (15 bytes)
// 0x8C salt (uint256) (32 bytes)
// 0xAC chainId (uint256) (32 bytes)
// 0xCC tokenContract (address) (32 bytes)
// 0xEC tokenId (uint256) (32 bytes)
// Silence unused variable warnings
pop(chainId)
// Copy bytecode + constant data to memory
calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId
mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer
mstore(0x5d, implementation) // implementation
mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header
// Copy create2 computation data to memory
mstore8(0x00, 0xff) // 0xFF
mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)
mstore(0x01, shl(96, address())) // registry address
mstore(0x15, salt) // salt
// Compute account address
let computed := keccak256(0x00, 0x55)
// If the account has not yet been deployed
if iszero(extcodesize(computed)) {
// Deploy account contract
let deployed := create2(0, 0x55, 0xb7, salt)
// Revert if the deployment fails
if iszero(deployed) {
mstore(0x00, 0x20188a59) // `AccountCreationFailed()`
revert(0x1c, 0x04)
}
// Store account address in memory before salt and chainId
mstore(0x6c, deployed)
// Emit the ERC6551AccountCreated event
log4(
0x6c,
0x60,
// `ERC6551AccountCreated(address,address,bytes32,uint256,address,uint256)`
0x79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf88722,
implementation,
tokenContract,
tokenId
)
// Return the account address
return(0x6c, 0x20)
}
// Otherwise, return the computed account address
mstore(0x00, shr(96, shl(96, computed)))
return(0x00, 0x20)
- ์ผ๋จ ๊นํ ์ปค๋ฐ ๋ฉ์์ง๋ ๋๋ฌธ์๋ก ํ๊ธฐ
- PR์ Motivation๊ณผ Solution์ผ๋ก ๋๋์ด ๊ธฐ์ ํ๊ธฐ
- ์ฝ๋
(address signer, ECDSA.RecoverError err) =
userOpHash.toEthSignedMessageHash().tryRecover(userOp.signature);
if (err != ECDSA.RecoverError.NoError) {
revert InvalidSignature();
}
- sol ํ์ผ ํจ์ ์ค๋ช
/// @title Base Session Key Plugin
/// @author Decipher ERC-6900 Team
/// @notice This plugin allows some designated EOA or smart contract to temporarily
/// own a modular account.
/// This base session key plugin acts as a 'parent plugin' for all specific session
/// keys. Using dependency, this plugin can be thought as a proxy contract that stores
/// session key duration information, but with validation functions for session keys.
///
/// It allows for session key owners to access MSCA both through user operation and
/// runtime, with its own validation functions.
/// @notice Route call to executeFromPluginExternal at the MSCA.
/// @dev This function will call with value = 0, since sending ether
/// for ERC20 contract is not a normal case.
/// @param target The target address to execute the call on.
/// @param data The call data to execute.
์๊ฒ๋ ๊ด์ฐฎ๋ค: https://github.com/erc6900/reference-implementation/pull/22/commits/0fb2113a0f1b09e8eeef72dd6d04b04bbc0151a8
โโ // โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// โ Execution functions โ
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
/// @inheritdoc ISessionKeyPlugin
function addTemporaryOwner(address tempOwner, uint48 _after, uint48 _until) external {
PR์ ์ค๋ช ๋ฌ๊ธฐ
## Motivation
We would like to accumulate the money for Poohnet Fund which will be used to support the real world projects which have content to make our world friendly.
## Solution
commit 789c3cf6c : Change the code for generating inflation for Poohnet Fund
commit c595c22a9 : Apply configuration for make the inflation start
supportsInterface
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
return interfaceId == type(ISessionKeyPlugin).interfaceId || super.supportsInterface(interfaceId);
}
storage modifier
EnumerableSet.Bytes32Set storage sessionKeySet = _sessionKeySet[msg.sender]; Purpose: This line declares a variable sessionKeySet that refers to a set of session keys for the message sender (msg.sender). The storage modifier indicates that sessionKeySet is a pointer to the data located in the contract's persistent storage, not a temporary copy. This is crucial in Solidity because changes to a storage variable directly modify the state on the blockchain.
unchecked block
The unchecked block is used here to tell the compiler not to check for overflows when incrementing the index i. This can save gas since the overflow is unlikely given the controlled environment of the loop (i.e., looping over an array length
transient storage sample
https://solidity-by-example.org/transient-storage/
forge create
forge script script/DeployTransactionDelegator.s.sol --rpc-url $LOCALNET_RPC_URL
CREATE a CONTRACT with 2 SAME addresses on 2 DIFFERENT chains
address = bytes20(keccak256(0xFF, senderAddress, salt, bytecode))
How to deploy my contract on 2 different chains with the same address? Now, letโs answer to the question: How to deploy a smart contract with the same addresses in 2 different chains?
You can do it with the CREATE2 opcode by providing the same salt on different chains. (easier than providing the nonce because you canโt fully control it)
foundry remapping์ toml์์ ์ง์ ํจ.
tokenURI ํจ์, ERC721
forge init โforce forge install https://github.com/OpenZeppelin/openzeppelin-contracts@v4.9.3
Fatal: Failed to write genesis block: database contains incompatible genesis
==> ์๋ genesis_testnet.json๊ณผ genesis_fund_testnet์ ์๋ ๋ถ๋ถ์ด ๋ค๋ฆ
"difficulty": "1",
"gasLimit": "8000000",
"extradata": "0x00000000000000000000000000000000000000000000000000000000000000008532654aD638Db3deE3836B22B35f7Ca707428ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"alloc": {
// ์ค๋ต
}
}
OnlyHardhatNetworkError: This helper can only be used with Hardhat Network. You are connected to 'localnet', whose identifier is 'Geth/v1.12.1-unstable-5e198bde-20240602/darwin-amd64/go1.21.3'
at checkIfDevelopmentNetwork (/Users/hyunjaelee/work/web/ex/node_modules/@nomicfoundation/hardhat-network-helpers/src/utils.ts:29:11)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at async getHardhatProvider (/Users/hyunjaelee/work/web/ex/node_modules/@nomicfoundation/hardhat-network-helpers/src/utils.ts:40:3)
at async Object.latest (/Users/hyunjaelee/work/web/ex/node_modules/@nomicfoundation/hardhat-network-helpers/src/helpers/time/latest.ts:7:20)
at async deployOneYearLockFixture (/Users/hyunjaelee/work/web/ex/test/basic.spec.localnet.ts:24:25)
at async loadFixture (/Users/hyunjaelee/work/web/ex/node_modules/@nomicfoundation/hardhat-network-helpers/src/loadFixture.ts:59:18)
at async Context.<anonymous> (/Users/hyunjaelee/work/web/ex/test/basic.spec.localnet.ts:37:36)
info
- 2023.06.07 Fri
- test code๋ฅผ ๋ก์ปฌ๋ท์์ ์คํ์ํค๋๊น ๋ฌธ์ ๊ฐ ๋ฐ์ํจ.
- web3_clientVersion ๊ด๋ จ ์์.
version.toLowerCase().startsWith("hardhatnetwork") ||
version.toLowerCase().startsWith("anvil");
- ๋ด geth code์ web3_clientVersion ์ฝ๋๋ฅผ ๋ฐ๊ฟ์ผ ๊ฐ๋ฅํจ.
- anvill ์ฝ๋ ๋ณด๋ฉด ๊ธ๋ฐฉ ๋ฐ๊ฟ ์ ์์ ๊ฒ์ผ๋ก ๋ณด์.
TypeError: Cannot read properties of undefined (reading 'provider')
at Object.<anonymous> (/Users/hyunjaelee/work/web/ex/test/create2/base.spec.ts:5:25)
at Module._compile (node:internal/modules/cjs/loader:1364:14)
at Module.m._compile (/Users/hyunjaelee/work/web/ex/node_modules/ts-node/src/index.ts:1618:23)
at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
at Object.require.extensions.<computed> [as .ts] (/Users/hyunjaelee/work/web/ex/node_modules/ts-node/src/index.ts:1621:12)
at Module.load (node:internal/modules/cjs/loader:1203:32)
at Function.Module._load (node:internal/modules/cjs/loader:1019:12)
at Module.require (node:internal/modules/cjs/loader:1231:19)
at require (node:internal/modules/helpers:177:18)
at /Users/hyunjaelee/work/web/ex/node_modules/mocha/lib/mocha.js:414:36
error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
hardhat.config.ts์ ์๋ ์ถ๊ฐ
import '@nomiclabs/hardhat-waffle' import '@typechain/hardhat' import { HardhatUserConfig } from 'hardhat/config' import 'hardhat-deploy' import '@nomiclabs/hardhat-etherscan'
TypeError: Cannot read properties of undefined (reading 'provider'):
์ด๋ฐ ์๋ฌ๊ฐ ๋จ์ด์ง๋ ์ด์ ๊ฐ ์๋ import ๋ฌธ ๋๋ฌธ์ธ๋ฐ,
import { ethers } from โhardhatโ
hardhat์ ethers ๋ฒ์ ์ ๋ด๊ฐ ์ฐ๋ ค๋ ๋ฒ์ ๋ณด๋ค ๋ฎ์์ ๊ทธ๋ฐ ๊ฒ์ด๋ค. ์๋์ ๊ฐ์ด ๋ฐ๊พธ๋ฉด ๋จ.
import { ethers } from "ethers";
hardhat์ ethers ๋ฒ์ ๊ณผ ๋์ ethers ๋ฒ์ ์ด ๋ค๋ฅด๋ฉด ๋ ๋ฌธ์ ๊ฐ ์๊น.
const provider = ethers.provider;
signer = await ethers.getSigner();
์์์ ๋ฐ์ํ๋ โTypeError: Cannot read properties of undefined (reading 'provider')โ ๋ฌธ์ ๋ ๋ชจ๋ ์๋์ ์ฐ๊ด์ด ์๋ ๊ฒ์ด๊ณ ,
ethers: typeof ethers & HardhatEthersHelpers;
์ด๊ฒ์ hardhat.config.ts์ import "@nomicfoundation/hardhat-toolbox"; ์ถ๊ฐํด์ผ ํจ.
๊ฒฐ๊ตญ provider์ getSigner๋ hardhat.config.ts์ ๊ด๋ จ๋ ๊ฒ์ด์์.
TypeError: Cannot read properties of undefined (reading 'waitForTransaction')
await expect(execAccount.executeUserOp(userOp, 1)).to.emit(execAccount, "Executed").withArgs("Got it!", hashedMessage);
TypeError: Cannot read properties of undefined (reading 'waitForTransaction')
at waitForPendingTransaction (node_modules/@nomicfoundation/hardhat-chai-matchers/src/internal/emit.ts:34:19)
at /Users/hyunjaelee/work/web/ex/node_modules/@nomicfoundation/hardhat-chai-matchers/src/internal/emit.ts:84:21
- @nomicfoundation/hardhat-chai-matchers ๋ฒ์ ์ ^1.0.6 -> ^2.0.7 ์ฌ๋ฆผ
- ๊ณผ์ฐ ์๋ก ๋ค๋ฅธ ํจํค์ง๋ฅผ ํ์์ ํฌํจ์ํฌ๋ ์ด๋ป๊ฒ ๋๋์ง ํ์ธํ๊ธฐ: ๊ฐ์์ ํจ์งํค๋ฅผ ์ฌ์ฉํ๋๋ฐ, Peer-dependency๋ฅผ ๊ฐ์ ํ๋ ๊ฒฝ์ฐ๋ ์์ง.
"ethers": "^6.1.0", <== ์์์ ์ค์น๋จ
TypeError: (0 , ethers_1.getAddress) is not a function
hardhat์ ethers๋ฅผ ์ธ๋ ์ด๋ฐ์ผ์ด ๋ฐ์ํจ์ผ๋ก 6.7.0์ ์จ์ผํจ. ๊ทธ๋ ๋ค๋ฉด hardhat์ ๋ด ethers๋ฅผ ์ด๋ค๋ ์๊ธฐ? ๋ด๊บผ ์ฐ๋๊ฒ ๋ง์. ๊ทธ๋ฌ๋ฉด ๋ญํ๋ฌ import { ethers } from "hardhat"; ์ด๊ฑธ์ฐ๋๊ตฌ??? ์ด์จ๋ hardhat์ node_modules์๋ hardhat ๊น๋ฆฌ๊ฒ ์์.
forge install ํ ๋, .gitmodules๊ฐ ํ์ํจ
forge init โforce
forge install OpenZeppelin/openzeppelin-contracts
forge test --match-contract PoohnetFund
forge test --match-contract PoohnetFund --fork-url $LOCALNET_RPC_URL
forge test --match-path test/forge/FulfillBasicOrderTest.sol --gas-report
source code
import "@openzeppelin/contracts/utils/Create2.sol";
address fundContractAddr = vm.envAddress(
"POOHNET_FUND_CONTRACT_ADDRESS"
);
command
console.log(balance of deployer: ${await provider.getBalance(deployer.address)});
console.log(Receipt: ${JSON.stringify(receipt)});
const tx = await deployerListSetStore.addValue(valueData);
CONTRACT="AllBasic" yarn contract --network localnet
function _getListValue(uint240 value) internal pure returns (SetValue) { return SetValue.wrap(bytes30(value)); }
byte(0, mload(add(sig, 96))) extracts the first byte of this 32-byte value, because 0 is the index for the first byte.
// Clear any dirty upper bits of address ์์๋นํธ๊ฐ ์ง์์ง์ ์ฃผ์ addr := and(addr, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
https://github.com/ethereum/solidity/releases
expect(receipt?.status).to.equal(1); ์ด๋ ๊ฒ ํด์ผ ๋นจ๊ฐ์ค์ด ์์๊น
slot := keccak256(keyBuffer, 0x80) // Solidity keccack256๊ณผ๋ ์ข ๋ค๋ฆ.
function executeUserOp ๋ฆฌํด๊ฐ์ ์ฒดํฌํ์ง ๋ชปํ๋ ๋ฌธ์ In view and pure functions, which are called statically from a local node without a transaction. Or when doing such a static call to any function, but knowing that the state changes are not persisted.
๋๊ฐ์ ์ฐจ์ด ==> ์ฒซ๋ฒ์ฌ๊ฒ ์ค๋ช
: This expression generally means you are waiting for the expect function (a promise) to resolve. This is typically used with assertion libraries like Chai when you are expecting a promise to be rejected or resolved in a certain way.
await expect(execAccount.executeUserOp(userOp, 1)).to.emit(execAccount, "Executed").withArgs("Got it!", hashedMessage);
expect(await execAccount.executeUserOp(userOp, 1)).to.emit(execAccount, "Executed").withArgs("Got it!", hashedMessage);
contract size
- limit: 24,576 bytes (24 KB).
- ๋น ํจ์ ํ๋ ์ถ๊ฐํ๋ฉด 23๋ฐ์ดํธ ์ถ๊ฐ๋จ ==> function addNone() public {}
- ํ๋ฌ์ค ์ฐ์ฐํ๋ ์ฝ๋ ํ๋ ์ถ๊ฐํ๋ฉด 26๋ฐ์ดํธ ์ถ๊ฐ๋จ ==> value2 += 62;
- Warning: 3 contracts exceed the size limit for mainnet deployment (24.000 KiB deployed, 48.000 KiB init).
const contractCode = await provider.getCode(tooBig.address);
const contractSize = (contractCode.length - 2) / 2; // Subtract 2 for '0x' prefix and divide by 2 to get the byte count
์๋์ isPrime์ฒ๋ฆฌ ์ฝ๋๋ฅผ library call ํ๋ ๊ฒ์ผ๋ก ๋ฐ๊พธ๋ฉด 200bytes ์ฐจ์ด, ๊ทธ๋ฅ ์์ ๋ฉด 500๋ฐ์ดํธ ์ฐจ์ด.
function addSixtyTwo(uint256 n) public returns (bool) {
// return n.isPrime();
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (uint256 i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) return false;
}
return true;
}
solc --bin --abi contracts/assembly/DataStorage.sol -o output
// Call transfer function and check for success/failure (bool sent, ) = _to.call{value: msg.value}(""); require(sent, "Failed to send Ether");
yarn init -y yarn add typescript ts-node @types/node --dev tsc --init
error: externally-managed-environment
ร This environment is externally managed โฐโ> To install Python packages system-wide, try brew install xyz, where xyz is the package you are trying to install.
==> python3 -m pip config set global.break-system-packages true
ModuleNotFoundError: No module named 'web3' python3 -m pip --version
python3 -m pip install web3
curl v4.ident.me
# 3. Dev
Projects Summary
๐๐๐ฆโพ๏ธ๐ณ๐๐ผ๐ธ๐๐๐๐น๐ถ๐ฆโ๏ธ๐โป
Project Analysis
๋ฌธ์ ํ์ธ: 2์ผ
- ํํ์ด์ง์์ ๊ธฐ๋ณธ์ ๋ณด ์ต๋ (์: centrifuge.io)
- ๊ฐ๋ฐ์ ๋ฌธ์ ๋ฐ github ์ฌ์ดํธ ์ฐพ๊ธฐ
- ํํ์ด์ง์ ๊ธฐ๋ณธ์ ์ธ ์ ๋ณด ๋ค ์์.
- ๊ฐ๊ด์ ์ธ ์ ๋ณด๋ฅผ ์ํด์ ๊ตฌ๊ธ๋งํด์ ์ฐพ์๋ณด๊ธฐ
- ํํ์ด์ง์์ ์ฐพ์ doc ๋ฌธ์ ๋ณด๊ธฐ
- github repo ์ฐพ์์ ๊ธฐ๋ณธ ๋ณด๊ธฐ
- discord ๋ค์ด๊ฐ๋ณด๊ธฐ
- ์งํ ์ํฉ์ ๊ตฌ๊ธ Docs์ ์ ๋ฆฌ
- ํ์ํ๋ฉด ๋ค์ด์ด๋ฆฌ๋ ํ์ฉ
- ์ฝ๋์ ๋ํด์๋ Miro์ ์ ๋ฆฌ
ํ ์คํธ ์ฝ๋ ๋ถ์: 3์ผ
- ํ๊ฒฝ์ค์
- ํ์ํ ์๋ฒ ๋ฐ ๊ตฌ์ฑ ํ์ธ
- ํ ์คํธ ์ฝ๋ ์คํ
poohnet testnet admin
58984b2bf6f0f3de4f38290ed3c541ac27bac384b378073ab133af8b314a1887
0x1811DfdE14b2e9aBAF948079E8962d200E71aCFD
keyless2
- hardhat-deploy
- .env.sample
zksync
local-setup์์ clear-sql.sh์ start-sql.sh localentry.sh ์คํ greeter-example์์ deploy-test์ greet-test์งํ
๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น ๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น ๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น ๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น๐น
Blockchain
๐๐๐ฆโพ๏ธ๐ณ๐๐ผ๐ธ๐๐๐๐ถ๐ฆโ๏ธ๐โป
hardhat localnet ์คํํ๊ธฐ
yarn hardhat node (chain id: 31337)
yarn hardhat run ./scripts/send-raw-tx.ts --network hardhat
Ethereum mainnet fork๋ ๋ก์ปฌ ๋คํธ์ํฌ๋ฅผ ์คํ
yarn hardhat node --fork https://eth-mainnet.g.alchemy.com/v2/<key>
ganache localnet ์คํํ๊ธฐ
npm install -g ganache-cli
ganache-cli
gaslimit์ ์ฃผ๊ณ ์ถ์๋
ganache-cli -l 7900000
clique in genesis.json
{
"config": {
"chainId": 12301,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"arrowglacierBlock": 0,
"clique": {
"period": 1,
"epoch": 30000
}
},
...
}
"period": This refers to the block time, the time interval between consecutive blocks. In this case, 1 means one second. This is a very fast block time, suitable for private or test networks where quick consensus is desired. In public networks, such short intervals could lead to network instability due to propagation delays and increased likelihood of forks.
"epoch": The epoch length, set here as 30000, is significant in Clique PoA. An epoch is a period after which the list of authorized signers can be updated. In Clique, every epoch blocks, a special block called the epoch transition block is generated, which contains the list of authorized signers for the next epoch. The number 30000 means that every 30,000 blocks, the network has an opportunity to update the list of signers.
BOA ์ ํต๋ API
- ์ ํต๋: https://api.bosplatformfoundation.io/boa_circulating_supply
- ์ด๋ฐํ๋: https://api.bosplatformfoundation.io/boa_supply
์ด๋๋ฆฌ์ Endpoint
- Alchemy ์ฌ์ฉ (https://dashboard.alchemy.com/)
Hardhat
Hardhat / solidity
Hardhat์ ๊ธฐ์กด ํ๋ก์ ํธ์์๋ ์๋จ.
yarn init -y (=npm init -y)
yarn add --dev hardhat
npx hardhat
yarn add -D hardhat-deploy
yarn add -D dotenv
์๋ ๋๊ฐ๋ ๊ฐ์ด ์ฐ๋ฉด ์๋จ.
import "@nomicfoundation/hardhat-toolbox";
import "@nomiclabs/hardhat-waffle"; // ์ด๊ฒ๋ง์จ.
๊ธฐํ
yarn add @openzeppelin/contracts
๐ solidiy import "hardhat/console.sol"; npx hardhat compile
const tx = await factoryInstance.setFeeTo(process.env.FEE_TO); const receipt = await (await tx).wait();
Hardhat / Foundry
If you have an existing Hardhat project and you want to use Foundry in it, you should follow these steps.
First, run forge --version to make sure that you have Foundry installed. If you don't, go here to get it.
After that, install the @nomicfoundation/hardhat-foundry plugin:
npm install --save-dev @nomicfoundation/hardhat-foundry
and import it in your Hardhat config:
import "@nomicfoundation/hardhat-foundry";
To complete the setup, run npx hardhat init-foundry. This task will create a foundry.toml file with the right configuration and install forge-std.
submodule์ด ์๋์ ๊ฐ์ด ์ถ๊ฐ๋จ
[submodule "ex2/lib/forge-std"]
path = ex2/lib/forge-std
url = https://github.com/foundry-rs/forge-std
Workspaces
- hardhat-zksync ์ฐธ๊ณ
Foundry
Install Foundry
mkdir foundry
cd foundry
curl -L https://foundry.paradigm.xyz | bash
source ~/.bashrc
foundryup
Initializing a new Foundry Project
forge init .
Dev Settings
๐๐๐ฆโพ๏ธ๐ณ๐๐ผ๐ธ๐๐๐๐ถ๐ฆโ๏ธ๐โป
Node workspaces
๐ Structure and Configuration
- Workspace Root: A single workspace has a root directory, usually with a package.json file that includes a workspaces field.
- Sub-packages: Inside the root, there are subdirectories for each workspace, each with its own package.json file.
- Shared Configuration: Dependencies and scripts can be shared across workspaces, which is especially useful for common configurations and shared libraries.
๐ Reference Project
TypsScript/Nodejs
๐ NodeJs ํ๋ก์ ํธ
- npm init -y
- touch index.js
๐ TypeScript ํ๋ก์ ํธ
- npm install -g typescript (or yarn global add typescript)
- npm init -y
- npx tsc --init
- package.json --> CoPilot์ด ๋ค ํด์ค "build": "tsc", "start": "node dist/index.js"
- tsconfig.json "outDir": "./dist", "include": ["./scripts", "./test", "./typechain"], "files": ["./hardhat.config.ts"]
- mkdir src
- touch src/index.ts
- yarn build
- yarn start
๐ yarn yarn add --dev
Docker
๐ Docker Image ๋ง๋ค๊ธฐ
- https://github.com/poohgithub/poohgeth/blob/master/Dockerfile ์ฐธ๊ณ
- docker build -t linked0/poohgeth:v1.3 . // ๋์ dot(.) ์ฃผ์
- docker ์คํ (optional)
docker run -p 3000:3000 linked0/poohgeth:v1.3
- docker login
- tag: ๊ธฐ์กด v1.0 ํ๊ทธ ๋ง๊ณ , latest๋ฅผ ๋ถ์ด๊ณ ์ถ์๋.
docker tag linked0/poohgeth:v1.0 linked0/poohgeth:latest
- push
docker push linked0/poohgeth:v1.3
- pull
docker pull linked0/poohgeth:v1.3
- run using docker-compose
https://github.com/poohgithub/poohgeth/blob/master/poohnet/docker-compose-node.yml ์ฐธ์กฐ
docker compose -f docker-compose-node.yml up el1 -d
๐ Docker ์ด์
docker build์ ์ค๋ซ๋์ ๋ฉ์ถฐ์์ ๋, pruneํ์ ์ฌ๋ถํ ํด๋ณด๊ธฐ.
docker container prune
๐ ๊ธฐํ
docker attach
docker ps | grep 5432
ํ์ผ์ ๊ถํ๋ github์ผ๋ก ๋ฑ๋ก๋๋ค. run_node ์คํ๊ถํ
To restore the entire staging area to the HEAD commit, you can run the following command: git restore --staged .
์ํธ๋ ๋ธ๋ก์ฒด์ธ ์ํ๊ณ๋ฅผ ํ์ฑํํ๊ณ ์ฐ๊ฒฐํ๊ธฐ ์ํ์ฌ Bridge, DEX์ ๊ฐ์ Dapp ํ๋ก๋ํธ๋ฅผ ๊ฐ๋ฐํ๊ณ ์์ต๋๋ค.
NPM
npm login npm publish --access public
Python
๐ venv ์ค์ ํ๊ณ ๊ฐ๋จํ ํ๋ก๊ทธ๋จ ์คํ python -m venv venv source venv/bin/activate code script.py
def hello_world():
print("Hello World")
if __name__ == "__main__":
hello_world()
python script.py
pip install requests pip freeze > requirements.txt pip install -r requirements.txt
๋ค ๋๋๋ฉด deactivate
๐ ๋จธ์ ์ ์ค์นํ๊ธฐ pip3 install -r requirements.txt python3 setup.py install
from setuptools import find_packages, setup
setup(
name="staking_deposit",
version='2.5.2',
py_modules=["staking_deposit"],
packages=find_packages(exclude=('tests', 'docs')),
python_requires=">=3.8,<4",
)
์ค์นํ๋ฉด ์๋์ ์์น์ ์ค์น๋จ
/Library/Python/3.9/site-packages/staking_deposit-2.5.4-py3.9.egg
์ค์น ํ๊ณ ๋๋ฉด ์๋ ์์คํฌ๋ฆฝํธ ์คํ ๊ฐ๋ฅ https://github.com/poohgithub/poohprysm/blob/develop/poohnet/pooh-deposit-cli/deposit.sh
๐ colab import matplotlib.pyplot as plt
๐ VS Code
- Open the Command Palette (โงโP), start typing the Python: Create Environment
- ๋ค๋ฅธ ํ๋ก์ ํธ(์: poohcode)์ ํ์ ํ๋ก์ ํธ๋ผ๋ฉด .venv ํด๋ ๋ณต์ฌ
- source ./venv/bin/activate
- ์๋์ผ๋ก ํ๋ ๋ฐฉ๋ฒ: python3 -m venv venv39
- pip3 freeze > requirements.txt <== venv๋ฅผ ๋น ์ ธ๋์ค๊ณ ํด์ผํจ.
- python hello.py
Rust
Homebrew rust์ rustup๋ก ์ค์น๋ ๊ฒ๊ณผ ์ฐ๋์๋จ. ๋ฐ๋ผ์ ์๋์ ๊ฐ์ด ์ง์ฐ๊ธฐ brew uninstall rust
๊ทธ๋ฆฌ๊ณ rustc ์ด์ฉ rustup install nightly-2023-07-21 rustup default nightly-2023-07-21
Prettier/Lint ์ ์ฉ
- VS Code์ settings: ์ด๊ฒ์ ํ๋ฉด ํ์ผ์ด ์ ์ฅ๋ ๋ ์๋์ ์ผ๋ก ์ ์ฉ๋จ.
- typescript.format: enable/disable
- solidity.formatter: none/prettier/forge
- prettier, eslint, solhint
- .prettierrc.js, .eslintrc.js(.eslintignore.js), .solhint.json(config ํด๋์ ์์ ์ ์์.)
"prettier": "node_modules/.bin/prettier --write --config .prettierrc 'contracts/**/*.sol' 'test/**/*.ts' 'utils/**/*.ts' 'scripts/**/*.ts'",
ํน์
"lint:check": "yarn lint:check:format && yarn lint:check:solhint && yarn lint:check:eslint",
"lint:check:format": "prettier --check **.{sol,js,ts}",
"lint:check:solhint": "yarn build && solhint --config ./config/.solhint.json --ignore-path ./config/.solhintignore contracts/**/*.sol",
"lint:check:eslint": "eslint . --ext js,ts",
- husky์์ ๋ค์ ์ฌ์ฉ ๊ฐ๋ฅ
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "npx --no -- commitlint --edit ${1}"
}
},
"lint-staged": {
"*.sol": "prettier --write",
"*.js": "prettier --write",
"*.ts": "prettier --write"
}
Github
๐๐๐ฆโพ๏ธ๐ณ๐๐ผ๐ธ๐๐๐๐ถ๐ฆโ๏ธ๐โป
fast-forward ๋ฌธ์
- push ํ๋ ค๊ณ ํ ๋ ์๋์ ๊ฐ์ ๋ฌธ์ ๋ฐ์ --> github remote์ ๋ธ๋์น๊ฐ ๋ ์ต์ ๋ฒ์ ์ผ๋ ๋ฐ์
- ์ด๊ฒ์ ๊ฐ์ฅ ์ต์ ์ ํ์คํ ๋ฐฉ๋ฒ์. ๊ทธ๋ฅ rebase ํด์ฃผ๋ฉด ๋จ
git rebase origin master
- ์ด๊ฒ ์์ ์ค๋ช ์ธ๋ฐ, ์ผ๋จ ๊ทธ๋ฅ ์ฐธ๊ณ ์ฉ์ผ๋ก ๊ทธ๋ฅ๋
$ account-abstraction git:(test-flow) โ git push -f
To github.com:linked0/account-abstraction
! [rejected] test-flow -> test-flow (non-fast-forward)
error: failed to push some refs to 'github.com:linked0/account-abstraction'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
- ์ด๋ด ๊ฒฝ์ฐ๋ ๋ค์์ ๋จ๊ณ๋ฅผ ๊ฑฐ์นจ
- git fetch origin
- git reset --hard HEAD~1
- git rebase origin/pooh-version
- git reflog : ์ถ๊ฐ๋ก ํธ์ํ๋ ค๊ณ ํ๋ ์ปค๋ฐ์ ์ฐพ์๋ด๊ธฐ
- git cherry-pick <์ปค๋ฐ์์ด๋> : ์ถ๊ฐํ๋ ค๊ณ ํ๋ ์ปค๋ฐ ์์ด๋๋ฅผ ์ฒด๋ฆฌํฝ
- ์์ธ ์ค๋ช
- ํ์ฌ ๋ฆฌ๋ชจํธ ๊ธฐ์ค์ผ๋ก HEAD + 1 ๊น์ง ์งํ๋ ์ํ์์, ๋ก์ปฌ์ HEAD์ ๋ฆฌ๋ชจํธ์ HEAD๊ฐ ๋ถ์ผ์น๋ ์ํ
- ๊ทธ๋ฐ๋ฐ, ๊ทธ ๋ถ์ผ์น ์ํ์์ ์ถ๊ฐ์ ์ธ commit์ด ์งํ๋ ์ํ์์ push๋ฅผ ํ๋ ค๊ณ ํด์ ๋ฌธ์ ๋ฐ์
- ๋ฐ๋ผ์, HEAD~1๊น์ง ๋๋๋ฆฐํ์ ๋ฆฌ๋ชจํธ์ HEAD๋ฅผ ์ ์ฉํ ํ์,
- ํ์ฌ์ commit์ ์ ์ฉํด์ผํ๋ ๊ฒ์
๋ก์ปฌ์ ์ปค๋ฐ์ ๋ ๋ ค๋จน์์๋
git reflog๋ฅผ ์ฌ์ฉํ๋ฉด ์ปค๋ฐ ์์ด๋๋ฅผ ํ์ธํ ์ ์์
git cherry-pick๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ ธ์ค๋ฉด ๋จ.
$ git reflog
8fd79d7 (HEAD -> pooh-version, origin/pooh-version) HEAD@{0}: cherry-pick: fixup;
bc5852b HEAD@{1}: rebase (finish): returning to refs/heads/pooh-version
bc5852b HEAD@{2}: rebase (start): checkout origin/pooh-version
28fbb3b (origin/main, origin/HEAD, main) HEAD@{3}: reset: moving to HEAD~1
bc5852b HEAD@{4}: reset: moving to HEAD
bc5852b HEAD@{5}: reset: moving to HEAD
bc5852b HEAD@{6}: reset: moving to origin/pooh-version
28fbb3b (origin/main, origin/HEAD, main) HEAD@{7}: reset: moving to HEAD
28fbb3b (origin/main, origin/HEAD, main) HEAD@{8}: reset: moving to HEAD~2
37017b9 HEAD@{9}: rebase (finish): returning to refs/heads/pooh-version
37017b9 HEAD@{10}: rebase (reword): fixup
b3d7c55 HEAD@{11}: rebase: fast-forward
6443037 HEAD@{12}: rebase (start): checkout HEAD~2
b3d7c55 HEAD@{13}: commit: fixup;
6443037 HEAD@{14}: reset: moving to HEAD
6443037 HEAD@{15}: reset: moving to HEAD~1
2d482e7 HEAD@{16}: cherry-pick: fixup
6443037 HEAD@{17}: reset: moving to HEAD~1
dd83300 HEAD@{18}: reset: moving to HEAD
dd83300 HEAD@{19}: commit: fixup
6443037 HEAD@{20}: reset: moving to HEAD
github ๊ณ์ ๊ผฌ์์๋
ERROR: Permission to poohgithub/poohnet-pow.git denied to jay-hyunjaelee. fatal: Could not read from remote repository.
Please make sure you have the correct access rights and the repository exists.
- ~/.gitconfig์ emial ์ค์ ์์ equal sign ์ ์์ ์คํ์ด์ค ์์ ๊ธฐ
- ์ฌ๋ถํ ํ๊ธฐ
error: cannot run delta: No such file or directory
- git lg ์คํ์ ๋ฐ์
- brew install git-delta.
git submodule update ์๋ฌ ๋ฐ์์
git rm --cached path_to_submodule
Edit .gitmodules File
Edit .git/config File
rm -rf .git/modules/path_to_submodule
git commit -am "Removed submodule"
git push
๋ด๊ฐ ์ฌ๋ฆฐ ๋ธ๋์น์ ๋ํด์ ์๋์ผ๋ก PR์ถ์ฒ์ ํ ์ ์๋๋ก ํ๊ธฐ.
- Organization์ ํด๋น ๋ฆฌํ์งํ ๋ฆฌ๋ก ์ด๋
- Settings -> General ์ด๋
- Always suggest updating pull request branches ๋ฅผ
Merge pull request ๋ฐ์ํ์ง ์๋๋ก Full Requests ์ค์
- Repository Setting -> Pull Requests
- Uncheck: "Allow merge commits", "Allow squash merging"
๊ธฐํ ์ ๋ฆฌ
git reset --hard michael/add-npm-script-prettier git remote update ํ๋ฒ ํด์ค์ผ ํจ. ํด๋น ๋ธ๋์น๋ก ๋ค์ด๊ฐ์ ์ต์ ๋ฒ์ ์ผ๋ก ๊ฐฑ์ ํ๊ธฐ
git pull
๋ก์ปฌ์ ์์ ์ ๋ฐ์ํ๊ธฐ ex) git pull zero commons-budget-contract git rebase ๋์ค ํ์ผ ์ ๊ฑฐํ๊ธฐ git rm --cached
git rebase ๋์ค stage๋ ํ์ผ ๋ฆฌ์ ํ๊ธฐ git reset HEAD~1 -- package.json
revert โป This will create three separate revert commits: ยง git revert a867b4af 25eee4ca 0766c053 โป It also takes ranges. This will revert the last two commits: ยง git revert HEAD~2..HEAD โป Similarly, you can revert a range of commits using commit hashes (non inclusive of first hash): ยง git revert 0d1d7fc..a867b4a
git clone์ ํด๋๋ช ์ง์ git clone git@github.com:whatever folder-name
Fatal: Not possible to fast-forward, aborting git pull --rebase.
git diff --name-only HEAD
1 HEAD2git log with graph git log --graph --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%an%C(reset)%C(bold yellow)%d%C(reset) %C(dim white)- %s%C(reset)' --all
๐ private repo clone
- $ key-gen
- $ eval "$(ssh-agent -s)"
- $ ss-add .ssh/id_rsa_graph_node
- id_rsa_graph_node.pub๋ฅผ catํด์ ๋ฆฌํ์งํ ๋ฆฌ Setting -> Deploy keys์ ์ถ๊ฐ
- git clone git@github.com:bosagora/boa-space-graph-node.git
๐ Organization๋ง๋ค๊ณ , ํฌํฌํ๊ธฐ (fork) poohgithub organization์์ Setting->Members privileges->Allow forking of private repositories.
Mac
๐๐๐ฆโพ๏ธ๐ณ๐๐ผ๐ธ๐๐๐๐ถ๐ฆโ๏ธ๐โป
MacVim์ Spotlight์์ ๋ณด๋๋ก ํ๊ธฐ
For those with Yosemite and MacVim from homebrew not showing up in Spotlight, using an alias works.
(Be sure to delete any MacVim that is already in /Applications.)
From the Terminal:
Uninstall existing: brew uninstall macvim Install latest: brew install macvim Open directory in Finder. Ex: open /usr/local/Cellar/macvim/7.3-64 In Finder, right-click on the MacVim.app icon and select "Make Alias". Copy the alias you just created to the /Applications folder. Spotlight will index the MacVim alias.
Source: https://github.com/Homebrew/homebrew/issues/8970#issuecomment-4262695
Mac Spotlight์์ ํน์ ์ ํ๋ฆฌ์ผ์ด์ ์ฐพ์ง ๋ชปํ ๋
First, turn off Spotlight: sudo mdutil -a -i off
Next, unload the metadata file that controls Spotlight's index: sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist ์ฌ๊ธฐ์ ์๋ฌ๋ ์ ์์ ๊ทธ๋ฅ ๋ฌด์ํ๊ณ ๋ค์์ผ๋ก ๋์ด๊ฐ.
The following command re-loads the index: sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist
Finally, turn Spotlight back on: sudo mdutil -a -i on
Mac์์ Sublime Text๋ฅผ ์ปค๋งจํธ์ฐฝ์์ ์คํ์ํค๊ธฐ
ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/subl
vi
๐๐๐ฆโพ๏ธ๐ณ๐๐ผ๐ธ๐๐๐๐ถ๐ฆโ๏ธ๐โป
์ค๋ฒํธ
:set number
:set nu
์์ ๊ธฐ๋ ์๋์ ๊ฐ์ด
:set number!
:set nu!
files ํ์ผ ๋ง๋ค๊ธฐ
find . -type f -not -path ./node_modules/ -not -path ./.git/ -not -path ./venv/ > files
find ./ -type f > files find . -type file -name '.js' -o -name '.json' > files //-o๋ or๋ฅผ ๋ปํจ find . -type f -not -path './node_modules/' -not -path './chaindata/' > files
open file: ctrl w, ctrl f
basics
g t: Next tab, ๊ทธ๋ฅ ์๋ํฐ์์ g์ t๋ฅผ ์น๋ฉด ๋จ g T: Prior tab nnn g t: Numbered tab, nnn์ ์ซ์๋ฅผ ๋ํ๋, 1์ผ์๋ ์๊ณ , 12์ผ์๋ ์์.
"*yy ; copt from vi :! wc ; sh command in vi
:shell ํน์ :sh๋ฅผ ์ด์ฉํด์ shell(:12)๋ก ๋น ์ ธ๋๊ฐ ์ ์๋ค. exit ํน์ Ctrl+D๋ฅผ ์ด์ฉํด์ vim์ผ๋ก ๋๋์์ฌ ์ ์๋ค. :! # ๋ง์ง๋ง ์ปค๋งจ๋์ ๊ฒฐ๊ณผ๋ณด๊ธฐ
mvim --remote-tab-silent search.go // ๊ฐ์ ์๋์ฐ์์ ์ด๊ธฐ
Move cursor to end of file in vim
:$
ํ๊ธ ๊นจ์ง๋ ๋ฌธ์
set enc=utf-8
vimrc (~/.vimrc)
set nocompatible filetype off set rtp+=~/.vim/bundle/Vundle.vim call vundle#begin() Plugin 'gmarik/Vundle.vim' "required Plugin 'tpope/vim-fugitive' "required call vundle#end() filetype plugin indent on " Put your non-Plugin stuff after this line :w :source % :PluginInstall syntax enable " syntax highlighting set nu " add line numbers set smartindent " make smart indent set tabstop=4 " tab width as 4 (default 8) set shiftwidth=4 set softtabstop=4 ; TABํค๋ฅผ ๋๋ ์๋ ๋ช ์นธ์ ์ด๋? set tabstop=4 ; ํ๋์ TAB์ ๋ช ์นธ์ผ๋ก ์ธ์? set number ; Line Number set expandtab " spaces for tab set incsearch set mouse=a
#aws
๐๐๐ฆโพ๏ธ๐ณ๐๐ผ๐ธ๐๐๐๐ถ๐ฆโ๏ธ๐โป
AWS ๊ฐ๊ฒฉํ
์ฐธ๊ณ : https://aws.amazon.com/ec2/pricing/on-demand/
| name | hourly | vCPU | Memory | Storage | Network performance |
|---|---|---|---|---|---|
| t3.small | $0.026 | 2 | 2 GiB | EBS | Up to 5 Gigabit |
| t3.medium | $0.052 | 2 | 4 GiB | EBS | Up to 5 Gigabit |
| t3.large | $0.104 | 2 | 8 GiB | EBS | Up to 5 Gigabit |
AWS์ Load Balancer ์ถ๊ฐ์
โข Certifacate Manager๋ฅผ ํตํด์ ๋๋ฉ์ธ ์ถ๊ฐ - "Create records in Route 53" ํด์ค์ผ ํจ.
node3์ ๋ค์ด๊ฐ์ postgresql ๋์ปค ์ ์๋ฐฉ๋ฒ
sudo docker exec -it ec22f5036e09 bash psql -d db -U postgres -W
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
Add correct host key in /Users/hyunjaelee/.ssh/known_hosts to get rid of this message.
public key ํ์ธ ๋ฐ ๊นํ์ ์ถ๊ฐํ๊ธฐ
cat .ssh/id_rsa_linked0.pub- ๊ณ์ ์ ์ธํ
์ผ๋ก ๋ค์ด๊ฐ๋ฉด
SSH and GPG keys์ ์ง์ด๋ฃ์ผ๋ฉด ๋จ. - git cloneํ ๋ sudo๋ฅผ ๋ฃ์ด์ผ
Load key โฆ : Permission denied์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์. git clone https://github.com/linked0/agora.git์ด๊ฑด ์๋๋ ssh๋ก ๋ฐ์๋ ์๋จ
์ ์
ssh -i "pooh-seoul.pem" ubuntu@ec2-52-79-227-164.ap-northeast-2.compute.amazonaws.com
AWS์์ ํ์ผ ์ ์ก
- ๊ฐ์ ธ์ค๊ธฐ
scp -i ~/pooh/pooh-seoul.pem ubuntu@ec2-52-78-204-156.ap-northeast-2.compute.amazonaws.com:~/share/test.txt .
- ๋ณด๋ด๊ธฐ
scp -i ~/pooh/pooh-seoul.pem test.txt ubuntu@ec2-52-78-204-156.ap-northeast-2.compute.amazonaws.com:~/share/test.txt
Load Balancer
- Mappings๋ ๋ชจ๋ ์กด์ผ๋ก
- Security Group์ AgoraDevNet_ELB
- ๋ฆฌ์ค๋ ์ง์ : Target Group์ง์
- ๋์ค์ 80์ ๋ํด์ 443์ผ๋ก Redirect
URL๋ก ์ ๊ทผ์ด ์๋๋ ๋ฌธ์
- ์คํจ์ํฉํฉ์ธ๋ฐ, CNAME๊ณผ A ์ค์ ๋ง ๋ง์ผ๋ฉด ๋ ๊ฒ ๊ฐ์ (230303)
Target Group
- Basic configuration: Instances
- Protocol/Port ์ง์
- Protocol version: HTTP1
- Health checks๋ ๊ทธ๋๋ก ๋๋ฉด ๋จ.
AWS ํ์์กด ๋ณ๊ฒฝ
$tzselect
.profile์ ๋ค์์ ์ถ๊ฐํ๊ณ ์ฌ๋ก๊ทธ์ธ
TZ='Asia/Seoul'; export TZ
#4. Freqeunt Use
์์ฃผ ์ฐ๋ ๊ฒ - Part1
๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ
Slack
๐ github subscribe
/github subscribe bosagora/boa-space-contracts issues pulls commits releases deployments reviews comments
/github subscribe zeroone-boa/validators reviews comments
์ด๊ฒ๋ ๋ฐฉ๋ฒ, ์์ ๊ฒ๊ณผ ๋น๊ต ํ์:
/github subscribe bosagora/boa-space-seaport-js issues pulls commits releases deployments reviews comments
Memo Google Docs
- bit.ly/44TH7Ua : Memo Pub
- bit.ly/357Is0p : Memo
์์์น ๋ชปํ ์ปดํ์ผ ์๋ฌ๊ฐ ๋์ฌ๋
- brew update && brew upgrade
Generate Private Key
openssl ecparam -name secp256k1 -genkey -noout
Mac XCode
brew install macvim --override-system-vim
https://developer.apple.com/download/more/?=command%20line%20tools ์์ ๋ค์ด๋ก๋ ํ์ xcode-select install sudo xcode-select --switch /Library/Developer/CommandLineTools
source๋ฅผ ๋ค๋ฅธ ์์น์ new_source๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ณต์ฌ(๋๊ฐ์ง ๋ฐฉ๋ฒ)
cp -a source ~/temp/new_source
find . -iname mainview* touch -t "201610041200" timestamp find . -type f -newer timestamp
sudo xcode-select -s /Applications/XCode7.2/Xcode.app/ To clear the terminal manually: Cmd + K ps aux | grep chrome
๐ธ Google docs
- Indentation ์์ Format - Align & Indent - Indentation Option์์ Hanging ์์ ํ๋ฉด ๋จ
๐ธ poohnet (EL/CL) ์คํํ๊ธฐ
๐ geth compile
brew install golang
go run build/ci.go install -static ./cmd/geth or make geth
sudo cp ./build/bin/geth /usr/local/bin/geth
๐ EL
- ./init ์น๋ฉด help ๋์ด
- ./enode ์น๋ฉด help ๋์ด
๐ CL
- ๋ธ๋ญํด์๊ณผ genesis time(date +%s)์ chain-config ๋ฐ์ํ๊ณ eth2-testnet-genesis ์คํ
- gen_genesis
- zcli pretty bellatrix BeaconState genesis.ssz > parsedState.json๋ก Validators Root ๊ฐ์ ธ์ค๊ธฐ
- settings.py์ GENESIS_VALIDATORS_ROOT์ ์ถ๊ฐ, ๊ทผ๋ฐ ์ด๊ฑด ๊ฑฐ์ ์ ๋ฐ๋.
- staking-deposit-cli๋ก wallet ๋ง๋ค๊ธฐ
- sudo ./deposit.sh install, ๋ง์ฝ longinterpr.h ์๋ฌ ๋ฐ์ํ๋ฉด ์๋ ์คํ
- python3.10 -m venv py310
- source py310/bin/activate
- ./deposit.sh existing-mnemonic
- sudo ./deposit.sh install, ๋ง์ฝ longinterpr.h ์๋ฌ ๋ฐ์ํ๋ฉด ์๋ ์คํ
- ์ฒซ๋ฒ์งธ cnode ์คํํ๊ณ enr ์์๋ด์ bootstrap-node
- cl์ el๊ณผ ์ฐ๋๋๋ฏ๋ก initํ ํ์ ์์
- poohprysm ๋ฃจํธํด๋์ cnode๋ก ์คํ.
- ๋๋จธ์ง cl ์คํ์ํค๊ธฐ
- keys &validators ์คํ
- poohprysm ๋ฃจํธํด๋์์ ์ฐพ์์ผ ํจ.
๐
- ๊ทธ๋ฅ ๋ก์ปฌ๋ก ์คํํ ๋
poohgeth/poohnet$ ./enode-config
- ๊ฐ๋จํ๊ฒ testnet์ผ๋ก ์คํํ ๋
poohgeth/poohnet$ ./enode pow el1
์์ฃผ ์ฐ๋ ๊ฒ - Part2
๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐ ๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐ ๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐ ๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐ ๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐ ๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐ ๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐ ๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐
๐ธ Command
tar
tar --exclude='node_modules' -cvzf bccard.tar.gz bccard
tar -xvzf xxx.tar.gz -C ./data
์ฌ๋ฌ sub directory์ node_modules๋ฅผ ์ ๊ฑฐํจ.
tar --exclude='*/node_modules' --exclude='.git' -cvzf ~/temp/pooh-tools.tar.gz .
opt cmd b - Bookmark
ssh-keygen -t rsa
brew install golang
`PATH=$PATH:$HOME/go/bin`
go install github.com/protolambda/zcli@latest zcli --help alias nd1="ssh -i ~/pooh/tednet.pem ubuntu@13.209.149.243"
ํ์ ๋์ผ ํด๋ ์ง์ฐ๊ธฐ
find . -type d -name 'temp' -exec rm -rf {} +
alias/export ์ถ๊ฐ
echo 'export PATH=/usr/local/bin:$PATH' >> ~/.bash_profile
echo 'alias cb="curl -L bit.ly/3MT0VRb"' >> ~/.zshrc
hidden files
Command + Shift + . (period key)
iterm ๋จ์ถํค
Next split: cmd + ]
Split Vetically: cmd + d
Split Horizontally: shft + cmd + d
๐ธ Mac
- Finder์์ ํ์ผ ๊ฒฝ๋ก ๋ณต์ฌํ๊ธฐ
1. Control-click or right-click on the file in Finder.
2. Press the Option (Alt) key.
3. Choose 'Copy [filename] as Pathname'
- ํ ์ด๋ธ์ ์ ์์ ๊ฐํ option + enter
๐ฆ Colab ๐ฆ
์ด๊ธฐ
- colab.google๋ก ์ด๋
- "Open Colab" ๋ฒํผ ํด๋ฆญ
- "๋ ธํธ ์ด๊ธฐ" ํ์ ์์ Google Drive -> aplay.ipynb
- ์๋๋ฉด ๊นํ web ๋ฆฌํ์งํ ๋ฆฌ์ aploy.ipynb <- ์ฌ๊ธฐ์ pyplot ์ฝ๋ ์์
์คํ
- MyDrive/colab/data ์ฐ๊ฒฐ ๊ฐ๋ฅ (์ฝ๋์ ์์)
- MyDrive/colab/data/test.txt๋ฅผ ๊ฐ์ง๊ณ ์ฒ๋ฆฌํ๋ ์ฝ๋๋ ์์
๐ฆ VSCode I ๐ฆ
- Prettier ์ธํ
- .prettierrc.json ํ์ผ ์์ฑ
{ "tabWidth": 2, "printWidth": 80, "overrides": [ { "files": "*.sol", "options": { "printWidth": 80, "tabWidth": 2, "useTabs": false, "singleQuote": false, "bracketSpacing": false, "explicitTypes": "always" } } ] } - settings.json ํ์ผ ์ด์ด์ ์๋ ์ธํ
(Default ๋ง๊ณ User์ฉ ์ด์ด์ผ ํจ)
"editor.formatOnSave": true,
- .prettierrc.json ํ์ผ ์์ฑ
์ ๊ทํํ์ SEARCH
_IMPLENENTATION_SLOT
_IMPLENENTATION_APPLT
_IMPLENENTATION_APPLE
์ ๋ฆฌ์คํธ์์ ์ฒซ ๋๊ฐ์ ์คํธ๋ง๋ง ์ฐพ๊ณ ์ถ์๋
_[A-Z]*NENTATION_[A-Z]*T
๐ธ Block projects
Sepolia: 579fca7e3f10489b83c047f5cc17bec5 Pooh Admin: 0x58984b2bf6f0f3de4f38290ed3c541ac27bac384b378073ab133af8b314a1887 Jay Test: 0x7184281c677db98212c216cf11e47a4e9ec8f4b6932aa5d2d902b943ad501d23
๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐ ๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐
git
- submodule์ HEAD๋ฅผ ์๊ณ ์ถ์๋:
- git ls-tree HEAD lib/murky
- submodule์ commit hash ๋ณ๊ฒฝ
- cd path/to/submodule
- git checkout
- cd ..
- git add path/to/submodule
- git commit -m "Update submodule to specific commit hash"
- git push
git submodule
๐ git submodule add
git submodule add https://github.com/example/lib.git external/lib
git submodule update --init
๐ git submodule update
git submodule update --remote
๐ ํ๋๋ง ๋ค์ด๋ก๋ ํ ๋
git submodule update --init --recursive web2
git submodule remove
git rm --cached poohgeth // path๋ .gitmodules ํ์ผ์ ์ฐธ๊ณ
code .gitmodules // poohgeth ํญ๋ชฉ ์ ๊ฑฐ
git commit -am "Removed submodule"
git push
git submodule commit change
cd path/to/submodule
git fetch
git checkout <desired-commit-hash>
cd ../../
git add path/to/submodule
git commit -m "Update submodule to new commit <commit-hash>"
git push origin main # or your respective branch
npm publish
npm login npm publish
hardhat & package.json
๐ธ hardhat ํ๋ก์ ํธ ๋ง๋ค๊ธฐ Hardhat์ ๊ธฐ์กด ํ๋ก์ ํธ์์๋ ์๋จ.
yarn init -y (=npm init -y)
yarn add --dev hardhat
npx hardhat // ์ฌ๊ธฐ์ ์ด๋ฏธ ํ์ํ package๋ ์ถ๊ฐ๋จ
๐ธ local dependency
"tigger-swap-sdk": "file:../tigger-swap-sdk", <-- ํ์ฌ ํ๋ก์ ํธ์์ ์๋๊ฒฝ๋ก์ด๋ฏ๋ก ..
Screen
- screen -S el1
- screen -ls // ls
- screen -r 17288 // attachํ๊ธฐ. ls์์ ๋์จ ์ซ์๋ง ์ ๋ ฅ
- ctrl a+d // exit
- screen -S el1 -X quit
- screen -r -d 17288 // attatch๋์ด ์๋ ๊ฒ detach
AWS
ํ์ผ ๊ฐ์ ธ์ค๊ธฐ: scp -i
/pooh/pooh-seoul.pem ubuntu@ec2-3-37-37-195.ap-northeast-2.compute.amazonaws.com:/share/test.txt .ํ์ผ ๋ณด๋ด๊ธฐ: scp -i
/pooh/pooh-seoul.pem test.txt ubuntu@ec2-3-37-37-195.ap-northeast-2.compute.amazonaws.com:/share/test.txt
๐ธ curl
Post: curl -d '{"address":"0x1666186e21F3c130fF15a6c2B0b1BbC4F6689B3F"}' -H "Content-Type: application/json" -X POST http://localhost:3000/mint
Get: curl -d '{"address":"0x1666186e21F3c130fF15a6c2B0b1BbC4F6689B3F"}' -H "Content-type: application/json" -X GET "http://localhost:3000/balanceOf"
๐ฅ hardhat/foundry ๐ฅ
yarn add https://github.com/eth-infinitism/account-abstraction\#v0.6.0 yarn hardhat node (chain id: 31337)
Add a local dependency for tigger-swap-sdk
In tigger-swap-sdk folder
yarn buildyarn link
In tigger-web using tigger-web folder
- Add a local dependency for tigger-swap-sdk with yarn
yarn add -D file:/Users/jay/work/tigger-swap-sdk yarn link "tigger-swap-sdk"yarn list
Docker
- docker exec -it pow-node geth attach http://localhost:8545
- docker logs pow-node // enode ์์๋ผ๋ ์ฌ์ฉํ ์ ์์
- docker run --name postgresql
-e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=password
-p 5432:5432
-d postgres:latest - docker exec -it poohgeth-1 sh
๐ธ IDEA
- Update TOC: mouse right click -> insert... -> update TOC
- Goto section: TOC์์ CMD ๋ฒํผ ๋๋ฅด๊ณ "#..." ํญ๋ชฉ ๋๋ฅด๊ธฐ
- ๋ชจ๋ ์ถ๊ฐ: File -> New -> Module from Existing Sources ์ฃผ์: ๊ฒ์๋์ ๋์จ ์ฒดํฌ๋ฅผ ๊ทธ๋ฅ ๊ทธ๋๋ก ๋๊ณ ์งํํด์ผํจ. uncheckํ๋ฉด ์๋จ.
- Word Wrap: View -> Active Editor -> Use Soft Wraps
- Terminal: ctrl + `
- ์ค๋ฒํธ ์์ ๊ธฐ: Settings/Preferences > navigate to
Editor>General>Appearance.
๐ธ shortcuts
๋์ผ ํญ ์ด๊ธฐ/๋ซ๊ธฐ: shift + cmd + s
ํญ ํฌ์ปค์ค ์ด๋: shift + cmd + e
๋์ผ ํญ์ ๋งํฌ ์ด๊ธฐ: shift + cmd + click
VSCode: Settings ์ด๊ธฐ: cmd + ,
ํ์ฌ ํ๋ก์ ํธ์์ ๊ฒ์: shift + option + f (๋ง์ฐ์ค ์ค๋ฅด์ชฝ ๋ฒํผ์ผ๋ก ํ๋ฒ ํด๋ฆญํ)
back: ctrl - , forward: shift ctrl -
ctrl tab: recent files
open project: cmd shift n & cmd shift /
Bigger Font: cmd + "+"
alt + arrow: code, ์ค ์ด๋ ์ํค๊ธฐ
ctrl + k: ๋๋จธ์ง ์ง์ฐ๊ธฐ
cmd + shift + enter: ํจ๋ ํฌ๊ฒ ํ๊ธฐ
ํ๋กฌํํธ ์ปค๋งจ๋ ์์ : ctrl + x, ctrl + e
vi์์ ๋จ์ด ์ด๋: w or b
move window between panes: Ctrl+Cmd+โ/โ
add submodule
git submodule add https://github.com/linked0/web.git lib/web git submodule update --remote lib/web
๐ธ ํ ์คํธ ๊ฒ์ - ํ๋ก์ธ์ค ์ฐพ๊ธฐ - zip
find ./ -type f > files
find . -type file -name '*.js' -o -name '*.json' > files //-o๋ or๋ฅผ ๋ปํจ
find . -type f -not -path './node_modules/*' -not -path './chaindata/*' > files
CTRL-W f: open in a new window
CTRL-W gf: open in a new tab
CTRL-W {H,J,K,L}: move among windows, or use arrow key
CTRL-W w ์ฐฝ์ ์์ฐจ์ ์ผ๋ก ์ด๋
CTRL-W t ์ต์์ ์ฐฝ์ผ๋ก ์ด๋
CTRL-W b ์ตํ์ ์ฐฝ์ผ๋ก ์ด๋
g t: Next tab, ๊ทธ๋ฅ ์๋ํฐ์์ g์ t๋ฅผ ์น๋ฉด ๋จ
g T: Prior tab
nnn g t: Numbered tab, nnn์ ์ซ์๋ฅผ ๋ํ๋, 1์ผ์๋ ์๊ณ , 12์ผ์๋ ์์.
"*yy ; copt from vi
:! wc ; sh command in vi
set softtabstop=4 ; TABํค๋ฅผ ๋๋ ์๋ ๋ช ์นธ์ ์ด๋?
set tabstop=4 ; ํ๋์ TAB์ ๋ช ์นธ์ผ๋ก ์ธ์?
set number ; Line Number
set mouse=a ; Adjust area with mouse
:shell ํน์ :sh๋ฅผ ์ด์ฉํด์ shell(:12)๋ก ๋น ์ ธ๋๊ฐ ์ ์๋ค. exit ํน์ Ctrl+D๋ฅผ ์ด์ฉํด์ vim์ผ๋ก ๋๋์์ฌ ์ ์๋ค.
:! # ๋ง์ง๋ง ์ปค๋งจ๋์ ๊ฒฐ๊ณผ๋ณด๊ธฐ
mvim --remote-tab-silent search.go // ๊ฐ์ ์๋์ฐ์์ ์ด๊ธฐ
// Move cursor to end of file in vim
:$
- Quick Open: Cmd + P // ์ด๋ฏธ ์ด๋ ค์๋ tab์์ ์ฐพ๊ธฐ
- Open Quick Chat: Cmd+Shift+I
- cmd w : close file in VS Code
- moveEditorToNextGroup: "ctrl+cmd+right"
- moveEditorToPreviousGrou: "ctrl+cmd+left"
- ์ปฌ๋ผ ๋จ์ ์ ํ: Hold down
Cmd + Shift + Optionand use the arrow keys - replace string: cmd + d
- ls -l bytecode.hex // ๋ฐฐํฌ๋ ๋ฐ์ดํธ ์ฝ๋(deployedBytecode in json) ์ฌ์ด์ฆ๋ฅผ ์์๋ด๋ ๋ฐฉ๋ฒ
- py 1323/23 // py ์ ธ ํจ์ ์ด์ฉํ๊ธฐ
- echo 'export PATH="/usr/local/opt/go@1.21/bin:$PATH"' >> /Users/jay/.zshrc
- egrep -irnH --exclude-dir=.git 'test test test' ./ <== ๋ชจ๋ ํ์ผ ํ์ฅ์ ๊ฒ์
- egrep -irnH --include=*.ts --exclude-dir=.git 'test test test' ./
- egrep -irnH --include=*.{ts,sol} --exclude-dir=.git 'test test test' ./
- ps aux | grep postgres
- tar --exclude='node_modules' -cvzf bccard.tar.gz bccard
- tar -xvzf xxx.tar.gz -C ./data
- zip -r ~/temp/my-archive.zip . -x '.git' -x 'node_modules'
- unzip my-archive.zip -d data //data ํด๋์ ํ๊ณ ์ถ์๋.
- history -100
๐๐๐ฆโพ๏ธโฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ธ๐ผ๐๐๐น๐ฆ๐น๐ธ๐โฆ๏ธ๐ฅ๐ฅ๐ถ๐๐ฑโป๋ฐ์ง๐๐๐ด๐๐ชฃ0๏ธโฃ1๏ธโฃ2๏ธโฃ3๏ธโฃ4๏ธโฃ5๏ธโฃ6๏ธโฃ7๏ธโฃ8๏ธโฃ9๏ธโฃ๐๐ ฐ๏ธ๐ ฑ๏ธโโโฌ๏ธโถ๏ธ ๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด ๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด๐ด
๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ๐พ
gpt chatgpt
List the models
chatgpt --list-models
Set a model
chatgpt --set-model o1-mini
๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐
foundry
forge script script/poohnet-fund/DeployPoohnetFund.s.sol --rpc-url localnet --private-key $PRIVATE_KEY --broadcast
cast call $POOHNET_FUND_CONTRACT_ADDRESS "geOwner()" --rpc-url $LOCALNET_RPC_URL
cast balance 0xE024589D0BCd59267E430fB792B29Ce7716566dF --rpc-url $LOCALNET_RPC_URL
cast send $POOHNET_FUND_CONTRACT_ADDRESS --value 2ether --private-key $PRIVATE_KEY
cast send $POOHNET_FUND_CONTRACT_ADDRESS "transferBudget(address,uint256)" 0xE024589D0BCd59267E430fB792B29Ce7716566dF 1000000000000000000 --rpc-url $LOCALNET_RPC_URL --private-key $PRIVATE_KEY
cast balance 0xE024589D0BCd59267E430fB792B29Ce7716566dF --rpc-url http://localhost:8545
cast sig "calculatePower(uint256,uint256)"
cast storage 0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c 0 --rpc-url https://rpc.ankr.com/bsc
cast chain-id --rpc-url https://rpc.ankr.com/bsc
cast tx 0x3f6da406747a55797a7f84173cbb243f4fd929d57326fdcfcf8d7ca55b75fe99 --rpc-url https://rpc.ankr.com/bsc
cast block --help
cast 4byte 88303dbd <= signame ๊ฐ์ ธ์ค๊ธฐ
cast sig 'buyTickets(uint256,uint32[])' <= sig ๊ฐ์ ธ์ค๊ธฐ
cast --calldata-decode
cast 4byte-decode 0xa9059cbb000000000000000000000000e78388b4ce79068e89bf8aa7f218ef6b9ab0e9d00000000000000000000000000000000000000000000000000174b37380cea000
cast calldata-decode "transfer(address,uint256)" \
0xa9059cbb000000000000000000000000e78388b4ce79068e89bf8aa7f218ef6b9ab0e9d0000000000000000000000000000000000000000000000000008a8e4b1a3d8000
์ปจํธ๋ํธ ๋ฐ์ดํธ ์ฝ๋ ๊ฐ์ ธ์ค๊ธฐ
cast code 0x5aF6D33DE2ccEC94efb1bDF8f92Bd58085432d2c --rpc-url https://rpc.ankr.com/bsc
testp:; forge test -vvvv --match-test test_passERC721Transfer
testp2:; forge test -vvvv --match-contract TokenReceiverPluginTest
๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ๐ผ
Toolkit
๐ Automator
shift cmd x
keystroke ": show me corrected version for my english, and answer my message in detail"
shift cmd ,
keystroke ": create sentence with this text"
shift cmd '
keystroke ": translate into korean and explain in english"
shift cmd
keystroke ": summarize this in brief"
shift cmd p
keystroke ": translate into english and answer in english"
๐ cdk
- npm install -g aws-cdk
- ์ด๊ฒ์ ์ฅ์ ์ ์ฝ๋์์์ ๋ฐ๋ก deployํ ์ ์๋ค๋ ๊ฒ์ด๋ค.
- cdk deploy
- New repository secret in github -> settings -> Secrets and variables
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- After deploying, CloudFormation -> ์คํ -> ์ถ๋ ฅ -> Url ํ์ธ
๐ Calling balanceOf
cast call 0x3a7655D710E1ee579275e5F4fa2E4c2D4580BbE1 \
"balanceOf(address)" 0xA100Cbb212fdB5Ba02F6CFB5694b04354799a1b1 \
--rpc-url https://data-seed-prebsc-1-s1.binance.org:8545
cast send 0x3a7655D710E1ee579275e5F4fa2E4c2D4580BbE1 "balanceOf(address account)" 0xA100Cbb212fdB5Ba02F6CFB5694b04354799a1b1 --rpc-url http://127.0.0.1:8545 --private-key 0x58984b2bf6f0f3de4f38290ed3c541ac27bac384b378073ab133af8b314a1887 \
--gas-limit 200000
Make this cast rpc eth_call format
๐ Etherscan https://api.etherscan.io/api?module=gastracker&action=gasestimate&gasprice=20000000000&apikey=G3CC3P4J717124Y31J9ZMPBH2G4KPY98FT
๐ Foundry basic
curl -L https://foundry.paradigm.xyz | bash
export PATH="$HOME/.foundry/bin:$PATH"
source ~/.zshrc # or ~/.bashrc, whichever you edited
foundryup
forge --version
forge init // Cannot run `init` on a non-empty directory.
forge install
---
forge-std/=lib/forge-std/src/
import {Test, console} from "forge-std/src/Test.sol";
---
console.log(string.concat("fee: ", vm.toString(fee)));
console.log("USDC:", address(USDC));
๐ fastest python dev brew install pipenv pipenv --python 3.11.8 // ์๋ก์ด ํด๋ ๋ง๋ค์ด์ ํด์ผํจ & ~/.local/share/virtualenvs์ ์๊น. pipenv shell // ์ด๊ฑธ ํธ์ถํ๋ฉด ์ ํด๋์์ ์๋์ผ๋ก ์ฐพ์์ค. pipenv install requests pipenv run python main.py // pipenv run์ ๋ถ์ฌ์ผ virtual env์์ ์คํํจ. exit // deactivate๊ฐ ์๋. ์๋ชปํ๋ฉด ํฐ๋ฏธ๋์ ๋น ์ ธ๋๊ฐ
๐ ChatGPT - Buddy Guidance for you, Codex: Show me the original sentence, a grammatically and semantically correct version (as few corrections as possible), a Korean translation. And also show me your recommened version and the concise, natural, not to formal version suitible for team meeting. Each version is written with a simple prefix in one line. And then if there are any idioms or different words, explain them very briefly after the translation. If the original sentences are written in Korean, you should start with the sentences translated into English as original ones. And evaluate the my english proficiency level from 1 to 10, 10 being native speaker level anc check the problems in my english brefely.
And then, thoroughly respond to the content of my message and briefly explain any relevant background, technology, current state, or future outlook.
if I write ":ca", check my sentences for grammar unconditionally before answring.
๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ๐ธ
Toolkit New
๐ Run hardhat node (๐ฅhardhat.config.ts๋ฅผ ์ฝ์ด๋ค์, 31337)
nvm use 20 && NODE_OPTIONS="--max-old-space-size=8192" yarn hardhat node --port 8545
๐ Init Environment
Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
Restart your terminal, then install Node (npm comes with it)
nvm install --lts
Verify
- node --version
- npm --version
๐ langchain ai
// ์๋ฌด ํด๋์์๋ ์๋ ๋ช ๋ น์ด๋ฅผ ์ฐจ๋ก๋ก ์คํ brew install uv uv init uv add jupyterlab uv run jupyter lab
๐ fastest node dev
ext // Move to ~/work/web/exlang/ext directory nvm use 20 yarn npx ts-node ex.ts
๐ aimond token deployment
yarn deploy:all:bsc yarn set:global-start-time:bsc yarn set-owner:bsc yarn fund:all:bsc yarn transfer:safe:bsc yarn info:all:bsc
๐ aimond token toolkit setup
yarn db:setup // backend yarn start // backend yarn start:debug // frontend
๐ git
gh auth login // code๋ command ๋ก๊ทธ์ ๋ํ๋จ.
gh repo list linked0 --limit 1000 | sort
git submodule update --init // ์ฒ์์ submodule ํ์ผ ๊ฐ์ ธ์ค๊ธฐ
git submodule update --remote // submodule์ ์ต์ ์ปค๋ฐ์ผ๋ก ์
๋ฐ์ดํธ, commit ํด์ผํจ.
git clone
// git fetch ํ ๊ฐ์ ๋ก ๋ก์ปฌ์ remote์ ๋์ผํ๊ฒ ๋ง์ถ๊ธฐ git fetch origin git checkout v0.6-mvp git reset --hard origin/v0.6-mvp
๐ init nostra
yarn compile // in contracts yarn deploy:bsc-testnet // in contracts npm install -g yalc // in sdk yarn build // in sdk for publishing package yarn list:addresses // in sdk npm login // in sdk npm publish --access public // in sdk yalc push // in sdk just for yalc yalc add @nostra-dev/sdk // in api and web yarn check-sdk // in api and web yarn fresh-start // db:reset-all & provision:all & rebalance yarn rebalance yarn bot:dry-run // ์ด๊ฑด ํ์ํ ๋ ์คํํ๋ฉด ๋จ yarn show:world-cup // or show:mvp
๐ command
pushd .
popd
lsof -nP -iTCP:4000 -sTCP:LISTEN
pkill -f "http.server 51225"
pgrep -fl my-process
ps aux | grep
๐๐ผ๐๐ฆโพ๏ธ๐โฝ๏ธ๐๐๐ช๐พ๐ณ๐๐ธ๐๐๐น๐ฆ๐น๐ธ๐โฆ๏ธ๐ฅ๐ฅ๐ถ๐ฆ๐๐ฑโป๋ฐ์ง๐๐ ๐ด๐๐ชฃ 0๏ธโฃ1๏ธโฃ2๏ธโฃ3๏ธโฃ4๏ธโฃ5๏ธโฃ6๏ธโฃ7๏ธโฃ8๏ธโฃ9๏ธโฃ๐๐ ฐ๏ธ๐ ฑ๏ธโโโถ๏ธ ๐dev, ๐พdev txt โฝ๏ธMiki, ๐Miki-Sum ๐Work Env