Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

목표는 내 localhost 환경에서 작성한 스마트 컨트랙트를 vue3를 이용해 사용하는 것입니다.

간단한 스마트 컨트랙트

Solidity Docs에 가면 아주 기본적인 코드가 있습니다.

일단은 아주 간단한 함수라도 실행해보는게 목표이기 때문에 아래 코드를 사용하기로 했습니다.

https://solidity-kr.readthedocs.io/ko/latest/introduction-to-smart-contracts.html

스마트 컨트랙트 소개 — Solidity 0.5.10 documentation

소개 Ethereum 가상머신, EVM은 Ethereum의 스마트 컨트랙트를 위한 런타임 환경입니다. 이것은 완전히 독립되어 있기 때문에 EVM 에서 실행되는 코드는 네트워크나 파일 시스템, 기타 프로세스들에 접

solidity-kr.readthedocs.io

pragma solidity >=0.4.0 <0.6.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

Remix IDE

Remix IDE는 스마트 컨트랙트를 개발하고 배포까지 할 수 있는 손쉬운 도구입니다.

위 SimepleStorage를 개발하고 배포하는 것도 Remix를 사용할 것입니다.

우선 파일을 생성하고 코드를 작성합니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

코드를 작성하고 좌측에서 위에서 두번째 아이콘을 선택합니다. 이 화면은 컴파일을 하는 화면입니다.

Compile Storage.sol 버튼을 클릭하시면 됩니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo
Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

위에서 세번째 아이콘은 배포를 하기 위한 곳입니다.

배포를 하기전에 저는 localhost에 배포를 하고 싶기 때문에 별도의 tool이 필요합니다.

ganache

가나슈는 localhost에서 이더리운 개발을 도와주는 개인 블록체인 도구입니다.

저도 이해와 설명이 많이 부족하지만 local network를 사용하기 위한 도구 정도로 해석하고 있습니다.

가나슈를 다운받아서 실행을 시켜줍니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

MetaMask

이번엔 지갑이 필용합니다.

이번 테스트에서 사용할 지갑은 MetaMask입니다.

MetaMask는 보통 브라우저의 extension 상태로 제공하며 크롬의 경우 여기서 설치할 수 있습니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

MetaMask와 local network

MetaMask의 우측 상단을 보면 '이더리움 메인넷' 이라고 되어 있는 것을 볼 수 있습니다.

저희는 당장 메인넷을 사용할 수 없고 localhost에서의 테스트 환경이 목적이었기에 ganache로 띄운 환경을 MetaMask에 추가합니다.

'이더리움 메인넷' 을 눌러서 네트워크 추가로 갑니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

네트워크 추가 항목에서는 아래처럼 작성을 합니다.

네트워크 이름은 자유롭게 하시고 RPC 주소, 체인 ID, 통화 기호는 아래와 같이 적으면 될 것입니다.

RPC 주소는 가나슈의 상단에서도 볼 수 있습니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo
Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

작성을 하고 저장을 하면 localhost 네트워크를 사용할 수 있습니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

Deploy 배포하기

다시 Remix로 돌아가서 이번엔 배포를 합니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

먼저 위 항목에서 Environment를 Web3 Provider로 변경합니다.

Endpoint를 적는 모달창이 뜨면 ganache에 있는 RPC 서버를 입력합니다. 

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

CONTRACT도 잘 선택이 되어있는지 확인하고 Deploy 버튼을 눌러 배포를 합니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo
Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

좌측 하단에 보면 Deployed Contracts에 배포된 컨트랙트를 확인할 수 있습니다.

토글을 열면 컨트랙트로 작성한 함수들을 테스트 할 수도 있습니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo
Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo
Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo
Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

Vue 준비하기

여기서는 Vue를 이용해서 web3를 구현하고자 합니다.

저는 Vue CLI를 사용할 것이며 vue create로 손쉽게 프로젝트를 생성할 수 있습니다.

Vue + MetaMask

MetaMask의 설치여부를 체크하고 연결하는 방법은 별도의 패키지 없이 window.ethereum으로 가능합니다.

const { ethereum } = window;

그 후 request를 통해 연결 체크, 연결등을 할 수 있습니다.

https://docs.metamask.io/guide/ethereum-provider.html#using-the-provider

