소프트웨어 개발을 업으로 삼고 오랜동안 일하며 느끼는 것 중의 하나는 빠른 IDE 의 발전속도이다.

처음으로 IDE 라는 개념을 접하게 된 것은 Borland 사의 Turbo-C IDE 였으며 이후 Vim, MS 의 Visual Studio, Eclipse, IntelliJ 와 VSCode 등의 IDE 도구들을 써왔으며, 그 도구들의 기능 중 가장 큰 발전이 있었다고 느끼는 부분은 바로 Code Assist 기능이다.

 
대표적으로 Visual Studio 의 Intelli Sense, JetBrains 의 IDE (IntelliJ IDEA, PyCharm, WebStorm 같은) 의 Code Completion, Eclipse 의 Code Assist, Sublime 같은 Text Editor 의 Auto-Completion 기능들이 이러한 Code Assist 기능이며, 요즘은 이러한 Code Assist 기능 없이는 개발 생산성이 떨어지는것은 물론이고 개발이 불가하다고 느끼는 개발자들도 많을 것이라 생각한다.
 
 
OOP 언어라면 보통 Object 에 "." 을 찍으면 IDE 에서 자동으로 해당 Object 의 Class 및 현재 Code 의 Context 를 분석하여 사용 가능한 Method 및 Attribute 등을 위 화면처럼 Popup 으로 알려준다. 그리고 이렇게 추천된 목록에서 Enter 나 Tab 을 누르는것 만으로 오타 없는 정확한 Keyword, Method, Attribute Name 이 입력된다.
 
만약 이런 Code Assist 기능이 없이 Notepad 에서 수백개의 Class, 수천개의 Method 와 수만 라인의 코드를 개발해 나아가야 한다고 생각하면 정말 Hell 일 것이다.
 
아래는 Code Completion 기능의 예시 이다. 변수, 코드의 일부만 입력 하더라도 현재 Context 에서 입력 가능한 Attribute, Method 나 Keyword 등의 추천이 실시간으로 표시 되며 이 또한 Enter 나 Tab 을 누르는것 만으로 오타 없고 Context 에 맞는 오류 없는(물론 컴파일 오류이지 런타임 오류가 없다는건 아니다) 코드를 입력할 수 있다. 이 얼마나 생산적이고 개발자의 시간과 노력을 아껴주는 일인가!?
 
 
 
요즘 이러한 Code Assist 기능은 기본 기능만으로도 완벽하다고 느꼈었지만 여기에서 만족하지 못한 업체나 개인들이 IDE 의 Plugin 개발을 통해 특정 Framework 을 사용 시 더 생산성있게 코딩할 수 있도록 하거나 심지어 Variable 이나 Attribute, JPA Repository Method 의 Naming 을 자동으로 Assist 해주는 기능, Design Pattern 을 코딩에 쉽게 적용할 수 있는 플러그인 등을 개발하여 배포하고 있으며, 개발자는 점점 이러한 Code Asssist 기능에 의존해 가는 추세이다.
 
 

◼︎ AI Code Assist 가 나왔다!

이러한 Code Assist 기능들의 눈부신 발전에 '이제 더 나올만한 Assist 기능이 있을까?' 하고있던 중 또 지금으로서는 "끝판왕" 이라고 할만한 Assist 기능이 나왔다. 바로 AI Code Assist 이다.
 
기존의 Code Assist 기능이 현재 Code 의 Context 와 전체 프로젝트 내 소스코드 및 리소스의 Indexing 을 통해 사용 가능한 Method 나 Rule 기반의 Code Snippet 을 추천해 주었다면, AI Code Assist 기능(주로 IDE 의 Plugin 형태)은 이러한 보조 외에 현재 코드의 Context 를 이해하고 "앞으로 개발 될 것 같은 코드를 미리 예측" 하여 "코드 조각 또는 장문의 코드를 생성하여 추천" 해준다.
 
위 코드의 경우 나는 mongoTemplate 까지만 쳤는데 나머지 코드들은 AI Code Assist 기능 (Github Copilot) 이 알아서 추천해준 경우이다. Method 의 Name 이나 변수명, 내 프로젝트의 코드들의 패턴, Gihub 의 무수한 코드들을 학습한 AI 가 '응 너 지금 이런 코드를 만들려고 하는거지?' 하며 코드를 추천해주는 것이다. 그런데 이러한 코드는 정말 말도 안되게 내가 하려던 의도의 코드인 경우가 많다.
 
만약 내가 개발하려는 의도의 코드가 아니더라도 내가 생각한 코드를 만들어 가는 도중에 추천 코드는 계속 변경되고 다시 추천된다. 나도 결정하거나 생각하지 못한 부분의 코드까지도 미리 완성하여 실시간으로 추천해주는 기능을 겪어보면 "와.. 이제 개발자 필요없네" 라는 말이 절로 나온다.
 
이러한 코드 추천은 나의 프로젝트와 현재 Code 의 Context , Github 의 코드 학습을 통해서 자동 생성되는것 뿐만이 아니다. 아래 예시를 보자.
 
위 코드에서 나는 // 이후의 주석만 한줄 만들었다. 주석을 심지어 한글로 썼다. 그리고 Enter 를 치자 그 아래로 저런 코드가 만들어진다.
난 처음 이런 기능이 실행 되었을 때 '미쳤다..' 라는 말이 나왔다.
 
반대로 코드를 분석하여 주석을 (그것도 한글로!) 달아주는 기능도 된다
위 코드에서 나는 // account 까지만 입력했다. 그런데 그 뒤 문장인 "컬렉션의 변경사항을 감지하여 로그를 출력한다." 라는 주석을 알아서 생성해준다!
 
정말 감탄스러운 기능이다. 주석을 코드로 만들어주고 코드를 해석하여 주석을 만들어 주며, 내가 개발중인 코드의 의도를 파악하여 코드의 남은 부분을 완성해주는 AI Code Assist 는 정말 충격적이다.
 
 

◼︎ 얼마나 효과적일까?

 
위의 간단한 몇가지 예시 만으로도 그 효과는 굳이 말로 설명하지 않아도 알 수 있을것이라 생각한다. 코드 개발의 진행을 분석하여 의도를 추론하고 깔끔한 형태의 코드로 귀신 같이 내가 만들려고 하던 나머지 부분을 미리 작성하여 추천해주는 기능은 최소 0.5 명 이상의 도움을 나에게 주어 나의 개발 생산성을 높여준다.
 
주석을 미리 작성하고 그 주석에 맞는 코드를 개발해 나아간다면 직접 코딩하는 분량은 매우 적어지고 나머지는 AI 가 코딩 해주도록 가능하므로 요구사항과 설계에 맞는 코드를 작성하는데 도움을 주어 코드의 품질을 높일 수 있다.
 
작성된 코드를 해석하여 주석을 생성해주는 기능을 활용하면 저렴한 비용과 시간을 투자해 코드의 가독성과 유지보수성을 높일 수 있다.
 
이러한 효과 외에도 다양한 오픈소스를 학습한 AI 가 추천해주는 코드로 개발자의 기술 도메인이 약한 부분의 코드를 작성할 때 Learning Curve 를 상당히 단축시킬 수 있다.
 
믿을 수 없겠지만 위의 코드에서 내가 한 것이라고는 파일 이름이 고차함수_테스트.kt 라는 Kotlin 파일을 만들고 "Int 를 받아서 .." 정도 까지를 써주고 shifter 라는 변수를 선언하는 정도의 타이핑만 했을 뿐 나머지는 대부분 추천하는 Code Completion 을 "선택" 한 것 뿐이다.
 

◼︎ Github Copilot

현재 가장 많은 개발자들이 사용하는 AI Code Assist Plugin 은 Github Copilot 이다.
ChatGPT 가 올해 2월 경 부터 급격히 인기를 얻으면서 GPT-3 모델을 활용한 Code 와 주석 Generate 를 해주는 Copilot 이 더욱 인기를 얻고 있는것 같다.
 
이후 글 부터 틈나는대로 개발자를 위한 Copilot 기능 활용 예시와 기회가 된다면 다른 Plugin 들도 사용해가며 글을 이어나아가 보겠다.
또한 개발자를 위한 나른 AI Tool 들이 있다면 사용해보고 글을 올려볼 생각이다.
 
 
 
 
반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

두서 없이 말하는 사람, 일 처리가 매끄럽지 않은 사람, 같은 시간 공부를 해도 머릿속에 남는게 적은 사람, 집중력이 떨어져서 욕먹는 사람 들 대부분의 공통점 중 하나가 주변이 어수선 하다는 것이다.

정리를 하면 좋은것은 안다 단순히 기분이 상쾌해지기 때문일까? 그러한 긍정적인 효과도 있겠지만 더 중요한것들을 이 정리정돈 이라는 행동의 결과로 얻을 수 있다.

당장 내가 자주가는 온라인 서점 사이트에서 “정리” 라는 키워드로 “자기계발” 분야에서 검색되어 나오는 책의 권수만 해도 2023.07.10 기준으로 238 권이나 된다.

시중에 자기계발서에 이렇게 많은 “정리” 와 관련한 책들이 있는 이유가 무엇일까? 이유는 정리는 자기계발에 매우 큰 영향을 끼치며 정리를 하여 무엇인가를 얻기 위한 목적이 있기 때문이다. 단순히 상쾌함 만을 느끼기 위한 기분전환 효과나 정리 자체로 느낄 수 있는 성취감 이상의 것이 있다.

 

정리의 목적

정리라는 단어는 “주변 정리” Arrangement, “문서 정리”, “노트 정리” 등과 같은 Organization, “창고 정리” Clearance, “사업 정리” Liquidation, “채무 정리” Settlement 등과 같이 여러 의미로 쓰인다.

‘우리나라 말은 왜이리 단순해?’ 라고 느낄 수도 있으나 사실 다른 영어단어들 속에서도 공통점이 있다. 바로 “깨끗한 상태로 만든다” 라는 의미를 포함하고 있다는 것이다.

깨끗한 상태로 만드는것이 왜 중요할까? 깨끗한 상태로 만드는 것은 “효율성” 과 관계가 있다. 본질적이지 않은 것들을 치워 깨끗한 상태로 만들면 우리는 본질에 집중할 수 있기 때문이며, 이때 다른것에 에너지를 낭비하지 않기 때문에 같은 에너지로 정리되지 않은 속에 있는 사람들 보다 더 효율적으로 핵심 가치를 얻어낼 수 있기 때문이다.

공부하려고 할 때 주변이 정리되어 있으면 공부하는 것에만 집중할 수 있게 되어 효율적으로 공부가 가능하고, 문서정리가 잘 되어있으면 어떤 문서 내용을 찾으려 하거나 빠르게 내용의 핵심을 파악해야 할 때 관련 없는 문서나 주변 내용을 보느라 시간을 허비하지 않아도 된다.

노트정리 리뷰를 통해 핵심 내용을 중심으로 뇌에 강한 연상력을 불러일으켜 망각곡선을 늦추어 공부한 내용을 오랜 동안 기억할 수 있게도 할 수 있으며, 수익성이 낮은 사업정리를 통해 핵심 사업에 더 집중할 수 있도록 한다.

이렇게 정리라는 행동한정된 노력으로 최대한의 효과를 내기 위한 목적을 이루기 위한 과정의 수단이며, 집중하기 어려운 상황에서 주변을 깨끗이 정리하여 본질을 정확히 대면하기 위한 강력한 도구이다.

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

 Stable Diffusion 이 무엇인지는 대부분 알기 때문에 이 글을 보고 계신다고 생각하니, 일단 Stable Diffusion 에 대한 소개는 건너뛰고 가보겠습니다. 이 부분은 나중에 아주 자세히 글을 한번 올려보겠습니다.

 

Colab 은 무엇인가

 Google Colab은 구글이 제공하는 클라우드 기반의 무료 Jupyter Notebook 환경입니다. 주로 파이썬 라이브러리를 사용하여 데이터 분석 및 머신러닝 모델링 등 다양한 작업을 할 수 있습니다.

사용자가 자신의 브라우저에서 코드를 실행하고 실행 결과를 확인할 있으며 사용자는 Google Drive에 데이터를 업로드하고, 해당 데이터를 Colab에서 로드하여 분석에 활용할 수 있습니다. 또한, Colab은 GPU나 TPU와 같은 하드웨어 가속기를 제공하여, 대용량 데이터셋의 학습을 더 빠르게 처리할 수 있습니다.

또한 Colab 의 Notebook 은 마크다운과 코드 셀 등 다양한 셀 유형을 지원하며, 코드 셀에서는 파이썬 코드를 실행할 수 있고, 다양한 라이브러리와 모듈이 많이 설치되어있습니다.

중요한것은 이러한 환경이 무료로 제공되며, 구글 계정으로 로그인만 하면 바로 사용할 수 있습니다. 이래서 Google Colab 은 저처럼 가난한 GPU 서버 없는 사용자가 AI Model 을 테스트 하거나 하기에 Google신이 내려준 축복같은 선물이라고 보면 되겠습니다.

 

어떻게 Colab 에 설치해야 하나

 네 Colab 에 "설치" 한다는 개념은 사실 딱 맞는 개념은 아니고요, Colab 에 Jupyter 노트북을 만들어서 그 노트북에서 Shell Script 및 Python Script를 실행시켜 필요한 File 들을 VM 에 설치하게 하고 (VM 은 Command Shell 로 접근이 안됩니다) Python 으로 개발된 Web UI 가 실행되어 Browser 로 Web UI 서버를 접근하게 하는 형태입니다.

 일단은 아래 URL 로 접근해봅니다.

https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Online-Services

Web UI 를 개발한 AUTOMATIC1111 이라는 개발자의 Github 내의 Wiki 인데, 여기에 보면 Google Colab, Paperspace, SageMaker 용 Jupyter 노트북용 스크립트들의 Link 가 있습니다

이 중 밑줄의 camenduru 라는 사람의 노트북을 써보기로 하겠습니다. camenduru 의 Github README 아랫쪽으로 스크롤 하다보면 아래와 같은 Link 들이 있습니다.

여러 Model 들이 preset 된 Jupyter script 들이 있는데요,

이중 저걸 설치해보겠습니다. 

링크를 클릭하면 CIVITAI (AI 생성 모델 과 모델로 부터 생성한 이미지들을 공유하는 사이트) 나 Huggin Face 커뮤니티 사이트(딥러닝 모델 및 데이터셋 공유 커뮤니티)로 연결 되니 대략 어떤 모델인지를 확인해볼 수 있습니다.

대략 확인했으면, 파란색 Link 가 아닌 좌측의 "stable" 이라고 되어있는 이미지 버튼을 누릅니다.

그러면, 실제 Colab 용 Jupyter 노트북으로 이동합니다. 저 노트북을 공유한 사람의 노트북인것이죠.

그리고 저 박스 안의 "Drive로 복사" 버튼을 눌러 나의 Google Drive 로 복사를 해줍니다. 

