SignedTransaction.go

package model

import (
	"errors"

	"github.com/Saseul/util"
)

type SignedTransaction struct {
	SignedData
}

func NewSignedTransaction(item map[string]interface{}) *SignedTransaction {
	st := &SignedTransaction{
		SignedData: SignedData{
			Data:         item["transaction"].(map[string]interface{}),
			PublicKey:    item["public_key"].(string),
			Signature:    item["signature"].(string),
			Cid:          item["transaction"].(map[string]interface{})["cid"].(string),
			Type:         item["transaction"].(map[string]interface{})["type"].(string),
			Timestamp:    int64(item["transaction"].(map[string]interface{})["timestamp"].(float64)),
			Attributes:   make(map[string]interface{}),
			CachedUniversal: make(map[string]interface{}),
			CachedLocal:  make(map[string]interface{}),
		},
	}
	st.Hash = st.Hash()
	return st
}

func (st *SignedTransaction) Validity() (bool, error) {
	if st.Data == nil {
		return false, errors.New("The signed transaction must contain the 'transaction' parameter.")
	}

	if st.PublicKey == "" {
		return false, errors.New("The signed transaction must contain the 'public_key' parameter.")
	}

	if _, ok := st.Data["public_key"].(string); !ok {
		return false, errors.New("Parameter 'public_key' must be of string type.")
	}

	if !util.SignerKeyValidity(st.PublicKey) {
		return false, errors.New("Invalid public key: " + st.PublicKey)
	}

	if st.Signature == "" {
		return false, errors.New("The signed transaction must contain the 'signature' parameter.")
	}

	if _, ok := st.Data["signature"].(string); !ok {
		return false, errors.New("Parameter 'signature' must be of string type.")
	}

	if st.Type == "" {
		return false, errors.New("The signed transaction must contain the 'transaction.type' parameter.")
	}

	if _, ok := st.Data["type"].(string); !ok {
		return false, errors.New("Parameter 'transaction.type' must be of string type.")
	}

	if st.Timestamp == 0 {
		return false, errors.New("The signed transaction must contain the 'transaction.timestamp' parameter.")
	}

	if _, ok := st.Data["timestamp"].(float64); !ok {
		return false, errors.New("Parameter 'transaction.timestamp' must be of float64 type.")
	}

	if !util.SignerSignatureValidity(st.Hash, st.PublicKey, st.Signature) {
		return false, errors.New("Invalid signature: " + st.Signature + " (transaction hash: " + st.Hash + ")")
	}

	return true, nil
}

func (st *SignedTransaction) Obj() map[string]interface{} {
	return map[string]interface{}{
		"transaction": st.Data,
		"public_key":  st.PublicKey,
		"signature":   st.Signature,
	}
}

이 μ½”λ“œλŠ” SignedTransactionλΌλŠ” ꡬ쑰체와 κ΄€λ ¨λœ λ‹€μ–‘ν•œ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 각 ν•¨μˆ˜κ°€ μ–΄λ–€ 역할을 ν•˜λŠ”μ§€ ν•˜λ‚˜ν•˜λ‚˜ μ„€λͺ…ν•΄ λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€.

SignedTransaction ꡬ쑰체

SignedTransaction κ΅¬μ‘°μ²΄λŠ” μ„œλͺ…λœ νŠΈλžœμž­μ…˜μ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€. 이 κ΅¬μ‘°μ²΄λŠ” SignedData ꡬ쑰체λ₯Ό ν¬ν•¨ν•˜κ³  있으며, μ„œλͺ…λœ νŠΈλžœμž­μ…˜ 데이터λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 좔가적인 λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

NewSignedTransaction ν•¨μˆ˜

이 ν•¨μˆ˜λŠ” μ΄ˆκΈ°ν™” 데이터λ₯Ό λ°›μ•„ μƒˆλ‘œμš΄ SignedTransaction 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

이 ν•¨μˆ˜λŠ” λ‹€μŒκ³Ό 같은 단계λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€:

  1. SignedTransaction 객체λ₯Ό μƒμ„±ν•˜κ³ , SignedData ꡬ쑰체λ₯Ό μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€.

  2. νŠΈλžœμž­μ…˜ 데이터, 곡개 ν‚€, μ„œλͺ…, ν΄λΌμ΄μ–ΈνŠΈ ID, νƒ€μž…, νƒ€μž„μŠ€νƒ¬ν”„ 등을 μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€.

  3. Hash λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ ν•΄μ‹œ 값을 μ„€μ •ν•©λ‹ˆλ‹€.

