콘텐츠로 건너뛰기

스마트 계정 세션 Snap: 게이밍 Dapp 자동 승인

ETHBogota 해커톤 Snap

7분 읽기
스마트 계정 세션 Snap: 게이밍 Dapp 자동 승인

MetaMask Snaps는 MetaMask를 세계에서 가장 확장 가능한 지갑으로 만들기 위한 로드맵입니다. 개발자라면 완전히 새로운 방식으로 자신만의 기능과 API를 MetaMask에 구현할 수 있습니다. Web3 개발자들은 이러한 성장의 핵심이며, 이 시리즈는 현재 개발 중인 혁신적인 MetaMask Snaps를 소개하는 것을 목표로 합니다.

스마트 계정 세션

Snap 저장소: https://github.com/livingrockrises/snap-auto-approvals

이것을 만든 이유는 무엇인가요?

게임 dapp에 안전한 방식으로 자동 승인 기능을 제공하여 원활한 사용자 경험을 만들기 위해서입니다.

기술적 구현 방식을 설명해 주시겠어요?

앱

저희 Snap은 두 가지 부분으로 구성되어 있습니다. 첫 번째는 사용자가 상호작용하는 웹사이트이고, 두 번째는 실제 Snap입니다. 이 두 요소는 클라이언트-서버 아키텍처와 유사한 방식으로 작동하며, Snap이 서버 역할을 하고 웹사이트가 클라이언트 역할을 합니다.

웹사이트의 사용자 흐름은 다음과 같습니다:

  1. EOA를 연결하고 스마트 계정 세션 Snap을 설치합니다.

  2. MetaMask 주소 위에 스마트 계정을 활성화합니다. MetaMask EOA가 이 스마트 계정의 컨트롤러가 됩니다.

  3. 스마트 계정에서 세션 모듈을 활성화합니다. 모듈은 스마트 Safe 계정에 추가적인 접근 제어 로직을 활성화합니다. 기본적으로 모든 스마트 계정은 두 가지 방식으로 제어됩니다. 서명자 키를 사용하는 MetaMask 계정 소유자와 자체 커스텀 접근 로직을 가진 선택적 모듈에 의해서입니다.

  4. 세션을 생성합니다.

  5. 이를 통해 모듈을 통해 지갑에서 트랜잭션을 승인받은 스마트 계정의 임시 세션 키가 생성됩니다. 세션에는 startTime, endTime 및 Dapp 컨트랙트의 커스텀 액션에 대한 권한과 같은 파라미터를 설정할 수 있습니다.

  6. MetaMask 팝업 없이 가스 또는 서명을 위해 위의 세션 키를 사용하여 자동 승인된 트랜잭션을 전송합니다.

MetaMask API

MetaMask는 사용자의 허가 하에 MetaMask Snaps에서 사용할 수 있는 API 호출을 제공합니다.

이 경우 아래 항목을 활용했습니다:

snap_manageState - MetaMask 내부에 암호화된 데이터를 저장할 수 있게 해줍니다. 예를 들어 생성된 세션 키 쌍을 저장하는 데 사용합니다.

export type SessionKeyStorage = {
  owner: string;
  sessionKey: string;
  pk: string;
};

export const storeSessionInfo = async (data: SessionKeyStorage) => {
  await wallet.request({
    method: 'snap_manageState',
    params: ['update', data],
  });
};

export const clearSessionInfo = async () => {
  const result = await wallet.request({
    method: 'snap_manageState',
    params: ['clear'],
  });
  return result;
};

export const getSessionInfo = async () => {
  const result = await wallet.request({
    method: 'snap_manageState',
    params: ['get'],
  });
  return result;
};
복사

snap_confirm - MetaMask 내부에 암호화된 데이터를 저장할 수 있게 해줍니다. 예를 들어 생성된 계정을 저장하는 데 사용합니다.


export const promptUser = async (
  prompt: string,
  description: string,
  content: string,
): Promise<boolean> => {
  const response: any = await wallet.request({
    method: 'snap_confirm',
    params: [
      {
        prompt,
        description,
        textAreaContent: content,
      },
    ],
  });
  console.log('Prompt user response', response);
  if (response) {
    return response;
  }
  return false;
};

promptUser(getMessage(origin),
            'Do you want to use Smart Account',
            `Your Smart Account Address is ${_smartAccount.address}`,
          ).then((approval) => {
            if (approval) {
              console.log('Sending smart acccount response ', _smartAccount);
              resolve({
                address: _smartAccount.address,
                owner: _smartAccount.owner,
              });
            } else {
              reject(new Error('EOA user'));
            }
          });
복사

Snap은 사이트에서 wallet_invokeSnap을 통해 전송된 수신 JSON-RPC 요청을 처리합니다.

위의 앱 흐름을 위해 connect, enable_session_module, create_session 및 interact와 같은 커스텀 요청 메서드를 만들었습니다. 아래에 한 가지 예시가 있으며 코드는 여기에서 확인할 수 있습니다.


