프론트엔드 개발자가 아는 만큼 설명해주는 블록체인 ⛓️ 이야기 (메타마스크 🦊, 컨트랙트, JSON-RPC)

어떰·2024년 1월 30일
4

블록체인 도메인에서 프론트엔드 개발을 한다면 마주하게 되는 것들에 대해서 이야기 해보려고 합니다.
블록체인 개발자는 아니기 때문에 더 깊은 지식은 없지만, 이정도 이해하고 있으면 우선 블록체인 개발자와 대화를 할 수 있게 됩니다❗️

메타마스크 지갑 🦊

이더리움 블록체인에서 NFT를 구매해봤다면 많이들 사용해보셨을 여우 지갑(👛) 입니다. 이 지갑은 이더리움 블록체인과 상호작용 하기 위한 웹 지갑 입니다. 크롬 익스텐션으로 쉽게 다운로드 받아서 지갑을 생성하여 사용할 수 있습니다.

그리고 쉬운만큼, 털리기도 쉽습니다.

메타마스크 익스텐션을 설치하고 웹 지갑을 생성하면 마지막에 시드(복구)구문을 주는데, 이 시드구문으로 지갑을 복원할 수 있습니다. 그러니 이걸 도둑 맞는다면? 도둑이 제 지갑을 똑같이 복원해서 그 안의 자산을 자기 지갑으로 전송하고 이는 아무도 지켜주지 않습니다.

🦊: 당신에게 12자리 시드구문을 드리겠습니당. 잘 보관하십쇼.

저는 돈이 없어서 털릴 것은 작고 소중한(❓) NFT 그림들 뿐이지만 털리면 속상하니 잘 보관해두었습니다.

스마트 컨트랙트가 뭘까?

블록체인에서의 컨트랙트는 자동으로 실행되는 계약을 의미합니다. 특정 조건이 충족되면 미리 정의된 액션을 자동으로 수행합니다. 이렇게 자동으로 실행되는 특성 때문에 스마트 컨트랙트라고 불립니다.

이런 자동 실행 기능은 복잡한 거래나 과정을 간소화 하고, 중개자가 없이도 신뢰성 있는 거래를 가능하게 해줍니다.

예를 들어서 꿀벌 A씨(🐝)가 메타마스크 지갑을 지원하는 KONKRIT 마켓에 들어와서 사자 B씨(🦁)가 판매 등록한 NFT를 구매한다고 가정해 봅시다.

꿀벌 A씨(🐝): NFT를 사고 싶은 사람
사자 B씨(🦁): NFT를 팔고 싶은 사람

꿀벌 A씨(🐝)는 메타마스크 지갑에 해당 NFT의 판매 가격만큼의 돈과 체인 사용료인 가스비를 낼 돈이 충분히 있습니다.

그 조건 외에 그 NFT를 판매 등록한 사자 B씨(🦁)가 체인 상에 실제로 소유주가 맞는지, 계약서가 만료되진 않았는지 스마트 컨트랙트가 요구하는 특정 조건들이 있습니다.

모두 만족한다면 A의 서명을 받고 스마트 컨트랙트가 실행이 됩니다.

그러면 꿀벌 A씨(🐝)와 사자 B씨(🦁)가 원하는대로 NFT와 돈을 주고 받게 됩니다. 이는 모두 중개자 없이, 마켓이 가지고 있는 스마트 컨트랙트를 통해 신뢰성 있는 거래가 진행된 것입니다.

🤔: 중개자 없는건 알겠는데, 왜 신뢰성 있다는거야?
🤖: 컨트랙트는 블록체인에 영구적으로 저장되고 변경이 불가능하기 때문이야.

메타마스크가 무슨 일을 할까?

메타마스크는 위에서 말씀드렸듯이 이더리움 블록체인과 상호작용하기 위한 웹 지갑입니다. 메타마스크는 사용자의 트랜잭션 요청을 이더리움 네트워크에 전송하여 실행하는 역할을 합니다.

좀더 코드 레벨로 내려가서 이야기를 해보면, 메타마스크는 window 객체에 ehtereum 객체를 주입합니다. 이 객체를 사용하여 프론트엔드 개발자는 메타마스크 지갑으로 이더리움 블록체인과 상호작용할 수 있게 됩니다.

