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

Testnet launched - Monetary Policy rewards #25

Merged
merged 10 commits into from
May 25, 2019
47 changes: 47 additions & 0 deletions consensus/ethash/callisto_diff.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package ethash

import (
"math/big"

"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
)

func calcDifficultyCallisto(time uint64, parent *types.Header) *big.Int {
// https://github.com/ethereum/EIPs/issues/100.
// algorithm:
// diff = (parent_diff +
// (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
// ) + 2^(periodCount - 2)

bigTime := new(big.Int).SetUint64(time)
bigParentTime := new(big.Int).SetUint64(parent.Time)

// holds intermediate values to make the algo easier to read & audit
x := new(big.Int)
y := new(big.Int)

// (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9
x.Sub(bigTime, bigParentTime)
x.Div(x, big9)
if parent.UncleHash == types.EmptyUncleHash {
x.Sub(big1, x)
} else {
x.Sub(big2, x)
}
// max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99)
if x.Cmp(bigMinus99) < 0 {
x.Set(bigMinus99)
}
// parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
x.Mul(y, x)
x.Add(parent.Difficulty, x)

// minimum difficulty can ever be (before exponential factor)
if x.Cmp(params.MinimumDifficulty) < 0 {
x.Set(params.MinimumDifficulty)
}

return x
}
91 changes: 91 additions & 0 deletions consensus/ethash/callisto_reward.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package ethash

import (
"math/big"

"github.com/ethereum/go-ethereum/common"
)

var (
// CLOMinerReward - Block reward in wei for successfully mining a block upward for Callisto Network
CLOMinerReward = new(big.Int).Mul(big.NewInt(420), big.NewInt(1e+18))
// CLOTreasuryReward - Block reward in wei for successfully mining a block upward for Callisto Network
CLOTreasuryReward = new(big.Int).Mul(big.NewInt(120), big.NewInt(1e+18))
// CLOStakeReward - Block reward in wei for successfully mining a block upward for Callisto Network
CLOStakeReward = new(big.Int).Mul(big.NewInt(60), big.NewInt(1e+18))
// CLOHF1TreasuryReward - Block reward in wei for successfully mining a block upward for Callisto Network
CLOHF1TreasuryReward = new(big.Int).Mul(big.NewInt(60), big.NewInt(1e+18))
// CLOHF1StakeReward - Block reward in wei for successfully mining a block upward for Callisto Network
CLOHF1StakeReward = new(big.Int).Mul(big.NewInt(120), big.NewInt(1e+18))
// CLOTreasuryAddress - Treasury Address
CLOTreasuryAddress = common.HexToAddress("0x74682Fc32007aF0b6118F259cBe7bCCC21641600")
// CLOStakeAddress - Stake Address before HF1
CLOStakeAddress = common.HexToAddress("0x3c06f218Ce6dD8E2c535a8925A2eDF81674984D9")
// CLOHF1StakeAddress - Stake Address HF1
CLOHF1StakeAddress = common.HexToAddress("0xd813419749b3c2cdc94a2f9cfcf154113264a9d6")
)

func calcBigNumber(reward float64) *big.Int {
bigReward := new(big.Float).Mul(big.NewFloat(reward), big.NewFloat(1e+18))
bigRewardInt := new(big.Int)
bigReward.Int(bigRewardInt)
return bigRewardInt
}

func getCLOMonetaryPolicyMinerReward(blockNumber *big.Int) *big.Int {
switch {
case big.NewInt(2900001).Cmp(blockNumber) == 0:
return calcBigNumber(234)
case big.NewInt(4400001).Cmp(blockNumber) == 0:
return calcBigNumber(129.6)
case big.NewInt(5900001).Cmp(blockNumber) == 0:
return calcBigNumber(71.28)
}
return calcBigNumber(38.88)
}

