[hardhat/ethers.js] HW Ledger 체크

ethers.js v5 기준 hardhat 태스크

import { LedgerSigner } from "@anders-t/ethers-ledger";
import { task } from "hardhat/config";

task("checkHW", "Check HW Wallet")
  .addOptionalPositionalParam("accountNumber", "Index of the address of the HW wallet")
  .setAction(async (taskArgs) => {
  const accountNumber = taskArgs.accountNumber;
    const _master = new LedgerSigner(ethers.provider, `m/44'/60'/${accountNumber}'/0/0`);
  _master.getFeeData = async () => {
    return {
      gasPrice: ethers.BigNumber.from(0),
      lastBaseFeePerGas: ethers.BigNumber.from(0),
      maxFeePerGas: ethers.utils.parseUnits("800", "gwei"),
      maxPriorityFeePerGas: ethers.utils.parseUnits("800", "gwei"),
    };
  };
  const master = _master;

  console.log(`HW Ledger: [${accountNumber}]:${await master.getAddress()}: ${ethers.utils.formatEther(await master.getBalance())} ETH`);
});

사용은 hh checkHW 0 와 같이 한다.

[ethers.js] ERC20 balance 체크

hardhat task로 만든 ERC20 잔액 확인 태스크

task("balanceERC20", "Check the balance of ERC20 token")
  .addPositionalParam("tokenAddress", "ERC20 Token contract address")
  .addPositionalParam("address", "Address to be checked")
  .setAction(async (taskArgs) => {
    const ERC20 = await ethers.getContractFactory("@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20");
    const erc20 = await ERC20.attach(taskArgs.tokenAddress);
    console.log(ethers.formatEther(await erc20.balanceOf(taskArgs.address)), await erc20.symbol());
  });

[ethers.js] Transaction details 얻기 및 ERC20 Transfer 정보 얻기

hardhat task로 만든 txHash로 transaction details 얻어서 ERC20 Transfer() 이면 정보 출력.

task("trasactionDetails", "Get the transaction deatils")
  .addPositionalParam("txHash", "Transaction Hash")
  .setAction(async (taskArgs, hre) => {
    const provider = ethers.provider;
    const transaction = await provider.getTransaction(taskArgs.txHash);
    console.log(transaction);
    if (transaction.value === 0n) {
      if (transaction.data.slice(0, 10) === "0xa9059cbb") {
        console.log("---- ERC20 Transfer -------------------------");
        await hre.run("parseERC20TransferData", { data: transaction.data });
      }
    }
  });

task("parseERC20TransferData", "Parsing")
  .addPositionalParam("data", "Transacton Data")
  .setAction(async (taskArgs) => {
    const abiCoder = new ethers.AbiCoder();
    const decodedData = abiCoder.decode(['address', 'uint256'], "0x" + taskArgs.data.slice(10));
    const to = decodedData[0];
    const value = decodedData[1].toString();

    console.log('To Address:', to);
    console.log('Token Amount:', ethers.formatEther(value));
  });

[ethers.js] Contract 시그니처와 hash 확인

const ca = await ethers.getContractFactory("DasomToken");
const cabi = ca.interface;
cabi.format() // Fragments 확인
cabi.forEachFunction((func, index) => { console.log(func.format()); }); // 각 함수의 시그니처 확인
cabi.forEachFunction((func, index) => { console.log(func.format(), ethers.keccak256(ethers.toUtf8Bytes(func.format()))); }); // 시그니처와 해시 값 확인.

WSL Import/Export

Export

wsl.exe --export <DistributionName> <FileName>

WSL 관련 모든 프로그램 닫은 후,

wsl --export Ubuntu-20.04 Ubuntu20.04_dasomoli.wsl

Import

wsl.exe --import <DistributionName> <InstallLocation> <FileName>

Install할 경로 폴더 (C:\Users\dasomoli\AppData\Local\Packages\Ubuntu-20.04-dasomoli)를 만든 후,

wsl --import Ubuntu-20.04-dasomoli C:\Users\dasomoli\AppData\Local\Packages\Ubuntu-20.04-dasomoli Ubuntu20.04-dasomoli.wsl

[git] 추가된 파일이지만 변경은 무시하고 싶은 경우

git에서 repository에 파일은 추가해서 두고 싶지만 해당 파일이 빌드 중 변경되는 등의 이유로 변경은 무시하고 싶은 경우가 있다. 이런 경우 .gitignore에 추가해도 repository에 추가된 파일이므로 변경을 계속 추적하게 된다. 이 변경을 무시하고 싶다면 다음 명령을 주면 된다.

git update-index --assume-unchanged <file>

위 명령을 주면 해당 파일은 변경되어도 git status를 해도 나오지 않고 무시된다. 그러므로 주의해야 한다. 해당 파일을 다시 추적하고 싶다면 다음 명령을 입력한다.

git update-index --no-assume-unchanged <file>

[Javascript] Arrow function 정리

형식

다음은 모두 함수의 선언 혹은 표현식입니다. 마지막 형태가 arrow function입니다.

function dasomoli(arg1, arg2) {}
const dasomoli = function(arg1, arg2) {};
const dasomoli = (arg1, arg2) => {};

function 키워드를 제거하고 “=>” 를 중간에 넣는 형식입니다. 매개 변수 역시 사용 가능합니다.

바로 실행하고 싶은 경우(IIFE: Immediately Invoked Function Expression), 다음과 같이 괄호로 감싸서 실행합니다.

((arg1, arg2) => {
  console.log(arg1);
  console.log(arg2);
})(window, document);

생략 가능 형태

매개 변수가 하나인 경우, ( ) 생략 가능

매개 변수가 하나인 경우 괄호를 생략 가능합니다. 다음은 예제입니다.

const dasomoli = (arg1) => {};
const dasomoli = arg1 => {};

바로 return하는 경우, { }와 return 생략 가능

arrow function이 바로 return 하는 경우, 중괄호 { } 와 return은 생략 가능합니다. 다음은 예제입니다.

const dasomoli = (arg1, arg2) => {
  return arg1 + arg2;
}
const dasomoli = (arg1, arg2) => arg1 + arg2;

바로 { }로 감싼 object를 return 하는 경우, { }와 return은 생략 가능하지만 object를 ( )로 감쌈

예외로 { } 로 감싸는 object를 리턴하는 경우, object 전체를 괄호()로 감싸주어야 합니다. 다음은 예제입니다.

const dasomoli = () => { return { prop1: 1 }; }
// const dasomoli = () => { prop1: 1 } <- 이건 안됩니다.
const dasomoli = () => ({ prop1: 1 });

array는 상관 없습니다.

const dasomoli = () => { return [ v1, v2, v3 ]; }
const dasomoli = () => [ v1, v2, v3 ];

[MySQL] DB auto repair 및 optimize

제공하는 mysqlcheck로 check 및 복구, optimize를 하려면 다음과 같이 한다.

mysqlcheck -u <USER_ID> -p<PASSWORD> --auto-repair <DB_NAME>
mysqlcheck -u <USER_ID> -p<PASSWORD> --optimize <DB_NAME>

예제로 wordpress의 경우, user를 wordpress로 했다면, 다음과 같이 하면 된다.

mysqlcheck -u wordpress -pPASSWORD_HERE --auto-repair wordpress
mysqlcheck -u wordpress -pPASSWORD_HERE --optimize wordpress

근데 wordpress의 경우 테이블을 optimize를 지원하도록 만들지는 않는다…