Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd: add genesis-gen tool #17

Merged
merged 6 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ geth-linux-arm64:
all:
$(GORUN) build/ci.go install

all-static:
$(GORUN) build/ci.go install -static

android:
$(GORUN) build/ci.go aar --local
@echo "Done building."
Expand Down
23 changes: 23 additions & 0 deletions cmd/genesis-gen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
genesis-gen
======

genesis-gen is a simple command-line tool for working with Dogechain genesis files.

# Usage

simple 4 validators genesis file:

```sh
$ genesis-gen --chain-id 23347 \
--epoch-size 300 \
--validator 0xC035596a28ed3C5E357baf2860baCB6d665E81d5 \
--validator 0x20E088469849516610a759C7Bd60434298a91589 \
--validator 0x8F869426530DC8653d347B64be1A9420d5F8eD89 \
--validator 0xcB4a9D4419f1cE42E5AC993A6E571C7587474C6E \
--premine 0x23d7B7be9B63e63F2e76b39bEA23BcD517731a0b:0x3635C9ADC5DEA0000000 \
--premine 0x612C307ae887230B3A5c7B0F93DeF10FF65cb722:0x3635C9ADC5DEA0000000 \
--premine 0x3e6e4eA30e00965d902718c04095d2934366407A:0x3635C9ADC5DEA0000000 \
--premine 0x21dc979ebc01E2dAED3f0792C13513CBe379E49A:0x3635C9ADC5DEA0000000 \
--validatorset-owner 0x20E088469849516610a759C7Bd60434298a91589
```

128 changes: 128 additions & 0 deletions cmd/genesis-gen/bridge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package main

import (
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/dccontracts"
"github.com/ethereum/go-ethereum/crypto"
)

var (
DefaultBridgeThreshold = "0x56bc75e2d63100000" // 100 wDoge
DefaultBridgeRate = 100 // 1%
)

// Slot definitions for SC storage
const (
ownerSlot = int64(iota) // Slot 0
minimumThresholdSlot
signersSlot
addressToIsSignerSlot
addressToSignerIndexSlot
// ordersSlot // too complicated, would not be set
// totalSupplySlot // would not be set
rateSlot = int64(iota + 2)
)

// StorageIndexes is a wrapper for different storage indexes that
// need to be modified
type StorageIndexes struct {
bridgeOwnerIndex []byte // address
bridgeMinimumThresholdIndex []byte // uint256
bridgeSignersIndex []byte // []address
bridgeSignersArraySizeIndex []byte // []address size
bridgeAddressToIsSignerIndex []byte // mapping(address => bool)
bridgeAddressToSignerIndexIndex []byte // mapping(address => uint256)
bridgeRateIndex []byte // uint256
}

// getStorageIndexes is a helper function for getting the correct indexes
// of the storage slots which need to be modified during bootstrap.
//
// It is SC dependant, and based on the SC located at:
// https://github.com/dogechain-lab/dogechain-contracts/
func getStorageIndexes(address common.Address, index int64) *StorageIndexes {
storageIndexes := StorageIndexes{}

// Get the indexes for _owner, _minimumThreshold
// Index for regular types is calculated as just the regular slot
storageIndexes.bridgeOwnerIndex = big.NewInt(ownerSlot).Bytes()
storageIndexes.bridgeMinimumThresholdIndex = big.NewInt(minimumThresholdSlot).Bytes()
storageIndexes.bridgeRateIndex = big.NewInt(rateSlot).Bytes()

// Get the indexes for the mappings
// The index for the mapping is retrieved with:
// keccak(address . slot)
// . stands for concatenation (basically appending the bytes)
storageIndexes.bridgeAddressToIsSignerIndex = getAddressMapping(address, addressToIsSignerSlot)
storageIndexes.bridgeAddressToSignerIndexIndex = getAddressMapping(address, addressToSignerIndexSlot)

// Index for array types is calculated as keccak(slot) + index
// The slot for the dynamic arrays that's put in the keccak needs to be in hex form (padded 64 chars)
storageIndexes.bridgeSignersIndex = getIndexWithOffset(
crypto.Keccak256(PadLeftOrTrim(big.NewInt(signersSlot).Bytes(), 32)),
index,
)

// For any dynamic array in Solidity, the size of the actual array should be
// located on slot x
storageIndexes.bridgeSignersArraySizeIndex = []byte{byte(signersSlot)}

return &storageIndexes
}

// predeployBridgeSC is a helper method for setting up the bridge smart contract account,
// using the passed in owner and signers as pre-defined accounts.
func predeployBridgeSC(owner common.Address, signers []common.Address) *core.GenesisAccount {
// Set the code for the bridge smart contract
// Code retrieved from https://github.com/dogechain-lab/dogechain-contracts
bridgeAccount := &core.GenesisAccount{
Code: dccontracts.DCBridgeContractByteCode,
}

bigDefaultRate := big.NewInt(int64(DefaultBridgeRate))
bigTrueValue := big.NewInt(1)

// Generate the empty account storage map
storageMap := make(map[common.Hash]common.Hash)

for indx, signer := range signers {
// Get the storage indexes
storageIndexes := getStorageIndexes(signer, int64(indx))

// Set the value for the owner
storageMap[common.BytesToHash(storageIndexes.bridgeOwnerIndex)] =
common.BytesToHash(owner.Bytes())

// Set the value for the minimum threshold
storageMap[common.BytesToHash(storageIndexes.bridgeMinimumThresholdIndex)] =
common.HexToHash(DefaultBridgeThreshold)

// Set the value for the signers array
storageMap[common.BytesToHash(storageIndexes.bridgeSignersIndex)] =
common.BytesToHash(signer.Bytes())

// Set the value for the size of the signers array
storageMap[common.BytesToHash(storageIndexes.bridgeSignersArraySizeIndex)] =
common.BigToHash(new(big.Int).SetUint64(uint64(indx + 1)))

// Set the value for the address -> is signer mapping
storageMap[common.BytesToHash(storageIndexes.bridgeAddressToIsSignerIndex)] =
common.BytesToHash(bigTrueValue.Bytes())

// Set the value for the address -> signer array index mapping
storageMap[common.BytesToHash(storageIndexes.bridgeAddressToSignerIndexIndex)] =
common.BigToHash(new(big.Int).SetUint64(uint64(indx)))

// Set the value for the rate
storageMap[common.BytesToHash(storageIndexes.bridgeRateIndex)] =
common.BytesToHash(bigDefaultRate.Bytes())
}

// Save the storage map
bridgeAccount.Storage = storageMap

return bridgeAccount
}
Loading