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 }