Validity ν•¨μˆ˜

이 ν•¨μˆ˜λŠ” SignedTransaction 객체의 μœ νš¨μ„±μ„ κ²€μ‚¬ν•©λ‹ˆλ‹€.

이 ν•¨μˆ˜λŠ” λ‹€μŒκ³Ό 같은 단계λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€:

  1. st.Dataκ°€ nil인 경우 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

  2. st.PublicKeyκ°€ 빈 λ¬Έμžμ—΄μΈ 경우 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

  3. st.Data["public_key"]κ°€ λ¬Έμžμ—΄ νƒ€μž…μ΄ μ•„λ‹Œ 경우 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

  4. 곡개 ν‚€μ˜ μœ νš¨μ„±μ„ κ²€μ‚¬ν•©λ‹ˆλ‹€.

  5. st.Signatureκ°€ 빈 λ¬Έμžμ—΄μΈ 경우 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

  6. st.Data["signature"]κ°€ λ¬Έμžμ—΄ νƒ€μž…μ΄ μ•„λ‹Œ 경우 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

  7. st.Type이 빈 λ¬Έμžμ—΄μΈ 경우 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

  8. st.Data["type"]이 λ¬Έμžμ—΄ νƒ€μž…μ΄ μ•„λ‹Œ 경우 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

  9. st.Timestampκ°€ 0인 경우 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

  10. st.Data["timestamp"]κ°€ float64 νƒ€μž…μ΄ μ•„λ‹Œ 경우 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

  11. μ„œλͺ…μ˜ μœ νš¨μ„±μ„ κ²€μ‚¬ν•©λ‹ˆλ‹€.

  12. λͺ¨λ“  쑰건을 λ§Œμ‘±ν•˜λ©΄ true와 nil을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

Obj ν•¨μˆ˜

이 ν•¨μˆ˜λŠ” SignedTransaction 객체λ₯Ό λ§΅ ν˜•νƒœλ‘œ λ°˜ν™˜ν•©λ‹ˆλ‹€. 이 맡은 JSON ν˜•μ‹μœΌλ‘œ λ³€ν™˜ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€.

이 ν•¨μˆ˜λŠ” SignedTransaction 객체의 μ£Όμš” 데이터λ₯Ό λ§΅ ν˜•νƒœλ‘œ λ°˜ν™˜ν•©λ‹ˆλ‹€. λ°˜ν™˜λœ 맡은 JSON ν˜•μ‹μœΌλ‘œ μ‰½κ²Œ λ³€ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

전체 μ½”λ“œ μ˜ˆμ‹œ

이 μ½”λ“œλŠ” μ„œλͺ…λœ νŠΈλžœμž­μ…˜ 데이터λ₯Ό μƒμ„±ν•˜κ³ , κ·Έ 데이터에 λŒ€ν•΄ λ‹€μ–‘ν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 방법을 λ³΄μ—¬μ€λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, 데이터λ₯Ό μ΄ˆκΈ°ν™”ν•˜κ³  μœ νš¨μ„±μ„ κ²€μ‚¬ν•˜λ©° 객체λ₯Ό λ§΅ ν˜•νƒœλ‘œ λ³€ν™˜ν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이 μ˜ˆμ œμ—μ„œλŠ” NewSignedTransaction ν•¨μˆ˜λ‘œ μƒˆλ‘œμš΄ μ„œλͺ…λœ νŠΈλžœμž­μ…˜ 데이터λ₯Ό μƒμ„±ν•˜κ³ , Validity ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ λ°μ΄ν„°μ˜ μœ νš¨μ„±μ„ κ²€μ‚¬ν•©λ‹ˆλ‹€. λ§ˆμ§€λ§‰μœΌλ‘œ, Obj ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 객체λ₯Ό λ§΅ ν˜•νƒœλ‘œ λ³€ν™˜ν•˜μ—¬ 좜λ ₯ν•©λ‹ˆλ‹€.

Last updated