github.com/Gessiux/neatchain@v1.3.1/chain/consensus/neatcon/types/genesis.go (about)

     1  package types
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"math/big"
     8  	"time"
     9  
    10  	"github.com/Gessiux/neatchain/utilities/common/hexutil"
    11  
    12  	. "github.com/Gessiux/go-common"
    13  	"github.com/Gessiux/go-crypto"
    14  	"github.com/Gessiux/neatchain/utilities/common"
    15  )
    16  
    17  //------------------------------------------------------------
    18  // we store the gendoc in the db
    19  
    20  var GenDocKey = []byte("GenDocKey")
    21  
    22  //------------------------------------------------------------
    23  // core types for a genesis definition
    24  
    25  var CONSENSUS_POS string = "pos"
    26  var CONSENSUS_POW string = "pow"
    27  var CONSENSUS_NeatCon string = "neatcon"
    28  
    29  type GenesisValidator struct {
    30  	EthAccount     common.Address `json:"address"`
    31  	PubKey         crypto.PubKey  `json:"pub_key"`
    32  	Amount         *big.Int       `json:"amount"`
    33  	Name           string         `json:"name"`
    34  	RemainingEpoch uint64         `json:"epoch"`
    35  }
    36  
    37  type OneEpochDoc struct {
    38  	Number         uint64             `json:"number"`
    39  	RewardPerBlock *big.Int           `json:"reward_per_block"`
    40  	StartBlock     uint64             `json:"start_block"`
    41  	EndBlock       uint64             `json:"end_block"`
    42  	Status         int                `json:"status"`
    43  	Validators     []GenesisValidator `json:"validators"`
    44  }
    45  
    46  type RewardSchemeDoc struct {
    47  	TotalReward        *big.Int `json:"total_reward"`
    48  	RewardFirstYear    *big.Int `json:"reward_first_year"`
    49  	EpochNumberPerYear uint64   `json:"epoch_no_per_year"`
    50  	TotalYear          uint64   `json:"total_year"`
    51  }
    52  
    53  type GenesisDoc struct {
    54  	ChainID      string          `json:"chain_id"`
    55  	Consensus    string          `json:"consensus"` //should be 'pos' or 'pow'
    56  	GenesisTime  time.Time       `json:"genesis_time"`
    57  	RewardScheme RewardSchemeDoc `json:"reward_scheme"`
    58  	CurrentEpoch OneEpochDoc     `json:"current_epoch"`
    59  }
    60  
    61  // 写入文件使用
    62  type GenesisDocWrite struct {
    63  	ChainID      string           `json:"chain_id"`
    64  	Consensus    string           `json:"consensus"` //should be 'pos' or 'pow'
    65  	GenesisTime  time.Time        `json:"genesis_time"`
    66  	RewardScheme RewardSchemeDoc  `json:"reward_scheme"`
    67  	CurrentEpoch OneEpochDocWrite `json:"current_epoch"`
    68  }
    69  
    70  // 写入文件使用
    71  type OneEpochDocWrite struct {
    72  	Number         uint64                  `json:"number"`
    73  	RewardPerBlock *big.Int                `json:"reward_per_block"`
    74  	StartBlock     uint64                  `json:"start_block"`
    75  	EndBlock       uint64                  `json:"end_block"`
    76  	Status         int                     `json:"status"`
    77  	Validators     []GenesisValidatorWrite `json:"validators"`
    78  }
    79  
    80  // 写入文件使用
    81  type GenesisValidatorWrite struct {
    82  	EthAccount     string        `json:"address"`
    83  	PubKey         crypto.PubKey `json:"pub_key"`
    84  	Amount         *big.Int      `json:"amount"`
    85  	Name           string        `json:"name"`
    86  	RemainingEpoch uint64        `json:"epoch"`
    87  }
    88  
    89  // Utility method for saving GenensisDoc as JSON file.
    90  //func (genDoc *GenesisDoc) SaveAs(file string) error {
    91  //	genDocBytes, err := json.MarshalIndent(genDoc, "", "\t")
    92  //	if err != nil {
    93  //		fmt.Println(err)
    94  //	}
    95  //
    96  //	return WriteFile(file, genDocBytes, 0644)
    97  //}
    98  // 写入文件使用
    99  func (genDoc *GenesisDoc) SaveAs(file string) error {
   100  
   101  	genDocWrite := GenesisDocWrite{
   102  		ChainID:      genDoc.ChainID,
   103  		Consensus:    genDoc.Consensus,
   104  		GenesisTime:  genDoc.GenesisTime,
   105  		RewardScheme: genDoc.RewardScheme,
   106  		CurrentEpoch: OneEpochDocWrite{
   107  			Number:         genDoc.CurrentEpoch.Number,
   108  			RewardPerBlock: genDoc.CurrentEpoch.RewardPerBlock,
   109  			StartBlock:     genDoc.CurrentEpoch.StartBlock,
   110  			EndBlock:       genDoc.CurrentEpoch.EndBlock,
   111  			Status:         genDoc.CurrentEpoch.Status,
   112  			Validators:     make([]GenesisValidatorWrite, len(genDoc.CurrentEpoch.Validators)),
   113  		},
   114  	}
   115  	for i, v := range genDoc.CurrentEpoch.Validators {
   116  		genDocWrite.CurrentEpoch.Validators[i] = GenesisValidatorWrite{
   117  			EthAccount:     v.EthAccount.String(),
   118  			PubKey:         v.PubKey,
   119  			Amount:         v.Amount,
   120  			Name:           v.Name,
   121  			RemainingEpoch: v.RemainingEpoch,
   122  		}
   123  	}
   124  
   125  	genDocBytes, err := json.MarshalIndent(genDocWrite, "", "\t")
   126  	if err != nil {
   127  		fmt.Println(err)
   128  	}
   129  
   130  	return WriteFile(file, genDocBytes, 0644)
   131  }
   132  
   133  //------------------------------------------------------------
   134  // Make genesis state from file
   135  
   136  //func GenesisDocFromJSON(jsonBlob []byte) (genDoc *GenesisDoc, err error) {
   137  //	err = json.Unmarshal(jsonBlob, &genDoc)
   138  //	return
   139  //}
   140  
   141  // 读取 genesisdocjson,并做转换
   142  func GenesisDocFromJSON(jsonBlob []byte) (genDoc *GenesisDoc, err error) {
   143  	var genDocWrite *GenesisDocWrite
   144  	err = json.Unmarshal(jsonBlob, &genDocWrite)
   145  	if err != nil {
   146  		return &GenesisDoc{}, err
   147  	}
   148  
   149  	genDoc = &GenesisDoc{
   150  		ChainID:      genDocWrite.ChainID,
   151  		Consensus:    genDocWrite.Consensus,
   152  		GenesisTime:  genDocWrite.GenesisTime,
   153  		RewardScheme: genDocWrite.RewardScheme,
   154  		CurrentEpoch: OneEpochDoc{
   155  			Number:         genDocWrite.CurrentEpoch.Number,
   156  			RewardPerBlock: genDocWrite.CurrentEpoch.RewardPerBlock,
   157  			StartBlock:     genDocWrite.CurrentEpoch.StartBlock,
   158  			EndBlock:       genDocWrite.CurrentEpoch.EndBlock,
   159  			Status:         genDocWrite.CurrentEpoch.Status,
   160  			Validators:     make([]GenesisValidator, len(genDocWrite.CurrentEpoch.Validators)),
   161  		},
   162  	}
   163  	for i, v := range genDocWrite.CurrentEpoch.Validators {
   164  		genDoc.CurrentEpoch.Validators[i] = GenesisValidator{
   165  			EthAccount:     common.StringToAddress(v.EthAccount),
   166  			PubKey:         v.PubKey,
   167  			Amount:         v.Amount,
   168  			Name:           v.Name,
   169  			RemainingEpoch: v.RemainingEpoch,
   170  		}
   171  	}
   172  
   173  	return
   174  }
   175  
   176  var MainnetGenesisJSON string = `{
   177  	"chain_id": "neatchain",
   178  	"consensus": "neatcon",
   179  	"genesis_time": "2021-07-27T20:53:08.85522769+02:00",
   180  	"reward_scheme": {
   181  		"total_reward": "0xa56fa5b99019a5c8000000",
   182  		"reward_first_year": "0x108b2a2c28029094000000",
   183  		"epoch_no_per_year": "0x111c",
   184  		"total_year": "0xa"
   185  	},
   186  	"current_epoch": {
   187  		"number": "0x0",
   188  		"reward_per_block": "0x8cd1dc18de05834",
   189  		"start_block": "0x0",
   190  		"end_block": "0x1c20",
   191  		"validators": [
   192  			{
   193  				"address": "NEATbNkySqxehp2vT1AmPhNqoMTciv1B",
   194  				"pub_key": "0x86F79C19E294576CBDD102589BA11ECC06C843A9ECE957674F551817F73DDBD0154D0AD4011C5C086685A4F6619FFD62193FE311E8FCA6C0F1946D8E116CAF686260B6D0D082FBA634DDF614E0E34BFC118EAD961A18F3A25FA64012357D69FB8649998590102AD484EE376055DEA5E35378019816F7BDDF09FB7FEE949867D9",
   195  				"amount": "0x152d02c7e14af6800000",
   196  				"name": "",
   197  				"epoch": "0x0"
   198  			}
   199  		]
   200  	}
   201  }`
   202  
   203  var TestnetGenesisJSON string = `{
   204  	"chain_id": "testnet",
   205  	"consensus": "neatcon",
   206  	"genesis_time": "2020-11-04T17:47:57.097366+08:00",
   207  	"reward_scheme": {
   208  		"total_reward": "0xa56fa5b99019a5c8000000",
   209  		"reward_first_year": "0x108b2a2c28029094000000",
   210  		"epoch_no_per_year": "0x111c",
   211  		"total_year": "0xa"
   212  	},
   213  	"current_epoch": {
   214  		"number": "0x0",
   215  		"reward_per_block": "0x8cd1dc18de05834",
   216  		"start_block": "0x0",
   217  		"end_block": "0x1c20",
   218  		"validators": [
   219  			{
   220  				"address": "NEAThptdM1qWpbREMNyi5G6tAqcTAedc",
   221  				"pub_key": "0x4C93012A158FEDAB46C48724F3A651E39EA9767B717E30A6403CFC9FD7B78DD664272CBD1570CD08522459DE96C6753B4D605C6FABFAB47B4E4A6BF4A71AD8DD2550F1C9B5088BCA0EE808322BF553C6C974B15D9128C3DDEB949D770C9A76448DC9E306A7DC10BEC28A19762E024B6B4284D08A7D7A52C6C6EFF6FC44496986",
   222  				"amount": "0x54b40b1f852bda000000",
   223  				"name": "",
   224  				"epoch": "0x0"
   225  			}
   226  		]
   227  	}
   228  }
   229  `
   230  
   231  func (ep OneEpochDoc) MarshalJSON() ([]byte, error) {
   232  	type hexEpoch struct {
   233  		Number         hexutil.Uint64     `json:"number"`
   234  		RewardPerBlock *hexutil.Big       `json:"reward_per_block"`
   235  		StartBlock     hexutil.Uint64     `json:"start_block"`
   236  		EndBlock       hexutil.Uint64     `json:"end_block"`
   237  		Validators     []GenesisValidator `json:"validators"`
   238  	}
   239  	var enc hexEpoch
   240  	enc.Number = hexutil.Uint64(ep.Number)
   241  	enc.RewardPerBlock = (*hexutil.Big)(ep.RewardPerBlock)
   242  	enc.StartBlock = hexutil.Uint64(ep.StartBlock)
   243  	enc.EndBlock = hexutil.Uint64(ep.EndBlock)
   244  	if ep.Validators != nil {
   245  		enc.Validators = ep.Validators
   246  	}
   247  	return json.Marshal(&enc)
   248  }
   249  
   250  func (ep *OneEpochDoc) UnmarshalJSON(input []byte) error {
   251  	type hexEpoch struct {
   252  		Number         hexutil.Uint64     `json:"number"`
   253  		RewardPerBlock *hexutil.Big       `json:"reward_per_block"`
   254  		StartBlock     hexutil.Uint64     `json:"start_block"`
   255  		EndBlock       hexutil.Uint64     `json:"end_block"`
   256  		Validators     []GenesisValidator `json:"validators"`
   257  	}
   258  	var dec hexEpoch
   259  	if err := json.Unmarshal(input, &dec); err != nil {
   260  		return err
   261  	}
   262  	ep.Number = uint64(dec.Number)
   263  	ep.RewardPerBlock = (*big.Int)(dec.RewardPerBlock)
   264  	ep.StartBlock = uint64(dec.StartBlock)
   265  	ep.EndBlock = uint64(dec.EndBlock)
   266  	if dec.Validators == nil {
   267  		return errors.New("missing required field 'validators' for Genesis/epoch")
   268  	}
   269  	ep.Validators = dec.Validators
   270  	return nil
   271  }
   272  
   273  // 写入文件中间转换
   274  func (ep OneEpochDocWrite) MarshalJSON() ([]byte, error) {
   275  	type hexEpoch struct {
   276  		Number         hexutil.Uint64          `json:"number"`
   277  		RewardPerBlock *hexutil.Big            `json:"reward_per_block"`
   278  		StartBlock     hexutil.Uint64          `json:"start_block"`
   279  		EndBlock       hexutil.Uint64          `json:"end_block"`
   280  		Validators     []GenesisValidatorWrite `json:"validators"`
   281  	}
   282  	var enc hexEpoch
   283  	enc.Number = hexutil.Uint64(ep.Number)
   284  	enc.RewardPerBlock = (*hexutil.Big)(ep.RewardPerBlock)
   285  	enc.StartBlock = hexutil.Uint64(ep.StartBlock)
   286  	enc.EndBlock = hexutil.Uint64(ep.EndBlock)
   287  	if ep.Validators != nil {
   288  		enc.Validators = ep.Validators
   289  	}
   290  	return json.Marshal(&enc)
   291  }
   292  
   293  // 写入文件中间转换
   294  func (ep *OneEpochDocWrite) UnmarshalJSON(input []byte) error {
   295  	type hexEpoch struct {
   296  		Number         hexutil.Uint64          `json:"number"`
   297  		RewardPerBlock *hexutil.Big            `json:"reward_per_block"`
   298  		StartBlock     hexutil.Uint64          `json:"start_block"`
   299  		EndBlock       hexutil.Uint64          `json:"end_block"`
   300  		Validators     []GenesisValidatorWrite `json:"validators"`
   301  	}
   302  	var dec hexEpoch
   303  	if err := json.Unmarshal(input, &dec); err != nil {
   304  		return err
   305  	}
   306  	ep.Number = uint64(dec.Number)
   307  	ep.RewardPerBlock = (*big.Int)(dec.RewardPerBlock)
   308  	ep.StartBlock = uint64(dec.StartBlock)
   309  	ep.EndBlock = uint64(dec.EndBlock)
   310  	if dec.Validators == nil {
   311  		return errors.New("missing required field 'validators' for Genesis/epoch")
   312  	}
   313  	ep.Validators = dec.Validators
   314  	return nil
   315  }
   316  
   317  func (gv GenesisValidator) MarshalJSON() ([]byte, error) {
   318  	type hexValidator struct {
   319  		Address        common.Address `json:"address"`
   320  		PubKey         string         `json:"pub_key"`
   321  		Amount         *hexutil.Big   `json:"amount"`
   322  		Name           string         `json:"name"`
   323  		RemainingEpoch hexutil.Uint64 `json:"epoch"`
   324  	}
   325  	var enc hexValidator
   326  	enc.Address = gv.EthAccount
   327  	enc.PubKey = gv.PubKey.KeyString()
   328  	enc.Amount = (*hexutil.Big)(gv.Amount)
   329  	enc.Name = gv.Name
   330  	enc.RemainingEpoch = hexutil.Uint64(gv.RemainingEpoch)
   331  
   332  	return json.Marshal(&enc)
   333  }
   334  
   335  func (gv *GenesisValidator) UnmarshalJSON(input []byte) error {
   336  	type hexValidator struct {
   337  		Address        common.Address `json:"address"`
   338  		PubKey         string         `json:"pub_key"`
   339  		Amount         *hexutil.Big   `json:"amount"`
   340  		Name           string         `json:"name"`
   341  		RemainingEpoch hexutil.Uint64 `json:"epoch"`
   342  	}
   343  	var dec hexValidator
   344  	if err := json.Unmarshal(input, &dec); err != nil {
   345  		return err
   346  	}
   347  	gv.EthAccount = dec.Address
   348  
   349  	pubkeyBytes := common.FromHex(dec.PubKey)
   350  	if dec.PubKey == "" || len(pubkeyBytes) != 128 {
   351  		return errors.New("wrong format of required field 'pub_key' for Genesis/epoch/validators")
   352  	}
   353  	var blsPK crypto.BLSPubKey
   354  	copy(blsPK[:], pubkeyBytes)
   355  	gv.PubKey = blsPK
   356  
   357  	if dec.Amount == nil {
   358  		return errors.New("missing required field 'amount' for Genesis/epoch/validators")
   359  	}
   360  	gv.Amount = (*big.Int)(dec.Amount)
   361  	gv.Name = dec.Name
   362  	gv.RemainingEpoch = uint64(dec.RemainingEpoch)
   363  	return nil
   364  }
   365  
   366  // 写入文件中间转换
   367  func (gv GenesisValidatorWrite) MarshalJSON() ([]byte, error) {
   368  	type hexValidator struct {
   369  		Address        string         `json:"address"`
   370  		PubKey         string         `json:"pub_key"`
   371  		Amount         *hexutil.Big   `json:"amount"`
   372  		Name           string         `json:"name"`
   373  		RemainingEpoch hexutil.Uint64 `json:"epoch"`
   374  	}
   375  	var enc hexValidator
   376  	enc.Address = gv.EthAccount
   377  	enc.PubKey = gv.PubKey.KeyString()
   378  	enc.Amount = (*hexutil.Big)(gv.Amount)
   379  	enc.Name = gv.Name
   380  	enc.RemainingEpoch = hexutil.Uint64(gv.RemainingEpoch)
   381  
   382  	return json.Marshal(&enc)
   383  }
   384  
   385  // 写入文件中间转换
   386  func (gv *GenesisValidatorWrite) UnmarshalJSON(input []byte) error {
   387  	type hexValidator struct {
   388  		Address        string         `json:"address"`
   389  		PubKey         string         `json:"pub_key"`
   390  		Amount         *hexutil.Big   `json:"amount"`
   391  		Name           string         `json:"name"`
   392  		RemainingEpoch hexutil.Uint64 `json:"epoch"`
   393  	}
   394  	var dec hexValidator
   395  	if err := json.Unmarshal(input, &dec); err != nil {
   396  		return err
   397  	}
   398  	gv.EthAccount = dec.Address
   399  
   400  	pubkeyBytes := common.FromHex(dec.PubKey)
   401  	if dec.PubKey == "" || len(pubkeyBytes) != 128 {
   402  		return errors.New("wrong format of required field 'pub_key' for Genesis/epoch/validators")
   403  	}
   404  	var blsPK crypto.BLSPubKey
   405  	copy(blsPK[:], pubkeyBytes)
   406  	gv.PubKey = blsPK
   407  
   408  	if dec.Amount == nil {
   409  		return errors.New("missing required field 'amount' for Genesis/epoch/validators")
   410  	}
   411  	gv.Amount = (*big.Int)(dec.Amount)
   412  	gv.Name = dec.Name
   413  	gv.RemainingEpoch = uint64(dec.RemainingEpoch)
   414  	return nil
   415  }
   416  
   417  func (rs RewardSchemeDoc) MarshalJSON() ([]byte, error) {
   418  	type hexRewardScheme struct {
   419  		TotalReward        *hexutil.Big   `json:"total_reward"`
   420  		RewardFirstYear    *hexutil.Big   `json:"reward_first_year"`
   421  		EpochNumberPerYear hexutil.Uint64 `json:"epoch_no_per_year"`
   422  		TotalYear          hexutil.Uint64 `json:"total_year"`
   423  	}
   424  	var enc hexRewardScheme
   425  	enc.TotalReward = (*hexutil.Big)(rs.TotalReward)
   426  	enc.RewardFirstYear = (*hexutil.Big)(rs.RewardFirstYear)
   427  	enc.EpochNumberPerYear = hexutil.Uint64(rs.EpochNumberPerYear)
   428  	enc.TotalYear = hexutil.Uint64(rs.TotalYear)
   429  
   430  	return json.Marshal(&enc)
   431  }
   432  
   433  func (rs *RewardSchemeDoc) UnmarshalJSON(input []byte) error {
   434  	type hexRewardScheme struct {
   435  		TotalReward        *hexutil.Big   `json:"total_reward"`
   436  		RewardFirstYear    *hexutil.Big   `json:"reward_first_year"`
   437  		EpochNumberPerYear hexutil.Uint64 `json:"epoch_no_per_year"`
   438  		TotalYear          hexutil.Uint64 `json:"total_year"`
   439  	}
   440  	var dec hexRewardScheme
   441  	if err := json.Unmarshal(input, &dec); err != nil {
   442  		return err
   443  	}
   444  	if dec.TotalReward == nil {
   445  		return errors.New("missing required field 'total_reward' for Genesis/reward_scheme")
   446  	}
   447  	rs.TotalReward = (*big.Int)(dec.TotalReward)
   448  	if dec.RewardFirstYear == nil {
   449  		return errors.New("missing required field 'reward_first_year' for Genesis/reward_scheme")
   450  	}
   451  	rs.RewardFirstYear = (*big.Int)(dec.RewardFirstYear)
   452  
   453  	rs.EpochNumberPerYear = uint64(dec.EpochNumberPerYear)
   454  	rs.TotalYear = uint64(dec.TotalYear)
   455  
   456  	return nil
   457  }