dukDukz

[블록체인] 블록 추가로 생성하기 본문

웹 개발/블록체인

[블록체인] 블록 추가로 생성하기

헤일리_HJ 2021. 9. 1. 15:04

# 이제 다음 블럭을 생성하는 루틴을 해보자
- 이게 코드가 길다

이때부터는 검증 , 데이터 타입을 신경쓰면서 만들어야 한다
--------

# 연결리스트 형태로 블럭을 나열할것이다.
순차적으로 만들거라는 얘기!!

블럭을 생성할 때마다 배열에 집어넣는거를 해보자

전역변수로 배열을 하나 선언한다.

let Blocks = [createGenesisBlock()]
console.log(Blocks) // 앞으로 볼때는 얘를 보면 됨


# 블럭을 추가해주는 거를 간략하게 해보자
전역변수로 선언한 곳에 push 하는 것
function addBlock(){
    // 우선 class 사용 new header -> new block (header, body) 를 해야겠군    
}
index 는 맨마지막에 있는 녀석에 +1 해주면 된다.
다음에 들어갈 index 값을 줄 수 있다.

해쉬값은 이전에 있는 블럭 가져와야 하고 header 정보 가져와야 하고 string 으로 연결할 줄 알아야함

 

더보기

[해쉬값은 부모의 정보를 담고 있다고 봐야 함]
전에 갖고 있는 키값
헤더 에 있는 인덱스... 여러 값들을 스트링으로 연결해서
sha256 으로 64 개로 줄여준다 이전 헤더에 대한 압축정보
그래서 검증....

이전에 있는 헤더값들을 다 스트링으로 바꾼다.
그거를 sha256으로 암호화 하면 64글자로 줄어든다
그 값을 만들어서.

 

이전 해쉬값의 헤더값에 넣었던 총 5가지
이 5가지를 스트링으로 바꿔서 더해서 sha256으로 암호화 시켜서 64 글자로 바꿔준다.


time 은 getCurrentTime 함수 사용

merkleRoot  body 를 가지고 다시한번 root 생성하면 된다.

# 마지막 블럭을 가져오는거!!!
Blocks 를 사용해서.. 여기에 블럭이 추가될때 마다 여기에 추가됨
배열의 마지막 녀석을 가져올 수 있는 방법 : Blocks[Blocks.length -1]

Blocks[Blocks.length -1].header.index

여기까지
제네시스 블록을 만들었다
전체 블럭을 배열로 관리하기로 하고
addBlock 을 통해서 함수가 하나 더 증가 할때 블럭에 push 를 해줘야 한다.
BlockHeader 와 Block 을 재사용해야 하는데 
index 값과 previousHash 값이 바뀐다
이전 해쉬값 : 마지막 블럭의 헤더에 있는 내용을 스트링으로 연결시켜서 sha256 으로 넣어야 한다.
addBlock 을 했을 때 다음블럭이 생성될 수 있도록 ..

 

// 헤더 만들기
class BlockHeader {
    constructor(version, index, previousHash, time, merkleRoot) {
        this.version = version      //  1 new 생성자를 통해서 this.version 은 {version:1} 이렇게 된다
        this.index = index          // 2 {version:1, index : 2}
        this.previousHash = previousHash
        this.time = time
        this.merkleRoot = merkleRoot
    }
}

class Block {
    constructor(header,body){
        this.header = header,       //BlockHeader 에서 만든값을 넣겠다. 객체 안에 객체가 들어가게 된다.
        this.body = body
    }
}

function getLastBlock(){
    return Blocks[Blocks.length - 1]    // 배열의 마지막 원소를 가져옴   
}

function getLastIndex(){
    let {index} = getLastBlock().header
    // console.log("이전 idx ====",index);
    return index
}

function getLastHash(){
    let {previousHash} = getLastBlock().header
    // console.log(SHA256(previousHash).toString());
    const newHash = SHA256(previousHash).toString()
    return newHash
}




function addBlock(){
    // 우선 class 사용 new header -> new block (header, body) 를 해야겠군
    const version = getVersion()
    const index = getLastIndex()+1
    const time = getCurrentTime()
    const previousHash = getLastHash()

    const body = ['next block']
    const tree = merkle('sha256').sync(body)
    const root = tree.root() || '0'.repeat(64)

    const header = new BlockHeader(version,index,previousHash,time,root)
    Blocks.push(new Block(header,body))
}
addBlock()      // 이게 계속 추가 되는..
addBlock()

 

 

 


0902 ver

const fs = require('fs')        // file system library 가져오고
const merkle = require('merkle')
const CryptoJs = require('crypto-js')
const SHA256 = require('crypto-js/sha256')


