일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- RBAC
- 재진입
- 일시정지
- git commit
- 프록시패턴
- github 에러
- 업그레이더블 컨트랙트
- 멀티시그
- 회로차단
- 팩토리패턴
- 싱글톤패턴
- 옵저버패턴
- 솔리디티
- 트러블슈팅
- git add
- 코드스테이츠
- 인센티브 기반 커뮤니티
- 투표
- solidity
- 팀 프로젝트
- 코드리뷰
- 부트캠프
- 스테이트머신패턴
- github
- 배팅
- 블록체인
- 웹툰
- 토큰노믹스
- 디자인 패턴
- Today
- Total
보다 더 생생한 기록
[GO] [코드리뷰] 블록체인 구축 코드 리뷰 - (1) 본문
노마드코드 강의를 들으며 클론코딩을 하고 있습니다. 강의가 끝난 뒤, 제 입맛대로 여러 기능을 가진 체인을 구축할 예정이지만, 수강중에 있으므로 코드리뷰는 노마드코더 클론코드를 위주로 진행합니다.
리뷰의 추가적인 목적으로는, 스스로 깨닫고 여타 큰 도움 없이 현 진도와 비슷한 체인을 구축하는것에 목적을 둡니다. (리뷰 후 자체 체인 구축에는 클라이언트단 없이, DB와 백엔드만 들어갈 예정입니다.)
Overview
- 강의 진도 : 8강 PERSISTENCE (36%)
- 기술스택 : go, boltDB, gorilla-mux, cli 관련 (os, flag, etc)
Whole Flow ( 클라이언트 제외 )
백엔드 실행
- CLI 커맨드로 서버 실행
- blockchain의 포인터가
- nil 값이면 : 서버를 킨 것이므로 비어있을 수 밖에 없다. 그래서 DB에서 block들을 저장한 내용이 있는지 확인한다
- DB에 저장한 내용이 있다면 불러온다.
- DB에 저장한 내용이 없다면 Genesis Block을 생성해서 DB에 블록 내용을 추가해준다.
- nil 값이 아니면 : 이미 서버가 실행되고 있었다는 뜻이므로 아무런 제스쳐가 필요없음
- nil 값이면 : 서버를 킨 것이므로 비어있을 수 밖에 없다. 그래서 DB에서 block들을 저장한 내용이 있는지 확인한다
블록 추가
1. AddBlock(data string)을 이용해 createBlock()에 데이터와 이전 해시값, 블록높이를 넣어 보낸다.
createBlock(data string, prevHash string, height int) *Block
그러면 Block struct 형태를 가진 block을 생성해, 그 포인터에 값을 넣어준다. (hash값은 다음단계에서 채워질 예정)
block := &Block{
Data: data,
Hash: "",
PrevHash: prevHash,
Height: height,
}
그 뒤, 3가지 값을 payload로 묶고 sha256 암호화를 거쳐, 블록의 해시값을 구한 뒤, 이를 block의 hash값에 넣어준다.
payload := block.Data + block.PrevHash + fmt.Sprint(block.Height)
block.Hash = fmt.Sprintf("%x", sha256.Sum256([]byte(payload)))
이제 block을 AddBlock으로 반환해서 해시값과 블록높이를,
체인의 현 블록과 관련된 데이터인 blockchain struct 포인터에 업데이트 해준다.
type blockchain struct {
NewestHash string
Height int
}
func (b *blockchain) AddBlock(data string) {
block := createBlock(data, b.NewestHash, b.Height+1)
b.NewestHash = block.Hash
b.Height = block.Height
b.persist()
}
이후 blockchain struct의 포인터값을 db에 저장시켜준다.
// 직전 사용한 b.persist()
func (b *blockchain) persist() {
db.SaveBlockchain(utils.ToBytes(b))
}
전체 블록 조회
Blocks() 함수내에서, blocks라는 Block struct 형태의 빈 slice를 생성한다.
그 뒤, 저장된 NewestHash를 가져온다.
type blockchain struct {
NewestHash string
Height int
}
이제 이걸 타켓화해서 DB Block에서 해시 컬럼을 조회한다.
{
"data": "Data for my block",
"hash": "c57fca35b986fc973b8f1b535ae9970c081606d5bffde0c3def73cba9cf50bf9",
"prevHash": "110e8eb40de97b0929e53a3b0cd2d697a4bd25a38fe1a5f069d6d35a40976e17",
"height": 5
},
조회하면 위와 같은 Block Object가 나오는데, blocks slice에 append로 저장하고, prevHash를 타겟으로 지정한다.
이걸 반복하면 Genesis Block 이 나올텐데, 그때는 prevHash가 빈 문자열이므로 중지한다.
지금까지 조회하면서 축적된 slice를 반환하여 전체블록을 화면에 뿌려준다.
특정 블록 조회
현재는 hash 값으로 검색하는 함수만 구현되어있다. 이 해시를 DB hash 컬럼에서 조회한다.
그러면 전체 블록 조회처럼 Block Object가 나오는데 이를 반환하여, 화면에 뿌려준다.
'Go' 카테고리의 다른 글
[GO] Method VS Function 선언 선택 공식, 함수 또는 메서드가 어떤 역할 하는지 선언만 보고 간단하게 파악하기 (0) | 2023.09.08 |
---|---|
[GO] once.Do() + 데드락 (0) | 2023.09.08 |
[GO] [코드리뷰] 블록체인 구축 코드 리뷰 (PoW) - (2) (0) | 2023.09.02 |
[GO] go get VS go install (zsh: command not found) (0) | 2023.08.30 |
[Go] ERROR : command-line-arguments, gopls - go 초기 에러 (0) | 2023.06.14 |