export const useSmartAccount = async () => {
  console.log('invoke Snap...');
  const smartAccountResponse: any = await window.ethereum.request({
    method: 'wallet_invokeSnap',
    params: [
      defaultSnapOrigin,
      {
        method: 'connect',
        params: [],
      },
    ],
  });
  return smartAccountResponse;
};
복사

세션 키 모듈

세션 키를 통한 접근 제어를 사용하여 스마트 컨트랙트 지갑의 기능을 확장하기 위해 Gnosis safe 스타일의 모듈을 작성했습니다.

모듈 및 지갑 컨트랙트에 대한 코드는 여기에서 확인할 수 있습니다.

struct Session {
        address smartAccount;
        address sessionKey;
        uint256 startTimestamp;
        uint256 nonce;
        uint256 endTimestamp;
        bool enable;
        PermissionStorage permission;
    }

struct PermissionStorage {
        address[] whitelistDestinations;
        mapping(address => bool) whitelistDestinationMap;
        mapping(address => bytes4[]) whitelistMethods;
        mapping(address => mapping(bytes4 => bool)) whitelistMethodsMap;
        mapping(address => TokenApproval) tokenApprovals;
    }
복사

Snap을 호출하고 스마트 계정을 호출하여 세션이 생성되면, 릴레이어를 통해 스마트 계정에서 세션 키 모듈에 대해 아래 메서드가 호출됩니다.