// const tree = merkle("sha256").sync(['aaaa'])
// tree.root() 

// 헤더 만들기
class BlockHeader {
    constructor(version, index, previousHash, time, merkleRoot) {
        this.version = version      //  1 new 생성자를 통해서 this.version 은 {version:1} 이렇게 된다
        this.index = index          // 2 {version:1, index : 2}
        this.previousHash = previousHash
        this.time = time
        this.merkleRoot = merkleRoot
    }
}

class Block {
    constructor(header, body) {
        this.header = header,       //BlockHeader 에서 만든값을 넣겠다. 객체 안에 객체가 들어가게 된다.
            this.body = body
    }
}

let Blocks = [createGenesisBlock()]

function getBlocks() {
    // 나중에 쓸거임 
    return Blocks
}


function getLastBlock() {
    return Blocks[Blocks.length - 1]    // 배열의 마지막 원소를 가져옴   
}



function createGenesisBlock() {
    const version = getVersion()    
    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)
}

// 다음 블럭의 header 와 body를 만들어주는 함수
function nextBlock(data){
    // header
    const prevBlock = getLastBlock()    // 맨 마지막 블럭의 정보를 가져옴
    const version = getVersion()
    const index = prevBlock.header.index+1
    const previousHash = createHash(prevBlock)
    const time = getCurrentTime()

    const merkleTree = merkle("sha256").sync(data)
    const merkleRoot = merkleTree.root() || '0'.repeat(64)

    const header = new BlockHeader(version, index, previousHash, time, merkleRoot)
    return new Block(header, data)
}

function createHash(block){
    const {
        version,
        index,
        previousHash,
        time,
        merkleRoot
    } = block.header 
    const blockString = version + index + previousHash + time + merkleRoot
    const Hash = CryptoJs.SHA256(blockString).toString()
    return Hash
}

// Blocks 에 push 하는 녀석
// 다음 블럭을 생성할 형태는 다른 곳에 만들거임
function addBlock(data) {
    // data는 nextBlock 에서 오는 배열 , 인자값으로 받아줘야함
    // 나중에 여기에 조건이 들어갈것이다. 검증하는 코드..
    const newBlock = nextBlock(data)
    Blocks.push(newBlock)
}

addBlock(['hello1'])
addBlock(['hello2'])
addBlock(['hello3'])





function getVersion() {
    const { version } = JSON.parse(fs.readFileSync("../package.json"))
    return version
}

function getCurrentTime() {
    return Math.ceil(new Date().getTime() / 1000)
}

console.log(Blocks);

교수님이 한 version

 

 

addBlock    - 배열에 push 만 하는 녀석
nextBlock   - 다음 블럭의 header 와 body를 만들어주는 함수

 

따로 따로 분리 해줘야 한다.

 

왜냐면 나중에 addBlock 에 조건이 들어갈것이다. 검증하는 코드 같은거

 

 

여기서 addBlock 함수를 호출할때 배열 안에 넣어서 인자값을 전달해야 한다. 

배열 안에 들어간 내용은 addBlock 에서 data로 받고 이건 body 내용이 되어 처리가 된다.

 

 

이게 3개의 함수가 추가 된 거라고 보면 된다.

더보기
// 다음 블럭의 header 와 body를 만들어주는 함수
function nextBlock(data){
    // header
    const prevBlock = getLastBlock()    // 맨 마지막 블럭의 정보를 가져옴
    const version = getVersion()
    const index = prevBlock.header.index+1
    const previousHash = createHash(prevBlock)
    const time = getCurrentTime()

    const merkleTree = merkle("sha256").sync(data)
    const merkleRoot = merkleTree.root() || '0'.repeat(64)

    const header = new BlockHeader(version, index, previousHash, time, merkleRoot)
    return new Block(header, data)
}

function createHash(block){
    const {
        version,
        index,
        previousHash,
        time,
        merkleRoot
    } = block.header 
    const blockString = version + index + previousHash + time + merkleRoot
    const Hash = CryptoJs.SHA256(blockString).toString()
    return Hash
}

// Blocks 에 push 하는 녀석
// 다음 블럭을 생성할 형태는 다른 곳에 만들거임
function addBlock(data) {
    // data는 nextBlock 에서 오는 배열 , 인자값으로 받아줘야함
    // 나중에 여기에 조건이 들어갈것이다. 검증하는 코드..
    const newBlock = nextBlock(data)
    Blocks.push(newBlock)
}

addBlock(['hello1'])
addBlock(['hello2'])
addBlock(['hello3'])