그러면 이제 복사가 완료되었을 것이고 바로 나의 Colab 으로 오게 됩니다.

 

이제 이 노트북을 실행시킬 VM 을 연결해주는 작업을 합니다. 아래 처럼 화면 우측 상단의 "연결" 을 눌러봅니다.

아래 처럼 할당된 리소스가 나오거나, 만약 연결한적이 없다면 런타임 유형을 선택하라고 나오는데 여기에서 "GPU" 를 선택하시면 됩니다.

만약 런타임 유형 선택 화면이 안나오면, 화면 하단의 "런타임 유형 변경" 을 누르시면 됩니다.

이제 Script 의 좌측 Play 버튼을 눌러서 실행시키면 됩니다

 

설치 후 첫 실행

 좀전에 실행시킨 스크립트창 하단에 보면 아래와 같은데 보일겁니다.

저 링크들이 Colab 에서 실행된 Web UI 서버로 접근할 수 있는 URL 입니다. 이중 클릭 해서 접속 되는 URL 로 들어가보시면 됩니다

접속이 잘 되었다면, 

prompt 란에 대략 내가 생성하고 싶은 이미지의 키워드들을 떠올려 넣어보시고, 필요하다면 바로 아래의 Nagative Prompt 에도 포함되면 안되는 요소의 키워드들을 넣어봅니다. 

그리고 저 빨간색 Generate 버튼을 누르면 시간이 흘러 image 가 생성 되고,  

하단의 Save 버튼을 누르면, 파일 이름이 그 밑의 목록에 추가 되고 "Download" 버튼을 통해 해당 이미지를 다운로드 받을 수 있습니다.

만약 Batch 로 생성(다음에 더 설명 예정입니다)하거나 하여 여러 이미지가 나왔다면 "Zip" 을 선택하여 모든 이미지들을 Zip 으로 묶어 다운로드 받을 수도 있습니다.

 

결론

 집에 사양 좋은 Windows Notebook 이 있어서 (NVIDIA 칩 GPU 있는) Local 에서 설치해서 사용하려 했으나 역시나 요구사양대로 4GB 이상의 VRAM 이 아닌 1GB 의 VRAM 노트북이라 실행이 불가했기에 Colab 에서 설치하고 실행하는 방법만 우선 올려봅니다.

 앞으로 여러 모델을 활용하고 다양한 파라미터들을 조작해서 내가 원하는 이미지들에 최대한 근접한 이미지를 만들어가는 방법도 올려보겠습니다. 

 또 다른 기술들과 접목을 하거나 유튜버들이 이야기하는 돈벌기 부업이 정말 되는지도 검증해보고, 다른 Generative AI 서비스나 도구들도 사용해보면서 다양한 컨텐츠를 만들어볼까 생각합니다. 응원 플리즈~

... 

그나저나 camenduru 의 README 를 보다보니 좀 암울한 얘기가 있네요.. 조만간 Stable Diffusion Web UI 사용이 Colab 에서 불가능할수도 있겠네요. Colab 팀이 Stable Diffusion Web UI 를 사람들이 너무 많이 돌려서 GPU 가 터질것 같은데 팀에 예산이 없어.. 조만간 뭔가 조치가 취해질 수 있다는 얘기네요.. 

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

Colab 으로 띄우는게 너무 시간도 오래 걸리고 이것저것 만져보고싶은 생각에 Windows PC 에 설치를 하려 했으나 실패했다.

설치는 매우 간단하지만, 설치 후 SD(Stable Diffusion) 실행 시 VRAM 에 Model 을 올리는것 같은데 VRAM 이 1GB 인 내 노트북이 역시나 실행 최소환경 요건에 맞지 않았다.ㅠㅠ

OutOfMemoryError.. 이럴수가.. OTL

어쩔 수 없이 Colab 으로 가야하는가보다

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

 Spring Security 에 OAuth 2 모듈이 있는걸 알고 있지만 OAuth 로 SSO 서버를 구현해보지는 않았기에 chatGPT 에게 물어봤다


Q > Springboot 의 OAuth 를 활용해 SSO 구현 가능하니?

A > ChatGPT 는 당근 가능하다고 하며 TMI 로 아래처럼 얘기를 붙여준다

 

OAuth 정의 

OAuth는 사용자 자격 증명을 공개하지 않고 보호된 서버에서 사용자 자원에 대한 제3자 응용 프로그램의 액세스를 허용하는 인증 프레임 워크입니다. 최신 웹 애플리케이션 및 API에서 인증 및 권한 부여에 자주 사용됩니다.

Spring Boot는 웹 애플리케이션 및 API를 구축하기위한 인기있는 Java 기반 프레임 워크로서 OAuth를 지원하기 위한 다양한 도구 및 라이브러리를 제공합니다.

Spring Boot를 사용하여 OAuth를 이용한 SSO를 구현하려면 Spring Security 프레임 워크를 사용할 수 있습니다. Spring Security는 OAuth 인증 및 권한 부여를 지원하는 내장 기능을 제공합니다. Spring Security를 구성하여 Google이나 Facebook과 같은 OAuth 공급자를 신원 공급자로 사용하도록 설정할 수 있습니다.

다음은 Spring Boot를 사용하여 OAuth를 이용한 SSO를 구현하는 일반적인 단계입니다.

  1. 새로운 Spring Boot 애플리케이션을 만들거나 기존 애플리케이션을 수정하여 Spring Security를 사용합니다.
  2. Google이나 Facebook과 같은 OAuth 공급자를 선택하고 클라이언트 ID 및 클라이언트 비밀번호를 얻기 위해 공급자에 애플리케이션을 등록합니다.
  3. Spring Security를 구성하여 OAuth 공급자를 신원 공급자로 사용하도록 설정합니다.
  4. OAuth 인증 흐름을 처리하는 필요한 컨트롤러 엔드 포인트 및 사용자 인터페이스를 구현합니다.
  5. 사용자가 인증되면 세션 또는 토큰에 사용자 자격 증명을 저장하여 여러 애플리케이션에서 SSO를 활성화합니다.

Spring Boot를 사용하여 OAuth를 이용한 SSO를 구현하는 방법에 대한 자습서, 가이드 및 샘플 코드를 포함한 많은 온라인 자료가 있습니다. Spring Security 문서는 OAuth 인증 및 권한 부여를 구성하는 방법에 대한 자세한 정보를 제공하는 좋은 출발점입니다.


추가질문

이번에도 나의 질문이 조금 부족했음을 느낀다 나는 SSO Server 를 구현하는 방법을 물어보고 싶었는데, SSO 구현방법을 물어봤다.

다시 수정해서 물어보고 Springboot 기반의 Sample Code 도 달라고 요청했다

 

Q >  역시나 친절하게도 아래처럼 대답해준다 

 

First, you would need to add the necessary dependencies to your pom.xml file:

<dependencies>
    <!-- Spring Security OAuth2 dependencies -->
    <dependency>
        <groupId>org.springframework.security.oauth</groupId>
        <artifactId>spring-security-oauth2</artifactId>
        <version>2.4.0</version>
    </dependency>
    
    <!-- Spring Boot dependencies -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.6.2</version>
    </dependency>
</dependencies>

Next, you would need to configure the OAuth2 server in your Spring Boot application. Here is an example configuration class:

@Configuration
@EnableAuthorizationServer
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
 
    @Autowired
    private AuthenticationManager authenticationManager;
 
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("client1")
            .secret("secret1")
            .authorizedGrantTypes("authorization_code")
            .scopes("read")
            .redirectUris("http://localhost:8081/login/oauth2/code/client1")
            .and()
            .withClient("client2")
            .secret("secret2")
            .authorizedGrantTypes("authorization_code")
            .scopes("read")
            .redirectUris("http://localhost:8082/login/oauth2/code/client2");
    }
 
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }
 
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.checkTokenAccess("isAuthenticated()");
    }
}

In this example configuration class, we are configuring two clients ("client1" and "client2") with different credentials and redirect URIs. We are also specifying that the clients are authorized to use the "authorization_code" grant type with the "read" scope. Finally, we are specifying that the AuthenticationManager should be used to authenticate clients and users.

You would also need to configure your Spring Boot application to use Spring Security for authentication. Here is an example WebSecurityConfigurerAdapter:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/oauth/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .httpBasic()
            .and()
            .csrf().disable();
    }
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user1")
            .password("{noop}password1")
            .roles("USER")
            .and()
            .withUser("user2")
            .password("{noop}password2")
            .roles("USER");
    }
 
    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
 
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

In this example WebSecurityConfigurerAdapter, we are configuring Spring Security to permit all requests to the "/oauth" endpoint and to require authentication for all other requests. We are also configuring an in-memory UserDetailsService with two users and their passwords,

 

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

오늘 열심히 새로운 프로젝트를 위한 분석설계 작업을 하던 중 옆 동료들과 잠시 머리도 식힐겸 이야기를 하다가 연동 시스템에서 HTTP 요청 시 Spring Boot 기반의 Multi Instance 서버들이 해당 요청을 Broadcast 받은 것 처럼 각 Instance 의 State 들을 업데이트 해야 하는 요건이 생겨 논의하고 있다는걸 알게 되었다.

머리 식히러 왔어서 자리를 피하고 싶었으나.. 최소한의 Effort 로 구현하고 싶고, Message Broker 나 Redis 같은 IMDB, Zookeper 등을 사용하지 않았으면 좋겠다 하고, NoSQL DB 로 MongoDB 를 사용하고 있으나 DB Polling 으로 인해 부하를 주고싶지 않다고 하고..

잠시 생각하던 중 MongoDB 에서 Collection 의 변경이 일어나면 이 이벤트를 Listen 할 수 있는 기능이 생각나서 해당 기능을 사용해서 구현해보는게 어떤가 이야기 했다.

말이 나온김에 ChatGPT 를 통해 Sample Code 를 만들어 보라 시켜봤다.

GPT write a pub sub example springboot java code using mongodb


ChatGPT 놈의 조언

Here is an example of a basic implementation of the publish-subscribe pattern in a Spring Boot application using MongoDB as the message broker:

@Service
public class PublisherService {
    private final MongoTemplate mongoTemplate;

    @Autowired
    public PublisherService(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    public void publishMessage(String message) {
        mongoTemplate.save(new Message(message));
    }
}

@Document
class Message {
    private String message;

    public Message(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

@Service
public class SubscriberService {
    private final MongoTemplate mongoTemplate;

    @Autowired
    public SubscriberService(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    @PostConstruct
    public void subscribe() {
        mongoTemplate.getDb().getCollection("message").watch().forEach((Consumer<ChangeStreamDocument<Document>>) changeStreamDocument -> {
            Message message = mongoTemplate.getConverter().read(Message.class, changeStreamDocument.getFullDocument());
            System.out.println("Received message: " + message.getMessage());
        });
    }
}

이녀석 초반에는 무늬만 pub sub 같은 코드를 내놓더니만 몇번 심도있는(?) 대화를 해주고 난 이후에는 Collection 의 watch() 로 ChangeStreamDocument 를 사용해 Event 를 Listen 하는 제대로 되어보이는 코드를 내어준다. 한번 테스트 해보자.

 

테스트 코드

package mongo.account;

import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Getter
@Setter
@Document(collection = "account")
public class Account {
    @Id
    private String id;
    private String userName;
    private String email;
}
@Repository
public interface AccountRepository extends MongoRepository<Account, String> {
    Account findAccountByUserName(String userName);
    List<Account> findAccountsByUserName(String userName);

    @Query(value = "distinct('userName')", fields = "userName")
    List<String> findDistinct();
}
@Service
@RequiredArgsConstructor
@Slf4j
public class AccountSubscriber {
    private final MongoTemplate mongoTemplate;

    @PostConstruct
    public void subscribe() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                log.info("Registering Subscriber");
                mongoTemplate.getDb().getCollection("account").watch()
                        .forEach((Consumer<ChangeStreamDocument<Document>>) changeStreamDocument -> {
                            Account account = mongoTemplate.getConverter().read(Account.class, changeStreamDocument.getFullDocument());
                            log.info("[{}] userName : {}", changeStreamDocument.getOperationType(), account!=null?account.getUserName():null);
                        });
                log.info("Subscriber Registered");
            }
        });
        t.start();
    }
}
@Bean
    @Order(1)
    public ApplicationRunner applicationRunner() {
        return args -> {
            Account account = new Account();
            account.setUserName("joon");
            account.setEmail("abcdef@naver.com");

            accountRepository.insert(account);
            log.info("Done");

            List<Account> result = accountRepository.findAccountsByUserName("joon");
            log.info("result 1 : {}", result.size());


            // .... 생략 ...

            accountRepository.deleteAll();

        };
    }

 

실행결과

 

오늘도 chatGPT 가 나름 참고할만한 코드를 잘 만들어주었다. 

물론 그대로 갖다 붙여넣는다고 원하는 동작을 하지는 못한다 (뭐 이러면 개발자 죽어야지..). watch() 에서 blocking 되기땜에 thread 로 빼주는 코드를 추가해주는 센스까지는 아직 chatGPT 가 못내주기는 하다마는 그래도 이게 어디냐..

구글링 해서 찾을수도 있지만 chatGPT 를 썼을 때에는 좀더 "덜 읽어도" 된다는게 좋은것 같다

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
요즘 ChatGPT 와 시간내서 노는게 참 재미있다. 이제야 SF 영화에서 보던 AI 라고 할 수 있을만한게 나온것 같다는 생각이 든다.

 작년부터 회사에서 AICC 솔루션 얘기가 나오고 있었다. SWA 시절 부터 Aka*** 회사에서의 Solutions Architect 시절 등 나야 솔루션을 만들거나 거대한 솔루션을 각종 업무 도메인과 각색의 아키텍쳐를 갖는 시스템들과 연계하던 경험이 있으나 현재 소속해있는 우리 팀은 사실 솔루션에 대한 경험이 있는 사람이 적고 그나마 이번 프로젝트에 involve 된 사람은 전무한 상황이다.

 나도 서비스 개발을 지속하다 보니 예전 솔루션 개발 방법론까지 Tailoring 해가며 개발해왔던 경험도 기억이 가물한 상황에서 술한잔 먹고 chatGPT 와 대화를 해봤다.

 우리회사에 AI 기술은 있으나, 이걸 AICC 솔루션으로 만들기 위해 우리에게 필요한게 뭐가 있을까?  기특한 GPT 가 답을 해준다.


