From 0bc8371f84cdf1b721e09df2fe94c097e5d1fd48 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Wed, 12 May 2021 22:34:14 +0300 Subject: [PATCH] Implement block and transaction primitives --- go.mod | 1 + go.sum | 7 ++++ types/block.go | 79 ++++++++++++++++++++++++++++++++++++++++++++ types/transaction.go | 26 +++++++++++++++ wallet/wallet.go | 4 +-- 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 types/block.go create mode 100644 types/transaction.go diff --git a/go.mod b/go.mod index a809fa9..4c33a81 100644 --- a/go.mod +++ b/go.mod @@ -55,6 +55,7 @@ require ( github.com/stretchr/testify v1.7.0 github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/valyala/fasthttp v1.17.0 + github.com/wealdtech/go-merkletree v1.0.1-0.20190605192610-2bb163c2ea2a // indirect github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 go.uber.org/zap v1.16.0 diff --git a/go.sum b/go.sum index 5bf985f..aaf874f 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,7 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CurtisLusmore/ghp v0.0.0-20190131093722-04a23b486a62/go.mod h1:+iVlyn4r8pVe5rgooNlrYjuzDayoXL5H/JBMhemDs/I= github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= @@ -1708,6 +1709,10 @@ github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvS github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/wealdtech/go-merkletree v1.0.0 h1:DsF1xMzj5rK3pSQM6mPv8jlyJyHXhFxpnA2bwEjMMBY= +github.com/wealdtech/go-merkletree v1.0.0/go.mod h1:cdil512d/8ZC7Kx3bfrDvGMQXB25NTKbsm0rFrmDax4= +github.com/wealdtech/go-merkletree v1.0.1-0.20190605192610-2bb163c2ea2a h1:MwXxGlHLoTCM3/5nlvGJqSWhcmWtGuc6RBtUsTKJwvU= +github.com/wealdtech/go-merkletree v1.0.1-0.20190605192610-2bb163c2ea2a/go.mod h1:Q/vZYhXjtE/oLDRqlGLWwRrNKZJAwidHlVfwIkKEH2w= github.com/weaveworks/common v0.0.0-20200512154658-384f10054ec5 h1:EYxr08r8x6r/5fLEAMMkida1BVgxVXE4LfZv/XV+znU= github.com/weaveworks/common v0.0.0-20200512154658-384f10054ec5/go.mod h1:c98fKi5B9u8OsKGiWHLRKus6ToQ1Tubeow44ECO1uxY= github.com/weaveworks/promrus v1.2.0 h1:jOLf6pe6/vss4qGHjXmGz4oDJQA+AOCqEL3FvvZGz7M= @@ -1842,6 +1847,7 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -2005,6 +2011,7 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/types/block.go b/types/block.go new file mode 100644 index 0000000..60e95a1 --- /dev/null +++ b/types/block.go @@ -0,0 +1,79 @@ +package types + +import ( + "time" + + "github.com/wealdtech/go-merkletree" + "github.com/wealdtech/go-merkletree/keccak256" + + "github.com/Secured-Finance/dione/wallet" + "github.com/libp2p/go-libp2p-core/peer" +) + +type Block struct { + Header *BlockHeader + Data []*Transaction +} + +type BlockHeader struct { + Timestamp int64 + SeqNum uint64 + Hash []byte + LastHash []byte + Proposer peer.ID + Signature []byte +} + +func GenesisBlock() *Block { + return &Block{ + Header: &BlockHeader{ + Timestamp: 1620845070, + SeqNum: 0, + Hash: []byte("DIMICANDUM"), + }, + Data: []*Transaction{}, + } +} + +func CreateBlock(lastBlockHeader *BlockHeader, txs []*Transaction, wallet *wallet.LocalWallet) (*Block, error) { + timestamp := time.Now().Unix() + proposer, err := wallet.GetDefault() + if err != nil { + return nil, err + } + + // extract hashes from transactions + var txHashes [][]byte + for _, tx := range txs { + txHashes = append(txHashes, tx.Hash) + } + txHashes = append(txHashes, lastBlockHeader.Hash) + + tree, err := merkletree.NewUsing(txHashes, keccak256.New(), false) + if err != nil { + return nil, err + } + + // fetch merkle tree root hash (block hash) + blockHash := tree.Root() + + // sign this block hash + s, err := wallet.Sign(proposer, blockHash) + if err != nil { + return nil, err + } + + block := &Block{ + Header: &BlockHeader{ + Timestamp: timestamp, + SeqNum: lastBlockHeader.SeqNum + 1, + Proposer: proposer, + Signature: s.Data, + Hash: blockHash, + LastHash: lastBlockHeader.Hash, + }, + Data: txs, + } + + return block, nil +} diff --git a/types/transaction.go b/types/transaction.go new file mode 100644 index 0000000..efa79b7 --- /dev/null +++ b/types/transaction.go @@ -0,0 +1,26 @@ +package types + +import ( + "encoding/hex" + "fmt" + "time" + + "github.com/ethereum/go-ethereum/crypto" +) + +type Transaction struct { + Hash []byte + Timestamp int64 + Data []byte +} + +func CreateTransaction(data []byte) *Transaction { + timestamp := time.Now().Unix() + encodedData := hex.EncodeToString(data) + hash := crypto.Keccak256([]byte(fmt.Sprintf("%d_%s", timestamp, encodedData))) + return &Transaction{ + Hash: hash, + Timestamp: timestamp, + Data: data, + } +} diff --git a/wallet/wallet.go b/wallet/wallet.go index 33f6ce7..249488f 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -50,7 +50,7 @@ func KeyWallet(keys ...*Key) *LocalWallet { } } -func (w *LocalWallet) WalletSign(ctx context.Context, addr peer.ID, msg []byte) (*types.Signature, error) { +func (w *LocalWallet) Sign(addr peer.ID, msg []byte) (*types.Signature, error) { ki, err := w.findKey(addr) if err != nil { return nil, err @@ -143,7 +143,7 @@ func (w *LocalWallet) GetDefault() (peer.ID, error) { return k.Address, nil } -func (w *LocalWallet) WalletNew(ctx context.Context, typ types.KeyType) (peer.ID, error) { +func (w *LocalWallet) NewKey(typ types.KeyType) (peer.ID, error) { w.lk.Lock() defer w.lk.Unlock()