728x90

이론 출처: https://steemit.com/kr/@yahweh87/3

코드설명:https://berrypjh.tistory.com/50

 

블록체인에서 사용되는 '블록' 일정 시간마다(비트코인의 기준으로 10분에 한 번씩 생성됩니다.)

 여러 건의 거래내역을 하나의 블록으로 묶어 기존에 생성된 블록에 체인처럼 계속적으로 연결하는 데이터 구조를 의미합니다. 

 

 

블록은 블록체인의 원소 개념으로, 다수의 거래 정보의 묶음을 의미합니다.

블록에는 블록의 이름이 있는데 Height(높이)라는 용어로 표현되고 있습니다.

한 칸 한 칸 쌓아나가 탑의 형태로 구성된다고 생각하여 Height(높이)라는 말을 쓴다고 합니다.(깊이라고 이해해도 될듯)

하지만 이 높이는 정확한 블록의 이름이 아닙니다. 

블록의 정확한 이름은 TXID라 불리는 블록의 해시값입니다. 이 블록의 해시값은 블록의 헤더 정보(블록의 버전, 이전블록해시,머클루트,타임,bits,논스 정보)를 모두 합산한 후 SHA256으로 변환된 값입니다.

bits : 난이도 해시 목표값을 의미하는 지표

nonce: 블록을 만드는 과정에서 해시값을 구할 때 필요한 재료 역할을 수행한다.

블록의 구성요소

여러 요소들이 있지만

크게 블록 헤더블록 바디로 나눌 수 있다.

블록 하나 만들기

(리눅스 우분투에서 코드 작성중)

<block.js>

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

class BlockHeader{
        constructor(version, previousHash, timestamp, merkleRoot, bit, nonce){
	     this.version = version
	     this.previousHash = previousHash
	     this.timetamp = timestamp
	     this.merkleRoot = merkleRoot
	     this.bit = bit
	     this.nonce = nonce

	}
}

header와 body가 들어간 block클래스를 만들고 블록의 header class도 만들어준다.

npm init

버전과 모듈설치확인 위해서 package.json 파일 만들고 fs불러서 버전표시해보자

const fs = require('fs')

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

}

 

 

# node block.js

 

첫번째 block값 대입한다

function createGenesisBlock(){
	const version = getVersion()
	const previousHash = '0'.repeat(64)
	const timestamp = parseInt(Date.now()/1000)

}

 

version은 getVersion에서 나온 값을 대입한다.

previousHash는 이전 블록이 없는 첫번째 블록이므로 64비트 '0'을 대입

timestamp는 Date써서 현재 시간 넣어두기

 

머클리루트 값을 넣기 위해 설치

 

npm i merkle

 