If you and your team have experience with AI technologies but have not built an AI-powered contact center solution before, there are a few things you may need to consider:

  1. Domain expertise: Having a deep understanding of the domain of contact center operations will be important to ensure that your solution addresses the specific needs of your customers and meets the requirements of your business.
  2. Business understanding: A good understanding of the business side of contact center operations will be important to ensure that your solution is cost-effective, scalable, and able to integrate with existing systems and processes.
  3. Project management skills: Building an AI-powered contact center solution will likely be a complex and time-consuming project, so it will be important to have project management skills and experience to ensure that the project stays on track and meets its deadlines.
  4. Data expertise: Having experience working with large datasets and data science tools will be important for collecting, cleaning, and preparing data for training your models.
  5. Software development skills: Experience in software development will be important for designing and implementing the system, including the integration with existing systems, and creating an API to access the AI models.
  6. Support and maintenance: Building a robust and maintainable system is important, and that means having the capacity to support and maintain the system after it's deployed, this includes monitoring and fine-tuning the system to improve its performance and adapt it to new requirements.
  7. Legal and ethical considerations: As mentioned before, AI-based contact center solutions may raise legal and ethical concerns, such as data privacy and bias. It's important to consider these issues and take appropriate measures to mitigate them.
  8. User experience design: having a good understanding of user experience design will be important to make sure that the system is easy to use and understand, this will help to improve customer satisfaction.

Building an AI-powered contact center solution is not an easy task and will require a combination of skills and expertise from different areas. Depending on the specific needs of your solution, you may need to bring in additional experts or resources to help with the development.


이쁜녀석.. 이렇게 체계적으로 말을 잘 만들어서 대답을 해주니 얼마나 좋은가? 내가 CEO 이고 의사결정자라면 이녀석 참 쓸데가 많을것 같다.

1. 도메인 전문지식

솔루션이 고객의 특정 요구 사항을 해결하고 비즈니스 요구 사항을 충족하는지 확인하려면 컨택 센터 운영 도메인을 깊이 이해하는 것이 중요합니다.

2. 비즈니스 이해

솔루션이 비용 효율적이고 확장 가능하며 기존 시스템 및 프로세스와 통합될 수 있도록 하려면 컨택 센터 운영의 비즈니스 측면을 잘 이해하는 것이 중요합니다.

3. 프로젝트 관리 스킬

AI 기반 컨택 센터 솔루션을 구축하는 것은 복잡하고 시간이 많이 소요되는 프로젝트일 가능성이 높으므로 프로젝트가 순조롭게 진행되고 기한을 맞추도록 프로젝트 관리 기술과 경험을 갖추는 것이 중요합니다.

4. 데이터 전문성

대규모 데이터 세트 및 데이터 과학 도구로 작업한 경험이 있으면 모델 교육을 위해 데이터를 수집, 정리 및 준비하는 데 중요합니다.

5. Software 개발 스킬

소프트웨어 개발 경험은 기존 시스템과의 통합을 포함하여 시스템을 설계 및 구현하고 AI 모델에 액세스하기 위한 API를 만드는 데 중요합니다.

6. 지원과 유지보수

강력하고 유지 관리 가능한 시스템을 구축하는 것이 중요합니다. 즉, 배포 후 시스템을 지원하고 유지 관리할 수 있는 능력을 갖추는 것입니다. 여기에는 성능을 개선하고 새로운 요구 사항에 맞게 조정하기 위한 시스템 모니터링 및 미세 조정이 포함됩니다.

7. 법과 윤리 고려

앞서 언급한 바와 같이 AI 기반 컨택 센터 솔루션은 데이터 프라이버시 및 편견과 같은 법적 및 윤리적 문제를 제기할 수 있습니다. 이러한 문제를 고려하고 이를 완화하기 위한 적절한 조치를 취하는 것이 중요합니다.

8. UX 디자인

사용자 경험 디자인을 잘 이해하는 것은 시스템이 사용하기 쉽고 이해하기 쉬운지 확인하는 데 중요하며 이는 고객 만족도를 향상시키는 데 도움이 됩니다.

AI 기반 컨택 센터 솔루션을 구축하는 것은 쉬운 일이 아니며 다양한 분야의 기술과 전문 지식의 조합이 필요합니다. 솔루션의 특정 요구 사항에 따라 개발을 돕기 위해 추가 전문가 또는 리소스를 가져와야 할 수 있습니다.


딱 보면 일을 시작하기 전에 어떤 측면의 중요성을 상기하고 있어야 하는지 잘 짚어주었다. 물론 일반론적 이야기이긴 하겠지만 개발하기 전 설계나 솔루션 개발 및 이행 단계에서 고려해야 할 요소들을 정확히 짚어주지 않았나 싶다.

앞으로 OpenAI 의 GPT 가 상당히 기대된다!

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
Edit

Multisig Wallet #2

220.Blockchain 이더리움 Ethereum 티스토리 multisigwallet ethereum

볼만한 Multisig Wallet 코드는 Consensys Gnosis 가 있다.

Consensys 의 Multisig Wallet 은 아직도 상당히 많은 양의 ETH 를 Holding 하며 잘 쓰이고 있고, 핵심인 Contract Code 만 올라가 있는 상태이다. Contract Code 는 업데이트 되지는 않고 있다.

Gnosis 의 코드같은 경우, Angular.js 기반의 Front-End 까지 Push 되어 있으며, Contract 또한 잘 구조화 하였고 Truffle 로 Test 와 Migration 이 가능하도록 Truffle Project 로 만들어 놓았다. 아직도 간간히 dApp 부분은 업데이트 되고 있다.

이번 글에서는 Consensys 의 MultisigWallet 코드를 봐보도록 하겠다. Gnosis 의 것이 잘 되어있기는 하지만, dApp 의 UI 쪽 코드가 대부분이며 핵심을 보기에는 오히려 그 외 적인 코드들이 많다.

Test 환경

이제는 dApp 개발하시는 분들이면 다들 쓰고 있을 TruffleGanache-CLI 를 사용하도록 한다.
Truffle 의 develop 커맨드를 사용해도 되겠지만 옵션 지정에 한계가 있는 관계로 보통은 Ganache-CLI 를 사용한다.

IDE 는 IntelliJ 에 Solidity 플러그인Solhint 를 사용하고 있지만, Solhint 의 Lint 기능이 Remix-IDE 보다 떨어지고 특히 내가 사용중인 IntelliJ 버전의 solhint 플러그인은 .solhint.json 이 제대로 안먹는 관계로 편집은 Remix 로 한다. 필요한 경우 Terminal 에서 solhint 를 직접 쳐서 Linting 을 해주는 상황이다.

Test 는 UI 가 필요한 상황이 아니라면, 대부분 Truffle Test 를 사용하도록 한다. Mocha + Chai 를 사용하여 테스트 코드를 만드는게 좀더 체계적이고 많은 테스트를 자동화 해줄 수 있기 때문에 사용한다.

요즘은 개발환경 구성과 관련한 글들은 여기저기서 많이 찾을 수 있으니 설치나 구성 방법은 생략 한다.

주요 Contract 코드

Consensys 의 MultisigWallet 은 딱 하나의 Contract 인 MultisigWalletWithDailyLimit.sol 이 들어있다. 이 Contract 를 이해 하면 시간내어 Gnosis 의 MultisigWallet 같은 녀석도 만들어갈 수 있다

Contract 는 간단히 2개로 구성된다. modifier 몇개와 이름만 봐도 어떤기능을 할지 짐작이 가는 녀석들이 있다. 중요 modifier 는 onlyWallet, confirmed, validRequirement 정도가 볼만 하며, Function 으로는 addOwner, submitTransaction, confirmTransaction, executeTransaction 정도라고 할 수 있겠다

아래 Contract 는 solc 0.4.10 에서 Compile 된다. pragma definition 만 바꾸면 0.4.13 까지는 큰 오류 없이 compile 된다. constant, throw, constructor 등등.. 그간의 변화가 반영되지 않은 코드이지만 원리 이해에는 별 무리가 없어서 그냥 사용한다

solc 는 지난달 공식 Release 된 0.5.0 에 와서 많은 변화들이 생겼다. 나중에 직접 코딩하는 경우에는 0.5 버전대를 기준으로 올리도록 하겠다. (하아.. 수없이 바뀌어가는 Solidity 도 이제 힘들다. Vyper 로 넘어가야 하나..ㅋ)

주요 Modifier

onlyWallet

modifier onlyWallet() {
if (msg.sender != address(this))
throw;
_;
}

위 Modifier 는 msg.sender 가 현재 Contract 가 아니면 throw 로 튕기라는 내용이다. 이게 왜 필요할까 싶을 수 있다.

onlyWallet modifier 를 사용하는 Function 은 addOwner, removeOwner, replaceOwner, changeRequirement,changeDailiyLimit 이다. 이 Function 들은 Wallet 고유의 기능(설정)을 변경하는 기능을 수행한다는 것이다. 즉 Wallet 이 다른 Address 로 Transaction 을 Submit 하지 않으며 Wallet 내부에서 모든 기능이 끝난다.

이러한 함수는 EOA 에서 Wallet Contract 로 Message Transaction 을 Submit 할 때, Data 파트에 to 에 해당하는 parameter(여기서는 submitTransaction 의 destination) 를 본 MultiSigWallet 의 Contract 로 하고, 함수의 Signature 를 위 5개 중의 하나의 함수로 하며 함수의 파라미터에 맞는 값을 넣어 submitTransaction 혹은 executeTransaction 으로 Submit 해주어야 한다.
(아래 나올 submitTransaction, executeTransaction 을 보면 이해가 갈 것이다)

이때, 위 5개 함수는 MultiSigWallet 이 .call() 로 자신이 Sender 가 되어 호출하게 된다. 그래서 이런 류의 호출만을 Accept 하기 위해 onlyWallet() modifier 를 만들어서 쓴다.

사실 이번 Blog 를 쓰는 주된 이유가 .call() / .delegatecall() / staticcall() 과 관련된 설명을 이후에 하기 위함이니 이어질 설명과 테스트를 통해 잘 이해 해두도록 하자

추가로, throw 는 deprecate 된지 오래이며, revert() 와 동일하게 취급된다. 즉, gas 는 throw 이전 까지 실행된 만큼만 소모된다

confirmed

mapping (uint => mapping (address => bool)) public confirmations;
modifier confirmed(uint transactionId, address owner) {
if (!confirmations[transactionId][owner])
throw;
_;
}

confirmed modifier 는 함수 중 revokeConfirmation() 에서만 사용된다. confirmations mapping 을 보면, uint => address => bool 로 되어있는것을 볼 수 있으며, transactionId => owner => true/false 형태로, submit 된 transactionId 에 revokeConfirmation() 을 실행한 ownerconfirm을 했는지 가 기록되어있는지를 확인해주고, 아니라면 throw 로 튕겨내는 기능을 한다.

validRequirement

uint public required;
modifier validRequirement(uint ownerCount, uint _required) {
if ( ownerCount > MAX_OWNER_COUNT
|| _required > ownerCount
|| _required == 0
|| ownerCount == 0)
throw;
_;
}

required 는 MultiSigWallet 의 constructor 에서 지정하도록 되어있으며, 전체 owner 의 수보다는 작아야 하며 owner 가 0 보다 커야 valid 하다는 조건을 가지도록 modifier 로 filtering 한다.

required 는 changeRequirement() 를 통해 변경될 수 있으며, changeRequirement() 함수는 onlyWallet modifier 에 의해 실행될 수 있다. 그 얘기는, changeRequirement() 를 실행시키기 위한 Transaction 을 Wallet 으로 submit 해야 하며, 이에 대해 이전에 설정된 required 만큼의 owner 가 confirm 을 해야 이 또한 실행될 수 있음을 의미한다

주요 Functions

addOwner

function addOwner(address owner)
public
onlyWallet
ownerDoesNotExist(owner)
notNull(owner)
validRequirement(owners.length + 1, required)
{
isOwner[owner] = true;
owners.push(owner);
OwnerAddition(owner);
}

confirm 할 자격이 있는 owner 를 추가하는 함수이다. 이 함수 또한 onlyWallet modifier 가 있어, 이 함수를 실행하기 위한 Transaction 이 Submit 되어 있어야 하고, Wallet 이 내부적으로 이 함수를 .call() 로 호출 하여야 한다. 결국, required 만큼의 confirm 이 있어야 owner 가 추가될 수 있다.

submitTransaction

function submitTransaction(address destination, uint value, bytes data)
public
returns (uint transactionId)
{
transactionId = addTransaction(destination, value, data);
confirmTransaction(transactionId);
}

실행시키고자 하는 Transaction 을 submit 하기 위해 호출하는 함수이다. Transaction 의 to 주소를 destination 으로, 이체 되어야 하는 ETH 의 양을 value 에 넣어준다. 그리고 to 주소가 Contract 라면 호출할 Contract 의 Call Code Data 를 data parameter 에 넣어준다. (이부분은 테스트 코드에서 설명 예정이다)

addTransaction() 은 internal 함수로, transactions mapping (transactionId => Transaction)에 Transaction 구조체의 Instance 를 만들어, 단순한 transaction count 를 ID 로 하는 transactionId 를 key 로 하여 저장 해준다.

마지막으로, confirmTransaction() 함수를 통해 submitTransaction 을 호출한 owner 의 confirm 을 자동 실행하게 한다.

confirmTransaction

function confirmTransaction(uint transactionId)
public
ownerExists(msg.sender)
transactionExists(transactionId)
notConfirmed(transactionId, msg.sender)
{
confirmations[transactionId][msg.sender] = true;
Confirmation(msg.sender, transactionId);
executeTransaction(transactionId);
}

confirmTransaction 은 등록된 특정 transactionId 에 대해 owner 가 confirm 을 하기 위한 함수이다. 내용은 위에서 설명한 confirmations (transactionId => owner => true/false 관계를 갖는 mapping) 에 msg.sender (confirmTransaction 을 실행 한 sender) 가 owner 인 경우, 해당 owner 가 confirm 했다고 true 로 바꾸어 주고, Event 를 emit 하는것이다.

마지막으로, 다음에 설명할 executeTransaction() 을 통해, confirm 의 수가 required 보다 같거나 많으면 실제 Transaction 을 실행하게 한다.

executeTransaction

사실 이번 글을 쓰는 주된 목적중의 하나가 아래 코드, 그중 .call() 함수 이다.
call delegatecall staticcall 을 사용하면 Contract 가 ABI 를 모르는 다른 Contract 의 Method 를 호출하도록 하는 Internal Transaction 을 만들어 실행시킬 수 있다. 예전에는 callcode 도 있었으나 0.4.25 버전을 끝으로 사라졌고 staticcall 이 새로 생겨났다.

function executeTransaction(uint transactionId)
public
notExecuted(transactionId)
{
if (isConfirmed(transactionId)) {
Transaction tx = transactions[transactionId];
tx.executed = true;
if (tx.destination.call.value(tx.value)(tx.data))
Execution(transactionId);
else {
ExecutionFailure(transactionId);
tx.executed = false;
}
}
}

isConfirmed() 로 transactionId 에 해당하는 transaction 이 required 이상의 confirm 을 받은 경우, transactions 안에 저장해둔 Transaction 을 실행한다.

