블롴체인 개념 설명
- 네트워크 (http, socket..)
- 분산원장 (데이터를 저장하는 코드)
- hash sha 256 -> JWT
- 단반향 암호화 ( 자리수는 고정되어 있다.)
- 머클 (Merkle)
- 작업증명 (pow) = 마이닝
Merkle 사용 이유 : 너무 많은 노드(블록)들을 찾기에 리소스의 낭비가 크고 효율성이 떨어짐 (완전탐색) => merkle 사용으로 연결된 데이터 중 찾고자하는 데이터를 효율적으로 찾을 수 있음.
이제 위의 내용대로 하나하나 만들어보기
1) version 가져오기
src 폴더 생성
src 폴더 cd 들어가기 전, (src의 상위 폴더 경로에서) 아래 명령어 실행
npm init
src > block.js 생성
package.json 파일을 불러와서 console.log 찍어보기
// file system package
const fs = require('fs')
function getVersion(){
const package = fs.readFileSync("../package.json")
console.log('package=',package.toString('utf8'))
}
getVersion()
toString('utf8') 이 없으면 binary 형태로 나옴
// file system package
const fs = require('fs')
function getVersion(){
const package = fs.readFileSync("../package.json")
// console.log('package=',package.toString('utf8'))
console.log('JSON.parse(package)=',JSON.parse(package))
console.log('JSON.parse(package) version=',JSON.parse(package).version)
}
getVersion()
↓↓↓
// file system package
const fs = require('fs')
function getVersion(){
const {version} = JSON.parse(fs.readFileSync("../package.json"))
console.log(version)
return version
}
getVersion()
2) timestamp (유닉스 기준일 1970년 1월 1일)
// file system package
const fs = require('fs')
function getVersion(){
const {version} = JSON.parse(fs.readFileSync("../package.json"))
// console.log('package=',package.toString('utf8'))
// console.log('JSON.parse(package)=',JSON.parse(package))
// console.log('JSON.parse(package) version=',JSON.parse(package).version)
console.log(version)
return version
}
function getCurrentTime(){
console.log( new Date())
}
getCurrentTime()
getVersion()
현재 날짜를 시간으로 바꿔주기 = .getTime()
function getCurrentTime(){
console.log( new Date().getTime())
}
getCurrentTime()
console.log( new Date().getTime()/1000) // 1000으로 나누기
return Math.ceil(new Date().getTime()/1000) // 올리기
시간 구하기 끝
3) Merkle
sha 256, merkel을 만드는 package 설치 (경로 : src)
npm i merkletreejs crypto-js
src > merkle.js 파일 생성 + 위에서 가져온 packages 가져오기
const { MerkleTree } = require('merkletreejs')
const SHA256 = require('crypto-js/sha256')
이제 sha256 사용하기
const { MerkleTree } = require('merkletreejs')
const SHA256 = require('crypto-js/sha256')
// SHA256 은 함수 (노랑색!)
//
console.log( SHA256('emily'))
node merkle
text로 만들어주기 .toStirng() 만 붙여주기
console.log( SHA256('emily').toString())
여기까지 sha256를 string으로 암호화 한 것 !
이제 배열로 만들 것 (a,b,c를 배열에 담아 암호화 ) 각각 256암호화 해서 배열에 넣기
const { MerkleTree } = require('merkletreejs')
const SHA256 = require('crypto-js/sha256')
// SHA256 은 함수 (노랑색!)
console.log( SHA256('emily').toString())
const testSet = ['a','b','c'].map((v)=>SHA256(v))
console.log(testSet)
a,b,c 를 머클에 적용해보기
const { MerkleTree } = require('merkletreejs')
const SHA256 = require('crypto-js/sha256')
// SHA256 은 함수 (노랑색!)
console.log( SHA256('emily').toString())
const testSet = ['a','b','c'].map((v)=>SHA256(v))
console.log(testSet)
const tree = new MerkleTree(testSet, SHA256)
console.log(tree)
Merkle에는 최상위 노드 (root)를 가져오는 매서드가 있음 !
const { MerkleTree } = require('merkletreejs')
const SHA256 = require('crypto-js/sha256')
// SHA256 은 함수 (노랑색!)
console.log( SHA256('emily').toString())
const testSet = ['a','b','c'].map((v)=>SHA256(v))
console.log(testSet)
const tree = new MerkleTree(testSet, SHA256)
console.log(tree)
const root = tree.getRoot()
console.log('root=',root)
tree.getRoot().toString() 도 안되고 toString('utf8')도 안됌 !
const root = tree.getRoot().toString('hex')
console.log('root=',root)
const { MerkleTree } = require('merkletreejs')
const SHA256 = require('crypto-js/sha256')
// SHA256 은 함수 (노랑색!)
console.log( SHA256('emily').toString())
const testSet = ['a','b','c'].map((v)=>SHA256(v))
console.log(testSet)
const tree = new MerkleTree(testSet, SHA256)
console.log(tree)
const root = tree.getRoot().toString('hex')
console.log('root=',root)
const testRoot = 'a'
const leaf = SHA256(testRoot)
// 첫번째 인자값 : 우리가 찾을 sha256 값
const proof = tree.getProof(leaf)
console.log(tree.verify(proof,leaf, root))
= >
npm install merkle
src > block.js 에 merkle & crypoJS 가져오기
Header
BlockHeader Class 사용해서 만들기 (붕어빵 틀 만들기)
// file system package
const fs = require('fs')
const merkle = require('merkle')
const cryptoJs = require('crypto-js')
// 암호화할 방법 넣어주기
// sync 배열만 가능
//const tree = merkle("sha256").sync([]) //tree 구조
//tree.root()
class BlockHeader {
// Header를 만들 인자값 5개 받기
constructor(version, index, previousHash, time, merkleRoot){
// 현재 클래스의 version, index, hash, time, merkle은 내가 받은 값으로 하겠다.
this.version = version
this.index = index
this.previousHash = previousHash
this.time = time
this.merkleRoot = merkleRoot
}
}
const header = new BlockHeader(1,2,3,4,5)
console.log('header=',header)
Block 이라는 class BlockHeader 사용해서 만들기
// file system package
const fs = require('fs')
const merkle = require('merkle')
const cryptoJs = require('crypto-js')
// 암호화할 방법 넣어주기
// sync 배열만 가능
//const tree = merkle("sha256").sync([]) //tree 구조
//tree.root()
class BlockHeader {
// Header를 만들 인자값 5개 받기
constructor(version, index, previousHash, time, merkleRoot){
// 현재 클래스의 version, index, hash, time, merkle은 내가 받은 값으로 하겠다.
this.version = version
this.index = index
this.previousHash = previousHash
this.time = time
this.merkleRoot = merkleRoot
}
}
class Block {
constructor(header,body){
this.header = header
this.body = body
}
}
const blockchain = new Block(new BlockHeader(1,2,3,4,5), ['hello'])
console.log('blockchain=',blockchain)
여기에 제대로 된 정보들만 넣으면 요 block이 최초의 제네시스 블록
이제 제네시스 블록을 만드는 함수 만들기
// file system package
const fs = require('fs')
const merkle = require('merkle')
const cryptoJs = require('crypto-js')
// 암호화할 방법 넣어주기
// sync 배열만 가능
//const tree = merkle("sha256").sync([]) //tree 구조
//tree.root()
class BlockHeader {
// Header를 만들 인자값 5개 받기
constructor(version, index, previousHash, time, merkleRoot){
// 현재 클래스의 version, index, hash, time, merkle은 내가 받은 값으로 하겠다.
this.version = version
this.index = index
this.previousHash = previousHash
this.time = time
this.merkleRoot = merkleRoot
}
}
class Block {
constructor(header,body){
this.header = header
this.body = body
}
}
function createGenesisBlock(){
// header 만들기 - 5개의 인자값이 필요해! version, index, hash, time, merkle..
const version = getVersion();
const time = getCurrentTime();
const index = 0 // 제네시스 블록은 index=0으로 설정 (최초의 블록이라 우리가 직접 하드코딩)
const previousHash = '0'.repeat(64) // 제네시스 블록은 이전 hash가 없으므로 자리수만 0으로 맞춰서 제공
// body는 배열 형태로
const body = ['hello block']
// body를 가지고 merkletree 값을 구성하기
const tree = merkle('sha256').sync(body)
const root = tree.root() || '0'.repeat(64) // ||사용해서 예외처리
// header 완성시키기
const header = new BlockHeader(version, index, previousHash, time, root)
console.log(header)
console.log('asdf',new Block(header,body))
// header 만들어진 결과 가지고 block class에 넣어주기
return new Block(header,body)
}
const BBLOCKK = createGenesisBlock()
console.log('completed', BBLOCKK)
function getVersion(){
const {version} = JSON.parse(fs.readFileSync("../package.json"))
// console.log('package=',package.toString('utf8'))
// console.log('JSON.parse(package)=',JSON.parse(package))
// console.log('JSON.parse(package) version=',JSON.parse(package).version)
return version
}
function getCurrentTime(){
return Math.ceil(new Date().getTime()/1000)
}
다음 사용자 / 블록이 생길 때
블록을 생성할 때마다 -> 배열에 넣기
전역변수로 배열 만들기
블록을 추가해주는 구조 간단히 틀만
마지막 블록 가져오기
let Blocks = [createGenesisBlock()]
function getLastBlock() {
return Blocks[Blocks.length - 1]
}
전체 코드 (교수님 코드)
const fs = require('fs')
const merkle = require('merkle')
const CryptoJs = require('crypto-js')
const { runInThisContext } = require('vm')
/* 사용법 */
// const tree = merkle("sha256").sync([]) // tree 구조
// tree.root()
class BlockHeader {
constructor(version ,index ,previousHash, time, merkleRoot){
this.version = version
this.index = index // 포인트
this.previousHash = previousHash // 마지막 블럭 -> header -> string 연결 -> SHA256
this.time = time //
this.merkleRoot = merkleRoot
}
}
class Block {
constructor(header,body){
this.header = header
this.body = body
}
}
let Blocks = [createGenesisBlock()]
function getBlocks(){
return Blocks
}
function getLastBlock() {
return Blocks[Blocks.length - 1]
}
function createGenesisBlock(){
// 1. header 만들기
// 5개의 인자값을 만들어야되여.
const version = getVersion() // 1.0.0
const index = 0
const time = getCurrentTime()
const previousHash = '0'.repeat(64)
const body = ['hello block']
const tree = merkle('sha256').sync(body)
const root = tree.root() || '0'.repeat(64)
const header = new BlockHeader(version,index,previousHash,time,root)
return new Block(header,body)
}
function addBlock(){
// new header -> new block ( header , body)
}
function getVersion(){
const {version} = JSON.parse(fs.readFileSync("../package.json"))
return version
}
function getCurrentTime(){
return Math.ceil(new Date().getTime()/1000)
}
// class
// { header body } 1차 목표는 제네시스 블럭을 만드는것
console.log(Blocks)
'블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기' 카테고리의 다른 글
[117일차 복습] 블록체인 제네시스 블록 만들기 with JavaScript (0) | 2021.09.01 |
---|---|
[116일차 복습] 리눅스/셸Shell script if문, for문, 반복문, break, continue (0) | 2021.09.01 |
[116일차] SHELL SCRIPT on Linux 기본 구문 if , for문 / blockChain 개념 (0) | 2021.08.31 |
[115일차 복습] 리눅스 기초 Ubuntu 입/출력 및 기타 기본 명령어 공부 (0) | 2021.08.30 |
[115일차] 리눅스 ubuntu 입/출력 (0) | 2021.08.30 |