728x90

다음과 같은 조건을 거쳐야함.

 

1. 블록구조가 유효한지

2. 현재 블록의 인덱스가 이전 블록의 인덱스보다 1만큼 큰지

3. 이전블록의 해시값과 현재 블록의 이전해시가 같은지

4. 데이터 필드로부터 계산한 머클루트와 블록헤더의 머클루트가 동일한지 

 

이 조건 다 맞으면 올바른 구조체이다.

 

 

1.블록구조가 유효한가

//블록의 각각 타입체크 블록구조 유효한지 체크하는 함수
function isValidBlockStructure(block) {
    return typeof(block.blockheader.version) === 'string'
    && typeof(block.header.index) === 'number'
    && typeof(block.header.previousHash) === 'string'
    && typeof(block.header.timestamp) === 'number'
    && typeof(block.header.merkleRoot) === 'string'
    && typeof(block.body) === 'object'
}
//위 함수를 통해 블록구조의 유효성 검사
function isValidNewBlock(newBlock, previousBlock) {
    if (isValidBlockStructure(newBlock) === false) {
        console.log('Invalid Block Structure')
        return false;
    }
    return true;
}

 

2. 현재 블록의 인덱스가 이전 블록의 인덱스보다 1만큼 큰지

 

//위 함수를 통해 블록구조의 유효성 검사
function isValidNewBlock(newBlock, previousBlock) {
    if (isValidBlockStructure(newBlock) === false) {
        console.log('Invalid Block Structure')
        return false;
        //현재블록이 이전 블록보다 1크지 않으면 false
    } else if (newBlock.header.index !== previousBlock.header.index +1 ){
        console.log('Invalid Index')
        return false;
    }
    return true;
}

3. 이전블록의 해시값과 현재 블록의 이전해시가 같은지

 

나는 새로 만들어서 하는중이라

blockcopy.js 에 블록생성block, 다음블록연결chainedBlock까지 해놨음

여기서 createHash 내보내주기 

 

//이전블록 해시값과 현재 블록해시값의 이전해시가 같은지
//보려고 내보내줘야함 
module.exports = { 
	createHash,
}

이제 현재 코드,

비교해볼 코드에 createHash 가져와야돼

 

(수업때는 checkValidBlock.js 라고 이름지은걸 걍 다시 하면서 checkedBlock.js라고 했닿 )

const {createHash} = require('./blockcopy');

 

//위 함수를 통해 블록구조의 유효성 검사
function isValidNewBlock(newBlock, previousBlock) {
    if (isValidBlockStructure(newBlock) === false) {
        console.log('Invalid Block Structure')
        return false;
    } else if (newBlock.header.index !== previousBlock.header.index +1 ){
        console.log('Invalid Index')
        return false;
        //이전블록해시랑 현재블록의 이전해시가 다르면 false
    } else if (createHash(previousBlock)!==newBlock.header.previousHash) {
        console.log('Invalid previousHash');
        return false;
    }
    return true;
}

4. 데이터 필드로부터 계산한 머클루트와 블록헤더의 머클루트가 동일한지 

 

merkle쓰려면 설치해야돼

 

npm i merkle
const merkle = require("merkle")

....

//위 함수를 통해 블록구조의 유효성 검사
function isValidNewBlock(newBlock, previousBlock) {
    if (isValidBlockStructure(newBlock) === false) {
        console.log('Invalid Block Structure')
        return false;
    } else if (newBlock.header.index !== previousBlock.header.index +1 ){
        console.log('Invalid Index')
        return false;
    } else if (createHash(previousBlock)!==newBlock.header.previousHash) {
        console.log('Invalid previousHash');
        return false;
    } else if (newBlock.body.length === 0 && ('0'.repeat(64) !== newBlock.header.merkleRoot) 
    || newBlock.body.length !== 0 && (merkle("sha256").sync(newBlock.body).root() !==newBlock.header.merkleRoot))
    {
        console.log('Invalid merkleRoot')
        return false
    }
    return true;
}