실제 transaction 을 실행하는 코드는 아래 부분이다

if (tx.destination.call.value(tx.value)(tx.data))

tx.destination 에는 submitTransaction() 을 호출할 때 넘겨준 destination 즉, transaction 의 to Address 가 들어있다. 이 to Address 에 .call() Low-Level 함수를 호출 해주면 argument 로 넘겨진 Code 를 Internal Transaction 으로 하여 대상 Smart Contract Account 의 Code 를 호출할 수 있게 된다.

주로 호출되는 함수들은 아래와 같은 Sequence 로 동작한다고 보면 된다.

  1. Sender 1 이 MultisigWallet Contract 의 submitTransacton() 을 호출하게 되는데, 이때 parameter 로 “0xCD01…” 주소의 destination 을 주고, 이체할 Ether (MultiSigWallet Contract 내에 자신이 Deposit 한 금액 중 일부)를 적어줄 수 있으며, 마지막으로, destination account (Smart Contract Account) 에서 실행되어야 하는 data 파트 (Function Hash + parameter 들) 을 넣어주는 것이다

  2. MultisigWallet 의 submitTransaction() 은 내부적으로 addTransaction() 을 통해 parameter 를 통해 받은 최종 Transaction 정보를 저장하고 있는다

  3. msg.sender 의 confirm 을 추가해주고

  4. Transation Receipt 의 Log 를 통해 Confirmation Event 를 Logging 해줄 것이다 (transactionId=1, 사실은 Submission Event 를 통해 Confirmation 전에 transactionId 가 Loggiing 된다)

  5. Sender 2 가 1번 Transaction 에 대해 Confirm 을 하고

  6. 이 또한 Confirmation Event 로 날아간다

  7. required 가 2 이라면, executeTransaction() 이 실행 된다

  8. 저장되어있던 Transaction Destination (“0xCD01…”) 으로 100 wei 만큼을 value 로 transfer 하면서 “0xD01A8D…” 의 data 부분을 “0xCD01…” Contract 에서 실행시키게 된다


다음편에는 Test Script 를 통해 실행 하고 마치는걸로~


반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
Edit

Amazon Managed Blockchain

220.Blockchain 블로그 이더리움 ethereum aws qldb 티스토리

11/28일, AWS 에서 AWS Blockchain Template 에 이어 Amazon Managed Blockchain 서비스와 QLDB 를 소개하였다. 지금 시점에는 Preview 상태인데 이마저도 Sign Up 을 해야 하기는 하다.

일단 Preview Signup 을 하고나면 시간이 좀 지났더니 아래 처럼 메일이 온다

위 메일이 왔다고 해서 Preview Applicant 가 되었다는게 아니다. 기다려야 한다..
Apply 를 했지만 이틀 째 아직 회신이 오거나 하지 않는다 그냥 계속 기다려야 한다.

혹시나 사용 가능해지면 써보고 바로 다시 글을 올려보겠다

어디에 있나

AWS Console 에 들어가면 아래 처럼 Amazon Managed Blockchain 이 있는걸 볼 수 있다

마치 될 것 같은 느낌이지만 클릭하면 다시 Preview sign up 페이지로 넘어간다

현재 AMB Preview 가 지원되는 Region 은 US East (Virginia) 뿐이다
현 시점에 QLDB 메뉴는 어디에 있는지 발견하지 못하였다

Amazon Managed Blockchain

아직은 들어가보지도 못하고 자료도 거의 전무한 상태이므로, AWS 상의 서비스 소개 페이지를 참고하여 어떤것인가 정리해놓겠다

전체 구성

AMB 는 독립된 Member 별로 Peer Node 를 구성하게 하고, Ordering Service 와 Client 를 Fabric Network 으로 연결해주기 위한 VPC Endpoint Service 등은 공용할 수 있는 컴포넌트 형태로 제공하는 것으로 보인다.

아래 가격표를 보아도 알겠지만, Ordering Service 를 위한 별도의 Node 는 구매하지 않는다. 이부분은 AWS 에서 제공하는 것으로 보이며, 대신 Membership 금액을 시간당으로 받는 것으로 생각된다

Benefits (&Features)

Fully Managed

  • 여러 AWS 계정에 걸쳐 Blockchain Network 을 쉽게 생성
  • 멤버 그룹과 Account 의 Transaction 실행, 데이터 공유를 설정
  • Infra 와 S/W 설치 등이 필요 없다
  • 모니터링 기능 제공한다
  • 멤버 추가와 삭제를 위한 투표 기능 API를 제공한다

Fabric 과 Ethereum 중 선택

  • Privacy 와 Permission 중요한 곳에 Fabric 추천
  • Transparency 와 분산화 중요한 곳에 Ethereum 추천
  • Ethereum 은 Public / Private Network 지원할 것으로 보임

Scalable and Secure

  • Peer node 추가를 위한 API 를 제공
  • 원하는 H/W spec 을 조합
  • AWS KMS(Key Management System)를 통한 Key 관리로 안전

Easily analyze Blockchain Activity (향후 예정)

  • Blockchain network 활동을 QLDB 에 저장할 수 있음
  • 변경되거나 삭제될 수 없는 형태로 영구히 남게됨
  • 누가 Transaction 을 발생하였는지, Transaction Rate 이 어떻게 되는지 등 Query 가능

Reliability

  • Ordering service 에 QLDB 를 접목, Transaction 의 Full History 를 조회 가능하도록 함

가격

N. Virginia Region 에 대한 가격만 나와있는 상황으로, 아래와 같이 가격표가 나온다

Membership

  • Starter Edition : $0.30/h (337원/시간)
    • 네트워크 상 최대 5개 멤버
    • 멤버 당 최대 2개 Peer Node
    • bc.t3.small 또는 medium 타입 Peer Node 가능
    • 최대 1 TB 의 Peer node storage
    • Orderer 성능 제약(Standard 에 비해 떨어짐. 수치는 안나옴)
  • Standard Edition : $0.55/h (617원/시간)
    • 네트워크 상 최대 30개 멤버
    • 멤버 당 최대 10개 Peer Node
    • bc.t3, bc.m5, bc.c5 타입 Peer Node 가능
    • 최대 15 TB 의 Peer node storage

On Demand peer node pricing

  • 38 원 ~ 1,220 원 / 시간

Peer node storage
최소 10GB 부터 최대 15TB 까지 선택할 수 있음

  • $0.10 / 월 (112원/월)

Data Written
Fabric Network 에 Write 되는 모든 Transaction Payload 를 포함한 Data 총량

  • $0.10 / GB (112원/GB)

가격 예시

✸ Starter Edition 기준으로 아래와 같이 세팅 한다고 하자

2 개 Starter Member
각 멤버가 bc.t3.small 1개씩 운영
20GB Storage
시간당 9MB 의 Network 사용

위 Spec 이면 간단한 내부 PoC 정도가 가능한 사양이라고 봐야 하겠다. 음.. 사실 PoC 를 위한 개발 정도?

✸ Standard Edition 으로 가보자. 상용에서는 자신의 Org 에 대한 비용만 내는 경우가 많은것이므로 아래와 같이 구성했다고 가정한다

1 개 Standard Member
3 개 Peer Node (m5.2xlarge)
Node 당 1TB Storage
시간당 200MB Network 사용

위 Spec 이면 상용 서비스를 위한 구성 으로 알맞는다고 본다. Offchain 시스템을 위한 부분은 추가로 갖추어져야 한다.

이상이 AMB(Amazon Managed Blockchain) 의 소개 이다. 대략 어떤 서비스가 가능한지 감이 온다. 설치와 설정을 위한 노가다가 줄어들고, 모니터링 기능이 추가될 것이고, Key 저장을 안전하게 해주고, QLDB 를 활용하여 모든 Transaction 과 Activity 가 저장되니 의미있는 데이터를 QLDB 에서 뽑아쓸 수 있다 정도가 핵심일듯 싶다.

그리고 소개 페이지나 Guide 등에 보면 대부분 Fabric 중심으로 설명되어 있어서 사실 Ethereum 은 기존의 Blockchain Template 기능 정도를 재탕하여 해주지 않을까 생각이 든다

사용 가능한 상태가 되면 실제 사용해보고 (설마 돈내라는건 아니겠지..) 추가로 글을 써보도록 하겠다

