Solidity + Web3j + Ganache를 통한 Smart Contract 배포

2023. 10. 14. 19:19· 언어/Solidity
반응형

작성 계기

  • Web3를 통한 프로젝트의 경우 truffle / hardhat 등의 Smart Contract을 위한 대중성있는 블록체인 프레임워크가 존재한다.
  • Java에서도 Web3j 모듈에서 다양하게 지원하긴 하지만, Web3 프로젝트에 비해 그 과정이 상당히 복잡하고 러닝커브가 높다.
  • Web3에 비해 커뮤니티 풀이 생각 외로 적고, 프로젝트 전체 플로우에 대해 참조할만한 블로그도 없어서 직접 작성하게 됐다.

사용 스택

  • Spring Boot 2.7 & Gradle 7.0
  • JDK 11 
  • Solidity 0.8.19

위 기술 스택으로 사용한 이유

  • Gradle 8.0 이상의 프로젝트 (JDK 17 / Spring Boot 3.0)에서는 아직 지원이 안 되는듯하여 이슈로 올라와있다.
  • Solidity 0.8.20 이상의 경우 Ganache에서 해당 버전 이상에서 "Invalid opcode" 에러가 발생한다.

 

1. Spring Project 생성

  • 위 사용 가능 버전에 참고하여 프로젝트를 생성한다.
  • external depndencies
    • solidity-gradle-plugin
    • org.web3j:core

2. Solidity 파일 생성

  • sol 파일 위치에 대해서는 DSL 에서 처리할 수 있으나, 기본적으로 제공되는 $projectDir/src/solidity 하위에 위치하도록 한다.
  • Contract 문법 등에 대해서는 주제와 떨어진 내용이니 따로 설명하지 않는다.

3. Web3j network에 배포

  • Smart Contract를 사용하기 위해서는 작성한 Contract를 Ethereum Network에 배포해야 한다.
  • 또한, 이를 배포하기 위해서는 작성한 Contract abi 또는 binary 파일을 Web3 나 Web3j를 통해 배포해야 한다.
  • 보통 NPM Package를 통해 배포하면 Web3 (Javascript 기반)를 사용하고
  • Gradle / Maven 등의 Java / Kotlin 프로젝트를 통해 배포하면 Web3j를 사용한다.
  • 내가 사용한 언어 모델은 Java라서 Web3j를 사용했다.

3-1. Web3j 사용에 대하여

  •  Web3j에서는 Contract라는 Class를 통해 Contract 배포에 대한 편의성을 제공해준다.
  • Contract 클래스는 기본적으로 추상 클래스 타입이고 다음과 같은 생성자를 제공해준다.
@SuppressWarnings({"WeakerAccess", "deprecation"})
public abstract class Contract extends ManagedTransaction {
...
	protected Contract(
            String contractBinary,
            String contractAddress,
            Web3j web3j,
            TransactionManager transactionManager,
            ContractGasProvider gasProvider) {

        this(
                new EnsResolver(web3j),
                contractBinary,
                contractAddress,
                web3j,
                transactionManager,
                gasProvider);
    }
    
...
  }
  • 나는 위 클래스를 활용하여 Web3jHelper라는 클래스를 구현했다.
  • 이 클래스는 하위 클래스로 위 클래스를 품고 있고, 생성할 때 binary code와 Gas 비용, Contract 생성자 정보만 넘겨서 처리하도록 간편화하여 구현했다. 코드는 다음과 같다.
  •  
class Web3jHelper {
    class InnerClass: Contract {
        constructor(byteCode: String,
                    contractAddress: String,
                    web3j: Web3j,
                    transactionManager: TransactionManager,
                    gasProvider: ContractGasProvider
        ): super(byteCode, contractAddress, web3j, transactionManager, gasProvider)
        
		companion object {
            private const val HOST = "http://localhost:7545"
            private const val EMPTY = "" // Contract Address

            fun create(byteCode: String, gasProvider: ContractGasProvider) : InnerClass {
                val web3j = Web3j.build(HttpService(HOST))
                val account = web3j.ethAccounts().send().accounts[0]
                val transactionManager = ClientTransactionManager(web3j, account)

                return InnerClass(byteCode, EMPTY, web3j, transactionManager, gasProvider)
            }

            fun getAccounts(): List<String> {
                val web3j = Web3j.build(HttpService(HOST))

                return web3j.ethAccounts().send().accounts
            }
        }
        
        fun deploy(encodedConstructor: String): InnerClass {
            return deploy(InnerClass::class.java, web3j, transactionManager, gasProvider, contractBinary, encodedConstructor, BigInteger.ZERO)
        }
        
