호랑이한테물릴래

Go언어로 간단한 블록체인 구현 본문

DevOps/Chain

Go언어로 간단한 블록체인 구현

호랑이한테물릴래 2022. 11. 29. 21:43
반응형

Golang x Blockchain

블록체인의 구조에 대해서 이해하더라도, 직접 코드로 구현해보는 것만큼 좋은게 없다. 이더리움도 Go로 개발할 정도로, Go는 빠른 처리속도를 자랑하기 때문에 다양한 블록체인 프로젝트에 Golang이 많이 사용된다.

간단한 구조로 구현해보고 개념도 학습해보자.

Block

블록은 블록체인의 가치있는 정보를 저장하는 매개체다. 비트코인의 경우엔 트랜잭션같은 거래내역들이 저장된다. 외에도 version, timestamp, hash 들이 저장되어 개별 블록이 구분되고 연결될 수 있다. 블록의 기본적인 구성은 아래와 같다.

type Block struct {
	Timestamp     int64
	Data          []byte
	PrevBlockHash []byte
	Hash          []byte
}
  • Timestamp : 현재의 타임스탬프
  • Data : 블록이 포함하는 가치있는 정보들
  • PrevBlockHash : 이전 블록의 해시값
  • Hash : 블록의 해시값

여기서 Hash는 블록체인의 보안을 담당한다고 볼 수 있을 정도로 아주 중요한 역할을 한다. Hash는 SHA-256 hash에 의해서 블록과 블록을 사슬처럼 연결한다.

func (b *Block) SetHash() {
	timestamp := []byte(strconv.FormatInt(b.Timestamp, 10))
	headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{})
	hash := sha256.Sum256(headers)

	b.Hash = hash[:]
}

위와 같이 블록에 포함된 모든 구성 요소들에 의해서 하나의 Hash가 만들어지며 다시 이 Hash가 다음 블록에 포함되면서 마치 블록과 블록 사이의 사슬처럼 concatenate해준다.

func NewBlock(data string, prevBlockHash []byte) *Block {
	block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}}
	block.SetHash()
	return block
}

그리고 새로운 블록을 생성할 때는, data와 이전 Hash를 파라미터로 넣고, 이를 모아 Hash를 생성하여 완성된 Block을 return한다.

package main

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

// Block keeps block headers
type Block struct {
	Timestamp     int64
	Data          []byte
	PrevBlockHash []byte
	Hash          []byte
}

// SetHash calculates and sets block hash
func (b *Block) SetHash() {
	timestamp := []byte(strconv.FormatInt(b.Timestamp, 10))
	headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{})
	hash := sha256.Sum256(headers)

	b.Hash = hash[:]
}

// NewBlock creates and returns Block
func NewBlock(data string, prevBlockHash []byte) *Block {
	block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}}
	block.SetHash()
	return block
}

// NewGenesisBlock creates and returns genesis Block
func NewGenesisBlock() *Block {
	return NewBlock("Genesis Block", []byte{})
}

type Blockchain struct {
	blocks []*Block
}

func (bc *Blockchain) AddBlock(data string) {
	prevBlock := bc.blocks[len(bc.blocks)-1]
	newBlock := NewBlock(data, prevBlock.Hash)
	bc.blocks = append(bc.blocks, newBlock)
}

func NewBlockchain() *Blockchain {
	return &Blockchain{[]*Block{NewGenesisBlock()}}
}

func main() {
	bc := NewBlockchain()

	bc.AddBlock("Send 1 BTC to Ivan")
	bc.AddBlock("Send 2 more BTC to Ivan")

	for _, block := range bc.blocks {
		fmt.Printf("Prev. hash: %x\n", block.PrevBlockHash)
		fmt.Printf("Data: %s\n", block.Data)
		fmt.Printf("Hash: %x\n", block.Hash)
		fmt.Println()
	}
}

https://jeiwan.net/posts/building-blockchain-in-go-part-1/

 

Building Blockchain in Go. Part 1: Basic Prototype - Going the distance

Chinese translations: by liuchengxu, by zhangli1. Introduction Blockchain is one of the most revolutionary technologies of the 21st century, which is still maturing and which potential is not fully realized yet. In its essence, blockchain is just a distrib

jeiwan.net

 

반응형
0 Comments
댓글쓰기 폼