%23%20Amazon%20Managed%20Blockchain%20%0A@%28220.Blockchain%29%5B%uBE14%uB85C%uADF8%2C%20%uC774%uB354%uB9AC%uC6C0%2C%20ethereum%2C%20aws%2C%20qldb%2C%20%uD2F0%uC2A4%uD1A0%uB9AC%5D%0A%0A11/28%uC77C%2C%20AWS%20%uC5D0%uC11C%20AWS%20Blockchain%20Template%20%uC5D0%20%uC774%uC5B4%20Amazon%20Managed%20Blockchain%20%uC11C%uBE44%uC2A4%uC640%20QLDB%20%uB97C%20%uC18C%uAC1C%uD558%uC600%uB2E4.%20%uC9C0%uAE08%20%uC2DC%uC810%uC5D0%uB294%20Preview%20%uC0C1%uD0DC%uC778%uB370%20%uC774%uB9C8%uC800%uB3C4%20Sign%20Up%20%uC744%20%uD574%uC57C%20%uD558%uAE30%uB294%20%uD558%uB2E4.%0A%0A%21%5BAlt%20text%5D%28./1543543140559.png%29%0A%21%5BAlt%20text%5D%28./1543542273179.png%29%0A%0A%uC77C%uB2E8%20Preview%20Signup%20%uC744%20%uD558%uACE0%uB098%uBA74%20%uC2DC%uAC04%uC774%20%uC880%20%uC9C0%uB0AC%uB354%uB2C8%20%uC544%uB798%20%uCC98%uB7FC%20%uBA54%uC77C%uC774%20%uC628%uB2E4%0A%0A%21%5BAlt%20text%5D%28./1543543183836.png%29%0A%0A%uC704%20%uBA54%uC77C%uC774%20%uC654%uB2E4%uACE0%20%uD574%uC11C%20Preview%20Applicant%20%uAC00%20%uB418%uC5C8%uB2E4%uB294%uAC8C%20%uC544%uB2C8%uB2E4.%20**%uAE30%uB2E4%uB824%uC57C%20%uD55C%uB2E4..**%0AApply%20%uB97C%20%uD588%uC9C0%uB9CC%20%uC774%uD2C0%20%uC9F8%20%uC544%uC9C1%20%uD68C%uC2E0%uC774%20%uC624%uAC70%uB098%20%uD558%uC9C0%20%uC54A%uB294%uB2E4%20%uADF8%uB0E5%20%uACC4%uC18D%20%uAE30%uB2E4%uB824%uC57C%20%uD55C%uB2E4.%0A%3E%20%uD639%uC2DC%uB098%20%uC0AC%uC6A9%20%uAC00%uB2A5%uD574%uC9C0%uBA74%20%uC368%uBCF4%uACE0%20%uBC14%uB85C%20%uB2E4%uC2DC%20%uAE00%uC744%20%uC62C%uB824%uBCF4%uACA0%uB2E4%0A%0A%23%23%20%uC5B4%uB514%uC5D0%20%uC788%uB098%0AAWS%20Console%20%uC5D0%20%uB4E4%uC5B4%uAC00%uBA74%20%uC544%uB798%20%uCC98%uB7FC%20Amazon%20Managed%20Blockchain%20%uC774%20%uC788%uB294%uAC78%20%uBCFC%20%uC218%20%uC788%uB2E4%0A%0A%21%5BAlt%20text%5D%28./1543543250433.png%29%0A%0A%uB9C8%uCE58%20%uB420%20%uAC83%20%uAC19%uC740%20%uB290%uB08C%uC774%uC9C0%uB9CC%20%uD074%uB9AD%uD558%uBA74%20%uB2E4%uC2DC%20Preview%20sign%20up%20%uD398%uC774%uC9C0%uB85C%20%uB118%uC5B4%uAC04%uB2E4%0A%0A%3E%20%uD604%uC7AC%20AMB%20Preview%20%uAC00%20%uC9C0%uC6D0%uB418%uB294%20Region%20%uC740%20**US%20East%20%28Virginia%29**%20%uBFD0%uC774%uB2E4%0A%3E%20%uD604%20%uC2DC%uC810%uC5D0%20QLDB%20%uBA54%uB274%uB294%20%uC5B4%uB514%uC5D0%20%uC788%uB294%uC9C0%20%uBC1C%uACAC%uD558%uC9C0%20%uBABB%uD558%uC600%uB2E4%0A%0A%23%23%20Amazon%20Managed%20Blockchain%0A%uC544%uC9C1%uC740%20%uB4E4%uC5B4%uAC00%uBCF4%uC9C0%uB3C4%20%uBABB%uD558%uACE0%20%uC790%uB8CC%uB3C4%20%uAC70%uC758%20%uC804%uBB34%uD55C%20%uC0C1%uD0DC%uC774%uBBC0%uB85C%2C%20%5BAWS%20%uC0C1%uC758%20%uC11C%uBE44%uC2A4%20%uC18C%uAC1C%20%uD398%uC774%uC9C0%5D%28https%3A//aws.amazon.com/ko/managed-blockchain/%29%uB97C%20%uCC38%uACE0%uD558%uC5EC%20%uC5B4%uB5A4%uAC83%uC778%uAC00%20%uC815%uB9AC%uD574%uB193%uACA0%uB2E4%0A%0A%23%23%23%20%uC804%uCCB4%20%uAD6C%uC131%0A%21%5BAlt%20text%5D%28./1543623032865.png%29%0A%0AAMB%20%uB294%20%uB3C5%uB9BD%uB41C%20Member%20%uBCC4%uB85C%20Peer%20Node%20%uB97C%20%uAD6C%uC131%uD558%uAC8C%20%uD558%uACE0%2C%20Ordering%20Service%20%uC640%20Client%20%uB97C%20Fabric%20Network%20%uC73C%uB85C%20%uC5F0%uACB0%uD574%uC8FC%uAE30%20%uC704%uD55C%20VPC%20Endpoint%20Service%20%uB4F1%uC740%20%uACF5%uC6A9%uD560%20%uC218%20%uC788%uB294%20%uCEF4%uD3EC%uB10C%uD2B8%20%uD615%uD0DC%uB85C%20%uC81C%uACF5%uD558%uB294%20%uAC83%uC73C%uB85C%20%uBCF4%uC778%uB2E4.%20%0A%0A%uC544%uB798%20%uAC00%uACA9%uD45C%uB97C%20%uBCF4%uC544%uB3C4%20%uC54C%uACA0%uC9C0%uB9CC%2C%20Ordering%20Service%20%uB97C%20%uC704%uD55C%20%uBCC4%uB3C4%uC758%20Node%20%uB294%20%uAD6C%uB9E4%uD558%uC9C0%20%uC54A%uB294%uB2E4.%20%uC774%uBD80%uBD84%uC740%20AWS%20%uC5D0%uC11C%20%uC81C%uACF5%uD558%uB294%20%uAC83%uC73C%uB85C%20%uBCF4%uC774%uBA70%2C%20%uB300%uC2E0%20Membership%20%uAE08%uC561%uC744%20%uC2DC%uAC04%uB2F9%uC73C%uB85C%20%uBC1B%uB294%20%uAC83%uC73C%uB85C%20%uC0DD%uAC01%uB41C%uB2E4%0A%0A%23%23%23%20Benefits%20%28%26Features%29%0A**Fully%20Managed**%0A-%20%uC5EC%uB7EC%20AWS%20%uACC4%uC815%uC5D0%20%uAC78%uCCD0%20Blockchain%20Network%20%uC744%20%uC27D%uAC8C%20%uC0DD%uC131%0A-%20%uBA64%uBC84%20%uADF8%uB8F9%uACFC%20Account%20%uC758%20Transaction%20%uC2E4%uD589%2C%20%uB370%uC774%uD130%20%uACF5%uC720%uB97C%20%uC124%uC815%0A-%20Infra%20%uC640%20S/W%20%uC124%uCE58%20%uB4F1%uC774%20%uD544%uC694%20%uC5C6%uB2E4%0A-%20%uBAA8%uB2C8%uD130%uB9C1%20%uAE30%uB2A5%20%uC81C%uACF5%uD55C%uB2E4%0A-%20%uBA64%uBC84%20%uCD94%uAC00%uC640%20%uC0AD%uC81C%uB97C%20%uC704%uD55C%20%uD22C%uD45C%20%uAE30%uB2A5%20API%uB97C%20%uC81C%uACF5%uD55C%uB2E4%0A%0A**Fabric%20%uACFC%20Ethereum%20%uC911%20%uC120%uD0DD**%0A-%20Privacy%20%uC640%20Permission%20%uC911%uC694%uD55C%20%uACF3%uC5D0%20Fabric%20%uCD94%uCC9C%0A-%20Transparency%20%uC640%20%uBD84%uC0B0%uD654%20%uC911%uC694%uD55C%20%uACF3%uC5D0%20Ethereum%20%uCD94%uCC9C%0A-%20Ethereum%20%uC740%20Public%20/%20Private%20Network%20%uC9C0%uC6D0%uD560%20%uAC83%uC73C%uB85C%20%uBCF4%uC784%0A%0A**Scalable%20and%20Secure**%0A-%20Peer%20node%20%uCD94%uAC00%uB97C%20%uC704%uD55C%20API%20%uB97C%20%uC81C%uACF5%0A-%20%uC6D0%uD558%uB294%20H/W%20spec%20%uC744%20%uC870%uD569%0A-%20AWS%20KMS%28Key%20Management%20System%29%uB97C%20%uD1B5%uD55C%20Key%20%uAD00%uB9AC%uB85C%20%uC548%uC804%0A%0A**Easily%20analyze%20Blockchain%20Activity**%20%28%uD5A5%uD6C4%20%uC608%uC815%29%0A-%20Blockchain%20network%20%uD65C%uB3D9%uC744%20QLDB%20%uC5D0%20%uC800%uC7A5%uD560%20%uC218%20%uC788%uC74C%0A-%20%uBCC0%uACBD%uB418%uAC70%uB098%20%uC0AD%uC81C%uB420%20%uC218%20%uC5C6%uB294%20%uD615%uD0DC%uB85C%20%uC601%uAD6C%uD788%20%uB0A8%uAC8C%uB428%0A-%20%uB204%uAC00%20Transaction%20%uC744%20%uBC1C%uC0DD%uD558%uC600%uB294%uC9C0%2C%20Transaction%20Rate%20%uC774%20%uC5B4%uB5BB%uAC8C%20%uB418%uB294%uC9C0%20%uB4F1%20Query%20%uAC00%uB2A5%0A%0A**Reliability**%0A-%20Ordering%20service%20%uC5D0%20QLDB%20%uB97C%20%uC811%uBAA9%2C%20Transaction%20%uC758%20Full%20History%20%uB97C%20%uC870%uD68C%20%uAC00%uB2A5%uD558%uB3C4%uB85D%20%uD568%0A%0A%23%23%23%20%uAC00%uACA9%0AN.%20Virginia%20Region%20%uC5D0%20%uB300%uD55C%20%uAC00%uACA9%uB9CC%20%uB098%uC640%uC788%uB294%20%uC0C1%uD669%uC73C%uB85C%2C%20%uC544%uB798%uC640%20%uAC19%uC774%20%5B%uAC00%uACA9%uD45C%5D%28https%3A//aws.amazon.com/ko/managed-blockchain/pricing/%29%uAC00%20%uB098%uC628%uB2E4%0A%0A**Membership**%0A-%20Starter%20Edition%20%3A%20%240.30/h%20%28337%uC6D0/%uC2DC%uAC04%29%0A%09-%20%uB124%uD2B8%uC6CC%uD06C%20%uC0C1%20%uCD5C%uB300%205%uAC1C%20%uBA64%uBC84%0A%09-%20%uBA64%uBC84%20%uB2F9%20%uCD5C%uB300%202%uAC1C%20Peer%20Node%0A%09-%20bc.t3.small%20%uB610%uB294%20medium%20%uD0C0%uC785%20Peer%20Node%20%uAC00%uB2A5%0A%09-%20%uCD5C%uB300%201%20TB%20%uC758%20Peer%20node%20storage%0A%09-%20Orderer%20%uC131%uB2A5%20%uC81C%uC57D%28Standard%20%uC5D0%20%uBE44%uD574%20%uB5A8%uC5B4%uC9D0.%20%uC218%uCE58%uB294%20%uC548%uB098%uC634%29%0A-%20Standard%20Edition%20%3A%20%240.55/h%20%28617%uC6D0/%uC2DC%uAC04%29%0A%09-%20%uB124%uD2B8%uC6CC%uD06C%20%uC0C1%20%uCD5C%uB300%2030%uAC1C%20%uBA64%uBC84%0A%09-%20%uBA64%uBC84%20%uB2F9%20%uCD5C%uB300%2010%uAC1C%20Peer%20Node%0A%09-%20bc.t3%2C%20bc.m5%2C%20bc.c5%20%uD0C0%uC785%20Peer%20Node%20%uAC00%uB2A5%0A%09-%20%uCD5C%uB300%2015%20TB%20%uC758%20Peer%20node%20storage%0A%0A**On%20Demand%20peer%20node%20pricing**%0A%0A%21%5BAlt%20text%5D%28./1543623968662.png%29%0A%0A-%2038%20%uC6D0%20%7E%201%2C220%20%uC6D0%20/%20%uC2DC%uAC04%0A%0A**Peer%20node%20storage**%0A%uCD5C%uC18C%2010GB%20%uBD80%uD130%20%uCD5C%uB300%2015TB%20%uAE4C%uC9C0%20%uC120%uD0DD%uD560%20%uC218%20%uC788%uC74C%0A-%20%240.10%20/%20%uC6D4%20%28112%uC6D0/%uC6D4%29%0A%0A**Data%20Written**%0AFabric%20Network%20%uC5D0%20Write%20%uB418%uB294%20%uBAA8%uB4E0%20Transaction%20Payload%20%uB97C%20%uD3EC%uD568%uD55C%20Data%20%uCD1D%uB7C9%0A-%20%240.10%20/%20GB%20%28112%uC6D0/GB%29%0A%0A**%uAC00%uACA9%20%uC608%uC2DC**%0A%0A%u2738%20Starter%20Edition%20%uAE30%uC900%uC73C%uB85C%20%uC544%uB798%uC640%20%uAC19%uC774%20%uC138%uD305%20%uD55C%uB2E4%uACE0%20%uD558%uC790%0A%3E%202%20%uAC1C%20Starter%20Member%0A%3E%20%uAC01%20%uBA64%uBC84%uAC00%20bc.t3.small%201%uAC1C%uC529%20%uC6B4%uC601%0A%3E%2020GB%20Storage%20%0A%3E%20%uC2DC%uAC04%uB2F9%209MB%20%uC758%20Network%20%uC0AC%uC6A9%0A%0A%21%5BAlt%20text%5D%28./1543627868394.png%29%0A%0A%uC704%20Spec%20%uC774%uBA74%20**%uAC04%uB2E8%uD55C%20%uB0B4%uBD80%20PoC%20%uC815%uB3C4**%uAC00%20%uAC00%uB2A5%uD55C%20%uC0AC%uC591%uC774%uB77C%uACE0%20%uBD10%uC57C%20%uD558%uACA0%uB2E4.%20%uC74C..%20%uC0AC%uC2E4%20PoC%20%uB97C%20%uC704%uD55C%20%uAC1C%uBC1C%20%uC815%uB3C4%3F%0A%0A%u2738%20Standard%20Edition%20%uC73C%uB85C%20%uAC00%uBCF4%uC790.%20%uC0C1%uC6A9%uC5D0%uC11C%uB294%20%uC790%uC2E0%uC758%20Org%20%uC5D0%20%uB300%uD55C%20%uBE44%uC6A9%uB9CC%20%uB0B4%uB294%20%uACBD%uC6B0%uAC00%20%uB9CE%uC740%uAC83%uC774%uBBC0%uB85C%20%uC544%uB798%uC640%20%uAC19%uC774%20%uAD6C%uC131%uD588%uB2E4%uACE0%20%uAC00%uC815%uD55C%uB2E4%0A%0A%3E%201%20%uAC1C%20Standard%20Member%0A%3E%203%20%uAC1C%20Peer%20Node%20%28m5.2xlarge%29%0A%3E%20Node%20%uB2F9%201TB%20Storage%0A%3E%20%uC2DC%uAC04%uB2F9%20200MB%20Network%20%uC0AC%uC6A9%0A%21%5BAlt%20text%5D%28./1543628282848.png%29%0A%0A%uC704%20Spec%20%uC774%uBA74%20**%uC0C1%uC6A9%20%uC11C%uBE44%uC2A4%uB97C%20%uC704%uD55C%20%uAD6C%uC131**%20%uC73C%uB85C%20%uC54C%uB9DE%uB294%uB2E4%uACE0%20%uBCF8%uB2E4.%20Offchain%20%uC2DC%uC2A4%uD15C%uC744%20%uC704%uD55C%20%uBD80%uBD84%uC740%20%uCD94%uAC00%uB85C%20%uAC16%uCD94%uC5B4%uC838%uC57C%20%uD55C%uB2E4.%0A%0A%uC774%uC0C1%uC774%20AMB%28Amazon%20Managed%20Blockchain%29%20%uC758%20%uC18C%uAC1C%20%uC774%uB2E4.%20%uB300%uB7B5%20%uC5B4%uB5A4%20%uC11C%uBE44%uC2A4%uAC00%20%uAC00%uB2A5%uD55C%uC9C0%20%uAC10%uC774%20%uC628%uB2E4.%20**%uC124%uCE58%uC640%20%uC124%uC815%uC744%20%uC704%uD55C%20%uB178%uAC00%uB2E4%uAC00%20%uC904%uC5B4%uB4E4%uACE0%2C%20%uBAA8%uB2C8%uD130%uB9C1%20%uAE30%uB2A5%uC774%20%uCD94%uAC00%uB420%20%uAC83%uC774%uACE0%2C%20Key%20%uC800%uC7A5%uC744%20%uC548%uC804%uD558%uAC8C%20%uD574%uC8FC%uACE0%2C%20QLDB%20%uB97C%20%uD65C%uC6A9%uD558%uC5EC%20%uBAA8%uB4E0%20Transaction%20%uACFC%20Activity%20%uAC00%20%uC800%uC7A5%uB418%uB2C8%20%uC758%uBBF8%uC788%uB294%20%uB370%uC774%uD130%uB97C%20QLDB%20%uC5D0%uC11C%20%uBF51%uC544%uC4F8%20%uC218%20%uC788%uB2E4**%20%uC815%uB3C4%uAC00%20%uD575%uC2EC%uC77C%uB4EF%20%uC2F6%uB2E4.%20%0A%0A%uADF8%uB9AC%uACE0%20%uC18C%uAC1C%20%uD398%uC774%uC9C0%uB098%20Guide%20%uB4F1%uC5D0%20%uBCF4%uBA74%20%uB300%uBD80%uBD84%20Fabric%20%uC911%uC2EC%uC73C%uB85C%20%uC124%uBA85%uB418%uC5B4%20%uC788%uC5B4%uC11C%20%uC0AC%uC2E4%20Ethereum%20%uC740%20%uAE30%uC874%uC758%20%20Blockchain%20Template%20%uAE30%uB2A5%20%uC815%uB3C4%uB97C%20%uC7AC%uD0D5%uD558%uC5EC%20%uD574%uC8FC%uC9C0%20%uC54A%uC744%uAE4C%20%uC0DD%uAC01%uC774%20%uB4E0%uB2E4%0A%0A%uC0AC%uC6A9%20%uAC00%uB2A5%uD55C%20%uC0C1%uD0DC%uAC00%20%uB418%uBA74%20%uC2E4%uC81C%20%uC0AC%uC6A9%uD574%uBCF4%uACE0%20%28%uC124%uB9C8%20%uB3C8%uB0B4%uB77C%uB294%uAC74%20%uC544%uB2C8%uACA0%uC9C0..%29%20%uCD94%uAC00%uB85C%20%uAE00%uC744%20%uC368%uBCF4%uB3C4%uB85D%20%uD558%uACA0%uB2E4%0A%0A

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
Edit

Multisig Wallet #1

Ethereum multisigwallet ethereum

Multisig Wallet 을 구현해보자. 블록체인의 응용을 이야기 하거나 할 때 빠지지 않는 단골 메뉴이기도 한 Multi Signature 를 활용하는 Wallet 을 만들어 보고, gnosis, consensys 애들이 만든 Multisign Wallet 은 어떤 구조를 갖고 있는지도 봐보는 재미진 시간을 가져보자

Blockchain 의 Wallet

일단 Wallet 의 개념은 다 알것이다. 특히 Blockchain 의 Wallet 또한 모두 잘 알 것이다. Blockchain 의 Wallet 은

  • Key Pair (Private / Public Key) 를 생성하여 안전하게 보관
  • Transaction 을 생성하고 여기에 본인의 전자서명을 첨부 (보통 Transaction 의 Hash 값을 원문으로 함)
  • Account 기반의 State Model 인 경우, Account Nonce 를 관리

를 기본 기능으로 가지며, 추가적으로

  • 복수의 계좌(Account)를 생성/관리 하는 HD Wallet 의 경우 KDF(Key Derivation Function)를 통한 루트 키와 Derived Key 관리
  • Mnemonic 기반의
  • Web 기반 dApp 실행을 위한 Web View 와 web3.js 등의 JS Injection
  • (Ethereum) ERC 20 기반의 Token 및 기타 EIP 제안 중 널리 쓰이는 ERC 지원(ERC721 등)

