IPAccountImpl 컨트랙트는 토큰 바운드 계정에 대한 ERC-6551 표준을 따르는 Story의 IP 계정 구현입니다. 이는 IP 자산이 다른 자산을 소유하고 관리하며, 트랜잭션을 실행하고, 허가된 방식으로 다른 컨트랙트와 상호 작용할 수 있는 기능을 제공합니다.

상태 변수

ACCESS_CONTROLLER

address public immutable ACCESS_CONTROLLER

권한 확인에 사용되는 AccessController 컨트랙트의 주소입니다. 이는 불변이며 생성 시 설정됩니다.

상속

IPAccountImpl은 다음을 상속받습니다:

  • ERC6551: Base implementation of the ERC-6551 standard
  • IPAccountStorage: Storage contract for IP Account data
  • IIPAccount: Interface for IP Account functionality

함수

생성자

constructor(
    address accessController,
    address ipAssetRegistry,
    address licenseRegistry,
    address moduleRegistry
)

새로운 IPAccountImpl 계약 인스턴스를 생성합니다.

Parameters:

  • accessController: 권한 확인에 사용될 AccessController 계약의 주소
  • ipAssetRegistry: IP 자산 레지스트리의 주소
  • licenseRegistry: 라이선스 레지스트리의 주소
  • moduleRegistry: 모듈 레지스트리의 주소

supportsInterface

function supportsInterface(bytes4 interfaceId) public view returns (bool)

계약이 특정 인터페이스를 지원하는지 확인합니다.

Parameters:

  • interfaceId: ERC-165에 명시된 인터페이스 식별자

Returns:

  • 계약이 인터페이스를 지원하는지 여부를 나타내는 불리언

token

function token() public view returns (uint256, address, uint256)

계정을 소유한 대체 불가능 토큰의 식별자를 반환합니다.

Returns:

  • chainId: 토큰이 존재하는 체인의 EIP-155 ID
  • tokenContract: 토큰의 계약 주소
  • tokenId: 토큰의 ID

isValidSigner

function isValidSigner(address signer, bytes calldata data) public view returns (bytes4 result)

서명자가 IP 계정을 대신하여 특정 작업을 실행할 수 있는 유효한 서명자인지 확인합니다.

Parameters:

  • signer: 확인할 서명자
  • data: 확인할 데이터, 로 인코딩됨abi.encode(address to, bytes calldata)

Returns:

  • 서명자가 유효한 경우 함수 선택자, 그렇지 않으면 0

isValidSigner

function isValidSigner(address signer, address to, bytes calldata data) public view returns (bool)

AccessController 권한 시스템을 통해 주어진 데이터와 수신자에 대해 서명자가 유효한지 확인합니다.

Parameters:

  • signer: 확인할 서명자
  • to: 거래의 수신자
  • data: 확인할 콜데이터

Returns:

  • 서명자가 유효한지 여부를 나타내는 불리언

owner

function owner() public view returns (address)

IP 계정의 소유자를 반환합니다.

Returns:

  • 소유자의 주소

state

function state() public view returns (bytes32 result)

거래 순서를 위한 IPAccount의 내부 nonce를 반환합니다.

Returns:

  • 계정의 현재 상태(nonce)

updateStateForValidSigner

function updateStateForValidSigner(address signer, address to, bytes calldata data) external

주어진 데이터와 수신자에 대해 서명자가 유효한 경우 IP 계정의 상태를 업데이트합니다.

Parameters:

  • signer: 확인할 서명자
  • to: 거래의 수신자
  • data: 확인할 콜데이터

executeWithSig

function executeWithSig(
    address to,
    uint256 value,
    bytes calldata data,
    address signer,
    uint256 deadline,
    bytes calldata signature
) external payable returns (bytes memory result)

서명자를 대신하여 IP 계정에서 거래를 실행합니다.

Parameters:

  • to: 거래의 수신자
  • value: 보낼 이더의 양
  • data: 거래와 함께 보낼 데이터
  • signer: 거래의 서명자
  • deadline: 거래 서명의 마감 시간
  • signature: EIP-712로 인코딩된 거래의 서명

Returns:

  • 거래의 반환 데이터

execute

function execute(address to, uint256 value, bytes calldata data) external payable returns (bytes memory result)

