이제 아래 녀석들을 이용해서 간단한 니모닉 지갑을 개발해보자.
과정은 다음 순서대로 해보겠다.
- 서버 구성 (react)
- 니모닉 및 지갑주소 API 작성
- 테스트 및 결과 정리
react 를 사용하여 결과를 테스트할 것이기 때문에 먼저 react 프로젝트를 생성한다. 나는 프로젝트명을
my-mnemonic-app
으로 하겠다.
npx create-react-app my-mnemonic-app
cd my-mnemonic-app
npm install next --save
create-react-app 을 이용하여 react 애플리케이션 프로젝트를 생성한다. next 모듈은 React 어플리케이션의 서버사이드렌더링(SSR)을 쉽게 구현할 수 있게 도와주는 프레임워크이다. 우리의 목표는 블록체인이니 관련 내용은 생략한다.
1-1. src/App.js
1-2. src/component/RequestMnemonicForm.js
1-3. src/Mnemonic.js
1-4. src/component/RequestAccount.js
1-5. src/Account.js
모든 내용을 App.js 에 담을 수 있지만, 그 동안 공부한 react 도 복습할 겸 굳이 view component 를 나누었읍니다..
App.js 에서 각 화면을 분기하였다. 참고로 완성되는 화면은 다음과 같다.
좋다 지금부터 파일을 하나씩 작성해보자.
다음과 같이 App.js 를 작성한다.
// App.js
import lightwallet from 'eth-lightwallet';
import Head from 'next/head'
import { useState } from 'react'
import RequestMnemonicForm from './component/RequestMnemonicForm'
import RequestAccountForm from './component/RequestAccountForm'
import Mnemonic from './component/Mnemonic'
import Account from './component/Account'
export default function App() {
// 니모닉 및 지갑주소 결과값 저장
const [mnemonicResult, setMnemonicResult] = useState();
const [accountResult, setAccountResult] = useState();
const requestMnemonic = () => {
// 니모닉 요청
// TODO : 다음 블로그에서 작성
}
const requestAccount = (mne, pwd) => {
// 지갑주소 요청
// TODO : 다음 블로그에서 작성
}
return (
<div>
<Head>
<title>코드스테이츠 BEB_01_박지헌 니모닉 지갑 만들기</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<h1>
코드스테이츠 BEB_01_박지헌 니모닉 지갑 만들기
</h1>
<div id="mnemonic-container">
<RequestMnemonicForm requestMnemonic={ requestMnemonic } />
<Mnemonic result={mnemonicResult} />
</div>
<div>
<RequestAccountForm requestAccount={ requestAccount }/>
<Account result={accountResult} />
</div>
</main>
</div>
)
}
리엑트(react) 내용은 다루지 않겠으니 간단히 필요한 부분만 정리하면,
import lightwallet from 'eth-lightwallet';
니모닉 및 지갑주소 생성을 위한 암호화 모듈로, 우리는 eth-lightwallet module 을 사용한다.
const [mnemonicResult, setMnemonicResult] = useState();
const [accountResult, setAccountResult] = useState();
니모닉 혹은 지갑주소를 생성하면 그 결과를 위 state 에 저장한다. 결과가 ajax 방식으로 화면에 보여지도록 한 것이다.
const requestMnemonic = () => {
// 니모닉 요청
// TODO : 다음 블로그에서 작성
}
const requestAccount = (mne, pwd) => {
// 지갑주소 요청
// TODO : 다음 블로그에서 작성
}
두 함수는 다음 블로깅에서 다룬다. 버튼(Button) 이벤트가 발생할 때 실행될 예정이다. 더 간결한 코드를 짜기 위해서는 두 함수 안에 들어갈 API 를 별도의 파일로 구성하는 것이 좋다. 이 블로깅에서는 파일을 나누면 더 헷갈릴 것 같아 그냥 App.js 에 모두 담는다.
// src/component/RequestMnemonicForm.js
function RequestMnemonicForm({ requestMnemonic }) {
const handleRequestClick = () => {
requestMnemonic();
}
return <fieldset>
<legend>랜덤 니모닉 코드 생성</legend>
<button onClick={handleRequestClick}>니모닉 생성 요청</button>
</fieldset>
}
export default RequestMnemonicForm
버튼을 클릭하면 App.js 의 requestMnemonic 함수를 실행한다.
니모닉 생성에는 별도의 인자가 필요하지 않다. 니모닉 영단어 12개는 random 하게 생성된다.
function Mnemonic({ result }) {
return <div className="row">
{ (result) ?
<div className="col">
<h3>생성 결과 : {result}</h3>
</div> : null }
</div>
}
export default Mnemonic;
만약 state 에 니모닉 결과가 업데이트되고 결과값이 존재하면 이 코드를 통해 결과값을 화면에 뿌려준다.
import { useState } from 'react'
function RequestAccountForm({ requestAccount }) {
const [inputMnemonic, setInputMnemonic] = useState('')
const [inputPwd, setInputPwd] = useState('')
const handleChangeMne = (e) => {
setInputMnemonic(e.target.value)
}
const handleChangePwd = (e) => {
setInputPwd(e.target.value)
}
const handleRequestClick = () => {
requestAccount(inputMnemonic, inputPwd);
}
return <fieldset id="request-account-container">
<legend>새 지갑주소 생성</legend>
<div>
<textarea id="textarea-mne" value={inputMnemonic} onChange={handleChangeMne} placeholder="니모닉 코드 입력" />
</div>
<div>
<input type="text" value={inputPwd} onChange={handleChangePwd} placeholder="임의 패스워드 입력" />
</div>
<p>
<button id="request-btn" onClick={handleRequestClick}>지갑 생성 요청</button>
</p>
</fieldset>
}
export default RequestAccountForm
지갑주소를 생성하기 위해서는 두 가지 인자가 필요하다.
- 니모닉 코드
- 임의의 패스워드
앞 블로그에서 HD Wallet 은 지갑주소 생성을 위해 Seed 가 필요하다고 하였다. 그리고 그 Seed 는 니모닉 코드를 통해 생성된다.
또한 임의의 패스워드를 입력하게 되는데, 이는 해시 생성 시 Salt 로 활용되는 것 같다.
버튼을 클릭하면 두 input 인자를 App.js 의 requestAccount 함수에 전달하여 실행하게 되는 코드다.
function Account({ result }) {
return <div>
{ (result) ?
<div>
<h3>지갑주소(공개키) : {result.address}</h3>
<p>Keystore : {result.keystore}</p>
</div> : null }
</div>
}
export default Account;
지갑주소 생성을 요청 후 그 결과값이 state 에 담기면 이 코드는 실행된다.
지갑주소를 생성하면 address 와 keystore 값을 json 으로 return 하도록 다음 블로그에서 API 를 개발할 것이다.
여기까지 완료되었다면 애플리케이션을 실행해 보자.
npm start
http://localhost:3000 에 웹브라우저로 접속하면 아래와 같은 화면이 보여야 정상이다.
오케이!! 지금까지 짠 코드는 단순이 사용자 인터페이스 react 를 짠 것이다. 다음 볼르그에서는 이 애플리케이션이 실제로 동작하도록 니모닉 & 지갑주소 요청 API 를 개발해보자~!!
App.js 의 requesetMnemonic() 과 requestAccount() 함수만 짜면 완성이니 좀 더 힘내 보겠읍니다!!