Aleph Zero Snap: Web3 사용자를 Aleph Zero 네트워크로 온보딩

Aleph Zero 네트워크에 사용자를 온보딩하는 MetaMask Snap

7분 읽기
Aleph Zero Snap: Web3 사용자를 Aleph Zero 네트워크로 온보딩

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

Piotr, Michael과 함께하는 Aleph Zero Snap

ETHWarsaw 해커톤에서 Aleph Zero Snap을 개발한 Web3 개발자 PiotrMichael과 이야기를 나눠봤습니다.

Snap 저장소: https://github.com/piotr-roslaniec/ethwarsaw-2022/tree/main/azero-snap/packages/snap-adapter

왜 만들게 되었나요?

저희 생각에 Polkadot 생태계의 지갑 경험은 아직 부족한 부분이 있습니다. 반면, MetaMask Snaps와의 통합은 기존 Web3 사용자들을 Aleph Zero 네트워크로 유입시키는 데 도움이 될 수 있습니다.

기술적인 구현 과정을 설명해 주실 수 있나요?

어댑터(Adapter)

저희 Snap은 두 가지 부분으로 구성되어 있습니다. 첫 번째는 사용자가 상호작용하는 웹사이트이고, 두 번째는 실제 Snap입니다. 이 두 요소는 클라이언트-서버 아키텍처와 유사한 방식으로 작동하며, Snap이 서버 역할을, 웹사이트가 클라이언트 역할을 합니다. 이러한 자연스러운 경계를 반영하기 위해 Snap API를 adapter라는 별도의 패키지로 분리했습니다. 이 패키지는 웹사이트가 Snap과 상호작용하는 데 사용할 수 있는 모든 메서드를 노출합니다. 이러한 추상화 계층은 다른 클라이언트(웹사이트)가 Snap을 더 쉽게 사용할 수 있도록 합니다. 저희 API는 이름만 봐도 기능을 알 수 있는 네 가지 메서드로 설명할 수 있습니다. 더 자세히 알고 싶다면 전체 코드를 확인해 보세요.

export const getAccountFromSeed = async (seed: string): Promise<PublicAccount> => {
  return await requestSnap("getAccountFromSeed", [seed]);
}

export const generateNewAccount = async (): Promise<PublicAccount> => {
  return await requestSnap("generateNewAccount", []);
}

export const signTransaction = async (transaction: SignerPayloadJSON): Promise<{ signature: string }> => {
  return await requestSnap("signTransaction", [transaction as unknown as string]);
}

export const getAccounts = async (): Promise<string[]> => {
  return await requestSnap("getAccounts", []);
}
복사

앱(App)

레이어 간의 연결 부분을 설명했으니, 이제 첫 번째 레이어인 웹사이트로 넘어가겠습니다. 저희는 공식 브라우저 기반 polkadot 앱을 포크했습니다. 그런 다음 트랜잭션 서명, 계정 생성 또는 복구와 같은 핵심 기능을 브라우저 기반 지갑에서 Snap 기반으로 교체해야 했습니다. 예를 들어, MetaMask 내에서 트랜잭션에 서명하기 위해 QrSigner의 구현을 Snap의 signTransaction을 사용하도록 변경했습니다.

MetaMask Snap을 polkadot 앱과 통합함으로써 두 가지 개선 사항이 생겼습니다:

  • 첫째, 로컬 스토리지 기반의 polkadot 앱 지갑 대신 MetaMask 확장 프로그램의 보안 모델을 상속받을 수 있게 되었습니다.

  • 둘째, MetaMask 시드를 사용하여 결정론적 방식으로 polkadot 앱을 생성할 수 있어, 시드를 내보낼 때 Aleph Zero 키도 함께 내보낼 수 있게 되었습니다.

MetaMask API

MetaMask는 사용자의 허가를 받은 경우 MetaMask Snaps에서 사용할 수 있는 API 호출을 제공합니다. 이 경우 저희는 그 중 두 가지를 활용했습니다:

snap_manageState - MetaMask 내에 암호화된 데이터를 저장할 수 있게 해줍니다. 예를 들어, 생성된 계정을 저장하는 데 사용합니다. 상태와의 상호작용은 매우 간단하며 다음과 같이 단순화할 수 있습니다:

const request = async (method: 'clear' | 'get' | 'update', newState?: unknown): Promise<any> => {
if (['get', 'clear'].includes(method) && newState) {
    throw new Error(`Cannot ${method} with newState`);
}
if (method == 'update' && !newState) {
    throw new Error('Cannot call update without newState');
}

const params = newState ? [method, newState] : [method];
return await wallet.request({
    method: `snap_manageState`,
    params,
  });
}
복사

snap_getBip44Entropy_ - MetaMask 시드에서 엔트로피를 가져옵니다. 문서

MetaMask의 매우 유용한 라이브러리인 passworder가 있다는 점도 언급할 가치가 있습니다. 이 라이브러리를 통해 상태를 쉽게 암호화하고 복호화할 수 있습니다. 저희의 경우 상태를 암호화하기 위한 대칭 키로 MetaMask 시드의 엔트로피를 다시 한번 사용했습니다.

SDK

정리하자면, 저희는 여기저기에 JavaScript를 주입하여 Snap 사용을 가능하게 함으로써 polkadot 앱을 수정했습니다. Snap은 MetaMask 내의 시드에서 엔트로피를 가져오고 암호화된 상태를 관리할 수 있습니다. 마지막 단계는 Aleph Zero용 SDK인 polkadotjs와 통합하는 것입니다.

간단해 보이는 작업으로, npm install @polkadot/api를 실행하고 임포트하면 됩니다. 하지만 Snap에 의존성을 임포트하는 것은 까다로울 수 있습니다. 이러한 어려움은 Snap이 JavaScript 가상 머신에서 직접 실행되지 않고, 먼저 Secure ECMAScript(SES)에서 샌드박스 처리되어야 하기 때문에 발생합니다. 간단히 말해, 일반적으로 문제없이 컴파일되는 코드가 SES에서 로드될 때 실패할 수 있습니다.

코드

대부분의 라이브러리를 사용할 때는 문제가 없지만, 저희의 경우는 달랐습니다. SES 내에서 polkadotjs SDK를 평가하는 데 두 가지 문제가 있었으며, 이를 해결하기 위해 번들된 소스 코드에서 실행되는 두 개의 스크립트를 작성했습니다.

첫 번째 문제는 JavaScript 파일 내에 포함된 잘못된 형식의 wasm 코드로 인해 발생했습니다. 수정 스크립트는 다음과 같습니다:

const fs = require('fs').promises;
const path = require('path');

const dirPath =
  '../../../../node_modules/@substrate/smoldot-light/dist/cjs/instance/autogen';

// SES doesn't like double slashes in strings so we need to replace them with single slashes
// and string concatenation.
async function fixDoubleSlash() {
  const files = ['wasm0.js', 'wasm1.js', 'wasm2.js'];
  for (const file of files) {
    console.log('Fixing ${file}');
    const filePath = path.join(__dirname, dirPath, file);
    const contents = await fs.readFile(filePath, 'utf8');
    let fixedContents = contents;
    while (fixedContents.includes('//')) {
      fixedContents = fixedContents.split('//').join('/"+"/');
    }
    await fs.writeFile(filePath, fixedContents);
  }
}

fixDoubleSlash();
복사

두 번째 문제도 polkadot 확장 프로그램으로 인해 발생했는데, SES에서 금지된 window.addEventListener 메서드에 접근하려 했기 때문입니다. 이 문제도 간단한 방법으로 해결되었습니다:

const fs = require('fs').promises;
const path = require('path');

const bundlePath = path.join(__dirname, '../dist/bundle.js');