새블록 body의 길이가 0일 경우 && 머클루트는 '0'.repeat(64)이 아니면

또는 

 

새블록바디 길이가 0이 아닐경우 && 머클루트에있는 정보와  새블록 바디의 루트 정보들이 같지 않으면

false

 

 

5. 새블록추가

chainedBlock.js 하단에 추가

 

나는 blockcopy.js에 추가함요

module.exports = {
	Blocks,
	getLastBlock,
	createHash,
}

checkValidBlock.js 상단에 불러오기

 

나는 checkBlock.js에 넣음

 

const {createHash,Blocks, createHash} = require('./blockcopy');

 

 

 

 

 

 

 

 

검증과정을 마친 블록

 

//검증마친 블록들은 chainedBlock.js의 Blocks배열에 추가한다
function addBlock(newBlock){
    if(isValidNewBlock(newBlock,getLastBlock())){
        Blocks.push(newBlock)
        return true;
    }
    return false;
}

const block = nextBlock(['transaction1'])
addBlock(block)

console.log(block)

 

 

 

blockcopy.js에서의 nextBlock함수 이용해서 

블록생성하고 출력해보기 

 

 

근데 결과에 

 

계속 이게 나와서 

이 콘솔임

 

코드비교해보니까 

blockcopy.js (chainedBlock.js) 에 

index순서 바꾸니까 안뜨네 뭐냐...

blockcopy.js (chained.js)

결과

 

 

 

코드 전체

blockcopy.js

(chainedBlock.js)

더보기
const cryptojs = require('crypto-js')
const fs = require('fs')
const merkle = require('merkle')


class Block{
        constructor(header, body){
		this.header = header
		this.body = body
	}
}

//블록헤더 구조체 선언 : 헤더 구성 요소 나열
class BlockHeader {
	constructor(index, version, previousHash, timestamp, merkleRoot, bit, nonce) {
	  this.index = index
	  this.version = version
	  this.previousHash = previousHash
	  this.timestamp = timestamp
	  this.merkleRoot = merkleRoot
	  this.bit = bit
	  this.nonce = nonce
	}
  }
  

//버전계산하는 함수 
function getVersion(){
	const package = fs.readFileSync("package.json")
	// console.log(JSON.parse(package).version)
	return JSON.parse(package).version

}


//getVersion()

function createGenesisBlock() {
  const index = 0
  const version = getVersion()
  const previousHash = '0'.repeat(64) // 0을 64번 반복
  const timestamp = parseInt(Date.now() / 1000) // 1000 나눈 이유 : 초 단위로 환산하기 위해
  const body = ['Hello block!']
  const tree = merkle('sha256').sync(body)
  const merkleRoot = tree.root() || '0'.repeat(64)
  const bit = 0
  const nonce = 0

  // console.log("version : %s, timestamp : %d, body: %s", version, timestamp, body);
  // console.log("previousHash : %d", previousHash);
  // console.log(tree);
  // console.log("merkleRoot: %s", merkleRoot);

  const header = new BlockHeader(index, version, previousHash, timestamp, merkleRoot, bit, nonce)
  return new Block(header, body)
}

//값넣어서 블록생성

let Blocks = [createGenesisBlock()]

function getBlocks() {
  return Blocks
}
function getLastBlock() {
  return Blocks[Blocks.length - 1]
}



//블록해시 값 구하기
function createHash (data){
	const {version,previousHash,timestamp, merkleRoot, bit, nonce}= data.header
	const blockString = version +previousHash +timestamp+ merkleRoot+ bit+ nonce
	const hash = cryptojs.SHA256(blockString).toString()
	return hash
}



// const block = createGenesisBlock()
// const testHash = createHash(block)
// console.log(testHash)