등의 기능을 가지는 Wallet 들이 많아지고 있다.

Wallet 에 관해서는 이번 주제 끝나고 다음에 한번 상세히 다루어 보도록 하겠다
HD Wallet 이나 Cold Wallet 에 대해서도 재미난 것들이 많이 있으니 그때 또~

일반 Crypto Wallet 의 Transfer Transaction

Multisig Wallet 은 Crypto Wallet 자체에서 지원하는 기능은 아니다. UTXO 내의 Script 혹은 Smart Contract 의 코드로 Blockchain 내에 존재한다.

일단 아래는 단순화 된 일반적인 Wallet 의 Transfer 과정이다

그림을 단순화 해서 그렇지 Wallet 내부에서는 아래와 같은 과정을 거친다

  1. (secp256k1 으로 Private Key 는 이미 생성 되었다고 가정한다. 즉, 주소는 이미 생성 되었다고 가정한다)
  2. ECDSA 전자서명이 붙지 않은, 100 Ether 를 Value 로 하는 Raw Transaction 을 구성한다
  3. Raw Transaction 의 keccak256 Hash 를 원문으로 한 ECDSA 전자서명 값 r,s,v 를 추가하여 Transaction 을 만든다
  4. Wallet 서비스를 하는 Gateway 를 거치거나 혹은 직접 Node 에게(이런경우는 흔치 않다) Transaction 을 Submit 한다
  5. 100 Ether 는 to address 에 해당하는 Account 의 State 에 더해진다

UTXO 기반 모델의 Blockchain 도 Wallet 의 기능은 마찬가지이다

Multisig Wallet 의 Transfer Transaction

일반적으로 Multisig Wallet 은 2개 이상의 서명이 있어야 실제 Token 의 이체가 일어나게 할 수 있는 기능을 갖는 Wallet 을 말한다.

Bitcoin Wallet 개발하시는 분들은 Multisig Wallet 하면, Wallet 에서 생성한 Tx(Transaction) 내 Output 의 Locking Script(Pubkey Script) 부분에 OP_CHECKMULTISIG 를 포함하도록 만드는 것을 생각 할 수 있겠다.

Ethereum 과 같이 Smart Contract 를 지원하는 블록체인의 경우는 좀더 세련된 방식으로 Multisig Wallet 을 만든다. 또한, Token Asset 의 이체를 위한 Transfer Transaction 뿐만이 아니라 Smart Contract 실행을 위한 Message Transaction 또한 조건을 만족하는 복수개의 서명이 Submit 되었을때에만 실행되게 할 수 있다(보통 이렇게 만든다).

왜 갑자기 Wallet 얘기를 하는데 Smart Contract 얘기가 나오는가 할 수도 있다. 예전부터 많은 사람들이 이부분을 헷갈려 한다는걸 느꼈다. Multisig Wallet 은 결국 내가 제출한 Transaction 에 대해, 미리 지정된 복수의 Account Owner 가 전자서명을 통해 허락해야지만 실제로 그 Transaction 이 실행되어야 하는 규칙 이다.

이러한 규칙은 Wallet App 에 구현되고 저장되는 경우 충분히 위변조 될 수 있으며 중요한 돈거래의 경우 보안성과 범용성의 측면에서 뭐하나 이로울게 없다. 그 얘기는, 블록체인 기술과 Smart Contract 의 필요성이 가장 강한 형태의 dApp 중 하나가 바로 Multisig Wallet 인 것이다.

아래의 Diagram 은 Multisig Wallet 의 동작을 단순화 해본 그림이다
상황은 0xa0c9… 주소를 갖는 EOA 가 0x039b… 에게 100 Ether 를 이체하려고 하며, 이때 미리 지정한 0x0248… EOA 의 최종 승인 이 있어야지만 실제로 100 Ether 가 0x039b… 에게 이체되는 Transaction 이 실행되게 해야 한다.

구성요소

  • Wallet - Account 소유자가 설치한 Browser Plug-in, Desktop, Mobile 용의 Wallet App (Metamask, MEW, Jaxx, Exodus …) 이거나 Smart Contract 실행을 위한 Message Transaction 을 만들어낼 수 있는 어떠한 dApp 도 될 수 있다
  • Multisig Wallet Contract
    • 이체하고자 하는 Token 을 보관
    • 제출 된 Transaction 실행 요건 지정 (n of m 개의 전자서명 요구와 같은)
    • 전자서명 주체가 되는 Wallet Owner 들의 등록 및 관리
    • Transaction 제출 알림
    • 요건을 만족한 경우 Transaction 의 실제 실행

이외에도 Wallet 앱을 개발하고 서비스 하는 회사의 경우, 아무나 자신들이 운영하는 Node 에 수많은 Transaction 을 날려 DoS Attack 을 하거나 부하를 일으키지 않도록 하고 부가적인 서비스를 제공하기위한 목적으로 Wallet Service Gateway 를 둘 수도 있겠지만 Offchain 시스템은 모두 생략하였다

위 구성요소의 설명을 보면 알겠지만 핵심은 Multisig Wallet Contract 이다. Multisig Wallet의 모든 핵심 기능은 이 Contract 에서 이루어진다. 예전에 문제가 된 Parity 의 Multisig Wallet 도 물론 Smart Contract 이다.

흐름

위 Multisig Wallet Contract 를 사용하는 흐름을 보면 간단하다 하지만 이전 글에서는 다루지 않았던 새로운 요소가 하나 등장한다

  1. submitTransaction
    submitTranaction() 을 실행하기 위한 Message Transaction 의 Parameter 를 이용하여 실제 Token(Ether) 을 받을 주소를 넣어준다

    이때, Token 을 받을 대상이 다른 Smart Contract 이고 Transaction 종류가 Message Transaction 인 경우, submitTransaction() 의 파라미터 중 하나에 실행해야 하는 Smart Contract 의 Method 와 파라미터를 포함하는 Data Payload 를 넣어준다 (web3 의 .getData() 사용)

    추가적으로, 예의상 submitTransaction() 이 되면 Event 로 transaction 이 submit 되었다고 알려주는 센스 정도는 설명하지 않아도 구현 되어야 한다고 느낌이 올 것이다

이부분은 구현 부분에서 설명하겠다. 향후 CALL, CALLCODE, DELEGATECALL 과 관련 있는 부분이니 그때 또 설명 하겠다 (음.. 오랜만이 시작하려니 설명할게 산더미같다..)

  1. confirmTransaction
    위 submitTransaction() 으로 제출 된 Transaction 을 승인 하는 단계이다. Contract 에 등록된 승인 권한이 있는 EOA 가 confirmTransaction() 을 통해 confirm 해주면 된다. 이때, 각 confirm 시 마다 등록된 조건(최소 n 개의 confirm 필요)을 만족하는 confirm 을 받았는지 check 한다

  2. executeTransaction
    confirmTransaction() 실행 시 만족하는 confirm 수가 채워졌으면 submitTransaction() 시에 제출 된 token 의 양 만큼을 원래 보내고자 했던 주소로 보내주도록 Transaction 의 value 값을 채우며, submitTransaction() 단계에서 제출 된 Message Transaction 이 있었다면 Wallet Contract 가(msg.sender == Wallet Contract) 해당 Message Transaction 을 실행한다

Multisig 인데, 서명은 언제하는가?

전에 Multisig Wallet 에 대해 차분히 설명 해주고 나서 들었던 질문이 있었다. “그런데 다른사람들(EOA)이 전자서명은 언제 해줘요?” 전자서명은 이미 Smart Contract 를 실행하는 submitTransaction(), confirmTransaction() 단계에서 Message Transaction 을 보내기 위해 Raw Transaction 에 대고 다 했다. 그래야 Transaction 이 submit 되었지 않겠는가..요.. 라고 답을 해줬던 기억이 난다.

(단, Smart Contract 이 internal call 을 하는 구간에는 전자서명이 당연히 없다. EOA 에서 이미 했지않은가. Smart Contract 는 서명할 수 있는 놈이 아니다. Smart Contract 을 실행한 놈이 이미 전자서명을 해서 Message Transaction 을 보낸 것이다)

이름이 문제다. Multisig.. 사실 confirmTransaction() 단계에서 파라미터로 메시지와 전자서명값 r,s,v 를 넣어줄 수도 있다. 그러나 다른 EOA 의 전자서명을 전달하는 상황이 아니고 confirmTransaction() 을 실행하는 주체 자체가 승인 권한을 가진 EOA 이므로 이미 transaction 내에 들어있는 전자서명을 Multisig Wallet Contract 의 파라미터로 보낼 이유가 없는 것이다

마치며

오랜만에 올리는 글 치고는 매우 기본적인 주제를 올려본다. 사실 0xProtocol, Plasma, Raiden, ERC20 Token 기반으로 돌아가는 dApp 만들기, plasma-mvp … 또는 Enterprise Blockchain, Quorum 등등 무엇부터 시작할까를 많이 고민해보았다.

그리고 이전에 올렸던 글들을 다시 훑어보다가, 블로그의 흐름이 갑자기 끊기는것 보다는 이전의 Context 를 이어나아가면서 좀더 빠르게 진행해보는 것으로 일단 마음을 먹어본다. (그래도 기본은 기본대로 가고, 중간중간 발표자료도 좀 올리고, 이런저런 구현 샘플들도 짬짬이 올리겠다^^;;)

다음은 Multisig Wallet 구현 예제를 1회 정도 올리고 퀵하게 마무리 하고 또 그 다음으로 넘어가 보도록 하는걸 목표로 해보겠다

