๊ถ๊ทน์ ์ผ๋ก ๋จ์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์๋ ๋ธ๋ก์ฒด์ธ์ผ๋ก ๋๋๋ ค๋ฉด ํ๋ก์ ํธ์ 3๊ฐ์ง ์ค์ํ ์์๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
- ๋ธ๋ก ๋ฐ์ดํฐ ๊ตฌ์กฐ ๋ฐ ๋ฐฉ๋ฒ์ ๋ํ ์ค๋ช
- ๋ฐ์ดํฐ ๊ตฌ์กฐ ๋ฐ ํธ๋์ญ์ ๋ฐฉ๋ฒ์ ๋ํ ์ค๋ช
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ธ๋ก์ ์ ์ฅํ๊ณ ํด์๋ ๋์ด(๋๋ ๋ค๋ฅธ ๊ฒ)๋ก ๋ธ๋ก์ ์ฐพ๋ ๋ธ๋ก์ฒด์ธ ๊ธฐ๋ฅ์ ๋๋ค.
์ฐ์
์ฉ ๋ธ๋ก์ฒด์ธ์ ๊ดํ ๋ ๋ฒ์งธ ๊ธ์
๋๋ค.
์ด ์๋ฆฌ์ฆ์ ์ด์ ๊ธฐ์ฌ์ ๋ํด ๋ ์๋ค์ด ๋์๊ฒ ๋ฌผ์๋ ์ง๋ฌธ์ ๊ธฐ์ตํ๋ฉด์ ์ฃผ๋ชฉํด์ผ ํ ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ด ๊ฒฝ์ฐ LevelDB ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ธ๋ก์ฒด์ธ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐ ์ฌ์ฉ๋์ง๋ง MySQL๊ณผ ๊ฐ์ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ๋ฐ ๋ฐฉํด๊ฐ ๋๋ ๊ฒ์ ์์ต๋๋ค. ์ด์ ์ด ๋ฐ์ดํฐ์ ๊ตฌ์กฐ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๊ฑฐ๋๋ถํฐ ์์ํด ๋ณด๊ฒ ์ต๋๋ค.
๋ฐ์ดํฐ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
type TX struct {
DataType byte
TxHash string
TxType byte
Timestamp int64
INs []TxIn
OUTs []TxOut
}
type TxIn struct {
ThatTxHash string
TxOutN int
ByteCode string
}
type TxOut struct {
Value int
ByteCode string
}
TX๋ ๋ฐ์ดํฐ ์ ํ(ํธ๋์ญ์ 2์ ๊ฒฝ์ฐ), ํด๋น ํธ๋์ญ์ ์ ํด์, ํธ๋์ญ์ ์์ฒด์ ์ ํ, ํ์์คํฌํ, ์ ๋ ฅ ๋ฐ ์ถ๋ ฅ์ ์ ์ฅํฉ๋๋ค. TxIn ์ ๋ ฅ์ ์ถ๋ ฅ์ด ์ฐธ์กฐ๋๋ ํธ๋์ญ์ ์ ํด์, ์ด ์ถ๋ ฅ ๋ฐ ๋ฐ์ดํธ์ฝ๋์ ์๋ฅผ ์ ์ฅํ๊ณ , TxOut ์ถ๋ ฅ์ ์ผ๋ถ ๊ฐ๊ณผ ๋ฐ์ดํธ์ฝ๋๋ฅผ ์ ์ฅํฉ๋๋ค.
์ด์ ํธ๋์ญ์ ์ด ๋ฐ์ดํฐ์ ๋ํด ์ด๋ค ์์ ์ ์ํํ ์ ์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค. ๋ฐฉ๋ฒ์ ์ดํด ๋ณด๊ฒ ์ต๋๋ค.
ํธ๋์ญ์ ์ ์์ฑํ๋ ค๋ฉด transaction.NewTransaction(txtype byte) *TX ํจ์๋ฅผ ์ฌ์ฉํ์ธ์.
AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) ๋ฉ์๋๋ ํธ๋์ญ์ ์ ์ ๋ ฅ์ ์ถ๊ฐํฉ๋๋ค.
AddTxOut(value int, data []byte) (*TxOut, error) ๋ฉ์๋๋ ํธ๋์ญ์ ์ ์ถ๋ ฅ์ ์ถ๊ฐํฉ๋๋ค.
ToBytes() []byte ๋ฉ์๋๋ ํธ๋์ญ์ ์ ๋ฐ์ดํธ ์กฐ๊ฐ์ผ๋ก ๋ณํํฉ๋๋ค.
๋ด๋ถ ํจ์ preByteHash(bytes []byte) string์ Build() ๋ฐ Check()์์ ์ฌ์ฉ๋์ด ์์ฑ๋ ํธ๋์ญ์ ํด์๊ฐ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ฑ๋ ํธ๋์ญ์ ํด์์ ํธํ๋๋๋ก ๋ง๋ญ๋๋ค.
Build() ๋ฉ์๋๋ ํธ๋์ญ์ ํด์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํฉ๋๋ค: tx.TxHash = preByteHash(tx.ToBytes()).
ToJSON() ๋ฌธ์์ด ๋ฉ์๋๋ ํธ๋์ญ์ ์ JSON ๋ฌธ์์ด๋ก ๋ณํํฉ๋๋ค.
FromJSON(data []byte) ์ค๋ฅ ๋ฉ์๋๋ ๋ฐ์ดํธ ์กฐ๊ฐ์ผ๋ก ์ ๋ฌ๋ JSON ํ์์์ ํธ๋์ญ์ ์ ๋ก๋ํฉ๋๋ค.
Check() bool ๋ฉ์๋๋ ํธ๋์ญ์ ํด์ ํ๋์ ๊ฒฐ๊ณผ ํด์๋ฅผ ์ด ํธ๋์ญ์ ์ ํด์ํ ๊ฒฐ๊ณผ(ํด์ ํ๋ ๋ฌด์)๋ก ์ป์ ํด์์ ๋น๊ตํฉ๋๋ค.
๊ฑฐ๋๊ฐ ๋ธ๋ก์ ์ถ๊ฐ๋ฉ๋๋ค.
๋ธ๋ก ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ ๋ ๋ฐฉ๋ํฉ๋๋ค.
type Block struct {
DataType byte
BlockHeight int
Timestamp int64
HeaderSize int
PrevBlockHash string
SelfBlockHash string
TxsHash string
MerkleRoot string
CreatorPublicKey string
CreatorSig string
Version int
TxsN int
Txs []transaction.TX
}
DataType์ ๋ฐ์ดํฐ ์ ํ์ ์ ์ฅํ๊ณ , ๋ ธ๋๋ ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ธ๋ก์ ํธ๋์ญ์ ์ด๋ ๋ค๋ฅธ ๋ฐ์ดํฐ์ ๊ตฌ๋ณํฉ๋๋ค. ๋ธ๋ก์ ๊ฒฝ์ฐ ์ด ๊ฐ์ 1์ ๋๋ค.
BlockHeight๋ ๋ธ๋ก์ ๋์ด๋ฅผ ์ ์ฅํฉ๋๋ค.
ํ์์คํฌํ ํ์์คํฌํ.
HeaderSize๋ ๋ธ๋ก ํฌ๊ธฐ(๋ฐ์ดํธ)์
๋๋ค.
PrevBlockHash๋ ์ด์ ๋ธ๋ก์ ํด์์ด๊ณ SelfBlockHash๋ ํ์ฌ ๋ธ๋ก์ ํด์์
๋๋ค.
TxsHash๋ ์ผ๋ฐ์ ์ธ ๊ฑฐ๋ ํด์์
๋๋ค.
MerkleRoot๋ Merkle ํธ๋ฆฌ์ ๋ฃจํธ์
๋๋ค.
๋ํ ํด๋น ํ๋์๋ ๋ธ๋ก ์์ฑ์์ ๊ณต๊ฐ ํค, ์์ฑ์์ ์๋ช , ๋ธ๋ก ๋ฒ์ , ๋ธ๋ก์ ํธ๋์ญ์ ์ ๋ฐ ์ด๋ฌํ ํธ๋์ญ์ ์์ฒด๊ฐ ์์ต๋๋ค.
๊ทธ ๋ฐฉ๋ฒ์ ์ดํด ๋ณด๊ฒ ์ต๋๋ค.
๋ธ๋ก์ ์์ฑํ๋ ค๋ฉด block.NewBlock() ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. NewBlock(prevBlockHash string, height int) *Block. ์ด ํจ์๋ ์ด์ ๋ธ๋ก์ ํด์์ ๋ธ๋ก์ฒด์ธ์์ ์์ฑ๋ ๋ธ๋ก์ ๋ํด ์ค์ ๋ ๋์ด๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ๋ธ๋ก ์ ํ์ ์ ํ ํจํค์ง ์์์์๋ ์ค์ ๋ฉ๋๋ค.
b.DataType = types.BLOCK_TYPE.
AddTx(tx *transaction.TX) ๋ฉ์๋๋ ๋ธ๋ก์ ํธ๋์ญ์ ์ ์ถ๊ฐํฉ๋๋ค.
Build() ๋ฉ์๋๋ ๊ฐ์ ๋ธ๋ก์ ํ๋์ ๋ก๋ํ๊ณ ํ์ฌ ํด์๋ฅผ ์์ฑ ๋ฐ ์ค์ ํฉ๋๋ค.
ToBytesHeader() []byte ๋ฉ์๋๋ ๋ธ๋ก ํค๋(ํธ๋์ญ์ ์์)๋ฅผ ๋ฐ์ดํธ ์ฌ๋ผ์ด์ค๋ก ๋ณํํฉ๋๋ค.
ToJSON() ๋ฌธ์์ด ๋ฉ์๋๋ ๋ฐ์ดํฐ์ ๋ฌธ์์ด ํํ์์ ๋ธ๋ก์ JSON ํ์์ผ๋ก ๋ณํํฉ๋๋ค.
FromJSON(data []byte) ์ค๋ฅ ๋ฉ์๋๋ JSON์ ๋ฐ์ดํฐ๋ฅผ ๋ธ๋ก ๊ตฌ์กฐ๋ก ๋ก๋ํฉ๋๋ค.
Check() bool ๋ฉ์๋๋ ๋ธ๋ก ํด์๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ ๋ธ๋ก ํด์ ํ๋์ ์ง์ ๋ ๊ฒ๊ณผ ๋น๊ตํฉ๋๋ค.
GetTxsHash() ๋ฌธ์์ด ๋ฉ์๋๋ ๋ธ๋ก์ ์๋ ๋ชจ๋ ํธ๋์ญ์ ์ ์ด ํด์๋ฅผ ๋ฐํํฉ๋๋ค.
GetMerkleRoot() ๋ฉ์๋๋ ๋ธ๋ก์ ํธ๋์ญ์ ์ ๋ํ Merkle ํธ๋ฆฌ์ ๋ฃจํธ๋ฅผ ์ง์ ํฉ๋๋ค.
Sign(privk string) ๋ฉ์๋๋ ๋ธ๋ก ์์ฑ์์ ๊ฐ์ธ ํค๋ก ๋ธ๋ก์ ์๋ช ํฉ๋๋ค.
SetHeight(height int) ๋ฉ์๋๋ ๋ธ๋ก์ ๋์ด๋ฅผ ๋ธ๋ก ๊ตฌ์กฐ ํ๋์ ์๋๋ค.
GetHeight() int ๋ฉ์๋๋ ๋ธ๋ก ๊ตฌ์กฐ์ ํด๋น ํ๋์ ์ง์ ๋ ๋๋ก ๋ธ๋ก์ ๋์ด๋ฅผ ๋ฐํํฉ๋๋ค.
ToGOBBytes() []byte ๋ฉ์๋๋ ๋ธ๋ก์ GOB ํ์์ผ๋ก ์ธ์ฝ๋ฉํ๊ณ ์ด๋ฅผ ๋ฐ์ดํธ ์ฌ๋ผ์ด์ค๋ก ๋ฐํํฉ๋๋ค.
FromGOBBytes(data []byte) ์ค๋ฅ ๋ฉ์๋๋ GOB ํ์์ผ๋ก ์ ๋ฌ๋ ๋ฐ์ดํธ ์ฌ๋ผ์ด์ค์ ๋ธ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ธ๋ก ๊ตฌ์กฐ์ ์๋๋ค.
GetHash() ๋ฌธ์์ด ๋ฉ์๋๋ ์ฃผ์ด์ง ๋ธ๋ก์ ํด์๋ฅผ ๋ฐํํฉ๋๋ค.
GetPrevHash() ๋ฌธ์์ด ๋ฉ์๋๋ ์ด์ ๋ธ๋ก์ ํด์๋ฅผ ๋ฐํํฉ๋๋ค.
SetPublicKey(pubk string) ๋ฉ์๋๋ ๋ธ๋ก ์์ฑ์์ ๊ณต๊ฐ ํค๋ฅผ ๋ธ๋ก์ ์๋๋ค.
๋ฐ๋ผ์ Block ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋คํธ์ํฌ๋ฅผ ํตํด ์ ์กํ๊ณ LevelDB ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ ์ ์๋ ํ์์ผ๋ก ์ฝ๊ฒ ๋ณํํ ์ ์์ต๋๋ค.
๋ธ๋ก์ฒด์ธ ํจํค์ง์ ๊ธฐ๋ฅ์ ๋ธ๋ก์ฒด์ธ์ ์ ์ฅํ๋ ์ผ์ ๋ด๋นํฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ ค๋ฉด ๋ธ๋ก์ด IBlock ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค.
type IGOBBytes interface {
ToGOBBytes() []byte
FromGOBBytes(data []byte) error
}
type IBlock interface {
IGOBBytes
GetHash() string
GetPrevHash() string
GetHeight() int
Check() bool
}
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ init() ํจ์์์ ํจํค์ง๊ฐ ์ด๊ธฐํ๋ ๋ ํ ๋ฒ ์์ฑ๋ฉ๋๋ค.
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).
CloseDB()๋ db.Cloce()์ ๋ํ ๋ํผ์ ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํ ์ฐ๊ฒฐ์ ๋ซ๋ ํจํค์ง ํจ์ ์์ ํ์ ํธ์ถ๋ฉ๋๋ค.
SetTargetBlockHash(ํด์ ๋ฌธ์์ด) ์ค๋ฅ ํจ์๋ BLOCK_HASH ์์๋ก ์ง์ ๋ ํค๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฌ ๋ธ๋ก์ ํด์๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋๋ค.
GetTargetBlockHash()(๋ฌธ์์ด, ์ค๋ฅ) ํจ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ ํ์ฌ ๋ธ๋ก์ ํด์๋ฅผ ๋ฐํํฉ๋๋ค.
SetTargetBlockHeight(height int) ์ค๋ฅ ํจ์๋ BLOCK_HEIGHT ์์๋ก ์ง์ ๋ ํค๋ฅผ ์ฌ์ฉํ์ฌ ๋ ธ๋์ ๋ธ๋ก์ฒด์ธ ๋์ด ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ธฐ๋กํฉ๋๋ค.
GetTargetBlockHeight() (int, error) ํจ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ ํน์ ๋ ธ๋์ ๋ํ ๋ธ๋ก์ฒด์ธ์ ๋์ด๋ฅผ ๋ฐํํฉ๋๋ค.
CheckBlock(block IBlock) bool ํจ์๋ ๋ธ๋ก์ ๋ธ๋ก์ฒด์ธ์ ์ถ๊ฐํ๊ธฐ ์ ์ ๋ธ๋ก์ ์ ํ์ฑ์ ํ์ธํฉ๋๋ค.
AddBlock(๋ธ๋ก IBlock) ์ค๋ฅ ๊ธฐ๋ฅ์ ๋ธ๋ก์ฒด์ธ์ ๋ธ๋ก์ ์ถ๊ฐํฉ๋๋ค.
๋ธ๋ก์ ๊ฒ์ํ๊ณ ๋ณด๋ ๊ธฐ๋ฅ์ ๋ธ๋ก์ฒด์ธ ํจํค์ง์ explore.go ํ์ผ์ ์์ต๋๋ค.
GetBlockByHash(ํด์ ๋ฌธ์์ด) (*block.Block, error) ํจ์๋ ๋น ๋ธ๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ํด์๊ฐ ์ ๋ฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํด๋น ๊ฐ์ฒด๋ก ๋ธ๋ก์ ๋ก๋ํ๊ณ , ์ด์ ๋ํ ํฌ์ธํฐ๋ฅผ ๋ฐํํฉ๋๋ค.
์ ๋ค์์ค ๋ธ๋ก ์์ฑ์ ๋ธ๋ก์ฒด์ธ ํจํค์ง์ Genesis.go ํ์ผ์ ์๋ Genesis() ์ค๋ฅ ํจ์์ ์ํด ์ํ๋ฉ๋๋ค.
๋ค์ ๊ธฐ์ฌ์์๋ WebSocket ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ์ฌ ํด๋ผ์ด์ธํธ๋ฅผ ๋
ธ๋์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ค๋ช
ํฉ๋๋ค.
์ถ์ฒ : habr.com