        ...
    }
  • Host 정보는 테스트를 위해 하드코딩했지만, Property 파일을 통해 따로 빼 주는 것이 좋다.
  • 해당 클래스에는 도메인 로직에 해당하는 Contract 메서드들만 구현하여 생성하는 것이 좋다(위 getAccounts()와 같은)

4. Ganache Test Network에 배포

  • 보통 Smart Contract을 Public Chain에 배포할 수도 있지만, 일단 Gas Cost가 비싸다..
  • 그래서 Private Network를 사용했는데, Private Network를 사용하는 다양한 이유가 있긴 하지만, 나는 테스트를 위해 사용했다.
  • Ganache는 Truffle 에서 제공하는 Test Network인데, GUI부터 Network UX까지 구성하기 쉽게 되어있다.
  • 시작하기 위해서는 [Ganache Download] 사이트에  접속하여 받고 띄운다.

5. 배포 시 유의사항

  • Ethereun Network는 각 Network 마다 정해진 Gas Limit이 존재한다. => Ganache에서 Gas 초과가 발생하면 Limit을 늘리도록 한다.
  • Network에서 Account 정보는 위 사진의 MNEMONIC 12 자리를 통해 만들어진다. => 간략하게 얘기하면 계정이 모자르지는 않는다.
  • 배포 시에 from address 혹은 to address를 적을 때에는 위 사진과 같이 해당 Network에서 제공되고 있는 address 정보를 사용해야 한다.

6. 결론

  • Web3를 사용하면 Truffle / Hardhat 등의 간편한 Framework이 존재한다.
  • 내가 Java 개발자라고 해서 Web3보다 Web3j로 개발하는 것이 빠르다라고 생각했지만, 생각보다 Web3j의 Community Pool이 너무 적기도 하고 Web3로 개발하는 것이 생각 이상으로 너무 간단했었다.
  • 또한, Latest Version에 대한 지원 부족으로 맞는 버전을 계속해서 찾아야했던 수고로움이 많았다.

 

한 줄 요약

  • Web3 쓰자..
반응형
LIST

'언어 > Solidity' 카테고리의 다른 글

Soldity - Storage Collision  (0) 2023.09.27
Solidity Gas Cost  (0) 2023.09.26
'언어/Solidity' 카테고리의 다른 글
  • Soldity - Storage Collision
  • Solidity Gas Cost
iron_jin
iron_jin
배운 것에 대한 내 생각을 가지고 정리하자
學而不思則罔(학이불사즉망)배운 것에 대한 내 생각을 가지고 정리하자
iron_jin
學而不思則罔(학이불사즉망)
iron_jin
전체
오늘
어제
  • 전체 (163)
    • 도서 (10)
    • 생각 정리 (0)
    • 후기 모음 (14)
    • 언어 (20)
      • css (1)
      • java (9)
      • Kotlin (0)
      • javascript (0)
      • Solidity (3)
      • Python (3)
      • GO (3)
      • C++ (1)
    • Spring Framework (32)
      • spring (16)
      • JPA (6)
      • Error (4)
      • Settings (4)
    • 알고리즘 (62)
      • 이론 (0)
      • 연습문제 (58)
    • 인프라 (6)
      • 클라우드 (1)
      • 도커 (0)
      • AWS (4)
      • Elastic Search (0)
    • 쿠버네티스 (3)
      • 이론 (0)
      • 실습 (2)
      • 트러블슈팅 (1)
    • Nginx (2)
    • CS (4)
      • 서버 (0)
      • 리눅스 (2)
      • 네트워크 (0)
      • OAuth (2)
    • 형상관리 (3)
      • GIT (3)
    • Open API (3)
      • 카카오 API (1)
      • QGIS (2)
    • 보안 (0)
      • 알고리즘 (0)
    • 공통 (1)
      • 성능 관리 도구 (1)
    • Database (2)
      • MySQL (1)
      • Redis (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 2018 kakao
  • spring
  • spring boot
  • 2018 카카오 블라인드
  • 자바
  • 2019 kakao
  • 카카오 겨울 인턴십
  • 프로그래머스
  • 항해플러스
  • 2020 카카오
  • 도메인 주도 개발
  • 알고리즘
  • Java
  • 2019 카카오 블라인드
  • 항해99
  • 2020 카카오 블라인드
  • MySQL
  • AWS
  • 2019 카카오
  • 코딩테스트
  • 에릭 에반스
  • 백준
  • 스프링
  • Hibernate
  • 2020 kakao
  • ddd
  • 스프링 부트
  • Python
  • JPA
  • SpringBoot

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
iron_jin
Solidity + Web3j + Ganache를 통한 Smart Contract 배포
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.