function createGenesisBlock(){
	const version = getVersion()
	const previousHash = '0'.repeat(64)
	const timestamp = parseInt(Date.now()/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(tree)
	console.log("merkleRoot : %s", merkleRoot);
	console.log("merkleRoot : %s", merkleRoot.toString('hex'));

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

}

해당 모듈 설치 후 body에 들어갈 트랜잭션(거래내역)인 첫 번째 데이터로 hello block을 넣음

나머지는 0대입하고 만들어보고 실행해보기

 

node block.js

하면

(아까는 merkleRoot 안나왔는데 %d 여서 그랬음 %s 이게 string값 불러오는건가보다 둘이 똑같이 뜨네)

 

 

첫번째 블록 생성하기

function createGenesisBlock(){
	const version = getVersion()
	const previousHash = '0'.repeat(64)
	const timestamp = parseInt(Date.now()/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(tree)
	console.log("merkleRoot : %s", merkleRoot);
	console.log("merkleRoot : %s", merkleRoot.toString('hex'));
     
	//헤더에 대입
	const header = new BlockHeader(version, previousHash, timestamp, merkleRoot, bit,nonce)
    return new Block(header, body)

}
//값넣어서 블록생성
const block = createGenesisBlock()
console.log(block)

위에 대입한 결과를 BlockHeader class로 정보를 전달하고 

블록헤더와 바디를 Block class에 전달하여 첫번째 블록을 생성하였다.

 

node block.js  로 실행결과보기

 

block.js 전체코드는 이와같다.

더보기
const fs = require('fs')
const merkle = require('merkle')

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

class BlockHeader{
        constructor(version, previousHash, timestamp, merkleRoot, bit, nonce){
	     this.version = version
	     this.previousHash = previousHash
	     this.timetamp = 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 version = getVersion()
	const previousHash = '0'.repeat(64)
	const timestamp = parseInt(Date.now()/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(tree)
	console.log("merkleRoot : %s", merkleRoot);
	console.log("merkleRoot : %s", merkleRoot.toString('hex'));
     
	//헤더에 대입
	const header = new BlockHeader(version, previousHash, timestamp, merkleRoot, bit,nonce)
    return new Block(header, body)

}
//값넣어서 블록생성
const block = createGenesisBlock()
console.log(block)

 

 

 

 

 

728x90
728x90

Hash

sha256

단방향 암호화, 자리수 64자리로 고정됨

 

해시함수 설명:

더보기

해시함수를 이용한다면 어떤 길이의 입력값이라도 256비트의 고정된 결과값을 출력할 것이고

입력값의 아주 일부만 변경되어도 전혀 다른 값이 출력되는 특징 때문에 데이터가 변경되었는지 쉽게 확인할 수 있습니다.

추가적으로 해시함수는 입력된 값이 같을 경우 항상 같은 결과 값을 출력해야합니다.

https://steemit.com/kr/@yahweh87/2)

 

머클트리 Merkle tree, 머클 루트 Merkle root

데이터가 위변조 되었는지 효율적으로 확인하기 위한 용도로 사용됨

자바스크립트에서 merkletreejs를 이용해 사용할 수 있다.

https://blockone.tistory.com/11 -Merkle tree

더보기

출처 : https://blockone.tistory.com/11

머클트리 Merkle tree

해시트리 라고도 한다. 여러 블록으로 나뉘어 있는 데이터를 전송할 때 데이터가 변조되지 않았음  보증하는 용도로 쓰인다. 특히 p2p네트워크에서 전송받는 데이터에 오류가 있거나 외부로부터 조작이 있었는지 검증하는 용로도로 쓰인다.

블록체인에서는 블록에 포함된 거래 데이터를 요약해 트리 형태로 만들게 되는데 해시함수를 활용해 두개의 거래 데이터를 하나의 데이터로 묶음으로써 용량을 절약할 수 있다.

머클 루트 

블록에 들어있는 모든 거래내역을 요약한 데이터로 최소한의 정보로 인증할 수 있도록 도와준다.

개별 거래에 대한 트랜잭션을 검증하는 기능을 수행하는 노드(라이트노드)에 대해서는 중요한 데이터만 갖고 있게 한다. 외부에서 다른 블록의 거래내역을 조작하면 머클루트를 대조하여 비교하게 된다. 가장 밑단에 있는 거래를 제외한 나머지내역을 두개씩 짝지어 해시값을 얻고 또 그 해시끼리 짝지어 암호화하는 식이다. 이렇게 모든 거래 내역에 해시값을 얻는 과정을 거듭하여 나무 모형으로 만들면 머클트리가 된다. 결국 머클트리 그 자체가 해시로 이루어져 있다. 하나의 트랜잭션이 변조되면 머클루트까지 모든 값이 바뀌게 되는 쇄도효과가 일어난다.

 

 

합의 알고리즘

-작업증명Proof of Work

-지분증명 Proof of Stake

728x90
728x90

 

//함수 참조
console.dir(add)
console.dir(sub)

https://www.howdy-mj.me/javascript/var-let-const/

에서 가져온 내용임.

 

https://medium.com/@ethannam/javascripts-memory-model-7c972cd2c239

변수 variable

하나의 값을 저장하기 위해 확보한 메모리 공간 자체  또는 그 메모리 공간을 식별하기 위해 붙인 이름을 말함

 

자바스크립트는 개발자가 직접 메모리 제어못함

그저 변수를 통해 안전하게 값에 접근할 수 있음. 

 

변수에 값 저장하는 것  :  할당(assignment,대입,저장)

변수에 저장된 값을 읽어들이는 것  :  참조(reference)

변수명을 자바스크립트 엔진에 알리는 것 : 선언(declaration)

 

변수 선언

var, const, let      

 

자바스크립트에서 변수 선언은 

선언 -> 초기화    단계를 거쳐 수행된다. 

선언단계: 변수명을 등록하여 자바스크립트 엔진에 변수의 존재를 알린다.
초기화 단계: 값을 저장하기 위한 메모리공간을 확보하고 암묵적으로 undefined를 할당해 초기화한다.

 

 

var kmj
console.log(kmj) // output: undefined

var 키워드를 이용한 변수 선언은 선언 단계와 초기화 단계가 동시에 진행되어, kmj에 암묵적으로 undefined를 할당해 초기화한다.

그런데 반대로, console을 먼저 찍어도 반환 값이 undefined로 나온다.

console.log(kmj) // output: undefined
var kmj

이는 변수 선언이 런타임에서 되는 것이 아니라, 그 이전 단계에서 먼저 실행되기 때문이다.

자바스크립트 엔진은 소스코드를 한 줄씩 순차적으로 실행하기에 앞서,

변수 선언을 포함한 모든 선언문(ex. 변수 선언문, 함수 선언문 등)을 찾아내 먼저 실행한다.

즉, 변수 선언이 어디에 있든 상관없이 다른 코드보다 먼저 실행되는 특징을 호이스팅(hoisting)이라 한다.

 

변수 선언 뿐만 아니라, var, let, const, function, function*, class 키워드를 사용해 선언한 모든 식별자(변수, 함수, 클래스 등)는 호이스팅이 된다.

 

 

변수 할당

변수에 값을 할당 할 때에는 할당 연산자(=)를 사용한다.

var kmj // 변수 선언
kmj = 'howdy-mj' // 값의 할당

var kmj = 'howdy-mj' // 변수 선언과 할당

변수 선언과 할당은 하나의 문(statement)으로 단축 표현할 수 있지만, 두 개의 실행 시점이 다르다.변수 선언이 호이스팅되어 런타임 이전에 실행되지만,

값의 할당은 소스코드가 순차적으로 실행되는 런타임에 실행된다.

따라서 변수의 할당과 console을 실행하는 위치에 따라 반환되는 값이 다르다.

 

console.log(kmj) // output: undefined

var kmj = 'howdy-mj'
console.log(kmj) // output: howdy-mj

kmj라는 변수에 새로운 값을 재할당할 수도 있다.

console.log(kmj) // output: howdy-mj

kmj = 'mj' //재할당
console.log(kmj) // output: mj

재할당은 변수에 저장된 값을 다른 값으로 변경하는 것으로, 만약 변경할 수 없는 값이라면 이는 변수가 아니라 상수(constant)라 부른다.

 

함수 호이스팅

더보기

위에서 function 키워드로 선언한 모든 식별자도 호이스팅이 된다고 했는데, 정확히 어떻게 이루어질까?

먼저 함수가 정의되는 방식 네 가지를 살펴보자.

//1. 함수 선언문
//함수 이름 생략 불가능 
function add(x, y) {
  return x + y
}
// 2. 함수 표현식
// 함수 이름 생략 가능
var add = function(x, y) {
  return x + y
}
// 함수 이름 작성 시,
// var add = function plus(x, y) {
//   return x + y
// }

// 3. Function 생성자 함수
var add = new Function('x', 'y', 'return x+ y')

// 4. 화살표 함수
var add = (x, y) => x + y

위에서 함수 선언문과 함수 표현식의 호이스팅 결과를 먼저 보자.

 

// 함수 참조
console.dir(add) // output: f add(x, y)
console.dir(sub) // output: undefined

// 함수 호출
console.log(add(2, 5)) // output: 7
console.log(sub(2, 5)) // output: Uncaught TypeError: sub is not a function

// 함수 선언문
function add(x, y) {
  return x + y
}

// 함수 표현식
var sub = function(x, y) {
  return x + y
}

 

함수 선언문의 경우, 런타임 이전에 자바스크립트 엔진에서 먼저 실행되어, 함수 자체를 호이스팅 시킬 수 있다.

반면, 함수 표현식은 위에서 봤던 변수 호이스팅과 같이 런타임 이전에 해당 값을 undefined로 초기화만 시키고, 런타임에서 해당 함수 표현식이 할당되어 그때 객체가 된다.

스코프(scope)

는 식별자(ex.변수명,함수명,클래스명 등)의 유효범위를 뜻하며 선언된 위치에 따라 유효범위가 달라진다.

전역에 선언된 변수, 전역 스코프

지역에 선언된 변수는 지역 스코프를 갖는다.

 

전역변수 : 어디에서든지 참조가 가능한 값

지역변수 : 함수몸체내부를 말한다.  자신의 지역스코프와 그 하위 지역스코프에서 유효하다.

 

 

var, let, const의 차이

var 문제점 

  • 변수 중복 선언 가능, 예기치 못한 값을 반환할 수 있다.
  • 함수 레벨 스코프로 인해 함수 외부에서 선언한 변수는 모두 전역 변수로 된다.
  • 변수 선언문 이전에 변수를 참조하면 언제나 undefined를 반환한다

1. 변수 중복 선언 불가

(1) let

let 키워드로는 변수 중복 선언이 불가하지만, 재할당은 가능하다.

 

더보기
let name = 'kmj'
console.log(name) // output: kmj

let name = 'howdy' // output: Uncaught SyntaxError: Identifier 'name' has already been declared

name = 'howdy'
console.log(name) // output: howdy

 

(2) const

const가 let과 다른 점이 있다면, 반드시 선언과 초기화를 동시에 진행되어야 한다.

const name; // output: Uncaught SyntaxError: Missing initializer in const declaration
const name = 'kmj'

const도 let과 마찬가지로 재선언이 불가하며, 더 나아가 재할당도 불가하다. 재할당의 경우, 원시 값은 불가능하지만, 객체는 가능하다. const 키워드는 재할당을 금지할 뿐, ‘불변’을 의미하지 않는다.

// 원시값의 재할당
const name = 'kmj'
name = 'howdy' // output: Uncaught TypeError: Assignment to constant variable.

// 객체의 재할당
const name = {
  eng: 'kmj',
}
name.eng = 'howdy'

console.log(name) // output: { eng: "howdy" }

2. 블록 레벨 스코프

let, const 키워드로 선언한 변수는 모두 코드 블록(ex. 함수, if, for, while, try/catch 문 등)을 지역 스코프로 인정하는 블록 레벨 스코프를 따른다.

위 var 키워드로 예를 들었던 것을 그대로 가져와 바꾸면 아래와 같은 결과가 나온다.

let a = 1

if (true) {
  let a = 5
}

console.log(a) // output: 1

var 키워드로 선언한 경우 5가 나왔지만, let 키워드로 선언한 경우 if 문 안에 있는 것은 지역 스코프를 가져 전역에서 console을 찍었을 경우, 전역에 있는 a가 결과 값으로 출력된다. (const 키워드도 let 키워드와 동일하게 동작한다)

3. 변수 호이스팅

(1) let

let 키워드로 선언한 변수는 선언 단계와 초기화 단계가 분리되어 진행된다. 즉, 런타임 이전에 자바스크립트 엔진에 의해 선언 단계가 먼저 실행되지만, 초기화 단계가 실행되지 않았을 때 해당 변수에 접근하려고 하면 참조 에러가 뜬다.

let도 호이스팅하지만 변수에 접근할 수 없다,쓸수 없다고 경고창떠요..

console.log(name) // output: Uncaught ReferenceError: name is not defined

let name = 'kmj'

따라서 let 키워드로 선언한 변수는 스코프의 시작 지점부터 초기화 단계 시작 지점까지 변수를 참조할 수 없는 일시적 사각지대(Temporal Dead Zone: TDZ) 구간에 존재한다.

 

(2) const

const 키워드는 선언 단계와 초기화 단계가 동시에 진행된다.

console.log(name) // output: Uncaught ReferenceError: Cannot access 'name' before initialization

const name = 'kmj'

let 키워드로 선언한 경우, 런타임 이전에 선언이 되어 자바스크립트 엔진에 이미 존재하지만 초기화가 되지 않았기 때문에 name is not defined라는 문구가 떴다. 하지만 const 키워드로 선언한 경우, 선언과 초기화가 동시에 이루어져야 하지만 런타임 이전에는 실행될 수 없다. 따라서 초기화가 진행되지 않은 상태이기 때문에 Cannot access 'name' before initialization 에러 문구가 뜬다.

정리

기본적으로 변수의 스코프는 최대한 좁게 만드는 것을 권장한다. 따라서, var 키워드 보다는 let과 const 키워드를 사용하며, 변경하지 않는 값(상수)이라면 let 보다는 const 키워드를 사용하는 것이 안전하다.

 

 

 

 

 

728x90
728x90

계속 헷갈리는게 root계정인지 일반계정인지 sudo su가 슈퍼관리자로 가능하대서 다되는구나 이생각

무지성으로 따라해서 ㅎㅎ

 

터미널에서 하던걸 vscode에서 해볼까했는데 저장안됨

어 저번엔 됐었는데

 

이유는 우분투 연결한 vscode는 

일반계정으로 열리는 거임

 

근데 터미널에서는 sudo su- 슈퍼계정 root로 파일들 만들잖아

그 파일이 일반계정으로 열리는 vscode에서는 수정이 안되는거임 권한이 없어서

 

그동안 일반계정으로 했다가 root계정으로 했다가 막한 흔적들

 

일반계정으로 파일 만들어보니까

vscode에서도 수정잘될 수 있는거 확인.

 

 

왜 파일만들때 sudo su-로 root계정에 들어가서 작업하는거지?

root에서만 할 수 있는 작업들이 있다 하더라고

 

728x90
728x90

 

 

분산되어 저장한다는 것은 탈중앙화를 의미

P2P(Peer to Peer) 네트워크를 통해서 관리되는 분산데이터베이스에 의한 형태

분산처리와 암호화

블록체인 네트워크에 연결된 여러 컴퓨터(노드)에 저장 및 보관하는 기술

 

블록들을 체인 형태로 묶은 형태

블록들이 형성된 후 시간의 흐름에 따라 순차적으로 연결된 '사슬(체인)'의 구조를 가지게 된다

 

특장점

 

  • 분산저장 (기존거래방식은 데이터를 위,변조하기 위해서 중앙서버를 공격)
  • 여러 명이 동일한 데이터를 저장
  • 블록체인 네트워크를 위,변조하기 위해서는 참여자(노드)의 거래 데이터를 모두 공격해야하기 때문에 사실상 해킹이 불가능
  • 중앙관리자 불필요(중앙기관,관리자 없어도 다수가 데이터를 저장,증명할 수 있기 때문에 탈중앙화가 가능)

 

블록체인의 기술 활용

  • 금융거래
  • 개인의료정보
  • 영상 또는 이미지, 콘텐츠
  • 부동상
  • 의료
  • 인적자원

 

 

블록체인의 기술

  • 해쉬(Hash) 함수를 사용
  • 스마트계약을 활용

블록체인 동작원리

  • 하나의 새로운 블록을 구성한 경우, 이전부터 이어져 내려오던 블록체인의 맨끝에 이 새로운 블록을 연결
  • 새로 구성한 블록의 이름에 해당하는 해시를 찾아내는 일(목표 값보다 작아야한다는 조건을 충족해야함.)

예시)목표 해시 값: 00ff32라고 가정

새로 만든 블록의 해시값: (블록생성에 실패)

새로 찾아낸 해시값: 00c3b1(새로운 블록의 생성에 성공)

 

 

728x90
728x90

 

 

 

와우 어렵구나.!!!

 

되긴됐는데..혼자서는 절대못짤거같음...ㅎ

 

 

 

while반복문

 

while [조건]
do
명령1
명령2
done

 

 

기본루프

number가 2보다 작을 동안(le) 반복

#!/bin/bash

number=0

while [ $number -le 2 ]
do
  echo "Number: ${number}"
  ((number++))
done

무한루프

if문을 이용하여 2보다 커지면 while 문을 탈출

#!/bin/bash

number=0

while :
do
  if [ $number -gt 2 ]; then
    break
  fi

  echo "Number: ${number}"
  ((number++))
done

 

날짜를 이용한 루프

 시작일자(2019.01.01)부터 종료일자 전일(2019.01.31)까지 일자를 출력하는 방법

#!/bin/bash

startDate=`date +"%Y%m%d" -d "20190101"`
endDate=`date +"%Y%m%d" -d "20190201"`

while [ "$startDate" != "$endDate" ] ; 
do 
    echo $startDate

    startDate=`date +"%Y%m%d" -d "$startDate + 1 day"`; 
done

종료일자(2019.02.01)까지 출력하기 위해서는 종료일자에 1을 더하여 whilte문 종료조건을 늘려주면 된다

#!/bin/bash

startDate=`date +"%Y%m%d" -d "20190101"`
endDate=`date +"%Y%m%d" -d "20190201"`
endDate=`date +"%Y%m%d" -d "${endDate} + 1 day"`

while [ "$startDate" != "$endDate" ] ; 
do 

    echo $startDate

    startDate=`date +"%Y%m%d" -d "$startDate + 1 day"`; 
done

 

 

 

 

 

 

출처: https://wikidocs.net/29981

https://judo0179.tistory.com/122?category=456195 

 

쉘 스크립트 반복문 사용하기

Shell Loop Types 이번 시간에서는 Unix Shell에서 사용하는 반복문에 대해서 알아본다. 반복은 일련의 명령을 반복할 수 있도록 하는 프로그래밍 도구로서 아래에서 다양한 반복문 종류를 살펴보도록

judo0179.tistory.com

https://blog.naver.com/yse1030/222600492209

 

[Linux] 반복문

#Linux #while #리눅스 #반복문 #while #for While Loop while문의 조건이 참이면 코드를 계속해서 반복...

blog.naver.com

 

728x90

+ Recent posts