IP 계정에서 거래를 실행합니다.

Parameters:

  • to: 거래의 수신자
  • value: 보낼 이더의 양
  • data: 거래와 함께 보낼 데이터

Returns:

  • 거래의 반환 데이터

execute

function execute(
    address to,
    uint256 value,
    bytes calldata data,
    uint8 operation
) public payable returns (bytes memory result)

지정된 작업 유형으로 IP 계정에서 거래를 실행합니다.

Parameters:

  • to: 거래의 수신자
  • value: 보낼 이더의 양
  • data: 거래와 함께 보낼 데이터
  • operation: 수행할 작업 유형, 0 - CALL만 지원됨

Returns:

  • 거래의 반환 데이터

executeBatch

function executeBatch(
    Call[] calldata calls,
    uint8 operation
) public payable returns (bytes[] memory results)

IP 계정에서 일괄 거래를 실행합니다.

Parameters:

  • calls: 실행할 호출의 배열
  • operation: 수행할 작업 유형, 0 - CALL만 지원됨

Returns:

  • 거래들의 반환 데이터

isValidSignature

function isValidSignature(bytes32 hash, bytes calldata signature) public view returns (bytes4 result)

IP 계정에 대해 ERC1271 서명 검증이 비활성화되어 있습니다.

Parameters:

  • hash: 서명될 데이터의 해시
  • signature: 검증할 서명

Returns:

  • 항상 0xffffffff를 반환 (비활성화됨)

이벤트

Executed

event Executed(address to, uint256 value, bytes data, bytes32 state)

IP 계정에서 거래가 실행될 때 발생합니다.

Parameters:

  • to: 거래의 수신자
  • value: 보낸 이더의 양
  • data: 거래와 함께 보낸 데이터
  • state: 계정의 새로운 상태(nonce)

ExecutedWithSig

event ExecutedWithSig(address to, uint256 value, bytes data, bytes32 state, uint256 deadline, address signer, bytes signature)

서명자를 대신하여 IP 계정에서 거래가 실행될 때 발생합니다.

Parameters:

  • to: 거래의 수신자
  • value: 보낸 이더의 양
  • data: 거래와 함께 보낸 데이터
  • state: 계정의 새로운 상태(nonce)
  • deadline: 트랜잭션 서명의 마감 시간
  • signer: 트랜잭션의 서명자
  • signature: 트랜잭션의 서명

보안 고려사항

IPAccountImpl 계약은 여러 보안 조치를 구현합니다:

  1. 권한 시스템: 다양한 서명자와 작업에 대한 권한을 관리하기 위해 AccessController를 사용합니다.

  2. 서명 검증: 안전한 트랜잭션 승인을 위해 EIP-712 타입 데이터 서명을 구현합니다.

  3. 마감 시간 확인: 재생 공격을 방지하기 위해 트랜잭션 마감 시간을 포함합니다.

  4. Nonce 관리: 트랜잭션 재생을 방지하기 위해 상태(nonce) 시스템을 사용합니다.

  5. 입력 유효성 검사: 입력을 검증하고 잘못된 작업 방지와 같은 엣지 케이스를 확인합니다.

  6. 서명 가변성 보호: 서명 가변성 공격에 대한 보호를 포함합니다.

  7. 제한된 작업: 보안상의 이유로 CALL 작업(0)만 지원하여 잠재적으로 위험한 작업을 제한합니다.

  8. 업그레이드 비활성화: 계약의 불변성을 보장하기 위해 UUPS 업그레이드 기능을 비활성화합니다.

사용 예시

트랜잭션 실행

IP 자산 소유자는 자신의 IP 계정을 통해 트랜잭션을 실행할 수 있습니다:

// Assuming 'ipAccount' is an instance of IPAccountImpl
ipAccount.execute(
    targetContract,
    0, // No ETH sent
    abi.encodeWithSignature("someFunction(uint256)", 123)
);

서명을 통한 실행

허가된 서명자는 IP 계정을 대신하여 트랜잭션을 실행할 수 있습니다:

// Generate signature off-chain
bytes signature = signEIP712Message(...);

// Execute transaction
ipAccount.executeWithSig(
    targetContract,
    0, // No ETH sent
    abi.encodeWithSignature("someFunction(uint256)", 123),
    signer,
    deadline,
    signature
);