Chain.go

package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

const (
	ConfirmInterval        = 600
	ResourceConfirmCount   = 10
	ValidatorCount         = 5
	GenesisAddress         = "genesis_address"
)

var Config = struct {
	ChainInfoPath string
}{
	ChainInfoPath: "./chain_info.txt",
}

type File struct{}

func (f *File) Read(filename string) string {
	content, err := os.ReadFile(filename)
	if err != nil {
		return ""
	}
	return strings.TrimSpace(string(content))
}

func (f *File) Overwrite(filename string, data interface{}) {
	content := fmt.Sprintf("%v", data)
	os.WriteFile(filename, []byte(content), 0644)
}

func (f *File) MakeDirectory(path string) error {
	return os.MkdirAll(path, os.ModePerm)
}

type Clock struct{}

func (c *Clock) Ufloortime() int64 {
	return time.Now().Unix()
}

type Signer struct{}

func (s *Signer) AddressValidity(address string) bool {
	// 실제 주소 유효성 검사 로직 구현
	return true
}

type Logger struct{}

func (l *Logger) Log(message string) {
	fmt.Println(message)
}

type MainBlock struct {
	BlockHash  string
	STimestamp int64
}

type ResourceBlock struct {
	MainHeight int
	BlockHash  string
	Validator  string
	Miner      string
}

type MainChain struct{}

func (mc *MainChain) Instance() *MainChain {
	return &MainChain{}
}

func (mc *MainChain) Block(height int) *MainBlock {
	// 실제 블록 조회 로직 구현
	return &MainBlock{
		BlockHash:  "blockhash",
		STimestamp: 1633036800,
	}
}

type ResourceChain struct{}

func (rc *ResourceChain) Instance() *ResourceChain {
	return &ResourceChain{}
}

func (rc *ResourceChain) LastHeight() int {
	// 실제 마지막 높이 조회 로직 구현
	return 100
}

func (rc *ResourceChain) LastBlock() *ResourceBlock {
	// 실제 마지막 블록 조회 로직 구현
	return &ResourceBlock{
		MainHeight: 100,
		BlockHash:  "lastblockhash",
		Validator:  "validator",
		Miner:      "miner",
	}
}

func (rc *ResourceChain) Block(height int) *ResourceBlock {
	// 실제 블록 조회 로직 구현
	return &ResourceBlock{
		MainHeight: height,
		BlockHash:  "blockhash",
		Validator:  "validator",
		Miner:      "miner",
	}
}

func (rc *ResourceChain) BeforeBlock(timestamp int) *ResourceBlock {
	// 실제 이전 블록 조회 로직 구현
	return &ResourceBlock{
		MainHeight: 100,
		BlockHash:  "blockhash",
		Validator:  "validator",
		Miner:      "miner",
	}
}

type Status struct{}

func (s *Status) Instance() *Status {
	return &Status{}
}

func (s *Status) Cache() {
	// 캐시 로직 구현
}

func (s *Status) BundleHeight() int {
	// 번들 높이 조회 로직 구현
	return 100
}

func (s *Status) Write(block *MainBlock) {
	// 블록 기록 로직 구현
}

type Chain struct{}

func (c *Chain) Reset() {
	c.SetFixedHeight(0)
}

func (c *Chain) FixedHeight() int {
	height, _ := strconv.Atoi(File{}.Read(Config.ChainInfoPath))
	return height
}

func (c *Chain) FixedPoint(timestamp int) int {
	lastHeight := ResourceChain{}.Instance().LastHeight()

	if lastHeight > 0 {
		confirmedHeight := c.ConfirmedHeight(timestamp)
		fixLimit := max(lastHeight-10, 1)
		return min(confirmedHeight, fixLimit)
	}

	return 0
}

func (c *Chain) UpdateFixedHeight() {
	fixedPoint := c.FixedPoint(Clock{}.Ufloortime())
	fixedHeight := c.FixedHeight()

	if fixedHeight < fixedPoint {
		targetBlock := ResourceChain{}.Instance().Block(fixedPoint)
		mainBlock := MainChain{}.Instance().Block(targetBlock.MainHeight)

		if targetBlock.BlockHash == mainBlock.BlockHash {
			c.SetFixedHeight(fixedPoint)
		}
	}
}

func (c *Chain) SetFixedHeight(height int) {
	File{}.Overwrite(Config.ChainInfoPath, height)
}

func (c *Chain) FixedResourceBlock() *ResourceBlock {
	return ResourceChain{}.Instance().Block(c.FixedHeight())
}

func (c *Chain) FixedMainHeight() int {
	resourceBlock := c.FixedResourceBlock()
	return resourceBlock.MainHeight
}

func (c *Chain) ConfirmedHeight(timestamp int) int {
	return c.ConfirmedResourceBlock(timestamp).MainHeight
}