func getCLOMonetaryPolicyTreasury(blockNumber *big.Int) *big.Int {
switch {
case big.NewInt(2900001).Cmp(blockNumber) == 0:
return calcBigNumber(36)
case big.NewInt(4400001).Cmp(blockNumber) == 0:
return calcBigNumber(21.6)
case big.NewInt(5900001).Cmp(blockNumber) == 0:
return calcBigNumber(12.96)
}
return calcBigNumber(7.77)
}

func getCLOMonetaryPolicyStake(blockNumber *big.Int) *big.Int {
switch {
case big.NewInt(2900001).Cmp(blockNumber) == 0:
return calcBigNumber(90)
case big.NewInt(4400001).Cmp(blockNumber) == 0:
return calcBigNumber(64.8)
case big.NewInt(5900001).Cmp(blockNumber) == 0:
return calcBigNumber(45.36)
}
return calcBigNumber(31.1)
}

func getMonetaryPolicyStepMainnet(blockNumber *big.Int) *big.Int {
if blockNumber.Cmp(big.NewInt(4400001)) == -1 {
return big.NewInt(2900001)
} else if blockNumber.Cmp(big.NewInt(5900001)) == -1 {
return big.NewInt(4400001)
} else if blockNumber.Cmp(big.NewInt(7400001)) == -1 {
return big.NewInt(5900001)
}
return big.NewInt(7400001)
}