function createSession(
        address sessionKey,
        PermissionParam[] calldata permissions,
        SessionParam calldata sessionParam
    ) external {
        require(
            !sessionMap[sessionKey].enable,
            "Session for key is already enabled"
        );
        Session storage _session = sessionMap[sessionKey];
        ...
복사

txHash: https://goerli.etherscan.io/tx/0x8b45f4cb0a7527bb7c44f6923eb9bb391faa656e212829ce0fd9c733ca71352b

세션이 생성되면, 릴레이어는 유효한 세션 키와 서명으로 세션 키 모듈에서 트랜잭션을 호출할 수 있습니다.


function executeTransaction(
        address _sessionKey,
        address payable _to,
        uint256 _value,
        bytes calldata _data,
        bytes calldata signature
    ) external returns (bool success) {
        Session storage session = sessionMap[_sessionKey];
        require(session.enable, "Session is not active");
        require(
            session.startTimestamp <= block.timestamp,
            "Session has not yet started"
        );
        require(session.endTimestamp >= block.timestamp, "Session has expired");
        ...
복사

txHash: https://goerli.etherscan.io/tx/0xf6d40bf9c74cff266f8bc26dabcf7a44ca1c0e85387f297f43fa5cb89bbea1a0

SDK

Biconomy SDK는 개발자가 스마트 계정을 활용하고 복잡한 다단계 사용자 여정을 간단한 원클릭 경험으로 단순화할 수 있는 궁극의 Web3 솔루션입니다.

각 사용자는 단순한 암호화 키 쌍이 아닌 스마트 컨트랙트 지갑을 받으며, dApp은 이 SC 지갑을 통한 트랜잭션 번들을 사용하여 사용자를 위한 다양한 원활한 상호작용을 커스터마이징할 수 있습니다.

아래 함수를 Snap을 호출하여 'connect' rpc 호출과 연결했습니다.


import SmartAccount from '@biconomy-sdk/smart-account';

async function getsmartAccount(): Promise<SmartAccount> {
  smartAccount = new SmartAccount(wallet, {
    activeNetworkId: Number(wallet.chainId),
    // supportedNetworksIds: supportedChains,
  });

  smartAccount = await smartAccount.init();
  console.log('initialized');
  console.log(smartAccount);
  return smartAccount;
}
복사

이것을 구현한다면 다음 단계는 무엇인가요?

keyrings 기능과 MetaMask UI에서 EOA 대신 스마트 계정 정보를 표시하는 기능을 기대하고 있습니다.

  1. 개발자들이 사용할 수 있도록 MetaMask Snaps와 호환되는 Biconomy SDK를 출시할 예정입니다.

  2. 소셜 복구 모듈 추가 및 스마트 계정을 사용한 원클릭 크로스체인 일괄 트랜잭션, 그리고 목적지 체인 트랜잭션이 실행되는 즉시 알림을 표시하는 기능을 추가할 예정입니다.

본인과 팀에 대해 간략히 소개해 주시겠어요?

Sachin은 Biconomy의 CTO이자 공동 창업자입니다. 컴퓨터 과학 배경을 가지고 있으며, web2에서 6년, web3에서 5년의 경험을 보유하고 있습니다. 그는 문제 해결에 체계적인 접근 방식을 취하는 것을 좋아하며, 아이디어를 빠르게 구현하고 테스트하기 위해 직접 실행하는 것을 즐깁니다.

Chirag는 Biconomy의 블록체인 엔지니어입니다. 그는 프로그래밍을 좋아하며 연구 및 개발을 통해 web3의 모든 것을 배우는 것을 즐깁니다.

MetaMask Snaps를 처음 접한 것은 언제이며, 어떤 경험이었나요?

ETHBogota 해커톤 직전에 MetaMask Snaps에 대해 알게 되었습니다. 문서화와 snap 메서드를 통한 기능에 매우 깊은 인상을 받았습니다.

MetaMask Snaps가 다른 지갑과 다른 점은 무엇인가요?

MetaMask 핵심 팀에 의존하지 않고 MetaMask 지갑의 기능을 확장하고 더 빠른 성장을 가능하게 하는 능력입니다. 개발자들은 JSON RPC 호출 인터페이스 및 스토리지와 같은 MetaMask의 기존 기능에 접근할 수 있습니다.

MetaMask와 함께 MetaMask Snaps를 개발하는 것이 본인과 팀에게 어떤 경험인가요?

기본적인 개발은 매우 직관적이었지만, 특정 메서드에 대한 권한 요구사항을 파악하는 데 많은 시간을 소비했습니다. 예를 들어 EOA처럼 스마트 컨트랙트 지갑의 잔액을 표시하기 위한 커스텀 UI 요소를 구축하는 기능은 현재로서는 까다롭습니다.

MetaMask Snaps는 본인에게 어떤 의미인가요?

MetaMask Snaps는 프론트엔드에 커스텀 위젯을 구축하거나 dapp이 통합할 필요 없이 MetaMask 내에서 ERC4337 스마트 컨트랙트 지갑을 지원할 수 있게 해주는 비밀 무기입니다.

MetaMask Snaps와 그것이 Web3 공간에서 열어주는 가능성에서 어떤 기회를 보시나요?

Dapp별 맞춤형 MetaMask Snaps는 더 나은 사용자 경험을 제공하고 멀티체인 상호작용을 가능하게 할 수 있습니다. 기존 Web3 사용자 기반 위에 수수료 추상화, 계정 추상화 및 지갑 보안 기능을 도입할 수 있습니다.

MetaMask Snaps를 시도하고자 하는 개발자들에게 공유하고 싶은 조언이 있나요?

개발 중 많은 장애물을 해결하는 데 도움이 되는 github discussions와 Discord를 확인해 보세요. JavaScript와 JSON RPC 호출에 익숙한 사람이라면 누구나 개발할 수 있습니다. snap-monorepos와 MetaMask Snaps 예시는 개발 속도를 높이기에 좋은 출발점입니다.

무언가를 저장해야 할 경우, 단일 객체만 저장할 수 있으므로 하나의 단일 객체 내에 여러 키 값을 중첩할 수 있습니다. 커스텀으로 호출된 snap 메서드에서 응답을 반환해야 할 때는 반드시 일반 JSON 객체를 반환하도록 하세요.

MetaMask Snaps로 개발하기

MetaMask Snaps를 시작하려면:

  1. 개발자 문서를 확인하세요

  2. MetaMask Flask를 설치하세요

  3. MetaMask Snaps 가이드를 확인하세요

  4. Twitter, GitHub discussions, Discord에서 저희와 계속 소통하세요

가까운 지역의 다음 해커톤에서 저희 팀을 만나보세요! 즐거운 BUIDLing ⚒️

면책 조항: MetaMask Snaps는 일반적으로 Consensys Software 이외의 제3자에 의해 개발됩니다. 제3자가 개발한 MetaMask Snaps의 사용은 전적으로 본인의 판단과 위험 부담 하에 이루어지며, 그러한 활동으로 인해 발생하는 모든 손실이나 피해에 대해 본인이 전적으로 책임을 진다는 것에 동의하는 것입니다. Consensys는 제3자가 개발한 MetaMask Snaps에 대해 구두 또는 서면으로 명시적이거나 묵시적인 어떠한 보증도 하지 않으며, 제3자가 개발한 MetaMask Snaps에 대한 모든 책임을 부인합니다. 블록체인 관련 소프트웨어 사용에는 위험이 따르며, MetaMask Snaps를 사용함으로써 이러한 위험을 전적으로 감수하게 됩니다.

AI가 번역했습니다. 오류가 있을 수 있습니다. 항상 정보를 확인하시기 바랍니다.

번역 평가하기

이 글의 작성자:

  • MetaMask

    MetaMask(구 Consensys Software Inc)은 세계 최대의 자기 수탁형 금융 플랫폼으로, 암호화폐와 전통 자산 모두에 걸쳐 자산을 보유하고, 사용하고, 저축하고, 불릴 수 있는 단일 공간을 제공합니다. MetaMask는 결제, 저축, 투자, 디지털 자산을 하나의 seamless한 경험으로 통합하는 소비자 플랫폼을 구축하고 있습니다. 세계에서 가장 널리 사용되는 자기 수탁형 지갑에서 성장한 MetaMask는 약 190개국에 걸쳐 사용자가 자신의 자금과 자산을 직접 통제할 수 있도록 합니다. MetaMask는 2016년부터 이더리움의 성장에 핵심적인 역할을 해왔습니다. 오늘날 MetaMask는 블록체인 경제의 중심에 자리하며, 오픈 머니(Open Money)를 위한 운영 체제를 구축하고 사람들이 자신의 금융 생활을 완전히 주도할 수 있도록 하고 있습니다.

    모든 글 읽기