EntryPoint
이 문서는 BOT Chain에 배포된 EntryPoint의 온체인 인터페이스를 설명합니다. UserOperation을 직접 실행할 때 호출자는 Bundler의 역할을 수행해야 합니다.

1. PackedUserOperation
struct PackedUserOperation {
address sender;
uint256 nonce;
bytes initCode;
bytes callData;
bytes32 accountGasLimits;
uint256 preVerificationGas;
bytes32 gasFees;
bytes paymasterAndData;
bytes signature;
}
1.1 필드 및 인코딩
| 필드 | 의미 | 인코딩 레이아웃 |
|---|---|---|
sender | 스마트 계정 주소 | smartAccount(160) |
nonce | EntryPoint가 관리하는 2차원 nonce | key(192) ‖ sequence(64) |
initCode | 최초 배포용 Factory 주소와 calldata | 미배포: factory(160) ‖ factoryData(N), 배포됨: 0x |
callData | 스마트 계정에 보낼 실행 데이터 | selector(32) ‖ encodedArguments(N) |
accountGasLimits | 검증 및 실행 Gas 한도 | verificationGasLimit(128) ‖ callGasLimit(128) |
preVerificationGas | 온체인 검증 외 calldata와 bundle 오버헤드 | preVerificationGas(256) |
gasFees | EIP-1559 우선 수수료 및 최대 총 수수료 | maxPriorityFeePerGas(128) ‖ maxFeePerGas(128) |
paymasterAndData | 선택적 Paymaster, Gas 한도 및 데이터 | 사용: paymaster(160) ‖ paymasterVerificationGasLimit(128) ‖ paymasterPostOpGasLimit(128) ‖ paymasterData(N), 미사용: 0x |
signature | 계정이 검증하는 권한 데이터 | accountSignature(N) |
괄호 안 숫자는 bit 길이이며 N은 가변 길이입니다.
2. 실행 인터페이스
function handleOps(PackedUserOperation[] calldata ops, address payable beneficiary) external;
function handleAggregatedOps(UserOpsPerAggregator[] calldata opsPerAggregator, address payable beneficiary) external;
2.1 handleOps
| 파라미터 | 설명 |
|---|---|
ops | 서명 집계기를 사용하지 않는 UserOperation 배열 |
beneficiary | 배치의 실제 Gas 수수료를 받는 주소 |
EntryPoint는 전체 배치를 검증한 후 각 계정의 callData를 실행합니다. 검증 오류는 전체 배치를 되돌릴 수 있습니다. 비즈니스 실행 실패는 이벤트에 기록되며 외부 트랜잭션을 반드시 되돌리지는 않습니다.
2.2 handleAggregatedOps
계정이 0이 아닌 서명 집계기를 반환할 때 사용합니다. UserOperation을 집계기별로 그룹화하며 각 그룹은 집계 서명을 포함합니다. 집계가 필요 없으면 handleOps를 사용합니다.
| 필드 | 타입 | 설명 |
|---|---|---|
userOps | PackedUserOperation[] | 현재 집계기가 처리하는 작업 |
aggregator | IAggregator | 그룹 집계기, 0 주소는 집계 불필요를 의미 |
signature | bytes | 그룹 집계 서명 |
3. Hash, nonce 및 주소
function getUserOpHash(PackedUserOperation calldata userOp) external view returns (bytes32);
function getNonce(address sender, uint192 key) external view returns (uint256 nonce);
function incrementNonce(uint192 key) external;
function getSenderAddress(bytes memory initCode) external;
3.1 getUserOpHash
계정이 검증할 UserOperation hash를 반환합니다. hash에는 signature를 제외한 내용, 현재 EntryPoint 주소, 현재 chainId가 포함됩니다. 서명 후 관련 필드를 변경하면 서명이 무효가 됩니다.
3.2 getNonce
계정과 nonce key의 다음 전체 nonce를 반환합니다.
nonce = uint192 key || uint64 sequence
SimpleAccount의 기본 key는 0입니다. Owner EOA 트랜잭션 nonce나 계정의 eth_getTransactionCount로 대체하지 마세요.
3.3 incrementNonce
호출자가 자신의 nonce key sequence를 미리 증가시킵니다. 일반 계정은 검증 성공 후 EntryPoint의 업데이트를 사용합니다.
3.4 getSenderAddress
initCode로 반사실적 계정 주소를 계산합니다. 항상 revert하며 사용자 정의 오류 SenderAddressResult(address sender)로 결과를 반환합니다.
4. Deposit 및 stake
function getDepositInfo(address account) external view returns (DepositInfo memory info);
function balanceOf(address account) external view returns (uint256);
function depositTo(address account) external payable;
function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;
function addStake(uint32 unstakeDelaySec) external payable;
function unlockStake() external;
function withdrawStake(address payable withdrawAddress) external;
4.1 Deposit
계정 또는 Paymaster가 UserOperation Gas를 지불하기 위해 EntryPoint에 예치한 잔액입니다.
| 메서드 | 설명 |
|---|---|
balanceOf | deposit 조회 |
getDepositInfo | deposit, stake, 잠금 해제 상태 동시 조회 |
depositTo | 임의 주소가 지정 엔터티에 입금 |
withdrawTo | 호출자 자신의 deposit 인출 |
4.2 Stake
Factory, Paymaster 또는 집계기가 검증과 평판 규칙을 위해 잠그는 자금이며 Gas 결제에는 직접 사용하지 않습니다.
| 메서드 | 설명 |
|---|---|
addStake | stake 추가 및 최소 잠금 해제 지연 설정 |
unlockStake | 잠금 해제 대기 기간 시작 |
withdrawStake | 대기 기간 후 stake 인출 |
Deposit과 stake는 독립적입니다. stake만으로 Gas를 낼 수 없고, deposit만으로 제한된 storage에 접근하는 엔터티에 대한 Bundler의 stake 요건을 충족하지 않을 수 있습니다.
5. 핵심 이벤트
| 이벤트 | 주요 필드 | 용도 |
|---|---|---|
UserOperationEvent | userOpHash, sender, paymaster, nonce, success, actualGasCost, actualGasUsed | 각 UserOperation 최종 결과 |
AccountDeployed | userOpHash, sender, factory, paymaster | 반사실적 계정 배포 기록 |
UserOperationRevertReason | userOpHash, sender, nonce, revertReason | 비즈니스 호출 revert 데이터 |
PostOpRevertReason | userOpHash, sender, nonce, revertReason | Paymaster postOp revert |
UserOperationPrefundTooLow | userOpHash, sender, nonce | 실행 중 prefund 부족 |
BeforeExecution | 없음 | 검증 및 실행 단계 이벤트 구분 |
Deposited / Withdrawn | account, amount | deposit 변경 |
StakeLocked / StakeUnlocked / StakeWithdrawn | account, stake, time | stake 생명주기 |
외부 handleOps 성공은 내부 모든 UserOperation의 성공을 의미하지 않습니다. UserOperationEvent.success를 확인합니다.
6. 핵심 오류
| 오류 | 설명 |
|---|---|
FailedOp(opIndex, reason) | 검증 또는 prefund 단계 실패 |
FailedOpWithRevert(opIndex, reason, inner) | 계정, Factory, Paymaster 내부 revert 데이터 포함 실패 |
PostOpReverted(returnData) | Paymaster postOp revert |
SignatureValidationFailed(aggregator) | 집계 서명 검증 실패 |
SenderAddressResult(sender) | getSenderAddress의 예상 결과 컨테이너 |