#1 Blocks and Chain

가장 기초가 되는 block과 blockchain 만들기

본 튜토리얼은 https://github.com/tensor-programming/golang-blockchain 레파지토리를 100% 참고하여 만들었습니다.

한글로 주석을 단 코드는 https://github.com/siisee11/golang-blockchain 의 step1 브랜치에 있습니다 .

Setup workspace

$GOPATH/src 에서 아래 커맨드를 입력하여 코딩을 시작할 workspace를 구성한다. module 초기화를 하는데 배포를 위해서 깃허브 링크와 동일하게 작성해야한다.

mkidr golang-blockchain && cd golang-blockchain
go mod init github.com/<user-name>/golang-blockchain

main.go

main.go 파일을 열어 아래와 같이 작성합니다. 코드는 단순하기 때문에 설명은 주석으로 대체하겠습니다. step 1의 관한 이론적 지식은 blockchain structure에서 찾아볼 수 있습니다.

package main

import (
	"bytes"
	"crypto/sha256"
	"fmt"
)

type BlockChain struct {
	blocks []*Block
}

type Block struct {
	Hash     []byte
	Data     []byte
	PrevHash []byte
}

func (b *Block) DeriveHash() {
	info := bytes.Join([][]byte{b.Data, b.PrevHash}, []byte{})
	hash := sha256.Sum256(info)
	b.Hash = hash[:]
}

func CreateBlock(data string, prevHash []byte) *Block {
	block := &Block{[]byte{}, []byte(data), prevHash}
	block.DeriveHash()
	return block
}

func (chain *BlockChain) AddBlock(data string) {
	prevBlock := chain.blocks[len(chain.blocks)-1]
	new := CreateBlock(data, prevBlock.Hash)
	chain.blocks = append(chain.blocks, new)
}

func Genesis() *Block {
	return CreateBlock("Genesis", []byte{})
}

func InitBlockChain() *BlockChain {
	return &BlockChain{[]*Block{Genesis()}}
}

func main() {
	chain := InitBlockChain()

	chain.AddBlock("First Block after Genesis")
	chain.AddBlock("Second Block after Genesis")
	chain.AddBlock("Third Block after Genesis")

	for _, block := range chain.blocks {
		fmt.Printf("Previous Hash: %x\n", block.PrevHash)
		fmt.Printf("Data in Block: %s\n", block.Data)
		fmt.Printf("Hash: %x\n", block.Hash)
	}
}

실행 시키면 아래와 같은 결과가 나옵니다.

두번째 블록 데이터의 대문자 S를 소문자 s로 바꿔보겠습니다.

암호화 함수 특성에 따라 두번째와 세번째 블럭의 Hash값이 크게 바뀌게 됩니다. 값을 바꾸면 이어진 모든 블럭의 해시가 바뀌는 특성 덕분에 blockchain의 데이터를 수정하는 것이 매우 어렵게 됩니다.

blockchain/block.go

블록에 관련된 코드를 blockchain/block.go 로 옮깁니다. main을 제외한 type Block부터 옮기면 됩니다. 또, BlockChain의 Block을 외부에서 사용할 것이기 때문에 관습상 첫 문자를 대문자로 바꿔줍니다.

main.go 도 import를 진행해주고 B를 대문자로 바꿔줍니다.

Last update: 04/26/2021

Last updated

Was this helpful?