Ethereum Provider API | MetaMask Docs

Ethereum Provider API Recommended Reading We recommend that all web3 site developers read the Basic Usage section. Recent Breaking Provider Changes If you are an Ethereum application developer and are looking for information about our January 2021 provider

docs.metamask.io

let accounts = await ethereum.request({ method: "eth_accounts" }); // 연결체크

if (accounts.length === 0) {
  accounts = await ethereum.request({method: "eth_requestAccounts"}); // 연결 시도
}

Vue + Smart Contract

스마트 컨트랙트와 통신하기 위해서는 ehters 라는 패키지를 사용했습니다.

https://github.com/ethers-io/ethers.js

GitHub - ethers-io/ethers.js: Complete Ethereum library and wallet implementation in JavaScript.

Complete Ethereum library and wallet implementation in JavaScript. - GitHub - ethers-io/ethers.js: Complete Ethereum library and wallet implementation in JavaScript.

github.com

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

스마트 컨트랙트와 연결하기 위해서는 지갑의 주소와 abi 파일이 필요합니다.

모두 Remix ide에서 가져올 수 있습니다.

먼저 주소는 set, get을 테스트 한 곳 위에 복사할 수 있게 되어 있습니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

abi 파일은 컴파일 화면 하단에 있습니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

그리고 코드에서 스마트 컨트랙트와 연결하는 코드는 다음과 같습니다.

import SimpleStorage from "../utils/SimpleStorage.json";

...

const {ethereum} = window;
const provider = new ethers.providers.Web3Provider(ethereum);

const signer = provider.getSigner();
const connectedContract = new ethers.Contract(
    "주소",
    SimpleStorage,
    signer
);

이후 Smart Contract의 GET 함수를 사용해봅니다.

그러면 Remix IDE에서 테스트 했던 200이 뜨는 것을 볼 수 있습니다.

let getNumber = await connectedContract.get();
console.log(getNumber.toString(10));
Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

반대로 Vue에서 SET을 한 뒤에 Remix에서 GET을 할 때 잘 나오는지 확인해보겠습니다.

console.log(await connectedContract.set(100));

get을 set으로 바꾸어 실행을 하면 가스비를 요구합니다.

지갑은 열리는만 지갑에 이더리움이 없기 때문에 자금이 부족하다고 나올 것입니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

Ganache 계정을 MetaMask에 추가하기

지금은 자금이 부족하므로 거부를 하고 이더리움이 있는 새로운 계정을 추가해서 사용하겠습니다.

메타마스크를 열고 우측 상단 프로필 버튼을 누릅니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

그리고 계정 가져오기를 누릅니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

여기서 사용할 비공개 키 문자열은 ganache에서 가져옵니다.

ganache의 account 탭을 보면 계정들이 많이 있습니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

이 중 아무계정의 제일 우측 열쇠 버튼을 누르면 PRIVATE KEY가 나옵니다.

그 키를 복사해서 MetaMask에 입력합니다.

그럼 100ETH가 들어온 계정을 가져올 수 있습니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

이제 다시 set 명령어를 실행합니다.

이젠 계정에 이더리움이 있기 때문에 허용을 할 수 있습니다.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

이번에 다시 Remix IDE로 가서 get을 체크해볼 것입니다.

우리는 같은 스마트 컨트랙트를 쓰기 때문에 GET을 실행시키면 100이 나오는 것을 볼 수 있습니다.

체감상 엄청 빠르게 반영되지는 않아서 그 부분을 주의해서 테스트 해보세요.

Web3 스마트 컨트랙트 배포 - Web3 seumateu keonteulaegteu baepo

마치며...

지금까지 기본적인(?) localhost 환경에서 web3를 이용해서 smart contract에 접근하는 예제를 진행하였습니다.

여기까지도 수많은 도구를 사용해서 구현했지만 실제로 개발을 생각하면 이정도로도 부족한게 많다고 느꼈습니다.

예를 들면 ganache를 한번 종료하면 스마트 컨트랙트가 유지되지 않아 다시 배포를 했어야 했습니다. (quick start를 사용해서 그런가)

기회가 되면 더 많은 유용한 부분을 가지고 오겠습니다.

감사합니다.