%23%20Multisig%20Wallet%20%231%0A@%28220.Blockchain%29%5B%uC774%uB354%uB9AC%uC6C0%2C%20Ethereum%2C%20%uD2F0%uC2A4%uD1A0%uB9AC%2C%20multisigwallet%2C%20ethereum%5D%0A%0A%3Cimg%20src%3D%22./1543316979811.png%22%20width%3D%22300%22%20align%3D%22middle%22%20/%3E%0A%0AMultisig%20Wallet%20%uC744%20%uAD6C%uD604%uD574%uBCF4%uC790.%20%uBE14%uB85D%uCCB4%uC778%uC758%20%uC751%uC6A9%uC744%20%uC774%uC57C%uAE30%20%uD558%uAC70%uB098%20%uD560%20%uB54C%20%uBE60%uC9C0%uC9C0%20%uC54A%uB294%20%uB2E8%uACE8%20%uBA54%uB274%uC774%uAE30%uB3C4%20%uD55C%20Multi%20Signature%20%uB97C%20%uD65C%uC6A9%uD558%uB294%20Wallet%20%uC744%20%uB9CC%uB4E4%uC5B4%20%uBCF4%uACE0%2C%20gnosis%2C%20consensys%20%uC560%uB4E4%uC774%20%uB9CC%uB4E0%20Multisign%20Wallet%20%uC740%20%uC5B4%uB5A4%20%uAD6C%uC870%uB97C%20%uAC16%uACE0%20%uC788%uB294%uC9C0%uB3C4%20%uBD10%uBCF4%uB294%20%uC7AC%uBBF8%uC9C4%20%uC2DC%uAC04%uC744%20%uAC00%uC838%uBCF4%uC790%20%0A%0A%23%23%20Blockchain%20%uC758%20Wallet%0A%uC77C%uB2E8%20Wallet%20%uC758%20%uAC1C%uB150%uC740%20%uB2E4%20%uC54C%uAC83%uC774%uB2E4.%20%uD2B9%uD788%20Blockchain%20%uC758%20Wallet%20%uB610%uD55C%20%uBAA8%uB450%20%uC798%20%uC54C%20%uAC83%uC774%uB2E4.%20Blockchain%20%uC758%20Wallet%20%uC740%20%0A-%20Key%20Pair%20%28Private%20/%20Public%20Key%29%20%uB97C%20%uC0DD%uC131%uD558%uC5EC%20%uC548%uC804%uD558%uAC8C%20%uBCF4%uAD00%0A-%20Transaction%20%uC744%20%uC0DD%uC131%uD558%uACE0%20%uC5EC%uAE30%uC5D0%20%uBCF8%uC778%uC758%20%uC804%uC790%uC11C%uBA85%uC744%20%uCCA8%uBD80%20%28%uBCF4%uD1B5%20Transaction%20%uC758%20Hash%20%uAC12%uC744%20%uC6D0%uBB38%uC73C%uB85C%20%uD568%29%0A-%20Account%20%uAE30%uBC18%uC758%20State%20Model%20%uC778%20%uACBD%uC6B0%2C%20Account%20Nonce%20%uB97C%20%uAD00%uB9AC%0A%0A%uB97C%20%uAE30%uBCF8%20%uAE30%uB2A5%uC73C%uB85C%20%uAC00%uC9C0%uBA70%2C%20%uCD94%uAC00%uC801%uC73C%uB85C%0A-%20%uBCF5%uC218%uC758%20%uACC4%uC88C%28Account%29%uB97C%20%uC0DD%uC131/%uAD00%uB9AC%20%uD558%uB294%20HD%20Wallet%20%uC758%20%uACBD%uC6B0%20KDF%28Key%20Derivation%20Function%29%uB97C%20%uD1B5%uD55C%20%uB8E8%uD2B8%20%uD0A4%uC640%20Derived%20Key%20%uAD00%uB9AC%20%0A-%20Mnemonic%20%uAE30%uBC18%uC758%20%0A-%20Web%20%uAE30%uBC18%20dApp%20%uC2E4%uD589%uC744%20%uC704%uD55C%20Web%20View%20%uC640%20web3.js%20%uB4F1%uC758%20JS%20Injection%0A-%20%28Ethereum%29%20ERC%2020%20%uAE30%uBC18%uC758%20Token%20%uBC0F%20%uAE30%uD0C0%20EIP%20%uC81C%uC548%20%uC911%20%uB110%uB9AC%20%uC4F0%uC774%uB294%20ERC%20%uC9C0%uC6D0%28ERC721%20%uB4F1%29%0A%0A%uB4F1%uC758%20%uAE30%uB2A5%uC744%20%uAC00%uC9C0%uB294%20Wallet%20%uB4E4%uC774%20%uB9CE%uC544%uC9C0%uACE0%20%uC788%uB2E4.%0A%0A%3E%20Wallet%20%uC5D0%20%uAD00%uD574%uC11C%uB294%20%uC774%uBC88%20%uC8FC%uC81C%20%uB05D%uB098%uACE0%20%uB2E4%uC74C%uC5D0%20%uD55C%uBC88%20%uC0C1%uC138%uD788%20%uB2E4%uB8E8%uC5B4%20%uBCF4%uB3C4%uB85D%20%uD558%uACA0%uB2E4%0A%3E%20HD%20Wallet%20%uC774%uB098%20Cold%20Wallet%20%uC5D0%20%uB300%uD574%uC11C%uB3C4%20%uC7AC%uBBF8%uB09C%20%uAC83%uB4E4%uC774%20%uB9CE%uC774%20%uC788%uC73C%uB2C8%20%uADF8%uB54C%20%uB610%7E%0A%0A%23%23%23%20%uC77C%uBC18%20Crypto%20Wallet%20%uC758%20Transfer%20Transaction%0AMultisig%20Wallet%20%uC740%20Crypto%20Wallet%20%uC790%uCCB4%uC5D0%uC11C%20%uC9C0%uC6D0%uD558%uB294%20%uAE30%uB2A5%uC740%20%uC544%uB2C8%uB2E4.%20UTXO%20%uB0B4%uC758%20Script%20%uD639%uC740%20Smart%20Contract%20%uC758%20%uCF54%uB4DC%uB85C%20Blockchain%20%uB0B4%uC5D0%20%uC874%uC7AC%uD55C%uB2E4.%0A%0A%uC77C%uB2E8%20%uC544%uB798%uB294%20%uB2E8%uC21C%uD654%20%uB41C%20%uC77C%uBC18%uC801%uC778%20Wallet%20%uC758%20Transfer%20%uACFC%uC815%uC774%uB2E4%0A%0A%3Cimg%20src%3D%22./multisig00.png%22%20width%3D%22600%22/%3E%0A%0A%uADF8%uB9BC%uC744%20%uB2E8%uC21C%uD654%20%uD574%uC11C%20%uADF8%uB807%uC9C0%20Wallet%20%uB0B4%uBD80%uC5D0%uC11C%uB294%20%uC544%uB798%uC640%20%uAC19%uC740%20%uACFC%uC815%uC744%20%uAC70%uCE5C%uB2E4%0A1.%20%28secp256k1%20%uC73C%uB85C%20Private%20Key%20%uB294%20%uC774%uBBF8%20%uC0DD%uC131%20%uB418%uC5C8%uB2E4%uACE0%20%uAC00%uC815%uD55C%uB2E4.%20%uC989%2C%20%uC8FC%uC18C%uB294%20%uC774%uBBF8%20%uC0DD%uC131%20%uB418%uC5C8%uB2E4%uACE0%20%uAC00%uC815%uD55C%uB2E4%29%0A2.%20ECDSA%20%uC804%uC790%uC11C%uBA85%uC774%20%uBD99%uC9C0%20%uC54A%uC740%2C%20100%20Ether%20%uB97C%20Value%20%uB85C%20%uD558%uB294%20Raw%20Transaction%20%uC744%20%uAD6C%uC131%uD55C%uB2E4%0A3.%20Raw%20Transaction%20%uC758%20keccak256%20Hash%20%uB97C%20%uC6D0%uBB38%uC73C%uB85C%20%uD55C%20ECDSA%20%uC804%uC790%uC11C%uBA85%20%uAC12%20r%2Cs%2Cv%20%uB97C%20%uCD94%uAC00%uD558%uC5EC%20Transaction%20%uC744%20%uB9CC%uB4E0%uB2E4%0A4.%20Wallet%20%uC11C%uBE44%uC2A4%uB97C%20%uD558%uB294%20Gateway%20%uB97C%20%uAC70%uCE58%uAC70%uB098%20%uD639%uC740%20%uC9C1%uC811%20Node%20%uC5D0%uAC8C%28%uC774%uB7F0%uACBD%uC6B0%uB294%20%uD754%uCE58%20%uC54A%uB2E4%29%20Transaction%20%uC744%20Submit%20%uD55C%uB2E4%0A5.%20100%20Ether%20%uB294%20**to**%20address%20%uC5D0%20%uD574%uB2F9%uD558%uB294%20Account%20%uC758%20State%20%uC5D0%20%uB354%uD574%uC9C4%uB2E4%0A%0AUTXO%20%uAE30%uBC18%20%uBAA8%uB378%uC758%20Blockchain%20%uB3C4%20Wallet%20%uC758%20%uAE30%uB2A5%uC740%20%uB9C8%uCC2C%uAC00%uC9C0%uC774%uB2E4%0A%0A%23%23%20Multisig%20Wallet%20%uC758%20Transfer%20Transaction%0A%uC77C%uBC18%uC801%uC73C%uB85C%20Multisig%20Wallet%20%uC740%202%uAC1C%20%uC774%uC0C1%uC758%20%uC11C%uBA85%uC774%20%uC788%uC5B4%uC57C%20%uC2E4%uC81C%20Token%20%uC758%20%uC774%uCCB4%uAC00%20%uC77C%uC5B4%uB098%uAC8C%20%uD560%20%uC218%20%uC788%uB294%20**%uAE30%uB2A5**%uC744%20%uAC16%uB294%20Wallet%20%uC744%20%uB9D0%uD55C%uB2E4.%20%0A%0ABitcoin%20Wallet%20%uAC1C%uBC1C%uD558%uC2DC%uB294%20%uBD84%uB4E4%uC740%20Multisig%20Wallet%20%uD558%uBA74%2C%20Wallet%20%uC5D0%uC11C%20%uC0DD%uC131%uD55C%20Tx%28Transaction%29%20%uB0B4%20Output%20%uC758%20Locking%20Script%28Pubkey%20Script%29%20%uBD80%uBD84%uC5D0%20OP_CHECKMULTISIG%20%uB97C%20%uD3EC%uD568%uD558%uB3C4%uB85D%20%uB9CC%uB4DC%uB294%20%uAC83%uC744%20%uC0DD%uAC01%20%uD560%20%uC218%20%uC788%uACA0%uB2E4.%20%0A%0AEthereum%20%uACFC%20%uAC19%uC774%20Smart%20Contract%20%uB97C%20%uC9C0%uC6D0%uD558%uB294%20%uBE14%uB85D%uCCB4%uC778%uC758%20%uACBD%uC6B0%uB294%20%uC880%uB354%20%uC138%uB828%uB41C%20%uBC29%uC2DD%uC73C%uB85C%20Multisig%20Wallet%20%uC744%20%uB9CC%uB4E0%uB2E4.%20%uB610%uD55C%2C%20Token%20Asset%20%uC758%20%uC774%uCCB4%uB97C%20%uC704%uD55C%20Transfer%20Transaction%20%uBFD0%uB9CC%uC774%20%uC544%uB2C8%uB77C%20Smart%20Contract%20%uC2E4%uD589%uC744%20%uC704%uD55C%20Message%20Transaction%20%uB610%uD55C%20%uC870%uAC74%uC744%20%uB9CC%uC871%uD558%uB294%20**%uBCF5%uC218%uAC1C%uC758%20%uC11C%uBA85**%uC774%20Submit%20%uB418%uC5C8%uC744%uB54C%uC5D0%uB9CC%20%uC2E4%uD589%uB418%uAC8C%20%uD560%20%uC218%20%uC788%uB2E4%28%uBCF4%uD1B5%20%uC774%uB807%uAC8C%20%uB9CC%uB4E0%uB2E4%29.%0A%0A%uC65C%20%uAC11%uC790%uAE30%20Wallet%20%uC598%uAE30%uB97C%20%uD558%uB294%uB370%20Smart%20Contract%20%uC598%uAE30%uAC00%20%uB098%uC624%uB294%uAC00%20%uD560%20%uC218%uB3C4%20%uC788%uB2E4.%20%uC608%uC804%uBD80%uD130%20%uB9CE%uC740%20%uC0AC%uB78C%uB4E4%uC774%20%uC774%uBD80%uBD84%uC744%20%uD5F7%uAC08%uB824%20%uD55C%uB2E4%uB294%uAC78%20%uB290%uAF08%uB2E4.%20Multisig%20Wallet%20%uC740%20%uACB0%uAD6D%20**%uB0B4%uAC00%20%uC81C%uCD9C%uD55C%20Transaction%20%uC5D0%20%uB300%uD574%2C%20%uBBF8%uB9AC%20%uC9C0%uC815%uB41C%20%uBCF5%uC218%uC758%20Account%20Owner%20%uAC00%20%uC804%uC790%uC11C%uBA85%uC744%20%uD1B5%uD574%20%uD5C8%uB77D**%uD574%uC57C%uC9C0%uB9CC%20%uC2E4%uC81C%uB85C%20%uADF8%20Transaction%20%uC774%20%uC2E4%uD589%uB418%uC5B4%uC57C%20%uD558%uB294%20**%uADDC%uCE59**%20%uC774%uB2E4.%0A%0A%uC774%uB7EC%uD55C%20**%uADDC%uCE59**%uC740%20Wallet%20App%20%uC5D0%20%uAD6C%uD604%uB418%uACE0%20%uC800%uC7A5%uB418%uB294%20%uACBD%uC6B0%20%uCDA9%uBD84%uD788%20%uC704%uBCC0%uC870%20%uB420%20%uC218%20%uC788%uC73C%uBA70%20%uC911%uC694%uD55C%20%uB3C8%uAC70%uB798%uC758%20%uACBD%uC6B0%20%uBCF4%uC548%uC131%uACFC%20%uBC94%uC6A9%uC131%uC758%20%uCE21%uBA74%uC5D0%uC11C%20%uBB50%uD558%uB098%20%uC774%uB85C%uC6B8%uAC8C%20%uC5C6%uB2E4.%20%uADF8%20%uC598%uAE30%uB294%2C%20%uBE14%uB85D%uCCB4%uC778%20%uAE30%uC220%uACFC%20Smart%20Contract%20%uC758%20%uD544%uC694%uC131%uC774%20%uAC00%uC7A5%20%uAC15%uD55C%20%uD615%uD0DC%uC758%20dApp%20%uC911%20%uD558%uB098%uAC00%20%uBC14%uB85C%20Multisig%20Wallet%20%uC778%20%uAC83%uC774%uB2E4.%0A%0A%uC544%uB798%uC758%20Diagram%20%uC740%20Multisig%20Wallet%20%uC758%20%uB3D9%uC791%uC744%20%uB2E8%uC21C%uD654%20%uD574%uBCF8%20%uADF8%uB9BC%uC774%uB2E4%0A%uC0C1%uD669%uC740%200xa0c9...%20%uC8FC%uC18C%uB97C%20%uAC16%uB294%20EOA%20%uAC00%200x039b...%20%uC5D0%uAC8C%20100%20Ether%20%uB97C%20%uC774%uCCB4%uD558%uB824%uACE0%20%uD558%uBA70%2C%20%uC774%uB54C%20%uBBF8%uB9AC%20%uC9C0%uC815%uD55C%200x0248...%20EOA%20%uC758%20%uCD5C%uC885%20**%uC2B9%uC778**%20%uC774%20%uC788%uC5B4%uC57C%uC9C0%uB9CC%20%uC2E4%uC81C%uB85C%20100%20Ether%20%uAC00%200x039b...%20%uC5D0%uAC8C%20%uC774%uCCB4%uB418%uB294%20Transaction%20%uC774%20%uC2E4%uD589%uB418%uAC8C%20%uD574%uC57C%20%uD55C%uB2E4.%0A%0A%3Cimg%20src%3D%22./multisig01.png%22%20width%3D%22600%22%20/%3E%0A%0A%23%23%23%20%uAD6C%uC131%uC694%uC18C%0A-%20**Wallet**%20-%20Account%20%uC18C%uC720%uC790%uAC00%20%uC124%uCE58%uD55C%20Browser%20Plug-in%2C%20Desktop%2C%20Mobile%20%uC6A9%uC758%20Wallet%20App%20%28Metamask%2C%20MEW%2C%20Jaxx%2C%20Exodus%20...%29%20%20%uC774%uAC70%uB098%20Smart%20Contract%20%uC2E4%uD589%uC744%20%uC704%uD55C%20Message%20Transaction%20%uC744%20%uB9CC%uB4E4%uC5B4%uB0BC%20%uC218%20%uC788%uB294%20%uC5B4%uB5A0%uD55C%20dApp%20%uB3C4%20%uB420%20%uC218%20%uC788%uB2E4%0A-%20**Multisig%20Wallet%20Contract**%0A%09-%20%uC774%uCCB4%uD558%uACE0%uC790%20%uD558%uB294%20Token%20%uC744%20%uBCF4%uAD00%0A%09-%20%uC81C%uCD9C%20%uB41C%20Transaction%20%uC2E4%uD589%20%uC694%uAC74%20%uC9C0%uC815%20%28n%20of%20m%20%uAC1C%uC758%20%uC804%uC790%uC11C%uBA85%20%uC694%uAD6C%uC640%20%uAC19%uC740%29%0A%09-%20%uC804%uC790%uC11C%uBA85%20%uC8FC%uCCB4%uAC00%20%uB418%uB294%20Wallet%20Owner%20%uB4E4%uC758%20%uB4F1%uB85D%20%uBC0F%20%uAD00%uB9AC%0A%09-%20Transaction%20%uC81C%uCD9C%20%uC54C%uB9BC%0A%09-%20%uC694%uAC74%uC744%20%uB9CC%uC871%uD55C%20%uACBD%uC6B0%20Transaction%20%uC758%20%uC2E4%uC81C%20%uC2E4%uD589%0A%0A%3E%uC774%uC678%uC5D0%uB3C4%20Wallet%20%uC571%uC744%20%uAC1C%uBC1C%uD558%uACE0%20%uC11C%uBE44%uC2A4%20%uD558%uB294%20%uD68C%uC0AC%uC758%20%uACBD%uC6B0%2C%20%uC544%uBB34%uB098%20%uC790%uC2E0%uB4E4%uC774%20%uC6B4%uC601%uD558%uB294%20Node%20%uC5D0%20%uC218%uB9CE%uC740%20Transaction%20%uC744%20%uB0A0%uB824%20DoS%20Attack%20%uC744%20%uD558%uAC70%uB098%20%uBD80%uD558%uB97C%20%uC77C%uC73C%uD0A4%uC9C0%20%uC54A%uB3C4%uB85D%20%uD558%uACE0%20%uBD80%uAC00%uC801%uC778%20%uC11C%uBE44%uC2A4%uB97C%20%uC81C%uACF5%uD558%uAE30%uC704%uD55C%20%uBAA9%uC801%uC73C%uB85C%20Wallet%20Service%20Gateway%20%uB97C%20%uB458%20%uC218%uB3C4%20%uC788%uACA0%uC9C0%uB9CC%20Offchain%20%uC2DC%uC2A4%uD15C%uC740%20%uBAA8%uB450%20%uC0DD%uB7B5%uD558%uC600%uB2E4%0A%0A%uC704%20%uAD6C%uC131%uC694%uC18C%uC758%20%uC124%uBA85%uC744%20%uBCF4%uBA74%20%uC54C%uACA0%uC9C0%uB9CC%20%uD575%uC2EC%uC740%20**Multisig%20Wallet%20Contract**%20%uC774%uB2E4.%20Multisig%20Wallet%uC758%20%uBAA8%uB4E0%20%uD575%uC2EC%20%uAE30%uB2A5%uC740%20%uC774%20Contract%20%uC5D0%uC11C%20%uC774%uB8E8%uC5B4%uC9C4%uB2E4.%20%uC608%uC804%uC5D0%20%uBB38%uC81C%uAC00%20%uB41C%20Parity%20%uC758%20Multisig%20Wallet%20%uB3C4%20%uBB3C%uB860%20Smart%20Contract%20%uC774%uB2E4.%20%0A%0A%23%23%23%20%uD750%uB984%0A%uC704%20Multisig%20Wallet%20Contract%20%uB97C%20%uC0AC%uC6A9%uD558%uB294%20%uD750%uB984%uC744%20%uBCF4%uBA74%20%uAC04%uB2E8%uD558%uB2E4%20%uD558%uC9C0%uB9CC%20%uC774%uC804%20%uAE00%uC5D0%uC11C%uB294%20%uB2E4%uB8E8%uC9C0%20%uC54A%uC558%uB358%20%uC0C8%uB85C%uC6B4%20%uC694%uC18C%uAC00%20%uD558%uB098%20%uB4F1%uC7A5%uD55C%uB2E4%0A1.%20**submitTransaction**%20%0AsubmitTranaction%28%29%20%uC744%20%uC2E4%uD589%uD558%uAE30%20%uC704%uD55C%20Message%20Transaction%20%uC758%20Parameter%20%uB97C%20%uC774%uC6A9%uD558%uC5EC%20%uC2E4%uC81C%20Token%28Ether%29%20%uC744%20%uBC1B%uC744%20%uC8FC%uC18C%uB97C%20%uB123%uC5B4%uC900%uB2E4%0A%0A%20%uC774%uB54C%2C%20Token%20%uC744%20%uBC1B%uC744%20%uB300%uC0C1%uC774%20%uB2E4%uB978%20Smart%20Contract%20%uC774%uACE0%20Transaction%20%uC885%uB958%uAC00%20Message%20Transaction%20%uC778%20%uACBD%uC6B0%2C%20submitTransaction%28%29%20%uC758%20%uD30C%uB77C%uBBF8%uD130%20%uC911%20%uD558%uB098%uC5D0%20**%uC2E4%uD589%uD574%uC57C%20%uD558%uB294%20Smart%20Contract%20%uC758**%20Method%20%uC640%20%uD30C%uB77C%uBBF8%uD130%uB97C%20%uD3EC%uD568%uD558%uB294%20**Data%20Payload**%20%uB97C%20%uB123%uC5B4%uC900%uB2E4%20%28web3%20%uC758%20.getData%28%29%20%uC0AC%uC6A9%29%20%0A%0A%20%uCD94%uAC00%uC801%uC73C%uB85C%2C%20%uC608%uC758%uC0C1%20submitTransaction%28%29%20%uC774%20%uB418%uBA74%20Event%20%uB85C%20transaction%20%uC774%20submit%20%uB418%uC5C8%uB2E4%uACE0%20%uC54C%uB824%uC8FC%uB294%20%uC13C%uC2A4%20%uC815%uB3C4%uB294%20%uC124%uBA85%uD558%uC9C0%20%uC54A%uC544%uB3C4%20%uAD6C%uD604%20%uB418%uC5B4%uC57C%20%uD55C%uB2E4%uACE0%20%uB290%uB08C%uC774%20%uC62C%20%uAC83%uC774%uB2E4%0A%0A%3E%20%uC774%uBD80%uBD84%uC740%20%uAD6C%uD604%20%uBD80%uBD84%uC5D0%uC11C%20%uC124%uBA85%uD558%uACA0%uB2E4.%20%uD5A5%uD6C4%20CALL%2C%20CALLCODE%2C%20DELEGATECALL%20%uACFC%20%uAD00%uB828%20%uC788%uB294%20%uBD80%uBD84%uC774%uB2C8%20%uADF8%uB54C%20%uB610%20%uC124%uBA85%20%uD558%uACA0%uB2E4%20%28%uC74C..%20%uC624%uB79C%uB9CC%uC774%20%uC2DC%uC791%uD558%uB824%uB2C8%20%uC124%uBA85%uD560%uAC8C%20%uC0B0%uB354%uBBF8%uAC19%uB2E4..%29%0A%0A%0A2.%20**confirmTransaction**%0A%uC704%20submitTransaction%28%29%20%uC73C%uB85C%20%uC81C%uCD9C%20%uB41C%20Transaction%20%uC744%20**%uC2B9%uC778**%20%uD558%uB294%20%uB2E8%uACC4%uC774%uB2E4.%20Contract%20%uC5D0%20%uB4F1%uB85D%uB41C%20%uC2B9%uC778%20%uAD8C%uD55C%uC774%20%uC788%uB294%20EOA%20%uAC00%20confirmTransaction%28%29%20%uC744%20%uD1B5%uD574%20confirm%20%uD574%uC8FC%uBA74%20%uB41C%uB2E4.%20%uC774%uB54C%2C%20%uAC01%20confirm%20%uC2DC%20%uB9C8%uB2E4%20%uB4F1%uB85D%uB41C%20%uC870%uAC74%28%uCD5C%uC18C%20n%20%uAC1C%uC758%20confirm%20%uD544%uC694%29%uC744%20%uB9CC%uC871%uD558%uB294%20confirm%20%uC744%20%uBC1B%uC558%uB294%uC9C0%20check%20%uD55C%uB2E4%0A%0A3.%20**executeTransaction**%0AconfirmTransaction%28%29%20%uC2E4%uD589%20%uC2DC%20%uB9CC%uC871%uD558%uB294%20confirm%20%uC218%uAC00%20%uCC44%uC6CC%uC84C%uC73C%uBA74%20submitTransaction%28%29%20%uC2DC%uC5D0%20%uC81C%uCD9C%20%uB41C%20token%20%uC758%20%uC591%20%uB9CC%uD07C%uC744%20%uC6D0%uB798%20%uBCF4%uB0B4%uACE0%uC790%20%uD588%uB358%20%uC8FC%uC18C%uB85C%20%uBCF4%uB0B4%uC8FC%uB3C4%uB85D%20Transaction%20%uC758%20value%20%uAC12%uC744%20%uCC44%uC6B0%uBA70%2C%20submitTransaction%28%29%20%uB2E8%uACC4%uC5D0%uC11C%20%uC81C%uCD9C%20%uB41C%20Message%20Transaction%20%uC774%20%uC788%uC5C8%uB2E4%uBA74%20**Wallet%20Contract%20%uAC00%28msg.sender%20%3D%3D%20Wallet%20Contract%29**%20%uD574%uB2F9%20Message%20Transaction%20%uC744%20%uC2E4%uD589%uD55C%uB2E4%0A%0A%23%23%23%20Multisig%20%uC778%uB370%2C%20%uC11C%uBA85%uC740%20%uC5B8%uC81C%uD558%uB294%uAC00%3F%0A%uC804%uC5D0%20Multisig%20Wallet%20%uC5D0%20%uB300%uD574%20%uCC28%uBD84%uD788%20%uC124%uBA85%20%uD574%uC8FC%uACE0%20%uB098%uC11C%20%uB4E4%uC5C8%uB358%20%uC9C8%uBB38%uC774%20%uC788%uC5C8%uB2E4.%20**%22%uADF8%uB7F0%uB370%20%uB2E4%uB978%uC0AC%uB78C%uB4E4%28EOA%29%uC774%20%uC804%uC790%uC11C%uBA85%uC740%20%uC5B8%uC81C%20%uD574%uC918%uC694%3F%22**%20%uC804%uC790%uC11C%uBA85%uC740%20%uC774%uBBF8%20Smart%20Contract%20%uB97C%20%uC2E4%uD589%uD558%uB294%20submitTransaction%28%29%2C%20confirmTransaction%28%29%20%uB2E8%uACC4%uC5D0%uC11C%20Message%20Transaction%20%uC744%20%uBCF4%uB0B4%uAE30%20%uC704%uD574%20Raw%20Transaction%20%uC5D0%20%uB300%uACE0%20%uB2E4%20%uD588%uB2E4.%20%uADF8%uB798%uC57C%20Transaction%20%uC774%20submit%20%uB418%uC5C8%uC9C0%20%uC54A%uACA0%uB294%uAC00..%uC694..%20%uB77C%uACE0%20%uB2F5%uC744%20%uD574%uC92C%uB358%20%uAE30%uC5B5%uC774%20%uB09C%uB2E4.%0A%0A%28%uB2E8%2C%20Smart%20Contract%20%uC774%20internal%20call%20%uC744%20%uD558%uB294%20%uAD6C%uAC04%uC5D0%uB294%20%uC804%uC790%uC11C%uBA85%uC774%20%uB2F9%uC5F0%uD788%20%uC5C6%uB2E4.%20EOA%20%uC5D0%uC11C%20%uC774%uBBF8%20%uD588%uC9C0%uC54A%uC740%uAC00.%20Smart%20Contract%20%uB294%20%uC11C%uBA85%uD560%20%uC218%20%uC788%uB294%20%uB188%uC774%20%uC544%uB2C8%uB2E4.%20Smart%20Contract%20%uC744%20%uC2E4%uD589%uD55C%20%uB188%uC774%20%uC774%uBBF8%20%uC804%uC790%uC11C%uBA85%uC744%20%uD574%uC11C%20Message%20Transaction%20%uC744%20%uBCF4%uB0B8%20%uAC83%uC774%uB2E4%29%0A%0A%uC774%uB984%uC774%20%uBB38%uC81C%uB2E4.%20Multisig..%20%uC0AC%uC2E4%20confirmTransaction%28%29%20%uB2E8%uACC4%uC5D0%uC11C%20%uD30C%uB77C%uBBF8%uD130%uB85C%20%uBA54%uC2DC%uC9C0%uC640%20%uC804%uC790%uC11C%uBA85%uAC12%20r%2Cs%2Cv%20%uB97C%20%uB123%uC5B4%uC904%20%uC218%uB3C4%20%uC788%uB2E4.%20%uADF8%uB7EC%uB098%20%uB2E4%uB978%20EOA%20%uC758%20%uC804%uC790%uC11C%uBA85%uC744%20%uC804%uB2EC%uD558%uB294%20%uC0C1%uD669%uC774%20%uC544%uB2C8%uACE0%20**confirmTransaction%28%29%20%uC744%20%uC2E4%uD589%uD558%uB294%20%uC8FC%uCCB4%20%uC790%uCCB4%uAC00%20%uC2B9%uC778%20%uAD8C%uD55C%uC744%20%uAC00%uC9C4%20EOA%20%uC774%uBBC0%uB85C%20%uC774%uBBF8%20transaction%20%uB0B4%uC5D0%20%uB4E4%uC5B4%uC788%uB294%20%uC804%uC790%uC11C%uBA85%uC744%20Multisig%20Wallet%20Contract%20%uC758%20%uD30C%uB77C%uBBF8%uD130%uB85C%20%uBCF4%uB0BC%20%uC774%uC720%uAC00%20%uC5C6%uB294%20%uAC83**%uC774%uB2E4%0A%0A%21%5BAlt%20text%5D%28./1543506496329.png%29%0A%0A%0A%23%23%20%uB9C8%uCE58%uBA70%0A%uC624%uB79C%uB9CC%uC5D0%20%uC62C%uB9AC%uB294%20%uAE00%20%uCE58%uACE0%uB294%20%uB9E4%uC6B0%20%uAE30%uBCF8%uC801%uC778%20%uC8FC%uC81C%uB97C%20%uC62C%uB824%uBCF8%uB2E4.%20%uC0AC%uC2E4%200xProtocol%2C%20Plasma%2C%20Raiden%2C%20ERC20%20Token%20%uAE30%uBC18%uC73C%uB85C%20%uB3CC%uC544%uAC00%uB294%20dApp%20%uB9CC%uB4E4%uAE30%2C%20plasma-mvp%20...%20%uB610%uB294%20Enterprise%20Blockchain%2C%20Quorum%20%uB4F1%uB4F1%20%uBB34%uC5C7%uBD80%uD130%20%uC2DC%uC791%uD560%uAE4C%uB97C%20%uB9CE%uC774%20%uACE0%uBBFC%uD574%uBCF4%uC558%uB2E4.%0A%0A%uADF8%uB9AC%uACE0%20%uC774%uC804%uC5D0%20%uC62C%uB838%uB358%20%uAE00%uB4E4%uC744%20%uB2E4%uC2DC%20%uD6D1%uC5B4%uBCF4%uB2E4%uAC00%2C%20%uBE14%uB85C%uADF8%uC758%20%uD750%uB984%uC774%20%uAC11%uC790%uAE30%20%uB04A%uAE30%uB294%uAC83%20%uBCF4%uB2E4%uB294%20%uC774%uC804%uC758%20Context%20%uB97C%20%uC774%uC5B4%uB098%uC544%uAC00%uBA74%uC11C%20%uC880%uB354%20%uBE60%uB974%uAC8C%20%uC9C4%uD589%uD574%uBCF4%uB294%20%uAC83%uC73C%uB85C%20%uC77C%uB2E8%20%uB9C8%uC74C%uC744%20%uBA39%uC5B4%uBCF8%uB2E4.%20%28%uADF8%uB798%uB3C4%20%uAE30%uBCF8%uC740%20%uAE30%uBCF8%uB300%uB85C%20%uAC00%uACE0%2C%20%uC911%uAC04%uC911%uAC04%20%uBC1C%uD45C%uC790%uB8CC%uB3C4%20%uC880%20%uC62C%uB9AC%uACE0%2C%20%uC774%uB7F0%uC800%uB7F0%20%uAD6C%uD604%20%uC0D8%uD50C%uB4E4%uB3C4%20%uC9EC%uC9EC%uC774%20%uC62C%uB9AC%uACA0%uB2E4%5E%5E%3B%3B%29%0A%0A%uB2E4%uC74C%uC740%20Multisig%20Wallet%20%uAD6C%uD604%20%uC608%uC81C%uB97C%201%uD68C%20%uC815%uB3C4%20%uC62C%uB9AC%uACE0%20%uD035%uD558%uAC8C%20%uB9C8%uBB34%uB9AC%20%uD558%uACE0%20%uB610%20%uADF8%20%uB2E4%uC74C%uC73C%uB85C%20%uB118%uC5B4%uAC00%20%uBCF4%uB3C4%uB85D%20%uD558%uB294%uAC78%20%uBAA9%uD45C%uB85C%20%uD574%uBCF4%uACA0%uB2E4%0A%0A%23%23%20References%0Ahttps%3A//medium.com/haechi-labs/parity-multisig-wallet-%25EB%258F%2599%25EA%25B2%25B0%25EA%25B3%25BC-eip999-4dc303cd8e27%0A%0Ahttps%3A//medium.com/hellogold/ethereum-multi-signature-wallets-77ab926ab63b%0A


반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,