메타마스크 지갑이 크롬에 깔려있다면, 개발자도구의 Console 창에서 다음과 같이 이 객체를 확인해볼 수 있습니다.

이더리움 블록체인 상에 배포된 어떤 스마트 컨트랙트의 어떤 메소드를 실행해야 한다면, 이 객체와 ethers.js(혹은 web3.js)와 같은 라이브러리, 스마트 컨트랙트가 이더리움 체인 상에 배포된 주소, ABI가 필요합니다.

준비물🎒

  • window.ethereum
  • ethers.js 라이브러리
  • Contract Address
  • Contract ABI(ABI는 스마트 컨트랙트 안에 존재하는 함수와 매개변수들을 JSON 형식으로 나타낸 리스트)

우선, window.ethereum 객체를 ethers.js 라이브러리에서 제공하는 provider(이더리움 네트워크에 대한 연결을 위한 추상화를 제공하는 클래스)의 메소드를 사용하여 web3Provider로 만듭니다.

그리고, getSigner를 통해 트랜잭션을 실행할 주체를 가져오고, 이를 모두 컨트랙트 인스턴스를 생성하는 생성자에 담아 인스턴스를 생성합니다.

// 1. provider 만들기
const provider = new ethers.providers.Web3Provider(ethereum)

// 2. 트랜잭션에 서명을 할 계정을 가져옴, 트랜잭션을 실행할 주체
const signer = provider.getSigner()

// 3. 실행할 스마트 컨트랙트의 주소와 ABI, 계정을 사용하여 컨트랙트 인스턴스 생성
const contractInstance = new ethers.Contract(contractAddress, contractAbi, signer)

이렇게 되면, 일단 (어떤 것일지는 알 수 없지만) 특정 컨트랙트의 메소드를 호출할 준비가 완료되었습니다.

이것이 NFT 민팅을 하기 위한 Minter 컨트랙트였다! 라고 하면 메소드명이 mint 일수도 있고, 그 mint 메소드는 내부 함수로 숨겨져 있고 외부에서 호출은 판매 타입에 따라 privateMint일수도, publicMint일수도 있습니다. 이는 ABI에서 정보를 얻을 수 있습니다.

// 실제로 이렇게 간단하지는 않지만!
const tx = await contractInstance.mint()

이런식으로 메소드가 호출이 되면, 이제 메타마스크(🦊)가 활약합니다.

위에서 호출한 컨트랙트 메소드는 이더리움 네트워크에 특정 트랜잭션을 실행하도록 요청하는 것입니다. 메타마스크는 먼저 트랜잭션 세부 정보를 표시하고 사용자에게 승인을 요청하는 팝업 창을 띄웁니다. 사용자는 그 세부 정보를 확인하고 실행하려는 계약 정보가 맞는지를 꼭꼭꼭 확인한 뒤 이를 승인 (🚨)합니다. 사용자가 트랜잭션을 승인하면, 메타마스크는 이를 이더리움 네트워크에 전송합니다. 이더리움 네트워크는 트랜잭션을 처리하고 결과가 블록체인에 기록됩니다. 블록체인에 기록된 결과는 이런 곳(❓)에서 확인이 가능합니다.

JSON-RPC 통신은 뭐지?

JSON-RPC원격 서버와 클라이언트 사이의 통신을 위한 프로토콜 입니다. 클라이언트가 JSON 형식의 메시지를 서버로 보내 요청을 하고, 서버는 그에 대한 응답을 다시 JSON 형식으로 보내는 방식 입니다. 이러한 통신 방식으로 이더리움 블록체인과 통신을 합니다.

🤔: 그렇지만, 위에서 그냥 컨트랙트 인스턴스를 만들어서 메소드 호출을 했잖아? 저기 어디에 JSON 형식의 메시지를 보내는게 있어?
🦊: 내가 했지.😉

메타마스크가 트랜잭션을 이더리움 네트워크에 전송할 때 JSON-RPC 프로토콜을 사용합니다. 메타마스크는 이 프로토콜을 이용하여 사용자가 발생시킨 트랜잭션 요청을 이더리움 네트워크에 전달하고, 그 결과를 받아옵니다. 이러한 방식을 통해서 웹 애플리케이션은 블록체인 네트워크와 효율적으로 통신할 수 있게 됩니다.

profile
요즘 보기 드문, 자세가 올바른 프론트엔드 개발자

0개의 댓글