수업때 배운걸 바탕으로 코드르 짠건데
수업때 쓴 코드예제가 이거다(추정)
https://newpouy.github.io/jekyll/update/2018/03/19/naivecoin-korean-translate-version.html
Naivecoin Korean Translate Version #1
navie코인 번역 원문: lhartikk.github.io
newpouy.github.io
우리팀이 한 내용은 ,시각화에서 꽤나 시간을 잡아먹었지만,
제네시스 블록 만들고
노드 켜면 제네시스 블록 만들고 db생성 연결돼서 제네시스 블록이 들어감
채굴하면 그 내용도 들어감
각노드가 db가지고 있어서 내용들어가고 ws웹소켓으로 둘이 연결을 시키면 블록 추가할때 받아옴. 길이가 긴쪽걸로 받아와. 지갑 생성은 지갑주소address띄우고 시각화정도만!
(우리팀한 거 백단내용 중간만 정리한거. 에러천국리뷰도 조만간 올리겠다 안에 팀플한 전체코드링크있음)
https://stepby-yun.tistory.com/115?category=0
블록체인 채굴, p2p서버통신, 블록업데이트 완료 (코드 적어놓고 정리)
각 노드, 참여자 컴퓨터에 3001이 관리자 6001이 노동자.. http서버는 모든 걸 보여주기 용으로 돌리는거 라고 대충이해했는데.. 이후에 db서버랑, 리액트서버랑 얘네가 어떻게 맞물리는지 사실 아직
stepby-yun.tistory.com
~~최소한의 블록체인 짜기~~~ 내용출처 상위링크
이제 트랜젝션 거래 내용을 짜야하는데 전체 구조를 제대로 이해못했는지 잘안된다. 문서보면서 정리하면서 해보자
나름의 코드풀이임..
(보니까 얘는 TypeScript를 썼더라고 그래도 npm start하면 알아서 자바스크립트로 뽑아 변환해주더라)
- 블록과 블록체인
- 기존 데이터에 새로운 블록 더하기
- 노드(node) 간 통신과 싱크 맞추기
- 간단한 HTTP를 통한 노드 제어
(첫번째 장에 써있는 이거 . 이건 다 한거임 그래도 다시 보기.. 함수명이 좀 다르지만)
블록구조 짜기
블록구조- 순서 , 데이터, 타임스템프, 해쉬값(블록데이터기반으로 계산됨, 블록의 고유한 식별자기능), 이전해쉬값
class Block {
constructor (인덱스, 해시~~~)
this.인덱스= 인덱스;
~~
}
(우리는 Block에 헤더랑 바디 넣고, BlockHeader추가로 만들어서 거기에 버전이랑 인덱스 넣었음)
최초의 블록(제네시스블록) - 블록체인의 시작. 안의 값은 일일이 넣어주면 됨.
const genesisBlock
블록체인 싹 저장할 배열 (javascript in memory 방식으로 저장. 컴끄면 사라짐)
const blockchain= [] //1장에서는 genesisBlock를 넣은 걸봐서 제네시스 블록 넣어서 보려나봄
필요한 함수 만들기
해쉬값계산함수
const calculateHash
다음블록만드는 함수(이전 해쉬 블록 알아야함)
const generateNextBlock
블록의 유효성 검사할 함수
그 조건임
- 이전 블록보다 인덱스값이 1 클 것.
- previousHash값이 이전블록의 hash값일 것.
- hash값이 유효한 값일 것. 다음의 코드로 이를 검사할 수 있어요.
const isValidNewBlock = (새블록, 이전블록) => {
1. 만약 이전블록인덱스가 새 블록인덱스보다 길이 더 길면
틀림 뱉어
2. 이전블록해시와 새블록이전해시가 같지 않으면
틀림뱉어
3. 새블록의 해시 계산한것이 새블록해시와 같지 않으면
틀림 뱉어
다 통과하면 맞음 뱉어
}
참고로 나 저기 들어가는 ,"새블록, 이전블록" 이렇게 써놓은 거, 파라미터(매개변수parameter)가 이름 내마음대로 지어줘도 되는건지 몰랐음.. 그래서 req, res도 막 거꾸로 써도 되더라고. 이전에 보내준 값(전달인자 argument)을 여기서 어떤 이름으로 쓸지 변수 정하고 이 함수 안에서 쓰는 것이었다!!!! 이전에 보내준 값이름이랑 이름이 달라도 상관없는 것!..ㅋㅋㅋ그동안 이름같은게 많길래 헷갈렸는데 이렇게 유동적이었다뉘
블록의 구조 검사하는 함수
const isValidBlockStructure {
블록 인덱스 타입은 숫자
블록 해시 타입은 문자열string(왜 끈, 줄이냐면 한글자씩연달아 메모리에 저장되는게 끈같아서..)
블록 시간기록, 타임스탬프는 숫자
블록 데이터,정보는 문자열
}
전체 블록체인을 검사하는 함수
최초의 블록검사하고, 이어지는 모든 블록검사할거야~
(이함수는 replaceChain, 새블록들어왔을때 전체 체인 교체할 경우에 쓸거임)
const isValidChain =(유효한정보의블록체인)=>{
최초의 블록을 json형태로 내보내라.
만약에 최조블록이 첫번째 인덱스가 아니면 틀림뱉어.
for문으로 돌릴건데, 두번째인덱스부터 블록길이까지 돌릴거임
만약에 새로들어온 i번째 블록의 검증이 실패하고, 새로들어온i-1번째 블록검증실패하면
틀림뱉어
다 통과하면 맞음 뱉어
}
블록체인은 원본체인 길이를 다같이 갖고 있는 개념이라서
유효성 검증 거친 옳은 체인은 하나만 존재해야해!
c가 채굴해서 블록체인에 연결한 다음에
동시에 a도 채굴하고 b도 채굴했을때 누구꺼로 하냐의 고민을
더 긴 체인을 옳은 체인으로 간주해.
(이유는 체인이 길다는 건 다른 노드가 아직 받지 못한 블록을 갖고 있다볼수있어서)
그래서 만드는
긴체인으로 전체 교체하는 함수
const replaceChain =(새블록)=>{
만약에 새블록이 전체 블록체인을 검사하는 함수를 잘 통과됐고 새블록길이가 전체블록길이보다 길면
콘솔로 "받은 블록체인이 유효하다. 현재블록체인을 받은 블록체인으로 교체한다" 띄움
아니면
콘솔로 "받은 블록체인 안유효해" 띄움
}
다른 노드와 통신
노드(참여자) 사이에 통신이 있어야 블록체인할 수 있겠지? 그래야 탈중앙화해서 우리끼리 알아서 거래하지.
데이터 싱크를 맞춰야하기 때문에 계속 통신하면서 우리가 가진 원본이 같은지 확인해야되는 게 물론 가장 큰이유지.
- 노드가 새 블록을 만들면 그것을 네트워크로 방출(발송,broadcast)해야한다.
- 노드 간에 연결될 때, 각자 지니고 있는 가장 마지막 블록이 무엇인지를 파악한다.
- 자기보다 긴 체인과 연결되면 상대가 가진 블록 중 내가 가진 블록 이후의 모든 블록을 추가하여 싱크를 맞춘다. (긴걸로 대체된다는 그 얘기임)
노드간의 통신에는 웹소켓을 쓸거임
먼저 노드를 제어하기 위한 http서버를 만들자
const initHttpServer =(내포트) =>{
express모듈써서 쓸 서버 app이라고 만들어놓음
그리고 서버통해서 json형태로 정보 띄우게 할거임
어떻게 쓸거냐면
/blocks버튼 쓸거야-요청들어오면 getBlockchain함수, 기존에 있는 갖고 있는 블록 다 보이게 응답할거야
/mineBlock 버튼, 근데 정보를 내가 보내주는,,
새블록은 요청한 바디의 데이터를 다음블록생성함수에 넣은거야.
새블록으로 응답할게
/peers 버튼, 웹소켓으로 연결한 주소랑 포트번호 보여줄게
/addPeer버튼 req.body.peer보내서 노드 연결해줄게.
}
서버실행해.listen (내포트주소,()=>{
내포트주소는 여기야
})
이제 이 서버로
- 블록의 리스트 가져오기
- 새로운 블록을 만들기
- 노드 목록을 가져오거나 새로운 노드를 추가하기 curl명령어로도 노드를 제어할 수 있어요.
할수 있음
curl http://localhost:3001/blocks
get이거 써서
전체구조
노드, 참여자는
두개의 웹서버와 통신할거야.
1. 사용자가 노드를 제어하기 위한 http서버
2. 다른 노드들과 통신하기 위한 웹소켓서버
(팀플때는 노드별로 웹소켓서버를 만들어줬었는데 둘이연결할 웹소켓서버 하나만 있으면 상관없겠네)