//다음블록 생성하기 
function nextBlock(bodyData) {
	const prevBlock = getLastBlock()
	const version = getVersion()
	//다음순서니까 하나 추가됨
	const index = prevBlock.header.index + 1
	//createHash함수에 이전블록 정보를 넣어 블록해시값을 구해넣는다.
	const previousHash = createHash(prevBlock)
	const timestamp = parseInt(Date.now() / 1000)
	//블록body부분에 저장될 트랜잭션(거래정보)인 bodyData를
	//merkle몯ㄹ을 사용하여 트랜잭션들의 해시트리를 만들어 tree에 넣어
	const tree = merkle('sha256').sync(bodyData)
	//여기서 최종적으로 구해진 해시값인 머클루트 해시값을 merkleRoot변수에 넣어
	const merkleRoot = tree.root() || '0'.repeat(64)
	const bit = 0
	const nonce = 0

	const header = new BlockHeader
	(index,version,previousHash,timestamp, 
		merkleRoot, bit, nonce)
    return new Block(header,bodyData)

}
//다음블록생성 출력하기
// const block1 = nextBlock(["tranjaction1"])
// console.log(block1)

//addblock함수를 통해 순차적으로 트랜잭션값 전달해 블록생성하고
function addBlock(bodyData) {
	const newBlock = nextBlock([bodyData])
	Blocks.push(newBlock)
  
  }

// addBlock(['transaction1'])
// addBlock(['transaction2'])
// addBlock(['transaction3'])
// addBlock(['transaction4'])
// addBlock(['transaction5'])

// console.log(Blocks);

//이전블록 해시값과 현재 블록해시값의 이전해시가 같은지
//보려고 내보내줘야함 
module.exports = { nextBlock, getLastBlock, createHash, Blocks, getVersion, getBlocks }


// function addBlock(newBlock){

// 	if(isValidNewBlock(newBlock,getLastBlock())){

// 		Blocks.push(newBlock)
// 		return true;
// 	} return false;
// }

 

checkedBlock.js

더보기
const merkle = require("merkle")
const {Blocks, createHash, getLastBlock,nextBlock} = require('./blockcopy');
// const { nextBlock } = require("./chainedBlock");


//블록구조 유효한지
//blockcopy.js에서 만든 블록체인

//블록의 각각 타입체크 블록구조 유효한지 체크하는 함수
function isValidBlockStructure(block) {
  return typeof (block.header.version) === 'string'
    && typeof (block.header.index) === 'number'
    && typeof (block.header.previousHash) === 'string'
    && typeof (block.header.timestamp) === 'number'
    && typeof (block.header.merkleRoot) === 'string'
    && typeof (block.body) === 'object'
}
//위 함수를 통해 블록구조의 유효성 검사
function isValidNewBlock(newBlock, previousBlock) {
    if (isValidBlockStructure(newBlock)===false){
		console.log('Invalid Block Structure');
		return false;
	} else if (newBlock.header.index !== previousBlock.header.index +1 ){
        console.log('Invalid Index')
        return false;
    } else if (createHash(previousBlock)!==newBlock.header.previousHash) {
        console.log('Invalid previousHash');
        return false;
        //블록길이가 0일경우
    } else if (newBlock.body.length === 0 
        //머클루트는길이가 
        && ('0'.repeat(64) !== newBlock.header.merkleRoot) 
    || newBlock.body.length !== 0 && (merkle("sha256").sync(newBlock.body).root() !==newBlock.header.merkleRoot))
    {
        console.log('Invalid merkleRoot')
        return false
    }
    return true;
}

//검증마친 블록들은 chainedBlock.js의 Blocks배열에 추가한다
function addBlock(newBlock){
    if(isValidNewBlock(newBlock,getLastBlock())){
        Blocks.push(newBlock)
        return true;
    }
    return false;
}

const block = nextBlock(['transaction1'])
addBlock(block)

console.log(block)
728x90

+ Recent posts