func getMonetaryPolicyStepTestnet(blockNumber *big.Int) *big.Int {
if blockNumber.Cmp(big.NewInt(2000)) == -1 {
return big.NewInt(2900001)
} else if blockNumber.Cmp(big.NewInt(3000)) == -1 {
return big.NewInt(4400001)
} else if blockNumber.Cmp(big.NewInt(4000)) == -1 {
return big.NewInt(5900001)
}
return big.NewInt(7400001)
}
57 changes: 34 additions & 23 deletions consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,11 @@ import (

// Ethash proof-of-work protocol constants.
var (
FrontierBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
ByzantiumBlockReward = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
ConstantinopleBlockReward = big.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople
CLOMinerReward = new(big.Int).Mul(big.NewInt(420), big.NewInt(1e+18)) // Block reward in wei for successfully mining a block upward for Callisto Network
CLOTreasuryReward = new(big.Int).Mul(big.NewInt(120), big.NewInt(1e+18)) // Block reward in wei for successfully mining a block upward for Callisto Network
CLOStakeReward = new(big.Int).Mul(big.NewInt(60), big.NewInt(1e+18)) // Block reward in wei for successfully mining a block upward for Callisto Network
CLOHF1TreasuryReward = new(big.Int).Mul(big.NewInt(60), big.NewInt(1e+18)) // Block reward in wei for successfully mining a block upward for Callisto Network
CLOHF1StakeReward = new(big.Int).Mul(big.NewInt(120), big.NewInt(1e+18)) // Block reward in wei for successfully mining a block upward for Callisto Network
CLOTreasuryAddress = common.HexToAddress("0x74682Fc32007aF0b6118F259cBe7bCCC21641600")
CLOStakeAddress = common.HexToAddress("0x3c06f218Ce6dD8E2c535a8925A2eDF81674984D9")
CLOHF1StakeAddress = common.HexToAddress("0xd813419749b3c2cdc94a2f9cfcf154113264a9d6")
maxUncles = 2 // Maximum number of uncles allowed in a single block
allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks
FrontierBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
ByzantiumBlockReward = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
ConstantinopleBlockReward = big.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople
maxUncles = 2 // Maximum number of uncles allowed in a single block
allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks

// calcDifficultyConstantinople is the difficulty adjustment algorithm for Constantinople.
// It returns the difficulty that a new block should have when created at time given the
Expand Down Expand Up @@ -316,6 +308,8 @@ func (ethash *Ethash) CalcDifficulty(chain consensus.ChainReader, time uint64, p
func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
next := new(big.Int).Add(parent.Number, big1)
switch {
case config.IsCLOMP(next):
return calcDifficultyCallisto(time, parent)
case config.IsConstantinople(next):
return calcDifficultyConstantinople(time, parent)
case config.IsByzantium(next):
Expand Down Expand Up @@ -556,14 +550,21 @@ func (ethash *Ethash) verifySeal(chain consensus.ChainReader, header *types.Head

var accumulateRewards func(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) = defaultAccumulateRewards

var getMonetaryPolicyStep func(blockNumber *big.Int) *big.Int = getMonetaryPolicyStepMainnet

// Prepare implements consensus.Engine, initializing the difficulty field of a
// header to conform to the ethash protocol. The changes are done inline.
func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) error {
genesisHash := chain.GetHeaderByNumber(0).Hash()

if genesisHash == params.CallistoGenesisHash || genesisHash == params.CallistoTestnetGenesisHash {
accumulateRewards = callistoAccumulateRewards
}

if genesisHash == params.CallistoTestnetGenesisHash {
getMonetaryPolicyStep = getMonetaryPolicyStepTestnet
}

parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
if parent == nil {
return consensus.ErrUnknownAncestor
Expand Down Expand Up @@ -643,7 +644,24 @@ func defaultAccumulateRewards(config *params.ChainConfig, state *state.StateDB,
// callistoAccumulateRewards()
func callistoAccumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
// Select the correct block reward based on chain progression
// Initial Callisto reward
blockReward := CLOMinerReward
treasuryReward := CLOTreasuryReward
stakeReward := CLOStakeReward

if config.IsCLOHF1(header.Number) {
treasuryReward = CLOHF1TreasuryReward
stakeReward = CLOHF1StakeReward
}

monetaryPolicyStep := big.NewInt(0)

if config.IsCLOMP(header.Number) {
monetaryPolicyStep = getMonetaryPolicyStep(header.Number)
blockReward = getCLOMonetaryPolicyMinerReward(monetaryPolicyStep)
treasuryReward = getCLOMonetaryPolicyTreasury(monetaryPolicyStep)
stakeReward = getCLOMonetaryPolicyStake(monetaryPolicyStep)
}

// Accumulate the rewards for the miner and any included uncles
reward := new(big.Int).Set(blockReward)
Expand All @@ -659,14 +677,7 @@ func callistoAccumulateRewards(config *params.ChainConfig, state *state.StateDB,
reward.Add(reward, r)
}

// Activate Callisto hardfork
if config.IsCLOHF1(header.Number) {
state.AddBalance(header.Coinbase, reward)
state.AddBalance(CLOTreasuryAddress, CLOHF1TreasuryReward)
state.AddBalance(CLOHF1StakeAddress, CLOHF1StakeReward)
} else {
state.AddBalance(header.Coinbase, reward)
state.AddBalance(CLOTreasuryAddress, CLOTreasuryReward)
state.AddBalance(CLOStakeAddress, CLOStakeReward)
}
state.AddBalance(header.Coinbase, reward)
state.AddBalance(CLOTreasuryAddress, treasuryReward)
state.AddBalance(CLOHF1StakeAddress, stakeReward)
}
11 changes: 9 additions & 2 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
"github.com/hashicorp/golang-lru"
lru "github.com/hashicorp/golang-lru"
)

var (
Expand Down Expand Up @@ -1135,7 +1135,14 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []
abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
defer close(abort)

errChain := bc.checkChainForAttack(chain)
chainProtectionActivationBlock := params.ActivationBlock

// Blockchain CLO Testnet
if bc.chainConfig.ChainID.Cmp(big.NewInt(20729)) == 0 {
chainProtectionActivationBlock = params.ActivationBlockTestnet
}

errChain := bc.checkChainForAttack(chain, chainProtectionActivationBlock)

// Peek the error for the first block to decide the directing import logic
it := newInsertIterator(chain, results, bc.Validator())
Expand Down
2 changes: 1 addition & 1 deletion core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ func DefaultCallistoTestnetGenesisBlock() *Genesis {
Config: params.CallistoChainTestnetConfig,
ExtraData: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000"),
GasLimit: 10400000,
Difficulty: big.NewInt(524288),
Difficulty: big.NewInt(1000000),
Timestamp: 1519622213,
Nonce: 0,
Coinbase: common.HexToAddress("0xc3F70b10CE5EC4aA47ce44Eb0B7900A883cd45Dd"),
Expand Down
2 changes: 1 addition & 1 deletion core/genesis_alloc.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ const testnetAllocData = "\xf9\x03\xa4\u0080\x01\xc2\x01\x01\xc2\x02\x01\xc2\x03
const rinkebyAllocData = "\xf9\x03\xb7\u0080\x01\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xc2\t\x01\xc2\n\x01\xc2\v\x01\xc2\f\x01\xc2\r\x01\xc2\x0e\x01\xc2\x0f\x01\xc2\x10\x01\xc2\x11\x01\xc2\x12\x01\xc2\x13\x01\xc2\x14\x01\xc2\x15\x01\xc2\x16\x01\xc2\x17\x01\xc2\x18\x01\xc2\x19\x01\xc2\x1a\x01\xc2\x1b\x01\xc2\x1c\x01\xc2\x1d\x01\xc2\x1e\x01\xc2\x1f\x01\xc2 \x01\xc2!\x01\xc2\"\x01\xc2#\x01\xc2$\x01\xc2%\x01\xc2&\x01\xc2'\x01\xc2(\x01\xc2)\x01\xc2*\x01\xc2+\x01\xc2,\x01\xc2-\x01\xc2.\x01\xc2/\x01\xc20\x01\xc21\x01\xc22\x01\xc23\x01\xc24\x01\xc25\x01\xc26\x01\xc27\x01\xc28\x01\xc29\x01\xc2:\x01\xc2;\x01\xc2<\x01\xc2=\x01\xc2>\x01\xc2?\x01\xc2@\x01\xc2A\x01\xc2B\x01\xc2C\x01\xc2D\x01\xc2E\x01\xc2F\x01\xc2G\x01\xc2H\x01\xc2I\x01\xc2J\x01\xc2K\x01\xc2L\x01\xc2M\x01\xc2N\x01\xc2O\x01\xc2P\x01\xc2Q\x01\xc2R\x01\xc2S\x01\xc2T\x01\xc2U\x01\xc2V\x01\xc2W\x01\xc2X\x01\xc2Y\x01\xc2Z\x01\xc2[\x01\xc2\\\x01\xc2]\x01\xc2^\x01\xc2_\x01\xc2`\x01\xc2a\x01\xc2b\x01\xc2c\x01\xc2d\x01\xc2e\x01\xc2f\x01\xc2g\x01\xc2h\x01\xc2i\x01\xc2j\x01\xc2k\x01\xc2l\x01\xc2m\x01\xc2n\x01\xc2o\x01\xc2p\x01\xc2q\x01\xc2r\x01\xc2s\x01\xc2t\x01\xc2u\x01\xc2v\x01\xc2w\x01\xc2x\x01\xc2y\x01\xc2z\x01\xc2{\x01\xc2|\x01\xc2}\x01\xc2~\x01\xc2\u007f\x01\u00c1\x80\x01\u00c1\x81\x01\u00c1\x82\x01\u00c1\x83\x01\u00c1\x84\x01\u00c1\x85\x01\u00c1\x86\x01\u00c1\x87\x01\u00c1\x88\x01\u00c1\x89\x01\u00c1\x8a\x01\u00c1\x8b\x01\u00c1\x8c\x01\u00c1\x8d\x01\u00c1\x8e\x01\u00c1\x8f\x01\u00c1\x90\x01\u00c1\x91\x01\u00c1\x92\x01\u00c1\x93\x01\u00c1\x94\x01\u00c1\x95\x01\u00c1\x96\x01\u00c1\x97\x01\u00c1\x98\x01\u00c1\x99\x01\u00c1\x9a\x01\u00c1\x9b\x01\u00c1\x9c\x01\u00c1\x9d\x01\u00c1\x9e\x01\u00c1\x9f\x01\u00c1\xa0\x01\u00c1\xa1\x01\u00c1\xa2\x01\u00c1\xa3\x01\u00c1\xa4\x01\u00c1\xa5\x01\u00c1\xa6\x01\u00c1\xa7\x01\u00c1\xa8\x01\u00c1\xa9\x01\u00c1\xaa\x01\u00c1\xab\x01\u00c1\xac\x01\u00c1\xad\x01\u00c1\xae\x01\u00c1\xaf\x01\u00c1\xb0\x01\u00c1\xb1\x01\u00c1\xb2\x01\u00c1\xb3\x01\u00c1\xb4\x01\u00c1\xb5\x01\u00c1\xb6\x01\u00c1\xb7\x01\u00c1\xb8\x01\u00c1\xb9\x01\u00c1\xba\x01\u00c1\xbb\x01\u00c1\xbc\x01\u00c1\xbd\x01\u00c1\xbe\x01\u00c1\xbf\x01\u00c1\xc0\x01\u00c1\xc1\x01\u00c1\xc2\x01\u00c1\xc3\x01\u00c1\xc4\x01\u00c1\xc5\x01\u00c1\xc6\x01\u00c1\xc7\x01\u00c1\xc8\x01\u00c1\xc9\x01\u00c1\xca\x01\u00c1\xcb\x01\u00c1\xcc\x01\u00c1\xcd\x01\u00c1\xce\x01\u00c1\xcf\x01\u00c1\xd0\x01\u00c1\xd1\x01\u00c1\xd2\x01\u00c1\xd3\x01\u00c1\xd4\x01\u00c1\xd5\x01\u00c1\xd6\x01\u00c1\xd7\x01\u00c1\xd8\x01\u00c1\xd9\x01\u00c1\xda\x01\u00c1\xdb\x01\u00c1\xdc\x01\u00c1\xdd\x01\u00c1\xde\x01\u00c1\xdf\x01\u00c1\xe0\x01\u00c1\xe1\x01\u00c1\xe2\x01\u00c1\xe3\x01\u00c1\xe4\x01\u00c1\xe5\x01\u00c1\xe6\x01\u00c1\xe7\x01\u00c1\xe8\x01\u00c1\xe9\x01\u00c1\xea\x01\u00c1\xeb\x01\u00c1\xec\x01\u00c1\xed\x01\u00c1\xee\x01\u00c1\xef\x01\u00c1\xf0\x01\u00c1\xf1\x01\u00c1\xf2\x01\u00c1\xf3\x01\u00c1\xf4\x01\u00c1\xf5\x01\u00c1\xf6\x01\u00c1\xf7\x01\u00c1\xf8\x01\u00c1\xf9\x01\u00c1\xfa\x01\u00c1\xfb\x01\u00c1\xfc\x01\u00c1\xfd\x01\u00c1\xfe\x01\u00c1\xff\x01\xf6\x941\xb9\x8d\x14\x00{\xde\xe67)\x80\x86\x98\x8a\v\xbd1\x18E#\xa0\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
const goerliAllocData = "\xf9\x04\x06\u0080\x01\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xc2\t\x01\xc2\n\x01\xc2\v\x01\xc2\f\x01\xc2\r\x01\xc2\x0e\x01\xc2\x0f\x01\xc2\x10\x01\xc2\x11\x01\xc2\x12\x01\xc2\x13\x01\xc2\x14\x01\xc2\x15\x01\xc2\x16\x01\xc2\x17\x01\xc2\x18\x01\xc2\x19\x01\xc2\x1a\x01\xc2\x1b\x01\xc2\x1c\x01\xc2\x1d\x01\xc2\x1e\x01\xc2\x1f\x01\xc2 \x01\xc2!\x01\xc2\"\x01\xc2#\x01\xc2$\x01\xc2%\x01\xc2&\x01\xc2'\x01\xc2(\x01\xc2)\x01\xc2*\x01\xc2+\x01\xc2,\x01\xc2-\x01\xc2.\x01\xc2/\x01\xc20\x01\xc21\x01\xc22\x01\xc23\x01\xc24\x01\xc25\x01\xc26\x01\xc27\x01\xc28\x01\xc29\x01\xc2:\x01\xc2;\x01\xc2<\x01\xc2=\x01\xc2>\x01\xc2?\x01\xc2@\x01\xc2A\x01\xc2B\x01\xc2C\x01\xc2D\x01\xc2E\x01\xc2F\x01\xc2G\x01\xc2H\x01\xc2I\x01\xc2J\x01\xc2K\x01\xc2L\x01\xc2M\x01\xc2N\x01\xc2O\x01\xc2P\x01\xc2Q\x01\xc2R\x01\xc2S\x01\xc2T\x01\xc2U\x01\xc2V\x01\xc2W\x01\xc2X\x01\xc2Y\x01\xc2Z\x01\xc2[\x01\xc2\\\x01\xc2]\x01\xc2^\x01\xc2_\x01\xc2`\x01\xc2a\x01\xc2b\x01\xc2c\x01\xc2d\x01\xc2e\x01\xc2f\x01\xc2g\x01\xc2h\x01\xc2i\x01\xc2j\x01\xc2k\x01\xc2l\x01\xc2m\x01\xc2n\x01\xc2o\x01\xc2p\x01\xc2q\x01\xc2r\x01\xc2s\x01\xc2t\x01\xc2u\x01\xc2v\x01\xc2w\x01\xc2x\x01\xc2y\x01\xc2z\x01\xc2{\x01\xc2|\x01\xc2}\x01\xc2~\x01\xc2\u007f\x01\u00c1\x80\x01\u00c1\x81\x01\u00c1\x82\x01\u00c1\x83\x01\u00c1\x84\x01\u00c1\x85\x01\u00c1\x86\x01\u00c1\x87\x01\u00c1\x88\x01\u00c1\x89\x01\u00c1\x8a\x01\u00c1\x8b\x01\u00c1\x8c\x01\u00c1\x8d\x01\u00c1\x8e\x01\u00c1\x8f\x01\u00c1\x90\x01\u00c1\x91\x01\u00c1\x92\x01\u00c1\x93\x01\u00c1\x94\x01\u00c1\x95\x01\u00c1\x96\x01\u00c1\x97\x01\u00c1\x98\x01\u00c1\x99\x01\u00c1\x9a\x01\u00c1\x9b\x01\u00c1\x9c\x01\u00c1\x9d\x01\u00c1\x9e\x01\u00c1\x9f\x01\u00c1\xa0\x01\u00c1\xa1\x01\u00c1\xa2\x01\u00c1\xa3\x01\u00c1\xa4\x01\u00c1\xa5\x01\u00c1\xa6\x01\u00c1\xa7\x01\u00c1\xa8\x01\u00c1\xa9\x01\u00c1\xaa\x01\u00c1\xab\x01\u00c1\xac\x01\u00c1\xad\x01\u00c1\xae\x01\u00c1\xaf\x01\u00c1\xb0\x01\u00c1\xb1\x01\u00c1\xb2\x01\u00c1\xb3\x01\u00c1\xb4\x01\u00c1\xb5\x01\u00c1\xb6\x01\u00c1\xb7\x01\u00c1\xb8\x01\u00c1\xb9\x01\u00c1\xba\x01\u00c1\xbb\x01\u00c1\xbc\x01\u00c1\xbd\x01\u00c1\xbe\x01\u00c1\xbf\x01\u00c1\xc0\x01\u00c1\xc1\x01\u00c1\xc2\x01\u00c1\xc3\x01\u00c1\xc4\x01\u00c1\xc5\x01\u00c1\xc6\x01\u00c1\xc7\x01\u00c1\xc8\x01\u00c1\xc9\x01\u00c1\xca\x01\u00c1\xcb\x01\u00c1\xcc\x01\u00c1\xcd\x01\u00c1\xce\x01\u00c1\xcf\x01\u00c1\xd0\x01\u00c1\xd1\x01\u00c1\xd2\x01\u00c1\xd3\x01\u00c1\xd4\x01\u00c1\xd5\x01\u00c1\xd6\x01\u00c1\xd7\x01\u00c1\xd8\x01\u00c1\xd9\x01\u00c1\xda\x01\u00c1\xdb\x01\u00c1\xdc\x01\u00c1\xdd\x01\u00c1\xde\x01\u00c1\xdf\x01\u00c1\xe0\x01\u00c1\xe1\x01\u00c1\xe2\x01\u00c1\xe3\x01\u00c1\xe4\x01\u00c1\xe5\x01\u00c1\xe6\x01\u00c1\xe7\x01\u00c1\xe8\x01\u00c1\xe9\x01\u00c1\xea\x01\u00c1\xeb\x01\u00c1\xec\x01\u00c1\xed\x01\u00c1\xee\x01\u00c1\xef\x01\u00c1\xf0\x01\u00c1\xf1\x01\u00c1\xf2\x01\u00c1\xf3\x01\u00c1\xf4\x01\u00c1\xf5\x01\u00c1\xf6\x01\u00c1\xf7\x01\u00c1\xf8\x01\u00c1\xf9\x01\u00c1\xfa\x01\u00c1\xfb\x01\u00c1\xfc\x01\u00c1\xfd\x01\u00c1\xfe\x01\u00c1\xff\x01\xe0\x94L*\xe4\x82Y5\x05\xf0\x16<\xde\xfc\a>\x81\xc6<\xdaA\a\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe0\x94\xa8\xe8\xf1G2e\x8eKQ\xe8q\x191\x05:\x8ai\xba\xf2\xb1\x8a\x15-\x02\xc7\xe1J\xf6\x80\x00\x00\xe1\x94\u0665\x17\x9f\t\x1d\x85\x05\x1d<\x98'\x85\xef\xd1E\\\uc199\x8b\bE\x95\x16\x14\x01HJ\x00\x00\x00\xe1\x94\u08bdBX\xd2v\x887\xba\xa2j(\xfeq\xdc\a\x9f\x84\u01cbJG\xe3\xc1$H\xf4\xad\x00\x00\x00"
const callistoAllocData = "\xf8:\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xe1\x94\x183\x94\xf5+,\x8c\x03H5\xed\xba;\xce\xce\xcao`\xb5\xa8\x8bS\x1f\xfa:s\xdb8X\xa8.\x8c"
const callistoTestnetAllocData = "\xf8\x86\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xe5\x94\x12\xb0\x91\xe7\xcfT\x90\xf1\xbf/&\xe6\xcez\xba4\xb6\xc7/C\x8f\x13Z\xa1\u007f;OWGN\x8d\xda\xf8\xf2x\x00\xe1\x94\x183\x94\xf5+,\x8c\x03H5\xed\xba;\xce\xce\xcao`\xb5\xa8\x8bS\x1f\xfa:s\xdb8X\xa8.\x8c\u5503\u022c\x9a\xa9\xe3e\xe4+\x1d5W\xdc\x14\f\x1e%\xa3\xc5\xf7\x8f\x13Z\xa1\u007f;OWGN\x8d\xda\xf8\xf2x\x00"
const callistoTestnetAllocData = "\xf8]\xc2\x01\x01\xc2\x02\x01\xc2\x03\x01\xc2\x04\x01\xc2\x05\x01\xc2\x06\x01\xc2\a\x01\xc2\b\x01\xe1\x94\x183\x94\xf5+,\x8c\x03H5\xed\xba;\xce\xce\xcao`\xb5\xa8\x8bS\x1f\xfa:s\xdb8X\xa8.\x8c\xe2\x94\u059b\x90\xe6\xf2\xb9V\x82\xcd\xfc\x1d\u007fA\xc9\xf8\xf9&\xf2Ca\x8c x}\xbe\xd5A\xa2\x02\xa1\xb2.\xb0"
Loading