diff --git a/core/genesis_block_test.json b/core/genesis_block_test.json new file mode 100644 index 000000000..2ac56fba3 --- /dev/null +++ b/core/genesis_block_test.json @@ -0,0 +1,8 @@ +{ + "b7a2c103728b7305b5ae6e961c94ee99c9fe8e2b": { + "wei": "50000000000000000000000" + }, + "b498bb0f520005b6216a4425b75aa9adc52d622b": { + "wei": "4000000000000000000000" + } +} diff --git a/core/genesis_util.go b/core/genesis_util.go new file mode 100644 index 000000000..4fa5be449 --- /dev/null +++ b/core/genesis_util.go @@ -0,0 +1,71 @@ +package core + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "math/big" + "sort" + + "github.com/ethereum/go-ethereum/rlp" +) + +// GenesisItem represents one genesis block transaction +type GenesisItem struct { + Addr *big.Int + Balance *big.Int +} + +// genesisConfig is a format compatible with genesis_block.json file +type genesisConfig map[string]map[string]string + +func encodeGenesisConfig(ga []GenesisItem) string { + by, err := rlp.EncodeToBytes(ga) + if err != nil { + panic("ops") + } + + return string(by) +} + +func parseGenesisConfigFile(fileName string) genesisConfig { + input, err := ioutil.ReadFile(fileName) + if err != nil { + panic(fmt.Sprintf("cannot open genesisblock config file %v, err %v\n", fileName, err)) + } + var gc genesisConfig + err = json.Unmarshal(input, &gc) + if err != nil { + panic(fmt.Sprintf("cannot parse json file %v, err %v\n", fileName, err)) + } + return gc +} + +// StringToBigInt converts a string to BigInt +func StringToBigInt(s string, base int) *big.Int { + z := new(big.Int) + z, ok := z.SetString(s, base) + if !ok { + panic(fmt.Sprintf("%v cannot convert to bigint with base %v", s, base)) + } + return z +} + +func convertToGenesisItems(gc genesisConfig) []GenesisItem { + gi := []GenesisItem{} + for k, v := range gc { + gi = append(gi, GenesisItem{StringToBigInt(k, 16), StringToBigInt(v["wei"], 10)}) + } + sort.Slice(gi, func(i, j int) bool { + return gi[i].Addr.Cmp(gi[j].Addr) == -1 + }) + return gi +} + +// EncodeGenesisConfig converts json file into binary format for genesis block +func EncodeGenesisConfig(fileName string) string { + gc := parseGenesisConfigFile(fileName) + gi := convertToGenesisItems(gc) + by := encodeGenesisConfig(gi) + return string(by) +} diff --git a/core/genesis_util_test.go b/core/genesis_util_test.go new file mode 100644 index 000000000..3d61d16ba --- /dev/null +++ b/core/genesis_util_test.go @@ -0,0 +1,19 @@ +package core + +import ( + "strings" + "testing" +) + +func TestEncodeGenesisConfig(t *testing.T) { + fileName := "genesis_block_test.json" + s := EncodeGenesisConfig(fileName) + genesisAcc := decodePrealloc(s) + + for k := range genesisAcc { + key := strings.ToLower(k.Hex()) + if key != "0xb7a2c103728b7305b5ae6e961c94ee99c9fe8e2b" && key != "0xb498bb0f520005b6216a4425b75aa9adc52d622b" { + t.Errorf("EncodeGenesisConfig incorrect") + } + } +}