func (c *Chain) ConfirmedResourceBlock(timestamp int) *ResourceBlock {
	confirmedTimestamp := max(timestamp-ConfirmInterval, 0)
	return ResourceChain{}.Instance().BeforeBlock(confirmedTimestamp)
}

func (c *Chain) ConfirmedMainBlock(timestamp int) *MainBlock {
	resourceBlock := c.ConfirmedResourceBlock(timestamp)
	return MainChain{}.Instance().Block(resourceBlock.MainHeight)
}

func (c *Chain) SelectValidators(confirmedHeight int) []string {
	if confirmedHeight <= ResourceConfirmCount {
		return []string{GenesisAddress}
	}

	if confirmedHeight == ResourceChain{}.Instance().LastBlock().MainHeight {
		return []string{}
	}

	var validators []string
	startHeight := max(confirmedHeight-ValidatorCount+1, 1)

	for i := startHeight; i <= confirmedHeight; i++ {
		block := ResourceChain{}.Instance().Block(i)
		if Signer{}.AddressValidity(block.Validator) {
			validators = append(validators, block.Validator)
		}
	}

	return validators
}

func (c *Chain) SelectMiners(confirmedHeight int) []string {
	if confirmedHeight <= ResourceConfirmCount {
		return []string{GenesisAddress}
	}

	if confirmedHeight == ResourceChain{}.Instance().LastBlock().MainHeight {
		return []string{}
	}

	var miners []string
	startHeight := max(confirmedHeight-ValidatorCount+1, 1)

	for i := startHeight; i <= confirmedHeight; i++ {
		block := ResourceChain{}.Instance().Block(i)
		if Signer{}.AddressValidity(block.Miner) {
			miners = append(miners, block.Miner)
		}
	}

	return miners
}

func (c *Chain) Bundling(once bool) {
	Status{}.Instance().Cache()

	fixedHeight := c.FixedMainHeight()
	bundleHeight := Status{}.Instance().BundleHeight()

	for i := bundleHeight + 1; i <= fixedHeight; i++ {
		Status{}.Instance().Write(MainChain{}.Instance().Block(i))

		if i%256 == 0 || i == fixedHeight {
			Logger{}.Log(fmt.Sprintf("Commit Bundle: %d", i))

			if once {
				break
			}
		}
	}
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func main() {
	chain := &Chain{}
	chain.Reset()
	fmt.Println("Fixed Height:", chain.FixedHeight())
	chain.UpdateFixedHeight()
	fmt.Println("Updated Fixed Height:", chain.FixedHeight())
}

주요 구성 요소와 함수

설정 및 상수

  • ConfirmInterval: 블록 확정 시간 간격(초)입니다.

  • ResourceConfirmCount: 리소스 블록의 확정 블록 수입니다.

  • ValidatorCount: 검증자 수입니다.

  • GenesisAddress: 제네시스 블록의 주소입니다.

  • Config.ChainInfoPath: 체인 정보가 저장되는 파일 경로입니다.

파일 읽기/쓰기 함수

File 구조체는 파일을 읽고 쓰는 작업을 수행합니다.

  • Read: 파일을 읽고 문자열로 반환합니다.

  • Overwrite: 파일의 내용을 주어진 데이터로 덮어씁니다.

  • MakeDirectory: 주어진 경로에 디렉토리를 생성합니다.

시간 및 서명 유효성 검사 함수

ClockSigner 구조체는 시간과 서명 유효성 검사를 담당합니다.

  • Ufloortime: 현재 시간을 Unix 타임스탬프로 반환합니다.

  • AddressValidity: 주소의 유효성을 검사합니다.

로깅 함수

Logger 구조체는 로그 메시지를 출력합니다.

  • Log: 주어진 메시지를 출력합니다.

블록체인 구조체

블록체인의 주요 구조체인 MainBlock, ResourceBlock, MainChain, ResourceChain, Status는 블록체인의 상태를 관리합니다.

체인 관리 구조체

Chain 구조체는 체인의 상태를 관리하고, 중요한 작업을 수행합니다.

보조 함수

  • max: 두 정수 중 큰 값을 반환합니다.

  • min: 두 정수 중 작은 값을 반환합니다.

main 함수

main 함수는 프로그램의 진입점으로, 체인을 초기화하고 상태를 업데이트합니다.

요약

이 코드는 블록체인 시스템에서 체인의 상태를 관리하고 블록을 처리하는 다양한 작업을 수행하는 데 사용됩니다. 주요 기능은 다음과 같습니다:

  • 체인의 고정된 높이 설정 및 업데이트

  • 블록 확정 및 검증자 선택

  • 블록 번들링

  • 파일 시스템을 통한 데이터 저장 및 관리

이 코드는 블록체인 시스템의 중요한 부분을 구성하며, 체인의 일관성과 무결성을 유지하는 데 중요한 역할을 합니다.

Last updated