async function fix() {
  console.log(`Fixing ${bundlePath}`);
  const contents = await fs.readFile(bundlePath, 'utf8');
  const replaceMissingTypes = '\n\nwindow.addEventListener = function(){};\n\n';

  // Looking for a first breakline after the first line of the file
  // This is where we can safely inject our code
  const fixed = contents.replace('\n\n', replaceMissingTypes);
  await fs.writeFile(bundlePath, fixed);
}

fix();
복사

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

저희 Snap을 polkadot.js와 완전히 호환되도록 만들고 Polkadot 생태계에서 웹 지갑으로 활용 가능하게 하고 싶습니다.

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

Michael은 폴란드 은행에서 블록체인 기술을 다루는 프로그래머입니다. 프로그래밍과 새로운 것을 배우는 것을 좋아합니다.

Piotr는 NuCypher에서 근무하는 소프트웨어 엔지니어입니다. 프라이버시, 데이터, 분산 시스템에 관심이 있습니다.

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

Piotr - 오사카에서 열린 Devcon에서 MetaMask Snaps에 대해 처음 알게 되었습니다. 이 주제는 EthDenver 해커톤 직전인 올해 초에 다시 떠올랐습니다.

Michaeł - EthDenver 직후에 Piotr가 저에게 MetaMask Snaps를 소개해 주었습니다.

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

dapp에서 애플리케이션별 암호화/개인 키에 접근할 수 있는 기능 덕분에, 익숙한 브라우저 지갑 경험을 기반으로 새로운 사용자 흐름을 구축할 수 있습니다.

팀과 함께 MetaMask Snaps를 개발하는 경험은 어떤가요?

기본적인 기능은 갖춰져 있지만, 특히 커스텀 UI 요소가 필요한 더 정교한 MetaMask Snaps를 개발하는 것은 까다롭습니다. 배포, 테스트 등 웹 개발자로서의 사고 방식을 Snaps에 맞추는 방법을 파악하는 데 많은 시간을 보냈습니다.

MetaMask Snaps는 여러분에게 어떤 의미인가요?

커뮤니티에 실질적인 권한을 부여하는 도구입니다. 각자가 자신의 MetaMask에 어떤 기능을 넣을지 스스로 결정할 수 있습니다. 플러그인은 개발을 민주화하고 더 빠른 성장을 가능하게 합니다.

MetaMask Snaps가 Web3 공간에서 열어주는 가능성과 기회는 무엇이라고 생각하시나요?

더 많은 네트워크(특히 비EVM 네트워크)에 대한 접근; 트랜잭션 라이프사이클에 개입하여 커스텀 로직(안전 검사 등)을 추가하거나 UX를 커스터마이징할 수 있는 기능; dapp별 민감한 콘텐츠를 위한 브라우저 내 암호화 스토리지, 그리고 MetaMask Snaps를 통해 사용자에게 "자체 암호화 방식"을 제공할 수 있는 기능.

MetaMask Snaps를 시도해 보려는 개발자들에게 조언이 있다면?

SES에서 JS 라이브러리를 컴파일하는 것이 어려울 수 있지만, 저희 경험상 불가능하지는 않습니다. MetaMask 개발에서 피드백 루프가 꽤 길기 때문에 단위 테스트를 꼭 작성하세요.

MetaMask Snaps에는 소규모이지만 활발한 개발자 커뮤니티가 있습니다. Discord, GitHub 토론 등을 방문하는 것이 매우 유익할 수 있으며, 특히 제품이 아직 새롭고 이 커뮤니티 밖에서는 관련 교육 자료가 부족하기 때문에 더욱 그렇습니다.

MetaMask Snaps로 개발하기

MetaMask Snaps를 시작하려면:

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

  2. MetaMask Flask를 설치하세요

  3. MetaMask Snaps 가이드를 참고하세요

  4. Twitter, GitHub 토론, Discord에서 저희와 소통하세요

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

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

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

번역 평가하기
  • MetaMask
    MetaMask

    Consensys가 구축한 선도적인 자기 보관형 암호화폐 지갑이자 Web3로 가는 관문입니다.

    모든 글 읽기