Chunk.go

package model

import (
	"encoding/json"
	"sort"
	"strconv"
	"strings"

	"github.com/saseul/util"
)

type Chunk struct {
	PreviousBlockHash string   `json:"previous_blockhash"`
	STimestamp        int64    `json:"s_timestamp"`
	Transactions      []string `json:"transactions"`

	ChunkHash string `json:"chunk_hash"`
	PublicKey string `json:"public_key"`
	Signature string `json:"signature"`
}

func NewChunk(initialInfo map[string]interface{}) *Chunk {
	chunk := &Chunk{
		PreviousBlockHash: initialInfo["previous_blockhash"].(string),
		STimestamp:        int64(initialInfo["s_timestamp"].(float64)),
		Transactions:      toStringSlice(initialInfo["transactions"]),
		ChunkHash:         initialInfo["chunk_hash"].(string),
		PublicKey:         initialInfo["public_key"].(string),
		Signature:         initialInfo["signature"].(string),
	}
	return chunk
}

func (c *Chunk) Signer() string {
	return util.Address(c.PublicKey)
}

func (c *Chunk) ChunkRoot() string {
	return util.MerkleRoot(c.Thashs())
}

func (c *Chunk) Thashs() []string {
	thashs := c.Transactions
	sort.Strings(thashs)
	return thashs
}

func (c *Chunk) SignChunk(account *Account) {
	chunkRoot := c.ChunkRoot()

	c.ChunkHash = util.TimeHash(c.PreviousBlockHash + chunkRoot, strconv.FormatInt(c.STimestamp, 10))
	c.PublicKey = account.PublicKey
	c.Signature = util.Signature(c.ChunkHash, account.PrivateKey)
}

func (c *Chunk) HashValidity() bool {
	chunkRoot := c.ChunkRoot()
	chunkHash := util.TimeHash(c.PreviousBlockHash + chunkRoot, strconv.FormatInt(c.STimestamp, 10))

	return chunkHash == c.ChunkHash
}

func (c *Chunk) SignatureValidity() bool {
	return util.SignatureValidity(c.ChunkHash, c.PublicKey, c.Signature)
}

func (c *Chunk) StructureValidity() bool {
	return c.PreviousBlockHash != "" &&
		c.STimestamp != 0 &&
		len(c.Transactions) > 0 &&
		c.ChunkHash != "" &&
		c.PublicKey != "" &&
		c.Signature != ""
}

func (c *Chunk) Validity() bool {
	return c.StructureValidity() &&
		c.HashValidity() &&
		c.SignatureValidity()
}

func (c *Chunk) Obj() map[string]interface{} {
	return map[string]interface{}{
		"previous_blockhash": c.PreviousBlockHash,
		"s_timestamp":        c.STimestamp,
		"transactions":       c.Transactions,
		"chunk_hash":         c.ChunkHash,
		"public_key":         c.PublicKey,
		"signature":          c.Signature,
	}
}

func (c *Chunk) JSON() string {
	obj := c.Obj()
	jsonStr, _ := json.Marshal(obj)
	return string(jsonStr)
}

func toStringSlice(data interface{}) []string {
	if data == nil {
		return nil
	}

	switch v := data.(type) {
	case []interface{}:
		result := make([]string, len(v))
		for i, value := range v {
			result[i] = value.(string)
		}
		return result
	case []string:
		return v
	default:
		return nil
	}
}

1. Chunk 구조체

Chunk 구조체는 블록체인에서 사용되는 청크(블록)의 정보를 저장합니다. 여섯 가지 필드를 가지고 있습니다:

  • PreviousBlockHash: 이전 블록의 해시

  • STimestamp: 청크가 생성된 시간의 타임스탬프

  • Transactions: 청크에 포함된 트랜잭션 목록

  • ChunkHash: 청크의 해시

  • PublicKey: 청크를 서명한 공개 키

  • Signature: 청크의 서명

2. NewChunk 함수

이 함수는 초기 정보 맵을 기반으로 새로운 Chunk 인스턴스를 생성합니다.

  • initialInfo 맵에서 값을 가져와서 Chunk 구조체의 각 필드를 초기화합니다.

  • Transactions 필드는 toStringSlice 함수를 사용하여 문자열 슬라이스로 변환합니다.

3. Signer 메서드

이 메서드는 청크를 서명한 사용자의 주소를 반환합니다.

  • PublicKey 필드를 사용하여 주소를 생성합니다.

4. ChunkRoot 메서드

이 메서드는 청크의 루트 해시를 반환합니다.

  • Thashs 메서드를 호출하여 트랜잭션 해시 목록을 가져오고, 이를 기반으로 머클 루트 해시를 계산합니다.

5. Thashs 메서드

이 메서드는 트랜잭션 해시 목록을 반환합니다.

  • Transactions 필드를 정렬하여 반환합니다.

6. SignChunk 메서드

이 메서드는 주어진 계정을 사용하여 청크에 서명합니다.

  • 청크의 루트 해시를 계산합니다.

  • PreviousBlockHashchunkRoot, STimestamp를 사용하여 청크 해시를 생성합니다.

  • 주어진 계정의 공개 키와 개인 키를 사용하여 청크에 서명합니다.

7. HashValidity 메서드

이 메서드는 청크 해시의 유효성을 검사합니다.

  • PreviousBlockHash, chunkRoot, STimestamp를 사용하여 청크 해시를 다시 계산하고, 현재 청크의 해시와 비교합니다.

8. SignatureValidity 메서드

이 메서드는 청크 서명의 유효성을 검사합니다.

  • ChunkHash, PublicKey, Signature를 사용하여 서명의 유효성을 검증합니다.

9. StructureValidity 메서드

이 메서드는 청크 구조의 유효성을 검사합니다.

  • 각 필드가 올바르게 설정되어 있는지 확인합니다.

10. Validity 메서드

이 메서드는 청크의 전체적인 유효성을 검사합니다.

  • 구조, 해시, 서명 유효성을 모두 검사합니다.

11. Obj 메서드

이 메서드는 청크의 모든 필드를 포함하는 맵을 반환합니다.

  • 청크의 모든 필드를 키-값 쌍으로 포함하는 맵을 생성하여 반환합니다.

12. JSON 메서드

이 메서드는 청크의 정보를 JSON 문자열로 반환합니다.

  • Obj 메서드의 결과를 JSON으로 직렬화하여 반환합니다.

13. toStringSlice 함수

이 함수는 주어진 데이터를 문자열 슬라이스로 변환합니다.

  • 입력 데이터가 nil인 경우 nil을 반환합니다.

  • 입력 데이터가 인터페이스 슬라이스인 경우, 각 값을 문자열로 변환하여 슬라이스로 반환합니다.

  • 입력 데이터가 이미 문자열 슬라이스인 경우, 그대로 반환합니다.

  • 다른 경우 nil을 반환합니다.

이 전체 코드는 Chunk라는 블록체인 데이터 구조체를 관리하기 위한 다양한 기능을 제공하며, 유효성 검사, 서명, JSON 변환 등의 작업을 수행할 수 있도록 설계되었습니다.

Last updated