사랑하애오
article thumbnail

 

secp256k1 알고리즘

지갑을 생성하기 위해 쓰이는 암호화 알고리즘이다.

src/wallet.js

$ npm i elliptic

 

console.log를 찍어서 elliptic이 무엇인지 알아봅시다.

const ecdsa = require('elliptic')

console.log(ecdsa)

우리는 맨 아래에 ec function을 사용할 것입니다.

 

 

const ecdsa = require('elliptic')

const ec = ecdsa.ec('secp256k1')

console.log(ec)

무언가 내용이 많지만 우리는 이 내용을 한줄로 바꿔서 그 걸 사용할 것입니다.

 

const ecdsa = require('elliptic')

const ec = ecdsa.ec('secp256k1')

// 키 만들기
console.log(ec.genKeyPair().getPrivate().toString())

// 16진수 키 만들기
console.log(ec.genKeyPair().getPrivate().toString(16))

 

toString() -> 숫자로
toString(16) -> 16진수로

 

그럼 다음과 같이 길이가 줄어든 것을 알 수 있다. 여기서 ec.genKeyPair().getPrivate().toString(16)은 랜덤키값이다. SHA256 암호화와는 또 다른 개념이다. SHA256은 특정 내용을 복호화가 안되는 단방향으로 암호화하는 반면 이건 로또처럼 랜덤으로 암호화한 키값을 반환해주는 것이다.

그래서 중복의 위험성이 있다. 그래서 그 문제를 해결하기 위해서 0과 1로 이루어진 256비트짜리를 만든다. 그러면 같은 키가 만들어질 확률이 로 줄어든다.

이 지갑 주소는 data베이스로 따지면 id와 같은 기능을 한다.

블록체인은 database로 정보를 저장할 수도 있지만 파일로 데이터를 관리하는 것또한 가능하다.

 

 

 wallet 폴더와 파일 만들기

 

이제 본격적으로 wallet 만들어봅시다.

wallet이라는 폴더가 생성되어있는지 확인 > 없으면 만든다.
wallet 폴더안에 default 폴더가 있는지 확인 > 없으면 만든다.
deafult 폴더 안에 private_key 파일이 있는 확인 > 없으면 만든다.

 

fs 내장객체 가져오기

const ecdsa = require('elliptic')
const ec = ecdsa.ec("secp256k1")
const fs = require('fs')

 

