OSDN Git Service

Genesis (#127)
authorGuanghua Guo <1536310027@qq.com>
Fri, 24 Nov 2017 05:36:40 +0000 (13:36 +0800)
committerPaladz <yzhu101@uottawa.ca>
Fri, 24 Nov 2017 05:36:40 +0000 (13:36 +0800)
* Add genesis block function

* Fix build error

* Run ok

* Add free genesis block

* Add genesis_test.go

* golink

* Update from review

* Formating

* Formating

blockchain/account/reserve.go
blockchain/hsm_test.go
cmd/bytomcli/example/issue.go
cmd/bytomcli/example/spend.go
cmd/bytomcli/main.go
config/genesis.go [new file with mode: 0644]
config/genesis_test.go [new file with mode: 0644]
consensus/general.go
node/node.go

index b4121dc..0a11873 100755 (executable)
@@ -12,11 +12,10 @@ import (
        log "github.com/sirupsen/logrus"
        dbm "github.com/tendermint/tmlibs/db"
 
-       "github.com/bytom/consensus"
        "github.com/bytom/errors"
+       "github.com/bytom/config"
        "github.com/bytom/protocol"
        "github.com/bytom/protocol/bc"
-       "github.com/bytom/protocol/bc/legacy"
        "github.com/bytom/sync/idempotency"
 )
 
@@ -444,7 +443,7 @@ func findSpecificUTXO(ctx context.Context, db dbm.DB, outHash bc.Hash) (*utxo, e
        accountUTXO := new(UTXO)
 
        //temp fix for coinbase UTXO isn't add to accountUTXO db, will be remove later
-       if outHash.String() == "73d1e97c7bcf2b084f936a40f4f2a72e909417f2b46699e8659fa4c4feddb98d" {
+       if outHash == *config.GenerateGenesisTx().ResultIds[0] {
                return genesisBlockUTXO(), nil
        }
 
@@ -483,15 +482,12 @@ func findSpecificUTXO(ctx context.Context, db dbm.DB, outHash bc.Hash) (*utxo, e
 //temp fix for coinbase UTXO isn't add to accountUTXO db, will be remove later
 func genesisBlockUTXO() *utxo {
        u := new(utxo)
-       genesisBlock := &legacy.Block{
-               BlockHeader:  legacy.BlockHeader{},
-               Transactions: []*legacy.Tx{},
-       }
-       genesisBlock.UnmarshalText(consensus.InitBlock())
-       tx := genesisBlock.Transactions[0]
+       tx := config.GenerateGenesisTx()
+
        out := tx.Outputs[0]
        resOutID := tx.ResultIds[0]
        resOut, _ := tx.Entries[*resOutID].(*bc.Output)
+       log.Infof("genesis Output:%v", resOut)
 
        //u.AccountID =
        u.OutputID = *tx.OutputID(0)
index f0528a9..129c705 100644 (file)
@@ -8,19 +8,17 @@ import (
        "testing"
        "time"
 
+       dbm "github.com/tendermint/tmlibs/db"
+
        "github.com/bytom/blockchain/account"
        "github.com/bytom/blockchain/asset"
        "github.com/bytom/blockchain/pseudohsm"
        "github.com/bytom/blockchain/txbuilder"
        "github.com/bytom/blockchain/txdb"
        cfg "github.com/bytom/config"
-       "github.com/bytom/consensus"
        "github.com/bytom/crypto/ed25519/chainkd"
        "github.com/bytom/protocol"
        "github.com/bytom/protocol/bc"
-       "github.com/bytom/protocol/bc/legacy"
-
-       dbm "github.com/tendermint/tmlibs/db"
 )
 
 const dirPath = "pseudohsm/testdata/pseudo"
@@ -38,12 +36,7 @@ func TestHSM(t *testing.T) {
        var accounts *account.Manager
        var wallet *account.Wallet
        var assets *asset.Registry
-
-       genesisBlock := &legacy.Block{
-               BlockHeader:  legacy.BlockHeader{},
-               Transactions: []*legacy.Tx{},
-       }
-       genesisBlock.UnmarshalText(consensus.InitBlock())
+       genesisBlock := cfg.GenerateGenesisBlock()
        // tx pool init
        txPool := protocol.NewTxPool()
        chain, err := protocol.NewChain(genesisBlock.Hash(), store, txPool)
index be487eb..9328f45 100644 (file)
@@ -11,6 +11,7 @@ import (
        "github.com/bytom/blockchain/txbuilder"
        "github.com/bytom/crypto/ed25519/chainkd"
        "github.com/bytom/encoding/json"
+       "github.com/bytom/config"
 
        stdjson "encoding/json"
        bchain "github.com/bytom/blockchain"
@@ -86,14 +87,15 @@ func IssueTest(client *rpc.Client, args []string) {
                        {
                                "type":"spend_account_unspent_output",
                                "receiver":null,
-                               "output_id":"73d1e97c7bcf2b084f936a40f4f2a72e909417f2b46699e8659fa4c4feddb98d",
+                               "output_id":"%v",
                                "reference_data":{}
                        },
                        {"type": "issue", "asset_id": "%s", "amount": 100},
                        {"type": "control_account", "asset_id": "%s", "amount": 100, "account_id": "%s"},
                        {"type": "control_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount": 8888888888, "account_id": "%s"}
                ]}`
-       buildReqStr := fmt.Sprintf(buildReqFmt, assets[0].ID.String(), assets[0].ID.String(), accounts[0].ID, accounts[0].ID)
+       fmt.Printf("spend_account_unspent_output:%v\n", config.GenerateGenesisTx().ResultIds[0])
+       buildReqStr := fmt.Sprintf(buildReqFmt, config.GenerateGenesisTx().ResultIds[0], assets[0].ID.String(), assets[0].ID.String(), accounts[0].ID, accounts[0].ID)
        var buildReq bchain.BuildRequest
        err := stdjson.Unmarshal([]byte(buildReqStr), &buildReq)
        if err != nil {
index b77b65a..1f8116f 100644 (file)
@@ -13,6 +13,7 @@ import (
        "github.com/bytom/blockchain/txbuilder"
        "github.com/bytom/crypto/ed25519/chainkd"
        "github.com/bytom/encoding/json"
+       "github.com/bytom/config"
 )
 
 type accUTXOShort struct {
@@ -90,14 +91,14 @@ func SpendTest(client *rpc.Client, args []string) {
                        {
                                "type":"spend_account_unspent_output",
                                "receiver":null,
-                               "output_id":"73d1e97c7bcf2b084f936a40f4f2a72e909417f2b46699e8659fa4c4feddb98d",
+                               "output_id":"%v",
                                "reference_data":{}
                        },
                        {"type": "issue", "asset_id": "%s", "amount": 100},
                        {"type": "control_account", "asset_id": "%s", "amount": 100, "account_id": "%s"},
                        {"type": "control_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount": 8888888888, "account_id": "%s"}
                ]}`
-       buildReqStr := fmt.Sprintf(buildReqFmt, assets[0].ID.String(), assets[0].ID.String(), accounts[0].ID, accounts[0].ID)
+       buildReqStr := fmt.Sprintf(buildReqFmt, config.GenerateGenesisTx().ResultIds[0], assets[0].ID.String(), assets[0].ID.String(), accounts[0].ID, accounts[0].ID)
        var buildReq bchain.BuildRequest
        err := stdjson.Unmarshal([]byte(buildReqStr), &buildReq)
        if err != nil {
index 27e5842..9b879ad 100755 (executable)
@@ -26,6 +26,7 @@ import (
        "github.com/bytom/encoding/json"
        "github.com/bytom/env"
        "github.com/bytom/errors"
+       "github.com/bytom/config"
 )
 
 // config vars
@@ -502,13 +503,13 @@ func buildTransaction(client *rpc.Client, args []string) {
                        {
                                "type":"spend_account_unspent_output",
                                "receiver":null,
-                               "output_id":"73d1e97c7bcf2b084f936a40f4f2a72e909417f2b46699e8659fa4c4feddb98d",
+                               "output_id":"%v",
                                "reference_data":{}
                        },
                        {"type": "issue", "asset_id": "%s", "amount": 100},
                        {"type": "control_account", "asset_id": "%s", "amount": 100, "account_id": "%s"}
                ]}`
-       buildReqStr := fmt.Sprintf(buildReqFmt, args[1], args[1], args[0])
+       buildReqStr := fmt.Sprintf(buildReqFmt, config.GenerateGenesisTx().ResultIds[0], args[1], args[1], args[0])
        var buildReq blockchain.BuildRequest
        err := stdjson.Unmarshal([]byte(buildReqStr), &buildReq)
        if err != nil {
@@ -536,7 +537,7 @@ func submitCreateIssueTransaction(client *rpc.Client, args []string) {
                        {
                                "type":"spend_account_unspent_output",
                                "receiver":null,
-                               "output_id":"73d1e97c7bcf2b084f936a40f4f2a72e909417f2b46699e8659fa4c4feddb98d",
+                               "output_id":"%v",
                                "reference_data":{}
                        },
                        {"type": "issue", "asset_id": "%s", "amount": %s},
@@ -544,7 +545,7 @@ func submitCreateIssueTransaction(client *rpc.Client, args []string) {
                        {"type": "control_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount": 8888888888, "account_id": "%s"},
                        {"type": "control_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount": 8888888888, "account_id": "%s"}
                ]}`
-       buildReqStr := fmt.Sprintf(buildReqFmt, args[2], args[4], args[2], args[4], args[0], args[0], args[1])
+       buildReqStr := fmt.Sprintf(buildReqFmt, config.GenerateGenesisTx().ResultIds[0], args[2], args[4], args[2], args[4], args[0], args[0], args[1])
        var buildReq blockchain.BuildRequest
        err := stdjson.Unmarshal([]byte(buildReqStr), &buildReq)
        if err != nil {
diff --git a/config/genesis.go b/config/genesis.go
new file mode 100644 (file)
index 0000000..c6df4bf
--- /dev/null
@@ -0,0 +1,81 @@
+package config
+
+import (
+       log "github.com/sirupsen/logrus"
+
+       "github.com/bytom/protocol/bc/legacy"
+       "github.com/bytom/protocol/bc"
+       "github.com/bytom/consensus"
+       "github.com/bytom/protocol/state"
+       "github.com/bytom/crypto/sha3pool"
+)
+
+// Generate genesis transaction
+func GenerateGenesisTx() *legacy.Tx {
+       txData := legacy.TxData{
+               Version: 1,
+               SerializedSize: 63,
+               Inputs: []*legacy.TxInput{},
+               Outputs:[]*legacy.TxOutput{
+                       &legacy.TxOutput{
+                               AssetVersion: 1,
+                               OutputCommitment: legacy.OutputCommitment{
+                                       AssetAmount: bc.AssetAmount{
+                                               AssetId: consensus.BTMAssetID,
+                                               Amount:  1470000000000000000,
+                                       },
+                                       VMVersion:      1,
+                                       ControlProgram: []byte{81},
+                               },
+                       },
+               },
+               MinTime: 0,
+               MaxTime: 1511318565142,
+       }
+
+       return legacy.NewTx(txData)
+}
+
+// Generate genesis block
+func GenerateGenesisBlock() *legacy.Block {
+       genesisCoinbaseTx := GenerateGenesisTx()
+       merkleRoot, err := bc.MerkleRoot([]*bc.Tx{genesisCoinbaseTx.Tx})
+       if err != nil {
+               log.Panicf("Fatal create merkelRoot")
+       }
+
+       snap := state.Empty()
+       if err := snap.ApplyTx(genesisCoinbaseTx.Tx); err != nil {
+               log.Panicf("Fatal ApplyTx")
+       }
+
+       var seed [32]byte
+       sha3pool.Sum256(seed[:], make([]byte, 32))
+
+       genesisBlock := &legacy.Block{
+               BlockHeader:  legacy.BlockHeader{
+                       Version: 1,
+                       Height: 1,
+                       Seed: bc.NewHash(seed),
+                       TimestampMS: 1511318565142,
+                       BlockCommitment: legacy.BlockCommitment{
+                               TransactionsMerkleRoot: merkleRoot,
+                               AssetsMerkleRoot:       snap.Tree.RootHash(),
+                       },
+                       Bits: 2161727821138738707,
+               },
+               Transactions: []*legacy.Tx{genesisCoinbaseTx},
+       }
+
+       for i := uint64(0); i <= 10000000000000; i++ {
+               genesisBlock.Nonce = i
+               hash := genesisBlock.Hash()
+
+               if consensus.CheckProofOfWork(&hash, genesisBlock.Bits) {
+                       break
+               }
+       }
+
+       log.Infof("genesisBlock:%v", genesisBlock)
+       return genesisBlock
+}
diff --git a/config/genesis_test.go b/config/genesis_test.go
new file mode 100644 (file)
index 0000000..2ffa91f
--- /dev/null
@@ -0,0 +1,16 @@
+package config
+
+import (
+       "testing"
+)
+
+// test genesis
+func TestGenesis(t *testing.T) {
+       if tx := GenerateGenesisTx(); tx == nil {
+               t.Errorf("Generate genesis tx failed")
+       }
+
+       if block := GenerateGenesisBlock(); block == nil {
+               t.Errorf("Generate genesis block failed")
+       }
+}
index 6dcd9fa..9f38724 100644 (file)
@@ -40,11 +40,6 @@ func BlockSubsidy(height uint64) uint64 {
        return baseSubsidy >> uint(height/subsidyReductionInterval)
 }
 
-// InitBlock record the byte init block
-func InitBlock() []byte {
-       return []byte("03010100000000000000000000000000000000000000000000000000000000000000009e6291970cb44dd94008c79bcaf9d86f18b4b49ba5b2a04781db7199ed3b9e4e96e2ec8cfe2b4046c8af216f53bf86a30638b13a0b7404c463b9cf8df153a22233ec23886fc5bd12553440d84371701d3d4348099f8abd59a7e7d819befa57b1de50212e5d20e3e1a4fd0193fcb680808080801e010701070096e2ec8cfe2b000001012fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8080ccdee2a69fb3140104cd57a069000000")
-}
-
 // IsBech32SegwitPrefix returns whether the prefix is a known prefix for segwit
 // addresses on any default or registered network.  This is used when decoding
 // an address string into a specific address type.
index 3d06457..c7be3bb 100755 (executable)
@@ -25,12 +25,10 @@ import (
        "github.com/bytom/blockchain/txdb"
        "github.com/bytom/blockchain/txfeed"
        cfg "github.com/bytom/config"
-       "github.com/bytom/consensus"
        "github.com/bytom/env"
        "github.com/bytom/errors"
        "github.com/bytom/p2p"
        "github.com/bytom/protocol"
-       "github.com/bytom/protocol/bc/legacy"
        "github.com/bytom/types"
        "github.com/bytom/version"
 )
@@ -151,11 +149,7 @@ func NewNode(config *cfg.Config) *Node {
 
        sw := p2p.NewSwitch(config.P2P)
 
-       genesisBlock := &legacy.Block{
-               BlockHeader:  legacy.BlockHeader{},
-               Transactions: []*legacy.Tx{},
-       }
-       genesisBlock.UnmarshalText(consensus.InitBlock())
+       genesisBlock := cfg.GenerateGenesisBlock()
 
        txPool := protocol.NewTxPool()
        chain, err := protocol.NewChain(genesisBlock.Hash(), store, txPool)