From a5f8f0357a5bbdb991cf001851490fdb5061c1a9 Mon Sep 17 00:00:00 2001
From: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Date: Wed, 20 Dec 2023 22:39:51 -0500
Subject: [PATCH 1/8] implement enough aura consensus to follow chain
---
cmd/utils/flags.go | 44 +-
consensus/aura/aura.go | 1456 +++++++++++++++++
consensus/aura/aura_test.go | 56 +
consensus/aura/auraabi/abi.go | 4 +
consensus/aura/auraabi/gen_block_reward.go | 202 +++
consensus/aura/auraabi/gen_validator_set.go | 461 ++++++
consensus/aura/aurainterfaces/interface.go | 44 +
consensus/aura/config.go | 196 +++
consensus/aura/config_test.go | 35 +
consensus/aura/contract_abi.go | 132 ++
.../contracts/authority_round_random.json | 149 ++
consensus/aura/contracts/block_gas_limit.json | 16 +
consensus/aura/contracts/block_reward.json | 29 +
consensus/aura/contracts/certifier.json | 164 ++
consensus/aura/contracts/embed.go | 20 +
consensus/aura/contracts/registrar.json | 21 +
.../test_authority_round_random.json | 265 +++
.../contracts/test_authority_round_random.sol | 101 ++
.../aura/contracts/test_validator_set.json | 8 +
consensus/aura/contracts/tx_acl.json | 1 +
.../aura/contracts/tx_acl_deprecated.json | 1 +
.../aura/contracts/tx_acl_gas_price.json | 83 +
.../aura/contracts/validator_report.json | 5 +
consensus/aura/contracts/validator_set.json | 55 +
consensus/aura/contracts/withdrawal.json | 23 +
consensus/aura/finality_test.go | 72 +
consensus/aura/gaslimit_override.go | 71 +
consensus/aura/validators.go | 931 +++++++++++
consensus/beacon/consensus.go | 49 +-
consensus/clique/clique.go | 6 +-
consensus/consensus.go | 26 +-
consensus/ethash/consensus.go | 6 +-
core/allocs/chiado.json | 88 +
core/allocs/gnosis.json | 14 +
core/forkid/forkid.go | 10 +-
core/genesis.go | 47 +
core/rawdb/accessors_chain_aura.go | 65 +
core/rawdb/schema.go | 11 +
core/state/statedb.go | 4 +-
core/state_processor.go | 62 +-
core/state_transition.go | 26 +-
core/types/block.go | 2 +
core/types/gen_header_rlp.go | 197 ++-
core/vm/evm.go | 2 +-
eth/ethconfig/config.go | 8 +
eth/protocols/eth/handshake.go | 7 +-
go.mod | 2 +
go.sum | 4 +
miner/worker.go | 29 +-
params/bootnodes.go | 16 +
params/chainspecs/chiado.json | 52 +
params/chainspecs/gnosis.json | 58 +
params/config.go | 10 +-
params/config_aura.go | 75 +
params/gnosis_config.go | 37 +
55 files changed, 5502 insertions(+), 56 deletions(-)
create mode 100644 consensus/aura/aura.go
create mode 100644 consensus/aura/aura_test.go
create mode 100644 consensus/aura/auraabi/abi.go
create mode 100644 consensus/aura/auraabi/gen_block_reward.go
create mode 100644 consensus/aura/auraabi/gen_validator_set.go
create mode 100644 consensus/aura/aurainterfaces/interface.go
create mode 100644 consensus/aura/config.go
create mode 100644 consensus/aura/config_test.go
create mode 100644 consensus/aura/contract_abi.go
create mode 100644 consensus/aura/contracts/authority_round_random.json
create mode 100644 consensus/aura/contracts/block_gas_limit.json
create mode 100644 consensus/aura/contracts/block_reward.json
create mode 100644 consensus/aura/contracts/certifier.json
create mode 100644 consensus/aura/contracts/embed.go
create mode 100644 consensus/aura/contracts/registrar.json
create mode 100644 consensus/aura/contracts/test_authority_round_random.json
create mode 100644 consensus/aura/contracts/test_authority_round_random.sol
create mode 100644 consensus/aura/contracts/test_validator_set.json
create mode 100644 consensus/aura/contracts/tx_acl.json
create mode 100644 consensus/aura/contracts/tx_acl_deprecated.json
create mode 100644 consensus/aura/contracts/tx_acl_gas_price.json
create mode 100644 consensus/aura/contracts/validator_report.json
create mode 100644 consensus/aura/contracts/validator_set.json
create mode 100644 consensus/aura/contracts/withdrawal.json
create mode 100644 consensus/aura/finality_test.go
create mode 100644 consensus/aura/gaslimit_override.go
create mode 100644 consensus/aura/validators.go
create mode 100644 core/allocs/chiado.json
create mode 100644 core/allocs/gnosis.json
create mode 100644 core/rawdb/accessors_chain_aura.go
create mode 100644 params/chainspecs/chiado.json
create mode 100644 params/chainspecs/gnosis.json
create mode 100644 params/config_aura.go
create mode 100644 params/gnosis_config.go
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 159c47ca0191..bf5fbe4ab94b 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -155,6 +155,16 @@ var (
Usage: "Holesky network: pre-configured proof-of-stake test network",
Category: flags.EthCategory,
}
+ GnosisChainFlag = &cli.BoolFlag{
+ Name: "gnosis",
+ Usage: "Gnosis chain network: pre-configured merged proof-of-authority test network",
+ Category: flags.EthCategory,
+ }
+ ChiadoFlag = &cli.BoolFlag{
+ Name: "chiado",
+ Usage: "Chiado network: pre-configured merged proof-of-authority test network",
+ Category: flags.EthCategory,
+ }
// Dev mode
DeveloperFlag = &cli.BoolFlag{
Name: "dev",
@@ -916,6 +926,8 @@ var (
GoerliFlag,
SepoliaFlag,
HoleskyFlag,
+ GnosisChainFlag,
+ ChiadoFlag,
}
// NetworkFlags is the flag group of all built-in supported networks.
NetworkFlags = append([]cli.Flag{MainnetFlag}, TestnetFlags...)
@@ -945,6 +957,12 @@ func MakeDataDir(ctx *cli.Context) string {
if ctx.Bool(HoleskyFlag.Name) {
return filepath.Join(path, "holesky")
}
+ if ctx.Bool(GnosisChainFlag.Name) {
+ return filepath.Join(path, "gnosis")
+ }
+ if ctx.Bool(ChiadoFlag.Name) {
+ return filepath.Join(path, "chiado")
+ }
return path
}
Fatalf("Cannot determine default data directory, please set manually (--datadir)")
@@ -1007,6 +1025,10 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
urls = params.SepoliaBootnodes
case ctx.Bool(GoerliFlag.Name):
urls = params.GoerliBootnodes
+ case ctx.Bool(GnosisChainFlag.Name):
+ urls = params.GnosisBootnodes
+ case ctx.Bool(ChiadoFlag.Name):
+ urls = params.ChiadoBootnodes
}
}
cfg.BootstrapNodes = mustParseBootnodes(urls)
@@ -1434,6 +1456,10 @@ func SetDataDir(ctx *cli.Context, cfg *node.Config) {
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "sepolia")
case ctx.Bool(HoleskyFlag.Name) && cfg.DataDir == node.DefaultDataDir():
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "holesky")
+ case ctx.Bool(GnosisChainFlag.Name) && cfg.DataDir == node.DefaultDataDir():
+ cfg.DataDir = filepath.Join(node.DefaultDataDir(), "gnosis")
+ case ctx.Bool(ChiadoFlag.Name) && cfg.DataDir == node.DefaultDataDir():
+ cfg.DataDir = filepath.Join(node.DefaultDataDir(), "chiado")
}
}
@@ -1585,7 +1611,7 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) {
// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
// Avoid conflicting network flags
- CheckExclusive(ctx, MainnetFlag, DeveloperFlag, GoerliFlag, SepoliaFlag, HoleskyFlag)
+ CheckExclusive(ctx, MainnetFlag, DeveloperFlag, GoerliFlag, SepoliaFlag, HoleskyFlag, ChiadoFlag, GnosisChainFlag)
CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
// Set configurations from CLI flags
@@ -1754,6 +1780,18 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
}
cfg.Genesis = core.DefaultGoerliGenesisBlock()
SetDNSDiscoveryDefaults(cfg, params.GoerliGenesisHash)
+ case ctx.Bool(GnosisChainFlag.Name):
+ if !ctx.IsSet(NetworkIdFlag.Name) {
+ cfg.NetworkId = 100
+ }
+ cfg.Genesis = core.DefaultGnosisGenesisBlock()
+ SetDNSDiscoveryDefaults(cfg, params.GnosisGenesisHash)
+ case ctx.Bool(ChiadoFlag.Name):
+ if !ctx.IsSet(NetworkIdFlag.Name) {
+ cfg.NetworkId = 10200
+ }
+ cfg.Genesis = core.DefaultChiadoGenesisBlock()
+ SetDNSDiscoveryDefaults(cfg, params.ChiadoGenesisHash)
case ctx.Bool(DeveloperFlag.Name):
if !ctx.IsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 1337
@@ -2063,6 +2101,10 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
genesis = core.DefaultSepoliaGenesisBlock()
case ctx.Bool(GoerliFlag.Name):
genesis = core.DefaultGoerliGenesisBlock()
+ case ctx.Bool(GnosisChainFlag.Name):
+ genesis = core.DefaultGnosisGenesisBlock()
+ case ctx.Bool(ChiadoFlag.Name):
+ genesis = core.DefaultChiadoGenesisBlock()
case ctx.Bool(DeveloperFlag.Name):
Fatalf("Developer chains are ephemeral")
}
diff --git a/consensus/aura/aura.go b/consensus/aura/aura.go
new file mode 100644
index 000000000000..44f57dd86b12
--- /dev/null
+++ b/consensus/aura/aura.go
@@ -0,0 +1,1456 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package aura
+
+import (
+ "bytes"
+ "container/list"
+ "errors"
+ "fmt"
+ "math/big"
+ "sort"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ // "github.com/ethereum/erigon-lib/kv"
+
+ "github.com/cockroachdb/pebble"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus"
+ "github.com/ethereum/go-ethereum/consensus/clique"
+ "github.com/ethereum/go-ethereum/consensus/misc"
+ // "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
+ "github.com/ethereum/go-ethereum/core/rawdb"
+ "github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/params"
+ "github.com/ethereum/go-ethereum/rlp"
+ "github.com/ethereum/go-ethereum/rpc"
+ "github.com/ethereum/go-ethereum/trie"
+ "github.com/holiman/uint256"
+ "golang.org/x/exp/constraints"
+ "golang.org/x/exp/slices"
+)
+
+const DEBUG_LOG_FROM = 999_999_999
+
+var (
+ errOlderBlockTime = errors.New("timestamp older than parent")
+
+ allowedFutureBlockTimeSeconds = int64(15) // Max seconds from current time allowed for blocks, before they're considered future blocks
+)
+
+/*
+Not implemented features from OS:
+ - two_thirds_majority_transition - because no chains in OE where this is != MaxUint64 - means 1/2 majority used everywhere
+ - emptyStepsTransition - same
+
+Repo with solidity sources: https://github.com/poanetwork/posdao-contracts
+*/
+
+type StepDurationInfo struct {
+ TransitionStep uint64
+ TransitionTimestamp uint64
+ StepDuration uint64
+}
+
+// EpochTransitionProof - Holds 2 proofs inside: ValidatorSetProof and FinalityProof
+type EpochTransitionProof struct {
+ SignalNumber uint64
+ SetProof []byte
+ FinalityProof []byte
+}
+
+// ValidatorSetProof - validator set proof
+type ValidatorSetProof struct {
+ Header *types.Header
+ Receipts types.Receipts
+}
+
+// FirstValidatorSetProof state-dependent proofs for the safe contract:
+// only "first" proofs are such.
+type FirstValidatorSetProof struct { // TODO: whaaat? here is no state!
+ ContractAddress common.Address
+ Header *types.Header
+}
+
+type EpochTransition struct {
+ /// Block hash at which the transition occurred.
+ BlockHash common.Hash
+ /// Block number at which the transition occurred.
+ BlockNumber uint64
+ /// "transition/epoch" proof from the engine combined with a finality proof.
+ ProofRlp []byte
+}
+
+type Step struct {
+ calibrate bool // whether calibration is enabled.
+ inner atomic.Uint64
+ // Planned durations of steps.
+ durations []StepDurationInfo
+}
+
+func (s *Step) doCalibrate() {
+ if s.calibrate {
+ if !s.optCalibrate() {
+ ctr := s.inner.Load()
+ panic(fmt.Errorf("step counter under- or overflow: %d", ctr))
+ }
+ }
+}
+
+// optCalibrate Calibrates the AuRa step number according to the current time.
+func (s *Step) optCalibrate() bool {
+ now := time.Now().Unix()
+ var info StepDurationInfo
+ i := 0
+ for _, d := range s.durations {
+ if d.TransitionTimestamp >= uint64(now) {
+ break
+ }
+ info = d
+ i++
+ }
+ if i == 0 {
+ panic("durations cannot be empty")
+ }
+
+ if uint64(now) < info.TransitionTimestamp {
+ return false
+ }
+
+ newStep := (uint64(now)-info.TransitionTimestamp)/info.StepDuration + info.TransitionStep
+ s.inner.Store(newStep)
+ return true
+}
+
+type PermissionedStep struct {
+ inner *Step
+ canPropose atomic.Bool
+}
+
+type ReceivedStepHashes map[uint64]map[common.Address]common.Hash //BTreeMap<(u64, Address), H256>
+
+// nolint
+func (r ReceivedStepHashes) get(step uint64, author common.Address) (common.Hash, bool) {
+ res, ok := r[step]
+ if !ok {
+ return common.Hash{}, false
+ }
+ result, ok := res[author]
+ return result, ok
+}
+
+// nolint
+func (r ReceivedStepHashes) insert(step uint64, author common.Address, blockHash common.Hash) {
+ res, ok := r[step]
+ if !ok {
+ res = map[common.Address]common.Hash{}
+ r[step] = res
+ }
+ res[author] = blockHash
+}
+
+// nolint
+func (r ReceivedStepHashes) dropAncient(step uint64) {
+ for i := range r {
+ if i < step {
+ delete(r, i)
+ }
+ }
+}
+
+// nolint
+type EpochManager struct {
+ epochTransitionHash common.Hash // H256,
+ epochTransitionNumber uint64 // BlockNumber
+ finalityChecker *RollingFinality
+ force bool
+}
+
+func NewEpochManager() *EpochManager {
+ return &EpochManager{
+ finalityChecker: NewRollingFinality([]common.Address{}),
+ force: true,
+ }
+}
+
+func (e *EpochManager) noteNewEpoch() { e.force = true }
+
+// zoomValidators - Zooms to the epoch after the header with the given hash. Returns true if succeeded, false otherwise.
+// It's analog of zoom_to_after function in OE, but doesn't require external locking
+// nolint
+func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, er *NonTransactionalEpochReader, validators ValidatorSet, hash common.Hash, call Syscall) (*RollingFinality, uint64, bool) {
+ var lastWasParent bool
+ if e.finalityChecker.lastPushed != nil {
+ lastWasParent = *e.finalityChecker.lastPushed == hash
+ }
+
+ // early exit for current target == chain head, but only if the epochs are
+ // the same.
+ if lastWasParent && !e.force {
+ return e.finalityChecker, e.epochTransitionNumber, true
+ }
+ e.force = false
+
+ // epoch_transition_for can be an expensive call, but in the absence of
+ // forks it will only need to be called for the block directly after
+ // epoch transition, in which case it will be O(1) and require a single
+ // DB lookup.
+ lastTransition, ok := epochTransitionFor(chain, er, hash)
+ if !ok {
+ if lastTransition.BlockNumber > DEBUG_LOG_FROM {
+ fmt.Printf("zoom1: %d\n", lastTransition.BlockNumber)
+ }
+ return e.finalityChecker, e.epochTransitionNumber, false
+ }
+
+ // extract other epoch set if it's not the same as the last.
+ if lastTransition.BlockHash != e.epochTransitionHash {
+ proof := &EpochTransitionProof{}
+ if err := rlp.DecodeBytes(lastTransition.ProofRlp, proof); err != nil {
+ panic(err)
+ }
+ first := proof.SignalNumber == 0
+ if lastTransition.BlockNumber > DEBUG_LOG_FROM {
+ fmt.Printf("zoom2: %d,%d\n", lastTransition.BlockNumber, len(proof.SetProof))
+ }
+
+ // use signal number so multi-set first calculation is correct.
+ list, _, err := validators.epochSet(first, proof.SignalNumber, proof.SetProof, call)
+ if err != nil {
+ panic(fmt.Errorf("proof produced by this engine is invalid: %w", err))
+ }
+ epochSet := list.validators
+ log.Trace("[aura] Updating finality checker with new validator set extracted from epoch", "num", lastTransition.BlockNumber)
+ e.finalityChecker = NewRollingFinality(epochSet)
+ if proof.SignalNumber >= DEBUG_LOG_FROM {
+ fmt.Printf("new rolling finality: %d\n", proof.SignalNumber)
+ for i := 0; i < len(epochSet); i++ {
+ fmt.Printf("\t%x\n", epochSet[i])
+ }
+ }
+ }
+
+ e.epochTransitionHash = lastTransition.BlockHash
+ e.epochTransitionNumber = lastTransition.BlockNumber
+ return e.finalityChecker, e.epochTransitionNumber, true
+}
+
+// / Get the transition to the epoch the given parent hash is part of
+// / or transitions to.
+// / This will give the epoch that any children of this parent belong to.
+// /
+// / The block corresponding the the parent hash must be stored already.
+// nolint
+func epochTransitionFor(chain consensus.ChainHeaderReader, e *NonTransactionalEpochReader, parentHash common.Hash) (transition EpochTransition, ok bool) {
+ //TODO: probably this version of func doesn't support non-canonical epoch transitions
+ h := chain.GetHeaderByHash(parentHash)
+ if h == nil {
+ return transition, false
+ }
+ num, hash, transitionProof, err := e.FindBeforeOrEqualNumber(h.Number.Uint64())
+ if err != nil {
+ panic(err)
+ }
+ if transitionProof == nil {
+ panic("genesis epoch transition must already be set")
+ }
+ return EpochTransition{BlockNumber: num, BlockHash: hash, ProofRlp: transitionProof}, true
+}
+
+type Syscall func(common.Address, []byte) ([]byte, error)
+
+// AuRa
+// nolint
+type AuRa struct {
+ e *NonTransactionalEpochReader
+ exitCh chan struct{}
+ lock sync.RWMutex // Protects the signer fields
+
+ step PermissionedStep
+ // History of step hashes recently received from peers.
+ receivedStepHashes ReceivedStepHashes
+
+ cfg AuthorityRoundParams
+ EmptyStepsSet *EmptyStepSet
+ EpochManager *EpochManager // Mutex,
+
+ certifier *common.Address // certifies service transactions
+ certifierLock sync.RWMutex
+
+ Syscall Syscall
+}
+
+func SortedKeys[K constraints.Ordered, V any](m map[K]V) []K {
+ keys := make([]K, len(m))
+ i := 0
+ for k := range m {
+ keys[i] = k
+ i++
+ }
+ slices.Sort(keys)
+ return keys
+}
+
+func NewAuRa(spec *params.AuRaConfig, db ethdb.KeyValueStore) (*AuRa, error) {
+ auraParams, err := FromJson(spec)
+ if err != nil {
+ return nil, err
+ }
+
+ if _, ok := auraParams.StepDurations[0]; !ok {
+ return nil, fmt.Errorf("authority Round step 0 duration is undefined")
+ }
+ for _, v := range auraParams.StepDurations {
+ if v == 0 {
+ return nil, fmt.Errorf("authority Round step duration cannot be 0")
+ }
+ }
+ //shouldTimeout := auraParams.StartStep == nil
+ initialStep := uint64(0)
+ if auraParams.StartStep != nil {
+ initialStep = *auraParams.StartStep
+ }
+ durations := make([]StepDurationInfo, 0, 1+len(auraParams.StepDurations))
+ durInfo := StepDurationInfo{
+ TransitionStep: 0,
+ TransitionTimestamp: 0,
+ StepDuration: auraParams.StepDurations[0],
+ }
+ durations = append(durations, durInfo)
+ times := SortedKeys(auraParams.StepDurations)
+ for i := 1; i < len(auraParams.StepDurations); i++ { // skip first
+ time := times[i]
+ dur := auraParams.StepDurations[time]
+ step, t, ok := nextStepTimeDuration(durInfo, time)
+ if !ok {
+ return nil, fmt.Errorf("timestamp overflow")
+ }
+ durInfo.TransitionStep = step
+ durInfo.TransitionTimestamp = t
+ durInfo.StepDuration = dur
+ durations = append(durations, durInfo)
+ }
+ step := &Step{
+ calibrate: auraParams.StartStep == nil,
+ durations: durations,
+ }
+ step.inner.Store(initialStep)
+ step.doCalibrate()
+
+ /*
+ let engine = Arc::new(AuthorityRound {
+ epoch_manager: Mutex::new(EpochManager::blank()),
+ received_step_hashes: RwLock::new(Default::default()),
+ gas_limit_override_cache: Mutex::new(LruCache::new(GAS_LIMIT_OVERRIDE_CACHE_CAPACITY)),
+ })
+ // Do not initialize timeouts for tests.
+ if should_timeout {
+ let handler = TransitionHandler {
+ step: engine.step.clone(),
+ client: engine.client.clone(),
+ };
+ engine
+ .transition_service
+ .register_handler(Arc::new(handler))?;
+ }
+ */
+
+ exitCh := make(chan struct{})
+
+ c := &AuRa{
+ e: newEpochReader(db),
+ exitCh: exitCh,
+ step: PermissionedStep{inner: step},
+ cfg: auraParams,
+ receivedStepHashes: ReceivedStepHashes{},
+ EpochManager: NewEpochManager(),
+ }
+ c.step.canPropose.Store(true)
+
+ return c, nil
+}
+
+type epochReader interface {
+ GetEpoch(blockHash common.Hash, blockN uint64) (transitionProof []byte, err error)
+ GetPendingEpoch(blockHash common.Hash, blockN uint64) (transitionProof []byte, err error)
+ FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash common.Hash, transitionProof []byte, err error)
+}
+type epochWriter interface {
+ epochReader
+ PutEpoch(blockHash common.Hash, blockN uint64, transitionProof []byte) (err error)
+ PutPendingEpoch(blockHash common.Hash, blockN uint64, transitionProof []byte) (err error)
+}
+
+type NonTransactionalEpochReader struct {
+ db ethdb.KeyValueStore
+}
+
+func newEpochReader(db ethdb.KeyValueStore) *NonTransactionalEpochReader {
+ return &NonTransactionalEpochReader{db: db}
+}
+
+func (cr *NonTransactionalEpochReader) GetEpoch(hash common.Hash, number uint64) (v []byte, err error) {
+ return rawdb.ReadEpoch(cr.db, number, hash)
+}
+func (cr *NonTransactionalEpochReader) PutEpoch(hash common.Hash, number uint64, proof []byte) error {
+ return rawdb.WriteEpoch(cr.db, number, hash, proof)
+}
+func (cr *NonTransactionalEpochReader) GetPendingEpoch(hash common.Hash, number uint64) (v []byte, err error) {
+ return rawdb.ReadPendingEpoch(cr.db, number, hash)
+}
+func (cr *NonTransactionalEpochReader) PutPendingEpoch(hash common.Hash, number uint64, proof []byte) error {
+ return rawdb.WritePendingEpoch(cr.db, number, hash, proof)
+}
+func (cr *NonTransactionalEpochReader) FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash common.Hash, transitionProof []byte, err error) {
+ return rawdb.FindEpochBeforeOrEqualNumber(cr.db, number)
+}
+
+// A helper accumulator function mapping a step duration and a step duration transition timestamp
+// to the corresponding step number and the correct starting second of the step.
+func nextStepTimeDuration(info StepDurationInfo, time uint64) (uint64, uint64, bool) {
+ stepDiff := time + info.StepDuration
+ if stepDiff < 1 {
+ return 0, 0, false
+ }
+ stepDiff -= 1
+ if stepDiff < info.TransitionTimestamp {
+ return 0, 0, false
+ }
+ stepDiff -= info.TransitionTimestamp
+ if info.StepDuration == 0 {
+ return 0, 0, false
+ }
+ stepDiff /= info.StepDuration
+ timeDiff := stepDiff * info.StepDuration
+ return info.TransitionStep + stepDiff, info.TransitionTimestamp + timeDiff, true
+}
+
+// Type returns underlying consensus engine
+// func (c *AuRa) Type() chain.ConsensusName {
+// return chain.AuRaConsensus
+// }
+
+// Author implements consensus.Engine, returning the Ethereum address recovered
+// from the signature in the header's extra-data section.
+// This is thread-safe (only access the Coinbase of the header)
+func (c *AuRa) Author(header *types.Header) (common.Address, error) {
+ /*
+ let message = keccak(empty_step_rlp(self.step, &self.parent_hash));
+ let public = publickey::recover(&self.signature.into(), &message)?;
+ Ok(publickey::public_to_address(&public))
+ */
+ return header.Coinbase, nil
+}
+
+// VerifyHeader checks whether a header conforms to the consensus rules.
+func (c *AuRa) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header) error {
+ // Ensure that the header's extra-data section is of a reasonable size
+ if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
+ return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize)
+ }
+ // Verify the header's timestamp
+ unixNow := time.Now().Unix()
+ if header.Time > uint64(unixNow+allowedFutureBlockTimeSeconds) {
+ return consensus.ErrFutureBlock
+ }
+ // Verify that the gas limit is <= 2^63-1
+ if header.GasLimit > params.MaxGasLimit {
+ return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, params.MaxGasLimit)
+ }
+ // Verify that the gasUsed is <= gasLimit
+ if header.GasUsed > header.GasLimit {
+ return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
+ }
+ // Verify the block's gas usage and (if applicable) verify the base fee.
+
+ // Verify that the block number is parent's +1
+
+ // Verify the non-existence of withdrawalsHash.
+ if header.WithdrawalsHash != nil {
+ return fmt.Errorf("invalid withdrawalsHash: have %x, expected nil", header.WithdrawalsHash)
+ }
+
+ // Verify the non-existence of cancun-specific header fields
+ switch {
+ case header.ExcessBlobGas != nil:
+ return fmt.Errorf("invalid excessBlobGas: have %d, expected nil", header.ExcessBlobGas)
+ case header.BlobGasUsed != nil:
+ return fmt.Errorf("invalid blobGasUsed: have %d, expected nil", header.BlobGasUsed)
+ case header.ParentBeaconRoot != nil:
+ return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", header.ParentBeaconRoot)
+ }
+
+ // If all checks passed, validate any special fields for hard forks
+ if err := misc.VerifyDAOHeaderExtraData(chain.Config(), header); err != nil {
+ return err
+ }
+ return nil
+
+}
+
+func (c *AuRa) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) (chan<- struct{}, <-chan error) {
+ abort := make(chan struct{})
+ results := make(chan error, len(headers))
+
+ go func() {
+ for _, header := range headers {
+ err := c.VerifyHeader(chain, header)
+
+ select {
+ case <-abort:
+ return
+ case results <- err:
+ }
+ }
+ }()
+ return abort, results
+}
+
+// nolint
+func (c *AuRa) hasReceivedStepHashes(step uint64, author common.Address, newHash common.Hash) bool {
+ /*
+ self
+ .received_step_hashes
+ .read()
+ .get(&received_step_key)
+ .map_or(false, |h| *h != new_hash)
+ */
+ return false
+}
+
+// nolint
+func (c *AuRa) insertReceivedStepHashes(step uint64, author common.Address, newHash common.Hash) {
+ /*
+ self.received_step_hashes
+ .write()
+ .insert(received_step_key, new_hash);
+ */
+}
+
+// VerifyUncles implements consensus.Engine, always returning an error for any
+// uncles as this consensus mechanism doesn't permit uncles.
+func (c *AuRa) VerifyUncles(chain consensus.ChainReader, header *types.Block) error {
+ return nil
+ //if len(uncles) > 0 {
+ // return errors.New("uncles not allowed")
+ //}
+ //return nil
+}
+
+// VerifySeal implements consensus.Engine, checking whether the signature contained
+// in the header satisfies the consensus protocol requirements.
+// func (c *AuRa) VerifySeal(chain consensus.ChainHeaderReader, header *types.Header) error {
+// return nil
+//snap, err := c.Snapshot(chain, header.Number.Uint64(), header.Hash(), nil)
+//if err != nil {
+// return err
+//}
+//return c.verifySeal(chain, header, snap)
+// }
+
+// Prepare implements consensus.Engine, preparing all the consensus fields of the
+// header for running the transactions on top.
+func (c *AuRa) Prepare(chain consensus.ChainHeaderReader, header *types.Header, statedb *state.StateDB) error {
+ // return nil
+ /// If the block isn't a checkpoint, cast a random vote (good enough for now)
+ //header.Coinbase = common.Address{}
+ //header.Nonce = types.BlockNonce{}
+ //
+ //number := header.Number.Uint64()
+ /// Assemble the voting snapshot to check which votes make sense
+ //snap, err := c.Snapshot(chain, number-1, header.ParentHash, nil)
+ //if err != nil {
+ // return err
+ //}
+ //if number%c.config.Epoch != 0 {
+ // c.lock.RLock()
+ //
+ // // Gather all the proposals that make sense voting on
+ // addresses := make([]common.Address, 0, len(c.proposals))
+ // for address, authorize := range c.proposals {
+ // if snap.validVote(address, authorize) {
+ // addresses = append(addresses, address)
+ // }
+ // }
+ // // If there's pending proposals, cast a vote on them
+ // if len(addresses) > 0 {
+ // header.Coinbase = addresses[rand.Intn(len(addresses))]
+ // if c.proposals[header.Coinbase] {
+ // copy(header.Nonce[:], NonceAuthVote)
+ // } else {
+ // copy(header.Nonce[:], nonceDropVote)
+ // }
+ // }
+ // c.lock.RUnlock()
+ //}
+ /// Set the correct difficulty
+ //header.Difficulty = calcDifficulty(snap, c.signer)
+ //
+ /// Ensure the extra data has all its components
+ //if len(header.Extra) < ExtraVanity {
+ // header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, ExtraVanity-len(header.Extra))...)
+ //}
+ //header.Extra = header.Extra[:ExtraVanity]
+ //
+ //if number%c.config.Epoch == 0 {
+ // for _, signer := range snap.GetSigners() {
+ // header.Extra = append(header.Extra, signer[:]...)
+ // }
+ //}
+ //header.Extra = append(header.Extra, make([]byte, ExtraSeal)...)
+ //
+ /// Mix digest is reserved for now, set to empty
+ //header.MixDigest = common.Hash{}
+ //
+ /// Ensure the timestamp has the correct delay
+ //parent := chain.GetHeader(header.ParentHash, number-1)
+ //if parent == nil {
+ // return consensus.ErrUnknownAncestor
+ //}
+ //header.Time = parent.Time + c.config.Period
+ //
+ //now := uint64(time.Now().Unix())
+ //if header.Time < now {
+ // header.Time = now
+ //}
+ //
+ //return nil
+ // }
+
+ c.verifyGasLimitOverride(chain.Config(), chain, header, statedb, c.Syscall)
+
+ // func (c *AuRa) Initialize(config *params.ChainConfig, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) {
+ blockNum := header.Number.Uint64()
+ for address, rewrittenCode := range c.cfg.RewriteBytecode[blockNum] {
+ statedb.SetCode(address, rewrittenCode)
+ }
+
+ c.certifierLock.Lock()
+ if c.cfg.Registrar != nil && c.certifier == nil && chain.Config().IsLondon(header.Number) {
+ c.certifier = getCertifier(*c.cfg.Registrar, c.Syscall)
+ }
+ c.certifierLock.Unlock()
+
+ if blockNum == 1 {
+ proof, err := c.GenesisEpochData(header)
+ if err != nil {
+ panic(err)
+ }
+ err = c.e.PutEpoch(header.ParentHash, 0, proof) //TODO: block 0 hardcoded - need fix it inside validators
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ //if err := c.verifyFamily(chain, e, header, call, syscall); err != nil { //TODO: OE has it as a separate engine call? why?
+ // panic(err)
+ //}
+
+ // check_and_lock_block -> check_epoch_end_signal
+
+ epoch, err := c.e.GetEpoch(header.ParentHash, blockNum-1)
+ if err != nil {
+ return err
+ }
+ isEpochBegin := epoch != nil
+ if !isEpochBegin {
+ return nil
+ }
+ return c.cfg.Validators.onEpochBegin(isEpochBegin, header, c.Syscall)
+ // check_and_lock_block -> check_epoch_end_signal END (before enact)
+
+}
+
+func (c *AuRa) ApplyRewards(header *types.Header, state *state.StateDB) error {
+ rewards, err := c.CalculateRewards(nil, header, nil)
+ if err != nil {
+ return err
+ }
+ for _, r := range rewards {
+ state.AddBalance(r.Beneficiary, &r.Amount)
+ }
+ return nil
+}
+
+// word `signal epoch` == word `pending epoch`
+func (c *AuRa) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal, receipts []*types.Receipt) {
+ if err := c.ApplyRewards(header, state); err != nil {
+ panic(err)
+ }
+
+ // check_and_lock_block -> check_epoch_end_signal (after enact)
+ if header.Number.Uint64() >= DEBUG_LOG_FROM {
+ fmt.Printf("finalize1: %d,%d\n", header.Number.Uint64(), len(receipts))
+ }
+ pendingTransitionProof, err := c.cfg.Validators.signalEpochEnd(header.Number.Uint64() == 0, header, receipts)
+ if err != nil {
+ panic(err)
+ }
+ if pendingTransitionProof != nil {
+ if header.Number.Uint64() >= DEBUG_LOG_FROM {
+ fmt.Printf("insert_pending_transition: %d,receipts=%d, lenProof=%d\n", header.Number.Uint64(), len(receipts), len(pendingTransitionProof))
+ }
+ if err = c.e.PutPendingEpoch(header.Hash(), header.Number.Uint64(), pendingTransitionProof); err != nil {
+ panic(err)
+ }
+ }
+ // check_and_lock_block -> check_epoch_end_signal END
+
+ finalized := buildFinality(c.EpochManager, chain, c.e, c.cfg.Validators, header, c.Syscall)
+ c.EpochManager.finalityChecker.print(header.Number.Uint64())
+ epochEndProof, err := isEpochEnd(chain, c.e, finalized, header)
+ if err != nil {
+ panic(err)
+ }
+ if epochEndProof != nil {
+ c.EpochManager.noteNewEpoch()
+ log.Info("[aura] epoch transition", "block_num", header.Number.Uint64())
+ if err := c.e.PutEpoch(header.Hash(), header.Number.Uint64(), epochEndProof); err != nil {
+ panic(err)
+ }
+ }
+}
+
+func buildFinality(e *EpochManager, chain consensus.ChainHeaderReader, er *NonTransactionalEpochReader, validators ValidatorSet, header *types.Header, syscall Syscall) []unAssembledHeader {
+ // commit_block -> aura.build_finality
+ _, _, ok := e.zoomToAfter(chain, er, validators, header.ParentHash, syscall)
+ if !ok {
+ return []unAssembledHeader{}
+ }
+ if e.finalityChecker.lastPushed == nil || *e.finalityChecker.lastPushed != header.ParentHash {
+ if err := e.finalityChecker.buildAncestrySubChain(func(hash common.Hash) ([]common.Address, common.Hash, common.Hash, uint64, bool) {
+ h := chain.GetHeaderByHash(hash)
+ if h == nil {
+ return nil, common.Hash{}, common.Hash{}, 0, false
+ }
+ return []common.Address{h.Coinbase}, h.Hash(), h.ParentHash, h.Number.Uint64(), true
+ }, header.ParentHash, e.epochTransitionHash); err != nil {
+ //log.Warn("[aura] buildAncestrySubChain", "err", err)
+ return []unAssembledHeader{}
+ }
+ }
+
+ res, err := e.finalityChecker.push(header.Hash(), header.Number.Uint64(), []common.Address{header.Coinbase})
+ if err != nil {
+ //log.Warn("[aura] finalityChecker.push", "err", err)
+ return []unAssembledHeader{}
+ }
+ return res
+}
+
+func isEpochEnd(chain consensus.ChainHeaderReader, e *NonTransactionalEpochReader, finalized []unAssembledHeader, header *types.Header) ([]byte, error) {
+ // commit_block -> aura.is_epoch_end
+ for i := range finalized {
+ pendingTransitionProof, err := e.GetPendingEpoch(finalized[i].hash, finalized[i].number)
+ // GNOSIS: pebble returns an error when a non-existent value
+ // isn't found, which is what happens at genesis.
+ if err != nil && !errors.Is(err, pebble.ErrNotFound) {
+ return nil, err
+ }
+ if pendingTransitionProof == nil {
+ continue
+ }
+ if header.Number.Uint64() >= DEBUG_LOG_FROM {
+ fmt.Printf("pending transition: %d,%x,len=%d\n", finalized[i].number, finalized[i].hash, len(pendingTransitionProof))
+ }
+
+ finalityProof := allHeadersUntil(chain, header, finalized[i].hash)
+ var finalizedHeader *types.Header
+ if finalized[i].hash == header.Hash() {
+ finalizedHeader = header
+ } else {
+ finalizedHeader = chain.GetHeader(finalized[i].hash, finalized[i].number)
+ }
+ signalNumber := finalizedHeader.Number
+ finalityProof = append(finalityProof, finalizedHeader)
+ for i, j := 0, len(finalityProof)-1; i < j; i, j = i+1, j-1 { // reverse
+ finalityProof[i], finalityProof[j] = finalityProof[j], finalityProof[i]
+ }
+ finalityProofRLP, err := rlp.EncodeToBytes(finalityProof)
+ if err != nil {
+ return nil, err
+ }
+ /*
+ // We turn off can_propose here because upon validator set change there can
+ // be two valid proposers for a single step: one from the old set and
+ // one from the new.
+ //
+ // This way, upon encountering an epoch change, the proposer from the
+ // new set will be forced to wait until the next step to avoid sealing a
+ // block that breaks the invariant that the parent's step < the block's step.
+ self.step.can_propose.store(false, AtomicOrdering::SeqCst);
+ */
+ return rlp.EncodeToBytes(EpochTransitionProof{SignalNumber: signalNumber.Uint64(), SetProof: pendingTransitionProof, FinalityProof: finalityProofRLP})
+ }
+ return nil, nil
+}
+
+// allHeadersUntil walk the chain backwards from current head until finalized_hash
+// to construct transition proof. author == ec_recover(sig) known
+// since the blocks are in the DB.
+func allHeadersUntil(chain consensus.ChainHeaderReader, from *types.Header, to common.Hash) (out []*types.Header) {
+ var header = from
+ for {
+ header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
+ if header == nil {
+ panic("not found header")
+ }
+ if header.Number.Uint64() == 0 {
+ break
+ }
+ if to == header.Hash() {
+ break
+ }
+ out = append(out, header)
+ }
+ return out
+}
+
+//func (c *AuRa) check_epoch_end(cc *params.ChainConfig, header *types.Header, state *state.StateDB, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) {
+//}
+
+// FinalizeAndAssemble implements consensus.Engine
+func (c *AuRa) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) {
+ c.Finalize(chain, header, state, txs, uncles, withdrawals, receipts)
+
+ // Assemble and return the final block for sealing
+ return types.NewBlockWithWithdrawals(header, txs, uncles, receipts, withdrawals, trie.NewStackTrie(nil)), nil
+}
+
+// Authorize injects a private key into the consensus engine to mint new blocks
+// with.
+func (c *AuRa) Authorize(signer common.Address, signFn clique.SignerFn) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ //c.signer = signer
+ //c.signFn = signFn
+}
+
+func (c *AuRa) GenesisEpochData(header *types.Header) ([]byte, error) {
+ setProof, err := c.cfg.Validators.genesisEpochData(header, c.Syscall)
+ if err != nil {
+ return nil, err
+ }
+ res, err := rlp.EncodeToBytes(EpochTransitionProof{SignalNumber: 0, SetProof: setProof, FinalityProof: []byte{}})
+ if err != nil {
+ panic(err)
+ }
+ //fmt.Printf("reere: %x\n", res)
+ //f91a84f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f91871b914c26060604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303aca79214610101578063108552691461016457806340a141ff1461019d57806340c9cdeb146101d65780634110a489146101ff57806345199e0a1461025757806349285b58146102c15780634d238c8e14610316578063752862111461034f578063900eb5a8146103645780639a573786146103c7578063a26a47d21461041c578063ae4b1b5b14610449578063b3f05b971461049e578063b7ab4db5146104cb578063d3e848f114610535578063fa81b2001461058a578063facd743b146105df575b600080fd5b341561010c57600080fd5b6101226004808035906020019091905050610630565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016f57600080fd5b61019b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b005b34156101a857600080fd5b6101d4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610807565b005b34156101e157600080fd5b6101e9610bb7565b6040518082815260200191505060405180910390f35b341561020a57600080fd5b610236600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bbd565b60405180831515151581526020018281526020019250505060405180910390f35b341561026257600080fd5b61026a610bee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ad578082015181840152602081019050610292565b505050509050019250505060405180910390f35b34156102cc57600080fd5b6102d4610c82565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032157600080fd5b61034d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d32565b005b341561035a57600080fd5b610362610fcc565b005b341561036f57600080fd5b61038560048080359060200190919050506110fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103d257600080fd5b6103da61113b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561042757600080fd5b61042f6111eb565b604051808215151515815260200191505060405180910390f35b341561045457600080fd5b61045c6111fe565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a957600080fd5b6104b1611224565b604051808215151515815260200191505060405180910390f35b34156104d657600080fd5b6104de611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610521578082015181840152602081019050610506565b505050509050019250505060405180910390f35b341561054057600080fd5b6105486112cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059557600080fd5b61059d6112f1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105ea57600080fd5b610616600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611317565b604051808215151515815260200191505060405180910390f35b60078181548110151561063f57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106cb57600080fd5b600460019054906101000a900460ff161515156106e757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561072357600080fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460016101000a81548160ff0219169083151502179055507f600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600061081461113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561084d57600080fd5b83600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615156108a957600080fd5b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549350600160078054905003925060078381548110151561090857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508160078581548110151561094657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506007838154811015156109e557fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600780549050111515610a2757600080fd5b6007805480919060019003610a3c9190611370565b506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610ba257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b58575b50509250505060405180910390a25050505050565b60085481565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b610bf661139c565b6007805480602002602001604051908101604052809291908181526020018280548015610c7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c2e575b5050505050905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349285b586000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610d1257600080fd5b6102c65a03f11515610d2357600080fd5b50505060405180519050905090565b610d3a61113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b80600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151515610dd057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e0c57600080fd5b6040805190810160405280600115158152602001600780549050815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015590505060078054806001018281610ea991906113b0565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610fba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610f70575b50509250505060405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156110365750600460009054906101000a900460ff16155b151561104157600080fd5b6001600460006101000a81548160ff0219169083151502179055506007600690805461106e9291906113dc565b506006805490506008819055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536110a4611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156110e75780820151818401526020810190506110cc565b505050509050019250505060405180910390a1565b60068181548110151561110b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639a5737866000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156111cb57600080fd5b6102c65a03f115156111dc57600080fd5b50505060405180519050905090565b600460019054906101000a900460ff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900460ff1681565b61123f61139c565b60068054806020026020016040519081016040528092919081815260200182805480156112c157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611277575b5050505050905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b81548183558181151161139757818360005260206000209182019101611396919061142e565b5b505050565b602060405190810160405280600081525090565b8154818355818115116113d7578183600052602060002091820191016113d6919061142e565b5b505050565b82805482825590600052602060002090810192821561141d5760005260206000209182015b8281111561141c578254825591600101919060010190611401565b5b50905061142a9190611453565b5090565b61145091905b8082111561144c576000816000905550600101611434565b5090565b90565b61149391905b8082111561148f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101611459565b5090565b905600a165627a7a7230582036ea35935c8246b68074adece2eab70c40e69a0193c08a6277ce06e5b25188510029b8f3f8f1a08023c0d95fc2364e0bf7593f5ff32e1db8ef9f4b41c0bd474eae62d1af896e99808080a0b47b4f0b3e73b5edc8f9a9da1cbcfed562eb06bf54619b6aefeadebf5b3604c280a0da6ec08940a924cb08c947dd56cdb40076b29a6f0ea4dba4e2d02d9a9a72431b80a030cc4138c9e74b6cf79d624b4b5612c0fd888e91f55316cfee7d1694e1a90c0b80a0c5d54b915b56a888eee4e6eeb3141e778f9b674d1d322962eed900f02c29990aa017256b36ef47f907c6b1378a2636942ce894c17075e56fc054d4283f6846659e808080a03340bbaeafcda3a8672eb83099231dbbfab8dae02a1e8ec2f7180538fac207e080b86bf869a033aa5d69545785694b808840be50c182dad2ec3636dfccbe6572fb69828742c0b846f8440101a0663ce0d171e545a26aa67e4ca66f72ba96bb48287dbcc03beea282867f80d44ba01f0e7726926cb43c03a0abf48197dba78522ec8ba1b158e2aa30da7d2a2c6f9eb838f7a03868bdfa8727775661e4ccf117824a175a33f8703d728c04488fbfffcafda9f99594e8ddc5c7a2d2f0d7a9798459c0104fdf5e987acaa3e2a02052222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01b853f851808080a07bb75cabebdcbd1dbb4331054636d0c6d7a2b08483b9e04df057395a7434c9e080808080808080a0e61e567237b49c44d8f906ceea49027260b4010c10a547b38d8b131b9d3b6f848080808080b8d3f8d1a0dc277c93a9f9dcee99aac9b8ba3cfa4c51821998522469c37715644e8fbac0bfa0ab8cdb808c8303bb61fb48e276217be9770fa83ecf3f90f2234d558885f5abf1808080a0fe137c3a474fbde41d89a59dd76da4c55bf696b86d3af64a55632f76cf30786780808080a06301b39b2ea8a44df8b0356120db64b788e71f52e1d7a6309d0d2e5b86fee7cb80a0da5d8b08dea0c5a4799c0f44d8a24d7cdf209f9b7a5588c1ecafb5361f6b9f07a01b7779e149cadf24d4ffb77ca7e11314b8db7097e4d70b2a173493153ca2e5a0808080b853f851808080a0a87d9bb950836582673aa0eecc0ff64aac607870637a2dd2012b8b1b31981f698080a08da6d5c36a404670c553a2c9052df7cd604f04e3863c4c7b9e0027bfd54206d680808080808080808080b86bf869a02080c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312ab846f8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
+ //f91a8c80b91a87f91a84f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f91871b914c26060604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303aca79214610101578063108552691461016457806340a141ff1461019d57806340c9cdeb146101d65780634110a489146101ff57806345199e0a1461025757806349285b58146102c15780634d238c8e14610316578063752862111461034f578063900eb5a8146103645780639a573786146103c7578063a26a47d21461041c578063ae4b1b5b14610449578063b3f05b971461049e578063b7ab4db5146104cb578063d3e848f114610535578063fa81b2001461058a578063facd743b146105df575b600080fd5b341561010c57600080fd5b6101226004808035906020019091905050610630565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016f57600080fd5b61019b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b005b34156101a857600080fd5b6101d4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610807565b005b34156101e157600080fd5b6101e9610bb7565b6040518082815260200191505060405180910390f35b341561020a57600080fd5b610236600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bbd565b60405180831515151581526020018281526020019250505060405180910390f35b341561026257600080fd5b61026a610bee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ad578082015181840152602081019050610292565b505050509050019250505060405180910390f35b34156102cc57600080fd5b6102d4610c82565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032157600080fd5b61034d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d32565b005b341561035a57600080fd5b610362610fcc565b005b341561036f57600080fd5b61038560048080359060200190919050506110fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103d257600080fd5b6103da61113b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561042757600080fd5b61042f6111eb565b604051808215151515815260200191505060405180910390f35b341561045457600080fd5b61045c6111fe565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a957600080fd5b6104b1611224565b604051808215151515815260200191505060405180910390f35b34156104d657600080fd5b6104de611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610521578082015181840152602081019050610506565b505050509050019250505060405180910390f35b341561054057600080fd5b6105486112cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059557600080fd5b61059d6112f1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105ea57600080fd5b610616600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611317565b604051808215151515815260200191505060405180910390f35b60078181548110151561063f57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106cb57600080fd5b600460019054906101000a900460ff161515156106e757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561072357600080fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460016101000a81548160ff0219169083151502179055507f600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600061081461113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561084d57600080fd5b83600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615156108a957600080fd5b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549350600160078054905003925060078381548110151561090857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508160078581548110151561094657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506007838154811015156109e557fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600780549050111515610a2757600080fd5b6007805480919060019003610a3c9190611370565b506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610ba257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b58575b50509250505060405180910390a25050505050565b60085481565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b610bf661139c565b6007805480602002602001604051908101604052809291908181526020018280548015610c7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c2e575b5050505050905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349285b586000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610d1257600080fd5b6102c65a03f11515610d2357600080fd5b50505060405180519050905090565b610d3a61113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b80600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151515610dd057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e0c57600080fd5b6040805190810160405280600115158152602001600780549050815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015590505060078054806001018281610ea991906113b0565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610fba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610f70575b50509250505060405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156110365750600460009054906101000a900460ff16155b151561104157600080fd5b6001600460006101000a81548160ff0219169083151502179055506007600690805461106e9291906113dc565b506006805490506008819055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536110a4611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156110e75780820151818401526020810190506110cc565b505050509050019250505060405180910390a1565b60068181548110151561110b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639a5737866000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156111cb57600080fd5b6102c65a03f115156111dc57600080fd5b50505060405180519050905090565b600460019054906101000a900460ff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900460ff1681565b61123f61139c565b60068054806020026020016040519081016040528092919081815260200182805480156112c157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611277575b5050505050905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b81548183558181151161139757818360005260206000209182019101611396919061142e565b5b505050565b602060405190810160405280600081525090565b8154818355818115116113d7578183600052602060002091820191016113d6919061142e565b5b505050565b82805482825590600052602060002090810192821561141d5760005260206000209182015b8281111561141c578254825591600101919060010190611401565b5b50905061142a9190611453565b5090565b61145091905b8082111561144c576000816000905550600101611434565b5090565b90565b61149391905b8082111561148f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101611459565b5090565b905600a165627a7a7230582036ea35935c8246b68074adece2eab70c40e69a0193c08a6277ce06e5b25188510029b8f3f8f1a08023c0d95fc2364e0bf7593f5ff32e1db8ef9f4b41c0bd474eae62d1af896e99808080a0b47b4f0b3e73b5edc8f9a9da1cbcfed562eb06bf54619b6aefeadebf5b3604c280a0da6ec08940a924cb08c947dd56cdb40076b29a6f0ea4dba4e2d02d9a9a72431b80a030cc4138c9e74b6cf79d624b4b5612c0fd888e91f55316cfee7d1694e1a90c0b80a0c5d54b915b56a888eee4e6eeb3141e778f9b674d1d322962eed900f02c29990aa017256b36ef47f907c6b1378a2636942ce894c17075e56fc054d4283f6846659e808080a03340bbaeafcda3a8672eb83099231dbbfab8dae02a1e8ec2f7180538fac207e080b86bf869a033aa5d69545785694b808840be50c182dad2ec3636dfccbe6572fb69828742c0b846f8440101a0663ce0d171e545a26aa67e4ca66f72ba96bb48287dbcc03beea282867f80d44ba01f0e7726926cb43c03a0abf48197dba78522ec8ba1b158e2aa30da7d2a2c6f9eb838f7a03868bdfa8727775661e4ccf117824a175a33f8703d728c04488fbfffcafda9f99594e8ddc5c7a2d2f0d7a9798459c0104fdf5e987acaa3e2a02052222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01b853f851808080a07bb75cabebdcbd1dbb4331054636d0c6d7a2b08483b9e04df057395a7434c9e080808080808080a0e61e567237b49c44d8f906ceea49027260b4010c10a547b38d8b131b9d3b6f848080808080b8d3f8d1a0dc277c93a9f9dcee99aac9b8ba3cfa4c51821998522469c37715644e8fbac0bfa0ab8cdb808c8303bb61fb48e276217be9770fa83ecf3f90f2234d558885f5abf1808080a0fe137c3a474fbde41d89a59dd76da4c55bf696b86d3af64a55632f76cf30786780808080a06301b39b2ea8a44df8b0356120db64b788e71f52e1d7a6309d0d2e5b86fee7cb80a0da5d8b08dea0c5a4799c0f44d8a24d7cdf209f9b7a5588c1ecafb5361f6b9f07a01b7779e149cadf24d4ffb77ca7e11314b8db7097e4d70b2a173493153ca2e5a0808080b853f851808080a0a87d9bb950836582673aa0eecc0ff64aac607870637a2dd2012b8b1b31981f698080a08da6d5c36a404670c553a2c9052df7cd604f04e3863c4c7b9e0027bfd54206d680808080808080808080b86bf869a02080c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312ab846f8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47080
+ return res, nil
+}
+
+func (c *AuRa) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
+ return nil
+ //header := block.Header()
+ //
+ /// Sealing the genesis block is not supported
+ //number := header.Number.Uint64()
+ //if number == 0 {
+ // return errUnknownBlock
+ //}
+ /// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
+ //if c.config.Period == 0 && len(block.Transactions()) == 0 {
+ // log.Info("Sealing paused, waiting for transactions")
+ // return nil
+ //}
+ /// Don't hold the signer fields for the entire sealing procedure
+ //c.lock.RLock()
+ //signer, signFn := c.signer, c.signFn
+ //c.lock.RUnlock()
+ //
+ /// Bail out if we're unauthorized to sign a block
+ //snap, err := c.Snapshot(chain, number-1, header.ParentHash, nil)
+ //if err != nil {
+ // return err
+ //}
+ //if _, authorized := snap.Signers[signer]; !authorized {
+ // return ErrUnauthorizedSigner
+ //}
+ /// If we're amongst the recent signers, wait for the next block
+ //for seen, recent := range snap.Recents {
+ // if recent == signer {
+ // // Signer is among RecentsRLP, only wait if the current block doesn't shift it out
+ // if limit := uint64(len(snap.Signers)/2 + 1); number < limit || seen > number-limit {
+ // log.Info("Signed recently, must wait for others")
+ // return nil
+ // }
+ // }
+ //}
+ /// Sweet, the protocol permits us to sign the block, wait for our time
+ //delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple
+ //if header.Difficulty.Cmp(diffNoTurn) == 0 {
+ // // It's not our turn explicitly to sign, delay it a bit
+ // wiggle := time.Duration(len(snap.Signers)/2+1) * wiggleTime
+ // delay += time.Duration(rand.Int63n(int64(wiggle)))
+ //
+ // log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle))
+ //}
+ /// Sign all the things!
+ //sighash, err := signFn(signer, accounts.MimetypeClique, CliqueRLP(header))
+ //if err != nil {
+ // return err
+ //}
+ //copy(header.Extra[len(header.Extra)-ExtraSeal:], sighash)
+ /// Wait until sealing is terminated or delay timeout.
+ //log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay))
+ //go func() {
+ // select {
+ // case <-stop:
+ // return
+ // case <-time.After(delay):
+ // }
+ //
+ // select {
+ // case results <- block.WithSeal(header):
+ // default:
+ // log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header))
+ // }
+ //}()
+ //
+ //return nil
+}
+
+func (c *AuRa) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int {
+ currentStep := c.step.inner.inner.Load()
+ currentEmptyStepsLen := 0
+ return calculateScore(parent.Step, currentStep, uint64(currentEmptyStepsLen)).ToBig()
+
+ /* TODO: do I need gasLimit override logic here ?
+ if let Some(gas_limit) = self.gas_limit_override(header) {
+ trace!(target: "engine", "Setting gas limit to {} for block {}.", gas_limit, header.number());
+ let parent_gas_limit = *parent.gas_limit();
+ header.set_gas_limit(gas_limit);
+ if parent_gas_limit != gas_limit {
+ info!(target: "engine", "Block gas limit was changed from {} to {}.", parent_gas_limit, gas_limit);
+ }
+ }
+ */
+}
+
+// calculateScore - analog of PoW difficulty:
+//
+// sqrt(U256::max_value()) + parent_step - current_step + current_empty_steps
+func calculateScore(parentStep, currentStep, currentEmptySteps uint64) *uint256.Int {
+ maxU128 := uint256.NewInt(0).SetAllOne()
+ maxU128 = maxU128.Rsh(maxU128, 128)
+ res := maxU128.Add(maxU128, uint256.NewInt(parentStep))
+ res = res.Sub(res, uint256.NewInt(currentStep))
+ res = res.Add(res, uint256.NewInt(currentEmptySteps))
+ return res
+}
+
+func (c *AuRa) SealHash(header *types.Header) common.Hash {
+ return clique.SealHash(header)
+}
+
+// See https://openethereum.github.io/Permissioning.html#gas-price
+// This is thread-safe: it only accesses the `certifier` which is used behind a RWLock
+func (c *AuRa) IsServiceTransaction(sender common.Address) bool {
+ c.certifierLock.RLock()
+ defer c.certifierLock.RUnlock()
+ if c.certifier == nil {
+ return false
+ }
+ packed, err := certifierAbi().Pack("certified", sender)
+ if err != nil {
+ panic(err)
+ }
+ out, err := c.Syscall(*c.certifier, packed)
+ if err != nil {
+ panic(err)
+ }
+ res, err := certifierAbi().Unpack("certified", out)
+ if err != nil {
+ log.Warn("error while detecting service tx on AuRa", "err", err)
+ return false
+ }
+ if len(res) == 0 {
+ return false
+ }
+ if certified, ok := res[0].(bool); ok {
+ return certified
+ }
+ return false
+}
+
+func SafeClose(ch chan struct{}) {
+ if ch == nil {
+ return
+ }
+ select {
+ case <-ch:
+ // Channel was already closed
+ default:
+ close(ch)
+ }
+}
+
+// Close implements consensus.Engine. It's a noop for clique as there are no background threads.
+func (c *AuRa) Close() error {
+ SafeClose(c.exitCh)
+ return nil
+}
+
+// APIs implements consensus.Engine, returning the user facing RPC API to allow
+// controlling the signer voting.
+func (c *AuRa) APIs(chain consensus.ChainHeaderReader) []rpc.API {
+ return []rpc.API{
+ //{
+ //Namespace: "clique",
+ //Version: "1.0",
+ //Service: &API{chain: chain, clique: c},
+ //Public: false,
+ //}
+ }
+}
+
+// nolint
+func (c *AuRa) emptySteps(fromStep, toStep uint64, parentHash common.Hash) []EmptyStep {
+ from := EmptyStep{step: fromStep + 1, parentHash: parentHash}
+ to := EmptyStep{step: toStep}
+ res := []EmptyStep{}
+ if to.LessOrEqual(&from) {
+ return res
+ }
+
+ c.EmptyStepsSet.Sort()
+ c.EmptyStepsSet.ForEach(func(i int, step *EmptyStep) {
+ if step.Less(&from) || (&to).Less(step) {
+ return
+ }
+ if step.parentHash != parentHash {
+ return
+ }
+ res = append(res, *step)
+ })
+ return res
+}
+
+func (c *AuRa) CalculateRewards(_ *params.ChainConfig, header *types.Header, _ []*types.Header) ([]consensus.Reward, error) {
+ var rewardContractAddress BlockRewardContract
+ var foundContract bool
+ for _, c := range c.cfg.BlockRewardContractTransitions {
+ if c.blockNum > header.Number.Uint64() {
+ break
+ }
+ foundContract = true
+ rewardContractAddress = c
+ }
+ if foundContract {
+ beneficiaries := []common.Address{header.Coinbase}
+ rewardKind := []consensus.RewardKind{consensus.RewardAuthor}
+ var amounts []*big.Int
+ beneficiaries, amounts = callBlockRewardAbi(rewardContractAddress.address, c.Syscall, beneficiaries, rewardKind)
+ rewards := make([]consensus.Reward, len(amounts))
+ for i, amount := range amounts {
+ rewards[i].Beneficiary = beneficiaries[i]
+ rewards[i].Kind = consensus.RewardExternal
+ rewards[i].Amount = *amount
+ }
+ return rewards, nil
+ }
+
+ // block_reward.iter.rev().find(|&(block, _)| *block <= number)
+ var reward BlockReward
+ var found bool
+ for i := range c.cfg.BlockReward {
+ if c.cfg.BlockReward[i].blockNum > header.Number.Uint64() {
+ break
+ }
+ found = true
+ reward = c.cfg.BlockReward[i]
+ }
+ if !found {
+ return nil, errors.New("Current block's reward is not found; this indicates a chain config error")
+ }
+
+ r := consensus.Reward{Beneficiary: header.Coinbase, Kind: consensus.RewardAuthor, Amount: *reward.amount}
+ return []consensus.Reward{r}, nil
+}
+
+// See https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md
+func (c *AuRa) ExecuteSystemWithdrawals(withdrawals []*types.Withdrawal) error {
+ if c.cfg.WithdrawalContractAddress == nil {
+ return nil
+ }
+
+ maxFailedWithdrawalsToProcess := big.NewInt(4)
+ amounts := make([]uint64, 0, len(withdrawals))
+ addresses := make([]common.Address, 0, len(withdrawals))
+ for _, w := range withdrawals {
+ amounts = append(amounts, w.Amount)
+ addresses = append(addresses, w.Address)
+ }
+
+ packed, err := withdrawalAbi().Pack("executeSystemWithdrawals", maxFailedWithdrawalsToProcess, amounts, addresses)
+ if err != nil {
+ return err
+ }
+
+ _, err = c.Syscall(*c.cfg.WithdrawalContractAddress, packed)
+ if err != nil {
+ log.Warn("ExecuteSystemWithdrawals", "err", err)
+ }
+ return err
+}
+
+// An empty step message that is included in a seal, the only difference is that it doesn't include
+// the `parent_hash` in order to save space. The included signature is of the original empty step
+// message, which can be reconstructed by using the parent hash of the block in which this sealed
+// empty message is included.
+// nolint
+type SealedEmptyStep struct {
+ signature []byte // H520
+ step uint64
+}
+
+/*
+// extracts the empty steps from the header seal. should only be called when there are 3 fields in the seal
+// (i.e. header.number() >= self.empty_steps_transition).
+func headerEmptySteps(header *types.Header) ([]EmptyStep, error) {
+ s := headerEmptyStepsRaw(header)
+ sealedSteps := []SealedEmptyStep{}
+ err := rlp.DecodeBytes(s, &sealedSteps)
+ if err != nil {
+ return nil, err
+ }
+ steps := make([]EmptyStep, len(sealedSteps))
+ for i := range sealedSteps {
+ steps[i] = newEmptyStepFromSealed(sealedSteps[i], header.ParentHash)
+ }
+ return steps, nil
+}
+
+func newEmptyStepFromSealed(step SealedEmptyStep, parentHash common.Hash) EmptyStep {
+ return EmptyStep{
+ signature: step.signature,
+ step: step.step,
+ parentHash: parentHash,
+ }
+}
+
+// extracts the raw empty steps vec from the header seal. should only be called when there are 3 fields in the seal
+// (i.e. header.number() >= self.empty_steps_transition)
+func headerEmptyStepsRaw(header *types.Header) []byte {
+ if len(header.Seal) < 3 {
+ panic("was checked with verify_block_basic; has 3 fields; qed")
+ }
+ return header.Seal[2]
+}
+*/
+
+// A message broadcast by authorities when it's their turn to seal a block but there are no
+// transactions. Other authorities accumulate these messages and later include them in the seal as
+// proof.
+//
+// An empty step message is created _instead of_ a block if there are no pending transactions.
+// It cannot itself be a parent, and `parent_hash` always points to the most recent block. E.g.:
+// - Validator A creates block `bA`.
+// - Validator B has no pending transactions, so it signs an empty step message `mB`
+// instead whose hash points to block `bA`.
+// - Validator C also has no pending transactions, so it also signs an empty step message `mC`
+// instead whose hash points to block `bA`.
+// - Validator D creates block `bD`. The parent is block `bA`, and the header includes `mB` and `mC`.
+type EmptyStep struct {
+ // The signature of the other two fields, by the message's author.
+ signature []byte // H520
+ // This message's step number.
+ step uint64
+ // The hash of the most recent block.
+ parentHash common.Hash // H256
+}
+
+func (s *EmptyStep) Less(other *EmptyStep) bool {
+ if s.step < other.step {
+ return true
+ }
+ if bytes.Compare(s.parentHash[:], other.parentHash[:]) < 0 {
+ return true
+ }
+ if bytes.Compare(s.signature, other.signature) < 0 {
+ return true
+ }
+ return false
+}
+func (s *EmptyStep) LessOrEqual(other *EmptyStep) bool {
+ if s.step <= other.step {
+ return true
+ }
+ if bytes.Compare(s.parentHash[:], other.parentHash[:]) <= 0 {
+ return true
+ }
+ if bytes.Compare(s.signature, other.signature) <= 0 {
+ return true
+ }
+ return false
+}
+
+// Returns `true` if the message has a valid signature by the expected proposer in the message's step.
+func (s *EmptyStep) verify(validators ValidatorSet) (bool, error) { //nolint
+ //sRlp, err := EmptyStepRlp(s.step, s.parentHash)
+ //if err != nil {
+ // return false, err
+ //}
+ //message := crypto.Keccak256(sRlp)
+
+ /*
+ let correct_proposer = step_proposer(validators, &self.parent_hash, self.step);
+
+ publickey::verify_address(&correct_proposer, &self.signature.into(), &message)
+ .map_err(|e| e.into())
+ */
+ return true, nil
+}
+
+// nolint
+func (s *EmptyStep) author() (common.Address, error) {
+ sRlp, err := EmptyStepRlp(s.step, s.parentHash)
+ if err != nil {
+ return common.Address{}, err
+ }
+ message := crypto.Keccak256(sRlp)
+ public, err := crypto.SigToPub(message, s.signature)
+ // public, err := secp256k1.RecoverPubkey(message, s.signature)
+ if err != nil {
+ return common.Address{}, err
+ }
+ return crypto.PubkeyToAddress(*public), nil
+}
+
+type EmptyStepSet struct {
+ lock sync.Mutex
+ list []*EmptyStep
+}
+
+func (s *EmptyStepSet) Less(i, j int) bool { return s.list[i].Less(s.list[j]) }
+func (s *EmptyStepSet) Swap(i, j int) { s.list[i], s.list[j] = s.list[j], s.list[i] }
+func (s *EmptyStepSet) Len() int { return len(s.list) }
+
+func (s *EmptyStepSet) Sort() {
+ s.lock.Lock()
+ defer s.lock.Unlock()
+ sort.Stable(s)
+}
+
+func (s *EmptyStepSet) ForEach(f func(int, *EmptyStep)) {
+ s.lock.Lock()
+ defer s.lock.Unlock()
+ for i, el := range s.list {
+ f(i, el)
+ }
+}
+
+func EmptyStepFullRlp(signature []byte, emptyStepRlp []byte) ([]byte, error) {
+ type A struct {
+ s []byte
+ r []byte
+ }
+
+ return rlp.EncodeToBytes(A{s: signature, r: emptyStepRlp})
+}
+
+func EmptyStepRlp(step uint64, parentHash common.Hash) ([]byte, error) {
+ type A struct {
+ s uint64
+ h common.Hash
+ }
+ return rlp.EncodeToBytes(A{s: step, h: parentHash})
+}
+
+// nolint
+type unAssembledHeader struct {
+ hash common.Hash
+ number uint64
+ signers []common.Address
+}
+type unAssembledHeaders struct {
+ l *list.List
+}
+
+func (u unAssembledHeaders) PushBack(header *unAssembledHeader) { u.l.PushBack(header) }
+func (u unAssembledHeaders) PushFront(header *unAssembledHeader) { u.l.PushFront(header) }
+func (u unAssembledHeaders) Pop() *unAssembledHeader {
+ e := u.l.Front()
+ if e == nil {
+ return nil
+ }
+ u.l.Remove(e)
+ return e.Value.(*unAssembledHeader)
+}
+func (u unAssembledHeaders) Front() *unAssembledHeader {
+ e := u.l.Front()
+ if e == nil {
+ return nil
+ }
+ return e.Value.(*unAssembledHeader)
+}
+
+// RollingFinality checker for authority round consensus.
+// Stores a chain of unfinalized hashes that can be pushed onto.
+// nolint
+type RollingFinality struct {
+ headers unAssembledHeaders //nolint
+ signers *SimpleList
+ signCount map[common.Address]uint
+ lastPushed *common.Hash // Option,
+}
+
+// NewRollingFinality creates a blank finality checker under the given validator set.
+func NewRollingFinality(signers []common.Address) *RollingFinality {
+ return &RollingFinality{
+ signers: NewSimpleList(signers),
+ headers: unAssembledHeaders{l: list.New()},
+ signCount: map[common.Address]uint{},
+ }
+}
+
+// Clears the finality status, but keeps the validator set.
+func (f *RollingFinality) print(num uint64) {
+ if num > DEBUG_LOG_FROM {
+ h := f.headers
+ i := 0
+ for e := h.l.Front(); e != nil; e = e.Next() {
+ i++
+ a := e.Value.(*unAssembledHeader)
+ fmt.Printf("\t%d,%x\n", a.number, a.signers[0])
+ }
+ if i == 0 {
+ fmt.Printf("\tempty\n")
+ }
+ }
+}
+
+func (f *RollingFinality) clear() {
+ f.headers = unAssembledHeaders{l: list.New()}
+ f.signCount = map[common.Address]uint{}
+ f.lastPushed = nil
+}
+
+// Push a hash onto the rolling finality checker (implying `subchain_head` == head.parent)
+//
+// Fails if `signer` isn't a member of the active validator set.
+// Returns a list of all newly finalized headers.
+func (f *RollingFinality) push(head common.Hash, num uint64, signers []common.Address) (newlyFinalized []unAssembledHeader, err error) {
+ for i := range signers {
+ if !f.hasSigner(signers[i]) {
+ return nil, fmt.Errorf("unknown validator")
+ }
+ }
+
+ f.addSigners(signers)
+ f.headers.PushBack(&unAssembledHeader{hash: head, number: num, signers: signers})
+
+ for f.isFinalized() {
+ e := f.headers.Pop()
+ if e == nil {
+ panic("headers length always greater than sign count length")
+ }
+ f.removeSigners(e.signers)
+ newlyFinalized = append(newlyFinalized, *e)
+ }
+ f.lastPushed = &head
+ return newlyFinalized, nil
+}
+
+// isFinalized returns whether the first entry in `self.headers` is finalized.
+func (f *RollingFinality) isFinalized() bool {
+ e := f.headers.Front()
+ if e == nil {
+ return false
+ }
+ return len(f.signCount)*2 > len(f.signers.validators)
+}
+func (f *RollingFinality) hasSigner(signer common.Address) bool {
+ for j := range f.signers.validators {
+ if f.signers.validators[j] == signer {
+ return true
+
+ }
+ }
+ return false
+}
+func (f *RollingFinality) addSigners(signers []common.Address) bool {
+ for i := range signers {
+ count, ok := f.signCount[signers[i]]
+ if ok {
+ f.signCount[signers[i]] = count + 1
+ } else {
+ f.signCount[signers[i]] = 1
+ }
+ }
+ return false
+}
+func (f *RollingFinality) removeSigners(signers []common.Address) {
+ for i := range signers {
+ count, ok := f.signCount[signers[i]]
+ if !ok {
+ panic("all hashes in `header` should have entries in `sign_count` for their signers")
+ //continue
+ }
+ if count <= 1 {
+ delete(f.signCount, signers[i])
+ } else {
+ f.signCount[signers[i]] = count - 1
+ }
+ }
+}
+func (f *RollingFinality) buildAncestrySubChain(get func(hash common.Hash) ([]common.Address, common.Hash, common.Hash, uint64, bool), parentHash, epochTransitionHash common.Hash) error { // starts from chainHeadParentHash
+ f.clear()
+
+ for {
+ signers, blockHash, newParentHash, blockNum, ok := get(parentHash)
+ if !ok {
+ return nil
+ }
+ if blockHash == epochTransitionHash {
+ return nil
+ }
+ for i := range signers {
+ if !f.hasSigner(signers[i]) {
+ return fmt.Errorf("unknown validator: blockNum=%d", blockNum)
+ }
+ }
+ if f.lastPushed == nil {
+ copyHash := parentHash
+ f.lastPushed = ©Hash
+ }
+ f.addSigners(signers)
+ f.headers.PushFront(&unAssembledHeader{hash: blockHash, number: blockNum, signers: signers})
+ // break when we've got our first finalized block.
+ if f.isFinalized() {
+ e := f.headers.Pop()
+ if e == nil {
+ panic("we just pushed a block")
+ }
+ f.removeSigners(e.signers)
+ //log.Info("[aura] finality encountered already finalized block", "hash", e.hash.String(), "number", e.number)
+ break
+ }
+
+ parentHash = newParentHash
+ }
+ return nil
+}
diff --git a/consensus/aura/aura_test.go b/consensus/aura/aura_test.go
new file mode 100644
index 000000000000..4b92c5e0261f
--- /dev/null
+++ b/consensus/aura/aura_test.go
@@ -0,0 +1,56 @@
+package aura_test
+
+// import (
+// "testing"
+
+// "github.com/stretchr/testify/require"
+
+// "github.com/ethereum/go-ethereum-lib/kv/memdb"
+// libcommon "github.com/ethereum/go-ethereum/common"
+
+// "github.com/ethereum/go-ethereum/consensus/aura"
+// "github.com/ethereum/go-ethereum/core"
+// "github.com/ethereum/go-ethereum/core/types"
+// "github.com/ethereum/go-ethereum/trie"
+// )
+
+// Check that the first block of Gnosis Chain, which doesn't have any transactions,
+// does not change the state root.
+// func TestEmptyBlock(t *testing.T) {
+// require := require.New(t)
+// genesis := core.DefaultGnosisGenesisBlock()
+// genesisBlock := genesis.ToBlock()
+
+// genesis.Config.TerminalTotalDifficultyPassed = false
+
+// chainConfig := genesis.Config
+// auraDB := memdb.NewTestDB(t)
+// engine, err := aura.NewAuRa(chainConfig.Aura, auraDB)
+// require.NoError(err)
+// m := stages.MockWithGenesisEngine(t, genesis, engine, false)
+
+// time := uint64(1539016985)
+// header := core.MakeEmptyHeader(genesisBlock.Header(), chainConfig, time, nil)
+// header.UncleHash = types.EmptyUncleHash
+// header.TxHash = trie.EmptyRoot
+// header.ReceiptHash = trie.EmptyRoot
+// header.Coinbase = libcommon.HexToAddress("0xcace5b3c29211740e595850e80478416ee77ca21")
+// header.Difficulty = engine.CalcDifficulty(nil, time,
+// 0,
+// genesisBlock.Difficulty(),
+// genesisBlock.NumberU64(),
+// genesisBlock.Hash(),
+// genesisBlock.UncleHash(),
+// genesisBlock.Header().AuRaStep,
+// )
+
+// block := types.NewBlockWithHeader(header)
+
+// headers, blocks, receipts := make([]*types.Header, 1), make(types.Blocks, 1), make([]types.Receipts, 1)
+// headers[0] = header
+// blocks[0] = block
+
+// chain := &core.ChainPack{Headers: headers, Blocks: blocks, Receipts: receipts, TopBlock: block}
+// err = m.InsertChain(chain)
+// require.NoError(err)
+// }
diff --git a/consensus/aura/auraabi/abi.go b/consensus/aura/auraabi/abi.go
new file mode 100644
index 000000000000..8622847f4872
--- /dev/null
+++ b/consensus/aura/auraabi/abi.go
@@ -0,0 +1,4 @@
+package auraabi
+
+//go:generate abigen -abi ./../contracts/block_reward.json -pkg auraabi -type block_reward -out ./gen_block_reward.go
+//go:generate abigen -abi ./../contracts/validator_set.json -pkg auraabi -type validator_set -out ./gen_validator_set.go
diff --git a/consensus/aura/auraabi/gen_block_reward.go b/consensus/aura/auraabi/gen_block_reward.go
new file mode 100644
index 000000000000..500267fe8d51
--- /dev/null
+++ b/consensus/aura/auraabi/gen_block_reward.go
@@ -0,0 +1,202 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package auraabi
+
+import (
+ "errors"
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var (
+ _ = errors.New
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+ _ = abi.ConvertType
+)
+
+// BlockRewardMetaData contains all meta data concerning the BlockReward contract.
+var BlockRewardMetaData = &bind.MetaData{
+ ABI: "[{\"constant\":false,\"inputs\":[{\"name\":\"benefactors\",\"type\":\"address[]\"},{\"name\":\"kind\",\"type\":\"uint16[]\"}],\"name\":\"reward\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"},{\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+}
+
+// BlockRewardABI is the input ABI used to generate the binding from.
+// Deprecated: Use BlockRewardMetaData.ABI instead.
+var BlockRewardABI = BlockRewardMetaData.ABI
+
+// BlockReward is an auto generated Go binding around an Ethereum contract.
+type BlockReward struct {
+ BlockRewardCaller // Read-only binding to the contract
+ BlockRewardTransactor // Write-only binding to the contract
+ BlockRewardFilterer // Log filterer for contract events
+}
+
+// BlockRewardCaller is an auto generated read-only Go binding around an Ethereum contract.
+type BlockRewardCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// BlockRewardTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type BlockRewardTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// BlockRewardFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type BlockRewardFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// BlockRewardSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type BlockRewardSession struct {
+ Contract *BlockReward // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// BlockRewardCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type BlockRewardCallerSession struct {
+ Contract *BlockRewardCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// BlockRewardTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type BlockRewardTransactorSession struct {
+ Contract *BlockRewardTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// BlockRewardRaw is an auto generated low-level Go binding around an Ethereum contract.
+type BlockRewardRaw struct {
+ Contract *BlockReward // Generic contract binding to access the raw methods on
+}
+
+// BlockRewardCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type BlockRewardCallerRaw struct {
+ Contract *BlockRewardCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// BlockRewardTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type BlockRewardTransactorRaw struct {
+ Contract *BlockRewardTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewBlockReward creates a new instance of BlockReward, bound to a specific deployed contract.
+func NewBlockReward(address common.Address, backend bind.ContractBackend) (*BlockReward, error) {
+ contract, err := bindBlockReward(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &BlockReward{BlockRewardCaller: BlockRewardCaller{contract: contract}, BlockRewardTransactor: BlockRewardTransactor{contract: contract}, BlockRewardFilterer: BlockRewardFilterer{contract: contract}}, nil
+}
+
+// NewBlockRewardCaller creates a new read-only instance of BlockReward, bound to a specific deployed contract.
+func NewBlockRewardCaller(address common.Address, caller bind.ContractCaller) (*BlockRewardCaller, error) {
+ contract, err := bindBlockReward(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &BlockRewardCaller{contract: contract}, nil
+}
+
+// NewBlockRewardTransactor creates a new write-only instance of BlockReward, bound to a specific deployed contract.
+func NewBlockRewardTransactor(address common.Address, transactor bind.ContractTransactor) (*BlockRewardTransactor, error) {
+ contract, err := bindBlockReward(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &BlockRewardTransactor{contract: contract}, nil
+}
+
+// NewBlockRewardFilterer creates a new log filterer instance of BlockReward, bound to a specific deployed contract.
+func NewBlockRewardFilterer(address common.Address, filterer bind.ContractFilterer) (*BlockRewardFilterer, error) {
+ contract, err := bindBlockReward(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &BlockRewardFilterer{contract: contract}, nil
+}
+
+// bindBlockReward binds a generic wrapper to an already deployed contract.
+func bindBlockReward(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := BlockRewardMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_BlockReward *BlockRewardRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _BlockReward.Contract.BlockRewardCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_BlockReward *BlockRewardRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _BlockReward.Contract.BlockRewardTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_BlockReward *BlockRewardRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _BlockReward.Contract.BlockRewardTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_BlockReward *BlockRewardCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _BlockReward.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_BlockReward *BlockRewardTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _BlockReward.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_BlockReward *BlockRewardTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _BlockReward.Contract.contract.Transact(opts, method, params...)
+}
+
+// Reward is a paid mutator transaction binding the contract method 0xf91c2898.
+//
+// Solidity: function reward(address[] benefactors, uint16[] kind) returns(address[], uint256[])
+func (_BlockReward *BlockRewardTransactor) Reward(opts *bind.TransactOpts, benefactors []common.Address, kind []uint16) (*types.Transaction, error) {
+ return _BlockReward.contract.Transact(opts, "reward", benefactors, kind)
+}
+
+// Reward is a paid mutator transaction binding the contract method 0xf91c2898.
+//
+// Solidity: function reward(address[] benefactors, uint16[] kind) returns(address[], uint256[])
+func (_BlockReward *BlockRewardSession) Reward(benefactors []common.Address, kind []uint16) (*types.Transaction, error) {
+ return _BlockReward.Contract.Reward(&_BlockReward.TransactOpts, benefactors, kind)
+}
+
+// Reward is a paid mutator transaction binding the contract method 0xf91c2898.
+//
+// Solidity: function reward(address[] benefactors, uint16[] kind) returns(address[], uint256[])
+func (_BlockReward *BlockRewardTransactorSession) Reward(benefactors []common.Address, kind []uint16) (*types.Transaction, error) {
+ return _BlockReward.Contract.Reward(&_BlockReward.TransactOpts, benefactors, kind)
+}
diff --git a/consensus/aura/auraabi/gen_validator_set.go b/consensus/aura/auraabi/gen_validator_set.go
new file mode 100644
index 000000000000..a1d51d68a839
--- /dev/null
+++ b/consensus/aura/auraabi/gen_validator_set.go
@@ -0,0 +1,461 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package auraabi
+
+import (
+ "errors"
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var (
+ _ = errors.New
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+ _ = abi.ConvertType
+)
+
+// ValidatorSetMetaData contains all meta data concerning the ValidatorSet contract.
+var ValidatorSetMetaData = &bind.MetaData{
+ ABI: "[{\"constant\":false,\"inputs\":[],\"name\":\"finalizeChange\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"name\":\"validators\",\"type\":\"address[]\"}],\"payable\":false,\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_parent_hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"_new_set\",\"type\":\"address[]\"}],\"name\":\"InitiateChange\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[],\"name\":\"emitInitiateChangeCallable\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"emitInitiateChange\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_reportingValidator\",\"type\":\"address\"},{\"name\":\"_maliciousValidator\",\"type\":\"address\"},{\"name\":\"_blockNumber\",\"type\":\"uint256\"}],\"name\":\"shouldValidatorReport\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]",
+}
+
+// ValidatorSetABI is the input ABI used to generate the binding from.
+// Deprecated: Use ValidatorSetMetaData.ABI instead.
+var ValidatorSetABI = ValidatorSetMetaData.ABI
+
+// ValidatorSet is an auto generated Go binding around an Ethereum contract.
+type ValidatorSet struct {
+ ValidatorSetCaller // Read-only binding to the contract
+ ValidatorSetTransactor // Write-only binding to the contract
+ ValidatorSetFilterer // Log filterer for contract events
+}
+
+// ValidatorSetCaller is an auto generated read-only Go binding around an Ethereum contract.
+type ValidatorSetCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ValidatorSetTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type ValidatorSetTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ValidatorSetFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type ValidatorSetFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ValidatorSetSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type ValidatorSetSession struct {
+ Contract *ValidatorSet // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// ValidatorSetCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type ValidatorSetCallerSession struct {
+ Contract *ValidatorSetCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// ValidatorSetTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type ValidatorSetTransactorSession struct {
+ Contract *ValidatorSetTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// ValidatorSetRaw is an auto generated low-level Go binding around an Ethereum contract.
+type ValidatorSetRaw struct {
+ Contract *ValidatorSet // Generic contract binding to access the raw methods on
+}
+
+// ValidatorSetCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type ValidatorSetCallerRaw struct {
+ Contract *ValidatorSetCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// ValidatorSetTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type ValidatorSetTransactorRaw struct {
+ Contract *ValidatorSetTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewValidatorSet creates a new instance of ValidatorSet, bound to a specific deployed contract.
+func NewValidatorSet(address common.Address, backend bind.ContractBackend) (*ValidatorSet, error) {
+ contract, err := bindValidatorSet(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &ValidatorSet{ValidatorSetCaller: ValidatorSetCaller{contract: contract}, ValidatorSetTransactor: ValidatorSetTransactor{contract: contract}, ValidatorSetFilterer: ValidatorSetFilterer{contract: contract}}, nil
+}
+
+// NewValidatorSetCaller creates a new read-only instance of ValidatorSet, bound to a specific deployed contract.
+func NewValidatorSetCaller(address common.Address, caller bind.ContractCaller) (*ValidatorSetCaller, error) {
+ contract, err := bindValidatorSet(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &ValidatorSetCaller{contract: contract}, nil
+}
+
+// NewValidatorSetTransactor creates a new write-only instance of ValidatorSet, bound to a specific deployed contract.
+func NewValidatorSetTransactor(address common.Address, transactor bind.ContractTransactor) (*ValidatorSetTransactor, error) {
+ contract, err := bindValidatorSet(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &ValidatorSetTransactor{contract: contract}, nil
+}
+
+// NewValidatorSetFilterer creates a new log filterer instance of ValidatorSet, bound to a specific deployed contract.
+func NewValidatorSetFilterer(address common.Address, filterer bind.ContractFilterer) (*ValidatorSetFilterer, error) {
+ contract, err := bindValidatorSet(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &ValidatorSetFilterer{contract: contract}, nil
+}
+
+// bindValidatorSet binds a generic wrapper to an already deployed contract.
+func bindValidatorSet(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := ValidatorSetMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_ValidatorSet *ValidatorSetRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _ValidatorSet.Contract.ValidatorSetCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_ValidatorSet *ValidatorSetRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _ValidatorSet.Contract.ValidatorSetTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_ValidatorSet *ValidatorSetRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _ValidatorSet.Contract.ValidatorSetTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_ValidatorSet *ValidatorSetCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _ValidatorSet.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_ValidatorSet *ValidatorSetTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _ValidatorSet.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_ValidatorSet *ValidatorSetTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _ValidatorSet.Contract.contract.Transact(opts, method, params...)
+}
+
+// EmitInitiateChangeCallable is a free data retrieval call binding the contract method 0x3d3b5458.
+//
+// Solidity: function emitInitiateChangeCallable() view returns(bool)
+func (_ValidatorSet *ValidatorSetCaller) EmitInitiateChangeCallable(opts *bind.CallOpts) (bool, error) {
+ var out []interface{}
+ err := _ValidatorSet.contract.Call(opts, &out, "emitInitiateChangeCallable")
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+// EmitInitiateChangeCallable is a free data retrieval call binding the contract method 0x3d3b5458.
+//
+// Solidity: function emitInitiateChangeCallable() view returns(bool)
+func (_ValidatorSet *ValidatorSetSession) EmitInitiateChangeCallable() (bool, error) {
+ return _ValidatorSet.Contract.EmitInitiateChangeCallable(&_ValidatorSet.CallOpts)
+}
+
+// EmitInitiateChangeCallable is a free data retrieval call binding the contract method 0x3d3b5458.
+//
+// Solidity: function emitInitiateChangeCallable() view returns(bool)
+func (_ValidatorSet *ValidatorSetCallerSession) EmitInitiateChangeCallable() (bool, error) {
+ return _ValidatorSet.Contract.EmitInitiateChangeCallable(&_ValidatorSet.CallOpts)
+}
+
+// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5.
+//
+// Solidity: function getValidators() returns(address[] validators)
+func (_ValidatorSet *ValidatorSetCaller) GetValidators(opts *bind.CallOpts) ([]common.Address, error) {
+ var out []interface{}
+ err := _ValidatorSet.contract.Call(opts, &out, "getValidators")
+
+ if err != nil {
+ return *new([]common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address)
+
+ return out0, err
+
+}
+
+// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5.
+//
+// Solidity: function getValidators() returns(address[] validators)
+func (_ValidatorSet *ValidatorSetSession) GetValidators() ([]common.Address, error) {
+ return _ValidatorSet.Contract.GetValidators(&_ValidatorSet.CallOpts)
+}
+
+// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5.
+//
+// Solidity: function getValidators() returns(address[] validators)
+func (_ValidatorSet *ValidatorSetCallerSession) GetValidators() ([]common.Address, error) {
+ return _ValidatorSet.Contract.GetValidators(&_ValidatorSet.CallOpts)
+}
+
+// ShouldValidatorReport is a free data retrieval call binding the contract method 0xcbd2d528.
+//
+// Solidity: function shouldValidatorReport(address _reportingValidator, address _maliciousValidator, uint256 _blockNumber) view returns(bool)
+func (_ValidatorSet *ValidatorSetCaller) ShouldValidatorReport(opts *bind.CallOpts, _reportingValidator common.Address, _maliciousValidator common.Address, _blockNumber *big.Int) (bool, error) {
+ var out []interface{}
+ err := _ValidatorSet.contract.Call(opts, &out, "shouldValidatorReport", _reportingValidator, _maliciousValidator, _blockNumber)
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+// ShouldValidatorReport is a free data retrieval call binding the contract method 0xcbd2d528.
+//
+// Solidity: function shouldValidatorReport(address _reportingValidator, address _maliciousValidator, uint256 _blockNumber) view returns(bool)
+func (_ValidatorSet *ValidatorSetSession) ShouldValidatorReport(_reportingValidator common.Address, _maliciousValidator common.Address, _blockNumber *big.Int) (bool, error) {
+ return _ValidatorSet.Contract.ShouldValidatorReport(&_ValidatorSet.CallOpts, _reportingValidator, _maliciousValidator, _blockNumber)
+}
+
+// ShouldValidatorReport is a free data retrieval call binding the contract method 0xcbd2d528.
+//
+// Solidity: function shouldValidatorReport(address _reportingValidator, address _maliciousValidator, uint256 _blockNumber) view returns(bool)
+func (_ValidatorSet *ValidatorSetCallerSession) ShouldValidatorReport(_reportingValidator common.Address, _maliciousValidator common.Address, _blockNumber *big.Int) (bool, error) {
+ return _ValidatorSet.Contract.ShouldValidatorReport(&_ValidatorSet.CallOpts, _reportingValidator, _maliciousValidator, _blockNumber)
+}
+
+// EmitInitiateChange is a paid mutator transaction binding the contract method 0x93b4e25e.
+//
+// Solidity: function emitInitiateChange() returns()
+func (_ValidatorSet *ValidatorSetTransactor) EmitInitiateChange(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _ValidatorSet.contract.Transact(opts, "emitInitiateChange")
+}
+
+// EmitInitiateChange is a paid mutator transaction binding the contract method 0x93b4e25e.
+//
+// Solidity: function emitInitiateChange() returns()
+func (_ValidatorSet *ValidatorSetSession) EmitInitiateChange() (*types.Transaction, error) {
+ return _ValidatorSet.Contract.EmitInitiateChange(&_ValidatorSet.TransactOpts)
+}
+
+// EmitInitiateChange is a paid mutator transaction binding the contract method 0x93b4e25e.
+//
+// Solidity: function emitInitiateChange() returns()
+func (_ValidatorSet *ValidatorSetTransactorSession) EmitInitiateChange() (*types.Transaction, error) {
+ return _ValidatorSet.Contract.EmitInitiateChange(&_ValidatorSet.TransactOpts)
+}
+
+// FinalizeChange is a paid mutator transaction binding the contract method 0x75286211.
+//
+// Solidity: function finalizeChange() returns()
+func (_ValidatorSet *ValidatorSetTransactor) FinalizeChange(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _ValidatorSet.contract.Transact(opts, "finalizeChange")
+}
+
+// FinalizeChange is a paid mutator transaction binding the contract method 0x75286211.
+//
+// Solidity: function finalizeChange() returns()
+func (_ValidatorSet *ValidatorSetSession) FinalizeChange() (*types.Transaction, error) {
+ return _ValidatorSet.Contract.FinalizeChange(&_ValidatorSet.TransactOpts)
+}
+
+// FinalizeChange is a paid mutator transaction binding the contract method 0x75286211.
+//
+// Solidity: function finalizeChange() returns()
+func (_ValidatorSet *ValidatorSetTransactorSession) FinalizeChange() (*types.Transaction, error) {
+ return _ValidatorSet.Contract.FinalizeChange(&_ValidatorSet.TransactOpts)
+}
+
+// ValidatorSetInitiateChangeIterator is returned from FilterInitiateChange and is used to iterate over the raw logs and unpacked data for InitiateChange events raised by the ValidatorSet contract.
+type ValidatorSetInitiateChangeIterator struct {
+ Event *ValidatorSetInitiateChange // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ValidatorSetInitiateChangeIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ValidatorSetInitiateChange)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ValidatorSetInitiateChange)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ValidatorSetInitiateChangeIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ValidatorSetInitiateChangeIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ValidatorSetInitiateChange represents a InitiateChange event raised by the ValidatorSet contract.
+type ValidatorSetInitiateChange struct {
+ ParentHash [32]byte
+ NewSet []common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterInitiateChange is a free log retrieval operation binding the contract event 0x55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89.
+//
+// Solidity: event InitiateChange(bytes32 indexed _parent_hash, address[] _new_set)
+func (_ValidatorSet *ValidatorSetFilterer) FilterInitiateChange(opts *bind.FilterOpts, _parent_hash [][32]byte) (*ValidatorSetInitiateChangeIterator, error) {
+
+ var _parent_hashRule []interface{}
+ for _, _parent_hashItem := range _parent_hash {
+ _parent_hashRule = append(_parent_hashRule, _parent_hashItem)
+ }
+
+ logs, sub, err := _ValidatorSet.contract.FilterLogs(opts, "InitiateChange", _parent_hashRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ValidatorSetInitiateChangeIterator{contract: _ValidatorSet.contract, event: "InitiateChange", logs: logs, sub: sub}, nil
+}
+
+// WatchInitiateChange is a free log subscription operation binding the contract event 0x55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89.
+//
+// Solidity: event InitiateChange(bytes32 indexed _parent_hash, address[] _new_set)
+func (_ValidatorSet *ValidatorSetFilterer) WatchInitiateChange(opts *bind.WatchOpts, sink chan<- *ValidatorSetInitiateChange, _parent_hash [][32]byte) (event.Subscription, error) {
+
+ var _parent_hashRule []interface{}
+ for _, _parent_hashItem := range _parent_hash {
+ _parent_hashRule = append(_parent_hashRule, _parent_hashItem)
+ }
+
+ logs, sub, err := _ValidatorSet.contract.WatchLogs(opts, "InitiateChange", _parent_hashRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ValidatorSetInitiateChange)
+ if err := _ValidatorSet.contract.UnpackLog(event, "InitiateChange", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// ParseInitiateChange is a log parse operation binding the contract event 0x55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89.
+//
+// Solidity: event InitiateChange(bytes32 indexed _parent_hash, address[] _new_set)
+func (_ValidatorSet *ValidatorSetFilterer) ParseInitiateChange(log types.Log) (*ValidatorSetInitiateChange, error) {
+ event := new(ValidatorSetInitiateChange)
+ if err := _ValidatorSet.contract.UnpackLog(event, "InitiateChange", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
diff --git a/consensus/aura/aurainterfaces/interface.go b/consensus/aura/aurainterfaces/interface.go
new file mode 100644
index 000000000000..cbcdc45c3c0d
--- /dev/null
+++ b/consensus/aura/aurainterfaces/interface.go
@@ -0,0 +1,44 @@
+package aurainterfaces
+
+import (
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus"
+)
+
+// see openethereum/crates/ethcore/res/contracts/block_reward.json
+type BlockRewardABI interface {
+ Reward(benefactors []common.Address, kind []consensus.RewardKind) ([]common.Address, []*big.Int, error)
+}
+
+type abiDecoder func([]byte, interface{}) error
+
+// see openethereum/crates/ethcore/res/contracts/validator_set.json
+type ValidatorSetABI interface {
+ GetValidators() ([]byte, abiDecoder)
+ ShouldValidatorReport(ourAddr, maliciousValidatorAddress common.Address, blockNum uint64) ([]byte, abiDecoder)
+}
+
+type SealKind [][]byte
+
+// Proposal seal; should be broadcasted, but not inserted into blockchain.
+type SealProposal SealKind
+
+// Regular block seal; should be part of the blockchain.
+type SealRegular SealKind
+
+// Engine does not generate seal for this block right now.
+type None SealKind
+
+// / The type of sealing the engine is currently able to perform.
+type SealingState uint8
+
+const (
+ /// The engine is ready to seal a block.
+ SealingStateReady SealingState = 0
+ /// The engine can't seal at the moment, and no block should be prepared and queued.
+ SealingStateNotReady SealingState = 1
+ /// The engine does not seal internally.
+ SealingStateExternal SealingState = 2
+)
diff --git a/consensus/aura/config.go b/consensus/aura/config.go
new file mode 100644
index 000000000000..0aa1ccbcbbdb
--- /dev/null
+++ b/consensus/aura/config.go
@@ -0,0 +1,196 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Package aura implements the proof-of-authority consensus engine.
+package aura
+
+import (
+ "errors"
+ "math/big"
+ "sort"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/params"
+)
+
+func newValidatorSetFromJson(j *params.ValidatorSetJson, posdaoTransition *uint64) ValidatorSet {
+ if j.List != nil {
+ return &SimpleList{validators: j.List}
+ }
+ if j.SafeContract != nil {
+ return NewValidatorSafeContract(*j.SafeContract, posdaoTransition, nil)
+ }
+ if j.Contract != nil {
+ return &ValidatorContract{
+ contractAddress: *j.Contract,
+ validators: NewValidatorSafeContract(*j.Contract, posdaoTransition, nil),
+ posdaoTransition: posdaoTransition,
+ }
+ }
+ if j.Multi != nil {
+ l := map[uint64]ValidatorSet{}
+ for block, set := range j.Multi {
+ l[block] = newValidatorSetFromJson(set, posdaoTransition)
+ }
+ return NewMulti(l)
+ }
+
+ return nil
+}
+
+type Code struct {
+ Code []byte
+ CodeHash common.Hash
+}
+
+type BlockRewardContract struct {
+ blockNum uint64
+ address common.Address // On-chain address.
+}
+
+type BlockRewardContractList []BlockRewardContract
+
+func (r BlockRewardContractList) Less(i, j int) bool { return r[i].blockNum < r[j].blockNum }
+func (r BlockRewardContractList) Len() int { return len(r) }
+func (r BlockRewardContractList) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
+
+type BlockReward struct {
+ blockNum uint64
+ amount *big.Int
+}
+
+type BlockRewardList []BlockReward
+
+func (r BlockRewardList) Less(i, j int) bool { return r[i].blockNum < r[j].blockNum }
+func (r BlockRewardList) Len() int { return len(r) }
+func (r BlockRewardList) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
+
+func NewBlockRewardContract(address common.Address) *BlockRewardContract {
+ return &BlockRewardContract{address: address}
+}
+
+type AuthorityRoundParams struct {
+ // A map defining intervals of blocks with the given times (in seconds) to wait before next
+ // block or authority switching. The keys in the map are steps of starting blocks of those
+ // periods. The entry at `0` should be defined.
+ //
+ // Wait times (durations) are additionally required to be less than 65535 since larger values
+ // lead to slow block issuance.
+ StepDurations map[uint64]uint64
+ // Starting step,
+ StartStep *uint64
+ // Valid validators.
+ Validators ValidatorSet
+ // Chain score validation transition block.
+ ValidateScoreTransition uint64
+ // Monotonic step validation transition block.
+ ValidateStepTransition uint64
+ // Immediate transitions.
+ ImmediateTransitions bool
+ // Block reward in base units.
+ BlockReward BlockRewardList
+ // Block reward contract addresses with their associated starting block numbers.
+ BlockRewardContractTransitions BlockRewardContractList
+ // Number of accepted uncles transition block.
+ MaximumUncleCountTransition uint64
+ // Number of accepted uncles.
+ MaximumUncleCount uint
+ // Transition block to strict empty steps validation.
+ StrictEmptyStepsTransition uint64
+ // If set, enables random number contract integration. It maps the transition block to the contract address.
+ RandomnessContractAddress map[uint64]common.Address
+ // The addresses of contracts that determine the block gas limit with their associated block
+ // numbers.
+ BlockGasLimitContractTransitions map[uint64]common.Address
+ // If set, this is the block number at which the consensus engine switches from AuRa to AuRa
+ // with POSDAO modifications.
+ PosdaoTransition *uint64
+ // Stores human-readable keys associated with addresses, like DNS information.
+ // This contract is primarily required to store the address of the Certifier contract.
+ Registrar *common.Address
+
+ // See https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md
+ WithdrawalContractAddress *common.Address
+
+ RewriteBytecode map[uint64]map[common.Address][]byte
+}
+
+func FromJson(jsonParams *params.AuRaConfig) (AuthorityRoundParams, error) {
+ params := AuthorityRoundParams{
+ Validators: newValidatorSetFromJson(jsonParams.Validators, jsonParams.PosdaoTransition),
+ StartStep: jsonParams.StartStep,
+ RandomnessContractAddress: jsonParams.RandomnessContractAddress,
+ BlockGasLimitContractTransitions: jsonParams.BlockGasLimitContractTransitions,
+ PosdaoTransition: jsonParams.PosdaoTransition,
+ Registrar: jsonParams.Registrar,
+ WithdrawalContractAddress: jsonParams.WithdrawalContractAddress,
+ }
+ params.StepDurations = map[uint64]uint64{}
+ if jsonParams.StepDuration != nil {
+ params.StepDurations[0] = *jsonParams.StepDuration
+ }
+
+ for blockNum, address := range jsonParams.BlockRewardContractTransitions {
+ params.BlockRewardContractTransitions = append(params.BlockRewardContractTransitions, BlockRewardContract{blockNum: uint64(blockNum), address: address})
+ }
+ sort.Sort(params.BlockRewardContractTransitions)
+ if jsonParams.BlockRewardContractAddress != nil {
+ transitionBlockNum := uint64(0)
+ if jsonParams.BlockRewardContractTransition != nil {
+ transitionBlockNum = *jsonParams.BlockRewardContractTransition
+ }
+ if len(params.BlockRewardContractTransitions) > 0 && transitionBlockNum >= params.BlockRewardContractTransitions[0].blockNum {
+ return params, errors.New("blockRewardContractTransition should be less than any of the keys in BlockRewardContractTransitions")
+ }
+ contract := BlockRewardContract{blockNum: transitionBlockNum, address: *jsonParams.BlockRewardContractAddress}
+ params.BlockRewardContractTransitions = append(BlockRewardContractList{contract}, params.BlockRewardContractTransitions...)
+ }
+
+ if jsonParams.ValidateScoreTransition != nil {
+ params.ValidateScoreTransition = *jsonParams.ValidateScoreTransition
+ }
+ if jsonParams.ValidateStepTransition != nil {
+ params.ValidateStepTransition = *jsonParams.ValidateStepTransition
+ }
+ if jsonParams.ImmediateTransitions != nil {
+ params.ImmediateTransitions = *jsonParams.ImmediateTransitions
+ }
+ if jsonParams.MaximumUncleCount != nil {
+ params.MaximumUncleCount = *jsonParams.MaximumUncleCount
+ }
+ if jsonParams.MaximumUncleCountTransition != nil {
+ params.MaximumUncleCountTransition = *jsonParams.MaximumUncleCountTransition
+ }
+
+ if jsonParams.BlockReward == nil {
+ params.BlockReward = append(params.BlockReward, BlockReward{blockNum: 0, amount: big.NewInt(0)})
+ } else {
+ if jsonParams.BlockReward != nil {
+ params.BlockReward = append(params.BlockReward, BlockReward{blockNum: 0, amount: big.NewInt(int64(*jsonParams.BlockReward))})
+ }
+ }
+ sort.Sort(params.BlockReward)
+
+ params.RewriteBytecode = make(map[uint64]map[common.Address][]byte, len(jsonParams.RewriteBytecode))
+ for block, overrides := range jsonParams.RewriteBytecode {
+ params.RewriteBytecode[block] = make(map[common.Address][]byte, len(overrides))
+ for address, code := range overrides {
+ params.RewriteBytecode[block][address] = []byte(code)
+ }
+ }
+
+ return params, nil
+}
diff --git a/consensus/aura/config_test.go b/consensus/aura/config_test.go
new file mode 100644
index 000000000000..c611d5cf5291
--- /dev/null
+++ b/consensus/aura/config_test.go
@@ -0,0 +1,35 @@
+package aura
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/params"
+)
+
+func TestGnosisBlockRewardContractTransitions(t *testing.T) {
+ spec := params.GnosisChainConfig.Aura
+
+ param, err := FromJson(spec)
+ require.NoError(t, err)
+
+ require.Equal(t, 2, len(param.BlockRewardContractTransitions))
+ assert.Equal(t, uint64(1310), param.BlockRewardContractTransitions[0].blockNum)
+ assert.Equal(t, common.HexToAddress("0x867305d19606aadba405ce534e303d0e225f9556"), param.BlockRewardContractTransitions[0].address)
+ assert.Equal(t, uint64(9186425), param.BlockRewardContractTransitions[1].blockNum)
+ assert.Equal(t, common.HexToAddress("0x481c034c6d9441db23ea48de68bcae812c5d39ba"), param.BlockRewardContractTransitions[1].address)
+}
+
+func TestInvalidBlockRewardContractTransition(t *testing.T) {
+ spec := *(params.GnosisChainConfig.Aura)
+
+ // blockRewardContractTransition should be smaller than any block number in blockRewardContractTransitions
+ invalidTransition := uint64(10_000_000)
+ spec.BlockRewardContractTransition = &invalidTransition
+
+ _, err := FromJson(&spec)
+ assert.Error(t, err)
+}
diff --git a/consensus/aura/contract_abi.go b/consensus/aura/contract_abi.go
new file mode 100644
index 000000000000..37890d7dffbf
--- /dev/null
+++ b/consensus/aura/contract_abi.go
@@ -0,0 +1,132 @@
+package aura
+
+import (
+ "bytes"
+ "math/big"
+
+ "github.com/holiman/uint256"
+
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus"
+ "github.com/ethereum/go-ethereum/consensus/aura/contracts"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+func callBlockRewardAbi(contractAddr common.Address, syscall Syscall, beneficiaries []common.Address, rewardKind []consensus.RewardKind) ([]common.Address, []*big.Int) {
+ castedKind := make([]uint16, len(rewardKind))
+ for i := range rewardKind {
+ castedKind[i] = uint16(rewardKind[i])
+ }
+ packed, err := blockRewardAbi().Pack("reward", beneficiaries, castedKind)
+ if err != nil {
+ panic(err)
+ }
+ out, err := syscall(contractAddr, packed)
+ if err != nil {
+ panic(err)
+ }
+ if len(out) == 0 {
+ return nil, nil
+ }
+ res, err := blockRewardAbi().Unpack("reward", out)
+ if err != nil {
+ panic(err)
+ }
+ beneficiariesRes := res[0].([]common.Address)
+ rewardsBig := res[1].([]*big.Int)
+ // rewardsU256 := make([]*big.Int, len(rewardsBig))
+ // for i := 0; i < len(rewardsBig); i++ {
+ // var overflow bool
+ // rewards[i], overflow = uint256.FromBig(rewardsBig[i])
+ // if overflow {
+ // panic("Overflow in callBlockRewardAbi")
+ // }
+ // }
+ return beneficiariesRes, rewardsBig
+}
+
+func callBlockGasLimitAbi(contractAddr common.Address, syscall Syscall) *uint256.Int {
+ packed, err := blockGasLimitAbi().Pack("blockGasLimit")
+ if err != nil {
+ panic(err)
+ }
+ out, err := syscall(contractAddr, packed)
+ if err != nil {
+ panic(err)
+ }
+ if len(out) == 0 {
+ return uint256.NewInt(0)
+ }
+ res, err := blockGasLimitAbi().Unpack("blockGasLimit", out)
+ if err != nil {
+ panic(err)
+ }
+
+ val, overflow := uint256.FromBig(res[0].(*big.Int))
+ if overflow {
+ panic("Overflow casting bigInt value to uint256")
+ }
+ return val
+}
+
+func blockGasLimitAbi() abi.ABI {
+ a, err := abi.JSON(bytes.NewReader(contracts.BlockGasLimit))
+ if err != nil {
+ panic(err)
+ }
+ return a
+}
+
+func blockRewardAbi() abi.ABI {
+ a, err := abi.JSON(bytes.NewReader(contracts.BlockReward))
+ if err != nil {
+ panic(err)
+ }
+ return a
+}
+
+func certifierAbi() abi.ABI {
+ a, err := abi.JSON(bytes.NewReader(contracts.Certifier))
+ if err != nil {
+ panic(err)
+ }
+ return a
+}
+
+func registrarAbi() abi.ABI {
+ a, err := abi.JSON(bytes.NewReader(contracts.Registrar))
+ if err != nil {
+ panic(err)
+ }
+ return a
+}
+
+func withdrawalAbi() abi.ABI {
+ a, err := abi.JSON(bytes.NewReader(contracts.Withdrawal))
+ if err != nil {
+ panic(err)
+ }
+ return a
+}
+
+func getCertifier(registrar common.Address, syscall Syscall) *common.Address {
+ hashedKey := crypto.Keccak256Hash([]byte("service_transaction_checker"))
+ packed, err := registrarAbi().Pack("getAddress", hashedKey, "A")
+ if err != nil {
+ panic(err)
+ }
+ out, err := syscall(registrar, packed)
+ if err != nil {
+ panic(err)
+ }
+ if len(out) == 0 {
+ return nil
+ }
+ res, err := registrarAbi().Unpack("getAddress", out)
+ if err != nil {
+ panic(err)
+ }
+ certifier := res[0].(common.Address)
+ return &certifier
+}
diff --git a/consensus/aura/contracts/authority_round_random.json b/consensus/aura/contracts/authority_round_random.json
new file mode 100644
index 000000000000..90766c93ef21
--- /dev/null
+++ b/consensus/aura/contracts/authority_round_random.json
@@ -0,0 +1,149 @@
+[
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_secretHash",
+ "type": "bytes32"
+ },
+ {
+ "name": "_cipher",
+ "type": "bytes"
+ }
+ ],
+ "name": "commitHash",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_number",
+ "type": "uint256"
+ }
+ ],
+ "name": "revealNumber",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "currentCollectRound",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_collectRound",
+ "type": "uint256"
+ },
+ {
+ "name": "_miningAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getCommitAndCipher",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_collectRound",
+ "type": "uint256"
+ },
+ {
+ "name": "_validator",
+ "type": "address"
+ }
+ ],
+ "name": "isCommitted",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isCommitPhase",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isRevealPhase",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_collectRound",
+ "type": "uint256"
+ },
+ {
+ "name": "_validator",
+ "type": "address"
+ }
+ ],
+ "name": "sentReveal",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
\ No newline at end of file
diff --git a/consensus/aura/contracts/block_gas_limit.json b/consensus/aura/contracts/block_gas_limit.json
new file mode 100644
index 000000000000..8ca9cf96946c
--- /dev/null
+++ b/consensus/aura/contracts/block_gas_limit.json
@@ -0,0 +1,16 @@
+[
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "blockGasLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
\ No newline at end of file
diff --git a/consensus/aura/contracts/block_reward.json b/consensus/aura/contracts/block_reward.json
new file mode 100644
index 000000000000..9209967f3ace
--- /dev/null
+++ b/consensus/aura/contracts/block_reward.json
@@ -0,0 +1,29 @@
+[
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "benefactors",
+ "type": "address[]"
+ },
+ {
+ "name": "kind",
+ "type": "uint16[]"
+ }
+ ],
+ "name": "reward",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address[]"
+ },
+ {
+ "name": "",
+ "type": "uint256[]"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/consensus/aura/contracts/certifier.json b/consensus/aura/contracts/certifier.json
new file mode 100644
index 000000000000..5025acb92fea
--- /dev/null
+++ b/consensus/aura/contracts/certifier.json
@@ -0,0 +1,164 @@
+[
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_new",
+ "type": "address"
+ }
+ ],
+ "name": "setOwner",
+ "outputs": [],
+ "payable": false,
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_who",
+ "type": "address"
+ }
+ ],
+ "name": "certify",
+ "outputs": [],
+ "payable": false,
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_who",
+ "type": "address"
+ },
+ {
+ "name": "_field",
+ "type": "string"
+ }
+ ],
+ "name": "getAddress",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_who",
+ "type": "address"
+ }
+ ],
+ "name": "revoke",
+ "outputs": [],
+ "payable": false,
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "delegate",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_who",
+ "type": "address"
+ },
+ {
+ "name": "_field",
+ "type": "string"
+ }
+ ],
+ "name": "getUint",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_new",
+ "type": "address"
+ }
+ ],
+ "name": "setDelegate",
+ "outputs": [],
+ "payable": false,
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_who",
+ "type": "address"
+ }
+ ],
+ "name": "certified",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_who",
+ "type": "address"
+ },
+ {
+ "name": "_field",
+ "type": "string"
+ }
+ ],
+ "name": "get",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "payable": false,
+ "type": "function"
+ }
+]
diff --git a/consensus/aura/contracts/embed.go b/consensus/aura/contracts/embed.go
new file mode 100644
index 000000000000..0a87b2d0b811
--- /dev/null
+++ b/consensus/aura/contracts/embed.go
@@ -0,0 +1,20 @@
+package contracts
+
+import (
+ _ "embed"
+)
+
+//go:embed block_reward.json
+var BlockReward []byte
+
+//go:embed certifier.json
+var Certifier []byte
+
+//go:embed registrar.json
+var Registrar []byte
+
+//go:embed withdrawal.json
+var Withdrawal []byte
+
+//go:embed block_gas_limit.json
+var BlockGasLimit []byte
diff --git a/consensus/aura/contracts/registrar.json b/consensus/aura/contracts/registrar.json
new file mode 100644
index 000000000000..2f4aab1fdbfa
--- /dev/null
+++ b/consensus/aura/contracts/registrar.json
@@ -0,0 +1,21 @@
+[
+ {"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"type":"function"},
+ {"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"confirmReverse","outputs":[{"name":"success","type":"bool"}],"type":"function"},
+ {"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[{"name":"success","type":"bool"}],"type":"function"},
+ {"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"bytes32"}],"name":"set","outputs":[{"name":"success","type":"bool"}],"type":"function"},
+ {"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"drop","outputs":[{"name":"success","type":"bool"}],"type":"function"},
+ {"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"getAddress","outputs":[{"name":"","type":"address"}],"type":"function"},
+ {"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"setFee","outputs":[],"type":"function"},
+ {"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_to","type":"address"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"type":"function"},
+ {"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},
+ {"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserved","outputs":[{"name":"reserved","type":"bool"}],"type":"function"},
+ {"constant":false,"inputs":[],"name":"drain","outputs":[],"type":"function"},
+ {"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_who","type":"address"}],"name":"proposeReverse","outputs":[{"name":"success","type":"bool"}],"type":"function"},
+ {"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"getUint","outputs":[{"name":"","type":"uint256"}],"type":"function"},
+ {"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"get","outputs":[{"name":"","type":"bytes32"}],"type":"function"},
+ {"constant":true,"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"type":"function"},
+ {"constant":true,"inputs":[{"name":"","type":"address"}],"name":"reverse","outputs":[{"name":"","type":"string"}],"type":"function"},
+ {"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"uint256"}],"name":"setUint","outputs":[{"name":"success","type":"bool"}],"type":"function"},
+ {"constant":false,"inputs":[],"name":"removeReverse","outputs":[],"type":"function"},
+ {"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"address"}],"name":"setAddress","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Drained","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"FeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"owner","type":"address"}],"name":"Reserved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"oldOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"Transferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"owner","type":"address"}],"name":"Dropped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"key","type":"string"}],"name":"DataChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":true,"name":"reverse","type":"address"}],"name":"ReverseProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":true,"name":"reverse","type":"address"}],"name":"ReverseConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":true,"name":"reverse","type":"address"}],"name":"ReverseRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}
+]
\ No newline at end of file
diff --git a/consensus/aura/contracts/test_authority_round_random.json b/consensus/aura/contracts/test_authority_round_random.json
new file mode 100644
index 000000000000..beab82ab4864
--- /dev/null
+++ b/consensus/aura/contracts/test_authority_round_random.json
@@ -0,0 +1,265 @@
+[
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "ciphers",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_collectRound",
+ "type": "uint256"
+ },
+ {
+ "name": "_miningAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getCipher",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_secretHash",
+ "type": "bytes32"
+ },
+ {
+ "name": "_cipher",
+ "type": "bytes"
+ }
+ ],
+ "name": "commitHash",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getValue",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "hashes",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "value",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "secrets",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_collectRound",
+ "type": "uint256"
+ },
+ {
+ "name": "_miningAddress",
+ "type": "address"
+ }
+ ],
+ "name": "sentReveal",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isCommitPhase",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_number",
+ "type": "uint256"
+ }
+ ],
+ "name": "revealNumber",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getRound",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_collectRound",
+ "type": "uint256"
+ },
+ {
+ "name": "_miningAddress",
+ "type": "address"
+ }
+ ],
+ "name": "isCommitted",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isRevealPhase",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_collectRound",
+ "type": "uint256"
+ },
+ {
+ "name": "_miningAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getCommit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
\ No newline at end of file
diff --git a/consensus/aura/contracts/test_authority_round_random.sol b/consensus/aura/contracts/test_authority_round_random.sol
new file mode 100644
index 000000000000..66c971786358
--- /dev/null
+++ b/consensus/aura/contracts/test_authority_round_random.sol
@@ -0,0 +1,101 @@
+pragma solidity 0.5.10;
+
+/// @dev Randomness test contract based on https://github.com/poanetwork/posdao-contracts.
+/// Generates and stores random numbers in a RANDAO manner and accumulates a random seed.
+contract Random {
+ mapping(uint256 => mapping(address => bytes32)) public hashes;
+ mapping(uint256 => mapping(address => bytes)) public ciphers;
+ mapping(uint256 => mapping(address => uint256)) public secrets;
+ uint256 public value;
+
+ /// @dev Called by the validator's node to store a hash and a cipher of the validator's secret on each collection
+ /// round. The validator's node must use its mining address to call this function.
+ /// This function can only be called once per collection round (during the `commits phase`).
+ /// @param _secretHash The Keccak-256 hash of the validator's secret.
+ /// @param _cipher The cipher of the validator's secret. Can be used by the node to decrypt and reveal.
+ function commitHash(bytes32 _secretHash, bytes calldata _cipher) external {
+ require(block.coinbase == msg.sender);
+ require(_isCommitPhase(block.number - 1));
+ uint256 round = _collectRound(block.number - 1);
+ require(!isCommitted(round, msg.sender));
+ hashes[round][msg.sender] = _secretHash;
+ ciphers[round][msg.sender] = _cipher;
+ }
+
+ /// @dev Called by the validator's node to XOR its secret with the current random seed.
+ /// The validator's node must use its mining address to call this function.
+ /// This function can only be called once per collection round (during the `reveals phase`).
+ /// @param _number The validator's secret.
+ function revealNumber(uint256 _number) external {
+ require(block.coinbase == msg.sender);
+ require(_isRevealPhase(block.number - 1));
+ uint256 round = _collectRound(block.number - 1);
+ require(!sentReveal(round, msg.sender));
+ require(hashes[round][msg.sender] == keccak256(abi.encodePacked(_number)));
+ secrets[round][msg.sender] = _number;
+ value ^= _number;
+ }
+
+ /// @dev Returns the Keccak-256 hash and cipher of the validator's secret for the specified collection round
+ /// and the specified validator stored by the validator through the `commitHash` function.
+ /// @param _collectRound The serial number of the collection round for which hash and cipher should be retrieved.
+ /// @param _miningAddress The mining address of validator.
+ function getCommitAndCipher(
+ uint256 _collectRound,
+ address _miningAddress
+ ) public view returns(bytes32, bytes memory) {
+ return (hashes[_collectRound][_miningAddress], ciphers[_collectRound][_miningAddress]);
+ }
+
+ /// @dev Returns a boolean flag indicating whether the specified validator has committed their secret's hash for the
+ /// specified collection round.
+ /// @param _collectRound The serial number of the collection round for which the checkup should be done.
+ /// @param _miningAddress The mining address of the validator.
+ function isCommitted(uint256 _collectRound, address _miningAddress) public view returns(bool) {
+ return hashes[_collectRound][_miningAddress] != bytes32(0);
+ }
+
+ /// @dev Returns a boolean flag indicating whether the current phase of the current collection round
+ /// is a `commits phase`. Used by the validator's node to determine if it should commit the hash of
+ /// the secret during the current collection round.
+ function isCommitPhase() public view returns(bool) {
+ return _isCommitPhase(block.number);
+ }
+
+ /// @dev Returns a boolean flag indicating whether the current phase of the current collection round
+ /// is a `reveals phase`. Used by the validator's node to determine if it should reveal the secret during
+ /// the current collection round.
+ function isRevealPhase() public view returns(bool) {
+ return _isRevealPhase(block.number);
+ }
+
+ /// @dev Returns a boolean flag of whether the specified validator has revealed their secret for the
+ /// specified collection round.
+ /// @param _collectRound The serial number of the collection round for which the checkup should be done.
+ /// @param _miningAddress The mining address of the validator.
+ function sentReveal(uint256 _collectRound, address _miningAddress) public view returns(bool) {
+ return secrets[_collectRound][_miningAddress] != uint256(0);
+ }
+
+ /// @dev Returns the current collect round number.
+ function currentCollectRound() public view returns(uint256) {
+ return _collectRound(block.number);
+ }
+
+ /// @dev Returns the current random value.
+ function getValue() public view returns(uint256) {
+ return value;
+ }
+
+ function _collectRound(uint256 blockNumber) private pure returns(uint256) {
+ return blockNumber / 6;
+ }
+
+ function _isCommitPhase(uint256 blockNumber) private pure returns(bool) {
+ return blockNumber % 6 < 3;
+ }
+
+ function _isRevealPhase(uint256 blockNumber) private pure returns(bool) {
+ return blockNumber % 6 >= 3;
+ }
+}
diff --git a/consensus/aura/contracts/test_validator_set.json b/consensus/aura/contracts/test_validator_set.json
new file mode 100644
index 000000000000..7ed6a000fe5d
--- /dev/null
+++ b/consensus/aura/contracts/test_validator_set.json
@@ -0,0 +1,8 @@
+[
+ {"constant":false,"inputs":[{"name":"_validators","type":"address[]"}],"name":"setValidators","outputs":[],"payable":false,"type":"function"},
+ {"constant":false,"inputs":[{"name":"","type":"address"},{"name":"","type":"bytes"}],"name":"reportMalicious","outputs":[],"payable":false,"type":"function"},
+ {"constant":false,"inputs":[],"name":"finalizeChange","outputs":[],"payable":false,"type":"function"},
+ {"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"_validators","type":"address[]"}],"payable":false,"type":"function"},
+ {"constant":false,"inputs":[{"name":"","type":"address"}],"name":"reportBenign","outputs":[],"payable":false,"type":"function"},
+ {"anonymous":false,"inputs":[{"indexed":true,"name":"_parent_hash","type":"bytes32"},{"indexed":false,"name":"_new_set","type":"address[]"}],"name":"InitiateChange","type":"event"}
+]
diff --git a/consensus/aura/contracts/tx_acl.json b/consensus/aura/contracts/tx_acl.json
new file mode 100644
index 000000000000..e110797d96fb
--- /dev/null
+++ b/consensus/aura/contracts/tx_acl.json
@@ -0,0 +1 @@
+[ { "constant": true, "inputs": [], "name": "contractNameHash", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "contractName", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "contractVersion", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "sender", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "allowedTxTypes", "outputs": [ { "name": "", "type": "uint32" }, { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ]
diff --git a/consensus/aura/contracts/tx_acl_deprecated.json b/consensus/aura/contracts/tx_acl_deprecated.json
new file mode 100644
index 000000000000..cc924cafb81d
--- /dev/null
+++ b/consensus/aura/contracts/tx_acl_deprecated.json
@@ -0,0 +1 @@
+[{"constant":true,"inputs":[{"name":"sender","type":"address"}],"name":"allowedTxTypes","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]
diff --git a/consensus/aura/contracts/tx_acl_gas_price.json b/consensus/aura/contracts/tx_acl_gas_price.json
new file mode 100644
index 000000000000..37b08e9f0dbc
--- /dev/null
+++ b/consensus/aura/contracts/tx_acl_gas_price.json
@@ -0,0 +1,83 @@
+[
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "contractNameHash",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "contractName",
+ "outputs": [
+ {
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "contractVersion",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "name": "gasPrice",
+ "type": "uint256"
+ },
+ {
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "allowedTxTypes",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint32"
+ },
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
\ No newline at end of file
diff --git a/consensus/aura/contracts/validator_report.json b/consensus/aura/contracts/validator_report.json
new file mode 100644
index 000000000000..e0c011432696
--- /dev/null
+++ b/consensus/aura/contracts/validator_report.json
@@ -0,0 +1,5 @@
+[
+ {"constant":false,"inputs":[{"name":"validator","type":"address"},{"name":"blockNumber","type":"uint256"},{"name":"proof","type":"bytes"}],"name":"reportMalicious","outputs":[],"payable":false,"type":"function"},
+ {"constant":false,"inputs":[{"name":"validator","type":"address"},{"name":"blockNumber","type":"uint256"}],"name":"reportBenign","outputs":[],"payable":false,"type":"function"},
+ {"constant": true, "inputs": [ { "name": "validator", "type": "address" }, { "name": "blockNum", "type": "uint256" } ], "name": "maliceReportedForBlock", "outputs": [ { "name": "", "type": "address[]" } ], "payable": false, "stateMutability": "view", "type": "function" }
+]
diff --git a/consensus/aura/contracts/validator_set.json b/consensus/aura/contracts/validator_set.json
new file mode 100644
index 000000000000..660e8b614bbe
--- /dev/null
+++ b/consensus/aura/contracts/validator_set.json
@@ -0,0 +1,55 @@
+[
+ {"constant":false,"inputs":[],"name":"finalizeChange","outputs":[],"payable":false,"type":"function"},
+ {"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"validators","type":"address[]"}],"payable":false,"type":"function"},
+ {"anonymous":false,"inputs":[{"indexed":true,"name":"_parent_hash","type":"bytes32"},{"indexed":false,"name":"_new_set","type":"address[]"}],"name":"InitiateChange","type":"event"},
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "emitInitiateChangeCallable",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [],
+ "name": "emitInitiateChange",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_reportingValidator",
+ "type": "address"
+ },
+ {
+ "name": "_maliciousValidator",
+ "type": "address"
+ },
+ {
+ "name": "_blockNumber",
+ "type": "uint256"
+ }
+ ],
+ "name": "shouldValidatorReport",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ]
\ No newline at end of file
diff --git a/consensus/aura/contracts/withdrawal.json b/consensus/aura/contracts/withdrawal.json
new file mode 100644
index 000000000000..1f706b8d4e5a
--- /dev/null
+++ b/consensus/aura/contracts/withdrawal.json
@@ -0,0 +1,23 @@
+[
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "maxNumberOfFailedWithdrawalsToProcess",
+ "type": "uint256"
+ },
+ {
+ "name": "amounts",
+ "type": "uint64[]"
+ },
+ {
+ "name": "addresses",
+ "type": "address[]"
+ }
+ ],
+ "name": "executeSystemWithdrawals",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/consensus/aura/finality_test.go b/consensus/aura/finality_test.go
new file mode 100644
index 000000000000..e132f658ff46
--- /dev/null
+++ b/consensus/aura/finality_test.go
@@ -0,0 +1,72 @@
+package aura
+
+import (
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestRollingFinality(t *testing.T) {
+ t.Run("RejectsUnknownSigners", func(t *testing.T) {
+ f := NewRollingFinality([]common.Address{{1}, {2}, {3}})
+ _, err := f.push(common.Hash{}, 0, []common.Address{{0}, {4}})
+ assert.Error(t, err)
+ _, err = f.push(common.Hash{}, 0, []common.Address{{0}, {1}, {4}})
+ assert.Error(t, err)
+ })
+ t.Run("FinalizeMultiple", func(t *testing.T) {
+ signers := []common.Address{{0}, {1}, {2}, {3}, {4}, {5}}
+ f := NewRollingFinality(signers)
+ // 3 / 6 signers is < 51% so no finality.
+ for i := 0; i < 6; i++ {
+ l, err := f.push(common.Hash{byte(i)}, uint64(i%3), []common.Address{signers[i%3]})
+ assert.NoError(t, err)
+ assert.Equal(t, 0, len(l))
+ }
+ // after pushing a block signed by a fourth validator, the first four
+ // blocks of the unverified chain become verified.
+ l, err := f.push(common.Hash{byte(6)}, 6, []common.Address{signers[4]})
+ assert.NoError(t, err)
+ for i := uint64(0); i < 4; i++ {
+ assert.Equal(t, common.Hash{byte(i)}, l[i].hash)
+ }
+ assert.Equal(t, 4, len(l))
+ })
+ t.Run("FromAncestry", func(t *testing.T) {
+ signers := []common.Address{{0}, {1}, {2}, {3}, {4}, {5}}
+ f := NewRollingFinality(signers)
+ i := 12
+ get := func(hash common.Hash) ([]common.Address, common.Hash, common.Hash, uint64, bool) {
+ i--
+ if i == -1 {
+ return nil, common.Hash{}, common.Hash{}, 0, false
+ }
+ return []common.Address{signers[i%6]}, common.Hash{byte(i)}, common.Hash{byte(i - 1)}, uint64(i), true
+ }
+ err := f.buildAncestrySubChain(get, common.Hash{11}, common.Hash{99})
+ assert.NoError(t, err)
+ assert.Equal(t, 3, f.headers.l.Len())
+ assert.Equal(t, common.Hash{11}, *f.lastPushed)
+ })
+ t.Run("FromAncestryMultipleSigners", func(t *testing.T) {
+ signers := []common.Address{{0}, {1}, {2}, {3}, {4}, {5}}
+ f := NewRollingFinality(signers)
+ i := 12
+ get := func(hash common.Hash) ([]common.Address, common.Hash, common.Hash, uint64, bool) {
+ i--
+ if i == -1 {
+ return nil, common.Hash{}, common.Hash{}, 0, false
+ }
+ return []common.Address{signers[i%6], signers[(i+1)%6], signers[(i+2)%6]}, common.Hash{byte(i)}, common.Hash{byte(i - 1)}, uint64(i), true
+ }
+ err := f.buildAncestrySubChain(get, common.Hash{11}, common.Hash{99})
+ assert.NoError(t, err)
+
+ // only the last hash has < 51% of authorities' signatures
+ assert.Equal(t, 1, f.headers.l.Len())
+ assert.Equal(t, common.Hash{11}, f.headers.Front().hash)
+ assert.Equal(t, common.Hash{11}, *f.lastPushed)
+ })
+
+}
diff --git a/consensus/aura/gaslimit_override.go b/consensus/aura/gaslimit_override.go
new file mode 100644
index 000000000000..c8f13604f6c1
--- /dev/null
+++ b/consensus/aura/gaslimit_override.go
@@ -0,0 +1,71 @@
+package aura
+
+import (
+ lru "github.com/hashicorp/golang-lru/v2"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus"
+ "github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/params"
+ "github.com/holiman/uint256"
+)
+
+type GasLimitOverride struct {
+ cache *lru.Cache[common.Hash, *uint256.Int]
+}
+
+func NewGasLimitOverride() *GasLimitOverride {
+ // The number of recent block hashes for which the gas limit override is memoized.
+ const GasLimitOverrideCacheCapacity = 10
+
+ cache, err := lru.New[common.Hash, *uint256.Int](GasLimitOverrideCacheCapacity)
+ if err != nil {
+ panic("error creating prefetching cache for blocks")
+ }
+ return &GasLimitOverride{cache: cache}
+}
+
+func (pb *GasLimitOverride) Pop(hash common.Hash) *uint256.Int {
+ if val, ok := pb.cache.Get(hash); ok && val != nil {
+ pb.cache.Remove(hash)
+ return val
+ }
+ return nil
+}
+
+func (pb *GasLimitOverride) Add(hash common.Hash, b *uint256.Int) {
+ if b == nil {
+ return
+ }
+ pb.cache.ContainsOrAdd(hash, b)
+}
+
+func (c *AuRa) HasGasLimitContract() bool {
+ return len(c.cfg.BlockGasLimitContractTransitions) != 0
+}
+
+func (c *AuRa) GetBlockGasLimitFromContract(_ *params.ChainConfig) uint64 {
+ // var blockLimitContract
+ addr, ok := c.cfg.BlockGasLimitContractTransitions[0]
+ if !ok {
+ return 0
+ }
+ gasLimit := callBlockGasLimitAbi(addr, c.Syscall)
+ return gasLimit.Uint64()
+}
+
+func (c *AuRa) verifyGasLimitOverride(config *params.ChainConfig, chain consensus.ChainHeaderReader, header *types.Header, statedb *state.StateDB, syscallCustom Syscall) {
+ // TODO(gballet): take care of that when we reach the merge
+ //IsPoSHeader check is necessary as merge.go calls Initialize on AuRa indiscriminately
+ // gasLimitOverride := c.HasGasLimitContract() && !misc.IsPoSHeader(header)
+ // if gasLimitOverride {
+ blockGasLimit := c.GetBlockGasLimitFromContract(config)
+
+ if blockGasLimit > 0 {
+ if header.GasLimit != blockGasLimit {
+ panic("Block gas limit doesn't match BlockGasLimitContract with AuRa")
+ }
+ }
+ // }
+}
diff --git a/consensus/aura/validators.go b/consensus/aura/validators.go
new file mode 100644
index 000000000000..67cb0c013558
--- /dev/null
+++ b/consensus/aura/validators.go
@@ -0,0 +1,931 @@
+package aura
+
+import (
+ "container/list"
+ "fmt"
+ "sort"
+ "strings"
+ "sync"
+ "sync/atomic"
+
+ lru "github.com/hashicorp/golang-lru/v2"
+
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus/aura/auraabi"
+ "github.com/ethereum/go-ethereum/consensus/aura/aurainterfaces"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/rlp"
+)
+
+// nolint
+type CallResults struct {
+ data []byte
+ proof [][]byte
+ execError string
+}
+
+// Type alias for a function we can make calls through synchronously.
+// Returns the call result and state proof for each call.
+type Call func(common.Address, []byte) (CallResults, error)
+
+// A system-calling closure. Enacts calls on a block's state from the system address.
+type SystemCall func(common.Address, []byte) (CallResults, error)
+
+type client interface {
+ CallAtBlockHash(common.Hash, common.Address, []byte) (CallResults, error)
+ CallAtLatestBlock(common.Address, []byte) (CallResults, error)
+ SystemCallAtBlockHash(blockHash common.Hash, contract common.Address, data []byte) (CallResults, error)
+}
+
+type ValidatorSet interface {
+
+ // Get the default "Call" helper, for use in general operation.
+ // TODO [keorn]: this is a hack intended to migrate off of
+ // a strict dependency on state always being available.
+ defaultCaller(blockHash common.Hash) (Call, error)
+
+ // Called for each new block this node is creating. If this block is
+ // the first block of an epoch, this is called *after* `on_epoch_begin()`,
+ // but with the same parameters.
+ //
+ // Returns a list of contract calls to be pushed onto the new block.
+ //func generateEngineTransactions(_firstInEpoch bool, _header *types.Header, _call SystemCall) -> Result, EthcoreError>
+
+ // Signalling that a new epoch has begun.
+ //
+ // All calls here will be from the `SYSTEM_ADDRESS`: 2^160 - 2
+ // and will have an effect on the block's state.
+ // The caller provided here may not generate proofs.
+ //
+ // `first` is true if this is the first block in the set.
+ onEpochBegin(firstInEpoch bool, header *types.Header, caller Syscall) error
+
+ // Called on the close of every block.
+ onCloseBlock(_header *types.Header, _address common.Address) error
+
+ // Draws a validator nonce modulo number of validators.
+ // getWithCaller(parentHash common.Hash, nonce uint, caller consensus.Call) (common.Address, error)
+ // Returns the current number of validators.
+ // countWithCaller(parentHash common.Hash, caller consensus.Call) (uint64, error)
+
+ // Recover the validator set from the given proof, the block number, and
+ // whether this header is first in its set.
+ //
+ // May fail if the given header doesn't kick off an epoch or
+ // the proof is invalid.
+ //
+ // Returns the set, along with a flag indicating whether finality of a specific
+ // hash should be proven.
+ epochSet(firstInEpoch bool, num uint64, setProof []byte, call Syscall) (SimpleList, common.Hash, error)
+
+ // Extract genesis epoch data from the genesis state and header.
+ genesisEpochData(header *types.Header, call Syscall) ([]byte, error)
+
+ /*
+ // Returns the current number of validators.
+ fn count(&self, parent: &H256) -> usize {
+ let default = self.default_caller(BlockId::Hash(*parent));
+ self.count_with_caller(parent, &*default)
+ }
+
+ // Signalling that a new epoch has begun.
+ //
+ // All calls here will be from the `SYSTEM_ADDRESS`: 2^160 - 2
+ // and will have an effect on the block's state.
+ // The caller provided here may not generate proofs.
+ //
+ // `first` is true if this is the first block in the set.
+ fn on_epoch_begin(
+ &self,
+ _first: bool,
+ _header: &Header,
+ _call: &mut SystemCall,
+ ) -> Result<(), ::error::Error> {
+ Ok(())
+ }
+
+ // Extract genesis epoch data from the genesis state and header.
+ fn genesis_epoch_data(&self, _header: &Header, _call: &Call) -> Result, String> {
+ Ok(Vec::new())
+ }
+ */
+ // Whether this block is the last one in its epoch.
+ //
+ // Indicates that the validator set changed at the given block in a manner
+ // that doesn't require finality.
+ //
+ // `first` is true if this is the first block in the set.
+ signalEpochEnd(firstInEpoch bool, header *types.Header, receipts types.Receipts) ([]byte, error)
+ /*
+ // Whether the given block signals the end of an epoch, but change won't take effect
+ // until finality.
+ //
+ // Engine should set `first` only if the header is genesis. Multiplexing validator
+ // sets can set `first` to internal changes.
+ fn signals_epoch_end(
+ &self,
+ first: bool,
+ header: &Header,
+ aux: AuxiliaryData,
+ ) -> ::engines::EpochChange;
+
+ // Recover the validator set from the given proof, the block number, and
+ // whether this header is first in its set.
+ //
+ // May fail if the given header doesn't kick off an epoch or
+ // the proof is invalid.
+ //
+ // Returns the set, along with a flag indicating whether finality of a specific
+ // hash should be proven.
+ fn epoch_set(
+ &self,
+ first: bool,
+ machine: &EthereumMachine,
+ number: BlockNumber,
+ proof: &[u8],
+ ) -> Result<(SimpleList, Option), ::error::Error>;
+
+ // Checks if a given address is a validator, with the given function
+ // for executing synchronous calls to contracts.
+ fn contains_with_caller(
+ &self,
+ parent_block_hash: &H256,
+ address: &Address,
+ caller: &Call,
+ ) -> bool;
+
+ // Draws an validator nonce modulo number of validators.
+ fn get_with_caller(&self, parent_block_hash: &H256, nonce: usize, caller: &Call) -> Address;
+
+
+ // Notifies about malicious behaviour.
+ fn report_malicious(
+ &self,
+ _validator: &Address,
+ _set_block: BlockNumber,
+ _block: BlockNumber,
+ _proof: Bytes,
+ ) {
+ }
+ // Notifies about benign misbehaviour.
+ fn report_benign(&self, _validator: &Address, _set_block: BlockNumber, _block: BlockNumber) {}
+ */
+}
+
+// func get(s ValidatorSet, h common.Hash, nonce uint, call consensus.Call) (common.Address, error) {
+// //d, err := s.defaultCaller(h)
+// //if err != nil {
+// // return common.Address{}, err
+// //}
+// return s.getWithCaller(h, nonce, call)
+// }
+// func count(s ValidatorSet, h common.Hash, call consensus.Call) (uint64, error) {
+// //d, err := s.defaultCaller(h)
+// //if err != nil {
+// // return 0, err
+// //}
+// return s.countWithCaller(h, call)
+// }
+
+// nolint
+type MultiItem struct {
+ num uint64
+ hash common.Hash
+ set ValidatorSet
+}
+
+type Multi struct {
+ sorted []MultiItem
+ parent func(common.Hash) *types.Header
+}
+
+func (s *Multi) Less(i, j int) bool { return s.sorted[i].num < s.sorted[j].num }
+func (s *Multi) Len() int { return len(s.sorted) }
+func (s *Multi) Swap(i, j int) { s.sorted[i], s.sorted[j] = s.sorted[j], s.sorted[i] }
+
+func NewMulti(m map[uint64]ValidatorSet) *Multi {
+ if _, ok := m[0]; !ok {
+ panic("ValidatorSet has to be specified from block 0")
+ }
+ list := make([]MultiItem, len(m))
+ i := 0
+ for n, v := range m {
+ list[i] = MultiItem{num: n, set: v}
+ i++
+ }
+ multi := &Multi{sorted: list}
+ sort.Sort(multi)
+ return multi
+}
+
+func (s *Multi) defaultCaller(blockHash common.Hash) (Call, error) {
+ set, ok := s.correctSet(blockHash)
+ if !ok {
+ return nil, fmt.Errorf("no validator set for given blockHash: %x", blockHash)
+ }
+ return set.defaultCaller(blockHash)
+}
+
+// func (s *Multi) getWithCaller(parentHash common.Hash, nonce uint, caller consensus.Call) (common.Address, error) {
+// panic("not implemented")
+// }
+// func (s *Multi) countWithCaller(parentHash common.Hash, caller consensus.Call) (uint64, error) {
+// set, ok := s.correctSet(parentHash)
+// if !ok {
+// return math.MaxUint64, nil
+// }
+// return set.countWithCaller(parentHash, caller)
+// }
+
+func (s *Multi) correctSet(blockHash common.Hash) (ValidatorSet, bool) {
+ parent := s.parent(blockHash)
+ if parent == nil {
+ return nil, false
+ }
+ _, set := s.correctSetByNumber(parent.Number.Uint64())
+ return set, set != nil
+}
+
+func (s *Multi) correctSetByNumber(parentNumber uint64) (uint64, ValidatorSet) {
+ // get correct set by block number, along with block number at which
+ // this set was activated.
+ for i := len(s.sorted) - 1; i >= 0; i-- {
+ if s.sorted[i].num <= parentNumber+1 {
+ return s.sorted[i].num, s.sorted[i].set
+ }
+ }
+ panic("constructor validation ensures that there is at least one validator set for block 0; block 0 is less than any uint; qed")
+}
+
+func (s *Multi) get(num uint64) (firstInEpoch bool, set ValidatorSet) {
+ block, set := s.correctSetByNumber(num)
+ firstInEpoch = block == num
+ return firstInEpoch, set
+}
+
+func (s *Multi) onCloseBlock(header *types.Header, address common.Address) error {
+ _, set := s.get(header.Number.Uint64())
+ return set.onCloseBlock(header, address)
+}
+
+// TODO: do we need add `proof` argument?
+// nolint
+func (s *Multi) epochSet(firstInEpoch bool, num uint64, proof []byte, call Syscall) (SimpleList, common.Hash, error) {
+ setBlock, set := s.correctSetByNumber(num)
+ firstInEpoch = setBlock == num
+ return set.epochSet(firstInEpoch, num, proof, call)
+}
+func (s *Multi) genesisEpochData(header *types.Header, call Syscall) ([]byte, error) {
+ _, set := s.correctSetByNumber(0)
+ return set.genesisEpochData(header, call)
+}
+
+func (s *Multi) onEpochBegin(_ bool, header *types.Header, caller Syscall) error {
+ setTransition, set := s.correctSetByNumber(header.Number.Uint64())
+ return set.onEpochBegin(setTransition == header.Number.Uint64(), header, caller)
+}
+func (s *Multi) signalEpochEnd(_ bool, header *types.Header, r types.Receipts) ([]byte, error) {
+ num := header.Number.Uint64()
+ setBlock, set := s.correctSetByNumber(num)
+ first := setBlock == num
+ return set.signalEpochEnd(first, header, r)
+}
+
+type SimpleList struct {
+ validators []common.Address
+}
+
+func (s *SimpleList) epochSet(firstInEpoch bool, num uint64, proof []byte, call Syscall) (SimpleList, common.Hash, error) {
+ return *s, common.Hash{}, nil
+}
+func (s *SimpleList) onEpochBegin(firstInEpoch bool, header *types.Header, caller Syscall) error {
+ return nil
+}
+func (s *SimpleList) onCloseBlock(_header *types.Header, _address common.Address) error {
+ return nil
+}
+func (s *SimpleList) defaultCaller(blockHash common.Hash) (Call, error) {
+ return nil, nil //simple list doesn't require calls
+}
+
+// func (s *SimpleList) getWithCaller(parentHash common.Hash, nonce uint, caller consensus.Call) (common.Address, error) {
+// if len(s.validators) == 0 {
+// return common.Address{}, fmt.Errorf("cannot operate with an empty validator set")
+// }
+// return s.validators[nonce%uint(len(s.validators))], nil
+// }
+//
+// func (s *SimpleList) countWithCaller(parentHash common.Hash, caller consensus.Call) (uint64, error) {
+// return uint64(len(s.validators)), nil
+// }
+func (s *SimpleList) genesisEpochData(header *types.Header, call Syscall) ([]byte, error) {
+ return []byte{}, nil
+}
+
+func (s *SimpleList) signalEpochEnd(_ bool, header *types.Header, r types.Receipts) ([]byte, error) {
+ return nil, nil
+}
+
+// Draws an validator nonce modulo number of validators.
+
+func NewSimpleList(validators []common.Address) *SimpleList {
+ return &SimpleList{validators: validators}
+}
+
+// nolint
+type ReportQueueItem struct {
+ addr common.Address
+ blockNum uint64
+ data []byte
+}
+
+// nolint
+type ReportQueue struct {
+ mu sync.RWMutex
+ list *list.List
+}
+
+// nolint
+func (q *ReportQueue) push(addr common.Address, blockNum uint64, data []byte) {
+ q.mu.Lock()
+ defer q.mu.Unlock()
+ q.list.PushBack(&ReportQueueItem{addr: addr, blockNum: blockNum, data: data})
+}
+
+// Filters reports of validators that have already been reported or are banned.
+// nolint
+func (q *ReportQueue) filter(abi aurainterfaces.ValidatorSetABI, client client, ourAddr, contractAddr common.Address) error {
+ q.mu.Lock()
+ defer q.mu.Unlock()
+ for e := q.list.Front(); e != nil; e = e.Next() {
+ el := e.Value.(*ReportQueueItem)
+ // Check if the validator should be reported.
+ maliciousValidatorAddress := el.addr
+ data, decoder := abi.ShouldValidatorReport(ourAddr, maliciousValidatorAddress, el.blockNum)
+ res, err := client.CallAtLatestBlock(contractAddr, data)
+ if err != nil {
+ return err
+ }
+ if res.execError != "" {
+ log.Warn("Failed to query report status, dropping pending report.", "reason", res.execError)
+ continue
+ }
+ var shouldReport bool
+ err = decoder(res.data, &res)
+ if err != nil {
+ return err
+ }
+ if !shouldReport {
+ q.list.Remove(e)
+ }
+ }
+ return nil
+}
+
+// Removes reports from the queue if it contains more than `MAX_QUEUED_REPORTS` entries.
+// nolint
+func (q *ReportQueue) truncate() {
+ // The maximum number of reports to keep queued.
+ const MaxQueuedReports = 10
+
+ q.mu.RLock()
+ defer q.mu.RUnlock()
+ // Removes reports from the queue if it contains more than `MAX_QUEUED_REPORTS` entries.
+ if q.list.Len() > MaxQueuedReports {
+ log.Warn("Removing reports from report cache, even though it has not been finalized", "amount", q.list.Len()-MaxQueuedReports)
+ }
+ i := 0
+ for e := q.list.Front(); e != nil; e = e.Next() {
+ if i > MaxQueuedReports {
+ q.list.Remove(e)
+ }
+ i++
+ }
+}
+
+// The validator contract should have the following interface:
+// nolint
+type ValidatorSafeContract struct {
+ contractAddress common.Address
+ validators *lru.Cache[common.Hash, *SimpleList] // RwLock>,
+ reportQueue ReportQueue //Mutex,
+ // The block number where we resent the queued reports last time.
+ resentReportsInBlock atomic.Uint64
+ // If set, this is the block number at which the consensus engine switches from AuRa to AuRa
+ // with POSDAO modifications.
+ posdaoTransition *uint64
+
+ abi abi.ABI
+ client client
+}
+
+func NewValidatorSafeContract(contractAddress common.Address, posdaoTransition *uint64, client client) *ValidatorSafeContract {
+ const MemoizeCapacity = 500
+ c, err := lru.New[common.Hash, *SimpleList](MemoizeCapacity)
+ if err != nil {
+ panic("error creating ValidatorSafeContract cache")
+ }
+
+ parsed, err := abi.JSON(strings.NewReader(auraabi.ValidatorSetABI))
+ if err != nil {
+ panic(err)
+ }
+ return &ValidatorSafeContract{contractAddress: contractAddress, posdaoTransition: posdaoTransition, validators: c, abi: parsed}
+}
+
+// Called for each new block this node is creating. If this block is
+// the first block of an epoch, this is called *after* `on_epoch_begin()`,
+// but with the same parameters.
+//
+// Returns a list of contract calls to be pushed onto the new block.
+// func generateEngineTransactions(_firstInEpoch bool, _header *types.Header, _call SystemCall) -> Result, EthcoreError>
+func (s *ValidatorSafeContract) epochSet(firstInEpoch bool, num uint64, setProof []byte, call Syscall) (SimpleList, common.Hash, error) {
+ if firstInEpoch {
+ var proof FirstValidatorSetProof
+ if err := rlp.DecodeBytes(setProof, &proof); err != nil {
+ return SimpleList{}, common.Hash{}, fmt.Errorf("[ValidatorSafeContract.epochSet] %w", err)
+ }
+
+ if num == 0 {
+ return *NewSimpleList([]common.Address{proof.Header.Coinbase}), proof.Header.ParentHash, nil
+ }
+ l, ok := s.getListSyscall(call)
+ if !ok {
+ panic(1)
+ }
+
+ //addresses, err := checkFirstValidatorSetProof(s.contractAddress, oldHeader, state_items)
+ //if err != nil {
+ // panic(err)
+ // return SimpleList{}, common.Hash{}, fmt.Errorf("insufitient proof: block=%d,%x: %w", oldHeader.Number.Uint64(), oldHeader.Hash(), err)
+ //}
+
+ //fmt.Printf("aaaa: %x,%x\n", common.HexToAddress("0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca"), params.SokolGenesisHash)
+ //fmt.Printf("bbbbb: %x,%x\n", proof.ContractAddress, proof.Header.Hash())
+ return *l, proof.Header.ParentHash, nil
+ }
+ var proof ValidatorSetProof
+ if err := rlp.DecodeBytes(setProof, &proof); err != nil {
+ return SimpleList{}, common.Hash{}, fmt.Errorf("[ValidatorSafeContract.epochSet] %w", err)
+ }
+
+ if num > DEBUG_LOG_FROM {
+ fmt.Printf("epoch_set1: %d,%d,%d\n", proof.Header.Number.Uint64(), len(setProof), len(proof.Receipts))
+ }
+ ll, ok := s.extractFromEvent(proof.Header, proof.Receipts)
+ if !ok {
+ panic(1)
+ }
+
+ // ensure receipts match header.
+ // TODO: optimize? these were just decoded.
+ /*
+ let found_root = ::triehash::ordered_trie_root(receipts.iter().map(|r| r.encode()));
+ if found_root != *old_header.receipts_root() {
+ return Err(::error::BlockError::InvalidReceiptsRoot(Mismatch {
+ expected: *old_header.receipts_root(),
+ found: found_root,
+ })
+ .into());
+ }
+
+ let bloom = self.expected_bloom(&old_header);
+
+ match self.extract_from_event(bloom, &old_header, &receipts) {
+ Some(list) => Ok((list, Some(old_header.hash()))),
+ None => Err(::engines::EngineError::InsufficientProof(
+ "No log event in proof.".into(),
+ )
+ .into()),
+ }
+ */
+ return *ll, common.Hash{}, nil
+ /*
+ setProof, err := decodeValidatorSetProof(proof.SetProof)
+ if err != nil {
+ return SimpleList{}, common.Hash{}, err
+ }
+ _ = setProof
+ */
+
+}
+
+// check a first proof: fetch the validator set at the given block.
+// nolint
+func checkFirstValidatorSetProof(contract_address common.Address, oldHeader *types.Header, dbItems [][]byte) ([]common.Address, error) {
+ /*
+ fn check_first_proof(
+ machine: &EthereumMachine,
+ contract_address: Address,
+ old_header: Header,
+ state_items: &[DBValue],
+ ) -> Result, String> {
+ use types::transaction::{Action, Transaction, TypedTransaction};
+
+ // TODO: match client contract_call_tx more cleanly without duplication.
+ const PROVIDED_GAS: u64 = 50_000_000;
+
+ let env_info = ::vm::EnvInfo {
+ number: old_header.number(),
+ author: *old_header.author(),
+ difficulty: *old_header.difficulty(),
+ gas_limit: PROVIDED_GAS.into(),
+ timestamp: old_header.timestamp(),
+ last_hashes: {
+ // this will break if we don't inclue all 256 last hashes.
+ let mut last_hashes: Vec<_> = (0..256).map(|_| H256::default()).collect();
+ last_hashes[255] = *old_header.parent_hash();
+ Arc::new(last_hashes)
+ },
+ gas_used: 0.into(),
+ };
+
+ // check state proof using given machine.
+ let number = old_header.number();
+ let (data, decoder) = validator_set::functions::get_validators::call();
+
+ let from = Address::default();
+ let tx = TypedTransaction::Legacy(Transaction {
+ nonce: machine.account_start_nonce(number),
+ action: Action::Call(contract_address),
+ gas: PROVIDED_GAS.into(),
+ gas_price: U256::default(),
+ value: U256::default(),
+ data,
+ })
+ .fake_sign(from);
+
+ let res = ::state::check_proof(
+ state_items,
+ *old_header.state_root(),
+ &tx,
+ machine,
+ &env_info,
+ );
+
+ match res {
+ ::state::ProvedExecution::BadProof => Err("Bad proof".into()),
+ ::state::ProvedExecution::Failed(e) => Err(format!("Failed call: {}", e)),
+ ::state::ProvedExecution::Complete(e) => {
+ decoder.decode(&e.output).map_err(|e| e.to_string())
+ }
+ }
+ }
+ */
+ return nil, nil
+}
+
+// inter-contract proofs are a header and receipts.
+// checking will involve ensuring that the receipts match the header and
+// extracting the validator set from the receipts.
+// nolint
+func (s *ValidatorSafeContract) defaultCaller(blockHash common.Hash) (Call, error) {
+ return func(addr common.Address, data []byte) (CallResults, error) {
+ return s.client.CallAtBlockHash(blockHash, addr, data)
+ }, nil
+}
+
+// func (s *ValidatorSafeContract) getWithCaller(blockHash common.Hash, nonce uint, caller consensus.Call) (common.Address, error) {
+// set, ok := s.validators.Get(blockHash)
+// if ok {
+// return get(set, blockHash, nonce, caller)
+// }
+
+// list, ok := s.getList(caller)
+// if !ok {
+// return common.Address{}, nil
+// }
+// s.validators.Add(blockHash, list)
+// return get(list, blockHash, nonce, caller)
+// }
+// func (s *ValidatorSafeContract) countWithCaller(parentHash common.Hash, caller consensus.Call) (uint64, error) {
+// set, ok := s.validators.Get(parentHash)
+// if ok {
+// return count(set, parentHash, caller)
+// }
+// list, ok := s.getList(caller)
+// if !ok {
+// return math.MaxUint64, nil
+// }
+// s.validators.Add(parentHash, list)
+// return count(list, parentHash, caller)
+// }
+
+// func (s *ValidatorSafeContract) getList(caller consensus.Call) (*SimpleList, bool) {
+// packed, err := s.abi.Pack("getValidators")
+// if err != nil {
+// panic(err)
+// }
+// out, err := caller(s.contractAddress, packed)
+// if err != nil {
+// panic(err)
+// }
+// res, err := s.abi.Unpack("getValidators", out)
+// if err != nil {
+// panic(err)
+// }
+// out0 := *abi.ConvertType(res[0], new([]common.Address)).(*[]common.Address)
+// return NewSimpleList(out0), true
+// }
+
+func (s *ValidatorSafeContract) getListSyscall(caller Syscall) (*SimpleList, bool) {
+ packed, err := s.abi.Pack("getValidators")
+ if err != nil {
+ panic(err)
+ }
+ out, err := caller(s.contractAddress, packed)
+ if err != nil {
+ panic(err)
+ }
+ res, err := s.abi.Unpack("getValidators", out)
+ if err != nil {
+ panic(err)
+ }
+ out0 := *abi.ConvertType(res[0], new([]common.Address)).(*[]common.Address)
+ return NewSimpleList(out0), true
+}
+
+func (s *ValidatorSafeContract) genesisEpochData(header *types.Header, call Syscall) ([]byte, error) {
+ return proveInitial(s, s.contractAddress, header, call)
+}
+
+func (s *ValidatorSafeContract) onEpochBegin(firstInEpoch bool, header *types.Header, caller Syscall) error {
+ data := common.FromHex("75286211") // s.abi.Pack("finalizeChange")
+ _, err := caller(s.contractAddress, data)
+ if err != nil {
+ return err
+ }
+
+ /*
+ let data = validator_set::functions::finalize_change::encode_input();
+ caller(self.contract_address, data)
+ .map(|_| ())
+ .map_err(::engines::EngineError::FailedSystemCall)
+ .map_err(Into::into)
+ */
+ return nil
+}
+
+func (s *ValidatorSafeContract) signalEpochEnd(firstInEpoch bool, header *types.Header, r types.Receipts) ([]byte, error) {
+ // transition to the first block of a contract requires finality but has no log event.
+ if firstInEpoch {
+ /*
+ let state_proof = Arc::new(FirstValidatorSetProof {
+ contract_address: self.contract_address,
+ header: header.clone(),
+ });
+ return ::engines::EpochChange::Yes(::engines::Proof::WithState(state_proof as Arc<_>));
+ */
+ return rlp.EncodeToBytes(FirstValidatorSetProof{Header: header, ContractAddress: s.contractAddress})
+ }
+
+ // otherwise, we're checking for logs.
+ //let bloom = self.expected_bloom(header);
+ //let header_bloom = header.log_bloom();
+ //if &bloom & header_bloom != bloom {
+ // return ::engines::EpochChange::No;
+ //}
+
+ _, ok := s.extractFromEvent(header, r)
+ if !ok {
+ return nil, nil
+ }
+ proof, err := rlp.EncodeToBytes(ValidatorSetProof{Header: header, Receipts: r})
+ if err != nil {
+ return nil, err
+ }
+ if header.Number.Uint64() >= DEBUG_LOG_FROM {
+ fmt.Printf("signalEpochEnd: %d,%d, proofLen=%d\n", header.Number.Uint64(), len(r), len(proof))
+ }
+ return proof, nil
+}
+
+func (s *ValidatorSafeContract) extractFromEvent(header *types.Header, receipts types.Receipts) (*SimpleList, bool) {
+ if len(receipts) == 0 {
+ if header.Number.Uint64() >= DEBUG_LOG_FROM {
+ fmt.Printf("extractFromEvent1: %d\n", header.Number.Uint64())
+ }
+ return nil, false
+ }
+ if header.Number.Uint64() >= DEBUG_LOG_FROM {
+ fmt.Printf("extractFromEvent111: %d,%d\n", header.Number.Uint64(), len(receipts))
+ }
+
+ // iterate in reverse because only the _last_ change in a given
+ // block actually has any effect.
+ // the contract should only increment the nonce once.
+ for j := len(receipts) - 1; j >= 0; j-- {
+ logs := receipts[j].Logs
+ /*
+ TODO: skipped next bloom check (is it required?)
+ expectedBloom := expected_bloom(&self, header: &Header) -> Bloom {
+ let topics = vec![*EVENT_NAME_HASH, *header.parent_hash()];
+
+ debug!(target: "engine", "Expected topics for header {}: {:?}",
+ header.hash(), topics);
+
+ LogEntry {
+ address: self.contract_address,
+ topics: topics,
+ data: Vec::new(), // irrelevant for bloom.
+ }
+ .bloom()
+ }
+ if !r.log_bloom.contains_bloom(&bloom){
+ continue
+ }
+ */
+ for i := 0; i < len(logs); i++ {
+ l := logs[i]
+ if header.Number.Uint64() >= DEBUG_LOG_FROM {
+ fmt.Printf("extractFromEvent3: %d\n", header.Number.Uint64())
+ }
+ if len(l.Topics) != 2 {
+ continue
+ }
+ found := l.Address == s.contractAddress && l.Topics[0] == EVENT_NAME_HASH && l.Topics[1] == header.ParentHash
+ if !found {
+ if header.Number.Uint64() >= DEBUG_LOG_FROM {
+ fmt.Printf("extractFromEvent4: %d\n", header.Number.Uint64())
+ }
+ continue
+ }
+
+ contract := bind.NewBoundContract(l.Address, s.abi, nil, nil, nil)
+ event := new(auraabi.ValidatorSetInitiateChange)
+ if err := contract.UnpackLog(event, "InitiateChange", *l); err != nil {
+ panic(err)
+ }
+ if header.Number.Uint64() >= DEBUG_LOG_FROM {
+ fmt.Printf("extractFromEvent5: %d\n", header.Number.Uint64())
+ }
+
+ // only one last log is taken into account
+ return NewSimpleList(event.NewSet), true
+ }
+ }
+ /*
+ let check_log = |log: &LogEntry| {
+ log.address == self.contract_address
+ && log.topics.len() == 2
+ && log.topics[0] == *EVENT_NAME_HASH
+ && log.topics[1] == *header.parent_hash()
+ };
+
+ //// iterate in reverse because only the _last_ change in a given
+ //// block actually has any effect.
+ //// the contract should only increment the nonce once.
+ let mut decoded_events = receipts
+ .iter()
+ .rev()
+ .filter(|r| r.log_bloom.contains_bloom(&bloom))
+ .flat_map(|r| r.logs.iter())
+ .filter(move |l| check_log(l))
+ .filter_map(|log| {
+ validator_set::events::initiate_change::parse_log(
+ (log.topics.clone(), log.data.clone()).into(),
+ )
+ .ok()
+ });
+
+ // only last log is taken into account
+ decoded_events.next().map(|matched_event| {
+ let l = SimpleList::new(matched_event.new_set);
+ println!("matched_event: {:?}", l);
+ l
+ })
+ */
+ return nil, false
+}
+
+const EVENT_NAME = "InitiateChange(bytes32,address[])"
+
+var EVENT_NAME_HASH = crypto.Keccak256Hash([]byte(EVENT_NAME))
+
+func (s *ValidatorSafeContract) onCloseBlock(header *types.Header, ourAddress common.Address) error {
+ // Skip the rest of the function unless there has been a transition to POSDAO AuRa.
+ if s.posdaoTransition != nil && header.Number.Uint64() < *s.posdaoTransition {
+ log.Trace("Skipping resending of queued malicious behavior reports")
+ return nil
+ }
+ /*
+ err := s.reportQueue.filter(s.abi, s.client, ourAddress, s.contractAddress)
+ if err != nil {
+ return err
+ }
+ s.reportQueue.truncate()
+ */
+
+ /*
+ let mut resent_reports_in_block = self.resent_reports_in_block.lock();
+
+ // Skip at least one block after sending malicious reports last time.
+ if header.number() > *resent_reports_in_block + REPORTS_SKIP_BLOCKS {
+ *resent_reports_in_block = header.number();
+ let mut nonce = client.latest_nonce(our_address);
+ for (address, block, data) in report_queue.iter() {
+ debug!(target: "engine", "Retrying to report validator {} for misbehavior on block {} with nonce {}.",
+ address, block, nonce);
+ while match self.transact(data.clone(), nonce) {
+ Ok(()) => false,
+ Err(EthcoreError(
+ EthcoreErrorKind::Transaction(transaction::Error::Old),
+ _,
+ )) => true,
+ Err(err) => {
+ warn!(target: "engine", "Cannot report validator {} for misbehavior on block {}: {}",
+ address, block, err);
+ false
+ }
+ } {
+ warn!(target: "engine", "Nonce {} already used. Incrementing.", nonce);
+ nonce += U256::from(1);
+ }
+ nonce += U256::from(1);
+ }
+ }
+
+ Ok(())
+
+ */
+ return nil
+}
+
+// ValidatorContract a validator contract with reporting.
+type ValidatorContract struct {
+ contractAddress common.Address
+ validators *ValidatorSafeContract
+ posdaoTransition *uint64
+}
+
+func (s *ValidatorContract) epochSet(firstInEpoch bool, num uint64, proof []byte, call Syscall) (SimpleList, common.Hash, error) {
+ return s.validators.epochSet(firstInEpoch, num, proof, call)
+}
+func (s *ValidatorContract) defaultCaller(blockHash common.Hash) (Call, error) {
+ return s.validators.defaultCaller(blockHash)
+}
+
+// func (s *ValidatorContract) getWithCaller(parentHash common.Hash, nonce uint, caller consensus.Call) (common.Address, error) {
+// return s.validators.getWithCaller(parentHash, nonce, caller)
+// }
+//
+// func (s *ValidatorContract) countWithCaller(parentHash common.Hash, caller consensus.Call) (uint64, error) {
+// return s.validators.countWithCaller(parentHash, caller)
+// }
+func (s *ValidatorContract) onEpochBegin(firstInEpoch bool, header *types.Header, caller Syscall) error {
+ return s.validators.onEpochBegin(firstInEpoch, header, caller)
+}
+func (s *ValidatorContract) onCloseBlock(header *types.Header, address common.Address) error {
+ return s.validators.onCloseBlock(header, address)
+}
+func (s *ValidatorContract) genesisEpochData(header *types.Header, call Syscall) ([]byte, error) {
+ return s.validators.genesisEpochData(header, call)
+}
+func (s *ValidatorContract) signalEpochEnd(firstInEpoch bool, header *types.Header, r types.Receipts) ([]byte, error) {
+ return s.validators.signalEpochEnd(firstInEpoch, header, r)
+}
+
+func proveInitial(s *ValidatorSafeContract, contractAddr common.Address, header *types.Header, caller Syscall) ([]byte, error) {
+ return rlp.EncodeToBytes(FirstValidatorSetProof{Header: header, ContractAddress: s.contractAddress})
+ //list, err := s.getList(caller)
+ //fmt.Printf("aaa: %x,%t\n", list, err)
+
+ //return common.FromHex("0xf91a84f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f91871b914c26060604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303aca79214610101578063108552691461016457806340a141ff1461019d57806340c9cdeb146101d65780634110a489146101ff57806345199e0a1461025757806349285b58146102c15780634d238c8e14610316578063752862111461034f578063900eb5a8146103645780639a573786146103c7578063a26a47d21461041c578063ae4b1b5b14610449578063b3f05b971461049e578063b7ab4db5146104cb578063d3e848f114610535578063fa81b2001461058a578063facd743b146105df575b600080fd5b341561010c57600080fd5b6101226004808035906020019091905050610630565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016f57600080fd5b61019b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b005b34156101a857600080fd5b6101d4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610807565b005b34156101e157600080fd5b6101e9610bb7565b6040518082815260200191505060405180910390f35b341561020a57600080fd5b610236600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bbd565b60405180831515151581526020018281526020019250505060405180910390f35b341561026257600080fd5b61026a610bee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ad578082015181840152602081019050610292565b505050509050019250505060405180910390f35b34156102cc57600080fd5b6102d4610c82565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032157600080fd5b61034d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d32565b005b341561035a57600080fd5b610362610fcc565b005b341561036f57600080fd5b61038560048080359060200190919050506110fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103d257600080fd5b6103da61113b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561042757600080fd5b61042f6111eb565b604051808215151515815260200191505060405180910390f35b341561045457600080fd5b61045c6111fe565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a957600080fd5b6104b1611224565b604051808215151515815260200191505060405180910390f35b34156104d657600080fd5b6104de611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610521578082015181840152602081019050610506565b505050509050019250505060405180910390f35b341561054057600080fd5b6105486112cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059557600080fd5b61059d6112f1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105ea57600080fd5b610616600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611317565b604051808215151515815260200191505060405180910390f35b60078181548110151561063f57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106cb57600080fd5b600460019054906101000a900460ff161515156106e757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561072357600080fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460016101000a81548160ff0219169083151502179055507f600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600061081461113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561084d57600080fd5b83600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615156108a957600080fd5b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549350600160078054905003925060078381548110151561090857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508160078581548110151561094657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506007838154811015156109e557fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600780549050111515610a2757600080fd5b6007805480919060019003610a3c9190611370565b506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610ba257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b58575b50509250505060405180910390a25050505050565b60085481565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b610bf661139c565b6007805480602002602001604051908101604052809291908181526020018280548015610c7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c2e575b5050505050905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349285b586000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610d1257600080fd5b6102c65a03f11515610d2357600080fd5b50505060405180519050905090565b610d3a61113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b80600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151515610dd057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e0c57600080fd5b6040805190810160405280600115158152602001600780549050815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015590505060078054806001018281610ea991906113b0565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610fba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610f70575b50509250505060405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156110365750600460009054906101000a900460ff16155b151561104157600080fd5b6001600460006101000a81548160ff0219169083151502179055506007600690805461106e9291906113dc565b506006805490506008819055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536110a4611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156110e75780820151818401526020810190506110cc565b505050509050019250505060405180910390a1565b60068181548110151561110b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639a5737866000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156111cb57600080fd5b6102c65a03f115156111dc57600080fd5b50505060405180519050905090565b600460019054906101000a900460ff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900460ff1681565b61123f61139c565b60068054806020026020016040519081016040528092919081815260200182805480156112c157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611277575b5050505050905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b81548183558181151161139757818360005260206000209182019101611396919061142e565b5b505050565b602060405190810160405280600081525090565b8154818355818115116113d7578183600052602060002091820191016113d6919061142e565b5b505050565b82805482825590600052602060002090810192821561141d5760005260206000209182015b8281111561141c578254825591600101919060010190611401565b5b50905061142a9190611453565b5090565b61145091905b8082111561144c576000816000905550600101611434565b5090565b90565b61149391905b8082111561148f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101611459565b5090565b905600a165627a7a7230582036ea35935c8246b68074adece2eab70c40e69a0193c08a6277ce06e5b25188510029b8f3f8f1a08023c0d95fc2364e0bf7593f5ff32e1db8ef9f4b41c0bd474eae62d1af896e99808080a0b47b4f0b3e73b5edc8f9a9da1cbcfed562eb06bf54619b6aefeadebf5b3604c280a0da6ec08940a924cb08c947dd56cdb40076b29a6f0ea4dba4e2d02d9a9a72431b80a030cc4138c9e74b6cf79d624b4b5612c0fd888e91f55316cfee7d1694e1a90c0b80a0c5d54b915b56a888eee4e6eeb3141e778f9b674d1d322962eed900f02c29990aa017256b36ef47f907c6b1378a2636942ce894c17075e56fc054d4283f6846659e808080a03340bbaeafcda3a8672eb83099231dbbfab8dae02a1e8ec2f7180538fac207e080b86bf869a033aa5d69545785694b808840be50c182dad2ec3636dfccbe6572fb69828742c0b846f8440101a0663ce0d171e545a26aa67e4ca66f72ba96bb48287dbcc03beea282867f80d44ba01f0e7726926cb43c03a0abf48197dba78522ec8ba1b158e2aa30da7d2a2c6f9eb838f7a03868bdfa8727775661e4ccf117824a175a33f8703d728c04488fbfffcafda9f99594e8ddc5c7a2d2f0d7a9798459c0104fdf5e987acaa3e2a02052222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01b853f851808080a07bb75cabebdcbd1dbb4331054636d0c6d7a2b08483b9e04df057395a7434c9e080808080808080a0e61e567237b49c44d8f906ceea49027260b4010c10a547b38d8b131b9d3b6f848080808080b8d3f8d1a0dc277c93a9f9dcee99aac9b8ba3cfa4c51821998522469c37715644e8fbac0bfa0ab8cdb808c8303bb61fb48e276217be9770fa83ecf3f90f2234d558885f5abf1808080a0fe137c3a474fbde41d89a59dd76da4c55bf696b86d3af64a55632f76cf30786780808080a06301b39b2ea8a44df8b0356120db64b788e71f52e1d7a6309d0d2e5b86fee7cb80a0da5d8b08dea0c5a4799c0f44d8a24d7cdf209f9b7a5588c1ecafb5361f6b9f07a01b7779e149cadf24d4ffb77ca7e11314b8db7097e4d70b2a173493153ca2e5a0808080b853f851808080a0a87d9bb950836582673aa0eecc0ff64aac607870637a2dd2012b8b1b31981f698080a08da6d5c36a404670c553a2c9052df7cd604f04e3863c4c7b9e0027bfd54206d680808080808080808080b86bf869a02080c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312ab846f8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), nil
+ //return common.FromHex("0xf91a84f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f91871b8d3f8d1a0dc277c93a9f9dcee99aac9b8ba3cfa4c51821998522469c37715644e8fbac0bfa0ab8cdb808c8303bb61fb48e276217be9770fa83ecf3f90f2234d558885f5abf1808080a0fe137c3a474fbde41d89a59dd76da4c55bf696b86d3af64a55632f76cf30786780808080a06301b39b2ea8a44df8b0356120db64b788e71f52e1d7a6309d0d2e5b86fee7cb80a0da5d8b08dea0c5a4799c0f44d8a24d7cdf209f9b7a5588c1ecafb5361f6b9f07a01b7779e149cadf24d4ffb77ca7e11314b8db7097e4d70b2a173493153ca2e5a0808080b8f3f8f1a08023c0d95fc2364e0bf7593f5ff32e1db8ef9f4b41c0bd474eae62d1af896e99808080a0b47b4f0b3e73b5edc8f9a9da1cbcfed562eb06bf54619b6aefeadebf5b3604c280a0da6ec08940a924cb08c947dd56cdb40076b29a6f0ea4dba4e2d02d9a9a72431b80a030cc4138c9e74b6cf79d624b4b5612c0fd888e91f55316cfee7d1694e1a90c0b80a0c5d54b915b56a888eee4e6eeb3141e778f9b674d1d322962eed900f02c29990aa017256b36ef47f907c6b1378a2636942ce894c17075e56fc054d4283f6846659e808080a03340bbaeafcda3a8672eb83099231dbbfab8dae02a1e8ec2f7180538fac207e080b838f7a03868bdfa8727775661e4ccf117824a175a33f8703d728c04488fbfffcafda9f99594e8ddc5c7a2d2f0d7a9798459c0104fdf5e987acaa3e2a02052222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01b853f851808080a0a87d9bb950836582673aa0eecc0ff64aac607870637a2dd2012b8b1b31981f698080a08da6d5c36a404670c553a2c9052df7cd604f04e3863c4c7b9e0027bfd54206d680808080808080808080b86bf869a033aa5d69545785694b808840be50c182dad2ec3636dfccbe6572fb69828742c0b846f8440101a0663ce0d171e545a26aa67e4ca66f72ba96bb48287dbcc03beea282867f80d44ba01f0e7726926cb43c03a0abf48197dba78522ec8ba1b158e2aa30da7d2a2c6f9eb86bf869a02080c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312ab846f8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470b853f851808080a07bb75cabebdcbd1dbb4331054636d0c6d7a2b08483b9e04df057395a7434c9e080808080808080a0e61e567237b49c44d8f906ceea49027260b4010c10a547b38d8b131b9d3b6f848080808080b914c26060604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303aca79214610101578063108552691461016457806340a141ff1461019d57806340c9cdeb146101d65780634110a489146101ff57806345199e0a1461025757806349285b58146102c15780634d238c8e14610316578063752862111461034f578063900eb5a8146103645780639a573786146103c7578063a26a47d21461041c578063ae4b1b5b14610449578063b3f05b971461049e578063b7ab4db5146104cb578063d3e848f114610535578063fa81b2001461058a578063facd743b146105df575b600080fd5b341561010c57600080fd5b6101226004808035906020019091905050610630565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016f57600080fd5b61019b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b005b34156101a857600080fd5b6101d4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610807565b005b34156101e157600080fd5b6101e9610bb7565b6040518082815260200191505060405180910390f35b341561020a57600080fd5b610236600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bbd565b60405180831515151581526020018281526020019250505060405180910390f35b341561026257600080fd5b61026a610bee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ad578082015181840152602081019050610292565b505050509050019250505060405180910390f35b34156102cc57600080fd5b6102d4610c82565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032157600080fd5b61034d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d32565b005b341561035a57600080fd5b610362610fcc565b005b341561036f57600080fd5b61038560048080359060200190919050506110fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103d257600080fd5b6103da61113b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561042757600080fd5b61042f6111eb565b604051808215151515815260200191505060405180910390f35b341561045457600080fd5b61045c6111fe565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a957600080fd5b6104b1611224565b604051808215151515815260200191505060405180910390f35b34156104d657600080fd5b6104de611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610521578082015181840152602081019050610506565b505050509050019250505060405180910390f35b341561054057600080fd5b6105486112cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059557600080fd5b61059d6112f1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105ea57600080fd5b610616600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611317565b604051808215151515815260200191505060405180910390f35b60078181548110151561063f57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106cb57600080fd5b600460019054906101000a900460ff161515156106e757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561072357600080fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460016101000a81548160ff0219169083151502179055507f600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600061081461113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561084d57600080fd5b83600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615156108a957600080fd5b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549350600160078054905003925060078381548110151561090857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508160078581548110151561094657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506007838154811015156109e557fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600780549050111515610a2757600080fd5b6007805480919060019003610a3c9190611370565b506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610ba257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b58575b50509250505060405180910390a25050505050565b60085481565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b610bf661139c565b6007805480602002602001604051908101604052809291908181526020018280548015610c7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c2e575b5050505050905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349285b586000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610d1257600080fd5b6102c65a03f11515610d2357600080fd5b50505060405180519050905090565b610d3a61113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b80600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151515610dd057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e0c57600080fd5b6040805190810160405280600115158152602001600780549050815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015590505060078054806001018281610ea991906113b0565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610fba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610f70575b50509250505060405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156110365750600460009054906101000a900460ff16155b151561104157600080fd5b6001600460006101000a81548160ff0219169083151502179055506007600690805461106e9291906113dc565b506006805490506008819055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536110a4611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156110e75780820151818401526020810190506110cc565b505050509050019250505060405180910390a1565b60068181548110151561110b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639a5737866000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156111cb57600080fd5b6102c65a03f115156111dc57600080fd5b50505060405180519050905090565b600460019054906101000a900460ff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900460ff1681565b61123f61139c565b60068054806020026020016040519081016040528092919081815260200182805480156112c157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611277575b5050505050905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b81548183558181151161139757818360005260206000209182019101611396919061142e565b5b505050565b602060405190810160405280600081525090565b8154818355818115116113d7578183600052602060002091820191016113d6919061142e565b5b505050565b82805482825590600052602060002090810192821561141d5760005260206000209182015b8281111561141c578254825591600101919060010190611401565b5b50905061142a9190611453565b5090565b61145091905b8082111561144c576000816000905550600101611434565b5090565b90565b61149391905b8082111561148f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101611459565b5090565b905600a165627a7a7230582036ea35935c8246b68074adece2eab70c40e69a0193c08a6277ce06e5b25188510029"), nil
+ /*
+
+ // given a provider and caller, generate proof. this will just be a state proof
+ // of `getValidators`.
+ fn prove_initial(
+ contract_address: Address,
+ header: &Header,
+ caller: &Call,
+ ) -> Result, String> {
+ use std::cell::RefCell;
+
+ let epoch_proof = RefCell::new(None);
+ let validators = {
+ let (data, decoder) = validator_set::functions::get_validators::call();
+ let (value, proof) = caller(contract_address, data)?;
+ *epoch_proof.borrow_mut() = Some(encode_first_proof(header, &proof));
+ decoder.decode(&value).map_err(|e| e.to_string())?
+ };
+
+ let proof = epoch_proof
+ .into_inner()
+ .expect("epoch_proof always set after call; qed");
+
+ trace!(target: "engine", "obtained proof for initial set: {} validators, {} bytes",
+ validators.len(), proof.len());
+
+ info!(target: "engine", "Signal for switch to contract-based validator set.");
+ info!(target: "engine", "Initial contract validators: {:?}", validators);
+
+ Ok(proof)
+ }
+ */
+}
diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go
index e856f4e6cead..46fb194dc9b8 100644
--- a/consensus/beacon/consensus.go
+++ b/consensus/beacon/consensus.go
@@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
+ "github.com/ethereum/go-ethereum/consensus/aura"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/state"
@@ -333,31 +334,38 @@ func (beacon *Beacon) verifyHeaders(chain consensus.ChainHeaderReader, headers [
// Prepare implements consensus.Engine, initializing the difficulty field of a
// header to conform to the beacon protocol. The changes are done inline.
-func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
+func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header, statedb *state.StateDB) error {
// Transition isn't triggered yet, use the legacy rules for preparation.
reached, err := IsTTDReached(chain, header.ParentHash, header.Number.Uint64()-1)
if err != nil {
return err
}
if !reached {
- return beacon.ethone.Prepare(chain, header)
+ return beacon.ethone.Prepare(chain, header, statedb)
}
header.Difficulty = beaconDifficulty
return nil
}
// Finalize implements consensus.Engine and processes withdrawals on top.
-func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) {
+func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal, receipts []*types.Receipt) {
if !beacon.IsPoSHeader(header) {
- beacon.ethone.Finalize(chain, header, state, txs, uncles, nil)
- return
+ beacon.ethone.Finalize(chain, header, state, txs, uncles, nil, receipts)
+ } else if a, ok := beacon.ethone.(*aura.AuRa); ok {
+ // GNOSIS: if the network has merged and this was an ex-AuRa
+ // network, still call the reward contract.
+ if err := a.ApplyRewards(header, state); err != nil {
+ panic(fmt.Sprintf("error applying reward %v", err))
+ }
}
+
// Withdrawals processing.
- for _, w := range withdrawals {
- // Convert amount from gwei to wei.
- amount := new(big.Int).SetUint64(w.Amount)
- amount = amount.Mul(amount, big.NewInt(params.GWei))
- state.AddBalance(w.Address, amount)
+ if withdrawals != nil {
+ if auraEngine, ok := beacon.ethone.(*aura.AuRa); ok {
+ if err := auraEngine.ExecuteSystemWithdrawals(withdrawals); err != nil {
+ panic(err)
+ }
+ }
}
// No block reward which is issued by consensus layer instead.
}
@@ -380,7 +388,7 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
}
}
// Finalize and assemble the block.
- beacon.Finalize(chain, header, state, txs, uncles, withdrawals)
+ beacon.Finalize(chain, header, state, txs, uncles, withdrawals, receipts)
// Assign the final state root to header.
header.Root = state.IntermediateRoot(true)
@@ -435,10 +443,11 @@ func (beacon *Beacon) Close() error {
// This function is not suitable for a part of APIs like Prepare or CalcDifficulty
// because the header difficulty is not set yet.
func (beacon *Beacon) IsPoSHeader(header *types.Header) bool {
- if header.Difficulty == nil {
- panic("IsPoSHeader called with invalid difficulty")
- }
- return header.Difficulty.Cmp(beaconDifficulty) == 0
+ // return header.Difficulty.Cmp(beaconDifficulty) == 0
+ // return header.Number.Cmp(big.NewInt())
+ // non-uint64 block numbers are 2,92271023×10¹² years in
+ // the future, but better be ready.
+ return !header.Number.IsInt64() || header.Number.Uint64() >= params.GnosisForkBlock
}
// InnerEngine returns the embedded eth1 consensus engine.
@@ -470,3 +479,13 @@ func IsTTDReached(chain consensus.ChainHeaderReader, parentHash common.Hash, par
}
return td.Cmp(chain.Config().TerminalTotalDifficulty) >= 0, nil
}
+
+func (beacon *Beacon) SetAuraSyscall(sc aura.Syscall) {
+ if a, ok := beacon.ethone.(*aura.AuRa); ok {
+ a.Syscall = sc
+ }
+}
+
+func (beacon *Beacon) AuraPrepare(chain consensus.ChainHeaderReader, header *types.Header, statedb *state.StateDB) {
+ beacon.ethone.Prepare(chain, header, statedb)
+}
diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go
index c693189ea5ef..6590424e6924 100644
--- a/consensus/clique/clique.go
+++ b/consensus/clique/clique.go
@@ -512,7 +512,7 @@ func (c *Clique) verifySeal(snap *Snapshot, header *types.Header, parents []*typ
// Prepare implements consensus.Engine, preparing all the consensus fields of the
// header for running the transactions on top.
-func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
+func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header, _ *state.StateDB) error {
// If the block isn't a checkpoint, cast a random vote (good enough for now)
header.Coinbase = common.Address{}
header.Nonce = types.BlockNonce{}
@@ -580,7 +580,7 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header
// Finalize implements consensus.Engine. There is no post-transaction
// consensus rules in clique, do nothing here.
-func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) {
+func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal, _ []*types.Receipt) {
// No block rewards in PoA, so the state remains as is
}
@@ -591,7 +591,7 @@ func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
return nil, errors.New("clique does not support withdrawals")
}
// Finalize block
- c.Finalize(chain, header, state, txs, uncles, nil)
+ c.Finalize(chain, header, state, txs, uncles, nil, receipts)
// Assign the final state root to header.
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
diff --git a/consensus/consensus.go b/consensus/consensus.go
index 3a2c2d222916..391fdab4fdf2 100644
--- a/consensus/consensus.go
+++ b/consensus/consensus.go
@@ -81,7 +81,7 @@ type Engine interface {
// Prepare initializes the consensus fields of a block header according to the
// rules of a particular engine. The changes are executed inline.
- Prepare(chain ChainHeaderReader, header *types.Header) error
+ Prepare(chain ChainHeaderReader, header *types.Header, state *state.StateDB) error
// Finalize runs any post-transaction state modifications (e.g. block rewards
// or process withdrawals) but does not assemble the block.
@@ -89,7 +89,7 @@ type Engine interface {
// Note: The state database might be updated to reflect any consensus rules
// that happen at finalization (e.g. block rewards).
Finalize(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
- uncles []*types.Header, withdrawals []*types.Withdrawal)
+ uncles []*types.Header, withdrawals []*types.Withdrawal, receipts []*types.Receipt)
// FinalizeAndAssemble runs any post-transaction state modifications (e.g. block
// rewards or process withdrawals) and assembles the final block.
@@ -127,3 +127,25 @@ type PoW interface {
// Hashrate returns the current mining hashrate of a PoW consensus engine.
Hashrate() float64
}
+
+// RewardKind - The kind of block reward.
+// Depending on the consensus engine the allocated block reward might have
+// different semantics which could lead e.g. to different reward values.
+type RewardKind uint16
+
+const (
+ // RewardAuthor - attributed to the block author.
+ RewardAuthor RewardKind = 0
+ // RewardEmptyStep - attributed to the author(s) of empty step(s) included in the block (AuthorityRound engine).
+ RewardEmptyStep RewardKind = 1
+ // RewardExternal - attributed by an external protocol (e.g. block reward contract).
+ RewardExternal RewardKind = 2
+ // RewardUncle - attributed to the block uncle(s) with given difference.
+ RewardUncle RewardKind = 3
+)
+
+type Reward struct {
+ Beneficiary common.Address
+ Kind RewardKind
+ Amount big.Int
+}
diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go
index 130dfdf213bf..d32e170805f1 100644
--- a/consensus/ethash/consensus.go
+++ b/consensus/ethash/consensus.go
@@ -490,7 +490,7 @@ var DynamicDifficultyCalculator = makeDifficultyCalculator
// 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.ChainHeaderReader, header *types.Header) error {
+func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.Header, _ *state.StateDB) error {
parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
if parent == nil {
return consensus.ErrUnknownAncestor
@@ -500,7 +500,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H
}
// Finalize implements consensus.Engine, accumulating the block and uncle rewards.
-func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal) {
+func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, withdrawals []*types.Withdrawal, _ []*types.Receipt) {
// Accumulate any block and uncle rewards
accumulateRewards(chain.Config(), state, header, uncles)
}
@@ -512,7 +512,7 @@ func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
return nil, errors.New("ethash does not support withdrawals")
}
// Finalize block
- ethash.Finalize(chain, header, state, txs, uncles, nil)
+ ethash.Finalize(chain, header, state, txs, uncles, nil, receipts)
// Assign the final state root to header.
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
diff --git a/core/allocs/chiado.json b/core/allocs/chiado.json
new file mode 100644
index 000000000000..a332c3a8b6d4
--- /dev/null
+++ b/core/allocs/chiado.json
@@ -0,0 +1,88 @@
+{
+ "0x0000000000000000000000000000000000000001": {
+ "balance": "0x1"
+ },
+ "0x0000000000000000000000000000000000000002": {
+ "balance": "0x1"
+ },
+ "0x0000000000000000000000000000000000000003": {
+ "balance": "0x1"
+ },
+ "0x0000000000000000000000000000000000000004": {
+ "balance": "0x1"
+ },
+ "0xB03a86b3126157C039b55E21D378587CcFc04d45": {
+ "balance": "0xc9f2c9cd04674edea40000000"
+ },
+ "0xcC4e00A72d871D6c328BcFE9025AD93d0a26dF51": {
+ "balance": "0xc9f2c9cd04674edea40000000"
+ },
+ "0x1000000000000000000000000000000000000001": {
+ "balance": "0x0",
+ "constructor": "0x60806040526040516108053803806108058339818101604052604081101561002657600080fd5b50805160209182015160408051600081529384018082527f656970313936372e70726f78792e696d706c656d656e746174696f6e00000000905251603c81850301902091929091839190600019016000805160206107aa8339815191521461008a57fe5b61009c826001600160e01b036101bd16565b805115610154576000826001600160a01b0316826040518082805190602001908083835b602083106100df5780518252601f1990920191602091820191016100c0565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461013f576040519150601f19603f3d011682016040523d82523d6000602084013e610144565b606091505b505090508061015257600080fd5b505b5050604080517f656970313936372e70726f78792e61646d696e000000000000000000000000008152905190819003601301902060008051602061078a833981519152600019909101146101a457fe5b6101b6816001600160e01b0361023716565b505061024f565b6101d08161024960201b6104801760201c565b610225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806107ca603b913960400191505060405180910390fd5b6000805160206107aa83398151915255565b60008051602061078a83398151915255565b3b151590565b61052c8061025e6000396000f3fe60806040526004361061004a5760003560e01c80633659cfe6146100545780634f1ef286146100875780635c60da1b146101075780638f28397014610138578063f851a4401461016b575b610052610180565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661019a565b6100526004803603604081101561009d57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100c857600080fd5b8201836020820111156100da57600080fd5b803590602001918460018302840111640100000000831117156100fc57600080fd5b5090925090506101cb565b34801561011357600080fd5b5061011c61026f565b604080516001600160a01b039092168252519081900360200190f35b34801561014457600080fd5b506100526004803603602081101561015b57600080fd5b50356001600160a01b031661027e565b34801561017757600080fd5b5061011c61033c565b610188610198565b610198610193610346565b61036b565b565b6101a261038f565b6001600160a01b0316336001600160a01b0316146101bf57600080fd5b6101c8816103b4565b50565b6101d361038f565b6001600160a01b0316336001600160a01b0316146101f057600080fd5b6101f9836103b4565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610256576040519150601f19603f3d011682016040523d82523d6000602084013e61025b565b606091505b505090508061026957600080fd5b50505050565b6000610279610346565b905090565b61028661038f565b6001600160a01b0316336001600160a01b0316146102a357600080fd5b6001600160a01b0381166102e85760405162461bcd60e51b81526004018080602001828103825260368152602001806104876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61031161038f565b604080516001600160a01b03928316815291841660208301528051918290030190a16101c8816103f4565b600061027961038f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561038a573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103bd81610418565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b61042181610480565b61045c5760405162461bcd60e51b815260040180806020018281038252603b8152602001806104bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b3b15159056fe43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a265627a7a72305820a9aab4b95b654a79b32f5aa284796894f8329aaa083932695296085b196c27bd64736f6c634300050a0032b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b03a86b3126157c039b55e21d378587ccfc04d45"
+ },
+ "0x1000000000000000000000000000000000000000": {
+ "balance": "0x0",
+ "constructor": "0x608060405234801561001057600080fd5b506141f5806100206000396000f3fe608060405234801561001057600080fd5b50600436106103b85760003560e01c806383465b82116101f4578063b41832e41161011a578063cd24327e116100ad578063ee99205c1161007c578063ee99205c14610e29578063eebc7a3914610e31578063facd743b14610e39578063fe54477e14610e5f576103b8565b8063cd24327e14610d79578063d207778214610de7578063e284789514610def578063e717de3a14610e0c576103b8565b8063c9e9694d116100e9578063c9e9694d14610cf8578063cbd2d52814610d1e578063cccf3a0214610d54578063ccf69e9b14610d71576103b8565b8063b41832e414610c3f578063b7ab4db514610c65578063b927ef4314610c6d578063c476dd4014610c75576103b8565b8063a48b042a11610192578063a881c5fd11610161578063a881c5fd14610be3578063a92252ae14610c09578063b172b22214610c2f578063b2c65a1014610c37576103b8565b8063a48b042a14610b50578063a4e01eaa14610b6d578063a657e57914610b8a578063a670eb5614610b92576103b8565b806393b4e25e116101ce57806393b4e25e14610ae857806394f3a24114610af05780639b4a14bf14610b0d578063a26301f914610b2a576103b8565b806383465b8214610a6b5780639184d0ad14610a9157806392d276b414610abf576103b8565b8063392e53cd116102e45780636729c2dc11610277578063714897df11610246578063714897df14610a2d57806374bdb37214610a355780637528621114610a3d57806381db0a4914610a45576103b8565b80636729c2dc1461090f5780636b5ecfd3146109175780636e85d53d1461093d578063704189ca14610a25576103b8565b806356b54bae116102b357806356b54bae1461081b5780635836d08a14610823578063595bddf9146108495780635ccee1de14610907576103b8565b8063392e53cd146107c85780633d34d9ef146107d05780633d3b5458146107f65780634d04481e146107fe576103b8565b80631776dee31161035c5780632bbb7b721161032b5780632bbb7b721461061c5780632f248e3014610642578063374dc77d1461065f578063378bf28b14610736576103b8565b80631776dee31461057c5780631a7fa237146105985780631d0cd4c6146105d05780631ee4d0bc146105f6576103b8565b80630636bdac116103985780630636bdac1461049157806309bee538146104ff5780630bf480c01461055757806316cf66ab1461055f576103b8565b80624a8803146103bd5780625351751461042457806305461c8514610466575b600080fd5b6103c5610e67565b604051808060200183151515158152602001828103825284818151815260200191508051906020019060200280838360005b8381101561040f5781810151838201526020016103f7565b50505050905001935050505060405180910390f35b61044a6004803603602081101561043a57600080fd5b50356001600160a01b0316610f21565b604080516001600160a01b039092168252519081900360200190f35b61048f6004803603606081101561047c57600080fd5b5080359060208101359060400135610f3c565b005b61048f600480360360208110156104a757600080fd5b810190602081018135600160201b8111156104c157600080fd5b8201836020820111156104d357600080fd5b803590602001918460208302840111600160201b831117156104f457600080fd5b50909250905061100d565b610507611073565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561054357818101518382015260200161052b565b505050509050019250505060405180910390f35b6105076110cc565b61044a6004803603602081101561057557600080fd5b5035611125565b610584611140565b604080519115158252519081900360200190f35b6105be600480360360208110156105ae57600080fd5b50356001600160a01b0316611147565b60408051918252519081900360200190f35b6105be600480360360208110156105e657600080fd5b50356001600160a01b0316611173565b61044a6004803603602081101561060c57600080fd5b50356001600160a01b031661119b565b6105be6004803603602081101561063257600080fd5b50356001600160a01b03166111b6565b61048f6004803603602081101561065857600080fd5b50356111c8565b6105be6004803603608081101561067557600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b8111156106a857600080fd5b8201836020820111156106ba57600080fd5b803590602001918460018302840111600160201b831117156106db57600080fd5b919390929091602081019035600160201b8111156106f857600080fd5b82018360208201111561070a57600080fd5b803590602001918460018302840111600160201b8311171561072b57600080fd5b50909250905061134a565b6107536004803603602081101561074c57600080fd5b50356113f1565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561078d578181015183820152602001610775565b50505050905090810190601f1680156107ba5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61058461148c565b61048f600480360360208110156107e657600080fd5b50356001600160a01b031661149d565b61058461194d565b6105846004803603602081101561081457600080fd5b503561196a565b61044a61199a565b6105be6004803603602081101561083957600080fd5b50356001600160a01b03166119a9565b61048f6004803603604081101561085f57600080fd5b810190602081018135600160201b81111561087957600080fd5b82018360208201111561088b57600080fd5b803590602001918460018302840111600160201b831117156108ac57600080fd5b919390929091602081019035600160201b8111156108c957600080fd5b8201836020820111156108db57600080fd5b803590602001918460018302840111600160201b831117156108fc57600080fd5b5090925090506119d1565b61048f611a82565b610507611f99565b6105846004803603602081101561092d57600080fd5b50356001600160a01b0316611fef565b61048f600480360360e081101561095357600080fd5b6001600160a01b03823581169260208101358216926040820135831692606083013516919081019060a081016080820135600160201b81111561099557600080fd5b8201836020820111156109a757600080fd5b803590602001918460208302840111600160201b831117156109c857600080fd5b919390929091602081019035600160201b8111156109e557600080fd5b8201836020820111156109f757600080fd5b803590602001918460208302840111600160201b83111715610a1857600080fd5b9193509150351515612004565b6105be61224e565b6105be61227e565b6105be612283565b61048f612289565b61048f60048036036020811015610a5b57600080fd5b50356001600160a01b0316612382565b6105be60048036036020811015610a8157600080fd5b50356001600160a01b03166125a5565b61058460048036036040811015610aa757600080fd5b506001600160a01b03813516906020013515156125b7565b610ac761270a565b604080519283526001600160a01b0390911660208301528051918290030190f35b61048f61271c565b61048f60048036036020811015610b0657600080fd5b5035612805565b61058460048036036020811015610b2357600080fd5b5035612833565b6105be60048036036020811015610b4057600080fd5b50356001600160a01b0316612848565b61058460048036036020811015610b6657600080fd5b503561285a565b61058460048036036020811015610b8357600080fd5b503561290e565b6105be61292d565b610bc860048036036060811015610ba857600080fd5b506001600160a01b03813581169160208101359091169060400135612933565b60408051921515835290151560208301528051918290030190f35b61058460048036036020811015610bf957600080fd5b50356001600160a01b0316612b1f565b61058460048036036020811015610c1f57600080fd5b50356001600160a01b0316612b32565b61044a612b4f565b61048f612b5e565b6105be60048036036020811015610c5557600080fd5b50356001600160a01b0316612d39565b610507612d61565b6105be612e11565b61048f60048036036060811015610c8b57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610cba57600080fd5b820183602082011115610ccc57600080fd5b803590602001918460018302840111600160201b83111715610ced57600080fd5b509092509050612e17565b6105be60048036036020811015610d0e57600080fd5b50356001600160a01b0316613022565b61058460048036036060811015610d3457600080fd5b506001600160a01b0381358116916020810135909116906040013561304a565b61075360048036036020811015610d6a57600080fd5b5035613104565b61044a61316c565b61048f60048036036020811015610d8f57600080fd5b810190602081018135600160201b811115610da957600080fd5b820183602082011115610dbb57600080fd5b803590602001918460208302840111600160201b83111715610ddc57600080fd5b50909250905061317b565b6105be6131ce565b61044a60048036036020811015610e0557600080fd5b50356131d4565b61058460048036036020811015610e2257600080fd5b50356131ef565b61044a613204565b610507613213565b61058460048036036020811015610e4f57600080fd5b50356001600160a01b03166132be565b6105076132e9565b600454604080518281526020808402820101909152606091600091908015610e99578160200160208202803883390190505b50915060005b8251811015610f1557601e600060036001018381548110610ebc57fe5b9060005260206000200154815260200190815260200160002060009054906101000a90046001600160a01b0316838281518110610ef557fe5b6001600160a01b0390921660209283029190910190910152600101610e9f565b505060035460ff169091565b6010602052600090815260409020546001600160a01b031681565b6025546001600160a01b03163314610f5357600080fd5b60008381526027602052604090205460ff1615610f6f57611008565b6000838152601e60205260409020546001600160a01b0316610f9057600080fd5b81610f9a57600080fd5b600083815260096020526040902054821115610fc25760008381526009602052604090208290555b600083815260086020908152604080832080546001019055600b9091529020819055610fed8361333f565b15610ffc57610ffc600061343e565b61100461347a565b6019555b505050565b6011546001600160a01b0316331461102457600080fd5b61106f828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250691d5b9c995d99585b195960b21b925061347e915050565b5050565b606060268054806020026020016040519081016040528092919081815260200182805480156110c157602002820191906000526020600020905b8154815260200190600101908083116110ad575b505050505090505b90565b606060036001018054806020026020016040519081016040528092919081815260200182805480156110c157602002820191906000526020600020908154815260200190600101908083116110ad575050505050905090565b601f602052600090815260409020546001600160a01b031681565b6004541590565b6001600160a01b0381166000908152601c60209081526040808320548352600a9091529020545b919050565b6001600160a01b03166000908152601c60209081526040808320548352600890915290205490565b6014602052600090815260409020546001600160a01b031681565b601c6020526000908152604090205481565b6111d061148c565b6111d957600080fd5b60008181526027602052604090205460ff166111f457600080fd5b6000818152601f60205260409020546001600160a01b031633811480611232575061121d613486565b6001600160a01b0316336001600160a01b0316145b61123b57600080fd5b601554604080516302f248e360e41b81526004810185905290516001600160a01b0390921691632f248e309160248082019260009290919082900301818387803b15801561128857600080fd5b505af115801561129c573d6000803e3d6000fd5b506000925050505b6026548110156113245782602682815481106112bc57fe5b9060005260206000200154141561131c576026805460001981019081106112df57fe5b9060005260206000200154602682815481106112f757fe5b60009182526020909120015560268054906113169060001983016140a6565b50611324565b6001016112a4565b506000828152602760205260409020805460ff1916905561134361347a565b6019555050565b6015546000906001600160a01b0316331461136457600080fd5b600061137088886134ab565b90506113e68187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b0181900481028201810190925289815292508991508890819084018382808284376000920191909152506137de92505050565b979650505050505050565b60246020908152600091825260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156114845780601f1061145957610100808354040283529160200191611484565b820191906000526020600020905b81548152906001019060200180831161146757829003601f168201915b505050505081565b600c546001600160a01b0316151590565b6114a561148c565b6114ae57600080fd5b33600081815260106020908152604080832054601d909252909120546001600160a01b039182169184166114e157600080fd5b6001600160a01b0382166114f457600080fd5b836001600160a01b0316826001600160a01b0316141561151357600080fd5b8061151d57600080fd5b6021541561152a57600080fd5b601554604080516322e8c68760e21b81526001600160a01b03878116600483015291519190921691638ba31a1c916024808301926020929190829003018186803b15801561157757600080fd5b505afa15801561158b573d6000803e3d6000fd5b505050506040513d60208110156115a157600080fd5b5051156115ad57600080fd5b6001600160a01b0384166000908152601a6020526040902054156115d057600080fd5b6001600160a01b0384166000908152601b602052604090205460ff16156115f657600080fd5b6000818152600e602052604090205460ff16156118ee57611615611140565b61161e57600080fd5b60055460ff161561162e57600080fd5b6117426116bc6002601160009054906101000a90046001600160a01b03166001600160a01b0316631c77c58c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561168457600080fd5b505afa158015611698573d6000803e3d6000fd5b505050506040513d60208110156116ae57600080fd5b50519063ffffffff61394416565b601560009054906101000a90046001600160a01b03166001600160a01b0316638c2243ae6040518163ffffffff1660e01b815260040160206040518083038186803b15801561170a57600080fd5b505afa15801561171e573d6000803e3d6000fd5b505050506040513d602081101561173457600080fd5b50519063ffffffff61396b16565b61174a61347a565b1061175457600080fd5b606061175e613213565b905060005b81518110156117d357836001600160a01b031682828151811061178257fe5b60200260200101516001600160a01b031614156117cb57858282815181106117a657fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506117d3565b600101611763565b50600180546117e4916004916140ca565b506021829055602280546001600160a01b0319166001600160a01b038781169190911790915560115460408051630b40282360e01b81526004810186905290519190921691630b40282391602480830192600092919082900301818387803b15801561184f57600080fd5b505af1158015611863573d6000803e3d6000fd5b50505050600161187161347a565b03407f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89826040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156118d55781810151838201526020016118bd565b505050509050019250505060405180910390a250611906565b6118fa82858386613980565b61190261347a565b6019555b836001600160a01b0316826001600160a01b0316827fad4c947995a3daa512a7371d31325a21227249f8dc1c52c1a4c6fe8475a3ebb160405160405180910390a450505050565b6000611957611140565b8015611965575060055460ff165b905090565b6000818152600960205260408120548061198857600091505061116e565b8061199161347a565b11159392505050565b600c546001600160a01b031681565b6001600160a01b03166000908152601c60209081526040808320548352600990915290205490565b6119d961148c565b6119e257600080fd5b336000908152601d6020526040902054806119fc57600080fd5b611a708186868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a0181900481028201810190925288815292508891508790819084018382808284376000920191909152506137de92505050565b611a7861347a565b6019555050505050565b600c546001600160a01b03163314611a9957600080fd5b6015546040805163a5d54f6560e01b815290516060926001600160a01b03169163a5d54f65916004808301926000929190829003018186803b158015611ade57600080fd5b505afa158015611af2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611b1b57600080fd5b810190808051600160201b811115611b3257600080fd5b82016020810184811115611b4557600080fd5b81518560208202830111600160201b82111715611b6157600080fd5b505060265490945060009350601310159150611b809050576000611b87565b6026546013035b9050808251118015611b9857508015155b15611e345760115460408051634191031360e11b815290516000926001600160a01b0316916383220626916004808301926020929190829003018186803b158015611be257600080fd5b505afa158015611bf6573d6000803e3d6000fd5b505050506040513d6020811015611c0c57600080fd5b50516015546040805163957950a760e01b815290519293506060926000926001600160a01b03169163957950a79160048083019286929190829003018186803b158015611c5857600080fd5b505afa158015611c6c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015611c9557600080fd5b810190808051600160201b811115611cac57600080fd5b82016020810184811115611cbf57600080fd5b81518560208202830111600160201b82111715611cdb57600080fd5b50506020909101518151919550935015801592509050611cfb5750600081115b15611e2c57606084604051908082528060200260200182016040528015611d2c578160200160208202803883390190505b50865190915060005b8251811015611e1f57604080516020808201989098528151808203890181529082019091528051960195909520946000611d70868689613a09565b9050888181518110611d7e57fe5b6020026020010151848381518110611d9257fe5b602002602001018181525050858181518110611daa57fe5b602002602001015185039450828060019003935050888381518110611dcb57fe5b6020026020010151898281518110611ddf57fe5b602002602001018181525050858381518110611df757fe5b6020026020010151868281518110611e0b57fe5b602090810291909101015250600101611d35565b50611e2982613a56565b50505b505050611e3d565b611e3d82613a56565b611e47600161343e565b815115611eb757601560009054906101000a90046001600160a01b03166001600160a01b0316631555371c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611e9e57600080fd5b505af1158015611eb2573d6000803e3d6000fd5b505050505b601560009054906101000a90046001600160a01b03166001600160a01b031663ee435f556040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611f0757600080fd5b505af1158015611f1b573d6000803e3d6000fd5b50506015546001600160a01b031691506320d96e469050611f3a61347a565b6001016040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611f7357600080fd5b505af1158015611f87573d6000803e3d6000fd5b5050600060185550611343905061347a565b606060018054806020026020016040519081016040528092919081815260200182805480156110c157602002820191906000526020600020908154815260200190600101908083116110ad575050505050905090565b601b6020526000908152604090205460ff1681565b61200c61347a565b1580612030575061201b613486565b6001600160a01b0316336001600160a01b0316145b61203957600080fd5b61204161148c565b1561204b57600080fd5b6001600160a01b03891661205e57600080fd5b6001600160a01b03871661207157600080fd5b6001600160a01b03861661208457600080fd5b8361208e57600080fd5b83821461209a57600080fd5b60138411156120a857600080fd5b600c80546001600160a01b03808c166001600160a01b031992831617909255602580548b8416908316179055601180548a841690831617905560158054928916929091169190911790556120fa61347a565b60195560005b8481101561224257600086868381811061211657fe5b905060200201356001600160a01b03169050600085858481811061213657fe5b905060200201356001600160a01b03169050600061215483836134ab565b60008054600181810183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563909101839055805480820182557fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf601839055828252600e60209081526040808420805460ff1916841790556017909152909120805490910190559050831580156121e75750845b15612237576026805460018181019092557f744a2cf8fd7008e3d53b67916e73460df9fa5214e3ef23dd4259ca09493a3594018290556000828152602760205260409020805460ff191690911790555b505050600101612100565b50505050505050505050565b602654600090612260575060006110c9565b602660008154811061226e57fe5b9060005260206000200154905090565b601381565b60195481565b6002600160a01b03331461229c57600080fd5b60035460ff1615612331576122af613c82565b6122b96001613d3b565b600c60009054906101000a90046001600160a01b03166001600160a01b031663c5dd76286040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561230957600080fd5b505af115801561231d573d6000803e3d6000fd5b5050505061232961347a565b601855612354565b60045415612348576123436000613d3b565b612354565b61235061347a565b6018555b61235c613eaf565b6003805460ff19168155600061237360048261411a565b505061237d61347a565b601955565b61238a61148c565b61239357600080fd5b336000818152601d60205260409020546001600160a01b0383166123b657600080fd5b826001600160a01b0316826001600160a01b031614156123d557600080fd5b806123df57600080fd5b602154156123ec57600080fd5b601554604080516322e8c68760e21b81526001600160a01b03868116600483015291519190921691638ba31a1c916024808301926020929190829003018186803b15801561243957600080fd5b505afa15801561244d573d6000803e3d6000fd5b505050506040513d602081101561246357600080fd5b50511561246f57600080fd5b6001600160a01b0383166000908152601a60205260409020541561249257600080fd5b6001600160a01b0383166000908152601b602052604090205460ff16156124b857600080fd5b6000818152601e60209081526040808320546001600160a01b03868116808652601d85528386208690558882168087528487208890559086526010855283862080546001600160a01b03199081169091558187528487208054821693909416928317909355868652601f855283862080548416821790558186526014855283862080549093168117909255908452601b909252909120805460ff1916600117905561256161347a565b6019556040516001600160a01b03808616919085169084907f5c44164828293bba0353472e907f7ee26a8659f916e6311fe826a7c70510e35290600090a450505050565b601a6020526000908152604090205481565b60008082156125df57506001600160a01b0383166000908152601c60205260409020546125fa565b506001600160a01b0383166000908152601a60205260409020545b6000818152600e602052604081205460ff16801561261e575061261c8261196a565b155b9050601560009054906101000a90046001600160a01b03166001600160a01b031663794c0c686040518163ffffffff1660e01b815260040160206040518083038186803b15801561266e57600080fd5b505afa158015612682573d6000803e3d6000fd5b505050506040513d602081101561269857600080fd5b505115806126a65750601854155b156126b45791506127049050565b60136018546126c161347a565b0311612700576000828152600f602052604081205460ff1680156126eb57506126e98361196a565b155b905081806126f65750805b9350505050612704565b9150505b92915050565b6021546022546001600160a01b031682565b61272461148c565b61272d57600080fd5b61273561194d565b61273e57600080fd5b6000612748613f0e565b6001549091501561280257600161275d61347a565b03407f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89612788613213565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156127c45781810151838201526020016127ac565b505050509050019250505060405180910390a2600180546127e7916004916140ca565b506003805460ff19168215151790556127fe61347a565b6019555b50565b61280d613486565b6001600160a01b0316336001600160a01b03161461282a57600080fd5b61280281613f26565b600e6020526000908152604090205460ff1681565b601d6020526000908152604090205481565b6000818152600e602052604081205460ff16156128795750600161116e565b6004546000905b808210156128be57600480548390811061289657fe5b90600052602060002001548414156128b35760019250505061116e565b600190910190612880565b50506001546000905b8082101561290457600182815481106128dc57fe5b90600052602060002001548414156128f95760019250505061116e565b6001909101906128c7565b5060009392505050565b6000818152600a602052604081205461292561347a565b111592915050565b60205481565b6000806129418560016125b7565b61295057506000905080612b17565b61295b8460006125b7565b61296a57506000905080612b17565b6001600160a01b038086166000908152601c60209081526040808320549388168352601a90915281205490546001811115612a825760155460408051630f29818d60e31b815290516000926001600160a01b03169163794c0c68916004808301926020929190829003018186803b1580156129e457600080fd5b505afa1580156129f8573d6000803e3d6000fd5b505050506040513d6020811015612a0e57600080fd5b5051600085815260126020908152604080832084845282528083205460139092528220549293509190828210612a535760018503838303600a0281612a4f57fe5b0490505b8460320283118015612a6457508083115b15612a7d57600060019850985050505050505050612b17565b505050505b6000612a8c61347a565b905080871115612aa6576000809550955050505050612b17565b60648082118015612ab8575080820388105b15612ace57600080965096505050505050612b17565b60008481526007602090815260408083208b8452825280832088845290915290205460ff1615612b0957600080965096505050505050612b17565b600160009650965050505050505b935093915050565b6000612b2a82611147565b61292561347a565b600080612b3e836119a9565b90508061198857600091505061116e565b6025546001600160a01b031681565b612b66613486565b6001600160a01b0316336001600160a01b031614612b8357600080fd5b60265415612b9057600080fd5b601654736a3154a1f55a8faf96dfde75d25eff0c06eb678414612bb257600080fd5b6016805460268054600181810183557f744a2cf8fd7008e3d53b67916e73460df9fa5214e3ef23dd4259ca09493a35949182019390935581548084019092557359be7069745a9820a75aa66357a50a5d7f66ced591018190558254600090815260276020526040808220805460ff1990811686179091559282527f4bf96c2adb0c7a309689f5f3e58c1a880f1b61efb59c1459be862d2666e5acdb8054909316909317909155601554925482516394f3a24160e01b8152600481019190915291516001600160a01b03909316926394f3a24192602480820193929182900301818387803b158015612ca257600080fd5b505af1158015612cb6573d6000803e3d6000fd5b5050601554604080516394f3a24160e01b81527359be7069745a9820a75aa66357a50a5d7f66ced5600482015290516001600160a01b0390921693506394f3a241925060248082019260009290919082900301818387803b158015612d1a57600080fd5b505af1158015612d2e573d6000803e3d6000fd5b505060006016555050565b6001600160a01b03166000908152601c60209081526040808320548352601790915290205490565b606080600080549050604051908082528060200260200182016040528015612d93578160200160208202803883390190505b50905060005b8151811015612e0b57601e6000808381548110612db257fe5b9060005260206000200154815260200190815260200160002060009054906101000a90046001600160a01b0316828281518110612deb57fe5b6001600160a01b0390921660209283029190910190910152600101612d99565b50905090565b60185481565b612e1f61148c565b612e2857600080fd5b336000818152601c60209081526040808320546001600160a01b0389168452601a90925290912054612e5b8360016125b7565b15612e6957612e6982613fff565b600080612e77858a8a612933565b9150915081612ef3578015612ee957604080516001808252818301909252606091602080830190803883390190505090508581600081518110612eb657fe5b60200260200101906001600160a01b031690816001600160a01b031681525050612ee781637370616d60e01b61347e565b505b505050505061301c565b60008381526006602090815260408083208b84528252808320805460018181018355828652848620909101899055878552600784528285208d86528452828520898652845293829020805460ff191690941790935580516001600160a01b03808a1682528d16928101929092528051869288928d927fc98c577e9aca0ce08e747dd843b95214821e69106d6916218997e8a8f357f3189281900390910190a46000548154612fa890600263ffffffff61394416565b111561224257604080516001808252818301909252606091602080830190803883390190505090508a81600081518110612fde57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505061301481686d616c6963696f757360b81b61347e565b505050505050505b50505050565b6001600160a01b03166000908152601c60209081526040808320548352600b90915290205490565b60008061305561347a565b90508060010183111561306c5760009150506130fd565b60648111801561307e57508260648203115b1561308d5760009150506130fd565b6001600160a01b0384166000908152601a60205260409020546130af8161196a565b156130bf576000925050506130fd565b6001600160a01b0386166000908152601c6020908152604080832054938352600782528083208784528252808320938352929052205460ff16159150505b9392505050565b60236020908152600091825260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156114845780601f1061145957610100808354040283529160200191611484565b6011546001600160a01b031681565b613183613486565b6001600160a01b0316336001600160a01b0316146131a057600080fd5b60005b81811015611008576131c68383838181106131ba57fe5b90506020020135613f26565b6001016131a3565b600d5481565b601e602052600090815260409020546001600160a01b031681565b60276020526000908152604090205460ff1681565b6015546001600160a01b031681565b606080600180549050604051908082528060200260200182016040528015613245578160200160208202803883390190505b50905060005b8151811015612e0b57601e60006001838154811061326557fe5b9060005260206000200154815260200190815260200160002060009054906101000a90046001600160a01b031682828151811061329e57fe5b6001600160a01b039092166020928302919091019091015260010161324b565b6001600160a01b03166000908152601c60209081526040808320548352600e90915290205460ff1690565b606060008054806020026020016040519081016040528092919081815260200182805480156110c157602002820191906000526020600020908154815260200190600101908083116110ad575050505050905090565b60155460408051630a38dcbd60e41b81526004810184905290516000926001600160a01b03169163a38dcbd0916024808301928692919082900301818387803b15801561338b57600080fd5b505af115801561339f573d6000803e3d6000fd5b505060018054925082141590506133ba57600091505061116e565b60005b818110156129045783600182815481106133d357fe5b90600052602060002001541415613436576001808303815481106133f357fe5b90600052602060002001546001828154811061340b57fe5b600091825260209091200155600180549061342a9060001983016140a6565b5060019250505061116e565b6001016133bd565b6005805460ff19166001179055808015613459575060015415155b1561346e576005805461ff0019166101001790555b50600d80546001019055565b4390565b61134361347a565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b602154600090156134bb57600080fd5b6001600160a01b0383166134ce57600080fd5b6001600160a01b0382166134e157600080fd5b816001600160a01b0316836001600160a01b0316141561350057600080fd5b6001600160a01b03828116600090815260106020526040902054161561352557600080fd5b6001600160a01b03838116600090815260106020526040902054161561354a57600080fd5b6001600160a01b03828116600090815260146020526040902054161561356f57600080fd5b6001600160a01b03838116600090815260146020526040902054161561359457600080fd5b601554604080516322e8c68760e21b81526001600160a01b03868116600483015291519190921691638ba31a1c916024808301926020929190829003018186803b1580156135e157600080fd5b505afa1580156135f5573d6000803e3d6000fd5b505050506040513d602081101561360b57600080fd5b50511561361757600080fd5b601554604080516322e8c68760e21b81526001600160a01b03858116600483015291519190921691638ba31a1c916024808301926020929190829003018186803b15801561366457600080fd5b505afa158015613678573d6000803e3d6000fd5b505050506040513d602081101561368e57600080fd5b50511561369a57600080fd5b6001600160a01b0383166000908152601a6020526040902054156136bd57600080fd5b6001600160a01b0382166000908152601a6020526040902054156136e057600080fd5b6001600160a01b0383166000908152601b602052604090205460ff161561370657600080fd5b6001600160a01b0382166000908152601b602052604090205460ff161561372c57600080fd5b506020805460019081018083556001600160a01b039485166000818152601c8552604080822084905595909616808752601d8552858720839055828752601e855285872080546001600160a01b03199081168417909155818852601086528688208054821684179055838852601f865286882080548216831790559187526014855285872080549092168117909155601a84528486208290558552601b90925291909220805460ff1916909117905590565b610100825111156137ee57600080fd5b610400815111156137fe57600080fd5b6000838152602360209081526040909120835161381d92850190614138565b506000838152602460209081526040909120825161383d92840190614138565b50827f79a6be597f1291d06b4ccea662f373201edec72cbcc5df2ccfcd74ce9ff4b2e98383604051808060200180602001838103835285818151815260200191508051906020019080838360005b838110156138a357818101518382015260200161388b565b50505050905090810190601f1680156138d05780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156139035781810151838201526020016138eb565b50505050905090810190601f1680156139305780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2505050565b60008261395357506000612704565b8282028284828161396057fe5b04146130fd57600080fd5b60008282111561397a57600080fd5b50900390565b6001600160a01b039384166000818152601c60209081526040808320839055958716808352868320869055858352601e825286832080546001600160a01b0319908116831790915594909716808352601082528683208054861689179055928252601481528582208054851690559581528481208054909316909117909155601a909352912055565b600080838381613a1557fe5b0690506000805b828211613a4857868181518110613a2f57fe5b6020026020010151820191508080600101915050613a1c565b600019019695505050505050565b8051613c1e5760005b600154811015613c1857600060018281548110613a7857fe5b6000918252602080832090910154808352602790915260409091205490915060ff1615613aa55750613c10565b601554604080516317775f1960e31b81526004810184905290516001600160a01b039092169163bbbaf8c891602480820192602092909190829003018186803b158015613af157600080fd5b505afa158015613b05573d6000803e3d6000fd5b505050506040513d6020811015613b1b57600080fd5b50518015613ba55750601554604080516371f87fb360e11b8152600481018490526000602482015290516001600160a01b039092169163e3f0ff6691604480820192602092909190829003018186803b158015613b7757600080fd5b505afa158015613b8b573d6000803e3d6000fd5b505050506040513d6020811015613ba157600080fd5b5051155b15613bb05750613c10565b600180541415613bc05750613c18565b600180546000198101908110613bd257fe5b906000526020600020015460018381548110613bea57fe5b6000918252602090912001556001805490613c099060001983016140a6565b5050600019015b600101613a5f565b50612802565b60268054613c2e916001916140ca565b5060005b815181108015613c4457506001546013115b1561106f576001828281518110613c5757fe5b6020908102919091018101518254600181810185556000948552929093209092019190915501613c32565b60025460005b81811015613cd6576000600f600060028481548110613ca357fe5b60009182526020808320919091015483528201929092526040019020805460ff1916911515919091179055600101613c88565b505060008054905b81811015613d2b576001600f6000808481548110613cf857fe5b60009182526020808320919091015483528201929092526040019020805460ff1916911515919091179055600101613cde565b60008054611008916002916140ca565b6060600080805480602002602001604051908101604052809291908181526020018280548015613d8a57602002820191906000526020600020905b815481526020019060010190808311613d76575b50505050509150600090505b8151811015613de2576000600e6000848481518110613db157fe5b6020908102919091018101518252810191909152604001600020805460ff1916911515919091179055600101613d96565b60048054613df2916000916140ca565b506000805480602002602001604051908101604052809291908181526020018280548015613e3f57602002820191906000526020600020905b815481526020019060010190808311613e2b575b50505050509150600090505b8151811015611008576000828281518110613e6257fe5b6020908102919091018101516000818152600e9092526040909120805460ff1916600117905590508315613ea6576000818152601760205260409020805460010190555b50600101613e4b565b6021548015613ef6576000818152601e6020908152604080832054602254601f9093529220546001600160a01b03928316929182169116613ef283838684613980565b5050505b506000602155602280546001600160a01b0319169055565b6005805461ffff198116909155610100900460ff1690565b60008181526027602052604090205460ff1615613f4257600080fd5b602654601311613f5157600080fd5b6026805460018181019092557f744a2cf8fd7008e3d53b67916e73460df9fa5214e3ef23dd4259ca09493a359401829055600082815260276020526040808220805460ff191690931790925560155482516394f3a24160e01b81526004810185905292516001600160a01b03909116926394f3a24192602480830193919282900301818387803b158015613fe457600080fd5b505af1158015613ff8573d6000803e3d6000fd5b5050505050565b60155460408051630f29818d60e31b815290516000926001600160a01b03169163794c0c68916004808301926020929190829003018186803b15801561404457600080fd5b505afa158015614058573d6000803e3d6000fd5b505050506040513d602081101561406e57600080fd5b505160009283526012602090815260408085209285529181528184208054600190810190915560139091529220805490920190915550565b815481835581811115611008576000838152602090206110089181019083016141a6565b82805482825590600052602060002090810192821561410a5760005260206000209182015b8281111561410a5782548255916001019190600101906140ef565b506141169291506141a6565b5090565b508054600082559060005260206000209081019061280291906141a6565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061417957805160ff191683800117855561410a565b8280016001018555821561410a579182015b8281111561410a57825182559160200191906001019061418b565b6110c991905b8082111561411657600081556001016141ac56fea265627a7a7230582055f1a6432160796b00712c102535aff37d15150aeb81412e0c35d8522cd3bc3164736f6c634300050a0032"
+ },
+ "0x1100000000000000000000000000000000000001": {
+ "balance": "0x0",
+ "constructor": "0x60806040526040516108053803806108058339818101604052604081101561002657600080fd5b50805160209182015160408051600081529384018082527f656970313936372e70726f78792e696d706c656d656e746174696f6e00000000905251603c81850301902091929091839190600019016000805160206107aa8339815191521461008a57fe5b61009c826001600160e01b036101bd16565b805115610154576000826001600160a01b0316826040518082805190602001908083835b602083106100df5780518252601f1990920191602091820191016100c0565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461013f576040519150601f19603f3d011682016040523d82523d6000602084013e610144565b606091505b505090508061015257600080fd5b505b5050604080517f656970313936372e70726f78792e61646d696e000000000000000000000000008152905190819003601301902060008051602061078a833981519152600019909101146101a457fe5b6101b6816001600160e01b0361023716565b505061024f565b6101d08161024960201b6104801760201c565b610225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806107ca603b913960400191505060405180910390fd5b6000805160206107aa83398151915255565b60008051602061078a83398151915255565b3b151590565b61052c8061025e6000396000f3fe60806040526004361061004a5760003560e01c80633659cfe6146100545780634f1ef286146100875780635c60da1b146101075780638f28397014610138578063f851a4401461016b575b610052610180565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661019a565b6100526004803603604081101561009d57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100c857600080fd5b8201836020820111156100da57600080fd5b803590602001918460018302840111640100000000831117156100fc57600080fd5b5090925090506101cb565b34801561011357600080fd5b5061011c61026f565b604080516001600160a01b039092168252519081900360200190f35b34801561014457600080fd5b506100526004803603602081101561015b57600080fd5b50356001600160a01b031661027e565b34801561017757600080fd5b5061011c61033c565b610188610198565b610198610193610346565b61036b565b565b6101a261038f565b6001600160a01b0316336001600160a01b0316146101bf57600080fd5b6101c8816103b4565b50565b6101d361038f565b6001600160a01b0316336001600160a01b0316146101f057600080fd5b6101f9836103b4565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610256576040519150601f19603f3d011682016040523d82523d6000602084013e61025b565b606091505b505090508061026957600080fd5b50505050565b6000610279610346565b905090565b61028661038f565b6001600160a01b0316336001600160a01b0316146102a357600080fd5b6001600160a01b0381166102e85760405162461bcd60e51b81526004018080602001828103825260368152602001806104876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61031161038f565b604080516001600160a01b03928316815291841660208301528051918290030190a16101c8816103f4565b600061027961038f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561038a573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103bd81610418565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b61042181610480565b61045c5760405162461bcd60e51b815260040180806020018281038252603b8152602001806104bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b3b15159056fe43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a265627a7a72305820a9aab4b95b654a79b32f5aa284796894f8329aaa083932695296085b196c27bd64736f6c634300050a0032b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000000000000000001100000000000000000000000000000000000000000000000000000000000000b03a86b3126157c039b55e21d378587ccfc04d45"
+ },
+ "0x1100000000000000000000000000000000000000": {
+ "balance": "0x0",
+ "constructor": "0x608060405234801561001057600080fd5b5061579480620000216000396000f3fe6080604052600436106103c35760003560e01c80638c2243ae116101f2578063cd22c7521161010d578063e3f0ff66116100a0578063f07860961161006f578063f078609614611033578063f3fef3a314611048578063f494250114611081578063fb367a9b14611096576103c3565b8063e3f0ff6614610efd578063e4a9e42e14610f36578063edd7db7514611009578063ee435f551461101e576103c3565b8063d609ea93116100dc578063d609ea9314610ea9578063da7a9b6a14610ebe578063df6f55f514610ed3578063dfc8bf4e14610ee8576103c3565b8063cd22c75214610dfe578063cfef144114610e28578063d290c21d14610e5b578063d2f2a13614610e70576103c3565b8063a4c0ed3611610185578063b61ed63a11610154578063b61ed63a14610cc4578063bbbaf8c814610cfd578063bcdb0d3814610d27578063cc4a666714610d51576103c3565b8063a4c0ed3614610bde578063a5d54f6514610c6e578063adc9772e14610c83578063b172b22214610caf576103c3565b806397997ebb116101c157806397997ebb14610b4b5780639fb0e72e14610b60578063a1fc275314610b8a578063a38dcbd014610bb4576103c3565b80638c2243ae14610a6157806394f3a24114610a76578063950a651314610aa0578063957950a714610adb576103c3565b80633ea15d62116102e2578063673a2a1f116102755780637069e746116102445780637069e746146109ef57806374bdb37214610a04578063794c0c6814610a195780638ba31a1c14610a2e576103c3565b8063673a2a1f146109365780636bda15771461094b5780636d01b4fe146109865780636e69cd8b146109c5576103c3565b80635292fccf116102b15780635292fccf14610891578063561c4c81146108c4578063570941d2146108ee5780635fef764314610921576103c3565b80633ea15d621461074b5780633fb1a1e4146108045780634070a2d01461083d57806348aaa4a214610867576103c3565b806327d89b3a1161035a5780632ebfaf4e116103295780632ebfaf4e146106445780632f248e30146106d3578063381883b0146106fd578063392e53cd14610736576103c3565b806327d89b3a146105865780632a8f6ecd146105bf5780632bafde8d146105e95780632d21d21714610613576103c3565b80631555371c116103965780631555371c146104b1578063186dc46f146104c657806320d96e4614610519578063251441a914610543576103c3565b806302a53ba1146103c85780630555c5e214610413578063073b62fe1461043f578063093411da14610478575b600080fd5b3480156103d457600080fd5b50610401600480360360408110156103eb57600080fd5b50803590602001356001600160a01b0316611173565b60408051918252519081900360200190f35b34801561041f57600080fd5b5061043d6004803603602081101561043657600080fd5b5035611190565b005b34801561044b57600080fd5b506104016004803603604081101561046257600080fd5b50803590602001356001600160a01b0316611325565b34801561048457600080fd5b506104016004803603604081101561049b57600080fd5b50803590602001356001600160a01b0316611359565b3480156104bd57600080fd5b5061043d611376565b3480156104d257600080fd5b50610505600480360360608110156104e957600080fd5b508035906001600160a01b036020820135169060400135611418565b604080519115158252519081900360200190f35b34801561052557600080fd5b5061043d6004803603602081101561053c57600080fd5b503561143e565b34801561054f57600080fd5b5061043d6004803603606081101561056657600080fd5b506001600160a01b0381358116916020810135909116906040013561145a565b34801561059257600080fd5b50610401600480360360408110156105a957600080fd5b50803590602001356001600160a01b03166115f2565b3480156105cb57600080fd5b50610401600480360360208110156105e257600080fd5b503561160f565b3480156105f557600080fd5b5061043d6004803603602081101561060c57600080fd5b5035611621565b34801561061f57600080fd5b5061062861165c565b604080516001600160a01b039092168252519081900360200190f35b34801561065057600080fd5b506106836004803603606081101561066757600080fd5b506001600160a01b03813516906020810135906040013561166b565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106bf5781810151838201526020016106a7565b505050509050019250505060405180910390f35b3480156106df57600080fd5b5061043d600480360360208110156106f657600080fd5b5035611780565b34801561070957600080fd5b506104016004803603604081101561072057600080fd5b50803590602001356001600160a01b03166117e3565b34801561074257600080fd5b50610505611800565b34801561075757600080fd5b5061043d6004803603604081101561076e57600080fd5b810190602081018135600160201b81111561078857600080fd5b82018360208201111561079a57600080fd5b803590602001918460208302840111600160201b831117156107bb57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505090356001600160a01b031691506118129050565b34801561081057600080fd5b506104016004803603604081101561082757600080fd5b50803590602001356001600160a01b0316611e87565b34801561084957600080fd5b506104016004803603602081101561086057600080fd5b5035611ea4565b34801561087357600080fd5b5061043d6004803603602081101561088a57600080fd5b5035611eb6565b34801561089d57600080fd5b5061043d600480360360208110156108b457600080fd5b50356001600160a01b0316611ef1565b3480156108d057600080fd5b50610683600480360360208110156108e757600080fd5b5035612045565b3480156108fa57600080fd5b5061043d6004803603602081101561091157600080fd5b50356001600160a01b03166120b1565b34801561092d57600080fd5b5061040161213d565b34801561094257600080fd5b50610683612143565b34801561095757600080fd5b506104016004803603604081101561096e57600080fd5b506001600160a01b038135811691602001351661219b565b34801561099257600080fd5b50610401600480360360608110156109a957600080fd5b508035906001600160a01b03602082013516906040013561235a565b3480156109d157600080fd5b50610401600480360360208110156109e857600080fd5b503561237d565b3480156109fb57600080fd5b5061040161238f565b348015610a1057600080fd5b50610401612395565b348015610a2557600080fd5b5061040161239b565b348015610a3a57600080fd5b5061040160048036036020811015610a5157600080fd5b50356001600160a01b03166123a1565b348015610a6d57600080fd5b506104016123bc565b348015610a8257600080fd5b5061043d60048036036020811015610a9957600080fd5b50356123e1565b348015610aac57600080fd5b5061040160048036036040811015610ac357600080fd5b506001600160a01b0381358116916020013516612420565b348015610ae757600080fd5b50610af06125d1565b6040518080602001838152602001828103825284818151815260200191508051906020019060200280838360005b83811015610b36578181015183820152602001610b1e565b50505050905001935050505060405180910390f35b348015610b5757600080fd5b50610401612634565b348015610b6c57600080fd5b5061040160048036036020811015610b8357600080fd5b503561263a565b348015610b9657600080fd5b5061068360048036036020811015610bad57600080fd5b503561264c565b348015610bc057600080fd5b5061043d60048036036020811015610bd757600080fd5b50356126b6565b348015610bea57600080fd5b5061050560048036036060811015610c0157600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610c3057600080fd5b820183602082011115610c4257600080fd5b803590602001918460018302840111600160201b83111715610c6357600080fd5b5090925090506126d6565b348015610c7a57600080fd5b5061068361283c565b61043d60048036036040811015610c9957600080fd5b506001600160a01b038135169060200135612892565b348015610cbb57600080fd5b5061062861289c565b348015610cd057600080fd5b5061043d60048036036040811015610ce757600080fd5b506001600160a01b0381351690602001356128ab565b348015610d0957600080fd5b5061050560048036036020811015610d2057600080fd5b5035612cd7565b348015610d3357600080fd5b5061040160048036036020811015610d4a57600080fd5b5035612d12565b348015610d5d57600080fd5b5061043d6004803603610100811015610d7557600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b811115610da857600080fd5b820183602082011115610dba57600080fd5b803590602001918460208302840111600160201b83111715610ddb57600080fd5b919350915080359060208101359060408101359060608101359060800135612d24565b348015610e0a57600080fd5b5061040160048036036020811015610e2157600080fd5b5035612f0f565b348015610e3457600080fd5b5061043d60048036036020811015610e4b57600080fd5b50356001600160a01b0316612f21565b348015610e6757600080fd5b50610683613128565b348015610e7c57600080fd5b5061040160048036036040811015610e9357600080fd5b50803590602001356001600160a01b031661317e565b348015610eb557600080fd5b5061040161319b565b348015610eca57600080fd5b506104016131a1565b348015610edf57600080fd5b506106836131a7565b348015610ef457600080fd5b506106286131fd565b348015610f0957600080fd5b5061040160048036036040811015610f2057600080fd5b50803590602001356001600160a01b031661320c565b61040160048036036080811015610f4c57600080fd5b8135916001600160a01b0360208201351691810190606081016040820135600160201b811115610f7b57600080fd5b820183602082011115610f8d57600080fd5b803590602001918460018302840111600160201b83111715610fae57600080fd5b919390929091602081019035600160201b811115610fcb57600080fd5b820183602082011115610fdd57600080fd5b803590602001918460018302840111600160201b83111715610ffe57600080fd5b509092509050613229565b34801561101557600080fd5b5061043d6132a3565b34801561102a57600080fd5b5061043d613452565b34801561103f57600080fd5b50610401613474565b34801561105457600080fd5b5061043d6004803603604081101561106b57600080fd5b506001600160a01b03813516906020013561347a565b34801561108d57600080fd5b50610505613568565b3480156110a257600080fd5b5061115a600480360360608110156110b957600080fd5b810190602081018135600160201b8111156110d357600080fd5b8201836020820111156110e557600080fd5b803590602001918460208302840111600160201b8311171561110657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550506001600160a01b0383358116945060209093013590921691506135aa9050565b6040805192835260208301919091528051918290030190f35b602a60209081526000928352604080842090915290825290205481565b611198613c33565b6001600160a01b0316336001600160a01b0316146111b557600080fd5b60006111bf613c58565b90506035546000146111d057600080fd5b6037548110806111e05750603754155b6111e957600080fd5b816111f2613c5c565b146111fc57600080fd5b600054828161120757fe5b061561121257600080fd5b6000805461122790849063ffffffff613cd816565b603780549084905590915060005b60005481101561131c57600080828154811061124d57fe5b6000918252602080832090910154603954604080516316cf66ab60e01b81526004810184905290519295506001600160a01b03909116926316cf66ab92602480840193829003018186803b1580156112a457600080fd5b505afa1580156112b8573d6000803e3d6000fd5b505050506040513d60208110156112ce57600080fd5b50516000838152603160209081526040808320838052909152902054909150156112f757600080fd5b611302818287613cfa565b506000908152600b60205260409020839055600101611235565b50603755505050565b6000828152600a602090815260408083206001600160a01b0385168452825280832060355484529091529020545b92915050565b602b60209081526000928352604080842090915290825290205481565b6039546001600160a01b0316331461138d57600080fd5b606060038054806020026020016040519081016040528092919081815260200182805480156113db57602002820191906000526020600020905b8154815260200190600101908083116113c7575b50939450600093505050505b81518110156114145761140c8282815181106113ff57fe5b60200260200101516141dc565b6001016113e7565b5050565b603060209081526000938452604080852082529284528284209052825290205460ff1681565b6039546001600160a01b0316331461145557600080fd5b603755565b816001600160a01b0316836001600160a01b0316141561147957600080fd5b6039546040805163a26301f960e01b81526001600160a01b0386811660048301529151600093929092169163a26301f991602480820192602092909190829003018186803b1580156114ca57600080fd5b505afa1580156114de573d6000803e3d6000fd5b505050506040513d60208110156114f457600080fd5b50516039546040805163a26301f960e01b81526001600160a01b0387811660048301529151939450600093919092169163a26301f9916024808301926020929190829003018186803b15801561154957600080fd5b505afa15801561155d573d6000803e3d6000fd5b505050506040513d602081101561157357600080fd5b50519050336115838682866142c8565b61158e858286613cfa565b603554604080516001600160a01b03898116825260208201889052818301879052606082018690529151828516928916917f982f87186288986ca297b6c86b6d4547934327c6e005ce210da6b0cdc06a370d919081900360800190a4505050505050565b603260209081526000928352604080842090915290825290205481565b60386020526000908152604090205481565b611629613c33565b6001600160a01b0316336001600160a01b03161461164657600080fd5b61164e611800565b61165757600080fd5b602555565b6053546001600160a01b031681565b6001600160a01b0383166000908152600860205260409020606090826116df578054604080516020808402820181019092528281529183918301828280156116d257602002820191906000526020600020905b8154815260200190600101908083116116be575b5050505050915050611779565b80546000906116f4908663ffffffff61453a16565b90508084116117035783611705565b805b60405190808252806020026020018201604052801561172e578160200160208202803883390190505b50925060005b835181101561177557828187018154811061174b57fe5b906000526020600020015484828151811061176257fe5b6020908102919091010152600101611734565b5050505b9392505050565b6039546001600160a01b0316331461179757600080fd5b806117a157600080fd5b6000818152603160209081526040808320838052909152902054156117d7576117c98161454f565b6117d28161460b565b6117e0565b6117e0816146c4565b50565b603360209081526000928352604080842090915290825290205481565b6039546001600160a01b031615155b90565b3a61181c57600080fd5b611824611800565b61182d57600080fd5b6039546040805163a26301f960e01b81526001600160a01b03848116600483015291513393600093169163a26301f9916024808301926020929190829003018186803b15801561187c57600080fd5b505afa158015611890573d6000803e3d6000fd5b505050506040513d60208110156118a657600080fd5b505190506001600160a01b0383166118bd57600080fd5b6001600160a01b0382166118d057600080fd5b806118da57600080fd5b6000836001600160a01b0316836001600160a01b031614156118fd5760006118ff565b825b9050600080846001600160a01b0316866001600160a01b0316146119715760008481526032602090815260408083206001600160a01b038916845290915290205491508161194c57600080fd5b5060008381526033602090815260408083206001600160a01b03881684529091529020545b60395460408051632b5aa5d760e11b815290516000926001600160a01b0316916356b54bae916004808301926020929190829003018186803b1580156119b657600080fd5b505afa1580156119ca573d6000803e3d6000fd5b505050506040513d60208110156119e057600080fd5b505190506119ec615708565b50604080518082019091526000808252602082018190528951611ad957826001600160a01b031663e7f6cfe2886040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b158015611a4d57600080fd5b505afa158015611a61573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611a8a57600080fd5b810190808051600160201b811115611aa157600080fd5b82016020810184811115611ab457600080fd5b81518560208202830111600160201b82111715611ad057600080fd5b50909d50505050505b60005b8a51811015611df25760008b8281518110611af357fe5b602002602001015190508160001480611b2157508b6001830381518110611b1657fe5b602002602001015181115b611b2a57600080fd5b6035548110611b3857600080fd5b60008981526030602090815260408083206001600160a01b038c168452825280832084845290915290205460ff1615611b715750611dea565b611b79615708565b8a6001600160a01b03168c6001600160a01b031614611c655787821015611ba1575050611dea565b818711158015611bb057508615155b15611bbc575050611df2565b611bc98289868d8f61474d565b9350816001019750856001600160a01b031663877ffdea85848d6040518463ffffffff1660e01b8152600401808481526020018381526020018281526020019350505050604080518083038186803b158015611c2457600080fd5b505afa158015611c38573d6000803e3d6000fd5b505050506040513d6040811015611c4e57600080fd5b508051602091820151918301919091528152611cec565b60408051631289b17960e01b815260048101849052602481018c905281516001600160a01b03891692631289b1799260448082019391829003018186803b158015611caf57600080fd5b505afa158015611cc3573d6000803e3d6000fd5b505050506040513d6040811015611cd957600080fd5b5080516020918201519183019190915281525b80518551611cff9163ffffffff6147bf16565b855260208082015190860151611d1a9163ffffffff6147bf16565b8560200181815250506001603060008c815260200190815260200160002060008b6001600160a01b03166001600160a01b03168152602001908152602001600020600084815260200190815260200160002060006101000a81548160ff021916908315150217905550818b6001600160a01b03168d6001600160a01b03167f6d8e1b032c4629c85b1e460dedd0e2d7c5eb72880982d3e495f0f892b7f64406846000015185602001518f60405180848152602001838152602001828152602001935050505060405180910390a450505b600101611adc565b50826001600160a01b03166370cafd65836000015184602001518b6040518463ffffffff1660e01b815260040180848152602001838152602001826001600160a01b03166001600160a01b031681526020019350505050600060405180830381600087803b158015611e6357600080fd5b505af1158015611e77573d6000803e3d6000fd5b5050505050505050505050505050565b603160209081526000928352604080842090915290825290205481565b60286020526000908152604090205481565b611ebe613c33565b6001600160a01b0316336001600160a01b031614611edb57600080fd5b611ee3611800565b611eec57600080fd5b602455565b611ef9613c33565b6001600160a01b0316336001600160a01b031614611f1657600080fd5b6001600160a01b038116611f2957600080fd5b6039546040805163a26301f960e01b815273eb43574e8f4fddf11fbaf65a8632ca92262a1266600482018190529151919269043c33c193756480000092849283926001600160a01b03169163a26301f991602480820192602092909190829003018186803b158015611f9a57600080fd5b505afa158015611fae573d6000803e3d6000fd5b505050506040513d6020811015611fc457600080fd5b505114611fd057600080fd5b6000838152600b6020526040812055611fea8180846142c8565b611ff484836147d1565b603554604080518481526020810186905281516001600160a01b0385169283927f5c5eecdba4673a19126d31c4ea006153eec8120d460905a4643cacd174da8722929081900390910190a450505050565b6000818152600660209081526040918290208054835181840281018401909452808452606093928301828280156120a557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612087575b50505050509050919050565b6120b9613c33565b6001600160a01b0316336001600160a01b0316146120d657600080fd5b6120de611800565b6120e757600080fd5b6001600160a01b0381166120fa57600080fd5b6053546001600160a01b03161561211057600080fd5b605380546001600160a01b0319166001600160a01b038316179055612133613c5c565b156117e057600080fd5b60245481565b6060600080548060200260200160405190810160405280929190818152602001828054801561219157602002820191906000526020600020905b81548152602001906001019080831161217d575b5050505050905090565b6039546040805163a26301f960e01b81526001600160a01b03858116600483015291516000938493169163a26301f9916024808301926020929190829003018186803b1580156121ea57600080fd5b505afa1580156121fe573d6000803e3d6000fd5b505050506040513d602081101561221457600080fd5b5051905060006001600160a01b038481169086161415612235576000612237565b835b90506001600160a01b038581169085161415612253838261488c565b6122635760009350505050611353565b60008381526031602090815260408083206001600160a01b0386168452909152902054816122ae576000848152600b60205260409020546122ab90829063ffffffff61453a16565b90505b60395460408051635245821560e11b81526004810187905290516001600160a01b039092169163a48b042a91602480820192602092909190829003018186803b1580156122fa57600080fd5b505afa15801561230e573d6000803e3d6000fd5b505050506040513d602081101561232457600080fd5b505161233557935061135392505050565b60006123418585611325565b90508082111561234f578091505b509695505050505050565b602660209081526000938452604080852082529284528284209052825290205481565b602c6020526000908152604090205481565b60375481565b603a5481565b60355481565b6001600160a01b031660009081526008602052604090205490565b60375460009080156123cf5760016123d2565b60005b60ff1660365482010391505090565b6039546001600160a01b031633146123f857600080fd5b6004546002541461240857600080fd5b6000818152600b60205260408120556117e0816148c2565b6039546040805163a26301f960e01b81526001600160a01b03858116600483015291516000938493169163a26301f9916024808301926020929190829003018186803b15801561246f57600080fd5b505afa158015612483573d6000803e3d6000fd5b505050506040513d602081101561249957600080fd5b505190506001600160a01b0384811690841614156000816124bb5760006124bd565b845b90506124c9838361488c565b6124d95760009350505050611353565b60395460408051635245821560e11b81526004810186905290516001600160a01b039092169163a48b042a91602480820192602092909190829003018186803b15801561252557600080fd5b505afa158015612539573d6000803e3d6000fd5b505050506040513d602081101561254f57600080fd5b50516125615760009350505050611353565b60008381526031602090815260408083206001600160a01b0385168452909152902054826125ac576000848152600b60205260409020546125a990829063ffffffff61453a16565b90505b6125c66125b98584611325565b829063ffffffff61453a16565b979650505050505050565b6060600060046005548180548060200260200160405190810160405280929190818152602001828054801561262557602002820191906000526020600020905b815481526020019060010190808311612611575b50505050509150915091509091565b60345481565b602e6020526000908152604090205481565b6000818152600760209081526040918290208054835181840281018401909452808452606093928301828280156120a5576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116120875750505050509050919050565b6039546001600160a01b031633146126cd57600080fd5b6117e0816141dc565b60006126e0611800565b6126e957600080fd5b6053546001600160a01b0316331461270057600080fd5b601482101561270e57600080fd5b600080606085858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050506020820151606081901c955060581c60ff1615801594509192506128239050576000806060602084015160ff8160501c16935050826040519080825280601f01601f1916602001820160405280156127a7576020820181803883390190505b50905082609a60208301378351609a84013560f01c92508190838501601801146127d057600080fd5b826040519080825280601f01601f1916602001820160405280156127fb576020820181803883390190505b5091508284609c016020840137816128188c8e8a60018686614a0e565b50505050505061282e565b61282e838989613cfa565b506001979650505050505050565b60606002805480602002602001604051908101604052809291908181526020018280548015612191576020028201919060005260206000209081548152602001906001019080831161217d575050505050905090565b6114148282614be1565b603b546001600160a01b031681565b3a6128b557600080fd5b6128bd611800565b6128c657600080fd5b6039546040805163a26301f960e01b81526001600160a01b0385811660048301529151600093929092169163a26301f991602480820192602092909190829003018186803b15801561291757600080fd5b505afa15801561292b573d6000803e3d6000fd5b505050506040513d602081101561294157600080fd5b505190506001600160a01b03831661295857600080fd5b8161296257600080fd5b8061296c57600080fd5b3360006001600160a01b038516821415612987576000612989565b815b90506129a0836001600160a01b038316151561488c565b6129a957600080fd5b60008381526027602090815260408083206001600160a01b0385168085529083528184205487855260288452828520546031855283862092865291845282852054888652603890945291842054919390929190881315612a8f5787612a0e8a88612420565b811115612a1a57600080fd5b612a2a858263ffffffff6147bf16565b9450612a3c848263ffffffff6147bf16565b9350612a4e838263ffffffff61453a16565b9250612a60828263ffffffff61453a16565b60355460008a81526029602090815260408083206001600160a01b038c1684529091529020559150612ade9050565b6000889003612aa4858263ffffffff61453a16565b9450612ab6848263ffffffff61453a16565b9350612ac8838263ffffffff6147bf16565b9250612ada828263ffffffff6147bf16565b9150505b60008781526027602090815260408083206001600160a01b03808a168086529184528285208990558b855260288452828520889055603184528285209185529083528184208690558a84526038909252909120829055868116908a161415612c24576000878152600b6020526040902054821015612b5b57600080fd5b811580612b6a57506024548210155b612b7357600080fd5b6039546040805163738bef1d60e11b8152600481018a905290516000926001600160a01b03169163e717de3a916024808301926020929190829003018186803b158015612bbf57600080fd5b505afa158015612bd3573d6000803e3d6000fd5b505050506040513d6020811015612be957600080fd5b50511590506000891315612c145782612c0f5780612c0657600080fd5b612c0f886146c4565b612c1e565b612c1e8882614c7f565b50612c6d565b811580612c3357506025548210155b612c3c57600080fd5b6000881315612c595781612c5457612c548787614cfb565b612c63565b612c638787614e4a565b612c6d8787614f07565b612c768761460b565b603554866001600160a01b03168a6001600160a01b03167f89b66c7c015442886e0ce3c9c8137443ebbe1b1766f6b3a942dde6c3bb82517d8b8b604051808381526020018281526020019250505060405180910390a4505050505050505050565b6000818152602d602052604081205481548110801561177957508260008281548110612cff57fe5b9060005260206000200154149392505050565b602f6020526000908152604090205481565b6001600160a01b038916612d3757600080fd5b85612d4157600080fd5b84612d4b57600080fd5b83612d5557600080fd5b82612d5f57600080fd5b808311612d6b57600080fd5b80612d7557600080fd5b612d7d613c58565b1580612da15750612d8c613c33565b6001600160a01b0316336001600160a01b0316145b612daa57600080fd5b612db2611800565b15612dbc57600080fd5b603980546001600160a01b03808c166001600160a01b031992831617909255603b8054928b169290911691909117905560005b86811015612edf57878782818110612e0357fe5b9050602002013560001415612e1757600080fd5b612e34888883818110612e2657fe5b905060200201356000614c7f565b6039546001600160a01b031663e717de3a898984818110612e5157fe5b905060200201356040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612e8c57600080fd5b505afa158015612ea0573d6000803e3d6000fd5b505050506040513d6020811015612eb657600080fd5b5051612ed757612ed7888883818110612ecb57fe5b905060200201356146c4565b600101612def565b5060258590556024849055603683905560378290556034819055612f01613c58565b603a55505050505050505050565b602d6020526000908152604090205481565b6039546040805163a26301f960e01b81526001600160a01b0384811660048301529151600093929092169163a26301f991602480820192602092909190829003018186803b158015612f7257600080fd5b505afa158015612f86573d6000803e3d6000fd5b505050506040513d6020811015612f9c57600080fd5b5051905080612faa57600080fd5b3360006001600160a01b038416821415612fc5576000612fc7565b815b60008481526029602090815260408083206001600160a01b038516845290915290205460355491925010612ffa57600080fd5b61300f836001600160a01b0383161515614fea565b1561301957600080fd5b60008381526027602090815260408083206001600160a01b03851684529091529020548061304657600080fd5b60008481526027602090815260408083206001600160a01b038616845282528083208390558683526028909152902054613086908263ffffffff61453a16565b600085815260286020908152604080832093909355603181528282206001600160a01b0386168352905220546130c1576130c18486856151a5565b6130cb83826147d1565b603554836001600160a01b0316866001600160a01b03167f3b1f0416a322c81d02b7eb108c29b8c9cf15503da84e83c389c529625b10389e8488604051808381526020018281526020019250505060405180910390a45050505050565b60606003805480602002602001604051908101604052809291908181526020018280548015612191576020028201919060005260206000209081548152602001906001019080831161217d575050505050905090565b602960209081526000928352604080842090915290825290205481565b60365481565b60255481565b60606001805480602002602001604051908101604052809291908181526020018280548015612191576020028201919060005260206000209081548152602001906001019080831161217d575050505050905090565b6039546001600160a01b031681565b602760209081526000928352604080842090915290825290205481565b60006125c6873388600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8d018190048102820181019092528b815292508b91508a9081908401838280828437600092019190915250614a0e92505050565b3a6132ad57600080fd5b6132b5611800565b6132be57600080fd5b6039546040805163a26301f960e01b815233600482015290516000926001600160a01b03169163a26301f9916024808301926020929190829003018186803b15801561330957600080fd5b505afa15801561331d573d6000803e3d6000fd5b505050506040513d602081101561333357600080fd5b505190508061334157600080fd5b600060355411806133c7575060395460408051639b4a14bf60e01b81526004810184905290516001600160a01b0390921691639b4a14bf91602480820192602092909190829003018186803b15801561339957600080fd5b505afa1580156133ad573d6000803e3d6000fd5b505050506040513d60208110156133c357600080fd5b5051155b6133d057600080fd5b6039546040805163738bef1d60e11b81526004810184905290516001600160a01b039092169163e717de3a91602480820192602092909190829003018186803b15801561341c57600080fd5b505afa158015613430573d6000803e3d6000fd5b505050506040513d602081101561344657600080fd5b5051156126cd57600080fd5b6039546001600160a01b0316331461346957600080fd5b603580546001019055565b610bb881565b6039546040805163a26301f960e01b81526001600160a01b03858116600483015291513393600093169163a26301f9916024808301926020929190829003018186803b1580156134c957600080fd5b505afa1580156134dd573d6000803e3d6000fd5b505050506040513d60208110156134f357600080fd5b505190506135028483856142c8565b61350c82846147d1565b603554826001600160a01b0316856001600160a01b03167f5c5eecdba4673a19126d31c4ea006153eec8120d460905a4643cacd174da87228685604051808381526020018281526020019250505060405180910390a450505050565b600080613573613c58565b905060375481101561358957600091505061180f565b6034546036546037549190039061359e576001015b60375490910310905090565b6039546040805163a26301f960e01b81526001600160a01b03858116600483015291516000938493849391169163a26301f991602480820192602092909190829003018186803b1580156135fd57600080fd5b505afa158015613611573d6000803e3d6000fd5b505050506040513d602081101561362757600080fd5b505190506001600160a01b03851661363e57600080fd5b6001600160a01b03841661365157600080fd5b8061365b57600080fd5b6000856001600160a01b0316856001600160a01b0316141561367e576000613680565b845b604080516002808252606080830184529394509091602083019080388339019050509050856001600160a01b0316876001600160a01b0316146137595760008381526032602090815260408083206001600160a01b038a1684529091528120548251909183916136ec57fe5b6020026020010181815250508060008151811061370557fe5b60200260200101516000141561371a57600080fd5b60008381526033602090815260408083206001600160a01b038a16845290915290205481518290600190811061374c57fe5b6020026020010181815250505b60395460408051632b5aa5d760e11b815290516000926001600160a01b0316916356b54bae916004808301926020929190829003018186803b15801561379e57600080fd5b505afa1580156137b2573d6000803e3d6000fd5b505050506040513d60208110156137c857600080fd5b505190506137d4615708565b50604080518082019091526000808252602082018190528a516138c157826001600160a01b031663e7f6cfe2876040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561383557600080fd5b505afa158015613849573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561387257600080fd5b810190808051600160201b81111561388957600080fd5b8201602081018481111561389c57600080fd5b81518560208202830111600160201b821117156138b857600080fd5b50909e50505050505b60005b8b51811015613c195780158061390257508b60018203815181106138e457fe5b60200260200101518c82815181106138f857fe5b6020026020010151115b61390b57600080fd5b6035548c828151811061391a57fe5b60200260200101511061392c57600080fd5b60008781526030602090815260408083206001600160a01b038a16845290915281208d519091908e908490811061395f57fe5b60209081029190910181015182528101919091526040016000205460ff161561398757613c11565b61398f615708565b8a6001600160a01b03168c6001600160a01b031614613b4157856000815181106139b557fe5b60200260200101518d83815181106139c957fe5b602002602001015110156139dd5750613c11565b8c82815181106139e957fe5b6020026020010151866001815181106139fe57fe5b602002602001015111158015613a29575085600181518110613a1c57fe5b6020026020010151600014155b15613a345750613c19565b613a688d8381518110613a4357fe5b602002602001015187600081518110613a5857fe5b6020026020010151858b8f61474d565b92508c8281518110613a7657fe5b602002602001015160010186600081518110613a8e57fe5b602002602001018181525050846001600160a01b031663877ffdea848f8581518110613ab657fe5b60200260200101518b6040518463ffffffff1660e01b8152600401808481526020018381526020018281526020019350505050604080518083038186803b158015613b0057600080fd5b505afa158015613b14573d6000803e3d6000fd5b505050506040513d6040811015613b2a57600080fd5b508051602091820151918301919091528152613bdc565b846001600160a01b0316631289b1798e8481518110613b5c57fe5b60200260200101518a6040518363ffffffff1660e01b81526004018083815260200182815260200192505050604080518083038186803b158015613b9f57600080fd5b505afa158015613bb3573d6000803e3d6000fd5b505050506040513d6040811015613bc957600080fd5b5080516020918201519183019190915281525b80518451613bef9163ffffffff6147bf16565b845260208082015190850151613c0a9163ffffffff6147bf16565b6020850152505b6001016138c4565b50508051602090910151909a909950975050505050505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b4390565b605354604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015613ca757600080fd5b505afa158015613cbb573d6000803e3d6000fd5b505050506040513d6020811015613cd157600080fd5b5051905090565b6000808211613ce657600080fd5b6000828481613cf157fe5b04949350505050565b3a613d0457600080fd5b613d0c611800565b613d1557600080fd5b6039546040805163a26301f960e01b81526001600160a01b0386811660048301529151600093929092169163a26301f991602480820192602092909190829003018186803b158015613d6657600080fd5b505afa158015613d7a573d6000803e3d6000fd5b505050506040513d6020811015613d9057600080fd5b505190506001600160a01b038416613da757600080fd5b80613db157600080fd5b81613dbb57600080fd5b60395460408051632682240f60e11b81526004810184905290516001600160a01b0390921691634d04481e91602480820192602092909190829003018186803b158015613e0757600080fd5b505afa158015613e1b573d6000803e3d6000fd5b505050506040513d6020811015613e3157600080fd5b505115613e3d57600080fd5b613e45613568565b613e4e57600080fd5b6000846001600160a01b0316846001600160a01b03161415613e71576000613e73565b835b60008381526031602090815260408083206001600160a01b038516845290915281205491925090613eaa908563ffffffff6147bf16565b9050856001600160a01b0316856001600160a01b03161415613eda57602454811015613ed557600080fd5b613f0c565b602554811015613ee957600080fd5b6000838152603160209081526040808320838052909152902054613f0c57600080fd5b60008381526031602090815260408083206001600160a01b03861684529091529020819055613f4b84613f3f8585611325565b9063ffffffff6147bf16565b6000848152600a602090815260408083206001600160a01b038716845282528083206035548452825280832093909355858252603890522054613f94908563ffffffff6147bf16565b6000848152603860205260409020556001600160a01b038581169087161415614040576039546040805163738bef1d60e11b815260048101869052905161403b9286926001600160a01b039091169163e717de3a91602480820192602092909190829003018186803b15801561400957600080fd5b505afa15801561401d573d6000803e3d6000fd5b505050506040513d602081101561403357600080fd5b505115614c7f565b614175565b61404a8386614e4a565b6140548386614f07565b6001600160a01b038516600090815260086020908152604080832080546009845282852088865290935290832054909282821015806140a957508684838154811061409b57fe5b906000526020600020015414155b905080156140e8576001600160a01b03891660009081526009602090815260408083208a84528252822085905585546001810187558683529120018790555b8261417057603954604080516341a32dc160e11b81526001600160a01b038c81166004830152915191909216916383465b82916024808301926020929190829003018186803b15801561413a57600080fd5b505afa15801561414e573d6000803e3d6000fd5b505050506040513d602081101561416457600080fd5b50511561417057600080fd5b505050505b61417e8361460b565b603554856001600160a01b0316876001600160a01b03167f1111552b4d689ce73a2a7356e066e28215e6d61a2294e89ac9e02a933ebb0d508787604051808381526020018281526020019250505060405180910390a4505050505050565b6000818152602d60205260408120549054811080156142115750816000828154811061420457fe5b9060005260206000200154145b1561428257600080548190600019810190811061422a57fe5b90600052602060002001549050806000838154811061424557fe5b6000918252602080832090910192909255828152602d9091526040808220849055848252812081905580549061427f906000198301615722565b50505b61428b826152f5565b1561429e5761429982615320565b6142a7565b6142a7826153c6565b6142b0826148c2565b6142b982615449565b6142c1613c58565b603a555050565b3a6142d257600080fd5b6142da611800565b6142e357600080fd5b6039546040805163a26301f960e01b81526001600160a01b0386811660048301529151600093929092169163a26301f991602480820192602092909190829003018186803b15801561433457600080fd5b505afa158015614348573d6000803e3d6000fd5b505050506040513d602081101561435e57600080fd5b505190506001600160a01b03841661437557600080fd5b8161437f57600080fd5b8061438957600080fd5b614393848461219b565b82111561439f57600080fd5b6000846001600160a01b0316846001600160a01b031614156143c25760006143c4565b835b60008381526031602090815260408083206001600160a01b0385168452909152812054919250906143fb908563ffffffff61453a16565b90506000856001600160a01b0316876001600160a01b0316141561443d576000848152600b602052604090205482101561443457600080fd5b50602454614442565b506025545b81158061444f5750808210155b61445857600080fd5b60008481526031602090815260408083206001600160a01b038716845290915281208390556144878585611325565b90508581101561449857600061449c565b8581035b6000868152600a602090815260408083206001600160a01b0389168452825280832060355484528252808320939093558782526038905220546144e5908763ffffffff61453a16565b60008681526038602052604090205582614504576145048589896151a5565b876001600160a01b0316876001600160a01b031614614527576145278588614f07565b6145308561460b565b5050505050505050565b60008282111561454957600080fd5b50900390565b6000818152602e602052604090205460025480821015806145875750826002838154811061457957fe5b906000526020600020015414155b156145fd576000838152602e602052604081208290556002805460018181019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0185905560048054918201815582527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01555b61460683615449565b505050565b614613613c58565b603a55600080614622836154ef565b91509150816146325750506117e0565b60006004828154811061464157fe5b90600052602060002001549050600060386000868152602001908152602001600020549050806004848154811061467457fe5b6000918252602090912001558181106146a45760055461469c9083830363ffffffff6147bf16565b6005556146bd565b6005546146b99082840363ffffffff61453a16565b6005555b5050505050565b6000818152602f602052604090205460035480821015806146fc575082600383815481106146ee57fe5b906000526020600020015414155b15614744576000838152602f602052604081208290556003805460018101825591527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b018390555b614606836148c2565b60005b5060008281526026602090815260408083206001600160a01b03851684528252808320888452909152902054801561479b5760001981146147915780614794565b60005b90506147b6565b848614156147aa5750826147b6565b60001990950194614750565b95945050505050565b60008282018381101561177957600080fd5b3a6147db57600080fd5b6147e3611800565b6147ec57600080fd5b6053546001600160a01b031661480157600080fd5b6053546040805163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561485757600080fd5b505af115801561486b573d6000803e3d6000fd5b505050506040513d602081101561488157600080fd5b50516142b957600080fd5b60006148988383614fea565b156148a557506000611353565b6148ad613568565b6148b957506000611353565b50600192915050565b600454600254146148d2576117e0565b6000818152602e602052604090205460025481108015614908575081600282815481106148fb57fe5b9060005260206000200154145b15611414576004818154811061491a57fe5b906000526020600020015460055410614955576004818154811061493a57fe5b6000918252602090912001546005805491909103905561495b565b60006005555b600280546000198101916000918390811061497257fe5b90600052602060002001549050806002848154811061498d57fe5b9060005260206000200181905550600482815481106149a857fe5b9060005260206000200154600484815481106149c057fe5b6000918252602080832090910192909255828152602e909152604080822085905585825281205560028054906149fa906000198301615722565b5060048054906146bd906000198301615722565b60395460405163374dc77d60e01b81526001600160a01b03868116600483019081528882166024840152608060448401908152865160848501528651600095869594169363374dc77d938b938d938b938b939291606482019160a4019060208701908083838f5b83811015614a8d578181015183820152602001614a75565b50505050905090810190601f168015614aba5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015614aed578181015183820152602001614ad5565b50505050905090810190601f168015614b1a5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b158015614b3d57600080fd5b505af1158015614b51573d6000803e3d6000fd5b505050506040513d6020811015614b6757600080fd5b505190508415614b8157614b7c87888a613cfa565b614b8b565b614b8b8789614be1565b856001600160a01b0316876001600160a01b03167f7342ad45e4a4592daa7f7e40b50c1c2ce42aa21da0242065e849a8509de7ba7e836040518082815260200191505060405180910390a3979650505050505050565b33614bed838284613cfa565b3415614bf857600080fd5b6053546001600160a01b0316614c0d57600080fd5b605354604080516356e4bb9760e11b81526001600160a01b038481166004830152602482018690529151919092169163adc9772e91604480830192600092919082900301818387803b158015614c6257600080fd5b505af1158015614c76573d6000803e3d6000fd5b50505050505050565b614c8882612cd7565b614ce35760008054838252602d602052604082208190556001810182559080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56301829055614cd561553f565b6000541115614ce357600080fd5b614cec82615320565b8015611414576114148261454f565b6000828152600660209081526040808320602a83528184206001600160a01b038616855290925290912054815481108015614d5e5750826001600160a01b0316828281548110614d4757fe5b6000918252602090912001546001600160a01b0316145b15614e0357815460009083906000198101908110614d7857fe5b9060005260206000200160009054906101000a90046001600160a01b0316905080838381548110614da557fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055878252602a8152604080832085851684529091528082208590559186168152908120558254614e00846000198301615722565b50505b60008481526027602090815260408083206001600160a01b038716845290915290205415614e3a57614e358484615545565b614e44565b614e4484846155fb565b50505050565b6000828152600660209081526040808320602a83528184206001600160a01b03861685529092529091205481548082101580614eaf5750836001600160a01b0316838381548110614e9757fe5b6000918252602090912001546001600160a01b031614155b15614efd576000858152602a602090815260408083206001600160a01b0388168085529083529083208490558554600181018755868452919092200180546001600160a01b03191690911790555b6146bd85856155fb565b60355460008381526031602090815260408083206001600160a01b038616845290915290205460019091019080614f4057600019614f42565b805b60008581526026602090815260408083206001600160a01b038816808552908352818420878552835281842094909455878352603282528083209383529290522054614fae5760008481526032602090815260408083206001600160a01b038716845290915290208290555b8015614fbb576000614fbd565b815b60009485526033602090815260408087206001600160a01b03909616875294905292909320919091555050565b6000811561507c57603954604080516352700f5560e11b81526004810186905290516001600160a01b039092169163a4e01eaa91602480820192602092909190829003018186803b15801561503e57600080fd5b505afa158015615052573d6000803e3d6000fd5b505050506040513d602081101561506857600080fd5b50511561507757506001611353565b61519c565b60395460408051632682240f60e11b81526004810186905290516001600160a01b0390921691634d04481e91602480820192602092909190829003018186803b1580156150c857600080fd5b505afa1580156150dc573d6000803e3d6000fd5b505050506040513d60208110156150f257600080fd5b50511561510157506001611353565b603b546001600160a01b03161580159061518f5750603b546040805163cd2ecdf360e01b81526004810186905290516001600160a01b039092169163cd2ecdf391602480820192602092909190829003018186803b15801561516257600080fd5b505afa158015615176573d6000803e3d6000fd5b505050506040513d602081101561518c57600080fd5b50515b1561519c57506001611353565b50600092915050565b816001600160a01b0316816001600160a01b031614156152d4576039546040805163738bef1d60e11b81526004810186905290516001600160a01b039092169163e717de3a91602480820192602092909190829003018186803b15801561520b57600080fd5b505afa15801561521f573d6000803e3d6000fd5b505050506040513d602081101561523557600080fd5b50516152cf5760395460408051639b4a14bf60e01b81526004810186905290516001600160a01b0390921691639b4a14bf91602480820192602092909190829003018186803b15801561528757600080fd5b505afa15801561529b573d6000803e3d6000fd5b505050506040513d60208110156152b157600080fd5b5051156152c6576152c1836146c4565b6152cf565b6152cf836141dc565b614606565b6152de8382614cfb565b6152e7836152f5565b156146065761460683615320565b6000818152603860205260408120541580156113535750506000908152602860205260409020541590565b6000818152602c6020526040902054600154811080156153565750816001828154811061534957fe5b9060005260206000200154145b15611414576001805460009190600019810190811061537157fe5b90600052602060002001549050806001838154811061538c57fe5b6000918252602080832090910192909255828152602c90915260408082208490558482528120556001805490614e44906000198301615722565b6000818152602c602052604090205460015480821015806153fe575082600183815481106153f057fe5b906000526020600020015414155b15614606576000838152602c6020526040812082905560018054808201825591527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf601839055505050565b6000818152602f60205260409020546003548110801561547f5750816003828154811061547257fe5b9060005260206000200154145b15611414576003805460009190600019810190811061549a57fe5b9060005260206000200154905080600383815481106154b557fe5b6000918252602080832090910192909255828152602f90915260408082208490558482528120556003805490614e44906000198301615722565b6000818152602e6020526040812054600254811080156155255750826002828154811061551857fe5b9060005260206000200154145b15615533576001915061553a565b5060009050805b915091565b610bb890565b6000828152600760209081526040808320602b83528184206001600160a01b038616855290925290912054815480821015806155aa5750836001600160a01b031683838154811061559257fe5b6000918252602090912001546001600160a01b031614155b156146bd576000948552602b602090815260408087206001600160a01b039690961680885295825286209190915582546001810184559285529093200180546001600160a01b031916909117905550565b6000828152600760209081526040808320602b83528184206001600160a01b03861685529092529091205481548110801561565e5750826001600160a01b031682828154811061564757fe5b6000918252602090912001546001600160a01b0316145b15614e445781546000908390600019810190811061567857fe5b9060005260206000200160009054906101000a90046001600160a01b03169050808383815481106156a557fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055878252602b8152604080832085851684529091528082208590559186168152908120558254615700846000198301615722565b505050505050565b604051806040016040528060008152602001600081525090565b8154818355818111156146065760008381526020902061460691810190830161180f91905b8082111561575b5760008155600101615747565b509056fea265627a7a72305820996d14df4eb718bdfaf51d30633ce9f875a01d08087e1f0c649175bcda695ad364736f6c634300050a0032"
+ },
+ "0x2000000000000000000000000000000000000001": {
+ "balance": "0x0",
+ "constructor": "0x60806040526040516108053803806108058339818101604052604081101561002657600080fd5b50805160209182015160408051600081529384018082527f656970313936372e70726f78792e696d706c656d656e746174696f6e00000000905251603c81850301902091929091839190600019016000805160206107aa8339815191521461008a57fe5b61009c826001600160e01b036101bd16565b805115610154576000826001600160a01b0316826040518082805190602001908083835b602083106100df5780518252601f1990920191602091820191016100c0565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461013f576040519150601f19603f3d011682016040523d82523d6000602084013e610144565b606091505b505090508061015257600080fd5b505b5050604080517f656970313936372e70726f78792e61646d696e000000000000000000000000008152905190819003601301902060008051602061078a833981519152600019909101146101a457fe5b6101b6816001600160e01b0361023716565b505061024f565b6101d08161024960201b6104801760201c565b610225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806107ca603b913960400191505060405180910390fd5b6000805160206107aa83398151915255565b60008051602061078a83398151915255565b3b151590565b61052c8061025e6000396000f3fe60806040526004361061004a5760003560e01c80633659cfe6146100545780634f1ef286146100875780635c60da1b146101075780638f28397014610138578063f851a4401461016b575b610052610180565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661019a565b6100526004803603604081101561009d57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100c857600080fd5b8201836020820111156100da57600080fd5b803590602001918460018302840111640100000000831117156100fc57600080fd5b5090925090506101cb565b34801561011357600080fd5b5061011c61026f565b604080516001600160a01b039092168252519081900360200190f35b34801561014457600080fd5b506100526004803603602081101561015b57600080fd5b50356001600160a01b031661027e565b34801561017757600080fd5b5061011c61033c565b610188610198565b610198610193610346565b61036b565b565b6101a261038f565b6001600160a01b0316336001600160a01b0316146101bf57600080fd5b6101c8816103b4565b50565b6101d361038f565b6001600160a01b0316336001600160a01b0316146101f057600080fd5b6101f9836103b4565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610256576040519150601f19603f3d011682016040523d82523d6000602084013e61025b565b606091505b505090508061026957600080fd5b50505050565b6000610279610346565b905090565b61028661038f565b6001600160a01b0316336001600160a01b0316146102a357600080fd5b6001600160a01b0381166102e85760405162461bcd60e51b81526004018080602001828103825260368152602001806104876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61031161038f565b604080516001600160a01b03928316815291841660208301528051918290030190a16101c8816103f4565b600061027961038f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561038a573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103bd81610418565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b61042181610480565b61045c5760405162461bcd60e51b815260040180806020018281038252603b8152602001806104bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b3b15159056fe43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a265627a7a72305820a9aab4b95b654a79b32f5aa284796894f8329aaa083932695296085b196c27bd64736f6c634300050a0032b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000000000000000002000000000000000000000000000000000000000000000000000000000000000b03a86b3126157c039b55e21d378587ccfc04d45"
+ },
+ "0x2000000000000000000000000000000000000000": {
+ "balance": "0x0",
+ "constructor": "0x608060405234801561001057600080fd5b50614620806100206000396000f3fe6080604052600436106102935760003560e01c80636834fc901161015a578063adc481a7116100c1578063dfc8bf4e1161007a578063dfc8bf4e14610d5c578063e706ba2714610d71578063e7f6cfe214610da1578063f8fdc6b914610dcb578063f91c289814610dfb578063faaf3aff14610f5f57610293565b8063adc481a714610c8f578063b25a00fd14610ca4578063b4a523e814610cb9578063c5dd762814610cec578063cc7cab9514610d01578063cdf7a09014610d3257610293565b80638c439867116101135780638c43986714610ad65780639a0a9fdc14610b51578063a4c0ed3614610b66578063a9add57d14610c2c578063aa9fa27414610c41578063ac8a094214610c7a57610293565b80636834fc901461096557806368c49f3d146109e057806370cafd65146109f5578063727b071d14610a345780638737929a14610a64578063877ffdea14610aa057610293565b80633bf47e96116101fe5780634b6368cf116101b75780634b6368cf1461086a5780634de6c0361461087f57806353251389146108ba578063553a5c85146108e45780635fba554e146108f9578063621784781461093b57610293565b80633bf47e96146106c45780633d84b8c1146106ee578063419ce2641461072157806343544960146107365780634476d66a14610805578063485cc9551461082f57610293565b8063212329f311610250578063212329f31461042d578063222fafb2146105375780632ee57f8d14610561578063307bff261461059357806330f6eb1614610662578063392e53cd1461069b57610293565b80630ac2daa014610298578063118d2191146102da5780631289b1791461030f578063128b265f14610358578063171d54dd146103825780631f1a01b7146103fd575b600080fd5b3480156102a457600080fd5b506102c8600480360360408110156102bb57600080fd5b5080359060200135610f74565b60408051918252519081900360200190f35b3480156102e657600080fd5b5061030d600480360360208110156102fd57600080fd5b50356001600160a01b0316610f91565b005b34801561031b57600080fd5b5061033f6004803603604081101561033257600080fd5b5080359060200135610fe9565b6040805192835260208301919091528051918290030190f35b34801561036457600080fd5b5061030d6004803603602081101561037b57600080fd5b5035611073565b34801561038e57600080fd5b5061030d600480360360208110156103a557600080fd5b810190602081018135600160201b8111156103bf57600080fd5b8201836020820111156103d157600080fd5b803590602001918460208302840111600160201b831117156103f257600080fd5b50909250905061107f565b34801561040957600080fd5b506102c86004803603604081101561042057600080fd5b508035906020013561117a565b34801561043957600080fd5b506104e76004803603608081101561045057600080fd5b81359190810190604081016020820135600160201b81111561047157600080fd5b82018360208201111561048357600080fd5b803590602001918460208302840111600160201b831117156104a457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505082359350505060200135611197565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561052357818101518382015260200161050b565b505050509050019250505060405180910390f35b34801561054357600080fd5b5061030d6004803603602081101561055a57600080fd5b5035611269565b34801561056d57600080fd5b506105766112e6565b604080516001600160e01b03199092168252519081900360200190f35b34801561059f57600080fd5b5061033f600480360360a08110156105b657600080fd5b6001600160a01b038235169160208101359160408201359160608101359181019060a081016080820135600160201b8111156105f157600080fd5b82018360208201111561060357600080fd5b803590602001918460208302840111600160201b8311171561062457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506112f2945050505050565b34801561066e57600080fd5b506102c86004803603604081101561068557600080fd5b506001600160a01b038135169060200135611318565b3480156106a757600080fd5b506106b0611335565b604080519115158252519081900360200190f35b3480156106d057600080fd5b506102c8600480360360208110156106e757600080fd5b5035611346565b3480156106fa57600080fd5b506102c86004803603602081101561071157600080fd5b50356001600160a01b031661192e565b34801561072d57600080fd5b506104e7611940565b34801561074257600080fd5b5061033f600480360360a081101561075957600080fd5b6001600160a01b038235169160208101359160408201359160608101359181019060a081016080820135600160201b81111561079457600080fd5b8201836020820111156107a657600080fd5b803590602001918460208302840111600160201b831117156107c757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506119a2945050505050565b34801561081157600080fd5b506102c86004803603602081101561082857600080fd5b50356119b2565b34801561083b57600080fd5b5061030d6004803603604081101561085257600080fd5b506001600160a01b03813581169160200135166119c4565b34801561087657600080fd5b506102c8611a78565b34801561088b57600080fd5b506104e7600480360360408110156108a257600080fd5b506001600160a01b0381358116916020013516611a83565b3480156108c657600080fd5b5061030d600480360360208110156108dd57600080fd5b5035611ee1565b3480156108f057600080fd5b506102c8611eea565b34801561090557600080fd5b506102c8600480360360a081101561091c57600080fd5b5080359060208101359060408101359060608101359060800135611ef0565b34801561094757600080fd5b5061030d6004803603602081101561095e57600080fd5b5035611f93565b34801561097157600080fd5b5061030d6004803603602081101561098857600080fd5b810190602081018135600160201b8111156109a257600080fd5b8201836020820111156109b457600080fd5b803590602001918460208302840111600160201b831117156109d557600080fd5b50909250905061202a565b3480156109ec57600080fd5b506102c8612121565b348015610a0157600080fd5b5061030d60048036036060811015610a1857600080fd5b50803590602081013590604001356001600160a01b0316612127565b348015610a4057600080fd5b506102c860048036036040811015610a5757600080fd5b50803590602001356122bf565b348015610a7057600080fd5b506102c860048036036080811015610a8757600080fd5b50803590602081013590604081013590606001356122dc565b348015610aac57600080fd5b5061033f60048036036060811015610ac357600080fd5b5080359060208101359060400135612356565b348015610ae257600080fd5b5061030d60048036036020811015610af957600080fd5b810190602081018135600160201b811115610b1357600080fd5b820183602082011115610b2557600080fd5b803590602001918460208302840111600160201b83111715610b4657600080fd5b5090925090506123ea565b348015610b5d57600080fd5b506104e76124e1565b348015610b7257600080fd5b506106b060048036036060811015610b8957600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610bb857600080fd5b820183602082011115610bca57600080fd5b803590602001918460018302840111600160201b83111715610beb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612541945050505050565b348015610c3857600080fd5b506102c8612548565b348015610c4d57600080fd5b5061030d60048036036040811015610c6457600080fd5b50803590602001356001600160a01b0316612555565b348015610c8657600080fd5b506102c86125e0565b348015610c9b57600080fd5b506102c86125e6565b348015610cb057600080fd5b506104e76125ec565b348015610cc557600080fd5b506102c860048036036020811015610cdc57600080fd5b50356001600160a01b031661264c565b348015610cf857600080fd5b5061030d61265e565b348015610d0d57600080fd5b50610d16612881565b604080516001600160a01b039092168252519081900360200190f35b348015610d3e57600080fd5b506102c860048036036020811015610d5557600080fd5b5035612890565b348015610d6857600080fd5b50610d166128a2565b348015610d7d57600080fd5b506102c860048036036040811015610d9457600080fd5b50803590602001356128b1565b348015610dad57600080fd5b506104e760048036036020811015610dc457600080fd5b50356128ce565b348015610dd757600080fd5b506102c860048036036040811015610dee57600080fd5b508035906020013561292e565b348015610e0757600080fd5b50610ec660048036036040811015610e1e57600080fd5b810190602081018135600160201b811115610e3857600080fd5b820183602082011115610e4a57600080fd5b803590602001918460208302840111600160201b83111715610e6b57600080fd5b919390929091602081019035600160201b811115610e8857600080fd5b820183602082011115610e9a57600080fd5b803590602001918460208302840111600160201b83111715610ebb57600080fd5b509092509050612949565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610f0a578181015183820152602001610ef2565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610f49578181015183820152602001610f31565b5050505090500194505050505060405180910390f35b348015610f6b57600080fd5b506102c8613211565b602960209081526000928352604080842090915290825290205481565b610f99613217565b6001600160a01b0316336001600160a01b031614610fb657600080fd5b610fbe611335565b610fc757600080fd5b604d80546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152602a6020908152604080832084845282528083205485845260298352818420858552835281842054868552604b84528285208686529093529083205483929061103c908790849084906122dc565b6000878152602260209081526040808320898452909152902054909450611068908790849084906122dc565b925050509250929050565b61107c81611f93565b50565b611087613217565b6001600160a01b0316336001600160a01b0316146110a457600080fd5b6110ac611335565b6110b557600080fd5b60005b60025481101561111157600060016000600284815481106110d557fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016110b8565b61111d60028484614526565b50600090505b8181101561117557600180600085858581811061113c57fe5b602090810292909201356001600160a01b0316835250810191909152604001600020805460ff1916911515919091179055600101611123565b505050565b602260209081526000928352604080842090915290825290205481565b606080836111bf576040805160008152602081019091526111b990849061323c565b90955093505b8515806111ca575083155b156111e4575060408051600081526020810190915261125e565b845160405190808252806020026020018201604052801561120f578160200160208202803883390190505b50905060005b855181101561125c578486828151811061122b57fe5b602002602001015188028161123c57fe5b0482828151811061124957fe5b6020908102919091010152600101611215565b505b90505b949350505050565b3360009081526001602052604090205460ff1661128557600080fd5b8061128f57600080fd5b6021546112a2908263ffffffff6134a316565b6021819055604080518381526020810192909252805133927f619cc90cbd264bea3dfc113e68fd307789a937a8c10ef4b0110607ac7490367392908290030190a250565b63069ad3e560e11b5b90565b60008061130a61130287856134bc565b8887876134d7565b915091509550959350505050565b602460209081526000928352604080842090915290825290205481565b602c546001600160a01b0316151590565b600080602c60009054906101000a90046001600160a01b03166001600160a01b031663ee99205c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561139757600080fd5b505afa1580156113ab573d6000803e3d6000fd5b505050506040513d60208110156113c157600080fd5b505160408051630f29818d60e31b815290519192506000916001600160a01b0384169163794c0c68916004808301926020929190829003018186803b15801561140957600080fd5b505afa15801561141d573d6000803e3d6000fd5b505050506040513d602081101561143357600080fd5b505190508061144757600092505050611929565b602c5460408051639b4a14bf60e01b81526004810187905290516001600160a01b0390921691639b4a14bf91602480820192602092909190829003018186803b15801561149357600080fd5b505afa1580156114a7573d6000803e3d6000fd5b505050506040513d60208110156114bd57600080fd5b50511561150a576000818152602a602090815260408083208784528252808320548484526029835281842088855290925290912054611501918391620f42406122dc565b92505050611929565b602c60009054906101000a90046001600160a01b03166001600160a01b031663b927ef436040518163ffffffff1660e01b815260040160206040518083038186803b15801561155857600080fd5b505afa15801561156c573d6000803e3d6000fd5b505050506040513d602081101561158257600080fd5b50516118285760606000602c60009054906101000a90046001600160a01b03166001600160a01b0316636729c2dc6040518163ffffffff1660e01b815260040160006040518083038186803b1580156115da57600080fd5b505afa1580156115ee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561161757600080fd5b810190808051600160201b81111561162e57600080fd5b8201602081018481111561164157600080fd5b81518560208202830111600160201b8211171561165d57600080fd5b5090955060009450505050505b81518110156116de5781818151811061167f57fe5b60200260200101518614156116d6576000838152602a60209081526040808320898452825280832054868452602983528184208a8552909252909120546116cb918591620f42406122dc565b945050505050611929565b60010161166a565b602c60009054906101000a90046001600160a01b03166001600160a01b0316630bf480c06040518163ffffffff1660e01b815260040160006040518083038186803b15801561172c57600080fd5b505afa158015611740573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561176957600080fd5b810190808051600160201b81111561178057600080fd5b8201602081018481111561179357600080fd5b81518560208202830111600160201b821117156117af57600080fd5b5090955060009450505050505b8151811015611825578181815181106117d157fe5b602002602001015186141561181d576000838152602a60209081526040808320898452825280832054868452602983528184208a8552909252909120546116cb918591620f42406122dc565b6001016117bc565b50505b60408051630fec687960e21b8152600481018690526000602482015290516119249183916001600160a01b03861691633fb1a1e4916044808301926020929190829003018186803b15801561187c57600080fd5b505afa158015611890573d6000803e3d6000fd5b505050506040513d60208110156118a657600080fd5b505160408051632a8f6ecd60e01b81526004810189905290516001600160a01b03871691632a8f6ecd916024808301926020929190829003018186803b1580156118ef57600080fd5b505afa158015611903573d6000803e3d6000fd5b505050506040513d602081101561191957600080fd5b5051620f42406122dc565b925050505b919050565b60236020526000908152604090205481565b6060600280548060200260200160405190810160405280929190818152602001828054801561199857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161197a575b5050505050905090565b60008061130a6113028785613578565b60256020526000908152604090205481565b6119cc61359b565b15806119f057506119db613217565b6001600160a01b0316336001600160a01b0316145b6119f957600080fd5b611a01611335565b15611a0b57600080fd5b6001600160a01b038216611a1e57600080fd5b602c80546001600160a01b039384166001600160a01b0319918216179091556000808052602b6020527fe18c65fb8491ea105d3652ed62258476aaccd771ae89682addbba12f33acc62a5560038054929093169116179055565b660b1a2bc2ec500081565b602c546040805163a26301f960e01b81526001600160a01b0385811660048301529151606093600093169163a26301f9916024808301926020929190829003018186803b158015611ad357600080fd5b505afa158015611ae7573d6000803e3d6000fd5b505050506040513d6020811015611afd57600080fd5b505190506001600160a01b038416611b1457600080fd5b6001600160a01b038316611b2757600080fd5b80611b3157600080fd5b602c5460408051633ba6481760e21b815290516000926001600160a01b03169163ee99205c916004808301926020929190829003018186803b158015611b7657600080fd5b505afa158015611b8a573d6000803e3d6000fd5b505050506040513d6020811015611ba057600080fd5b5051905060006001600160a01b038581169087161415611bc1576000611bc3565b845b90506000806001600160a01b03831615611d1157836001600160a01b03166327d89b3a86856040518363ffffffff1660e01b815260040180838152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b158015611c3557600080fd5b505afa158015611c49573d6000803e3d6000fd5b505050506040513d6020811015611c5f57600080fd5b5051915081611c845750506040805160008152602081019091529350611edb92505050565b836001600160a01b031663381883b086856040518363ffffffff1660e01b815260040180838152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b158015611ce257600080fd5b505afa158015611cf6573d6000803e3d6000fd5b505050506040513d6020811015611d0c57600080fd5b505190505b600085815260208181526040918290208054835181815281840281019093019093529190606090828015611d4f578160200160208202803883390190505b5090506000805b83811015611e63576000858281548110611d6c57fe5b60009182526020909120015490506001600160a01b03891615611db15787811015611d975750611e5b565b808711158015611da657508615155b15611db15750611e63565b6040805163186dc46f60e01b8152600481018d90526001600160a01b038b81166024830152604482018490529151918c169163186dc46f91606480820192602092909190829003018186803b158015611e0957600080fd5b505afa158015611e1d573d6000803e3d6000fd5b505050506040513d6020811015611e3357600080fd5b5051611e595780848480600101955081518110611e4c57fe5b6020026020010181815250505b505b600101611d56565b81604051908082528060200260200182016040528015611e8d578160200160208202803883390190505b509a50600090505b81811015611ed057828181518110611ea957fe5b60200260200101518b8281518110611ebd57fe5b6020908102919091010152600101611e95565b505050505050505050505b92915050565b61107c81611269565b60265481565b6000841580611efd575083155b80611f06575082155b15611f1357506000611f8a565b60008085851015611f25576000611f29565b8585035b905080611f3b57600092505050611f8a565b6000888152602b6020526040902054818102606482900388021115611f6d578588860281611f6557fe5b049250611f84565b81606402816064038987020281611f8057fe5b0492505b50909150505b95945050505050565b3360009081526046602052604090205460ff1680611fc057503360009081526047602052604090205460ff165b611fc957600080fd5b80611fd357600080fd5b604a54611fe6908263ffffffff6134a316565b604a819055604080518381526020810192909252805133927f412edf02d82089ccd9d6158ca78bb761a19c8f63a840cff791e4ad472bcaa0ac92908290030190a250565b612032613217565b6001600160a01b0316336001600160a01b03161461204f57600080fd5b612057611335565b61206057600080fd5b60005b6049548110156120bc576000604760006049848154811061208057fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff1916911515919091179055600101612063565b6120c860498484614526565b50600090505b81811015611175576001604760008585858181106120e857fe5b602090810292909201356001600160a01b0316835250810191909152604001600020805460ff19169115159190911790556001016120ce565b604c5481565b602c60009054906101000a90046001600160a01b03166001600160a01b031663ee99205c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561217557600080fd5b505afa158015612189573d6000803e3d6000fd5b505050506040513d602081101561219f57600080fd5b50516001600160a01b031633146121b557600080fd5b82156122b55760003390506000816001600160a01b0316632d21d2176040518163ffffffff1660e01b815260040160206040518083038186803b1580156121fb57600080fd5b505afa15801561220f573d6000803e3d6000fd5b505050506040513d602081101561222557600080fd5b50516040805163a9059cbb60e01b81526001600160a01b0386811660048301526024820189905291519293509083169163a9059cbb916044808201926020929091908290030181600087803b15801561227d57600080fd5b505af1158015612291573d6000803e3d6000fd5b505050506040513d60208110156122a757600080fd5b50516122b257600080fd5b50505b611175828261359f565b602a60209081526000928352604080842090915290825290205481565b60008315806122e9575082155b156122f657506000611261565b6000808585101561230857600061230c565b8585035b6000888152602b602052604090205490915080820260648290038802111561234157858786028161233957fe5b04925061234a565b60648582020492505b50909695505050505050565b6000828152602a6020908152604080832084845282528083205485845260298352818420858552835281842054868552604b8452828520868652909352908320548392906123ab908790899085908590611ef0565b93506123de86888484602260008c815260200190815260200160002060008b815260200190815260200160002054611ef0565b92505050935093915050565b6123f2613217565b6001600160a01b0316336001600160a01b03161461240f57600080fd5b612417611335565b61242057600080fd5b60005b60485481101561247c576000604660006048848154811061244057fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff1916911515919091179055600101612423565b61248860488484614526565b50600090505b81811015611175576001604660008585858181106124a857fe5b602090810292909201356001600160a01b0316835250810191909152604001600020805460ff191691151591909117905560010161248e565b60606048805480602002602001604051908101604052809291908181526020018280548015611998576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161197a575050505050905090565b6000806000fd5b6004546005540360010190565b3360009081526001602052604090205460ff1661257157600080fd5b8161257b57600080fd5b600354600160a01b900460ff1661259157600080fd5b61259c828233613617565b60408051838152905133916001600160a01b038416917f3c798bbcf33115b42c728b8504cff11dd58736e9fa789f1cda2738db7d696b2a9181900360200190a35050565b60215481565b60285481565b60606049805480602002602001604051908101604052809291908181526020018280548015611998576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161197a575050505050905090565b60276020526000908152604090205481565b602c546001600160a01b0316331461267557600080fd5b602c5460408051633ba6481760e21b815290516000926001600160a01b03169163ee99205c916004808301926020929190829003018186803b1580156126ba57600080fd5b505afa1580156126ce573d6000803e3d6000fd5b505050506040513d60208110156126e457600080fd5b505160408051630f29818d60e31b815290519192506000916001600160a01b0384169163794c0c68916004808301926020929190829003018186803b15801561272c57600080fd5b505afa158015612740573d6000803e3d6000fd5b505050506040513d602081101561275657600080fd5b5051602c5460408051637f2a23bf60e11b815290519293506060926001600160a01b039092169163fe54477e91600480820192600092909190829003018186803b1580156127a357600080fd5b505afa1580156127b7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156127e057600080fd5b810190808051600160201b8111156127f757600080fd5b8201602081018481111561280a57600080fd5b81518560208202830111600160201b8211171561282657600080fd5b50909450600093505050505b815181101561287b57600083815260208052604081208351829085908590811061285857fe5b602090810291909101810151825281019190915260400160002055600101612832565b50505050565b604d546001600160a01b031681565b602b6020526000908152604090205481565b602c546001600160a01b031681565b604b60209081526000928352604080842090915290825290205481565b6000818152602081815260409182902080548351818402810184019094528084526060939283018282801561292257602002820191906000526020600020905b81548152602001906001019080831161290e575b50505050509050919050565b60208080526000928352604080842090915290825290205481565b6060806002600160a01b03331461295f57600080fd5b848314158061296f575060018514155b8061299657508383600081811061298257fe5b9050602002013561ffff1661ffff16600014155b156129c75760408051600080825260208201909252905b506040805160008152602081019091529092509050613208565b602c546001600160a01b03166129ed5760408051600080825260208201909252906129ad565b602c60009054906101000a90046001600160a01b03166001600160a01b031663ccf69e9b6040518163ffffffff1660e01b815260040160206040518083038186803b158015612a3b57600080fd5b505afa158015612a4f573d6000803e3d6000fd5b505050506040513d6020811015612a6557600080fd5b50516040805163109c110760e01b815290516001600160a01b039092169163109c11079160048082019260009290919082900301818387803b158015612aaa57600080fd5b505af1158015612abe573d6000803e3d6000fd5b5050600354600160a01b900460ff169150612afa905057600160045560006005556003805460ff60a01b1916600160a01b179055612afa61368c565b602c5460408051633ba6481760e21b815290516064926000926001600160a01b039091169163ee99205c91600480820192602092909190829003018186803b158015612b4557600080fd5b505afa158015612b59573d6000803e3d6000fd5b505050506040513d6020811015612b6f57600080fd5b505160408051630f29818d60e31b815290519192506000916001600160a01b0384169163794c0c68916004808301926020929190829003018186803b158015612bb757600080fd5b505afa158015612bcb573d6000803e3d6000fd5b505050506040513d6020811015612be157600080fd5b50516040805163461121d760e11b815290519192506000916001600160a01b03851691638c2243ae916004808301926020929190829003018186803b158015612c2957600080fd5b505afa158015612c3d573d6000803e3d6000fd5b505050506040513d6020811015612c5357600080fd5b5051602c546040805163b927ef4360e01b815290519293506000926001600160a01b039092169163b927ef4391600480820192602092909190829003018186803b158015612ca057600080fd5b505afa158015612cb4573d6000803e3d6000fd5b505050506040513d6020811015612cca57600080fd5b505115612e3f578215801590612d7b5750602c546001600160a01b031663a92252ae8c8c600081612cf757fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612d4d57600080fd5b505afa158015612d61573d6000803e3d6000fd5b505050506040513d6020811015612d7757600080fd5b5051155b15612e3f57602c546000906001600160a01b0316632bbb7b728d8d8481612d9e57fe5b905060200201356001600160a01b03166040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612df457600080fd5b505afa158015612e08573d6000803e3d6000fd5b505050506040513d6020811015612e1e57600080fd5b50516000858152602080805260408083209383529290522080546001019055505b81612e4861359b565b14156131f4578215612e6257612e5f8484846137ee565b90505b602c60009054906101000a90046001600160a01b03166001600160a01b0316635ccee1de6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612eb257600080fd5b505af1158015612ec6573d6000803e3d6000fd5b5050602c54604080516319ca70b760e21b81529051600094506001880193506060926001600160a01b031691636729c2dc9160048083019288929190829003018186803b158015612f1657600080fd5b505afa158015612f2a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612f5357600080fd5b810190808051600160201b811115612f6a57600080fd5b82016020810184811115612f7d57600080fd5b81518560208202830111600160201b82111715612f9957600080fd5b5060009750909450505050505b8051831015612fd857612fcd8783838681518110612fc057fe5b602002602001015161391c565b600190920191612fa6565b602c60009054906101000a90046001600160a01b03166001600160a01b031663fe54477e6040518163ffffffff1660e01b815260040160006040518083038186803b15801561302657600080fd5b505afa15801561303a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561306357600080fd5b810190808051600160201b81111561307a57600080fd5b8201602081018481111561308d57600080fd5b81518560208202830111600160201b821117156130a957600080fd5b5060009750909450505050505b80518310156130db576130d08783838681518110612fc057fe5b6001909201916130b6565b602c60009054906101000a90046001600160a01b03166001600160a01b0316630bf480c06040518163ffffffff1660e01b815260040160006040518083038186803b15801561312957600080fd5b505afa15801561313d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561316657600080fd5b810190808051600160201b81111561317d57600080fd5b8201602081018481111561319057600080fd5b81518560208202830111600160201b821117156131ac57600080fd5b5060009750909450505050505b80518310156131de576131d38783838681518110612fc057fe5b6001909201916131b9565b506000908152602b602052604081208190559550505b6131fe8186613a70565b9650965050505050505b94509492505050565b604a5481565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6060600082516000141561332457602c60009054906101000a90046001600160a01b03166001600160a01b031663fe54477e6040518163ffffffff1660e01b815260040160006040518083038186803b15801561329857600080fd5b505afa1580156132ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156132d557600080fd5b810190808051600160201b8111156132ec57600080fd5b820160208101848111156132ff57600080fd5b81518560208202830111600160201b8211171561331b57600080fd5b50909650505050505b60608351604051908082528060200260200182016040528015613351578160200160208202803883390190505b5090506000805b855181101561349757600086828151811061336f57fe5b60209081029190910181015160008a8152602a8352604080822083835290935291909120549091501580159061341a5750602c5460408051632682240f60e11b81526004810184905290516001600160a01b0390921691634d04481e91602480820192602092909190829003018186803b1580156133ec57600080fd5b505afa158015613400573d6000803e3d6000fd5b505050506040513d602081101561341657600080fd5b5051155b1561345657600088815260208080526040808320848452909152902054845185908490811061344557fe5b602002602001018181525050613471565b600084838151811061346457fe5b6020026020010181815250505b83828151811061347d57fe5b602002602001015183019250508080600101915050613358565b50909590945092505050565b6000828201838110156134b557600080fd5b9392505050565b60006134c88383613c87565b60285460215401019392505050565b600080826135535761354d85866001600160a01b0316638c2243ae6040518163ffffffff1660e01b815260040160206040518083038186803b15801561351c57600080fd5b505afa158015613530573d6000803e3d6000fd5b505050506040513d602081101561354657600080fd5b5051613c8f565b90945092505b60008361356157600061356e565b838588028161356c57fe5b045b9795505050505050565b600061358c8383660b1a2bc2ec5000613e27565b604c54604a5401019392505050565b4390565b81158015906135d057506040516001600160a01b0382169083156108fc029084906000818181858888f19350505050155b156136135781816040516135e390614589565b6001600160a01b039091168152604051908190036020019082f08015801561360f573d6000803e3d6000fd5b5050505b5050565b60058054604080516060810182529586526001600160a01b03938416602080880191825295851687830190815260019384016000818152600690985292909620965187555191860180549285166001600160a01b03199384161790559351600290950180549590931694169390931790559055565b6003546001600160a01b03166136a1576137ec565b60005b600254811015613765576000600282815481106136bd57fe5b6000918252602091829020015460035460408051631694a47d60e31b81526001600160a01b03938416600482018190529151919550919092169263b4a523e892602480840193829003018186803b15801561371757600080fd5b505afa15801561372b573d6000803e3d6000fd5b505050506040513d602081101561374157600080fd5b50516001600160a01b039091166000908152602760205260409020556001016136a4565b50600254156137ec57600360009054906101000a90046001600160a01b03166001600160a01b031663553a5c856040518163ffffffff1660e01b815260040160206040518083038186803b1580156137bc57600080fd5b505afa1580156137d0573d6000803e3d6000fd5b505050506040513d60208110156137e657600080fd5b50516026555b565b60006060602c60009054906101000a90046001600160a01b03166001600160a01b031663fe54477e6040518163ffffffff1660e01b815260040160006040518083038186803b15801561384057600080fd5b505afa158015613854573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561387d57600080fd5b810190808051600160201b81111561389457600080fd5b820160208101848111156138a757600080fd5b81518560208202830111600160201b821117156138c357600080fd5b505092919050505090506000806138da8786613c8f565b91509150606060006138ec888661323c565b915091506138ff89898686898787613f83565b95506139108989868689878761409a565b50505050509392505050565b60008281526029602090815260408083208484529091529020541561394057611175565b6000836001600160a01b0316632a8f6ecd836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561398657600080fd5b505afa15801561399a573d6000803e3d6000fd5b505050506040513d60208110156139b057600080fd5b50519050806139bf5750611175565b600083815260296020908152604080832085845282528083208490558051630fec687960e21b8152600481018690526024810193909352516001600160a01b03871692633fb1a1e4926044808301939192829003018186803b158015613a2457600080fd5b505afa158015613a38573d6000803e3d6000fd5b505050506040513d6020811015613a4e57600080fd5b50516000848152602a6020908152604080832086845290915290205550505050565b6060806000613a7d612548565b905083811115613a8a5750825b84151580613a99576000613a9c565b60015b60ff168201604051908082528060200260200182016040528015613aca578160200160208202803883390190505b5093508351604051908082528060200260200182016040528015613af8578160200160208202803883390190505b50925060005b82811015613b75576000806000613b13614437565b92509250925081888581518110613b2657fe5b60200260200101906001600160a01b031690816001600160a01b03168152505082878581518110613b5357fe5b602002602001018181525050613b6a8383836144b8565b505050600101613afe565b508015613bc35730848381518110613b8957fe5b60200260200101906001600160a01b031690816001600160a01b03168152505085838381518110613bb657fe5b6020026020010181815250505b7f2834f3daea15e82b5f27095c4b6d08cd437f303149009a0a3304be801d2dd7ce8484604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015613c2a578181015183820152602001613c12565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015613c69578181015183820152602001613c51565b5050505090500194505050505060405180910390a150509250929050565b600092915050565b602c546040805163b927ef4360e01b815290516000928392839260019284926001600160a01b039091169163b927ef4391600480820192602092909190829003018186803b158015613ce057600080fd5b505afa158015613cf4573d6000803e3d6000fd5b505050506040513d6020811015613d0a57600080fd5b5051905080156134975760006003602c60009054906101000a90046001600160a01b03166001600160a01b031663714897df6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d6657600080fd5b505afa158015613d7a573d6000803e3d6000fd5b505050506040513d6020811015613d9057600080fd5b505160020281613d9c57fe5b04886001600160a01b0316637069e7466040518163ffffffff1660e01b815260040160206040518083038186803b158015613dd657600080fd5b505afa158015613dea573d6000803e3d6000fd5b505050506040513d6020811015613e0057600080fd5b505101600101905080821015613e14578091505b6001918703820198960301955050505050565b600081613e36575060006134b5565b8251613f1657602c60009054906101000a90046001600160a01b03166001600160a01b031663fe54477e6040518163ffffffff1660e01b815260040160006040518083038186803b158015613e8a57600080fd5b505afa158015613e9e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015613ec757600080fd5b810190808051600160201b811115613ede57600080fd5b82016020810184811115613ef157600080fd5b81518560208202830111600160201b82111715613f0d57600080fd5b50909650505050505b6000805b8451811015613f6c57602960008781526020019081526020016000206000868381518110613f4457fe5b6020026020010151815260200190815260200160002054820191508080600101915050613f1a565b50670de0b6b3a76400009083020490509392505050565b6000806000613f958a8a8a8a8a6112f2565b915091508060001415613fad5760009250505061408f565b600060218190556060613fc28488888e611197565b90508751815114156140835760005b8851811015614081576000898281518110613fe857fe5b60200260200101519050828281518110613ffe57fe5b60209081029190910181015160008f81526022835260408082208583529093529190912055825183908390811061403157fe5b60200260200101518401935082828151811061404957fe5b602002602001015160001461407857600081815260208181526040822080546001810182559083529120018d90555b50600101613fd1565b505b50908190036028559150505b979650505050505050565b6000806140aa89898989896119a2565b9150915080600014156140be57505061442e565b6000604a819055506000896001600160a01b0316632d21d2176040518163ffffffff1660e01b815260040160206040518083038186803b15801561410157600080fd5b505afa158015614115573d6000803e3d6000fd5b505050506040513d602081101561412b57600080fd5b5051604d549091506000906001600160a01b03161580159061415557506001600160a01b03821615155b156141f757604d5460408051638da5cb5b60e01b815290516001600160a01b0392831692851691638da5cb5b916004808301926020929190829003018186803b1580156141a157600080fd5b505afa1580156141b5573d6000803e3d6000fd5b505050506040513d60208110156141cb57600080fd5b50516001600160a01b031614156141ee5750604d546001600160a01b03166141f2565b5060005b6141fa565b50805b60006001600160a01b038216158015906142895750306001600160a01b0316826001600160a01b03166356b54bae6040518163ffffffff1660e01b815260040160206040518083038186803b15801561425257600080fd5b505afa158015614266573d6000803e3d6000fd5b505050506040513d602081101561427c57600080fd5b50516001600160a01b0316145b1561442457606061429c8689898f611197565b90508851815114156144225760005b89518110156143c2578181815181106142c057fe5b6020026020010151604b60008f815260200190815260200160002060008c84815181106142e957fe5b602002602001015181526020019081526020016000208190555081818151811061430f57fe5b60200260200101518301925081818151811061432757fe5b60200260200101516000141580156143765750602260008e815260200190815260200160002060008b838151811061435b57fe5b60200260200101518152602001908152602001600020546000145b156143ba576000808b838151811061438a57fe5b60209081029190910181015182528181019290925260400160009081208054600181018255908252919020018d90555b6001016142ab565b50826001600160a01b03166391c0aabf836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561440957600080fd5b505af115801561441d573d6000803e3d6000fd5b505050505b505b909203604c555050505b50505050505050565b60045460055460009182918291908181101561445e576000945060009350600092506144b1565b6000828152600660205260408120805460028201805460018085018054969095556001600160a01b03198087169095559381169091556004805490930190925596506001600160a01b0390811695501692505b5050909192565b60006144c261359b565b6001600160a01b03938416600081815260246020908152604080832085845282528083208990559282526023815282822080548901905592815260258352818120805488019055939094168352602790525020805482019055602680549091019055565b828054828255906000526020600020908101928215614579579160200282015b828111156145795781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190614546565b50614585929150614595565b5090565b6032806145ba83390190565b6112ef91905b808211156145855780546001600160a01b031916815560010161459b56fe60806040526040516032380380603283398181016040526020811015602357600080fd5b50516001600160a01b038116fffea265627a7a7230582062631356e570e39d323d66f88466882635eb13d9b0b483126bb5ca9245d1dedf64736f6c634300050a0032"
+ },
+ "0x3000000000000000000000000000000000000001": {
+ "balance": "0x0",
+ "constructor": "0x60806040526040516108053803806108058339818101604052604081101561002657600080fd5b50805160209182015160408051600081529384018082527f656970313936372e70726f78792e696d706c656d656e746174696f6e00000000905251603c81850301902091929091839190600019016000805160206107aa8339815191521461008a57fe5b61009c826001600160e01b036101bd16565b805115610154576000826001600160a01b0316826040518082805190602001908083835b602083106100df5780518252601f1990920191602091820191016100c0565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461013f576040519150601f19603f3d011682016040523d82523d6000602084013e610144565b606091505b505090508061015257600080fd5b505b5050604080517f656970313936372e70726f78792e61646d696e000000000000000000000000008152905190819003601301902060008051602061078a833981519152600019909101146101a457fe5b6101b6816001600160e01b0361023716565b505061024f565b6101d08161024960201b6104801760201c565b610225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806107ca603b913960400191505060405180910390fd5b6000805160206107aa83398151915255565b60008051602061078a83398151915255565b3b151590565b61052c8061025e6000396000f3fe60806040526004361061004a5760003560e01c80633659cfe6146100545780634f1ef286146100875780635c60da1b146101075780638f28397014610138578063f851a4401461016b575b610052610180565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661019a565b6100526004803603604081101561009d57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100c857600080fd5b8201836020820111156100da57600080fd5b803590602001918460018302840111640100000000831117156100fc57600080fd5b5090925090506101cb565b34801561011357600080fd5b5061011c61026f565b604080516001600160a01b039092168252519081900360200190f35b34801561014457600080fd5b506100526004803603602081101561015b57600080fd5b50356001600160a01b031661027e565b34801561017757600080fd5b5061011c61033c565b610188610198565b610198610193610346565b61036b565b565b6101a261038f565b6001600160a01b0316336001600160a01b0316146101bf57600080fd5b6101c8816103b4565b50565b6101d361038f565b6001600160a01b0316336001600160a01b0316146101f057600080fd5b6101f9836103b4565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610256576040519150601f19603f3d011682016040523d82523d6000602084013e61025b565b606091505b505090508061026957600080fd5b50505050565b6000610279610346565b905090565b61028661038f565b6001600160a01b0316336001600160a01b0316146102a357600080fd5b6001600160a01b0381166102e85760405162461bcd60e51b81526004018080602001828103825260368152602001806104876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61031161038f565b604080516001600160a01b03928316815291841660208301528051918290030190a16101c8816103f4565b600061027961038f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561038a573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103bd81610418565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b61042181610480565b61045c5760405162461bcd60e51b815260040180806020018281038252603b8152602001806104bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b3b15159056fe43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a265627a7a72305820a9aab4b95b654a79b32f5aa284796894f8329aaa083932695296085b196c27bd64736f6c634300050a0032b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000000000000000003000000000000000000000000000000000000000000000000000000000000000b03a86b3126157c039b55e21d378587ccfc04d45"
+ },
+ "0x3000000000000000000000000000000000000000": {
+ "balance": "0x0",
+ "constructor": "0x608060405234801561001057600080fd5b50611f2a806100206000396000f3fe6080604052600436106101c25760003560e01c80637a3e286b116100f7578063c64c206411610095578063f2f56ffe11610064578063f2f56ffe146106df578063f58ccc6a14610718578063fd6c1d15146105ad578063fe7d567d14610583576101c2565b8063c64c206414610634578063cc93dab414610649578063de109e2014610675578063dfc8bf4e146106ae576101c2565b806398df67c6116100d157806398df67c614610583578063b6b295ae146105ad578063baf11cab146105e6578063c358ced01461061f576101c2565b80637a3e286b1461054457806383209c3f14610559578063832206261461056e576101c2565b80633afa443c1161016457806363f160e61161013e57806363f160e614610429578063695e89f61461046257806374ce90671461051a57806378ab865d1461052f576101c2565b80633afa443c146103c657806343e7aa1d146103db5780635aca47f6146103f0576101c2565b8063109c1107116101a0578063109c1107146103205780631c77c58c1461033557806328804dbd1461035c578063392e53cd1461039d576101c2565b8063096a113d146101c45780630b402823146102725780630b61ba851461029c575b005b3480156101d057600080fd5b506101fd600480360360408110156101e757600080fd5b50803590602001356001600160a01b031661072d565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561023757818101518382015260200161021f565b50505050905090810190601f1680156102645780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027e57600080fd5b506101c26004803603602081101561029557600080fd5b5035610853565b3480156102a857600080fd5b506101c2600480360360408110156102bf57600080fd5b813591908101906040810160208201356401000000008111156102e157600080fd5b8201836020820111156102f357600080fd5b8035906020019184600183028401116401000000008311171561031557600080fd5b5090925090506108d2565b34801561032c57600080fd5b506101c2610a08565b34801561034157600080fd5b5061034a6111f7565b60408051918252519081900360200190f35b34801561036857600080fd5b506101c26004803603606081101561037f57600080fd5b508035906001600160a01b03602082013516906040013515156111fd565b3480156103a957600080fd5b506103b2611418565b604080519115158252519081900360200190f35b3480156103d257600080fd5b506103b261142a565b3480156103e757600080fd5b5061034a611433565b3480156103fc57600080fd5b5061034a6004803603604081101561041357600080fd5b50803590602001356001600160a01b0316611447565b34801561043557600080fd5b506103b26004803603604081101561044c57600080fd5b50803590602001356001600160a01b03166114e4565b34801561046e57600080fd5b5061049b6004803603604081101561048557600080fd5b50803590602001356001600160a01b0316611584565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156104de5781810151838201526020016104c6565b50505050905090810190601f16801561050b5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561052657600080fd5b506103b26116c8565b34801561053b57600080fd5b5061034a6116ee565b34801561055057600080fd5b5061034a6116fd565b34801561056557600080fd5b5061034a611714565b34801561057a57600080fd5b5061034a611742565b34801561058f57600080fd5b506101c2600480360360208110156105a657600080fd5b5035611748565b3480156105b957600080fd5b506103b2600480360360408110156105d057600080fd5b506001600160a01b038135169060200135611765565b3480156105f257600080fd5b506103b26004803603604081101561060957600080fd5b50803590602001356001600160a01b0316611778565b34801561062b57600080fd5b506103b26118d8565b34801561064057600080fd5b5061034a6118e8565b34801561065557600080fd5b506101c26004803603602081101561066c57600080fd5b5035151561191f565b34801561068157600080fd5b506103b26004803603604081101561069857600080fd5b506001600160a01b038135169060200135611957565b3480156106ba57600080fd5b506106c3611a26565b604080516001600160a01b039092168252519081900360200190f35b3480156106eb57600080fd5b5061034a6004803603604081101561070257600080fd5b50803590602001356001600160a01b0316611a35565b34801561072457600080fd5b5061034a611ad2565b600854604080516315ddbdb960e11b81526001600160a01b03848116600483015291516060936000931691632bbb7b72916024808301926020929190829003018186803b15801561077d57600080fd5b505afa158015610791573d6000803e3d6000fd5b505050506040513d60208110156107a757600080fd5b50516000858152602081815260408083208484528252918290208054835160026001831615610100026000190190921691909104601f810184900484028201840190945283815293945091908301828280156108445780601f1061081957610100808354040283529160200191610844565b820191906000526020600020905b81548152906001019060200180831161082757829003601f168201915b50505050509150505b92915050565b6008546001600160a01b0316331461086a57600080fd5b60006108746116fd565b600081815260076020908152604080832086845290915290205490915060ff166108ce576000818152600160209081526040808320858452825280832083905583835282825280832085845290915281206108ce91611df0565b5050565b6108da611418565b6108e357600080fd5b336108ee8185611957565b6108f757600080fd5b806001600160a01b0316610909611ae8565b6001600160a01b03161461091c57600080fd5b60006109266116fd565b600854604080516315ddbdb960e11b81526001600160a01b03868116600483015291519394506000939190921691632bbb7b72916024808301926020929190829003018186803b15801561097957600080fd5b505afa15801561098d573d6000803e3d6000fd5b505050506040513d60208110156109a357600080fd5b5051600083815260016020908152604080832084845282528083208a905585835282825280832084845290915290209091506109e0908686611e34565b5060009182526002602090815260408320805460018101825590845292209091015550505050565b600860009054906101000a90046001600160a01b03166001600160a01b03166356b54bae6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a5657600080fd5b505afa158015610a6a573d6000803e3d6000fd5b505050506040513d6020811015610a8057600080fd5b50516001600160a01b03163314610a9657600080fd5b600354610aa1611aec565b81610aa857fe5b0615610ab3576111f5565b60606000806000600860009054906101000a90046001600160a01b03166001600160a01b031663ee99205c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0857600080fd5b505afa158015610b1c573d6000803e3d6000fd5b505050506040513d6020811015610b3257600080fd5b505160408051630f29818d60e31b815290519192506000916001600160a01b0384169163794c0c68916004808301926020929190829003018186803b158015610b7a57600080fd5b505afa158015610b8e573d6000803e3d6000fd5b505050506040513d6020811015610ba457600080fd5b505160408051633834f3a360e11b815290519192506000916001600160a01b03851691637069e746916004808301926020929190829003018186803b158015610bec57600080fd5b505afa158015610c00573d6000803e3d6000fd5b505050506040513d6020811015610c1657600080fd5b50516040805163461121d760e11b815290519192506000916001600160a01b03861691638c2243ae916004808301926020929190829003018186803b158015610c5e57600080fd5b505afa158015610c72573d6000803e3d6000fd5b505050506040513d6020811015610c8857600080fd5b505190506000610c966116fd565b90506003546003028301610ca8611aec565b1115610e6457600860009054906101000a90046001600160a01b03166001600160a01b031663b7ab4db56040518163ffffffff1660e01b815260040160006040518083038186803b158015610cfc57600080fd5b505afa158015610d10573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610d3957600080fd5b810190808051640100000000811115610d5157600080fd5b82016020810184811115610d6457600080fd5b8151856020820283011164010000000082111715610d8157600080fd5b50909b5060009950505050505b8751861015610e6457878681518110610da357fe5b60200260200101519650610db781886114e4565b610e5957600854604080516315ddbdb960e11b81526001600160a01b038a8116600483015291516000939290921691632bbb7b7291602480820192602092909190829003018186803b158015610e0c57600080fd5b505afa158015610e20573d6000803e3d6000fd5b505050506040513d6020811015610e3657600080fd5b505160008681526006602090815260408083209383529290522080546001019055505b600190950194610d8e565b60055460ff168015610e90575081610e7a611aec565b1480610e90575081600354610e8d611aec565b01115b156111e3576000600354866001600160a01b03166397997ebb6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ed357600080fd5b505afa158015610ee7573d6000803e3d6000fd5b505050506040513d6020811015610efd57600080fd5b505181610f0657fe5b0490506001811115610f1b5760011901610f26565b8015610f2657600019015b600860009054906101000a90046001600160a01b03166001600160a01b031663b7ab4db56040518163ffffffff1660e01b815260040160006040518083038186803b158015610f7457600080fd5b505afa158015610f88573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610fb157600080fd5b810190808051640100000000811115610fc957600080fd5b82016020810184811115610fdc57600080fd5b8151856020820283011164010000000082111715610ff957600080fd5b5050929190505050985060608951604051908082528060200260200182016040528015611030578160200160208202803883390190505b50600098509050875b8a518910156110ba578a898151811061104e57fe5b60200260200101519950611062848b6114e4565b1580611076575082611074888c611447565b115b156110af578982828060010193508151811061108e57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b600190980197611039565b80156111df576060816040519080825280602002602001820160405280156110ec578160200160208202803883390190505b509050600099505b818a101561113f57828a8151811061110857fe5b6020026020010151818b8151811061111c57fe5b6001600160a01b03909216602092830291909101909101526001909901986110f4565b60085460405163018daf6b60e21b81526020600482018181528451602484015284516001600160a01b0390941693630636bdac9386938392604490920191818601910280838360005b838110156111a0578181015183820152602001611188565b5050505090500192505050600060405180830381600087803b1580156111c557600080fd5b505af11580156111d9573d6000803e3d6000fd5b50505050505b5050505b6111ec81611af0565b50505050505050505b565b60035481565b611205611aec565b15806112295750611214611ba7565b6001600160a01b0316336001600160a01b0316145b61123257600080fd5b61123a611418565b1561124457600080fd5b81600284061561125357600080fd5b806001600160a01b031663714897df6040518163ffffffff1660e01b815260040160206040518083038186803b15801561128c57600080fd5b505afa1580156112a0573d6000803e3d6000fd5b505050506040513d60208110156112b657600080fd5b505184816112c057fe5b06156112cb57600080fd5b83816001600160a01b031663ee99205c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561130557600080fd5b505afa158015611319573d6000803e3d6000fd5b505050506040513d602081101561132f57600080fd5b50516040805163d609ea9360e01b815290516001600160a01b039092169163d609ea9391600480820192602092909190829003018186803b15801561137357600080fd5b505afa158015611387573d6000803e3d6000fd5b505050506040513d602081101561139d57600080fd5b5051816113a657fe5b06156113b157600080fd5b600084116113be57600080fd5b600354156113cb57600080fd5b6001600160a01b0383166113de57600080fd5b50600392909255600880546001600160a01b0319166001600160a01b03929092169190911790556005805460ff1916911515919091179055565b6008546001600160a01b031615155b90565b60055460ff1681565b600060026003548161144157fe5b04905090565b600854604080516315ddbdb960e11b81526001600160a01b038481166004830152915160009384931691632bbb7b72916024808301926020929190829003018186803b15801561149657600080fd5b505afa1580156114aa573d6000803e3d6000fd5b505050506040513d60208110156114c057600080fd5b50516000858152600660209081526040808320938352929052205491505092915050565b600854604080516315ddbdb960e11b81526001600160a01b038481166004830152915160009384931691632bbb7b72916024808301926020929190829003018186803b15801561153357600080fd5b505afa158015611547573d6000803e3d6000fd5b505050506040513d602081101561155d57600080fd5b50516000858152600760209081526040808320938352929052205460ff1691505092915050565b600854604080516315ddbdb960e11b81526001600160a01b03848116600483015291516000936060938593911691632bbb7b7291602480820192602092909190829003018186803b1580156115d857600080fd5b505afa1580156115ec573d6000803e3d6000fd5b505050506040513d602081101561160257600080fd5b505160008681526001602081815260408084208585528252808420548a855284835281852086865283529381902080548251600295821615610100026000190190911694909404601f810184900484028501840190925281845294955092939283918301828280156116b55780601f1061168a576101008083540402835291602001916116b5565b820191906000526020600020905b81548152906001019060200180831161169857829003601f168201915b5050505050905092509250509250929050565b60006116d2611433565b60035460016116df611aec565b03816116e757fe5b0610905090565b60006116f8611714565b905090565b6000600354600161170c611aec565b038161144157fe5b60008061171f611aec565b90506000600354600183038161173157fe5b066003540390508082019250505090565b60045481565b611750611418565b61175957600080fd5b61176281611bcc565b50565b60006117718383611cd8565b9392505050565b600854604080516315ddbdb960e11b81526001600160a01b038481166004830152915160009384931691632bbb7b72916024808301926020929190829003018186803b1580156117c757600080fd5b505afa1580156117db573d6000803e3d6000fd5b505050506040513d60208110156117f157600080fd5b50519050801580159061180757506118076116c8565b1561189057600854604080516324b49dad60e21b815281516000936001600160a01b0316926392d276b49260048082019391829003018186803b15801561184d57600080fd5b505afa158015611861573d6000803e3d6000fd5b505050506040513d604081101561187757600080fd5b505190508181141561188e5760019250505061084d565b505b60008481526001602090815260408083208484529091529020541515806118d05750600084815260076020908152604080832084845290915290205460ff165b949350505050565b60006118e26116c8565b15905090565b60006118f26116c8565b1561190f576118ff611433565b611907611ad2565b019050611427565b611917611433565b611907611714565b611927611ba7565b6001600160a01b0316336001600160a01b03161461194457600080fd5b6005805460ff1916911515919091179055565b60006119616116c8565b61196d5750600061084d565b8161197a5750600061084d565b6008546040805163facd743b60e01b81526001600160a01b0386811660048301529151919092169163facd743b916024808301926020929190829003018186803b1580156119c757600080fd5b505afa1580156119db573d6000803e3d6000fd5b505050506040513d60208110156119f157600080fd5b50516119ff5750600061084d565b611a10611a0a6116fd565b84611778565b15611a1d5750600061084d565b50600192915050565b6008546001600160a01b031681565b600854604080516315ddbdb960e11b81526001600160a01b038481166004830152915160009384931691632bbb7b72916024808301926020929190829003018186803b158015611a8457600080fd5b505afa158015611a98573d6000803e3d6000fd5b505050506040513d6020811015611aae57600080fd5b50516000858152600160209081526040808320938352929052205491505092915050565b6000600354611adf6116fd565b02600101905090565b4190565b4390565b80611afa57611762565b60001981016000818152600260205260408120805490915b81811015611b93576000838281548110611b2857fe5b60009182526020808320909101548783528282526040808420828552909252908220909250611b5691611df0565b6000858152600160208181526040808420858552825280842084905588845260078252808420948452939052919020805460ff1916905501611b12565b506000611ba08382611eb2565b5050505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b33611bd78183611765565b611be057600080fd5b806001600160a01b0316611bf2611ae8565b6001600160a01b031614611c0557600080fd5b600854604080516315ddbdb960e11b81526001600160a01b03848116600483015291516000939290921691632bbb7b7291602480820192602092909190829003018186803b158015611c5657600080fd5b505afa158015611c6a573d6000803e3d6000fd5b505050506040513d6020811015611c8057600080fd5b5051600480548518905590506000611c966116fd565b60008181526007602090815260408083208684528252808320805460ff1916600190811790915593835292815282822094825293909352822091909155505050565b6000611ce26118d8565b611cee5750600061084d565b604080516020808201859052825180830382018152918301909252805191012080611d1d57600091505061084d565b6008546040805163facd743b60e01b81526001600160a01b0387811660048301529151919092169163facd743b916024808301926020929190829003018186803b158015611d6a57600080fd5b505afa158015611d7e573d6000803e3d6000fd5b505050506040513d6020811015611d9457600080fd5b5051611da457600091505061084d565b6000611dae6116fd565b9050611dba81866114e4565b15611dca5760009250505061084d565b611dd48186611a35565b8214611de55760009250505061084d565b506001949350505050565b50805460018160011615610100020316600290046000825580601f10611e165750611762565b601f0160209004906000526020600020908101906117629190611edb565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611e755782800160ff19823516178555611ea2565b82800160010185558215611ea2579182015b82811115611ea2578235825591602001919060010190611e87565b50611eae929150611edb565b5090565b815481835581811115611ed657600083815260209020611ed6918101908301611edb565b505050565b61142791905b80821115611eae5760008155600101611ee156fea265627a7a72305820fb070d0efcf95ea5a546d38c7d35a2cc3bb541e53f6853d2b155fd86d1bde23564736f6c634300050a0032"
+ },
+ "0x4000000000000000000000000000000000000001": {
+ "balance": "0x0",
+ "constructor": "0x60806040526040516108053803806108058339818101604052604081101561002657600080fd5b50805160209182015160408051600081529384018082527f656970313936372e70726f78792e696d706c656d656e746174696f6e00000000905251603c81850301902091929091839190600019016000805160206107aa8339815191521461008a57fe5b61009c826001600160e01b036101bd16565b805115610154576000826001600160a01b0316826040518082805190602001908083835b602083106100df5780518252601f1990920191602091820191016100c0565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461013f576040519150601f19603f3d011682016040523d82523d6000602084013e610144565b606091505b505090508061015257600080fd5b505b5050604080517f656970313936372e70726f78792e61646d696e000000000000000000000000008152905190819003601301902060008051602061078a833981519152600019909101146101a457fe5b6101b6816001600160e01b0361023716565b505061024f565b6101d08161024960201b6104801760201c565b610225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806107ca603b913960400191505060405180910390fd5b6000805160206107aa83398151915255565b60008051602061078a83398151915255565b3b151590565b61052c8061025e6000396000f3fe60806040526004361061004a5760003560e01c80633659cfe6146100545780634f1ef286146100875780635c60da1b146101075780638f28397014610138578063f851a4401461016b575b610052610180565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661019a565b6100526004803603604081101561009d57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100c857600080fd5b8201836020820111156100da57600080fd5b803590602001918460018302840111640100000000831117156100fc57600080fd5b5090925090506101cb565b34801561011357600080fd5b5061011c61026f565b604080516001600160a01b039092168252519081900360200190f35b34801561014457600080fd5b506100526004803603602081101561015b57600080fd5b50356001600160a01b031661027e565b34801561017757600080fd5b5061011c61033c565b610188610198565b610198610193610346565b61036b565b565b6101a261038f565b6001600160a01b0316336001600160a01b0316146101bf57600080fd5b6101c8816103b4565b50565b6101d361038f565b6001600160a01b0316336001600160a01b0316146101f057600080fd5b6101f9836103b4565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610256576040519150601f19603f3d011682016040523d82523d6000602084013e61025b565b606091505b505090508061026957600080fd5b50505050565b6000610279610346565b905090565b61028661038f565b6001600160a01b0316336001600160a01b0316146102a357600080fd5b6001600160a01b0381166102e85760405162461bcd60e51b81526004018080602001828103825260368152602001806104876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61031161038f565b604080516001600160a01b03928316815291841660208301528051918290030190a16101c8816103f4565b600061027961038f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561038a573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103bd81610418565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b61042181610480565b61045c5760405162461bcd60e51b815260040180806020018281038252603b8152602001806104bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b3b15159056fe43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a265627a7a72305820a9aab4b95b654a79b32f5aa284796894f8329aaa083932695296085b196c27bd64736f6c634300050a0032b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000000000000000004000000000000000000000000000000000000000000000000000000000000000b03a86b3126157c039b55e21d378587ccfc04d45"
+ },
+ "0x4000000000000000000000000000000000000000": {
+ "balance": "0x0",
+ "constructor": "0x608060405234801561001057600080fd5b5061139e806100206000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c806390482d72116100ad578063baddbfa011610071578063baddbfa014610479578063c746c8f4146104a5578063d9eb2d5e146104cb578063dfc8bf4e146104d3578063efc78401146104db57610121565b806390482d72146102b957806394a1fd781461033a5780639d7912aa14610360578063a0a8e46014610386578063b9056afa1461038e57610121565b8063392e53cd116100f4578063392e53cd146101ea578063469ab1e314610206578063471eab5c1461020e57806375d0c0dc146102345780637877a797146102b157610121565b80630651cd86146101265780631a9ebeaa146101545780631b9f67a1146101785780633272b28c14610192575b600080fd5b6101526004803603604081101561013c57600080fd5b506001600160a01b038135169060200135610501565b005b61015c61058b565b604080516001600160a01b039092168252519081900360200190f35b61018061059a565b60408051918252519081900360200190f35b61019a6105a1565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156101d65781810151838201526020016101be565b505050509050019250505060405180910390f35b6101f2610604565b604080519115158252519081900360200190f35b610180610615565b6101526004803603602081101561022457600080fd5b50356001600160a01b0316610691565b61023c6107c5565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561027657818101518382015260200161025e565b50505050905090810190601f1680156102a35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101806107f5565b610152600480360360608110156102cf57600080fd5b8101906020810181356401000000008111156102ea57600080fd5b8201836020820111156102fc57600080fd5b8035906020019184602083028401116401000000008311171561031e57600080fd5b91935091506001600160a01b0381358116916020013516610914565b6101806004803603602081101561035057600080fd5b50356001600160a01b03166109e2565b6101806004803603602081101561037657600080fd5b50356001600160a01b03166109f4565b610180610a26565b610459600480360360a08110156103a457600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a0810160808201356401000000008111156103e457600080fd5b8201836020820111156103f657600080fd5b8035906020019184600183028401116401000000008311171561041857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610a2b945050505050565b6040805163ffffffff909316835290151560208301528051918290030190f35b6101526004803603604081101561048f57600080fd5b506001600160a01b038135169060200135610a4c565b610152600480360360208110156104bb57600080fd5b50356001600160a01b0316610ad6565b610180610b18565b61015c610b1f565b6101f2600480360360208110156104f157600080fd5b50356001600160a01b0316610b2e565b610509610b43565b6001600160a01b0316336001600160a01b03161461052657600080fd5b61052e610604565b61053757600080fd5b6001600160a01b038216600081815260056020908152604091829020849055815184815291517fc8eecc08ae9cffd51fce8871ab6f4c6c8c112f8753fad097a055d51433661a7d9281900390910190a25050565b6001546001600160a01b031681565b623d090081565b606060008054806020026020016040519081016040528092919081815260200182805480156105f957602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116105db575b505050505090505b90565b6003546001600160a01b0316151590565b600061061f6107c5565b6040516020018082805190602001908083835b602083106106515780518252601f199092019160209182019101610632565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905090565b610699610b43565b6001600160a01b0316336001600160a01b0316146106b657600080fd5b6106be610604565b6106c757600080fd5b6001600160a01b03811660009081526002602052604090205460ff166106ec57600080fd5b60008054905b818110156107a2576000818154811061070757fe5b6000918252602090912001546001600160a01b038481169116141561079a576000600183038154811061073657fe5b600091825260208220015481546001600160a01b0390911691908390811061075a57fe5b6000918252602082200180546001600160a01b0319166001600160a01b039390931692909217909155805490610794906000198301611322565b506107a2565b6001016106f2565b50506001600160a01b03166000908152600260205260409020805460ff19169055565b604080518082019091526016815275151617d41154935254d4d253d397d0d3d395149050d560521b602082015290565b600080600360009054906101000a90046001600160a01b03166001600160a01b031663ee99205c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084657600080fd5b505afa15801561085a573d6000803e3d6000fd5b505050506040513d602081101561087057600080fd5b50516040805163461121d760e11b815290519192506000916001600160a01b03841691638c2243ae916004808301926020929190829003018186803b1580156108b857600080fd5b505afa1580156108cc573d6000803e3d6000fd5b505050506040513d60208110156108e257600080fd5b5051905043600019820114806108f757508043145b1561090957623d090092505050610601565b62bebc209250505090565b4315806109395750610924610b43565b6001600160a01b0316336001600160a01b0316145b61094257600080fd5b61094a610604565b1561095457600080fd5b6001600160a01b03821661096757600080fd5b6001600160a01b03811661097a57600080fd5b60005b838110156109b1576109a985858381811061099457fe5b905060200201356001600160a01b0316610b68565b60010161097d565b50600180546001600160a01b039384166001600160a01b031991821617909155600380549290931691161790555050565b60056020526000908152604090205481565b6001600160a01b0381166000908152600460205260408120548015610a1a579050610a21565b6178009150505b919050565b600390565b600080610a3e8787878788600089610c06565b915091509550959350505050565b610a54610b43565b6001600160a01b0316336001600160a01b031614610a7157600080fd5b610a79610604565b610a8257600080fd5b6001600160a01b038216600081815260046020908152604091829020849055815184815291517f89afe3f32b77b643649ede79272f126acd78aa80feeabe1b8c103d0b2f2848969281900390910190a25050565b610ade610b43565b6001600160a01b0316336001600160a01b031614610afb57600080fd5b610b03610604565b610b0c57600080fd5b610b1581610b68565b50565b62bebc2081565b6003546001600160a01b031681565b60026020526000908152604090205460ff1681565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6001600160a01b03811660009081526002602052604090205460ff1615610b8e57600080fd5b6001600160a01b038116610ba157600080fd5b60008054600181810183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390910180546001600160a01b039094166001600160a01b031990941684179055918152600260205260409020805460ff19169091179055565b6001600160a01b038716600090815260026020526040812054819060ff1615610c38575063ffffffff90506000611316565b6001600160a01b038816158015610c575750610c53896109f4565b8351115b15610c6757506000905080611316565b6004838101516003546040805163ccf69e9b60e01b8152905160e09390931b936001600160a01b039092169263ccf69e9b92828101926020929190829003018186803b158015610cb657600080fd5b505afa158015610cca573d6000803e3d6000fd5b505050506040513d6020811015610ce057600080fd5b50516001600160a01b038a811691161415610e5e576001600160e01b03198116630b61ba8560e01b148015610d16575060248451115b15610db957602484810151604080516306f084f160e51b81526001600160a01b038e81166004830152938101839052905191928c169163de109e2091604480820192602092909190829003018186803b158015610d7257600080fd5b505afa158015610d86573d6000803e3d6000fd5b505050506040513d6020811015610d9c57600080fd5b5051610da9576000610dac565b60025b6000935093505050611316565b6001600160e01b0319811663fe7d567d60e01b1480610de857506001600160e01b03198116634c6fb3e360e11b145b8015610df5575083516024145b15610e51576024848101516040805163fd6c1d1560e01b81526001600160a01b038e81166004830152938101839052905191928c169163fd6c1d1591604480820192602092909190829003018186803b158015610d7257600080fd5b6000809250925050611316565b6003546001600160a01b038a8116911614156110bd576001600160e01b031981166349da712f60e11b1415610f2157600360009054906101000a90046001600160a01b03166001600160a01b0316633d3b54586040518163ffffffff1660e01b815260040160206040518083038186803b158015610edb57600080fd5b505afa158015610eef573d6000803e3d6000fd5b505050506040513d6020811015610f0557600080fd5b5051610f12576000610f15565b60025b60009250925050611316565b6001600160e01b03198116630311db7560e61b148015610f4357506044845110155b156110335760008060248601519150604486015190506000600360009054906101000a90046001600160a01b03166001600160a01b031663a670eb568e85856040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050604080518083038186803b158015610fe757600080fd5b505afa158015610ffb573d6000803e3d6000fd5b505050506040513d604081101561101157600080fd5b5051905080611021576000611024565b60025b60009550955050505050611316565b86156110bd576003546040805163facd743b60e01b81526001600160a01b038d811660048301529151919092169163facd743b916024808301926020929190829003018186803b15801561108657600080fd5b505afa15801561109a573d6000803e3d6000fd5b505050506040513d60208110156110b057600080fd5b5051610e51576002610f15565b6003546040805163facd743b60e01b81526001600160a01b038d811660048301529151919092169163facd743b916024808301926020929190829003018186803b15801561110a57600080fd5b505afa15801561111e573d6000803e3d6000fd5b505050506040513d602081101561113457600080fd5b505180156111425750600087115b15611195576001600160e01b0319811663a9059cbb60e01b141561116e57600260009250925050611316565b60008a6001600160a01b03163111611187576000610f15565b600160009250925050611316565b6003546040805163facd743b60e01b81526001600160a01b038c811660048301529151919092169163facd743b916024808301926020929190829003018186803b1580156111e257600080fd5b505afa1580156111f6573d6000803e3d6000fd5b505050506040513d602081101561120c57600080fd5b505115611220576000809250925050611316565b866112ba57600154604080516303a388eb60e61b81526001600160a01b038d811660048301529151919092169163e8e23ac0916024808301926020929190829003018186803b15801561127257600080fd5b505afa158015611286573d6000803e3d6000fd5b505050506040513d602081101561129c57600080fd5b50516112a9576000610f15565b63ffffffff60009250925050611316565b6001600160a01b038a166000908152600560205260409020548710806112f757506001600160a01b038a1660009081526005602052604090205486105b15611309576000809250925050611316565b63ffffffff600092509250505b97509795505050505050565b8154818355818111156113465760008381526020902061134691810190830161134b565b505050565b61060191905b808211156113655760008155600101611351565b509056fea265627a7a72305820de9ee9915ae9231fc972bc7570c92a6e882aae006233dfefbea7769e5545011064736f6c634300050a0032"
+ },
+ "0x4100000000000000000000000000000000000000": {
+ "balance": "0x0",
+ "constructor": "0x60806040523480156200001157600080fd5b506040516200232d3803806200232d8339810160408190526200003491620000bd565b6001600160a01b038116620000465750335b6001600160a01b0381166200005a57600080fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35062000112565b8051620000b781620000f8565b92915050565b600060208284031215620000d057600080fd5b6000620000de8484620000aa565b949350505050565b60006001600160a01b038216620000b7565b6200010381620000e6565b81146200010f57600080fd5b50565b61220b80620001226000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c80638da5cb5b1161008c578063a5b62cb311610066578063a5b62cb314610187578063d13a26531461019a578063f2fde38b146101bc578063f53c7e2f146101cf576100cf565b80638da5cb5b14610157578063a0daeed21461016c578063a2bf0af514610174576100cf565b80630af28392146100d4578063338cd6bd146100e9578063399b6f3e14610107578063662520bd1461011c5780637d616fd31461012f578063879cda7314610144575b600080fd5b6100e76100e2366004611ccd565b6101e2565b005b6100f1610465565b6040516100fe91906120a0565b60405180910390f35b61010f6104c7565b6040516100fe9190612140565b6100e761012a366004611c93565b6104cd565b610137610608565b6040516100fe91906120b1565b6100e7610152366004611c93565b610699565b61015f610915565b6040516100fe9190612058565b610137610924565b6100e7610182366004611d1a565b610a15565b6100e7610195366004611ccd565b610a89565b6101ad6101a8366004611d5c565b610c9c565b6040516100fe93929190612066565b6100e76101ca366004611c6d565b610ccb565b61010f6101dd366004611c93565b610d77565b6008546001600160a01b031633146102155760405162461bcd60e51b815260040161020c90612100565b60405180910390fd5b6001600160a01b03831661023b5760405162461bcd60e51b815260040161020c90612120565b806102585760405162461bcd60e51b815260040161020c90612130565b6001600160a01b03831660009081526004602090815260408083206001600160e01b031986168452909152902054600354811080156102c55750836001600160a01b0316600382815481106102a957fe5b60009182526020909120600290910201546001600160a01b0316145b801561030b5750826001600160e01b031916600382815481106102e457fe5b6000918252602090912060029091020154600160a01b900460e01b6001600160e01b031916145b1561033857816003828154811061031e57fe5b906000526020600020906002020160010181905550610413565b600380546001600160a01b0386811660008181526004602090815260408083206001600160e01b03198b16808552908352818420879055815160608101835294855291840191825283018881526001860187559590915290517fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b6002909402938401805492516001600160a01b0319909316919093161763ffffffff60a01b1916600160a01b60e09290921c9190910217905590517fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c909101555b826001600160e01b031916846001600160a01b03167f7c3ecffa528bfccc8dd5c2454093da1c08757c960b1e5425afb9cb3b18439028846040516104579190612140565b60405180910390a350505050565b606060028054806020026020016040519081016040528092919081815260200182805480156104bd57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161049f575b5050505050905090565b60055481565b6008546001600160a01b031633146104f75760405162461bcd60e51b815260040161020c90612100565b6001600160a01b03821660009081526007602090815260408083206001600160e01b031985168452909152902054806105425760405162461bcd60e51b815260040161020c906120d0565b61055360008263ffffffff610d9416565b6001600160a01b03831660009081526007602090815260408083206001600160e01b03198616845282528083208390558383526006909152812080546001600160c01b03191681556001908101919091556005546105b091610fc2565b6005556040516001600160e01b03198316906001600160a01b038516907f896fc6a8eb054c92d480f4d32ec773e5ebe77109ad3b179f3e97ac78cf3e7cb7906105fb906000906120c2565b60405180910390a3505050565b60606003805480602002602001604051908101604052809291908181526020016000905b82821015610690576000848152602090819020604080516060810182526002860290920180546001600160a01b0381168452600160a01b900460e01b6001600160e01b0319168385015260019081015491830191909152908352909201910161062c565b50505050905090565b6008546001600160a01b031633146106c35760405162461bcd60e51b815260040161020c90612100565b6001600160a01b03821660009081526004602090815260408083206001600160e01b031985168452909152902054600354811080156107305750826001600160a01b03166003828154811061071457fe5b60009182526020909120600290910201546001600160a01b0316145b80156107765750816001600160e01b0319166003828154811061074f57fe5b6000918252602090912060029091020154600160a01b900460e01b6001600160e01b031916145b156108f857610783611b02565b60038054600019810190811061079557fe5b600091825260209182902060408051606081018252600290930290910180546001600160a01b03811684526001600160e01b0319600160a01b90910460e01b169383019390935260019092015491810191909152600380549192508291849081106107fc57fe5b60009182526020808320845160029093020180548583015160e01c600160a01b0263ffffffff60a01b196001600160a01b039586166001600160a01b031990931692909217919091161781556040948501516001909101558451821683526004808252848420868301516001600160e01b03199081168652908352858520889055928916845281528383209187168352529081205560038054906108a4906000198301611b22565b50826001600160e01b031916846001600160a01b03167f7c3ecffa528bfccc8dd5c2454093da1c08757c960b1e5425afb9cb3b1843902860006040516108ea91906120c2565b60405180910390a350610910565b60405162461bcd60e51b815260040161020c90612110565b505050565b6008546001600160a01b031681565b606060055460405190808252806020026020018201604052801561096257816020015b61094f611b02565b8152602001906001900390816109475790505b50905060006109716000610fdc565b905060005b8115610a1057600554811061098a57600080fd5b600082815260066020908152604091829020825160608101845281546001600160a01b0381168252600160a01b900460e01b6001600160e01b0319169281019290925260019081015492820192909252845191830192909185919081106109ed57fe5b6020908102919091010152610a0960008363ffffffff61101c16565b9150610976565b505090565b6008546001600160a01b03163314610a3f5760405162461bcd60e51b815260040161020c90612100565b610a4b60028383611b4e565b507ff3a1b17f96de235ad0ae63327b65739025bc92dd4bc161c9d8b661cb449ec62d8282604051610a7d92919061208e565b60405180910390a15050565b6008546001600160a01b03163314610ab35760405162461bcd60e51b815260040161020c90612100565b6001600160a01b038316610ad95760405162461bcd60e51b815260040161020c90612120565b80610af65760405162461bcd60e51b815260040161020c906120e0565b6001600160a01b03831660009081526007602090815260408083206001600160e01b0319861684529091529020548015610bac5781811415610b7657826001600160e01b031916846001600160a01b03167f896fc6a8eb054c92d480f4d32ec773e5ebe77109ad3b179f3e97ac78cf3e7cb7846040516108ea9190612140565b610b8760008263ffffffff610d9416565b600081815260066020526040812080546001600160c01b031916815560010155610bc4565b600554610bc090600163ffffffff6110b916565b6005555b610bd560008363ffffffff6110d216565b604080516060810182526001600160a01b038087168083526001600160e01b03198716602080850182815285870189815260008a81526006845288812097518854935160e01c600160a01b0263ffffffff60a01b19919098166001600160a01b031990941693909317929092169590951786559351600190950194909455818352600784528483208184529093529083902085905591519091907f896fc6a8eb054c92d480f4d32ec773e5ebe77109ad3b179f3e97ac78cf3e7cb790610457908690612140565b600660205260009081526040902080546001909101546001600160a01b03821691600160a01b900460e01b9083565b6008546001600160a01b03163314610cf55760405162461bcd60e51b815260040161020c90612100565b6001600160a01b038116610d1b5760405162461bcd60e51b815260040161020c906120f0565b6008546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600880546001600160a01b0319166001600160a01b0392909216919091179055565b600760209081526000928352604080842090915290825290205481565b80610d9e57600080fd5b610da882826111ec565b610db157600080fd5b6000818152600180840160205260408220015481901580610de357506000838152600185016020526040902060020154155b15610def575081610e37565b5060008281526001840160205260409020600201545b600081815260018086016020526040909120015415610e37576000908152600180850160205260409091200154610e05565b600081815260018086016020526040909120015415610e6b5760008181526001808601602052604090912001549150610e82565b600081815260018501602052604090206002015491505b60008181526001850160205260408082205484835291208190558015610ef4576000818152600180870160205260409091200154821415610ed85760008181526001808701602052604090912001839055610eef565b600081815260018601602052604090206002018390555b610ef8565b8285555b600082815260018601602052604090206003015460ff1615848314610f8257610f2286848761121b565b60008581526001878101602052604080832080830154878552828520938401819055845281842087905560028082015490840181905584529083208690556003908101549286905201805460ff191660ff90921615159190911790559193915b8015610f9257610f928685611292565b5050600090815260019384016020526040812081815593840181905560028401555050600301805460ff19169055565b600082821115610fd157600080fd5b508082035b92915050565b80548015611017575b600081815260018301602052604090206002015415611017576000908152600182016020526040902060020154610fe5565b919050565b60008161102857600080fd5b6000828152600180850160205260409091200154156110675760008281526001808501602052604090912001546110609084906116ad565b9050610fd6565b5060008181526001830160205260409020545b801580159061109b5750600081815260018085016020526040909120015482145b15610fd657600081815260018401602052604090205490915061107a565b6000828201838110156110cb57600080fd5b9392505050565b806110dc57600080fd5b6110e682826111ec565b156110f057600080fd5b81546000905b801561113a5780915080831015611120576000908152600180850160205260409091200154611135565b60009081526001840160205260409020600201545b6110f6565b60408051608081018252838152600060208083018281528385018381526001606086018181528a86528b82019094529590932093518455519383019390935551600282015590516003909101805460ff1916911515919091179055816111a2578284556111dc565b818310156111c557600082815260018086016020526040909120018390556111dc565b600082815260018501602052604090206002018390555b6111e684846116ea565b50505050565b600081158015906110cb575082548214806110cb57505060009081526001919091016020526040902054151590565b600081815260018401602052604080822054848352912081905580611242578284556111e6565b600081815260018086016020526040909120015482141561127857600081815260018086016020526040909120018390556111e6565b600090815260019390930160205250604090912060020155565b60005b825482148015906112ba5750600082815260018401602052604090206003015460ff16155b1561168e5760008281526001808501602052604080832054808452922001548314156114b75760008181526001850160205260408082206002015480835291206003015490925060ff161561135e576000828152600180860160205260408083206003908101805460ff199081169091558585529190932090920180549092161790556113478482611955565b600081815260018501602052604090206002015491505b60008281526001808601602052604080832090910154825290206003015460ff161580156113a95750600082815260018501602052604080822060020154825290206003015460ff16155b156113d657600082815260018581016020526040909120600301805460ff191690911790559150816114b2565b600082815260018501602052604080822060020154825290206003015460ff16611453576000828152600180860160205260408083208083015484529083206003908101805460ff199081169091559386905201805490921617905561143c8483611a2d565b600081815260018501602052604090206002015491505b600081815260018501602052604080822060039081018054868552838520808401805460ff909316151560ff1993841617905582548216909255600290910154845291909220909101805490911690556114ad8482611955565b835492505b611688565b6000818152600180860160205260408083209091015480835291206003015490925060ff1615611536576000828152600180860160205260408083206003908101805460ff1990811690915585855291909320909201805490921617905561151f8482611a2d565b600081815260018086016020526040909120015491505b600082815260018501602052604080822060020154825290206003015460ff16158015611581575060008281526001808601602052604080832090910154825290206003015460ff16155b156115ae57600082815260018581016020526040909120600301805460ff19169091179055915081611688565b60008281526001808601602052604080832090910154825290206003015460ff1661162d57600082815260018086016020526040808320600281015484529083206003908101805460ff19908116909155938690520180549092161790556116168483611955565b600081815260018086016020526040909120015491505b60008181526001808601602052604080832060039081018054878652838620808401805460ff909316151560ff199384161790558254821690925593015484529220909101805490911690556116838482611a2d565b835492505b50611295565b506000908152600190910160205260409020600301805460ff19169055565b60005b6000828152600184016020526040902060020154156116e457600091825260018301602052604090912060020154906116b0565b50919050565b60005b825482148015906117175750600082815260018401602052604080822054825290206003015460ff165b1561193357600082815260018085016020526040808320548084528184205484529220015481141561183a5760008181526001850160205260408082205482528082206002015480835291206003015490925060ff16156117c0576000818152600180860160205260408083206003808201805460ff19908116909155878652838620820180548216905582548652928520018054909216909217905590829052549250611835565b60008181526001850160205260409020600201548314156117e8578092506117e88484611955565b50600082815260018085016020526040808320548084528184206003808201805460ff19908116909155825487529386200180549093169093179091559182905254611835908590611a2d565b61192d565b6000818152600180860160205260408083205483528083209091015480835291206003015490925060ff16156118b8576000818152600180860160205260408083206003808201805460ff1990811690915587865283862082018054821690558254865292852001805490921690921790559082905254925061192d565b60008181526001808601602052604090912001548314156118e0578092506118e08484611a2d565b50600082815260018085016020526040808320548084528184206003808201805460ff1990811690915582548752938620018054909316909317909155918290525461192d908590611955565b506116ed565b505080546000908152600190910160205260409020600301805460ff19169055565b60008181526001808401602052604080832060028101805491548286529285209093015493859052918390559091801561199d57600081815260018601602052604090208490555b60008381526001860160205260409020829055816119bd57828555611a0a565b60008281526001808701602052604090912001548414156119f35760008281526001808701602052604090912001839055611a0a565b600082815260018601602052604090206002018390555b505060008181526001938401602052604080822090940183905591825291902055565b60008181526001808401602052604080832091820180549254838552918420600201549385905283905590918015611a7357600081815260018601602052604090208490555b6000838152600186016020526040902082905581611a9357828555611ae0565b6000828152600186016020526040902060020154841415611ac95760008281526001860160205260409020600201839055611ae0565b600082815260018087016020526040909120018390555b5050600081815260019093016020526040808420600201839055918352912055565b604080516060810182526000808252602082018190529181019190915290565b815481835581811115610910576002028160020283600052602060002091820191016109109190611bb1565b828054828255906000526020600020908101928215611ba1579160200282015b82811115611ba15781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190611b6e565b50611bad929150611bdf565b5090565b611bdc91905b80821115611bad5780546001600160c01b031916815560006001820155600201611bb7565b90565b611bdc91905b80821115611bad5780546001600160a01b0319168155600101611be5565b8035610fd68161219f565b60008083601f840112611c2057600080fd5b50813567ffffffffffffffff811115611c3857600080fd5b602083019150836020820283011115611c5057600080fd5b9250929050565b8035610fd6816121b6565b8035610fd6816121bf565b600060208284031215611c7f57600080fd5b6000611c8b8484611c03565b949350505050565b60008060408385031215611ca657600080fd5b6000611cb28585611c03565b9250506020611cc385828601611c57565b9150509250929050565b600080600060608486031215611ce257600080fd5b6000611cee8686611c03565b9350506020611cff86828701611c57565b9250506040611d1086828701611c62565b9150509250925092565b60008060208385031215611d2d57600080fd5b823567ffffffffffffffff811115611d4457600080fd5b611d5085828601611c0e565b92509250509250929050565b600060208284031215611d6e57600080fd5b6000611c8b8484611c62565b6000611d868383611da2565b505060200190565b6000611d9a838361201c565b505060600190565b611dab81612170565b82525050565b6000611dbd8385612158565b9350611dc882611bdc565b8060005b85811015611dfe57611dde8284612161565b611de88882611d7a565b9750611df38361214e565b925050600101611dcc565b509495945050505050565b6000611e1482612154565b611e1e8185612158565b9350611e298361214e565b8060005b83811015611dfe578151611e418882611d7a565b9750611e4c8361214e565b925050600101611e2d565b6000611e6282612154565b611e6c8185612158565b9350611e778361214e565b8060005b83811015611dfe578151611e8f8882611d8e565b9750611e9a8361214e565b925050600101611e7b565b611dab8161217b565b611dab81612194565b6000611ec4601a83612158565b7f64657374696e6174696f6e20646f6573206e6f74206578697374000000000000815260200192915050565b6000611efd601283612158565b7107765696768742063616e6e6f7420626520360741b815260200192915050565b6000611f2b601d83612158565b7f6e6577206f776e657220697320746865207a65726f2061646472657373000000815260200192915050565b6000611f64601783612158565b7f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000815260200192915050565b6000611f9d600983612158565b681b9bdd08199bdd5b9960ba1b815260200192915050565b6000611fc2601283612158565b7107461726765742063616e6e6f7420626520360741b815260200192915050565b6000611ff0601783612158565b7f6d696e47617350726963652063616e6e6f742062652030000000000000000000815260200192915050565b8051606083019061202d8482611da2565b5060208201516120406020850182611ea5565b5060408201516111e660408501825b611dab81611bdc565b60208101610fd68284611da2565b606081016120748286611da2565b6120816020830185611ea5565b611c8b604083018461204f565b60208082528101611c8b818486611db1565b602080825281016110cb8184611e09565b602080825281016110cb8184611e57565b60208101610fd68284611eae565b60208082528101610fd681611eb7565b60208082528101610fd681611ef0565b60208082528101610fd681611f1e565b60208082528101610fd681611f57565b60208082528101610fd681611f90565b60208082528101610fd681611fb5565b60208082528101610fd681611fe3565b60208101610fd6828461204f565b60200190565b5190565b90815260200190565b60006110cb6020840184611c03565b6000610fd682612188565b6001600160e01b03191690565b6001600160a01b031690565b6000610fd682611bdc565b6121a881612170565b81146121b357600080fd5b50565b6121a88161217b565b6121a881611bdc56fea365627a7a72305820f7014cfc58f43e5dc9f5a4bf6c6a6f5bce8883c71fa0b037ee28c5764fedabab6c6578706572696d656e74616cf564736f6c634300050a0040000000000000000000000000b03a86b3126157c039b55e21d378587ccfc04d45"
+ },
+ "0x5000000000000000000000000000000000000001": {
+ "balance": "0x0",
+ "constructor": "0x60806040526040516108053803806108058339818101604052604081101561002657600080fd5b50805160209182015160408051600081529384018082527f656970313936372e70726f78792e696d706c656d656e746174696f6e00000000905251603c81850301902091929091839190600019016000805160206107aa8339815191521461008a57fe5b61009c826001600160e01b036101bd16565b805115610154576000826001600160a01b0316826040518082805190602001908083835b602083106100df5780518252601f1990920191602091820191016100c0565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461013f576040519150601f19603f3d011682016040523d82523d6000602084013e610144565b606091505b505090508061015257600080fd5b505b5050604080517f656970313936372e70726f78792e61646d696e000000000000000000000000008152905190819003601301902060008051602061078a833981519152600019909101146101a457fe5b6101b6816001600160e01b0361023716565b505061024f565b6101d08161024960201b6104801760201c565b610225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806107ca603b913960400191505060405180910390fd5b6000805160206107aa83398151915255565b60008051602061078a83398151915255565b3b151590565b61052c8061025e6000396000f3fe60806040526004361061004a5760003560e01c80633659cfe6146100545780634f1ef286146100875780635c60da1b146101075780638f28397014610138578063f851a4401461016b575b610052610180565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661019a565b6100526004803603604081101561009d57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100c857600080fd5b8201836020820111156100da57600080fd5b803590602001918460018302840111640100000000831117156100fc57600080fd5b5090925090506101cb565b34801561011357600080fd5b5061011c61026f565b604080516001600160a01b039092168252519081900360200190f35b34801561014457600080fd5b506100526004803603602081101561015b57600080fd5b50356001600160a01b031661027e565b34801561017757600080fd5b5061011c61033c565b610188610198565b610198610193610346565b61036b565b565b6101a261038f565b6001600160a01b0316336001600160a01b0316146101bf57600080fd5b6101c8816103b4565b50565b6101d361038f565b6001600160a01b0316336001600160a01b0316146101f057600080fd5b6101f9836103b4565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610256576040519150601f19603f3d011682016040523d82523d6000602084013e61025b565b606091505b505090508061026957600080fd5b50505050565b6000610279610346565b905090565b61028661038f565b6001600160a01b0316336001600160a01b0316146102a357600080fd5b6001600160a01b0381166102e85760405162461bcd60e51b81526004018080602001828103825260368152602001806104876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61031161038f565b604080516001600160a01b03928316815291841660208301528051918290030190a16101c8816103f4565b600061027961038f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561038a573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103bd81610418565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b61042181610480565b61045c5760405162461bcd60e51b815260040180806020018281038252603b8152602001806104bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b3b15159056fe43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a265627a7a72305820a9aab4b95b654a79b32f5aa284796894f8329aaa083932695296085b196c27bd64736f6c634300050a0032b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000000000000000005000000000000000000000000000000000000000000000000000000000000000b03a86b3126157c039b55e21d378587ccfc04d45"
+ },
+ "0x5000000000000000000000000000000000000000": {
+ "balance": "0x0",
+ "constructor": "0x608060405234801561001057600080fd5b50610616806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80635d6067d01161005b5780635d6067d014610189578063cc1d4c02146101f9578063dfc8bf4e1461021f578063e8e23ac0146102435761007d565b806305f203d914610082578063392e53cd146100f4578063462d0b2e14610110575b600080fd5b6100f26004803603602081101561009857600080fd5b8101906020810181356401000000008111156100b357600080fd5b8201836020820111156100c557600080fd5b803590602001918460208302840111640100000000831117156100e757600080fd5b509092509050610269565b005b6100fc61033e565b604080519115158252519081900360200190f35b6100f26004803603604081101561012657600080fd5b81019060208101813564010000000081111561014157600080fd5b82018360208201111561015357600080fd5b8035906020019184602083028401116401000000008311171561017557600080fd5b9193509150356001600160a01b031661034f565b6100f26004803603602081101561019f57600080fd5b8101906020810181356401000000008111156101ba57600080fd5b8201836020820111156101cc57600080fd5b803590602001918460208302840111640100000000831117156101ee57600080fd5b5090925090506103fe565b6100fc6004803603602081101561020f57600080fd5b50356001600160a01b0316610456565b61022761050a565b604080516001600160a01b039092168252519081900360200190f35b6100fc6004803603602081101561025957600080fd5b50356001600160a01b0316610519565b610271610537565b6001600160a01b0316336001600160a01b03161461028e57600080fd5b61029661033e565b61029f57600080fd5b60005b818110156103395760008383838181106102b857fe5b602090810292909201356001600160a01b03166000818152928390526040909220549192505060ff166102ea57600080fd5b6001600160a01b038116600081815260208190526040808220805460ff19169055517fb6fa8b8bd5eab60f292eca876e3ef90722275b785309d84b1de113ce0b8c4e749190a2506001016102a2565b505050565b6001546001600160a01b0316151590565b431580610374575061035f610537565b6001600160a01b0316336001600160a01b0316145b61037d57600080fd5b61038561033e565b1561038f57600080fd5b6001600160a01b0381166103a257600080fd5b60005b828110156103d9576103d18484838181106103bc57fe5b905060200201356001600160a01b031661055c565b6001016103a5565b50600180546001600160a01b0319166001600160a01b03929092169190911790555050565b610406610537565b6001600160a01b0316336001600160a01b03161461042357600080fd5b61042b61033e565b61043457600080fd5b60005b818110156103395761044e8383838181106103bc57fe5b600101610437565b6001600160a01b03811660009081526020819052604081205460ff161561047f57506001610505565b6001805460408051639184d0ad60e01b81526001600160a01b038681166004830152602482019490945290519290911691639184d0ad91604480820192602092909190829003018186803b1580156104d657600080fd5b505afa1580156104ea573d6000803e3d6000fd5b505050506040513d602081101561050057600080fd5b505190505b919050565b6001546001600160a01b031681565b6001600160a01b031660009081526020819052604090205460ff1690565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6001600160a01b03811661056f57600080fd5b6001600160a01b03811660009081526020819052604090205460ff161561059557600080fd5b6001600160a01b038116600081815260208190526040808220805460ff19166001179055517fd415b905d4dd806bfba99a7a0e6351bd0c9db3a9912add21c0e6bef4479f673f9190a25056fea265627a7a72305820f80f64fde129011b547316cf9ce9cd58a9917ae771746100649cc2e4b3ba4edf64736f6c634300050a0032"
+ },
+ "0x6100000000000000000000000000000000000001": {
+ "balance": "0x0",
+ "constructor": "0x60806040526040516108053803806108058339818101604052604081101561002657600080fd5b50805160209182015160408051600081529384018082527f656970313936372e70726f78792e696d706c656d656e746174696f6e00000000905251603c81850301902091929091839190600019016000805160206107aa8339815191521461008a57fe5b61009c826001600160e01b036101bd16565b805115610154576000826001600160a01b0316826040518082805190602001908083835b602083106100df5780518252601f1990920191602091820191016100c0565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461013f576040519150601f19603f3d011682016040523d82523d6000602084013e610144565b606091505b505090508061015257600080fd5b505b5050604080517f656970313936372e70726f78792e61646d696e000000000000000000000000008152905190819003601301902060008051602061078a833981519152600019909101146101a457fe5b6101b6816001600160e01b0361023716565b505061024f565b6101d08161024960201b6104801760201c565b610225576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806107ca603b913960400191505060405180910390fd5b6000805160206107aa83398151915255565b60008051602061078a83398151915255565b3b151590565b61052c8061025e6000396000f3fe60806040526004361061004a5760003560e01c80633659cfe6146100545780634f1ef286146100875780635c60da1b146101075780638f28397014610138578063f851a4401461016b575b610052610180565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661019a565b6100526004803603604081101561009d57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100c857600080fd5b8201836020820111156100da57600080fd5b803590602001918460018302840111640100000000831117156100fc57600080fd5b5090925090506101cb565b34801561011357600080fd5b5061011c61026f565b604080516001600160a01b039092168252519081900360200190f35b34801561014457600080fd5b506100526004803603602081101561015b57600080fd5b50356001600160a01b031661027e565b34801561017757600080fd5b5061011c61033c565b610188610198565b610198610193610346565b61036b565b565b6101a261038f565b6001600160a01b0316336001600160a01b0316146101bf57600080fd5b6101c8816103b4565b50565b6101d361038f565b6001600160a01b0316336001600160a01b0316146101f057600080fd5b6101f9836103b4565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d8060008114610256576040519150601f19603f3d011682016040523d82523d6000602084013e61025b565b606091505b505090508061026957600080fd5b50505050565b6000610279610346565b905090565b61028661038f565b6001600160a01b0316336001600160a01b0316146102a357600080fd5b6001600160a01b0381166102e85760405162461bcd60e51b81526004018080602001828103825260368152602001806104876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61031161038f565b604080516001600160a01b03928316815291841660208301528051918290030190a16101c8816103f4565b600061027961038f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561038a573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6103bd81610418565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b61042181610480565b61045c5760405162461bcd60e51b815260040180806020018281038252603b8152602001806104bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b3b15159056fe43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a265627a7a72305820a9aab4b95b654a79b32f5aa284796894f8329aaa083932695296085b196c27bd64736f6c634300050a0032b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000000000000000006100000000000000000000000000000000000000000000000000000000000000b03a86b3126157c039b55e21d378587ccfc04d45"
+ },
+ "0x6100000000000000000000000000000000000000": {
+ "balance": "0x0",
+ "constructor": "0x608060405234801561001057600080fd5b50611976806100206000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c8063b1724b46116100f9578063dfc8bf4e11610097578063f1854e1911610071578063f1854e1914610498578063f9d5ee75146104b5578063fc87bc9e14610531578063ff1ad2d91461054e576101c4565b8063dfc8bf4e1461044f578063e523d61c14610473578063e852faad14610490576101c4565b8063bf8b68da116100d3578063bf8b68da146103d2578063c342a7bf146103ef578063c4d66de81461040c578063cd2ecdf314610432576101c4565b8063b1724b461461039f578063b384abef146103a7578063b6a6d177146103ca576101c4565b80633b79f1a511610166578063518d9fca11610140578063518d9fca1461031757806382c4c9631461033457806388cb91b614610365578063a7debe9d14610382576101c4565b80633b79f1a5146102c057806340e58ee5146102dd5780634e7b4366146102fa576101c4565b8063260f08ad116101a2578063260f08ad1461024c578063280ad39a1461026957806332eac267146102865780633381afbd146102a3576101c4565b806305261aea146101c95780630d13a1c1146101e85780630f045f691461021d575b600080fd5b6101e6600480360360208110156101df57600080fd5b503561056b565b005b61020b600480360360408110156101fe57600080fd5b5080359060200135610589565b60408051918252519081900360200190f35b6101e66004803603608081101561023357600080fd5b50803590602081013590604081013590606001356105a6565b61020b6004803603602081101561026257600080fd5b5035610c1f565b61020b6004803603602081101561027f57600080fd5b5035610c31565b61020b6004803603602081101561029c57600080fd5b5035610c43565b61020b600480360360208110156102b957600080fd5b5035610c55565b61020b600480360360208110156102d657600080fd5b5035610c67565b6101e6600480360360208110156102f357600080fd5b5035610c79565b61020b6004803603602081101561031057600080fd5b5035610e61565b61020b6004803603602081101561032d57600080fd5b5035610e73565b6103516004803603602081101561034a57600080fd5b5035610e85565b604080519115158252519081900360200190f35b61020b6004803603602081101561037b57600080fd5b50356110e8565b61020b6004803603602081101561039857600080fd5b50356110fa565b61020b61110c565b6101e6600480360360408110156103bd57600080fd5b5080359060200135611113565b61020b611375565b61020b600480360360208110156103e857600080fd5b503561137b565b61020b6004803603602081101561040557600080fd5b503561138d565b6101e66004803603602081101561042257600080fd5b50356001600160a01b031661139f565b6103516004803603602081101561044857600080fd5b503561141f565b6104576114e2565b604080516001600160a01b039092168252519081900360200190f35b61020b6004803603602081101561048957600080fd5b50356114f1565b61020b611503565b61020b600480360360208110156104ae57600080fd5b5035611509565b6104d2600480360360208110156104cb57600080fd5b503561151b565b604080519c8d5260208d019b909b528b8b019990995260608b019790975260808a019590955260a089019390935260c088019190915260e087015261010086015261012085015261014084015261016083015251908190036101800190f35b61020b6004803603602081101561054757600080fd5b5035611607565b61020b6004803603602081101561056457600080fd5b5035611619565b61057481610e85565b61057d57600080fd5b6105868161162b565b50565b600f60209081526000928352604080842090915290825290205481565b6011546040805163a26301f960e01b815233600482015290516000926001600160a01b03169163a26301f9916024808301926020929190829003018186803b1580156105f157600080fd5b505afa158015610605573d6000803e3d6000fd5b505050506040513d602081101561061b57600080fd5b505160115460408051639b4a14bf60e01b81526004810189905290519293506001600160a01b0390911691639b4a14bf91602480820192602092909190829003018186803b15801561066c57600080fd5b505afa158015610680573d6000803e3d6000fd5b505050506040513d602081101561069657600080fd5b50516106a157600080fd5b60115460408051639b4a14bf60e01b81526004810184905290516001600160a01b0390921691639b4a14bf91602480820192602092909190829003018186803b1580156106ed57600080fd5b505afa158015610701573d6000803e3d6000fd5b505050506040513d602081101561071757600080fd5b505161072257600080fd5b8085141561072f57600080fd5b6000858152602081905260409020541561074857600080fd5b60115460408051637f2a23bf60e11b815290516000926001600160a01b03169163fe54477e9160048083019286929190829003018186803b15801561078c57600080fd5b505afa1580156107a0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156107c957600080fd5b8101908080516401000000008111156107e157600080fd5b820160208101848111156107f457600080fd5b815185602082028301116401000000008211171561081157600080fd5b50505160008681526001602081905260409091208054918201905590945060038504935083119150610844905057600080fd5b61438086101561085357600080fd5b6201518086111561086357600080fd5b716f6674656e20626c6f636b2064656c61797360701b8514806108995750706f6674656e20626c6f636b20736b69707360781b85145b806108b85750716f6674656e2072657665616c20736b69707360701b85145b806108cf5750691d5b9c995d99585b195960b21b85145b6108d857600080fd5b601080546001019081905560006108fd886108f1611810565b9063ffffffff61181416565b60008381526002602090815260408083208d90556003825280832089905560048083528184208590556011548251633ba6481760e21b81529251959650600c956001600160a01b039091169363ee99205c938084019391929190829003018186803b15801561096b57600080fd5b505afa15801561097f573d6000803e3d6000fd5b505050506040513d602081101561099557600080fd5b50516040805163d609ea9360e01b815290519192506000916001600160a01b0384169163d609ea93916004808301926020929190829003018186803b1580156109dd57600080fd5b505afa1580156109f1573d6000803e3d6000fd5b505050506040513d6020811015610a0757600080fd5b50516040805163461121d760e11b815290519192506000916001600160a01b03851691638c2243ae916004808301926020929190829003018186803b158015610a4f57600080fd5b505afa158015610a63573d6000803e3d6000fd5b505050506040513d6020811015610a7957600080fd5b5051905080851115610aaf57610aac60016108f1868186610aa08b8863ffffffff61182f16565b9063ffffffff61184416565b93505b610ac3816108f1868563ffffffff61186616565b600087815260056020526040902055610af7816108f184610aeb88600c63ffffffff61182f16565b9063ffffffff61186616565b6006600088815260200190815260200160002081905550826001600160a01b031663794c0c686040518163ffffffff1660e01b815260040160206040518083038186803b158015610b4757600080fd5b505afa158015610b5b573d6000803e3d6000fd5b505050506040513d6020811015610b7157600080fd5b50516000878152600a6020908152604080832093909355600781528282208e90556009905220600190555060029250869150610baa9050565b6000848152600b60209081526040808320949093046001019093558b81529182905290208290558515610be157610be18287611113565b6040805183815290517f06acbfb32bcf8383f3b0a768b70ac9ec234ea0f2d3b9c77fa6a2de69b919aad19181900360200190a1505050505050505050565b60006020819052908152604090205481565b60036020526000908152604090205481565b600e6020526000908152604090205481565b60076020526000908152604090205481565b60026020526000908152604090205481565b6011546040805163a26301f960e01b815233600482015290516000926001600160a01b03169163a26301f9916024808301926020929190829003018186803b158015610cc457600080fd5b505afa158015610cd8573d6000803e3d6000fd5b505050506040513d6020811015610cee57600080fd5b50516000838152600360205260409020549091508114610d0d57600080fd5b600082815260096020526040902054600114610d2857600080fd5b600082815260046020526040902054610d3f611810565b10610d4957600080fd5b60115460408051639b4a14bf60e01b81526004810184905290516001600160a01b0390921691639b4a14bf91602480820192602092909190829003018186803b158015610d9557600080fd5b505afa158015610da9573d6000803e3d6000fd5b505050506040513d6020811015610dbf57600080fd5b5051610dca57600080fd5b60008281526009602090815260408083206003905583835260019182905290912054610dfb9163ffffffff61182f16565b6000828152600160209081526040808320939093558482526002815282822054808352828252838320929092558251858152925191927f829a8683c544ad289ce92d3ce06e9ebad69b18a6916e60ec766c2c217461d8e9929081900390910190a1505050565b600d6020526000908152604090205481565b60086020526000908152604090205481565b600081815260096020526040812054600114610ea3575060006110e3565b600082815260046020526040902054610eba611810565b10610ec7575060016110e3565b6000828152600a6020908152604091829020546011548351633ba6481760e21b8152935191936001600160a01b039091169263ee99205c92600480840193829003018186803b158015610f1957600080fd5b505afa158015610f2d573d6000803e3d6000fd5b505050506040513d6020811015610f4357600080fd5b505160408051630f29818d60e31b815290516001600160a01b039092169163794c0c6891600480820192602092909190829003018186803b158015610f8757600080fd5b505afa158015610f9b573d6000803e3d6000fd5b505050506040513d6020811015610fb157600080fd5b505114156110df576000828152600c6020908152604080832054600d835281842054600e909352818420546011548351637f2a23bf60e11b815293519295919391926001600160a01b039091169163fe54477e9160048083019286929190829003018186803b15801561102357600080fd5b505afa158015611037573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561106057600080fd5b81019080805164010000000081111561107857600080fd5b8201602081018481111561108b57600080fd5b81518560208202830111640100000000821117156110a857600080fd5b50505193508392506110c891508490506108f1878763ffffffff61181416565b106110da5760019450505050506110e3565b505050505b5060005b919050565b60016020526000908152604090205481565b60066020526000908152604090205481565b6201518081565b60008281526003602052604090205461112b57600080fd5b6011546040805163a26301f960e01b815233600482015290516000926001600160a01b03169163a26301f9916024808301926020929190829003018186803b15801561117657600080fd5b505afa15801561118a573d6000803e3d6000fd5b505050506040513d60208110156111a057600080fd5b505160115460408051639b4a14bf60e01b81526004810184905290519293506001600160a01b0390911691639b4a14bf91602480820192602092909190829003018186803b1580156111f157600080fd5b505afa158015611205573d6000803e3d6000fd5b505050506040513d602081101561121b57600080fd5b505161122657600080fd5b60008381526002602052604090205481141561124157600080fd5b60008381526009602052604090205460011461125c57600080fd5b600083815260046020526040902054611273611810565b1061127d57600080fd5b6000838152600f60209081526040808320848452909152902054156112a157600080fd5b6000838152600f60209081526040808320848452909152902082905560018214156112e0576000838152600c6020526040902080546001019055611322565b6002821415611303576000838152600d6020526040902080546001019055611322565b60038214156101c4576000838152600e60205260409020805460010190555b604080518381529051829185917f5fe8f1cc066896edbe87bedf2e870c54f6311a7d6668c860949e2e1224a0955e9181900360200190a361136283610e85565b15611370576113708361162b565b505050565b61438081565b600a6020526000908152604090205481565b60046020526000908152604090205481565b6113a7611810565b15806113cb57506113b661188d565b6001600160a01b0316336001600160a01b0316145b6113d457600080fd5b6011546001600160a01b0316156113ea57600080fd5b6001600160a01b0381166113fd57600080fd5b601180546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526020819052604081205480158061144a5750600081815260096020526040902054600114155b156114595760009150506110e3565b600081815260046020526040902054611470611810565b10156114805760019150506110e3565b600061148b826118b2565b905060028114156114b8576000828152600660205260409020546114ad611810565b1115925050506110e3565b60038114156114d8576000828152600560205260409020546114ad611810565b5060009392505050565b6011546001600160a01b031681565b60056020526000908152604090205481565b60105481565b600c6020526000908152604090205481565b60008181526002602090815260408083205460038352818420546004845282852054600585528386205460068652848720546007875285882054600988528689205460089098529588205494979396929591949093919291908190819081908190156115955760008d81526008602052604090205461159e565b61159e8d6118b2565b9450600b60008e8152602001908152602001600020549350600c60008e8152602001908152602001600020549250600d60008e8152602001908152602001600020549150600e60008e815260200190815260200160002054905091939597999b5091939597999b565b600b6020526000908152604090205481565b60096020526000908152604090205481565b6011546001600160a01b031661164057600080fd5b600061164b826118b2565b600083815260036020908152604080832054600283528184205460088452828520869055818552600193849052919093205493945091926116919163ffffffff61182f16565b60008381526001602052604090205560028314156117355760115460008581526006602090815260408083205460079092528083205481516305461c8560e01b81526004810187905260248101939093526044830152516001600160a01b03909316926305461c859260648084019391929182900301818387803b15801561171857600080fd5b505af115801561172c573d6000803e3d6000fd5b505050506117c6565b60038314156117c65760115460008581526005602090815260408083205460079092528083205481516305461c8560e01b81526004810187905260248101939093526044830152516001600160a01b03909316926305461c859260648084019391929182900301818387803b1580156117ad57600080fd5b505af11580156117c1573d6000803e3d6000fd5b505050505b60008181526020818152604080832092909255815186815291517f839cf22e1ba87ce2f5b9bbf46cf0175a09eed52febdfaac8852478e68203c7639281900390910190a150505050565b4390565b60008282018381101561182657600080fd5b90505b92915050565b60008282111561183e57600080fd5b50900390565b600080821161185257600080fd5b600082848161185d57fe5b04949350505050565b60008261187557506000611829565b8282028284828161188257fe5b041461182657600080fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b6000818152600c6020908152604080832054600d835281842054600e845282852054600b909452918420549092906118f4826108f1868663ffffffff61181416565b101561190657600193505050506110e3565b600181831115611921578383111561191c575060025b611938565b828211801561192f57508382115b15611938575060035b9594505050505056fea265627a7a723058200623ccf119f7da78633edc0832418c3a32f1244627f261a1dc1d135e3ceccba164736f6c634300050a0032"
+ },
+ "0x6000000000000000000000000000000000000000": {
+ "balance": "0x0",
+ "constructor": "0x6080604052600080546001600160a01b03191633179055670de0b6b3a764000060035534801561002e57600080fd5b506040516120943803806120948339818101604052604081101561005157600080fd5b5080516020909101516001600160a01b03821661006d57600080fd5b604080517f736572766963655f7472616e73616374696f6e5f636865636b657200000000008152905190819003601b019020336001600160a01b038316156100cd5750600080546001600160a01b0319166001600160a01b038416179055815b600082815260016020819052604080832080546001600160a01b0386166001600160a01b03199091168117825582517f4100000000000000000000000000000000000000000000000000000000000000815260029092019382019390935290519081900360210181206001600160601b0319606089901b169055909184917f4963513eca575aba66fdcd25f267aae85958fe6fb97e75fa25d783f1a091a2219190a36040805181815260018183018190527f41000000000000000000000000000000000000000000000000000000000000006060830181905260806020840181905283019190915260a0820152905183917fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea919081900360c00190a250505050611e98806101fc6000396000f3fe60806040526004361061014b5760003560e01c80639890220b116100b6578063df57b7421161006f578063df57b742146105e6578063e30bd74014610610578063eadf9760146106b8578063ef5454d61461073a578063f25eb5c1146107be578063f6d339e4146107d35761014b565b80639890220b146104e4578063ac4e73f9146104f9578063ac72c1201461057d578063c3a3582514610426578063ddca3f43146105a7578063deb931a2146105bc5761014b565b80636795dbcd116101085780636795dbcd1461031057806369fe0e2d146103ae57806379ce9fac146103d85780638da5cb5b1461041157806390b97fc11461042657806392698814146104ba5761014b565b806306b2ff471461015057806313af40351461019757806319362a28146101cc5780633f3935d11461024e578063432ced04146102c95780634f39ca59146102e6575b600080fd5b34801561015c57600080fd5b506101836004803603602081101561017357600080fd5b50356001600160a01b031661085e565b604080519115158252519081900360200190f35b3480156101a357600080fd5b506101ca600480360360208110156101ba57600080fd5b50356001600160a01b031661088d565b005b3480156101d857600080fd5b50610183600480360360608110156101ef57600080fd5b81359190810190604081016020820135600160201b81111561021057600080fd5b82018360208201111561022257600080fd5b803590602001918460018302840111600160201b8311171561024357600080fd5b919350915035610912565b34801561025a57600080fd5b506101836004803603602081101561027157600080fd5b810190602081018135600160201b81111561028b57600080fd5b82018360208201111561029d57600080fd5b803590602001918460018302840111600160201b831117156102be57600080fd5b509092509050610a5b565b610183600480360360208110156102df57600080fd5b5035610be4565b3480156102f257600080fd5b506101836004803603602081101561030957600080fd5b5035610c91565b34801561031c57600080fd5b506103926004803603604081101561033357600080fd5b81359190810190604081016020820135600160201b81111561035457600080fd5b82018360208201111561036657600080fd5b803590602001918460018302840111600160201b8311171561038757600080fd5b509092509050610efa565b604080516001600160a01b039092168252519081900360200190f35b3480156103ba57600080fd5b50610183600480360360208110156103d157600080fd5b5035610f8c565b3480156103e457600080fd5b50610183600480360360408110156103fb57600080fd5b50803590602001356001600160a01b0316610fe4565b34801561041d57600080fd5b506103926110b4565b34801561043257600080fd5b506104a86004803603604081101561044957600080fd5b81359190810190604081016020820135600160201b81111561046a57600080fd5b82018360208201111561047c57600080fd5b803590602001918460018302840111600160201b8311171561049d57600080fd5b5090925090506110c3565b60408051918252519081900360200190f35b3480156104c657600080fd5b50610183600480360360208110156104dd57600080fd5b5035611152565b3480156104f057600080fd5b506101836111bb565b34801561050557600080fd5b506101836004803603604081101561051c57600080fd5b810190602081018135600160201b81111561053657600080fd5b82018360208201111561054857600080fd5b803590602001918460018302840111600160201b8311171561056957600080fd5b9193509150356001600160a01b031661123d565b34801561058957600080fd5b50610183600480360360208110156105a057600080fd5b5035611546565b3480156105b357600080fd5b506104a86115b3565b3480156105c857600080fd5b50610392600480360360208110156105df57600080fd5b50356115b9565b3480156105f257600080fd5b506103926004803603602081101561060957600080fd5b5035611620565b34801561061c57600080fd5b506106436004803603602081101561063357600080fd5b50356001600160a01b031661168b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561067d578181015183820152602001610665565b50505050905090810190601f1680156106aa5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156106c457600080fd5b50610183600480360360608110156106db57600080fd5b81359190810190604081016020820135600160201b8111156106fc57600080fd5b82018360208201111561070e57600080fd5b803590602001918460018302840111600160201b8311171561072f57600080fd5b919350915035611734565b34801561074657600080fd5b506101836004803603604081101561075d57600080fd5b810190602081018135600160201b81111561077757600080fd5b82018360208201111561078957600080fd5b803590602001918460018302840111600160201b831117156107aa57600080fd5b9193509150356001600160a01b0316611880565b3480156107ca57600080fd5b506101ca6119c4565b3480156107df57600080fd5b50610183600480360360608110156107f657600080fd5b81359190810190604081016020820135600160201b81111561081757600080fd5b82018360208201111561082957600080fd5b803590602001918460018302840111600160201b8311171561084a57600080fd5b9193509150356001600160a01b0316611c30565b6001600160a01b0316600090815260026020819052604090912054600181161561010002600019011604151590565b6000546001600160a01b031633146108a457600080fd5b6001600160a01b0381166108b757600080fd5b600080546040516001600160a01b03808516939216917f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236491a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000848152600160208190526040822001548590600160a01b900460ff1615801561095357506000818152600160205260409020546001600160a01b031615155b61095c57600080fd5b60008681526001602052604090205486906001600160a01b0316331461098157600080fd5b83600160008981526020019081526020016000206002018787604051808383808284378083019250505092505050908152602001604051809103902081905550867fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea878789896040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a25060019695505050505050565b600082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508451602080870191909120825260019081905260409091200154600160a01b900460ff161592505081159050610ae6575080516020808301919091206000908152600190915260409020546001600160a01b031615155b610aef57600080fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525084516020808701919091208252600190819052604090912001546001600160a01b031633149250610b5491505057600080fd5b336000908152600260205260409020610b6e908686611d8b565b50336001600160a01b03167f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c91920868660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2506001949350505050565b6000818152600160208190526040822001548290600160a01b900460ff16158015610c2457506000818152600160205260409020546001600160a01b0316155b610c2d57600080fd5b600354341015610c3c57600080fd5b60008381526001602052604080822080546001600160a01b031916339081179091559051909185917f4963513eca575aba66fdcd25f267aae85958fe6fb97e75fa25d783f1a091a2219190a350600192915050565b6000818152600160208190526040822001548290600160a01b900460ff16158015610cd257506000818152600160205260409020546001600160a01b031615155b610cdb57600080fd5b60008381526001602052604090205483906001600160a01b03163314610d0057600080fd5b60008481526001602081815260408084208301546001600160a01b03168452600291829052928390209251835488949391928392859260001991811615610100029190910116048015610d8a5780601f10610d68576101008083540402835291820191610d8a565b820191906000526020600020905b815481529060010190602001808311610d76575b505091505060405180910390201415610ea25760008481526001602081815260408084208301546001600160a01b03168085526002808452948290208251848152815460001996811615610100029690960190951695909504928401839052937f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd939092909182919082019084908015610e655780601f10610e3a57610100808354040283529160200191610e65565b820191906000526020600020905b815481529060010190602001808311610e4857829003601f168201915b50509250505060405180910390a26000848152600160208181526040808420909201546001600160a01b03168352600290528120610ea291611e09565b6000848152600160208190526040808320909101805460ff60a01b1916600160a01b17905551339186917fef1961b4d2909dc23643b309bfe5c3e5646842d98c3a58517037ef3871185af39190a35060019392505050565b6000838152600160208190526040822001548490600160a01b900460ff16158015610f3b57506000818152600160205260409020546001600160a01b031615155b610f4457600080fd5b60016000868152602001908152602001600020600201848460405180838380828437919091019485525050604051928390036020019092205460601c93505050509392505050565b600080546001600160a01b03163314610fa457600080fd5b60038290556040805183815290517f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c39181900360200190a1506001919050565b6000828152600160208190526040822001548390600160a01b900460ff1615801561102557506000818152600160205260409020546001600160a01b031615155b61102e57600080fd5b60008481526001602052604090205484906001600160a01b0316331461105357600080fd5b60008581526001602052604080822080546001600160a01b0319166001600160a01b03881690811790915590519091339188917f7b97c62130aa09acbbcbf7482630e756592496f1759eaf702f469cf64dfb779491a4506001949350505050565b6000546001600160a01b031681565b6000838152600160208190526040822001548490600160a01b900460ff1615801561110457506000818152600160205260409020546001600160a01b031615155b61110d57600080fd5b60016000868152602001908152602001600020600201848460405180838380828437919091019485525050604051928390036020019092205493505050509392505050565b6000818152600160208190526040822001548290600160a01b900460ff1615801561119357506000818152600160205260409020546001600160a01b031615155b61119c57600080fd5b50506000908152600160205260409020546001600160a01b0316151590565b600080546001600160a01b031633146111d357600080fd5b604080513031815290517fdef931299fe61d176f949118058530c1f3f539dcb6950b4e372c9b835c33ca079181900360200190a16040513390303180156108fc02916000818181858888f19350505050158015611234573d6000803e3d6000fd5b50600190505b90565b600083838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508451602080870191909120825260019081905260409091200154600160a01b900460ff1615925050811590506112c8575080516020808301919091206000908152600190915260409020546001600160a01b031615155b6112d157600080fd5b8484604051808383808284376040805193909101839003909220600081815260016020529290922054919450506001600160a01b031633149150611316905057600080fd5b60008686604051808383808284376040805191909301819003902060008181526001602081905293902090920154919550506001600160a01b0316158015935091506113f89050575060008181526001602081815260408084208301546001600160a01b031684526002918290529283902092518354859493919283928592600019918116156101000291909101160480156113e95780601f106113c75761010080835404028352918201916113e9565b820191906000526020600020905b8154815290600101906020018083116113d5575b50509150506040518091039020145b156114aa576000818152600160208181526040808420909201546001600160a01b0316835260029052812061142c91611e09565b6000818152600160208181526040928390209091015482518281529182018990526001600160a01b0316917f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd918a918a919081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a25b60008181526001602081815260409283902090910180546001600160a01b0319166001600160a01b0389169081179091558251828152918201899052917f728435a0031f6a04538fcdd24922a7e06bc7bc945db03e83d22122d1bc5f28df918a918a919081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a25060019695505050505050565b6000818152600160208190526040822001548290600160a01b900460ff1615801561158757506000818152600160205260409020546001600160a01b031615155b61159057600080fd5b5050600090815260016020819052604090912001546001600160a01b0316151590565b60035481565b6000818152600160208190526040822001548290600160a01b900460ff161580156115fa57506000818152600160205260409020546001600160a01b031615155b61160357600080fd5b50506000908152600160205260409020546001600160a01b031690565b6000818152600160208190526040822001548290600160a01b900460ff1615801561166157506000818152600160205260409020546001600160a01b031615155b61166a57600080fd5b5050600090815260016020819052604090912001546001600160a01b031690565b6001600160a01b038116600090815260026020818152604092839020805484516001821615610100026000190190911693909304601f810183900483028401830190945283835260609390918301828280156117285780601f106116fd57610100808354040283529160200191611728565b820191906000526020600020905b81548152906001019060200180831161170b57829003601f168201915b50505050509050919050565b6000848152600160208190526040822001548590600160a01b900460ff1615801561177557506000818152600160205260409020546001600160a01b031615155b61177e57600080fd5b60008681526001602052604090205486906001600160a01b031633146117a357600080fd5b8360001b600160008981526020019081526020016000206002018787604051808383808284378083019250505092505050908152602001604051809103902081905550867fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea878789896040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a25060019695505050505050565b600083838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508451602080870191909120825260019081905260409091200154600160a01b900460ff16159250508115905061190b575080516020808301919091206000908152600190915260409020546001600160a01b031615155b61191457600080fd5b6000546001600160a01b0316331461192b57600080fd5b6001600160a01b038316600090815260026020526040902061194e908686611d8b565b50826001600160a01b03167f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c91920868660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2506001949350505050565b33600090815260026020818152604092839020805484516001821615610100026000190190911693909304601f8101839004830284018301909452838352919290830182828015611a565780601f10611a2b57610100808354040283529160200191611a56565b820191906000526020600020905b815481529060010190602001808311611a3957829003601f168201915b5050505050600160008280519060200120815260200190815260200160002060010160149054906101000a900460ff16158015611ab4575080516020808301919091206000908152600190915260409020546001600160a01b031615155b611abd57600080fd5b33600081815260026020818152604092839020835182815281546000196101006001831615020116939093049183018290527f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd93909291829182019084908015611b685780601f10611b3d57610100808354040283529160200191611b68565b820191906000526020600020905b815481529060010190602001808311611b4b57829003601f168201915b50509250505060405180910390a2336000908152600260208190526040808320905181546001949382918491600019610100838a16150201909116048015611be75780601f10611bc5576101008083540402835291820191611be7565b820191906000526020600020905b815481529060010190602001808311611bd3575b505060408051918290039091208452602080850195909552928301600090812060010180546001600160a01b0319169055338152600290945250508120611c2d91611e09565b50565b6000848152600160208190526040822001548590600160a01b900460ff16158015611c7157506000818152600160205260409020546001600160a01b031615155b611c7a57600080fd5b60008681526001602052604090205486906001600160a01b03163314611c9f57600080fd5b8360601b6bffffffffffffffffffffffff1916600160008981526020019081526020016000206002018787604051808383808284378083019250505092505050908152602001604051809103902081905550867fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea878789896040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a25060019695505050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611dcc5782800160ff19823516178555611df9565b82800160010185558215611df9579182015b82811115611df9578235825591602001919060010190611dde565b50611e05929150611e49565b5090565b50805460018160011615610100020316600290046000825580601f10611e2f5750611c2d565b601f016020900490600052602060002090810190611c2d91905b61123a91905b80821115611e055760008155600101611e4f56fea265627a7a723058206a686f5fa03e765c624a73295db57b5403554102e83af1f6c94d41e196e3939564736f6c634300050a00320000000000000000000000005000000000000000000000000000000000000001000000000000000000000000b03a86b3126157c039b55e21d378587ccfc04d45"
+ },
+ "0x7000000000000000000000000000000000000000": {
+ "balance": "0x0",
+ "constructor": "0x608060405234801561001057600080fd5b506040516109dd3803806109dd833981810160405261016081101561003457600080fd5b81019080805164010000000081111561004c57600080fd5b8201602081018481111561005f57600080fd5b815185602082028301116401000000008211171561007c57600080fd5b505060208201516040909201805191949293916401000000008111156100a157600080fd5b820160208101848111156100b457600080fd5b81518560208202830111640100000000821117156100d157600080fd5b505092919060200180516401000000008111156100ed57600080fd5b8201602081018481111561010057600080fd5b815185602082028301116401000000008211171561011d57600080fd5b5050602082015160408301516060840151608085015160a086015160c087015160e0909701518c51969950949750929591949093908b9060009061015d57fe5b60200260200101516001600160a01b0316636e85d53d8c60018151811061018057fe5b60200260200101518d60068151811061019557fe5b60200260200101518e6002815181106101aa57fe5b60200260200101518f6003815181106101bf57fe5b60200260200101518e8e8e6040518863ffffffff1660e01b815260040180886001600160a01b03166001600160a01b03168152602001876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b03168152602001806020018060200184151515158152602001838103835286818151815260200191508051906020019060200280838360005b8381101561028757818101518382015260200161026f565b50505050905001838103825285818151815260200191508051906020019060200280838360005b838110156102c65781810151838201526020016102ae565b505050509050019950505050505050505050600060405180830381600087803b1580156102f257600080fd5b505af1158015610306573d6000803e3d6000fd5b5050505060608851604051908082528060200260200182016040528015610337578160200160208202803883390190505b50905060005b8151811015610410578c60008151811061035357fe5b60200260200101516001600160a01b031663a26301f98b838151811061037557fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156103c357600080fd5b505afa1580156103d7573d6000803e3d6000fd5b505050506040513d60208110156103ed57600080fd5b505182518390839081106103fd57fe5b602090810291909101015260010161033d565b508b60038151811061041e57fe5b60200260200101516001600160a01b031663cc4a66678d60008151811061044157fe5b60200260200101518e60068151811061045657fe5b6020026020010151848b8b8b8b8b6040518963ffffffff1660e01b815260040180896001600160a01b03166001600160a01b03168152602001886001600160a01b03166001600160a01b0316815260200180602001878152602001868152602001858152602001848152602001838152602001828103825288818151815260200191508051906020019060200280838360005b838110156105015781810151838201526020016104e9565b505050509050019950505050505050505050600060405180830381600087803b15801561052d57600080fd5b505af1158015610541573d6000803e3d6000fd5b50505050508a60018151811061055357fe5b60200260200101516001600160a01b031663485cc9558c60008151811061057657fe5b602002602001015160006040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b0316815260200192505050600060405180830381600087803b1580156105e157600080fd5b505af11580156105f5573d6000803e3d6000fd5b505050508a60028151811061060657fe5b60200260200101516001600160a01b03166328804dbd828d60008151811061062a57fe5b602002602001015160016040518463ffffffff1660e01b815260040180848152602001836001600160a01b03166001600160a01b03168152602001821515151581526020019350505050600060405180830381600087803b15801561068e57600080fd5b505af11580156106a2573d6000803e3d6000fd5b5050604080516001808252818301909252606093509150602080830190803883390190505090508a816000815181106106d757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508b60048151811061070457fe5b60200260200101516001600160a01b03166390482d72828e60058151811061072857fe5b60200260200101518f60008151811061073d57fe5b60200260200101516040518463ffffffff1660e01b81526004018080602001846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828103825285818151815260200191508051906020019060200280838360005b838110156107c45781810151838201526020016107ac565b50505050905001945050505050600060405180830381600087803b1580156107eb57600080fd5b505af11580156107ff573d6000803e3d6000fd5b505050508b60058151811061081057fe5b60200260200101516001600160a01b031663462d0b2e828e60008151811061083457fe5b60200260200101516040518363ffffffff1660e01b81526004018080602001836001600160a01b03166001600160a01b03168152602001828103825284818151815260200191508051906020019060200280838360005b838110156108a357818101518382015260200161088b565b505050509050019350505050600060405180830381600087803b1580156108c957600080fd5b505af11580156108dd573d6000803e3d6000fd5b505050508b6006815181106108ee57fe5b60200260200101516001600160a01b031663c4d66de88d60008151811061091157fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b15801561096157600080fd5b505af1158015610975573d6000803e3d6000fd5b5050505060004311156109855733ff5b505050505050505050505050603e8061099f6000396000f3fe6080604052600080fdfea265627a7a72305820a55f32c63be7e06dfeb1da79cfe2235ed39ef2873ad64c118154d8cdff8e697e64736f6c634300050a00320000000000000000000000000000000000000000000000000000000000000160000000000000000000000000b03a86b3126157c039b55e21d378587ccfc04d45000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000070000000000000000000000001000000000000000000000000000000000000001000000000000000000000000200000000000000000000000000000000000000100000000000000000000000030000000000000000000000000000000000000010000000000000000000000001100000000000000000000000000000000000001000000000000000000000000400000000000000000000000000000000000000100000000000000000000000050000000000000000000000000000000000000010000000000000000000000006100000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000014747a698ec1227e6753026c08b29b4d5d3bc48400000000000000000000000056d421c0ac39976e89fa400d34ca6579417b84ca0000000000000000000000005cd99ac2f0f8c25a1e670f6bab19d52aad69d87500000000000000000000000060f1cf46b42df059b98acf67c1dd7771b100e124000000000000000000000000655e97ba0f63a56c2b56eb3e84f7bf42b20bae14000000000000000000000000755b6259938d140626301c0b6026c1c00c9ed5d9000000000000000000000000a8010da9cb0ac018c86a06301963853cc371a18c000000000000000000000000e11c7ffea05634889f39a1d997772b73adfd685b000000000000000000000000e621f323f5cb0ca55a041aeea0f025ce338b8aee000000000000000000000000f85bb4a67db28522644cbe63595d1665b64090ef000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000047200b51fcbf7177c24c1a484c960be8bf9abf00000000000000000000000001753f99abe0433fc81e396bc1bdabec6b0f1d49d0000000000000000000000001fd4b06403e95eb0114cb3e8f6b71f7a0cc58d7300000000000000000000000041bec4dcb8dd230cb4e077c5fda61d37798b06d90000000000000000000000004b56e96ad92b4d81f533c5716988f9f3665125d20000000000000000000000005d46a20c7e9bd3556e36d39ea1a931f9fe994519000000000000000000000000cc80dff6b6386b56213a9f2701a67ebeca0bbea8000000000000000000000000dc8a45c55f83ac461bc49662324d2ad2ea811e84000000000000000000000000dd3cd543a443bd405bfbea1165753794906bd994000000000000000000000000fdd90b7d2b52a6232675f54bb2f03a5dfb2e832a"
+ }
+}
diff --git a/core/allocs/gnosis.json b/core/allocs/gnosis.json
new file mode 100644
index 000000000000..ddb896259ffa
--- /dev/null
+++ b/core/allocs/gnosis.json
@@ -0,0 +1,14 @@
+{
+ "0x0000000000000000000000000000000000000001": {
+ "balance": "0x1"
+ },
+ "0x0000000000000000000000000000000000000002": {
+ "balance": "0x1"
+ },
+ "0x0000000000000000000000000000000000000003": {
+ "balance": "0x1"
+ },
+ "0x0000000000000000000000000000000000000004": {
+ "balance": "0x1"
+ }
+}
diff --git a/core/forkid/forkid.go b/core/forkid/forkid.go
index 76825d3befc1..f5abe2fda55c 100644
--- a/core/forkid/forkid.go
+++ b/core/forkid/forkid.go
@@ -293,5 +293,13 @@ func gatherForks(config *params.ChainConfig, genesis uint64) ([]uint64, []uint64
for len(forksByTime) > 0 && forksByTime[0] <= genesis {
forksByTime = forksByTime[1:]
}
- return forksByBlock, forksByTime
+ // hack-insert the poa reward contract block
+ var hackedForksByBlock []uint64
+ for i := range forksByBlock {
+ if i > 0 && forksByBlock[i-1] < 9186425 && forksByBlock[i] > 9186425 {
+ hackedForksByBlock = append(hackedForksByBlock, 9186425)
+ }
+ hackedForksByBlock = append(hackedForksByBlock, forksByBlock[i])
+ }
+ return hackedForksByBlock, forksByTime
}
diff --git a/core/genesis.go b/core/genesis.go
index 634be9a9e0b1..dba416992a3a 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -18,6 +18,7 @@ package core
import (
"bytes"
+ "embed"
"encoding/hex"
"encoding/json"
"errors"
@@ -66,6 +67,7 @@ type Genesis struct {
BaseFee *big.Int `json:"baseFeePerGas"` // EIP-1559
ExcessBlobGas *uint64 `json:"excessBlobGas"` // EIP-4844
BlobGasUsed *uint64 `json:"blobGasUsed"` // EIP-4844
+ AuRaSeal []byte `json:"auraSeal,omitempty"`
}
func ReadGenesis(db ethdb.Database) (*Genesis, error) {
@@ -416,6 +418,10 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
return params.SepoliaChainConfig
case ghash == params.GoerliGenesisHash:
return params.GoerliChainConfig
+ case ghash == params.GnosisGenesisHash:
+ return params.GnosisChainConfig
+ case ghash == params.ChiadoGenesisHash:
+ return params.ChiadoChainConfig
default:
return params.AllEthashProtocolChanges
}
@@ -445,6 +451,7 @@ func (g *Genesis) ToBlock() *types.Block {
Difficulty: g.Difficulty,
MixDigest: g.Mixhash,
Coinbase: g.Coinbase,
+ Signature: g.AuRaSeal,
Root: root,
}
if g.GasLimit == 0 {
@@ -579,6 +586,46 @@ func DefaultHoleskyGenesisBlock() *Genesis {
}
}
+//go:embed allocs
+var allocs embed.FS
+
+func readPrealloc(filename string) GenesisAlloc {
+ f, err := allocs.Open(filename)
+ if err != nil {
+ panic(fmt.Sprintf("Could not open genesis preallocation for %s: %v", filename, err))
+ }
+ defer f.Close()
+ decoder := json.NewDecoder(f)
+ ga := make(GenesisAlloc)
+ err = decoder.Decode(&ga)
+ if err != nil {
+ panic(fmt.Sprintf("Could not parse genesis preallocation for %s: %v", filename, err))
+ }
+ return ga
+}
+
+func DefaultGnosisGenesisBlock() *Genesis {
+ return &Genesis{
+ Config: params.GnosisChainConfig,
+ Timestamp: 0,
+ AuRaSeal: common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
+ GasLimit: 0x989680,
+ Difficulty: big.NewInt(0x20000),
+ Alloc: readPrealloc("allocs/gnosis.json"),
+ }
+}
+
+func DefaultChiadoGenesisBlock() *Genesis {
+ return &Genesis{
+ Config: params.ChiadoChainConfig,
+ Timestamp: 0,
+ AuRaSeal: common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
+ GasLimit: 0x989680,
+ Difficulty: big.NewInt(0x20000),
+ Alloc: readPrealloc("allocs/chiado.json"),
+ }
+}
+
// DeveloperGenesisBlock returns the 'geth --dev' genesis block.
func DeveloperGenesisBlock(gasLimit uint64, faucet *common.Address) *Genesis {
// Override the default period to the user requested one
diff --git a/core/rawdb/accessors_chain_aura.go b/core/rawdb/accessors_chain_aura.go
new file mode 100644
index 000000000000..a5a9e8060923
--- /dev/null
+++ b/core/rawdb/accessors_chain_aura.go
@@ -0,0 +1,65 @@
+package rawdb
+
+import (
+ "encoding/binary"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/ethdb"
+)
+
+func ReadEpoch(db ethdb.KeyValueReader, blockNum uint64, blockHash common.Hash) (transitionProof []byte, err error) {
+ k := make([]byte, 40 /* block num uint64 + block hash */)
+ binary.BigEndian.PutUint64(k, blockNum)
+ copy(k[8:], blockHash[:])
+ return db.Get(epochKey(k))
+}
+
+// TODO use sqlite if leveldb doesn't work
+func FindEpochBeforeOrEqualNumber(db ethdb.KeyValueStore, n uint64) (blockNum uint64, blockHash common.Hash, transitionProof []byte, err error) {
+ // seek := make([]byte, 8)
+ // if n > 1 {
+ // move to the previous block - but actually this
+ // could be way older than the previous block number.
+ // binary.BigEndian.PutUint64(seek, n-1)
+ // }
+
+ it := db.NewIterator(EpochPrefix, nil)
+ defer it.Release()
+
+ blockNum = 0
+ for it.Next() {
+ k := it.Key()
+ k = k[len(EpochPrefix):]
+ num := binary.BigEndian.Uint64(k)
+ if num > n {
+ break
+ }
+
+ blockNum = num
+ transitionProof = it.Value()
+ blockHash = common.BytesToHash(k[8:])
+ }
+
+ return
+}
+
+func WriteEpoch(db ethdb.KeyValueWriter, blockNum uint64, blockHash common.Hash, transitionProof []byte) (err error) {
+ k := make([]byte, 40)
+ binary.BigEndian.PutUint64(k, blockNum)
+ copy(k[8:], blockHash[:])
+ return db.Put(epochKey(k), transitionProof)
+}
+
+func ReadPendingEpoch(db ethdb.KeyValueReader, blockNum uint64, blockHash common.Hash) (transitionProof []byte, err error) {
+ k := make([]byte, 8+32)
+ binary.BigEndian.PutUint64(k, blockNum)
+ copy(k[8:], blockHash[:])
+ return db.Get(pendingEpochKey(k))
+}
+
+func WritePendingEpoch(db ethdb.KeyValueWriter, blockNum uint64, blockHash common.Hash, transitionProof []byte) (err error) {
+ k := make([]byte, 8+32)
+ binary.BigEndian.PutUint64(k, blockNum)
+ copy(k[8:], blockHash[:])
+ return db.Put(pendingEpochKey(k), transitionProof)
+}
diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go
index 11cf5b40fef6..26117d33c2b1 100644
--- a/core/rawdb/schema.go
+++ b/core/rawdb/schema.go
@@ -121,6 +121,9 @@ var (
configPrefix = []byte("ethereum-config-") // config prefix for the db
genesisPrefix = []byte("ethereum-genesis-") // genesis state prefix for the db
+ EpochPrefix = []byte("aura-epoch-")
+ PendingEpochPrefix = []byte("aura-pending-epoch-")
+
// BloomBitsIndexPrefix is the data table of a chain indexer to track its progress
BloomBitsIndexPrefix = []byte("iB")
@@ -339,3 +342,11 @@ func IsStorageTrieNode(key []byte) bool {
ok, _, _ := ResolveStorageTrieNode(key)
return ok
}
+
+func epochKey(key []byte) []byte {
+ return append(EpochPrefix, key...)
+}
+
+func pendingEpochKey(key []byte) []byte {
+ return append(PendingEpochPrefix, key...)
+}
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 3804c6603b59..f58b834650f1 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -831,7 +831,7 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) {
// Thus, we can safely ignore it here
continue
}
- if obj.selfDestructed || (deleteEmptyObjects && obj.empty()) {
+ if obj.selfDestructed || (deleteEmptyObjects && obj.empty() && obj.address != params.SystemAddress) {
obj.deleted = true
// We need to maintain account deletions explicitly (will remain
@@ -1167,7 +1167,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
return common.Hash{}, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr)
}
// Finalize any pending changes and merge everything into the tries
- s.IntermediateRoot(deleteEmptyObjects)
+ s.IntermediateRoot(false)
// Commit objects to the trie, measuring the elapsed time
var (
diff --git a/core/state_processor.go b/core/state_processor.go
index 9a4333f72330..efb3d65e692b 100644
--- a/core/state_processor.go
+++ b/core/state_processor.go
@@ -19,10 +19,13 @@ package core
import (
"errors"
"fmt"
+ "math"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
+ "github.com/ethereum/go-ethereum/consensus/aura"
+ "github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
@@ -67,6 +70,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
allLogs []*types.Log
gp = new(GasPool).AddGas(block.GasLimit())
)
+
// Mutate the block and state according to any hard-fork specs
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
misc.ApplyDAOHardFork(statedb)
@@ -76,6 +80,35 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg)
signer = types.MakeSigner(p.config, header.Number, header.Time)
)
+ b, ok := p.engine.(*beacon.Beacon)
+ if ok {
+ b.SetAuraSyscall(func(contractaddr common.Address, data []byte) ([]byte, error) {
+ sysaddr := common.HexToAddress("fffffffffffffffffffffffffffffffffffffffe")
+ msg := &Message{
+ To: &contractaddr,
+ From: sysaddr,
+ Nonce: 0,
+ Value: big.NewInt(0),
+ GasLimit: math.MaxUint64,
+ GasPrice: big.NewInt(0),
+ GasFeeCap: nil,
+ GasTipCap: nil,
+ Data: data,
+ AccessList: nil,
+ BlobHashes: nil,
+ SkipAccountChecks: false,
+ }
+ txctx := NewEVMTxContext(msg)
+ evm := vm.NewEVM(context, txctx, statedb, p.bc.chainConfig, vm.Config{ /*Debug: true, Tracer: logger.NewJSONLogger(nil, os.Stdout)*/ })
+ ret, _, err := evm.Call(vm.AccountRef(sysaddr), contractaddr, data, math.MaxUint64, new(big.Int))
+ if err != nil {
+ panic(err)
+ }
+ statedb.Finalise(true)
+ return ret, err
+ })
+ }
+ b.AuraPrepare(p.bc, block.Header(), statedb)
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
}
@@ -86,7 +119,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
}
statedb.SetTxContext(tx.Hash(), i)
- receipt, err := applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv)
+ receipt, err := applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, p.engine)
if err != nil {
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
}
@@ -99,12 +132,33 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
return nil, nil, 0, errors.New("withdrawals before shanghai")
}
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
- p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), withdrawals)
+ p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), withdrawals, receipts)
return receipts, allLogs, *usedGas, nil
}
-func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
+func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, engine consensus.Engine) (*types.Receipt, error) {
+ if config.IsLondon(blockNumber) {
+ switch engine := engine.(type) {
+ case *beacon.Beacon:
+ if a, ok := engine.InnerEngine().(*aura.AuRa); ok && msg.GasFeeCap.BitLen() == 0 {
+ if a.IsServiceTransaction(msg.From) {
+ msg.SetFree()
+ }
+ }
+ case *aura.AuRa:
+ if msg.GasFeeCap.BitLen() == 0 {
+ if engine.IsServiceTransaction(msg.From) {
+ msg.SetFree()
+ }
+ }
+ }
+ if a, ok := engine.(*aura.AuRa); engine != nil && msg.GasFeeCap.BitLen() == 0 && ok {
+ if a.IsServiceTransaction(msg.From) {
+ msg.SetFree()
+ }
+ }
+ }
// Create a new context to be used in the EVM environment.
txContext := NewEVMTxContext(msg)
evm.Reset(txContext, statedb)
@@ -167,7 +221,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
blockContext := NewEVMBlockContext(header, bc, author)
txContext := NewEVMTxContext(msg)
vmenv := vm.NewEVM(blockContext, txContext, statedb, config, cfg)
- return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
+ return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv, nil)
}
// ProcessBeaconBlockRoot applies the EIP-4788 system call to the beacon block root
diff --git a/core/state_transition.go b/core/state_transition.go
index df2faa19a935..c9ecb23d4d0c 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -144,6 +144,16 @@ type Message struct {
// account nonce in state. It also disables checking that the sender is an EOA.
// This field will be set to true for operations like RPC eth_call.
SkipAccountChecks bool
+
+ isFree bool
+}
+
+func (msg *Message) SetFree() {
+ msg.isFree = true
+}
+
+func (msg *Message) IsFree() bool {
+ return msg.isFree
}
// TransactionToMessage converts a transaction into a Message.
@@ -307,7 +317,7 @@ func (st *StateTransition) preCheck() error {
}
// This will panic if baseFee is nil, but basefee presence is verified
// as part of header validation.
- if msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
+ if msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 && !msg.IsFree() {
return fmt.Errorf("%w: address %v, maxFeePerGas: %s, baseFee: %s", ErrFeeCapTooLow,
msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee)
}
@@ -434,18 +444,24 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
gasRefund = st.refundGas(params.RefundQuotientEIP3529)
}
effectiveTip := msg.GasPrice
- if rules.IsLondon {
+ if rules.IsLondon && !msg.IsFree() {
effectiveTip = cmath.BigMin(msg.GasTipCap, new(big.Int).Sub(msg.GasFeeCap, st.evm.Context.BaseFee))
}
+ fee := new(big.Int).SetUint64(st.gasUsed())
+ fee.Mul(fee, effectiveTip)
+ st.state.AddBalance(st.evm.Context.Coinbase, fee)
+
if st.evm.Config.NoBaseFee && msg.GasFeeCap.Sign() == 0 && msg.GasTipCap.Sign() == 0 {
// Skip fee payment when NoBaseFee is set and the fee fields
// are 0. This avoids a negative effectiveTip being applied to
// the coinbase when simulating calls.
} else {
- fee := new(big.Int).SetUint64(st.gasUsed())
- fee.Mul(fee, effectiveTip)
- st.state.AddBalance(st.evm.Context.Coinbase, fee)
+ if rules.IsLondon && !msg.IsFree() {
+ burntContractAddress := *st.evm.ChainConfig().Aura.Eip1559FeeCollector
+ burnAmount := new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.evm.Context.BaseFee)
+ st.state.AddBalance(burntContractAddress, burnAmount)
+ }
}
return &ExecutionResult{
diff --git a/core/types/block.go b/core/types/block.go
index 1a357baa3a41..eaff2c36f5cb 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -78,6 +78,8 @@ type Header struct {
Extra []byte `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash"`
Nonce BlockNonce `json:"nonce"`
+ Step uint64 `json:"step,omitempty"`
+ Signature []byte `json:"signature"`
// BaseFee was added by EIP-1559 and is ignored in legacy headers.
BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"`
diff --git a/core/types/gen_header_rlp.go b/core/types/gen_header_rlp.go
index ed6a1a002cdb..0324cdc72974 100644
--- a/core/types/gen_header_rlp.go
+++ b/core/types/gen_header_rlp.go
@@ -2,8 +2,14 @@
package types
-import "github.com/ethereum/go-ethereum/rlp"
-import "io"
+import (
+ "io"
+ "fmt"
+ "errors"
+
+ "github.com/ethereum/go-ethereum/rlp"
+ "github.com/ethereum/go-ethereum/common"
+)
func (obj *Header) EncodeRLP(_w io.Writer) error {
w := rlp.NewEncoderBuffer(_w)
@@ -35,8 +41,13 @@ func (obj *Header) EncodeRLP(_w io.Writer) error {
w.WriteUint64(obj.GasUsed)
w.WriteUint64(obj.Time)
w.WriteBytes(obj.Extra)
- w.WriteBytes(obj.MixDigest[:])
- w.WriteBytes(obj.Nonce[:])
+ if len(obj.Signature) == 0 {
+ w.WriteBytes(obj.MixDigest[:])
+ w.WriteBytes(obj.Nonce[:])
+ } else {
+ w.WriteUint64(obj.Step)
+ w.WriteBytes(obj.Signature)
+ }
_tmp1 := obj.BaseFee != nil
_tmp2 := obj.WithdrawalsHash != nil
_tmp3 := obj.BlobGasUsed != nil
@@ -83,3 +94,181 @@ func (obj *Header) EncodeRLP(_w io.Writer) error {
w.ListEnd(_tmp0)
return w.Flush()
}
+
+
+func (h *Header) DecodeRLP(s *rlp.Stream) error {
+ _, err := s.List()
+ if err != nil {
+ return err
+ }
+ var b []byte
+ if b, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read ParentHash: %w", err)
+ }
+ if len(b) != 32 {
+ return fmt.Errorf("wrong size for ParentHash: %d", len(b))
+ }
+ copy(h.ParentHash[:], b)
+ if b, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read UncleHash: %w", err)
+ }
+ if len(b) != 32 {
+ return fmt.Errorf("wrong size for UncleHash: %d", len(b))
+ }
+ copy(h.UncleHash[:], b)
+ if b, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read Coinbase: %w", err)
+ }
+ if len(b) != 20 {
+ return fmt.Errorf("wrong size for Coinbase: %d", len(b))
+ }
+ copy(h.Coinbase[:], b)
+ if b, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read Root: %w", err)
+ }
+ if len(b) != 32 {
+ return fmt.Errorf("wrong size for Root: %d", len(b))
+ }
+ copy(h.Root[:], b)
+ if b, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read TxHash: %w", err)
+ }
+ if len(b) != 32 {
+ return fmt.Errorf("wrong size for TxHash: %d", len(b))
+ }
+ copy(h.TxHash[:], b)
+ if b, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read ReceiptHash: %w", err)
+ }
+ if len(b) != 32 {
+ return fmt.Errorf("wrong size for ReceiptHash: %d", len(b))
+ }
+ copy(h.ReceiptHash[:], b)
+ if b, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read Bloom: %w", err)
+ }
+ if len(b) != 256 {
+ return fmt.Errorf("wrong size for Bloom: %d", len(b))
+ }
+ copy(h.Bloom[:], b)
+ if h.Difficulty, err = s.BigInt(); err != nil {
+ return fmt.Errorf("read Difficulty: %w", err)
+ }
+ if h.Number, err = s.BigInt(); err != nil {
+ return fmt.Errorf("read Number: %w", err)
+ }
+ if h.GasLimit, err = s.Uint(); err != nil {
+ return fmt.Errorf("read GasLimit: %w", err)
+ }
+ if h.GasUsed, err = s.Uint(); err != nil {
+ return fmt.Errorf("read GasUsed: %w", err)
+ }
+ if h.Time, err = s.Uint(); err != nil {
+ return fmt.Errorf("read Time: %w", err)
+ }
+ if h.Extra, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read Extra: %w", err)
+ }
+
+ _, size, err := s.Kind()
+ if err != nil {
+ return fmt.Errorf("read MixDigest: %w", err)
+ }
+ if size != 32 { // AuRa
+ if h.Step, err = s.Uint(); err != nil {
+ return fmt.Errorf("read AuRaStep: %w", err)
+ }
+ if h.Signature, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read AuRaSeal: %w", err)
+ }
+ } else {
+ if b, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read MixDigest: %w", err)
+ }
+ copy(h.MixDigest[:], b)
+ if b, err = s.Bytes(); err != nil {
+ return fmt.Errorf("read Nonce: %w", err)
+ }
+ if len(b) != 8 {
+ return fmt.Errorf("wrong size for Nonce: %d", len(b))
+ }
+ copy(h.Nonce[:], b)
+ }
+
+ // BaseFee
+ if h.BaseFee, err = s.BigInt(); err != nil {
+ if errors.Is(err, rlp.EOL) {
+ h.BaseFee = nil
+ if err := s.ListEnd(); err != nil {
+ return fmt.Errorf("close header struct (no BaseFee): %w", err)
+ }
+ return nil
+ }
+ return fmt.Errorf("read BaseFee: %w", err)
+ }
+
+ // WithdrawalsHash
+ if b, err = s.Bytes(); err != nil {
+ if errors.Is(err, rlp.EOL) {
+ h.WithdrawalsHash = nil
+ if err := s.ListEnd(); err != nil {
+ return fmt.Errorf("close header struct (no WithdrawalsHash): %w", err)
+ }
+ return nil
+ }
+ return fmt.Errorf("read WithdrawalsHash: %w", err)
+ }
+ if len(b) != 32 {
+ return fmt.Errorf("wrong size for WithdrawalsHash: %d", len(b))
+ }
+ h.WithdrawalsHash = new(common.Hash)
+ h.WithdrawalsHash.SetBytes(b)
+
+ var blobGasUsed uint64
+ if blobGasUsed, err = s.Uint(); err != nil {
+ if errors.Is(err, rlp.EOL) {
+ h.BlobGasUsed = nil
+ if err := s.ListEnd(); err != nil {
+ return fmt.Errorf("close header struct (no BlobGasUsed): %w", err)
+ }
+ return nil
+ }
+ return fmt.Errorf("read BlobGasUsed: %w", err)
+ }
+ h.BlobGasUsed = &blobGasUsed
+
+ var excessBlobGas uint64
+ if excessBlobGas, err = s.Uint(); err != nil {
+ if errors.Is(err, rlp.EOL) {
+ h.ExcessBlobGas = nil
+ if err := s.ListEnd(); err != nil {
+ return fmt.Errorf("close header struct (no ExcessBlobGas): %w", err)
+ }
+ return nil
+ }
+ return fmt.Errorf("read ExcessBlobGas: %w", err)
+ }
+ h.ExcessBlobGas = &excessBlobGas
+
+ // ParentBeaconBlockRoot
+ if b, err = s.Bytes(); err != nil {
+ if errors.Is(err, rlp.EOL) {
+ h.ParentBeaconRoot = nil
+ if err := s.ListEnd(); err != nil {
+ return fmt.Errorf("close header struct (no ParentBeaconBlockRoot): %w", err)
+ }
+ return nil
+ }
+ return fmt.Errorf("read ParentBeaconBlockRoot: %w", err)
+ }
+ if len(b) != 32 {
+ return fmt.Errorf("wrong size for ParentBeaconBlockRoot: %d", len(b))
+ }
+ h.ParentBeaconRoot= new(common.Hash)
+ h.ParentBeaconRoot.SetBytes(b)
+
+ if err := s.ListEnd(); err != nil {
+ return fmt.Errorf("close header struct: %w", err)
+ }
+ return nil
+}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 088b18aaa4ff..0e0e6d6728ea 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -467,7 +467,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
ret, err := evm.interpreter.Run(contract, nil, false)
// Check whether the max code size has been exceeded, assign err if the case.
- if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {
+ if err == nil && evm.chainRules.IsShanghai && len(ret) > params.MaxCodeSize {
err = ErrMaxCodeSizeExceeded
}
diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go
index ad664afb5bd1..0d330daae8bb 100644
--- a/eth/ethconfig/config.go
+++ b/eth/ethconfig/config.go
@@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
+ "github.com/ethereum/go-ethereum/consensus/aura"
"github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/consensus/ethash"
@@ -169,6 +170,13 @@ func CreateConsensusEngine(config *params.ChainConfig, db ethdb.Database) (conse
if config.Clique != nil {
return beacon.New(clique.New(config.Clique, db)), nil
}
+ if config.Aura != nil {
+ a, err := aura.NewAuRa(config.Aura, db)
+ if err != nil {
+ return nil, err
+ }
+ return beacon.New(a), nil
+ }
// If defaulting to proof-of-work, enforce an already merged network since
// we cannot run PoW algorithms anymore, so we cannot even follow a chain
// not coordinated by a beacon node.
diff --git a/eth/protocols/eth/handshake.go b/eth/protocols/eth/handshake.go
index ea16a85b1e1e..b3ee0e9838df 100644
--- a/eth/protocols/eth/handshake.go
+++ b/eth/protocols/eth/handshake.go
@@ -73,9 +73,10 @@ func (p *Peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis
// TD at mainnet block #7753254 is 76 bits. If it becomes 100 million times
// larger, it will still fit within 100 bits
- if tdlen := p.td.BitLen(); tdlen > 100 {
- return fmt.Errorf("too large total difficulty: bitlen %d", tdlen)
- }
+ // GNOSIS: total difficulty on the gnosis chain is way larger than 100 bits
+ // if tdlen := p.td.BitLen(); tdlen > 100 {
+ // return fmt.Errorf("too large total difficulty: bitlen %d", tdlen)
+ // }
return nil
}
diff --git a/go.mod b/go.mod
index 79bdc2551abe..5aaa357ccdc9 100644
--- a/go.mod
+++ b/go.mod
@@ -110,6 +110,8 @@ require (
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.4 // indirect
+ github.com/hashicorp/golang-lru v1.0.2 // indirect
+ github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kilic/bls12-381 v0.1.0 // indirect
diff --git a/go.sum b/go.sum
index b692629b6b6a..95ba5b240975 100644
--- a/go.sum
+++ b/go.sum
@@ -336,6 +336,10 @@ github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
+github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
+github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw=
github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc=
diff --git a/miner/worker.go b/miner/worker.go
index 2ed91cc18781..6e9df1a9116d 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
+ "github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core"
@@ -704,15 +705,7 @@ func (w *worker) resultLoop() {
}
// makeEnv creates a new environment for the sealing block.
-func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase common.Address) (*environment, error) {
- // Retrieve the parent state to execute on top and start a prefetcher for
- // the miner to speed block sealing up a bit.
- state, err := w.chain.StateAt(parent.Root)
- if err != nil {
- return nil, err
- }
- state.StartPrefetcher("miner")
-
+func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase common.Address, state *state.StateDB) (*environment, error) {
// Note the passed coinbase may be different with header.Coinbase.
env := &environment{
signer: types.MakeSigner(w.chainConfig, header.Number, header.Time),
@@ -960,15 +953,29 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
header.ExcessBlobGas = &excessBlobGas
header.ParentBeaconRoot = genParams.beaconRoot
}
+ // Retrieve the parent state to execute on top and start a prefetcher for
+ // the miner to speed block sealing up a bit.
+ state, err := w.chain.StateAt(parent.Root)
+ if err != nil {
+ return nil, err
+ }
+ state.StartPrefetcher("miner")
+
+ b, ok := w.engine.(*beacon.Beacon)
+ if ok {
+ b.SetAuraSyscall(func(contractaddr common.Address, data []byte) ([]byte, error) {
+ return nil, nil
+ })
+ }
// Run the consensus preparation with the default or customized consensus engine.
- if err := w.engine.Prepare(w.chain, header); err != nil {
+ if err := w.engine.Prepare(w.chain, header, state); err != nil {
log.Error("Failed to prepare header for sealing", "err", err)
return nil, err
}
// Could potentially happen if starting to mine in an odd state.
// Note genParams.coinbase can be different with header.Coinbase
// since clique algorithm can modify the coinbase field in header.
- env, err := w.makeEnv(parent, header, genParams.coinbase)
+ env, err := w.makeEnv(parent, header, genParams.coinbase, state)
if err != nil {
log.Error("Failed to create sealing context", "err", err)
return nil, err
diff --git a/params/bootnodes.go b/params/bootnodes.go
index 5e2c7c218102..57b13737bd0f 100644
--- a/params/bootnodes.go
+++ b/params/bootnodes.go
@@ -64,6 +64,22 @@ var GoerliBootnodes = []string{
"enode://d2b720352e8216c9efc470091aa91ddafc53e222b32780f505c817ceef69e01d5b0b0797b69db254c586f493872352f5a022b4d8479a00fc92ec55f9ad46a27e@88.99.70.182:30303",
}
+// GnosisBootnodes are the enode URLs of the P2P bootstrap nodes running on the
+// Gnosis chain network.
+var GnosisBootnodes = []string{
+ // TODO
+}
+
+// ChiadoBootnodes are the enode URLs of the P2P bootstrap nodes running on the
+// Chiado test network.
+var ChiadoBootnodes = []string{
+ "enode://7dd44af6138120f328bb031eb56e00985c149319d4f1e33275b30be7fddadd8ccd9f7b9c3b35a16136a61e85b2b2d1de073f30ec1d0ddf576a33be8ff48d88d0@139.144.26.89:30303",
+ "enode://317b9cee65ccf1d747b00e604242bfa3ae367beee8f149e28c5b2b88820f855ea7b5a75eb5327cfc3d8ca97adbf71538468290a46592ed7009f3fb394ec752f1@139.144.26.115:30303",
+ "enode://b77ae97906155ebbb83fd32c87ab0aa57372a24abbd8aa4bae679f048b726de4a195709f613be4981e44b24640bc89e4824427d94e9a37afc148da8250c8ab2d@139.144.26.101:30303",
+ "enode://69f8abfa3b0221161f8c19014b90857a18742554af27af73fd779c486728750a0ff11b873975f104fc5276a3a7c3b5b68cb3c26c815e9f78462901895d652124@139.144.26.85:30303",
+ "enode://ac7fc76f9b2ab343fb2d091365a7f46d17018e525cbedfbf24b247c76657e934ef4df61cc2f6dad6bfcf722425e03e1a8a6e4e4b52743acc2319cb8ebf27d742@170.187.154.239:30303",
+}
+
var V5Bootnodes = []string{
// Teku team's bootnode
"enr:-KG4QMOEswP62yzDjSwWS4YEjtTZ5PO6r65CPqYBkgTTkrpaedQ8uEUo1uMALtJIvb2w_WWEVmg5yt1UAuK1ftxUU7QDhGV0aDKQu6TalgMAAAD__________4JpZIJ2NIJpcIQEnfA2iXNlY3AyNTZrMaEDfol8oLr6XJ7FsdAYE7lpJhKMls4G_v6qQOGKJUWGb_uDdGNwgiMog3VkcIIjKA", // # 4.157.240.54 | azure-us-east-virginia
diff --git a/params/chainspecs/chiado.json b/params/chainspecs/chiado.json
new file mode 100644
index 000000000000..fac44bbd3f14
--- /dev/null
+++ b/params/chainspecs/chiado.json
@@ -0,0 +1,52 @@
+{
+ "ChainName": "chiado",
+ "chainId": 10200,
+ "consensus": "aura",
+ "homesteadBlock": 0,
+ "eip150Block": 0,
+ "eip155Block": 0,
+ "byzantiumBlock": 0,
+ "constantinopleBlock": 0,
+ "petersburgBlock": 0,
+ "istanbulBlock": 0,
+ "berlinBlock": 0,
+ "londonBlock": 0,
+ "eip1559FeeCollectorTransition": 0,
+ "eip1559FeeCollector": "0x1559000000000000000000000000000000000000",
+ "terminalTotalDifficulty": 231707791542740786049188744689299064356246512,
+ "terminalTotalDifficultyPassed": true,
+ "aura": {
+ "stepDuration": 5,
+ "blockReward": 0,
+ "maximumUncleCountTransition": 0,
+ "maximumUncleCount": 0,
+ "validators": {
+ "multi": {
+ "0": {
+ "list": ["0x14747a698Ec1227e6753026C08B29b4d5D3bC484"]
+ },
+ "67334": {
+ "list": [
+ "0x14747a698Ec1227e6753026C08B29b4d5D3bC484",
+ "0x56D421c0AC39976E89fa400d34ca6579417B84cA",
+ "0x5CD99ac2F0F8C25a1e670F6BaB19D52Aad69D875",
+ "0x60F1CF46B42Df059b98Acf67C1dD7771b100e124",
+ "0x655e97bA0f63A56c2b56EB3e84f7bf42b20Bae14",
+ "0x755B6259938D140626301c0B6026c1C00C9eD5d9",
+ "0xa8010da9Cb0AC018C86A06301963853CC371a18c"
+ ]
+ }
+ }
+ },
+ "blockRewardContractAddress": "0x2000000000000000000000000000000000000001",
+ "blockRewardContractTransition": 0,
+ "randomnessContractAddress": {
+ "0": "0x3000000000000000000000000000000000000001"
+ },
+ "posdaoTransition": 0,
+ "blockGasLimitContractTransitions": {
+ "0": "0x4000000000000000000000000000000000000001"
+ },
+ "registrar": "0x6000000000000000000000000000000000000000"
+ }
+}
diff --git a/params/chainspecs/gnosis.json b/params/chainspecs/gnosis.json
new file mode 100644
index 000000000000..44bd8e3cccca
--- /dev/null
+++ b/params/chainspecs/gnosis.json
@@ -0,0 +1,58 @@
+{
+ "ChainName": "gnosis",
+ "chainId": 100,
+ "consensus": "aura",
+ "homesteadBlock": 0,
+ "eip150Block": 0,
+ "eip155Block": 0,
+ "eip158Block": 0,
+ "byzantiumBlock": 0,
+ "constantinopleBlock": 1604400,
+ "petersburgBlock": 2508800,
+ "istanbulBlock": 7298030,
+ "berlinBlock": 16101500,
+ "londonBlock": 19040000,
+ "shanghaiTime": 1690889660,
+ "cancunTime": 1710181820,
+ "terminalTotalDifficulty": 8626000000000000000000058750000000000000000000,
+ "terminalTotalDifficultyPassed": true,
+ "aura": {
+ "stepDuration": 5,
+ "blockReward": 0,
+ "maximumUncleCountTransition": 0,
+ "maximumUncleCount": 0,
+ "validators": {
+ "multi": {
+ "0": {
+ "list": [
+ "0xcace5b3c29211740e595850e80478416ee77ca21"
+ ]
+ },
+ "1300": {
+ "safeContract": "0x22e1229a2c5b95a60983b5577f745a603284f535"
+ },
+ "9186425": {
+ "contract": "0xB87BE9f7196F2AE084Ca1DE6af5264292976e013"
+ }
+ }
+ },
+ "blockRewardContractAddress": "0x867305d19606aadba405ce534e303d0e225f9556",
+ "blockRewardContractTransition": 1310,
+ "blockRewardContractTransitions": {
+ "9186425": "0x481c034c6d9441db23ea48de68bcae812c5d39ba"
+ },
+ "randomnessContractAddress": {
+ "9186425": "0x5870b0527DeDB1cFBD9534343Feda1a41Ce47766"
+ },
+ "posdaoTransition": 9186425,
+ "registrar": "0x6B53721D4f2Fb9514B85f5C49b197D857e36Cf03",
+ "rewriteBytecode": {
+ "21735000": {
+ "0xf8D1677c8a0c961938bf2f9aDc3F3CFDA759A9d9": "0x6080604052600436106101b35763ffffffff60e060020a60003504166305d2035b81146101b857806306fdde03146101e1578063095ea7b31461026b5780630b26cf661461028f57806318160ddd146102b257806323b872dd146102d957806330adf81f14610303578063313ce567146103185780633644e5151461034357806339509351146103585780634000aea01461037c57806340c10f19146103ad57806342966c68146103d157806354fd4d50146103e957806366188463146103fe57806369ffa08a1461042257806370a0823114610449578063715018a61461046a578063726600ce1461047f5780637d64bcb4146104a05780637ecebe00146104b5578063859ba28c146104d65780638da5cb5b146105175780638fcbaf0c1461054857806395d89b4114610586578063a457c2d71461059b578063a9059cbb146105bf578063b753a98c146105e3578063bb35783b14610607578063c6a1dedf14610631578063cd59658314610646578063d505accf1461065b578063d73dd62314610694578063dd62ed3e146106b8578063f2d5d56b146106df578063f2fde38b14610703578063ff9e884d14610724575b600080fd5b3480156101c457600080fd5b506101cd61074b565b604080519115158252519081900360200190f35b3480156101ed57600080fd5b506101f661076c565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610230578181015183820152602001610218565b50505050905090810190601f16801561025d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027757600080fd5b506101cd600160a060020a03600435166024356107fa565b34801561029b57600080fd5b506102b0600160a060020a0360043516610810565b005b3480156102be57600080fd5b506102c761086a565b60408051918252519081900360200190f35b3480156102e557600080fd5b506101cd600160a060020a0360043581169060243516604435610870565b34801561030f57600080fd5b506102c7610a38565b34801561032457600080fd5b5061032d610a5c565b6040805160ff9092168252519081900360200190f35b34801561034f57600080fd5b506102c7610a65565b34801561036457600080fd5b506101cd600160a060020a0360043516602435610a6b565b34801561038857600080fd5b506101cd60048035600160a060020a0316906024803591604435918201910135610aac565b3480156103b957600080fd5b506101cd600160a060020a0360043516602435610bbd565b3480156103dd57600080fd5b506102b0600435610cc8565b3480156103f557600080fd5b506101f6610cd5565b34801561040a57600080fd5b506101cd600160a060020a0360043516602435610d0c565b34801561042e57600080fd5b506102b0600160a060020a0360043581169060243516610de9565b34801561045557600080fd5b506102c7600160a060020a0360043516610e0e565b34801561047657600080fd5b506102b0610e29565b34801561048b57600080fd5b506101cd600160a060020a0360043516610e40565b3480156104ac57600080fd5b506101cd610e54565b3480156104c157600080fd5b506102c7600160a060020a0360043516610e5b565b3480156104e257600080fd5b506104eb610e6d565b6040805167ffffffffffffffff9485168152928416602084015292168183015290519081900360600190f35b34801561052357600080fd5b5061052c610e78565b60408051600160a060020a039092168252519081900360200190f35b34801561055457600080fd5b506102b0600160a060020a0360043581169060243516604435606435608435151560ff60a4351660c43560e435610e87565b34801561059257600080fd5b506101f6610fc5565b3480156105a757600080fd5b506101cd600160a060020a036004351660243561101f565b3480156105cb57600080fd5b506101cd600160a060020a0360043516602435611032565b3480156105ef57600080fd5b506102b0600160a060020a0360043516602435611054565b34801561061357600080fd5b506102b0600160a060020a0360043581169060243516604435611064565b34801561063d57600080fd5b506102c7611075565b34801561065257600080fd5b5061052c611099565b34801561066757600080fd5b506102b0600160a060020a036004358116906024351660443560643560ff6084351660a43560c4356110a8565b3480156106a057600080fd5b506101cd600160a060020a0360043516602435611184565b3480156106c457600080fd5b506102c7600160a060020a036004358116906024351661120b565b3480156106eb57600080fd5b506102b0600160a060020a0360043516602435611236565b34801561070f57600080fd5b506102b0600160a060020a0360043516611241565b34801561073057600080fd5b506102c7600160a060020a0360043581169060243516611261565b60065474010000000000000000000000000000000000000000900460ff1681565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107f25780601f106107c7576101008083540402835291602001916107f2565b820191906000526020600020905b8154815290600101906020018083116107d557829003601f168201915b505050505081565b600061080733848461127e565b50600192915050565b600654600160a060020a0316331461082757600080fd5b610830816112c0565b151561083b57600080fd5b6007805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60045490565b600080600160a060020a038516151561088857600080fd5b600160a060020a038416151561089d57600080fd5b600160a060020a0385166000908152600360205260409020546108c6908463ffffffff6112c816565b600160a060020a0380871660009081526003602052604080822093909355908616815220546108fb908463ffffffff6112da16565b600160a060020a038086166000818152600360209081526040918290209490945580518781529051919392891692600080516020611d7283398151915292918290030190a3600160a060020a0385163314610a225761095a853361120b565b905060001981146109c457610975818463ffffffff6112c816565b600160a060020a038616600081815260056020908152604080832033808552908352928190208590558051948552519193600080516020611d92833981519152929081900390910190a3610a22565b600160a060020a0385166000908152600a602090815260408083203384529091529020541580610a175750600160a060020a0385166000908152600a602090815260408083203384529091529020544211155b1515610a2257600080fd5b610a2d8585856112ed565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025460ff1681565b60085481565b336000818152600560209081526040808320600160a060020a03871684529091528120549091610807918590610aa7908663ffffffff6112da16565b61127e565b600084600160a060020a03811615801590610ad05750600160a060020a0381163014155b1515610adb57600080fd5b610ae58686611324565b1515610af057600080fd5b85600160a060020a031633600160a060020a03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16878787604051808481526020018060200182810382528484828181526020019250808284376040519201829003965090945050505050a3610b65866112c0565b15610bb157610ba633878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750611330945050505050565b1515610bb157600080fd5b50600195945050505050565b600654600090600160a060020a03163314610bd757600080fd5b60065474010000000000000000000000000000000000000000900460ff1615610bff57600080fd5b600454610c12908363ffffffff6112da16565b600455600160a060020a038316600090815260036020526040902054610c3e908363ffffffff6112da16565b600160a060020a038416600081815260036020908152604091829020939093558051858152905191927f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688592918290030190a2604080518381529051600160a060020a03851691600091600080516020611d728339815191529181900360200190a350600192915050565b610cd233826114ad565b50565b60408051808201909152600181527f3100000000000000000000000000000000000000000000000000000000000000602082015281565b336000908152600560209081526040808320600160a060020a0386168452909152812054808310610d6057336000908152600560209081526040808320600160a060020a0388168452909152812055610d95565b610d70818463ffffffff6112c816565b336000908152600560209081526040808320600160a060020a03891684529091529020555b336000818152600560209081526040808320600160a060020a038916808552908352928190205481519081529051929392600080516020611d92833981519152929181900390910190a35060019392505050565b600654600160a060020a03163314610e0057600080fd5b610e0a828261159c565b5050565b600160a060020a031660009081526003602052604090205490565b600654600160a060020a031633146101b357600080fd5b600754600160a060020a0390811691161490565b6000806000fd5b60096020526000908152604090205481565b600260056000909192565b600654600160a060020a031681565b600080861580610e975750864211155b1515610ea257600080fd5b604080517fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb6020820152600160a060020a03808d16828401528b166060820152608081018a905260a0810189905287151560c0808301919091528251808303909101815260e0909101909152610f17906115da565b9150610f25828686866116e1565b600160a060020a038b8116911614610f3c57600080fd5b600160a060020a038a1660009081526009602052604090208054600181019091558814610f6857600080fd5b85610f74576000610f78565b6000195b905085610f86576000610f88565b865b600160a060020a03808c166000908152600a60209081526040808320938e1683529290522055610fb98a8a836118e3565b50505050505050505050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107f25780601f106107c7576101008083540402835291602001916107f2565b600061102b8383610d0c565b9392505050565b600061103e8383611324565b151561104957600080fd5b6108073384846112ed565b61105f338383610870565b505050565b61106f838383610870565b50505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb81565b600754600160a060020a031690565b600080428610156110b857600080fd5b600160a060020a03808a1660008181526009602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c99281019290925281830193909352928b166060840152608083018a905260a0830182905260c08084018a90528151808503909101815260e090930190529250611149906115da565b9050611157818686866116e1565b600160a060020a038a811691161461116e57600080fd5b61117989898961127e565b505050505050505050565b336000908152600560209081526040808320600160a060020a03861684529091528120546111b8908363ffffffff6112da16565b336000818152600560209081526040808320600160a060020a038916808552908352928190208590558051948552519193600080516020611d92833981519152929081900390910190a350600192915050565b600160a060020a03918216600090815260056020908152604080832093909416825291909152205490565b61105f823383610870565b600654600160a060020a0316331461125857600080fd5b610cd281611a3e565b600a60209081526000928352604080842090915290825290205481565b6112898383836118e3565b60001981141561105f57600160a060020a038084166000908152600a60209081526040808320938616835292905290812055505050565b6000903b1190565b6000828211156112d457fe5b50900390565b818101828110156112e757fe5b92915050565b6112f682610e40565b1561105f5760408051600081526020810190915261131990849084908490611330565b151561105f57600080fd5b600061102b8383611abc565b600083600160a060020a031663a4c0ed3660e060020a028685856040516024018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156113a8578181015183820152602001611390565b50505050905090810190601f1680156113d55780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909916989098178852518151919790965086955093509150819050838360005b8381101561146357818101518382015260200161144b565b50505050905090810190601f1680156114905780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1979650505050505050565b600160a060020a0382166000908152600360205260409020548111156114d257600080fd5b600160a060020a0382166000908152600360205260409020546114fb908263ffffffff6112c816565b600160a060020a038316600090815260036020526040902055600454611527908263ffffffff6112c816565b600455604080518281529051600160a060020a038416917fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5919081900360200190a2604080518281529051600091600160a060020a03851691600080516020611d728339815191529181900360200190a35050565b80600160a060020a03811615156115b257600080fd5b600160a060020a03831615156115d0576115cb82611b8b565b61105f565b61105f8383611b97565b6000600854826040518082805190602001908083835b6020831061160f5780518252601f1990920191602091820191016115f0565b51815160209384036101000a6000190180199092169116179052604080519290940182900382207f190100000000000000000000000000000000000000000000000000000000000083830152602283019790975260428083019790975283518083039097018752606290910192839052855192945084935085019190508083835b602083106116af5780518252601f199092019160209182019101611690565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b6000808460ff16601b14806116f957508460ff16601c145b1515611775576040805160e560020a62461bcd02815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611813576040805160e560020a62461bcd02815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60408051600080825260208083018085528a905260ff8916838501526060830188905260808301879052925160019360a0808501949193601f19840193928390039091019190865af115801561186d573d6000803e3d6000fd5b5050604051601f190151915050600160a060020a03811615156118da576040805160e560020a62461bcd02815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b95945050505050565b600160a060020a0383161515611968576040805160e560020a62461bcd028152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03821615156119ee576040805160e560020a62461bcd02815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0380841660008181526005602090815260408083209487168084529482529182902085905581518581529151600080516020611d928339815191529281900390910190a3505050565b600160a060020a0381161515611a5357600080fd5b600654604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b33600090815260036020526040812054821115611ad857600080fd5b600160a060020a0383161515611aed57600080fd5b33600090815260036020526040902054611b0d908363ffffffff6112c816565b3360009081526003602052604080822092909255600160a060020a03851681522054611b3f908363ffffffff6112da16565b600160a060020a038416600081815260036020908152604091829020939093558051858152905191923392600080516020611d728339815191529281900390910190a350600192915050565b3031610e0a8282611c44565b604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290518391600091600160a060020a038416916370a0823191602480830192602092919082900301818787803b158015611bfc57600080fd5b505af1158015611c10573d6000803e3d6000fd5b505050506040513d6020811015611c2657600080fd5b5051905061106f600160a060020a038516848363ffffffff611cac16565b604051600160a060020a0383169082156108fc029083906000818181858888f193505050501515610e0a578082611c79611d41565b600160a060020a039091168152604051908190036020019082f080158015611ca5573d6000803e3d6000fd5b5050505050565b82600160a060020a031663a9059cbb83836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b158015611d0f57600080fd5b505af1158015611d23573d6000803e3d6000fd5b505050503d1561105f5760206000803e600051151561105f57600080fd5b604051602180611d51833901905600608060405260405160208060218339810160405251600160a060020a038116ff00ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a165627a7a72305820b96bb0733a3e45fdddafa592f51114d0cf16cad047ad60b9b91ae91eb772c6940029"
+ }
+ },
+ "eip1559FeeCollectorTransition": 19040000,
+ "eip1559FeeCollector": "0x6BBe78ee9e474842Dbd4AB4987b3CeFE88426A92",
+ "withdrawalContractAddress" : "0x0B98057eA310F4d31F2a452B414647007d1645d9"
+ }
+}
diff --git a/params/config.go b/params/config.go
index 9b4c1338e451..b56b37cf9530 100644
--- a/params/config.go
+++ b/params/config.go
@@ -34,7 +34,8 @@ var (
func newUint64(val uint64) *uint64 { return &val }
var (
- MainnetTerminalTotalDifficulty, _ = new(big.Int).SetString("58_750_000_000_000_000_000_000", 0)
+ MainnetTerminalTotalDifficulty, _ = new(big.Int).SetString("58_750_000_000_000_000_000_000", 0)
+ GnosisChainTerminalTotalDifficulty, _ = new(big.Int).SetString("8_626_000_110_427_540_000_000_000_000_000_000_000_000_000_000", 0)
// MainnetChainConfig is the chain parameters to run a node on the main network.
MainnetChainConfig = &ChainConfig{
@@ -363,6 +364,7 @@ type ChainConfig struct {
// Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty"`
Clique *CliqueConfig `json:"clique,omitempty"`
+ Aura *AuRaConfig `json:"aura,omitempty"`
}
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
@@ -411,6 +413,12 @@ func (c *ChainConfig) Description() string {
} else {
banner += "Consensus: Beacon (proof-of-stake), merged from Clique (proof-of-authority)\n"
}
+ case c.Aura != nil:
+ if c.TerminalTotalDifficulty == nil {
+ banner += "Consensus: Aura (proof-of-authority)\n"
+ } else {
+ banner += "Consensus: Beacon (proof-of-stake), merged from Aura (proof-of-authority)\n"
+ }
default:
banner += "Consensus: unknown\n"
}
diff --git a/params/config_aura.go b/params/config_aura.go
new file mode 100644
index 000000000000..cff5d2a021a1
--- /dev/null
+++ b/params/config_aura.go
@@ -0,0 +1,75 @@
+package params
+
+import (
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+)
+
+// Different ways of specifying validators.
+type ValidatorSetJson struct {
+ // A simple list of authorities.
+ List []common.Address `json:"list"`
+ // Address of a contract that indicates the list of authorities.
+ SafeContract *common.Address `json:"safeContract"`
+ // Address of a contract that indicates the list of authorities and enables reporting of their misbehaviour using transactions.
+ Contract *common.Address `json:"contract"`
+ // A map of starting blocks for each validator set.
+ Multi map[uint64]*ValidatorSetJson `json:"multi"`
+}
+
+// AuRaConfig is the consensus engine configs for proof-of-authority based sealing.
+type AuRaConfig struct {
+ StepDuration *uint64 `json:"stepDuration"` // Block duration, in seconds.
+ Validators *ValidatorSetJson `json:"validators"` // Valid authorities
+
+ // Starting step. Determined automatically if not specified.
+ // To be used for testing only.
+ StartStep *uint64 `json:"startStep"`
+ ValidateScoreTransition *uint64 `json:"validateScoreTransition"` // Block at which score validation should start.
+ ValidateStepTransition *uint64 `json:"validateStepTransition"` // Block from which monotonic steps start.
+ ImmediateTransitions *bool `json:"immediateTransitions"` // Whether transitions should be immediate.
+ BlockReward *uint64 `json:"blockReward"` // Reward per block in wei.
+ // Block at which the block reward contract should start being used. This option allows one to
+ // add a single block reward contract transition and is compatible with the multiple address
+ // option `block_reward_contract_transitions` below.
+ BlockRewardContractTransition *uint64 `json:"blockRewardContractTransition"`
+ /// Block reward contract address which overrides the `block_reward` setting. This option allows
+ /// one to add a single block reward contract address and is compatible with the multiple
+ /// address option `block_reward_contract_transitions` below.
+ BlockRewardContractAddress *common.Address `json:"blockRewardContractAddress"`
+ // Block reward contract addresses with their associated starting block numbers.
+ //
+ // Setting the block reward contract overrides `block_reward`. If the single block reward
+ // contract address is also present then it is added into the map at the block number stored in
+ // `block_reward_contract_transition` or 0 if that block number is not provided. Therefore both
+ // a single block reward contract transition and a map of reward contract transitions can be
+ // used simultaneously in the same configuration. In such a case the code requires that the
+ // block number of the single transition is strictly less than any of the block numbers in the
+ // map.
+ BlockRewardContractTransitions map[uint]common.Address `json:"blockRewardContractTransitions"`
+ // Block at which maximum uncle count should be considered.
+ MaximumUncleCountTransition *uint64 `json:"maximumUncleCountTransition"`
+ // Maximum number of accepted uncles.
+ MaximumUncleCount *uint `json:"maximumUncleCount"`
+ // Strict validation of empty steps transition block.
+ StrictEmptyStepsTransition *uint `json:"strictEmptyStepsTransition"`
+ // The random number contract's address, or a map of contract transitions.
+ RandomnessContractAddress map[uint64]common.Address `json:"randomnessContractAddress"`
+ // The addresses of contracts that determine the block gas limit starting from the block number
+ // associated with each of those contracts.
+ BlockGasLimitContractTransitions map[uint64]common.Address `json:"blockGasLimitContractTransitions"`
+ // The block number at which the consensus engine switches from AuRa to AuRa with POSDAO
+ // modifications.
+ PosdaoTransition *uint64 `json:"PosdaoTransition"`
+ // Stores human-readable keys associated with addresses, like DNS information.
+ // This contract is primarily required to store the address of the Certifier contract.
+ Registrar *common.Address `json:"registrar"`
+
+ // See https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md
+ WithdrawalContractAddress *common.Address `json:"withdrawalContractAddress"`
+
+ RewriteBytecode map[uint64]map[common.Address]hexutil.Bytes `json:"rewriteBytecode"`
+
+ // Burn contract address
+ Eip1559FeeCollector *common.Address `json:"eip1559FeeCollector"`
+}
diff --git a/params/gnosis_config.go b/params/gnosis_config.go
new file mode 100644
index 000000000000..66000afd1599
--- /dev/null
+++ b/params/gnosis_config.go
@@ -0,0 +1,37 @@
+package params
+
+import (
+ "embed"
+ "encoding/json"
+ "fmt"
+
+ "github.com/ethereum/go-ethereum/common"
+)
+
+//go:embed chainspecs
+var chainspecs embed.FS
+
+func readChainSpec(filename string) *ChainConfig {
+ f, err := chainspecs.Open(filename)
+ if err != nil {
+ panic(fmt.Sprintf("Could not open chainspec for %s: %v", filename, err))
+ }
+ defer f.Close()
+ decoder := json.NewDecoder(f)
+ spec := &ChainConfig{}
+ err = decoder.Decode(&spec)
+ if err != nil {
+ panic(fmt.Sprintf("Could not parse chainspec for %s: %v", filename, err))
+ }
+ return spec
+}
+
+var (
+ GnosisGenesisHash = common.HexToHash("0x4f1dd23188aab3a76b463e4af801b52b1248ef073c648cbdc4c9333d3da79756")
+ ChiadoGenesisHash = common.HexToHash("0xada44fd8d2ecab8b08f256af07ad3e777f17fb434f8f8e678b312f576212ba9a")
+
+ GnosisChainConfig = readChainSpec("chainspecs/gnosis.json")
+ ChiadoChainConfig = readChainSpec("chainspecs/chiado.json")
+
+ GnosisForkBlock = uint64(25349536)
+)
From fe8df87c5bdbfc2d951dc97f9a8d49c8b0fac3cd Mon Sep 17 00:00:00 2001
From: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Date: Wed, 29 May 2024 18:08:21 +0200
Subject: [PATCH 2/8] add constructor
---
core/gen_genesis_account.go | 26 +++++++++------
core/genesis.go | 65 ++++++++++++++++++++++++++++++-------
core/genesis_test.go | 14 ++++++++
core/vm/evm.go | 21 ++++++++----
params/gnosis_config.go | 3 ++
5 files changed, 100 insertions(+), 29 deletions(-)
diff --git a/core/gen_genesis_account.go b/core/gen_genesis_account.go
index a9d47e6ba355..7604eebb222a 100644
--- a/core/gen_genesis_account.go
+++ b/core/gen_genesis_account.go
@@ -17,13 +17,15 @@ var _ = (*genesisAccountMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (g GenesisAccount) MarshalJSON() ([]byte, error) {
type GenesisAccount struct {
- Code hexutil.Bytes `json:"code,omitempty"`
- Storage map[storageJSON]storageJSON `json:"storage,omitempty"`
- Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"`
- Nonce math.HexOrDecimal64 `json:"nonce,omitempty"`
- PrivateKey hexutil.Bytes `json:"secretKey,omitempty"`
+ Constructor hexutil.Bytes `json:"constructor,omitempty"`
+ Code hexutil.Bytes `json:"code,omitempty"`
+ Storage map[storageJSON]storageJSON `json:"storage,omitempty"`
+ Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"`
+ Nonce math.HexOrDecimal64 `json:"nonce,omitempty"`
+ PrivateKey hexutil.Bytes `json:"secretKey,omitempty"`
}
var enc GenesisAccount
+ enc.Constructor = g.Constructor
enc.Code = g.Code
if g.Storage != nil {
enc.Storage = make(map[storageJSON]storageJSON, len(g.Storage))
@@ -40,16 +42,20 @@ func (g GenesisAccount) MarshalJSON() ([]byte, error) {
// UnmarshalJSON unmarshals from JSON.
func (g *GenesisAccount) UnmarshalJSON(input []byte) error {
type GenesisAccount struct {
- Code *hexutil.Bytes `json:"code,omitempty"`
- Storage map[storageJSON]storageJSON `json:"storage,omitempty"`
- Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"`
- Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"`
- PrivateKey *hexutil.Bytes `json:"secretKey,omitempty"`
+ Constructor *hexutil.Bytes `json:"constructor,omitempty"`
+ Code *hexutil.Bytes `json:"code,omitempty"`
+ Storage map[storageJSON]storageJSON `json:"storage,omitempty"`
+ Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"`
+ Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"`
+ PrivateKey *hexutil.Bytes `json:"secretKey,omitempty"`
}
var dec GenesisAccount
if err := json.Unmarshal(input, &dec); err != nil {
return err
}
+ if dec.Constructor != nil {
+ g.Constructor = *dec.Constructor
+ }
if dec.Code != nil {
g.Code = *dec.Code
}
diff --git a/core/genesis.go b/core/genesis.go
index dba416992a3a..f94493c3a265 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -32,6 +32,7 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
@@ -123,6 +124,35 @@ func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
return nil
}
+// SysCreate is a special (system) contract creation methods for genesis constructors.
+func SysCreate(contract common.Address, data []byte, chainConfig *params.ChainConfig, statedb *state.StateDB, header *types.Header) (result []byte, err error) {
+ msg := &Message{
+ From: contract,
+ Nonce: 0,
+ Value: big.NewInt(0),
+ GasLimit: math.MaxUint64,
+ GasPrice: big.NewInt(0),
+ // GasFeeCap, GasTipCap,
+ Data: data,
+ isFree: true,
+ }
+ vmConfig := vm.Config{}
+ // Create a new context to be used in the EVM environment
+ author := &contract
+ txContext := NewEVMTxContext(msg)
+ blockContext := NewEVMBlockContext(header, nil, author)
+ evm := vm.NewEVM(blockContext, txContext, statedb, chainConfig, vmConfig)
+
+ ret, _, err := evm.SysCreate(
+ vm.AccountRef(msg.From),
+ msg.Data,
+ msg.GasLimit,
+ msg.Value,
+ contract,
+ )
+ return ret, err
+}
+
// hash computes the state root according to the genesis specification.
func (ga *GenesisAlloc) hash(isVerkle bool) (common.Hash, error) {
// If a genesis-time verkle trie is requested, create a trie config
@@ -146,7 +176,11 @@ func (ga *GenesisAlloc) hash(isVerkle bool) (common.Hash, error) {
if account.Balance != nil {
statedb.AddBalance(addr, account.Balance)
}
- statedb.SetCode(addr, account.Code)
+ if len(account.Constructor) != 0 {
+ SysCreate(addr, account.Constructor, nil, statedb, nil)
+ } else {
+ statedb.SetCode(addr, account.Code)
+ }
statedb.SetNonce(addr, account.Nonce)
for key, value := range account.Storage {
statedb.SetState(addr, key, value)
@@ -167,7 +201,12 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhas
if account.Balance != nil {
statedb.AddBalance(addr, account.Balance)
}
- statedb.SetCode(addr, account.Code)
+ log.Info("adding account", "addr", addr, "constructor", account.Constructor, "code", account.Code)
+ if len(account.Constructor) != 0 {
+ SysCreate(addr, account.Constructor, nil, statedb, nil)
+ } else {
+ statedb.SetCode(addr, account.Code)
+ }
statedb.SetNonce(addr, account.Nonce)
for key, value := range account.Storage {
statedb.SetState(addr, key, value)
@@ -194,11 +233,12 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhas
// GenesisAccount is an account in the state of the genesis block.
type GenesisAccount struct {
- Code []byte `json:"code,omitempty"`
- Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
- Balance *big.Int `json:"balance" gencodec:"required"`
- Nonce uint64 `json:"nonce,omitempty"`
- PrivateKey []byte `json:"secretKey,omitempty"` // for tests
+ Constructor []byte `json:"constructor,omitempty"` // deployment code
+ Code []byte `json:"code,omitempty"`
+ Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
+ Balance *big.Int `json:"balance" gencodec:"required"`
+ Nonce uint64 `json:"nonce,omitempty"`
+ PrivateKey []byte `json:"secretKey,omitempty"` // for tests
}
// field type overrides for gencodec
@@ -217,11 +257,12 @@ type genesisSpecMarshaling struct {
}
type genesisAccountMarshaling struct {
- Code hexutil.Bytes
- Balance *math.HexOrDecimal256
- Nonce math.HexOrDecimal64
- Storage map[storageJSON]storageJSON
- PrivateKey hexutil.Bytes
+ Constructor hexutil.Bytes
+ Code hexutil.Bytes
+ Balance *math.HexOrDecimal256
+ Nonce math.HexOrDecimal64
+ Storage map[storageJSON]storageJSON
+ PrivateKey hexutil.Bytes
}
// storageJSON represents a 256 bit byte array, but allows less than 256 bits when
diff --git a/core/genesis_test.go b/core/genesis_test.go
index 1d85b510caa1..953af99d9194 100644
--- a/core/genesis_test.go
+++ b/core/genesis_test.go
@@ -325,3 +325,17 @@ func TestVerkleGenesisCommit(t *testing.T) {
t.Fatal("could not find node")
}
}
+
+func TestGnosisGenesisBlocks(t *testing.T) {
+ if DefaultGnosisGenesisBlock().ToBlock().Hash() != params.GnosisGenesisHash {
+ t.Fatalf("invalid gnosis chain genesis block. got %x, want %x", DefaultChiadoGenesisBlock().ToBlock().Hash(), params.GnosisGenesisHash)
+ }
+
+ chiadoGenesis := DefaultChiadoGenesisBlock().ToBlock()
+ if chiadoGenesis.Root() != params.ChiadoGenesisStateRoot {
+ t.Fatalf("invalid chiado state root, got %x, want %x", chiadoGenesis.Root(), params.ChiadoGenesisStateRoot)
+ }
+ if chiadoGenesis.Hash() != params.ChiadoGenesisHash {
+ t.Fatalf("invalid chiado genesis block, got %x, want %x", chiadoGenesis.Hash(), params.ChiadoGenesisHash)
+ }
+}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 0e0e6d6728ea..9d35207c16b6 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -419,7 +419,7 @@ func (c *codeAndHash) Hash() common.Hash {
}
// create creates a new contract using code as deployment code.
-func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address, typ OpCode) ([]byte, common.Address, uint64, error) {
+func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address, typ OpCode, incrementSenderNonce bool) ([]byte, common.Address, uint64, error) {
// Depth check execution. Fail if we're trying to execute above the
// limit.
if evm.depth > int(params.CallCreateDepth) {
@@ -428,11 +428,13 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
return nil, common.Address{}, gas, ErrInsufficientBalance
}
- nonce := evm.StateDB.GetNonce(caller.Address())
- if nonce+1 < nonce {
- return nil, common.Address{}, gas, ErrNonceUintOverflow
+ if incrementSenderNonce {
+ nonce := evm.StateDB.GetNonce(caller.Address())
+ if nonce+1 < nonce {
+ return nil, common.Address{}, gas, ErrNonceUintOverflow
+ }
+ evm.StateDB.SetNonce(caller.Address(), nonce+1)
}
- evm.StateDB.SetNonce(caller.Address(), nonce+1)
// We add this to the access list _before_ taking a snapshot. Even if the creation fails,
// the access-list change should not be rolled back
if evm.chainRules.IsBerlin {
@@ -512,7 +514,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// Create creates a new contract using code as deployment code.
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
- return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE)
+ return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE, false)
}
// Create2 creates a new contract using code as deployment code.
@@ -522,8 +524,13 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
codeAndHash := &codeAndHash{code: code}
contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes())
- return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2)
+ return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2, true)
}
// ChainConfig returns the environment's chain configuration
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
+
+func (evm *EVM) SysCreate(caller ContractRef, code []byte, gas uint64, endowment *big.Int, contractAddr common.Address) (ret []byte, leftOverGas uint64, err error) {
+ ret, _, leftOverGas, err = evm.create(caller, &codeAndHash{code: code}, gas, endowment, contractAddr, CREATE, false /* incrementNonce */)
+ return
+}
diff --git a/params/gnosis_config.go b/params/gnosis_config.go
index 66000afd1599..05fe780f3489 100644
--- a/params/gnosis_config.go
+++ b/params/gnosis_config.go
@@ -30,6 +30,9 @@ var (
GnosisGenesisHash = common.HexToHash("0x4f1dd23188aab3a76b463e4af801b52b1248ef073c648cbdc4c9333d3da79756")
ChiadoGenesisHash = common.HexToHash("0xada44fd8d2ecab8b08f256af07ad3e777f17fb434f8f8e678b312f576212ba9a")
+ GnosisGenesisStateRoot = common.HexToHash("0x40cf4430ecaa733787d1a65154a3b9efb560c95d9e324a23b97f0609b539133b")
+ ChiadoGenesisStateRoot = common.HexToHash("0x9ec3eaf4e6188dfbdd6ade76eaa88289b57c63c9a2cde8d35291d5a29e143d31")
+
GnosisChainConfig = readChainSpec("chainspecs/gnosis.json")
ChiadoChainConfig = readChainSpec("chainspecs/chiado.json")
From 183fbc94ec9f9b533571fd03a956af4c0c40dfc5 Mon Sep 17 00:00:00 2001
From: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Date: Wed, 5 Jun 2024 16:21:24 +0200
Subject: [PATCH 3/8] add empty header to fix first panic
---
core/genesis.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/genesis.go b/core/genesis.go
index f94493c3a265..deae9d9fcf29 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -177,7 +177,7 @@ func (ga *GenesisAlloc) hash(isVerkle bool) (common.Hash, error) {
statedb.AddBalance(addr, account.Balance)
}
if len(account.Constructor) != 0 {
- SysCreate(addr, account.Constructor, nil, statedb, nil)
+ SysCreate(addr, account.Constructor, nil, statedb, &types.Header{})
} else {
statedb.SetCode(addr, account.Code)
}
From 224fe3f79b358ad639152244e9c4c9a6b46f2ec6 Mon Sep 17 00:00:00 2001
From: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Date: Wed, 5 Jun 2024 22:01:33 +0200
Subject: [PATCH 4/8] store the created output
---
core/genesis.go | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/core/genesis.go b/core/genesis.go
index deae9d9fcf29..50cb44e2f6e4 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -177,7 +177,13 @@ func (ga *GenesisAlloc) hash(isVerkle bool) (common.Hash, error) {
statedb.AddBalance(addr, account.Balance)
}
if len(account.Constructor) != 0 {
- SysCreate(addr, account.Constructor, nil, statedb, &types.Header{})
+ // hardcode chiado since this is the only use case we have for the time being.
+ // things could be cleaner, but it would increase the diff with geth.
+ code, err := SysCreate(addr, account.Constructor, params.ChiadoChainConfig, statedb, &types.Header{Difficulty: big.NewInt(131072), Number: big.NewInt(0)})
+ if err != nil {
+ panic(err)
+ }
+ statedb.SetCode(addr, code)
} else {
statedb.SetCode(addr, account.Code)
}
From 38d6ac857ec78a36faf6bd2f4c08272b1959e8a1 Mon Sep 17 00:00:00 2001
From: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Date: Wed, 26 Jun 2024 13:33:32 +0200
Subject: [PATCH 5/8] chiado genesis block
---
core/allocs/chiado.json | 3 +++
params/config.go | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/core/allocs/chiado.json b/core/allocs/chiado.json
index a332c3a8b6d4..46fdd1c1fead 100644
--- a/core/allocs/chiado.json
+++ b/core/allocs/chiado.json
@@ -1,4 +1,7 @@
{
+ "0x0000000000000000000000000000000000000000": {
+ "balance": "0x0"
+ },
"0x0000000000000000000000000000000000000001": {
"balance": "0x1"
},
diff --git a/params/config.go b/params/config.go
index b56b37cf9530..5a48bbbbd063 100644
--- a/params/config.go
+++ b/params/config.go
@@ -624,7 +624,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
{name: "daoForkBlock", block: c.DAOForkBlock, optional: true},
{name: "eip150Block", block: c.EIP150Block},
{name: "eip155Block", block: c.EIP155Block},
- {name: "eip158Block", block: c.EIP158Block},
+ // {name: "eip158Block", block: c.EIP158Block},
{name: "byzantiumBlock", block: c.ByzantiumBlock},
{name: "constantinopleBlock", block: c.ConstantinopleBlock},
{name: "petersburgBlock", block: c.PetersburgBlock},
From a31945e1223677a1e390928ef61d0d06f0d66c4b Mon Sep 17 00:00:00 2001
From: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Date: Wed, 26 Jun 2024 13:34:38 +0200
Subject: [PATCH 6/8] add gnosis chain bootnodes
---
params/bootnodes.go | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/params/bootnodes.go b/params/bootnodes.go
index 57b13737bd0f..3d084e7d1e01 100644
--- a/params/bootnodes.go
+++ b/params/bootnodes.go
@@ -67,7 +67,14 @@ var GoerliBootnodes = []string{
// GnosisBootnodes are the enode URLs of the P2P bootstrap nodes running on the
// Gnosis chain network.
var GnosisBootnodes = []string{
- // TODO
+ "enode://fb14d72321ee823fcf21e163091849ee42e0f6ac0cddc737d79e324b0a734c4fc51823ef0a96b749c954483c25e8d2e534d1d5fc2619ea22d58671aff96f5188@65.109.103.148:30303",
+ "enode://40f40acd78004650cce57aa302de9acbf54becf91b609da93596a18979bb203ba79fcbee5c2e637407b91be23ce72f0cc13dfa38d13e657005ce842eafb6b172@65.109.103.149:30303",
+ "enode://9e50857aa48a7a31bc7b46957e8ced0ef69a7165d3199bea924cb6d02b81f1f35bd8e29d21a54f4a331316bf09bb92716772ea76d3ef75ce027699eccfa14fad@141.94.97.22:30303",
+ "enode://96dc133ce3aeb5d9430f1dce1d77a36418c8789b443ae0445f06f73c6b363f5b35c019086700a098c3e6e54974d64f37e97d72a5c711d1eae34dc06e3e00eed5@141.94.97.74:30303",
+ "enode://516cbfbe9bbf26b6395ed68b24e383401fc33e7fe96b9d235ebca86c9f812fde8d33a7dbebc0fb5595459d2c5cc6381595d96507af89e6b48b5bdd0ebf8af0c0@141.94.97.84:30303",
+ "enode://fc86a93545c56322dd861180b76632b9baeb65af8f304269b489b4623ae060847569c3c3c10c4b39baf221a2cdefea66efabce061a542cdcda374cbba45aa3d4@51.68.39.206:30303",
+ "enode://0e6dd3815a627893515465130c1e95aa73b18fe2f723b2467f3abf94df9be036f27595f301b5e78750ad128e59265f980c92033ae903330c0460c40ae088c04a@35.210.37.245:30303",
+ "enode://b72d6233d50bef7b31c09f3ea39459257520178f985a872bbaa4e371ed619455b7671053ffe985af1b5fb3270606e2a49e4e67084debd75e6c9b93e227c5b01c@35.210.156.59:30303",
}
// ChiadoBootnodes are the enode URLs of the P2P bootstrap nodes running on the
From 609e0fe55373bab44a1e37d595e585c39ce921af Mon Sep 17 00:00:00 2001
From: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Date: Wed, 26 Jun 2024 13:37:56 +0200
Subject: [PATCH 7/8] fix chiado genesis block
---
core/genesis.go | 37 ++++++++++++++++++++++++++++++++-----
1 file changed, 32 insertions(+), 5 deletions(-)
diff --git a/core/genesis.go b/core/genesis.go
index 50cb44e2f6e4..ac5c9c0af365 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -24,6 +24,7 @@ import (
"errors"
"fmt"
"math/big"
+ "slices"
"strings"
"github.com/ethereum/go-ethereum/common"
@@ -172,7 +173,16 @@ func (ga *GenesisAlloc) hash(isVerkle bool) (common.Hash, error) {
if err != nil {
return common.Hash{}, err
}
- for addr, account := range *ga {
+ keys := make([]string, len(*ga))
+ i := 0
+ for k := range *ga {
+ keys[i] = string(k.Bytes())
+ i++
+ }
+ slices.Sort(keys)
+ for _, key := range keys {
+ addr := common.BytesToAddress([]byte(key))
+ account := (*ga)[addr]
if account.Balance != nil {
statedb.AddBalance(addr, account.Balance)
}
@@ -184,10 +194,11 @@ func (ga *GenesisAlloc) hash(isVerkle bool) (common.Hash, error) {
panic(err)
}
statedb.SetCode(addr, code)
+ statedb.SetNonce(addr, 1)
} else {
statedb.SetCode(addr, account.Code)
+ statedb.SetNonce(addr, account.Nonce)
}
- statedb.SetNonce(addr, account.Nonce)
for key, value := range account.Storage {
statedb.SetState(addr, key, value)
}
@@ -203,17 +214,33 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhas
if err != nil {
return err
}
- for addr, account := range *ga {
+ keys := make([]string, len(*ga))
+ i := 0
+ for k := range *ga {
+ keys[i] = string(k.Bytes())
+ i++
+ }
+ slices.Sort(keys)
+ for _, key := range keys {
+ addr := common.BytesToAddress([]byte(key))
+ account := (*ga)[addr]
if account.Balance != nil {
statedb.AddBalance(addr, account.Balance)
}
log.Info("adding account", "addr", addr, "constructor", account.Constructor, "code", account.Code)
if len(account.Constructor) != 0 {
- SysCreate(addr, account.Constructor, nil, statedb, nil)
+ // hardcode chiado since this is the only use case we have for the time being.
+ // things could be cleaner, but it would increase the diff with geth.
+ code, err := SysCreate(addr, account.Constructor, params.ChiadoChainConfig, statedb, &types.Header{Difficulty: big.NewInt(131072), Number: big.NewInt(0)})
+ if err != nil {
+ panic(err)
+ }
+ statedb.SetCode(addr, code)
+ statedb.SetNonce(addr, 1)
} else {
statedb.SetCode(addr, account.Code)
+ statedb.SetNonce(addr, account.Nonce)
}
- statedb.SetNonce(addr, account.Nonce)
for key, value := range account.Storage {
statedb.SetState(addr, key, value)
}
From 13872962d89dad3f974cf1c698de69d3aac01768 Mon Sep 17 00:00:00 2001
From: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Date: Wed, 28 Aug 2024 07:25:41 +0200
Subject: [PATCH 8/8] fix chiado sync + start block production
---
consensus/aura/gaslimit_override.go | 16 +++++++--------
consensus/beacon/consensus.go | 6 +++++-
core/vm/evm.go | 6 ++++--
core/vm/gas_table.go | 2 +-
miner/worker.go | 32 ++++++++++++++++++++++++++++-
params/chainspecs/chiado.json | 16 ++++++++++++---
params/protocol_params.go | 20 ++++++++++--------
7 files changed, 73 insertions(+), 25 deletions(-)
diff --git a/consensus/aura/gaslimit_override.go b/consensus/aura/gaslimit_override.go
index c8f13604f6c1..81748a42fc57 100644
--- a/consensus/aura/gaslimit_override.go
+++ b/consensus/aura/gaslimit_override.go
@@ -58,14 +58,14 @@ func (c *AuRa) GetBlockGasLimitFromContract(_ *params.ChainConfig) uint64 {
func (c *AuRa) verifyGasLimitOverride(config *params.ChainConfig, chain consensus.ChainHeaderReader, header *types.Header, statedb *state.StateDB, syscallCustom Syscall) {
// TODO(gballet): take care of that when we reach the merge
//IsPoSHeader check is necessary as merge.go calls Initialize on AuRa indiscriminately
- // gasLimitOverride := c.HasGasLimitContract() && !misc.IsPoSHeader(header)
- // if gasLimitOverride {
- blockGasLimit := c.GetBlockGasLimitFromContract(config)
+ gasLimitOverride := c.HasGasLimitContract() && !c.isPos
+ if gasLimitOverride {
+ _ /*blockGasLimit */ = c.GetBlockGasLimitFromContract(config)
- if blockGasLimit > 0 {
- if header.GasLimit != blockGasLimit {
- panic("Block gas limit doesn't match BlockGasLimitContract with AuRa")
- }
+ // if blockGasLimit > 0 {
+ // if header.GasLimit != blockGasLimit {
+ // panic(fmt.Sprintf("Block gas limit doesn't match BlockGasLimitContract with AuRa: %d != %d at block %d, merged=%v", header.GasLimit, blockGasLimit, header.Number, c.isPos))
+ // }
+ // }
}
- // }
}
diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go
index 46fb194dc9b8..a45dae07b34c 100644
--- a/consensus/beacon/consensus.go
+++ b/consensus/beacon/consensus.go
@@ -447,7 +447,7 @@ func (beacon *Beacon) IsPoSHeader(header *types.Header) bool {
// return header.Number.Cmp(big.NewInt())
// non-uint64 block numbers are 2,92271023×10¹² years in
// the future, but better be ready.
- return !header.Number.IsInt64() || header.Number.Uint64() >= params.GnosisForkBlock
+ return !header.Number.IsInt64() || header.Number.Uint64() >= params.GnosisForkBlock || header.Difficulty.Cmp(common.Big0) == 0
}
// InnerEngine returns the embedded eth1 consensus engine.
@@ -487,5 +487,9 @@ func (beacon *Beacon) SetAuraSyscall(sc aura.Syscall) {
}
func (beacon *Beacon) AuraPrepare(chain consensus.ChainHeaderReader, header *types.Header, statedb *state.StateDB) {
+ // mark down if the current chain has merged
+ if a, ok := beacon.ethone.(*aura.AuRa); ok {
+ a.SetMerged(beacon.IsPoSHeader(header))
+ }
beacon.ethone.Prepare(chain, header, statedb)
}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 9d35207c16b6..6db725f3afaa 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -448,7 +448,9 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// Create a new account on the state
snapshot := evm.StateDB.Snapshot()
evm.StateDB.CreateAccount(address)
- if evm.chainRules.IsEIP158 {
+ // On gnosis chains, this is activated as part of SpuriousDragon in
+ // spite of being part of eip 161.
+ if evm.chainRules.IsEIP155 {
evm.StateDB.SetNonce(address, 1)
}
evm.Context.Transfer(evm.StateDB, caller.Address(), address, value)
@@ -514,7 +516,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// Create creates a new contract using code as deployment code.
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
- return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE, false)
+ return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE, true)
}
// Create2 creates a new contract using code as deployment code.
diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go
index 4b141d8f9a5d..eee1aa8ec889 100644
--- a/core/vm/gas_table.go
+++ b/core/vm/gas_table.go
@@ -369,7 +369,7 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize
transfersValue = !stack.Back(2).IsZero()
address = common.Address(stack.Back(1).Bytes20())
)
- if evm.chainRules.IsEIP158 {
+ if evm.chainRules.IsEIP155 {
if transfersValue && evm.StateDB.Empty(address) {
gas += params.CallNewAccountGas
}
diff --git a/miner/worker.go b/miner/worker.go
index 6e9df1a9116d..365069813915 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -19,6 +19,7 @@ package miner
import (
"errors"
"fmt"
+ "math"
"math/big"
"sync"
"sync/atomic"
@@ -963,8 +964,34 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
b, ok := w.engine.(*beacon.Beacon)
if ok {
+ if header.Difficulty == nil {
+ header.Difficulty = common.Big0
+ }
b.SetAuraSyscall(func(contractaddr common.Address, data []byte) ([]byte, error) {
- return nil, nil
+ sysaddr := common.HexToAddress("fffffffffffffffffffffffffffffffffffffffe")
+ msg := &core.Message{
+ To: &contractaddr,
+ From: sysaddr,
+ Nonce: 0,
+ Value: big.NewInt(0),
+ GasLimit: math.MaxUint64,
+ GasPrice: big.NewInt(0),
+ GasFeeCap: nil,
+ GasTipCap: nil,
+ Data: data,
+ AccessList: nil,
+ BlobHashes: nil,
+ SkipAccountChecks: false,
+ }
+ context := core.NewEVMBlockContext(header, w.chain, nil)
+ txctx := core.NewEVMTxContext(msg)
+ evm := vm.NewEVM(context, txctx, state, w.chainConfig, vm.Config{ /*Debug: true, Tracer: logger.NewJSONLogger(nil, os.Stdout)*/ })
+ ret, _, err := evm.Call(vm.AccountRef(sysaddr), contractaddr, data, math.MaxUint64, new(big.Int))
+ if err != nil {
+ panic(err)
+ }
+ state.Finalise(true)
+ return ret, err
})
}
// Run the consensus preparation with the default or customized consensus engine.
@@ -980,6 +1007,9 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
log.Error("Failed to create sealing context", "err", err)
return nil, err
}
+ if ok {
+ b.AuraPrepare(w.chain, header, state)
+ }
if header.ParentBeaconRoot != nil {
context := core.NewEVMBlockContext(header, w.chain, nil)
vmenv := vm.NewEVM(context, vm.TxContext{}, env.state, w.chainConfig, vm.Config{})
diff --git a/params/chainspecs/chiado.json b/params/chainspecs/chiado.json
index fac44bbd3f14..b530faf3f2d9 100644
--- a/params/chainspecs/chiado.json
+++ b/params/chainspecs/chiado.json
@@ -11,10 +11,17 @@
"istanbulBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
- "eip1559FeeCollectorTransition": 0,
- "eip1559FeeCollector": "0x1559000000000000000000000000000000000000",
"terminalTotalDifficulty": 231707791542740786049188744689299064356246512,
"terminalTotalDifficultyPassed": true,
+ "shanghaiTime": 1684934220,
+ "cancunTime": 1706724940,
+ "minBlobGasPrice": 1000000000,
+ "maxBlobGasPerBlock": 262144,
+ "targetBlobGasPerBlock": 131072,
+ "blobGasPriceUpdateFraction": 1112826,
+ "noPruneContracts": {
+ "0xb97036A26259B7147018913bD58a774cf91acf25": true
+ },
"aura": {
"stepDuration": 5,
"blockReward": 0,
@@ -47,6 +54,9 @@
"blockGasLimitContractTransitions": {
"0": "0x4000000000000000000000000000000000000001"
},
- "registrar": "0x6000000000000000000000000000000000000000"
+ "eip1559FeeCollectorTransition": 0,
+ "eip1559FeeCollector": "0x1559000000000000000000000000000000000000",
+ "registrar": "0x6000000000000000000000000000000000000000",
+ "withdrawalContractAddress": "0xb97036A26259B7147018913bD58a774cf91acf25"
}
}
diff --git a/params/protocol_params.go b/params/protocol_params.go
index 7eb63e89ac61..b44924e5b733 100644
--- a/params/protocol_params.go
+++ b/params/protocol_params.go
@@ -164,15 +164,17 @@ const (
RefundQuotient uint64 = 2
RefundQuotientEIP3529 uint64 = 5
- BlobTxBytesPerFieldElement = 32 // Size in bytes of a field element
- BlobTxFieldElementsPerBlob = 4096 // Number of field elements stored in a single data blob
- BlobTxBlobGasPerBlob = 1 << 17 // Gas consumption of a single data blob (== blob byte size)
- BlobTxMinBlobGasprice = 1 // Minimum gas price for data blobs
- BlobTxBlobGaspriceUpdateFraction = 3338477 // Controls the maximum rate of change for blob gas price
- BlobTxPointEvaluationPrecompileGas = 50000 // Gas price for the point evaluation precompile.
-
- BlobTxTargetBlobGasPerBlock = 3 * BlobTxBlobGasPerBlob // Target consumable blob gas for data blobs per block (for 1559-like pricing)
- MaxBlobGasPerBlock = 6 * BlobTxBlobGasPerBlob // Maximum consumable blob gas for data blobs per block
+ BlobTxBytesPerFieldElement = 32 // Size in bytes of a field element
+ BlobTxFieldElementsPerBlob = 4096 // Number of field elements stored in a single data blob
+ BlobTxBlobGasPerBlob = 1 << 17 // Gas consumption of a single data blob (== blob byte size)
+ BlobTxMinBlobGasprice = 1000000000 // Minimum gas price for data blobs
+ BlobTxBlobGaspriceUpdateFraction = 1112826 // Controls the maximum rate of change for blob gas price
+ BlobTxPointEvaluationPrecompileGas = 50000 // Gas price for the point evaluation precompile.
+
+ // BlobTxMinBlobGasprice = 1000000000 // Minimum gas price for data blobs
+
+ BlobTxTargetBlobGasPerBlock = 1 * BlobTxBlobGasPerBlob // Target consumable blob gas for data blobs per block (for 1559-like pricing)
+ MaxBlobGasPerBlock = 2 * BlobTxBlobGasPerBlob // Maximum consumable blob gas for data blobs per block
)
// Gas discount table for BLS12-381 G1 and G2 multi exponentiation operations