const privateKeyLocation = "wallet/"+( process.env.PRIVATE_KEY || "default"
const privateFile = `${privateKeyLocation}/private_key`
                                      
function initWallet(){
    if(!fs.existsSync('wallet/')){
            fs.mkdirSync("wallet/")
    }
    if(!fs.existsSync(privateKeyLocation)){
            fs.mkdirSync(privateKeyLocation)
    }
    if(!fs.existsSync(privateFile)){
        //파일이 없다면 true이고 있으면 false임
        console.log(`주소값 키값을 생성중입니다.`)
        const newPrivateKey = generatorPrivateKey()
        fs.writeFileSync(privateFile,newPrivateKey)
        //첫번째 인자값은 경로+파일명, 넣을 내용들
        console.log(`개인키 생성이 완료되었습니다.`)
        
        fs.mkdirSync(privateKeyLocation)
    }
    
}

fs.existSync('폴더나 파일')은 폴더나 파일이 존재하는지 안하는지 알려주는 함수이다. 폴더나 파일이 존재하면 true값을 반환하고 존재하지 않으면 false값을 반환한다.
fs.mkdirSync('폴더')는 폴더를 만들어주는 함수이다.
fs.writeFileSync('경로+파일명','파일에 들어갈 내용)는 파일을 만들고 그 안에 내용도 넣어주는 함수이다. 첫번째 인잣값으로는 '경로+파일명'을 넣고, 두번째 인잣값으로는 '파일 내용'을 넣는다.
여기서 넣는 파일 내용은 비밀키(인증서)내용이다.

함수를 실행하니 wallet이라는 폴더가 만들어지고 그 안에 default라는 폴더가 생겨났다. 그리고 그 폴더에 private_key라는 파일이 생겨났다.

 

 

비밀키(인증서) 출력하는 함수

 

공개키와 비밀키를 만들 수 있는데 보통은 비밀키를 조작해서 공개키를 만드는 과정으로 진행한다. 지금 작성하는 코드는 컴퓨터를 사용해서 복호화가 가능하게끔 하는 코드이지만 원래는 복호화가 안되게 하는게 맞다.

아래의 함수는 비밀키를 출력해주는 코드이다.

function getPrivateFromWallet(){
    const buffer = fs.readFileSync(privateFile)
    //console.log(buffer.toString())//toString()붙이면 우리가 알아들을 수 있는 결과물로 출력한다.
    return buffer.toString()
}

fs.readFileSync(파일명)은 파일 안의 내용을 출력해주는 역할을 한다.
여기서 우리가 만든 파일의 내용을 txt로 인식하지 않는다. 그래서 buffer형태로 출력해준다.

그래서 꼭 toString()을 써주도록 하자.

 

server.js를 통해 url을 치면 공개키를 출력하는 함수를 만들기

 

server.js

wallet 가져오기 

const express = require('express')
const app = express()
const port = process.env.PORT || 3001
const bodyParser = require('body-parser')
const bc = require('./block.js')
const ws = require('./network.js')
const wl = require('./wallet')                  //추가

폴더, 파일, 파일 안 키값 생성하기 위해 initWallet() 실행 

wl.initWallet()
ws.wsInit()
app.listen(port,()=>{
    console.log(`server start port ${port}`)
})

get address 만들기 

app.get('/address', (req,res)=>{
    const address = wl.getPublicFromWallet()
    res.send({address})
})

windows Terminal 에서 확인

curl http://localhost:3001/address | python3 -m json.tool

 

친절한 성현씨의 wallet.js 전체코드

//wallet.js

//secp256k1
//npm i elliptic

const ecdsa = require('elliptic');
const ec = ecdsa.ec("secp256k1")
// console.log(ec)

// //키를 만드는 방법
// console.log(ec.genKeyPair())
// console.log(ec.genKeyPair().getPrivate().toString(16))

function generatorPrivateKey() {
  //랜덤하게 글자를 만들어주는 행위임.
  const KeyPair = ec.genKeyPair()
  const privateKey = KeyPair.getPrivate()
  return privateKey.toString(16).toUpperCase()
}

console.log(generatorPrivateKey())

const fs = require('fs')//내장객체
const privateKeyLocation = "wallet/" + (process.env.PRIVATE_KEY || "default")//환경변수 사용
//파일명
// const privateFile = privateKeyLocation + "/private_key"
const privateFile = `${privateKeyLocation}/private_key`

function initWallet() {
  //console.log(fs.existsSync('wallet/'))
  //true false 반환함
  if (!fs.existsSync('wallet/')) {
    //폴더를 생성하는 코드를 작성해주면 된다.
    fs.mkdirSync("wallet/")
  }
  if (!fs.existsSync(privateKeyLocation)) {
    //폴더를 생성하는 코드를 작성해주면 된다.
    fs.mkdirSync(privateKeyLocation)
  }
  if (!fs.existsSync(privateFile)) {
    //파일이 없다면 true이고 있으면 false임
    console.log(`주소값 키값을 생성중입니다.`)
    const newPrivateKey = generatorPrivateKey()
    fs.writeFileSync(privateFile, newPrivateKey)
    //첫번째 인자값은 경로+파일명, 넣을 내용들
    console.log(`개인키 생성이 완료되었습니다.`)

    fs.mkdirSync(privateKeyLocation)
  }

}
initWallet()

//파일을 읽어서 출력해주느 함수 만들기
function getPrivateFromWallet() {
  const buffer = fs.readFileSync(privateFile)
  //console.log(buffer.toString())//toString()붙이면 우리가 알아들을 수 있는 결과물로 출력한다.
  return buffer.toString()
}

getPrivateFromWallet()

//공개키(지갑주소) 
// 비밀키(transaction)인증서라고 생각하면 편함

//비밀키를 조작해서 공개키를 만드는 과정을 만듦. 컴퓨터를 사용해서 복호화 가능하게 함 
//근데 원래 복호화가 안되도록 하는게 맞음.


function getPublicFromWallet() {
  const privateKey = getPrivateFromWallet();
  const key = ec.keyFromPrivate(privateKey, "hex")
  return key.getPublic().encode("hex")
}

console.log(getPublicFromWallet())
console.log('--------------')
console.log(getPrivateFromWallet())

//AWS pem도 비슷한 인증방식임. RSA인증방식

module.exports = {
  initWallet,
  getPrivateFromWallet,

}

 

정상수처럼 정상적으로 지갑이 생성되고 확인이 되는 것을 확인하였습니다. 섹보빠>.<

profile

사랑하애오

@사랑하애

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!