dukDukz
[블록체인] 지갑 만들기 본문
[wallet.js] 생성
# secp256k1
이거를 쓴다... 상세한 내용은 블로그에서 알아보는게 좋을 것 같다.
사용방법만.. 알아보자
기본적으로 얘는 알고리즘 암호화다.
그래서 저 암호화를 사용하려면 패키지가 하나 필요한데,
그게 바로 elliptic 이다.
$ npm install elliptic
가져오자
const ecdsa = require('elliptic')
console.log(ecdsa);
ecdsa 를 한번 찍어보자
색을 보니 class 는 절대 아님
찍어보니 긴 객체가 나오는데
일단은 이 안에 있는 ec 라는 애를 사용할거임
그래서 사용방법이
const ec = ecdsa.ec("secp256k1") // 암호화 방법은 secp256k1
console.log(ec);
ec 를 찍어보니 긴 객체가 쭉 나온다.
이제 ec 라는 애가 갖고 있는 속성값을 사용해서 어떤걸 만들어낼 수 있는지 봐야함
1. key 만들기
console.log(ec.genKeyPair());
하면
KeyPair {
ec: EC {
...
}
이런 객체가 나온다.
console.log(ec.genKeyPair().getPrivate());
이렇게 하면 바이너리 파일이 나온다.
words : [숫자들..] 이 있으면
.toString(16)
이렇게 바꾸면 16진수로 바뀜
.toUpperCase()
여기 까지하면 대문자로
console.log(ec.genKeyPair().getPrivate().toString(16).toUpperCase());
지금 키값을 생성한거면
렌덤 키값을 생성한거임
sha256 으로 암호화를 진행했는데 얘는 기본적으로 복화화가 안되는 단방향 암호화임
하지만 이번에 생성한 암호화는 렌덤한 글자 스트링들을 우리한테 반환해주는거임
그런데 렌덤하게 하다보면 중복될 수 있는 가능성은 없는가?
예를 들어 동전 던지기를 256번한다
앞면 0 뒷면 1
이걸 256번
256bit
경우의 수가 2^256 = 10^77 정도가 되어서 렌덤 생성으로 인해 중복될 가능성은 희박하다.
정리
주로 블록체인에서 쓰는 암호화는 secp256k1 이거라고 한다.
렌덤한 키 값을 생성하기 위해서 secp256k1 이거를 썼고
console.log(ec.genKeyPair().getPrivate().toString(16).toUpperCase());
이렇게 쓰면 16진수로 반환이 되는 키값을 생성할 수 있다.
2. key 생성 함수 만들기
// key 생성하는 함수
function generatorPrivateKey(){
const KeyPair = ec.genKeyPair()
const privateKey = KeyPair.getPrivate()
return privateKey.toString(16).toUpperCase()
}
console.log(generatorPrivateKey());
단순히 키를 생성한거고 아무런 의미는 없다..
지갑이라는 뜻은 무언가를 넣는 공간.
db 로 치면
id 값이 key 값이라는것이다.
content
date
그래서 id 누구의 content 를 찾고 싶다면 볼 수 있듯이
지갑의 history 를 볼 수 있도록 해야한다.
3. 지갑 만들기 기본 작업
const fs = require('fs')
이걸 추가
db를 사용하는 이유? - 파일로만 관리하기 힘들어서..
코인은 다시 옛날로 돌아가서 파일로 관리한다고 보면 된다.
뭔가 저장하는 곳(=파일) 이 필요함
내가 생성한 블럭에 코인이라는게 있을텐데
그 생성한 내용을 지갑에 담아서 내용을 볼 수 있게 해준다.
랜덤생성을 하면, 그 사람의 지갑 주소를 실행할때마다 다르게 보여준다. -> 이건 지갑이 아니다.
주소값이 항상 같아야함
그래서 렌덤생성한 값을 파일에 저장해줘야 한다는 것.
최종 목표 :
node server.js 가 실행되면 특정 폴더에 특정 파일에
키 값이 나올 수 있도록 할 것이다.
keyfile을 저장함
node server.js 를 하면
http 인터페이스를 통해서 3000번에 /address 로 요청하게 되면 (http://localhost:3000/address)
키값(generatorPrivateKey)을 보여줄 수 있도록 해줄 것이다. <- keyfile을 읽어서 보여줌
4. 키 값이 저장될 폴더 생성하기
node server.js 했는데
특정폴더 = wallet
하나의 변수라고 생각하고
wallet이 있는지 -> fs.existsSync("wallet/")
있으면 wallet/ 생성 안함
없으면 wallet/ 폴더 생성함
mkdir 로 생성 (찾을 수도 있고 만들 수도 있음)
구현해보자!
const fs = require('fs')
const privateKeyLocation = "wallet/"+(process.env.PRIVATE_KEY || "default")
const privateFile = `${privateKeyLocation}/private_key`
function initWallet() {
if (!fs.existsSync("wallet/")) { // 값이 true 여야 if 문이 실행되니까 앞에 ! 붙여줌
fs.mkdirSync("wallet/") // 폴더를 생성해준다.
}
if(!fs.existsSync(privateKeyLocation)){
fs.mkdirSync(privateKeyLocation)
}
// 파일이 있는가 없는가를 체크해봐야함
if(!fs.existsSync(privateFile)){
// 디렉토리를 만드는게 아니라서 mkdirSync 가 필요없음
console.log(`주소값 키값을 생성중입니다...`);
const newPrivateKey = generatorPrivateKey() //key 를 생성해서 변수에 담음
// 파일 생성
fs.writeFileSync(privateFile,newPrivateKey)
// 첫번째 인자값은 경로+파일명, 두번째 인자값은 파일 내용들
console.log(`개인 키 생성이 완료되었습니다`);
}
}
initWallet()
파일을 읽어서 갖다 쓰는것도 해놔야함
파일을 읽는데 읽는 순간 우리가 알 수 없는 언어로 읽게 됨
그래서 잘라서 읽기를 시도함
// 저 파일을 읽어서 출력하는 함수
function getPrivateFromWallet(){
// 파일을 읽어서 가져와서 buffer 에 넣을거임
const buffer = fs.readFileSync(privateFile)
// 첫번째 인자값은 경로+파일명
//console.log(buffer.toString()); // 알 수 없는 Buffer ~ 형태로 가져옴
return buffer.toString()
}
getPrivateFromWallet()
console.log(getPrivateFromWallet());
5. 비밀키를 이용해서 공개키 만들기
블록체인에는 키가 두개 존재함
공개키 와 비밀키
내가 나임을 증명하는 것은 비밀키로 인증
비밀키는 공개되면 내 지갑을 해킹할 수 있음..(특별한 권한까지 다 있는 키-공인인증서)
공개 키는 내 히스토리 정도만 다 보낼 수 있음 (계좌번호)
비밀 키를 갖고 내용 조작해서 공개키를 만드는 경우가 대부분이다.
function getPublicFromWallet(){
const privateKey = getPrivateFromWallet() // 일단 비밀키를 가져오고
const key = ec.keyFromPrivate(privateKey,"hex") // ec 안에 있는 내장함수 keyFromPrivate()
return key.getPublic().encode("hex") // ec 안에 있는 내장함수 getPublic()
}
console.log(getPublicFromWallet());
module.exports = {
initWallet,
getPublicFromWallet,
}
이렇게 내보내고 사용해보자
[server.js]
const wl = require('./wallet')
app.get('/address',(req,res)=>{
const address = wl.getPublicFromWallet()
res.send({address})
})
맨 아래로 가서
wl.initWallet() // 저함수가 실행되면 파일, 키값 생성
추가해줌
$ node server
팽귄에서
$ curl http://localhost:3000/address
하면
{
"address": "04afd5d3486de820dd40ffb24437c369c676f2f799bf8dcf04c9ec8dfe22fd2ef38b167055de22c99cde26f63e9918aae8e5292fd90b2ca6089724d490fc7aa04b"
}
이런게 나온다.
'웹 개발 > 블록체인' 카테고리의 다른 글
[블록체인] 용어들 [메인넷/테스트넷 , 메타마스크, 코인과 토큰, ERC 20과 ERC-721] (0) | 2021.09.09 |
---|---|
[블록체인] 추가 개념 (0) | 2021.09.09 |
[블록체인] 작업증명 / 난이도 조절 (0) | 2021.09.08 |
[블록체인] 남의 서버에 연결 및 데이터 추가 (0) | 2021.09.07 |
[블록체인] network.js 상세설명 (0) | 2021.09.07 |