개발공부일지
BlockChain - gas paymaster, meta transaction, ethers 본문
목차
1. ERC 4337
2. 계정 추상화
3. ERC4337 이전에 제안된 개념
4. 가스비 대납 paymaster
5. metaTransaction 실습
6. ethers 사용하기
1. ERC 4337
① user Operations
- 프론트 페이지에서 보내는 객체(트랜잭션 형태)
- 새로운 트랜잭션 pool에 요청하면 객체가 쌓임(pending상태)
- EIP-2718 === 미래의 거래유형을 위해서 새로운 트랜잭션 pool 유형을 정의함
- 기존의 트랜잭션 수정하기 않기 위해서 → 이전버전과 호환이 되지않을수있기때문
- Dapp 환경에서 새로운 트랜잭션 풀에 담기위해 새로운 객체를 만들어서 요청을 보냄,
→ 담아놓은것을 처리하는것이 bundlers
② bundlers
- user Operations 객체들을 pool에서 수집 → 다중의 서명을 검증 → DTO 데이터를 하나의 트랜잭션 형태로 변경함
→ 컨트랙트로 요청보냄
- node에서 배웠던 entity라고 생각하기
- 객체들을 다 가지고 와서 서명을 검증하는 암호학을 추가할수도있음
③ entrypoint
- bundlers에서 보낸 트랜잭션 내용을 처리할 컨트랙트
- ERC 4337 사용 목적
→ WEB3의 지식이없는 유저도 일반페이지/앱 사용하는 느낌을 받게 UX 경험을 좋게 만들어주기 위해
2. 계정 추상화
- 추상화의 개념은 실제의 것에서 시작해서 불필요한 요소들을 제거함
- 계정에는 EOA, CA 가 있는데 이 두개를 모호하게 만들어
- CA를 EOA처럼 사용해서 더 복잡한 트랙잭션 요청하는것
- 기존의 방식은 EOA계정이 개인키로 서명해서 트랜잭션을 CA에 요청하는 차이가 있음
- EOA, CA는 개인키 유무차이가 있음 (CA는 개인키 X)
- 계정을 추상화 한다는 것은 EOA와 CA 두계정 모두 트랜잭션 발생가능하게 함 -> EOA와 CA의 차이를 줄임
- 추상화하려는 이유 :
- EOA계정을 사용자가 직접 가지고 사용하지 않음!
- CA계정을 하나 만들어주어서 CA계정으로 요청을 보낼수있게 로직을 작성
- 다중 서명 확인과 임의의 서명 확인(암호학)
- 일정 시간 출금 불가능, 소셜 복구
- 사용자는 클릭 한번으로 web3 생태계에 참여가 가능해짐
- 추상 계정의 단점 보완으로 서명의 문제 : EIP-1271 방식으로 서명하는데 추상계정은 다른 방식의 서명을 사용해야해서 가스비를 연구해서 제안한 내용
3. ERC4337 이전에 제안된 개념
- EIP 이더리움 개선 제안
- https://eips.ethereum.org/EIPS/eip-4337
- EIP 중에서 EIP-86, EIP-2938 실현이 불가능했고
- 합의계층을 변경하지 않고 상위 인프라에서 계정을 추상화하는 접근 방식을 도입
- ERC4337은 CA의 컨트랙트를 사용자가 계정으로 사용할수있게 검증 로직을 작성하는 개념
- 이더리움 합의계층의 변경을 피하고 상위 인프라에서 해결
- 기존의 이더리움 프로토콜을 추가나 트랜잭션 구조를 변경하지 않고 추상화 시키자는 것
- user Operations의 객체 내용을 새로운 트랜잭션 풀에 담고
- 각각의 노드는 bundlers를 통해 user Operations의 객체들을 조회해서 하나의 트랜잭션으로 엔트리포인트(컨트랙트)에 요청을 보낸다.
4. 가스비 대납 paymaster
- 번들러에서 엔트리포인트과정에서 가스비를 대납해주는 metaTransaction
- web3를 모르는 사용자의 경우 가스비를 모르고,
- 웹사이트에서 토큰을 받아 수가 늘어나고 그 토큰을 사용하고자할때 가스비가 없어서 토큰을 지불할수가 없음
(트랜잭션을 발생시킬수가없음)
- 이런 사용자를 위해 가스비를 대신 지불해주는 대신 나중에 다른형태로 요금발생시키는 것
(이후 어떻게 요금 발생시킬지는 우리가 작성할 로직내용)
5. metaTransaction 실습
- 설치하기
npx create-react-app meta
npm install ethers ganache express cors axios @openzeppelin/contracts
npx ganache
remixd -s . --remix-ide "https://remix.ethereum.org/"
- 가나쉬 네트워크 사용해서 제공하는 10개의 계정 사용 (그중에 가장 마지막 지갑을 대납 역할 계정)
- ERC20 토큰을 민트하는 컨트랙트작성 (token.sol, metaTransactiosn.sol)
- express 백엔드열고 api설정, axois로 요청
- remix로 배포하기
- 가장 마지막 계정으로 배포하기
- 토큰먼저 배포하고 그 트랜잭션 CA계정으로 metatransaction 배포
- 다시 서버로 돌아가서 app.post('/metaTransaction') 작성
- 객체를 트랜잭션 pool에 담아놓고 서명검증하기
- 백엔드 다중 트랜잭션 처리하면서 가스비를 가장 마지막 계정이 지불
6. ethers 사용하기
https://docs.ethers.org/v6/getting-started/
** 기존방식으로 확장프로그램 연결하는 방법
- getSigner() : 접속된 계정확인 가능함
- getBalance() : 연결된 지갑의 잔액
- formatEther() : 이더단위로 변경
*** 가나쉬 네트워크 계정전체를 객체로 담아서 사용하는방법
- ganache 사용하기 Private Keys 전체를 객체에 담아 사용
- JsonRpcProvider() : 경로를담아 "http://127.0.0.1:8545" 요청 → 가나쉬
- 여러개의 비동기를 처리하기위해 promise.all사용
- Wallet() : 지갑이 해당 네트워크에 요청 보낼수있는 인스턴스 생성
- wallet.address : 개인키로 만든 공개키
import { ethers } from 'ethers';
const provider = new ethers.JsonRpcProvider('http://127.0.0.1:8545');
const wallet = new ethers.Wallet(myPrikey, provider);
const balance = await provider.getBalance(wallet);
const balanceETH = ethers.formatEther(balance);
const senderSigner = ethers.verifyMessage(JSON.stringify(message), signature);
const contract = new ethers.Contract(contractAddress, contractABI, provider);
const ethPrv = new ethers.BrowserProvider(window.ethereum);
const signer = await ethPrv.getSigner();
※ user Operations으로 객체를 만들고 그걸 트랜잭션 POOL에 담고 bundlers에서 객체를 트랜잭션으로 만들어서 엔트리포인트(컨트랙트)에 요청을 보낸다!
※ EIP(Ethereum Improvement Proposals) 이더리움 개선 제안 제도
※ EIP 2771 (가스 리스 대납) : 기존 트랜잭션의 구조를 유지하면서 상위의 트랜잭션의 풀을 하나 더 만들어 관리하는 것
'BlockChain' 카테고리의 다른 글
BlockChain - Proxy contract, EVM OPCODE, assembly (0) | 2024.02.08 |
---|---|
BlockChain - factory contract, DAO, modifier, checks-effects-interactions pattern, mutex (0) | 2024.02.07 |
BlockChain - ERC721, IPFS, pinata (0) | 2024.02.01 |
BlockChain - token, transfer (0) | 2024.01.31 |
BlockChain - 메타마스크 네트워크 추가하기 (0) | 2024.01.31 |