aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--Dockerfile41
-rwxr-xr-x_data/chain1bin0 -> 175331 bytes
-rwxr-xr-x_data/chain2bin0 -> 28118 bytes
-rw-r--r--block_pool.go347
-rw-r--r--chain/chain_manager_test.go116
-rw-r--r--chain/filter_test.go7
-rw-r--r--chain/state_transition.go291
-rw-r--r--chain/vm_env.go40
-rw-r--r--cmd/ethereum/cmd.go2
-rw-r--r--cmd/ethereum/flags.go6
-rw-r--r--cmd/ethereum/main.go11
-rw-r--r--cmd/ethereum/repl/repl.go2
-rw-r--r--cmd/ethtest/main.go2
-rw-r--r--cmd/evm/code.txt1
-rw-r--r--cmd/evm/input.txt1
-rw-r--r--cmd/evm/main.go97
-rw-r--r--cmd/mist/assets/qml/main.qml1
-rw-r--r--cmd/mist/assets/qml/views/miner.qml2
-rw-r--r--cmd/mist/assets/qml/views/wallet.qml35
-rw-r--r--cmd/mist/assets/qml/views/whisper.qml47
-rw-r--r--cmd/mist/bindings.go10
-rw-r--r--cmd/mist/debugger.go25
-rw-r--r--cmd/mist/ext_app.go14
-rw-r--r--cmd/mist/flags.go4
-rw-r--r--cmd/mist/gui.go127
-rw-r--r--cmd/mist/html_container.go3
-rw-r--r--cmd/mist/main.go18
-rw-r--r--cmd/mist/qml_container.go3
-rw-r--r--cmd/mist/ui_lib.go46
-rw-r--r--cmd/peerserver/main.go40
-rw-r--r--cmd/utils/cmd.go42
-rw-r--r--cmd/utils/vm_env.go40
-rw-r--r--cmd/utils/websockets.go2
-rw-r--r--core/.gitignore (renamed from chain/.gitignore)0
-rw-r--r--core/asm.go (renamed from chain/asm.go)2
-rw-r--r--core/block_manager.go (renamed from chain/block_manager.go)173
-rw-r--r--core/chain_manager.go (renamed from chain/chain_manager.go)272
-rw-r--r--core/chain_manager_test.go77
-rw-r--r--core/dagger.go (renamed from chain/dagger.go)83
-rw-r--r--core/dagger_test.go (renamed from chain/dagger_test.go)2
-rw-r--r--core/error.go (renamed from chain/error.go)15
-rw-r--r--core/events.go (renamed from chain/events.go)7
-rw-r--r--core/execution.go76
-rw-r--r--core/fees.go (renamed from chain/fees.go)2
-rw-r--r--core/filter.go (renamed from chain/filter.go)12
-rw-r--r--core/filter_test.go1
-rw-r--r--core/genesis.go (renamed from chain/genesis.go)4
-rw-r--r--core/helper_test.go (renamed from chain/helper_test.go)4
-rw-r--r--core/simple_pow.go1
-rw-r--r--core/state_transition.go232
-rw-r--r--core/transaction_pool.go (renamed from chain/transaction_pool.go)137
-rw-r--r--core/types/block.go (renamed from chain/types/block.go)47
-rw-r--r--core/types/bloom9.go (renamed from chain/types/bloom9.go)16
-rw-r--r--core/types/bloom9_test.go (renamed from chain/types/bloom9_test.go)0
-rw-r--r--core/types/common.go (renamed from chain/types/common.go)3
-rw-r--r--core/types/derive_sha.go (renamed from chain/types/derive_sha.go)0
-rw-r--r--core/types/receipt.go (renamed from chain/types/receipt.go)13
-rw-r--r--core/types/transaction.go (renamed from chain/types/transaction.go)115
-rw-r--r--core/types/transaction_test.go (renamed from chain/types/transaction_test.go)0
-rw-r--r--core/vm_env.go61
-rw-r--r--crypto/crypto.go70
-rw-r--r--crypto/curve.go363
-rw-r--r--crypto/encrypt_decrypt_test.go40
-rw-r--r--crypto/key_manager.go4
-rw-r--r--eth/backend.go249
-rw-r--r--eth/block_pool.go1015
-rw-r--r--eth/block_pool_test.go198
-rw-r--r--eth/error.go71
-rw-r--r--eth/peer_util.go23
-rw-r--r--eth/protocol.go319
-rw-r--r--eth/protocol_test.go232
-rw-r--r--ethereum.go661
-rw-r--r--ethutil/big.go10
-rw-r--r--ethutil/rlp.go34
-rw-r--r--ethutil/rlp_test.go10
-rw-r--r--ethutil/script_unix.go42
-rw-r--r--ethutil/script_windows.go23
-rw-r--r--ethutil/value.go2
-rw-r--r--event/filter/filter.go70
-rw-r--r--event/filter/filter_test.go34
-rw-r--r--event/filter/generic_filter.go32
-rw-r--r--event/filter/old_filter.go94
-rw-r--r--events.go11
-rwxr-xr-xinstall.sh41
-rw-r--r--javascript/javascript_runtime.go32
-rw-r--r--javascript/types.go2
-rw-r--r--miner/miner.go65
-rw-r--r--nat.go12
-rw-r--r--natpmp.go55
-rw-r--r--natupnp.go338
-rw-r--r--p2p/client_identity.go6
-rw-r--r--p2p/connection.go275
-rw-r--r--p2p/connection_test.go222
-rw-r--r--p2p/message.go279
-rw-r--r--p2p/message_test.go141
-rw-r--r--p2p/messenger.go220
-rw-r--r--p2p/messenger_test.go147
-rw-r--r--p2p/natpmp.go34
-rw-r--r--p2p/natupnp.go198
-rw-r--r--p2p/network.go196
-rw-r--r--p2p/peer.go501
-rw-r--r--p2p/peer_error.go161
-rw-r--r--p2p/peer_error_handler.go101
-rw-r--r--p2p/peer_error_handler_test.go34
-rw-r--r--p2p/peer_test.go339
-rw-r--r--p2p/protocol.go454
-rw-r--r--p2p/protocol_test.go58
-rw-r--r--p2p/server.go731
-rw-r--r--p2p/server_test.go309
-rw-r--r--p2p/testlog_test.go28
-rw-r--r--p2p/testpoc7.go40
-rw-r--r--peer.go892
-rw-r--r--pow/block.go9
-rw-r--r--pow/ezp/pow.go93
-rw-r--r--pow/pow.go8
-rw-r--r--rlp/decode.go248
-rw-r--r--rlp/decode_test.go129
-rw-r--r--rlp/typecache.go39
-rw-r--r--state/dump.go2
-rw-r--r--state/log.go61
-rw-r--r--state/state.go85
-rw-r--r--state/state_object.go13
-rw-r--r--state/state_test.go2
-rw-r--r--tests/files/BasicTests/genesishashestest.json4
-rw-r--r--tests/files/StateTests/stExample.json2
-rw-r--r--tests/files/StateTests/stInitCodeTest.json870
-rw-r--r--tests/files/StateTests/stLogTests.json3712
-rw-r--r--tests/files/StateTests/stPreCompiledContracts.json446
-rw-r--r--tests/files/StateTests/stRecursiveCreate.json7231
-rw-r--r--tests/files/StateTests/stRefundTest.json523
-rw-r--r--tests/files/StateTests/stSpecialTest.json77
-rw-r--r--tests/files/StateTests/stSystemOperationsTest.json3554
-rw-r--r--tests/files/StateTests/stTransactionTest.json277
-rw-r--r--tests/files/TrieTests/trieanyorder.json55
-rw-r--r--tests/files/TrieTests/trietest.json105
-rw-r--r--tests/files/VMTests/RandomTests/randomTest.json46
-rw-r--r--tests/files/VMTests/vmArithmeticTest.json454
-rw-r--r--tests/files/VMTests/vmBitwiseLogicOperationTest.json120
-rw-r--r--tests/files/VMTests/vmBlockInfoTest.json12
-rw-r--r--tests/files/VMTests/vmEnvironmentalInfoTest.json280
-rw-r--r--tests/files/VMTests/vmIOandFlowOperationsTest.json142
-rw-r--r--tests/files/VMTests/vmLogTest.json2190
-rw-r--r--tests/files/VMTests/vmPushDupSwapTest.json204
-rw-r--r--tests/files/VMTests/vmSha3Test.json60
-rw-r--r--tests/files/VMTests/vmtests.json8
-rw-r--r--tests/files/index.js10
-rw-r--r--tests/helper/vm.go114
-rw-r--r--tests/vm/gh_test.go369
-rw-r--r--ui/filter.go12
-rw-r--r--ui/qt/filter.go6
-rw-r--r--ui/qt/qwhisper/whisper.go98
-rw-r--r--ui/qt/qwhisper/whisper_test.go15
-rw-r--r--vm/address.go32
-rw-r--r--vm/analysis.go10
-rw-r--r--vm/closure.go77
-rw-r--r--vm/common.go11
-rw-r--r--vm/environment.go37
-rw-r--r--vm/execution.go95
-rw-r--r--vm/stack.go7
-rw-r--r--vm/types.go13
-rw-r--r--vm/virtual_machine.go5
-rw-r--r--vm/vm.go690
-rw-r--r--vm/vm_debug.go245
-rw-r--r--vm/vm_test.go180
-rw-r--r--whisper/doc.go16
-rw-r--r--whisper/envelope.go127
-rw-r--r--whisper/filter.go10
-rw-r--r--whisper/main.go37
-rw-r--r--whisper/message.go74
-rw-r--r--whisper/messages_test.go51
-rw-r--r--whisper/peer.go128
-rw-r--r--whisper/sort.go25
-rw-r--r--whisper/sort_test.go19
-rw-r--r--whisper/util.go36
-rw-r--r--whisper/whisper.go245
-rw-r--r--whisper/whisper_test.go47
-rw-r--r--wire/.gitignore12
-rw-r--r--wire/README.md36
-rw-r--r--wire/client_identity.go56
-rw-r--r--wire/client_identity_test.go30
-rw-r--r--wire/messages2.go199
-rw-r--r--wire/messaging.go179
-rw-r--r--xeth/hexface.go93
-rw-r--r--xeth/js_types.go87
-rw-r--r--xeth/pipe.go141
-rw-r--r--xeth/vm_env.go36
-rw-r--r--xeth/world.go9
188 files changed, 28378 insertions, 8702 deletions
diff --git a/.travis.yml b/.travis.yml
index ebb631969..d09cbcdb0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,9 +19,7 @@ before_script:
# - go vet ./...
# - go test -race ./...
script:
- - ./gocoverage.sh
-after_script:
- - goveralls -coverprofile=profile.cov -service=travis-ci -repotoken $COVERALLS_TOKEN
+ - ./gocoverage.sh && goveralls -coverprofile=profile.cov -service=travis-ci -repotoken $COVERALLS_TOKEN
env:
- secure: "U2U1AmkU4NJBgKR/uUAebQY87cNL0+1JHjnLOmmXwxYYyj5ralWb1aSuSH3qSXiT93qLBmtaUkuv9fberHVqrbAeVlztVdUsKAq7JMQH+M99iFkC9UiRMqHmtjWJ0ok4COD1sRYixxi21wb/JrMe3M1iL4QJVS61iltjHhVdM64="
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 000000000..1f37ce892
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,41 @@
+FROM ubuntu:14.04
+
+## Environment setup
+ENV HOME /root
+ENV GOPATH /root/go
+ENV PATH /go/bin:/root/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
+
+RUN mkdir -p /root/go
+ENV DEBIAN_FRONTEND noninteractive
+
+## Install base dependencies
+RUN apt-get update && apt-get upgrade -y
+RUN apt-get install -y git mercurial build-essential software-properties-common pkg-config libgmp3-dev libreadline6-dev libpcre3-dev libpcre++-dev
+
+## Build and install Go
+RUN hg clone -u release https://code.google.com/p/go
+RUN cd go && hg update go1.4
+RUN cd go/src && ./all.bash && go version
+
+## Install GUI dependencies
+RUN add-apt-repository ppa:ubuntu-sdk-team/ppa -y
+RUN apt-get update -y
+RUN apt-get install -y qtbase5-private-dev qtdeclarative5-private-dev libqt5opengl5-dev
+
+## Fetch and install serpent-go
+RUN go get -v -d github.com/ethereum/serpent-go
+WORKDIR $GOPATH/src/github.com/ethereum/serpent-go
+RUN git checkout master
+RUN git submodule update --init
+RUN go install -v
+
+# Fetch and install go-ethereum
+RUN go get -v -d github.com/ethereum/go-ethereum/...
+WORKDIR $GOPATH/src/github.com/ethereum/go-ethereum
+RUN git checkout poc8
+RUN ETH_DEPS=$(go list -f '{{.Imports}} {{.TestImports}} {{.XTestImports}}' github.com/ethereum/go-ethereum/... | sed -e 's/\[//g' | sed -e 's/\]//g' | sed -e 's/C //g'); if [ "$ETH_DEPS" ]; then go get $ETH_DEPS; fi
+RUN go install -v ./cmd/ethereum
+
+# Run JSON RPC
+ENTRYPOINT ["ethereum", "-rpc=true", "-rpcport=8080"]
+EXPOSE 8080
diff --git a/_data/chain1 b/_data/chain1
new file mode 100755
index 000000000..ef392e001
--- /dev/null
+++ b/_data/chain1
Binary files differ
diff --git a/_data/chain2 b/_data/chain2
new file mode 100755
index 000000000..48ed4d5ea
--- /dev/null
+++ b/_data/chain2
Binary files differ
diff --git a/block_pool.go b/block_pool.go
deleted file mode 100644
index 38302a4c7..000000000
--- a/block_pool.go
+++ /dev/null
@@ -1,347 +0,0 @@
-package eth
-
-import (
- "bytes"
- "container/list"
- "fmt"
- "math"
- "math/big"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/chain"
- "github.com/ethereum/go-ethereum/chain/types"
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/state"
- "github.com/ethereum/go-ethereum/wire"
-)
-
-var poollogger = logger.NewLogger("BPOOL")
-
-type block struct {
- from *Peer
- peer *Peer
- block *types.Block
- reqAt time.Time
- requested int
-}
-
-type BlockPool struct {
- mut sync.Mutex
-
- eth *Ethereum
-
- hashes [][]byte
- pool map[string]*block
-
- td *big.Int
- quit chan bool
-
- fetchingHashes bool
- downloadStartedAt time.Time
-
- ChainLength, BlocksProcessed int
-
- peer *Peer
-}
-
-func NewBlockPool(eth *Ethereum) *BlockPool {
- return &BlockPool{
- eth: eth,
- pool: make(map[string]*block),
- td: ethutil.Big0,
- quit: make(chan bool),
- }
-}
-
-func (self *BlockPool) Len() int {
- return len(self.hashes)
-}
-
-func (self *BlockPool) Reset() {
- self.pool = make(map[string]*block)
- self.hashes = nil
-}
-
-func (self *BlockPool) HasLatestHash() bool {
- self.mut.Lock()
- defer self.mut.Unlock()
-
- return self.pool[string(self.eth.ChainManager().CurrentBlock.Hash())] != nil
-}
-
-func (self *BlockPool) HasCommonHash(hash []byte) bool {
- return self.eth.ChainManager().GetBlock(hash) != nil
-}
-
-func (self *BlockPool) Blocks() (blocks types.Blocks) {
- for _, item := range self.pool {
- if item.block != nil {
- blocks = append(blocks, item.block)
- }
- }
-
- return
-}
-
-func (self *BlockPool) FetchHashes(peer *Peer) bool {
- highestTd := self.eth.HighestTDPeer()
-
- if (self.peer == nil && peer.td.Cmp(highestTd) >= 0) || (self.peer != nil && peer.td.Cmp(self.peer.td) > 0) || self.peer == peer {
- if self.peer != peer {
- poollogger.Debugf("Found better suitable peer (%v vs %v)\n", self.td, peer.td)
-
- if self.peer != nil {
- self.peer.doneFetchingHashes = true
- }
- }
-
- self.peer = peer
- self.td = peer.td
-
- if !self.HasLatestHash() {
- peer.doneFetchingHashes = false
-
- const amount = 256
- peerlogger.Debugf("Fetching hashes (%d) %x...\n", amount, peer.lastReceivedHash[0:4])
- peer.QueueMessage(wire.NewMessage(wire.MsgGetBlockHashesTy, []interface{}{peer.lastReceivedHash, uint32(amount)}))
- }
-
- return true
- }
-
- return false
-}
-
-func (self *BlockPool) AddHash(hash []byte, peer *Peer) {
- self.mut.Lock()
- defer self.mut.Unlock()
-
- if self.pool[string(hash)] == nil {
- self.pool[string(hash)] = &block{peer, nil, nil, time.Now(), 0}
-
- self.hashes = append([][]byte{hash}, self.hashes...)
- }
-}
-
-func (self *BlockPool) Add(b *types.Block, peer *Peer) {
- self.addBlock(b, peer, false)
-}
-
-func (self *BlockPool) AddNew(b *types.Block, peer *Peer) {
- self.addBlock(b, peer, true)
-}
-
-func (self *BlockPool) addBlock(b *types.Block, peer *Peer, newBlock bool) {
- self.mut.Lock()
- defer self.mut.Unlock()
-
- hash := string(b.Hash())
-
- if self.pool[hash] == nil && !self.eth.ChainManager().HasBlock(b.Hash()) {
- poollogger.Infof("Got unrequested block (%x...)\n", hash[0:4])
-
- self.hashes = append(self.hashes, b.Hash())
- self.pool[hash] = &block{peer, peer, b, time.Now(), 0}
-
- // The following is only performed on an unrequested new block
- if newBlock {
- fmt.Println("1.", !self.eth.ChainManager().HasBlock(b.PrevHash), ethutil.Bytes2Hex(b.Hash()[0:4]), ethutil.Bytes2Hex(b.PrevHash[0:4]))
- fmt.Println("2.", self.pool[string(b.PrevHash)] == nil)
- fmt.Println("3.", !self.fetchingHashes)
- if !self.eth.ChainManager().HasBlock(b.PrevHash) && self.pool[string(b.PrevHash)] == nil && !self.fetchingHashes {
- poollogger.Infof("Unknown chain, requesting (%x...)\n", b.PrevHash[0:4])
- peer.QueueMessage(wire.NewMessage(wire.MsgGetBlockHashesTy, []interface{}{b.Hash(), uint32(256)}))
- }
- }
- } else if self.pool[hash] != nil {
- self.pool[hash].block = b
- }
-
- self.BlocksProcessed++
-}
-
-func (self *BlockPool) Remove(hash []byte) {
- self.mut.Lock()
- defer self.mut.Unlock()
-
- self.hashes = ethutil.DeleteFromByteSlice(self.hashes, hash)
- delete(self.pool, string(hash))
-}
-
-func (self *BlockPool) DistributeHashes() {
- self.mut.Lock()
- defer self.mut.Unlock()
-
- var (
- peerLen = self.eth.peers.Len()
- amount = 256 * peerLen
- dist = make(map[*Peer][][]byte)
- )
-
- num := int(math.Min(float64(amount), float64(len(self.pool))))
- for i, j := 0, 0; i < len(self.hashes) && j < num; i++ {
- hash := self.hashes[i]
- item := self.pool[string(hash)]
-
- if item != nil && item.block == nil {
- var peer *Peer
- lastFetchFailed := time.Since(item.reqAt) > 5*time.Second
-
- // Handle failed requests
- if lastFetchFailed && item.requested > 5 && item.peer != nil {
- if item.requested < 100 {
- // Select peer the hash was retrieved off
- peer = item.from
- } else {
- // Remove it
- self.hashes = ethutil.DeleteFromByteSlice(self.hashes, hash)
- delete(self.pool, string(hash))
- }
- } else if lastFetchFailed || item.peer == nil {
- // Find a suitable, available peer
- eachPeer(self.eth.peers, func(p *Peer, v *list.Element) {
- if peer == nil && len(dist[p]) < amount/peerLen && p.statusKnown {
- peer = p
- }
- })
- }
-
- if peer != nil {
- item.reqAt = time.Now()
- item.peer = peer
- item.requested++
-
- dist[peer] = append(dist[peer], hash)
- }
- }
- }
-
- for peer, hashes := range dist {
- peer.FetchBlocks(hashes)
- }
-
- if len(dist) > 0 {
- self.downloadStartedAt = time.Now()
- }
-}
-
-func (self *BlockPool) Start() {
- go self.downloadThread()
- go self.chainThread()
-}
-
-func (self *BlockPool) Stop() {
- close(self.quit)
-}
-
-func (self *BlockPool) downloadThread() {
- serviceTimer := time.NewTicker(100 * time.Millisecond)
-out:
- for {
- select {
- case <-self.quit:
- break out
- case <-serviceTimer.C:
- // Check if we're catching up. If not distribute the hashes to
- // the peers and download the blockchain
- self.fetchingHashes = false
- eachPeer(self.eth.peers, func(p *Peer, v *list.Element) {
- if p.statusKnown && p.FetchingHashes() {
- self.fetchingHashes = true
- }
- })
-
- if len(self.hashes) > 0 {
- self.DistributeHashes()
- }
-
- if self.ChainLength < len(self.hashes) {
- self.ChainLength = len(self.hashes)
- }
-
- /*
- if !self.fetchingHashes {
- blocks := self.Blocks()
- chain.BlockBy(chain.Number).Sort(blocks)
-
- if len(blocks) > 0 {
- if !self.eth.ChainManager().HasBlock(b.PrevHash) && self.pool[string(b.PrevHash)] == nil && !self.fetchingHashes {
- }
- }
- }
- */
- }
- }
-}
-
-func (self *BlockPool) chainThread() {
- procTimer := time.NewTicker(500 * time.Millisecond)
-out:
- for {
- select {
- case <-self.quit:
- break out
- case <-procTimer.C:
- blocks := self.Blocks()
- types.BlockBy(types.Number).Sort(blocks)
-
- // Find common block
- for i, block := range blocks {
- if self.eth.ChainManager().HasBlock(block.PrevHash) {
- blocks = blocks[i:]
- break
- }
- }
-
- if len(blocks) > 0 {
- if self.eth.ChainManager().HasBlock(blocks[0].PrevHash) {
- for i, block := range blocks[1:] {
- // NOTE: The Ith element in this loop refers to the previous block in
- // outer "blocks"
- if bytes.Compare(block.PrevHash, blocks[i].Hash()) != 0 {
- blocks = blocks[:i]
-
- break
- }
- }
- } else {
- blocks = nil
- }
- }
-
- if len(blocks) > 0 {
- chainManager := self.eth.ChainManager()
- // Test and import
- bchain := chain.NewChain(blocks)
- _, err := chainManager.TestChain(bchain)
- if err != nil && !chain.IsTDError(err) {
- poollogger.Debugln(err)
-
- self.Reset()
-
- if self.peer != nil && self.peer.conn != nil {
- poollogger.Debugf("Punishing peer for supplying bad chain (%v)\n", self.peer.conn.RemoteAddr())
- }
-
- // This peer gave us bad hashes and made us fetch a bad chain, therefor he shall be punished.
- self.eth.BlacklistPeer(self.peer)
- self.peer.StopWithReason(DiscBadPeer)
- self.td = ethutil.Big0
- self.peer = nil
- } else {
- if !chain.IsTDError(err) {
- chainManager.InsertChain(bchain, func(block *types.Block, messages state.Messages) {
- self.eth.EventMux().Post(chain.NewBlockEvent{block})
- self.eth.EventMux().Post(messages)
-
- self.Remove(block.Hash())
- })
-
- }
- }
- }
- }
- }
-}
diff --git a/chain/chain_manager_test.go b/chain/chain_manager_test.go
deleted file mode 100644
index 0314914a9..000000000
--- a/chain/chain_manager_test.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package chain
-
-import (
- "fmt"
- "math/big"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/chain/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/state"
-)
-
-var TD *big.Int
-
-func init() {
- ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
- ethutil.Config.Db, _ = ethdb.NewMemDatabase()
-}
-
-type fakeproc struct {
-}
-
-func (self fakeproc) ProcessWithParent(a, b *types.Block) (*big.Int, state.Messages, error) {
- TD = new(big.Int).Add(TD, big.NewInt(1))
- return TD, nil, nil
-}
-
-func makechain(cman *ChainManager, max int) *BlockChain {
- blocks := make(types.Blocks, max)
- for i := 0; i < max; i++ {
- addr := ethutil.LeftPadBytes([]byte{byte(i)}, 20)
- block := cman.NewBlock(addr)
- if i != 0 {
- cman.CurrentBlock = blocks[i-1]
- }
- blocks[i] = block
- }
- return NewChain(blocks)
-}
-
-func TestLongerFork(t *testing.T) {
- cman := NewChainManager()
- cman.SetProcessor(fakeproc{})
-
- TD = big.NewInt(1)
- chainA := makechain(cman, 5)
-
- TD = big.NewInt(1)
- chainB := makechain(cman, 10)
-
- td, err := cman.TestChain(chainA)
- if err != nil {
- t.Error("unable to create new TD from chainA:", err)
- }
- cman.TD = td
-
- _, err = cman.TestChain(chainB)
- if err != nil {
- t.Error("expected chainB not to give errors:", err)
- }
-}
-
-func TestEqualFork(t *testing.T) {
- cman := NewChainManager()
- cman.SetProcessor(fakeproc{})
-
- TD = big.NewInt(1)
- chainA := makechain(cman, 5)
-
- TD = big.NewInt(2)
- chainB := makechain(cman, 5)
-
- td, err := cman.TestChain(chainA)
- if err != nil {
- t.Error("unable to create new TD from chainA:", err)
- }
- cman.TD = td
-
- _, err = cman.TestChain(chainB)
- if err != nil {
- t.Error("expected chainB not to give errors:", err)
- }
-}
-
-func TestBrokenChain(t *testing.T) {
- cman := NewChainManager()
- cman.SetProcessor(fakeproc{})
-
- TD = big.NewInt(1)
- chain := makechain(cman, 5)
- chain.Remove(chain.Front())
-
- _, err := cman.TestChain(chain)
- if err == nil {
- t.Error("expected broken chain to return error")
- }
-}
-
-func BenchmarkChainTesting(b *testing.B) {
- const chainlen = 1000
-
- ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
- ethutil.Config.Db, _ = ethdb.NewMemDatabase()
-
- cman := NewChainManager()
- cman.SetProcessor(fakeproc{})
-
- TD = big.NewInt(1)
- chain := makechain(cman, chainlen)
-
- stime := time.Now()
- cman.TestChain(chain)
- fmt.Println(chainlen, "took", time.Since(stime))
-}
diff --git a/chain/filter_test.go b/chain/filter_test.go
deleted file mode 100644
index c63bb5a2d..000000000
--- a/chain/filter_test.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package chain
-
-// import "testing"
-
-// func TestFilter(t *testing.T) {
-// NewFilter(NewTestManager())
-// }
diff --git a/chain/state_transition.go b/chain/state_transition.go
deleted file mode 100644
index 789698675..000000000
--- a/chain/state_transition.go
+++ /dev/null
@@ -1,291 +0,0 @@
-package chain
-
-import (
- "fmt"
- "math/big"
-
- "github.com/ethereum/go-ethereum/chain/types"
- "github.com/ethereum/go-ethereum/state"
- "github.com/ethereum/go-ethereum/vm"
-)
-
-/*
- * The State transitioning model
- *
- * A state transition is a change made when a transaction is applied to the current world state
- * The state transitioning model does all all the necessary work to work out a valid new state root.
- * 1) Nonce handling
- * 2) Pre pay / buy gas of the coinbase (miner)
- * 3) Create a new state object if the recipient is \0*32
- * 4) Value transfer
- * == If contract creation ==
- * 4a) Attempt to run transaction data
- * 4b) If valid, use result as code for the new state object
- * == end ==
- * 5) Run Script section
- * 6) Derive new state root
- */
-type StateTransition struct {
- coinbase, receiver []byte
- tx *types.Transaction
- gas, gasPrice *big.Int
- value *big.Int
- data []byte
- state *state.State
- block *types.Block
-
- cb, rec, sen *state.StateObject
-}
-
-func NewStateTransition(coinbase *state.StateObject, tx *types.Transaction, state *state.State, block *types.Block) *StateTransition {
- return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil}
-}
-
-func (self *StateTransition) Coinbase() *state.StateObject {
- if self.cb != nil {
- return self.cb
- }
-
- self.cb = self.state.GetOrNewStateObject(self.coinbase)
- return self.cb
-}
-func (self *StateTransition) Sender() *state.StateObject {
- if self.sen != nil {
- return self.sen
- }
-
- self.sen = self.state.GetOrNewStateObject(self.tx.Sender())
-
- return self.sen
-}
-func (self *StateTransition) Receiver() *state.StateObject {
- if self.tx != nil && self.tx.CreatesContract() {
- return nil
- }
-
- if self.rec != nil {
- return self.rec
- }
-
- self.rec = self.state.GetOrNewStateObject(self.tx.Recipient)
- return self.rec
-}
-
-func (self *StateTransition) UseGas(amount *big.Int) error {
- if self.gas.Cmp(amount) < 0 {
- return OutOfGasError()
- }
- self.gas.Sub(self.gas, amount)
-
- return nil
-}
-
-func (self *StateTransition) AddGas(amount *big.Int) {
- self.gas.Add(self.gas, amount)
-}
-
-func (self *StateTransition) BuyGas() error {
- var err error
-
- sender := self.Sender()
- if sender.Balance().Cmp(self.tx.GasValue()) < 0 {
- return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Balance())
- }
-
- coinbase := self.Coinbase()
- err = coinbase.BuyGas(self.tx.Gas, self.tx.GasPrice)
- if err != nil {
- return err
- }
-
- self.AddGas(self.tx.Gas)
- sender.SubAmount(self.tx.GasValue())
-
- return nil
-}
-
-func (self *StateTransition) RefundGas() {
- coinbase, sender := self.Coinbase(), self.Sender()
- coinbase.RefundGas(self.gas, self.tx.GasPrice)
-
- // Return remaining gas
- remaining := new(big.Int).Mul(self.gas, self.tx.GasPrice)
- sender.AddAmount(remaining)
-}
-
-func (self *StateTransition) preCheck() (err error) {
- var (
- tx = self.tx
- sender = self.Sender()
- )
-
- // Make sure this transaction's nonce is correct
- if sender.Nonce != tx.Nonce {
- return NonceError(tx.Nonce, sender.Nonce)
- }
-
- // Pre-pay gas / Buy gas of the coinbase account
- if err = self.BuyGas(); err != nil {
- return err
- }
-
- return nil
-}
-
-func (self *StateTransition) TransitionState() (err error) {
- statelogger.Debugf("(~) %x\n", self.tx.Hash())
-
- // XXX Transactions after this point are considered valid.
- if err = self.preCheck(); err != nil {
- return
- }
-
- var (
- tx = self.tx
- sender = self.Sender()
- receiver *state.StateObject
- )
-
- defer self.RefundGas()
-
- // Increment the nonce for the next transaction
- sender.Nonce += 1
-
- // Transaction gas
- if err = self.UseGas(vm.GasTx); err != nil {
- return
- }
-
- // Pay data gas
- dataPrice := big.NewInt(int64(len(self.data)))
- dataPrice.Mul(dataPrice, vm.GasData)
- if err = self.UseGas(dataPrice); err != nil {
- return
- }
-
- if sender.Balance().Cmp(self.value) < 0 {
- return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Balance)
- }
-
- var snapshot *state.State
- // If the receiver is nil it's a contract (\0*32).
- if tx.CreatesContract() {
- // Subtract the (irreversible) amount from the senders account
- sender.SubAmount(self.value)
-
- snapshot = self.state.Copy()
-
- // Create a new state object for the contract
- receiver = MakeContract(tx, self.state)
- self.rec = receiver
- if receiver == nil {
- return fmt.Errorf("Unable to create contract")
- }
-
- // Add the amount to receivers account which should conclude this transaction
- receiver.AddAmount(self.value)
- } else {
- receiver = self.Receiver()
-
- // Subtract the amount from the senders account
- sender.SubAmount(self.value)
- // Add the amount to receivers account which should conclude this transaction
- receiver.AddAmount(self.value)
-
- snapshot = self.state.Copy()
- }
-
- msg := self.state.Manifest().AddMessage(&state.Message{
- To: receiver.Address(), From: sender.Address(),
- Input: self.tx.Data,
- Origin: sender.Address(),
- Block: self.block.Hash(), Timestamp: self.block.Time, Coinbase: self.block.Coinbase, Number: self.block.Number,
- Value: self.value,
- })
-
- // Process the init code and create 'valid' contract
- if types.IsContractAddr(self.receiver) {
- // Evaluate the initialization script
- // and use the return value as the
- // script section for the state object.
- self.data = nil
-
- code, evmerr := self.Eval(msg, receiver.Init(), receiver)
- if evmerr != nil {
- self.state.Set(snapshot)
-
- statelogger.Debugf("Error during init execution %v", evmerr)
- }
-
- receiver.Code = code
- msg.Output = code
- } else {
- if len(receiver.Code) > 0 {
- ret, evmerr := self.Eval(msg, receiver.Code, receiver)
- if evmerr != nil {
- self.state.Set(snapshot)
-
- statelogger.Debugf("Error during code execution %v", evmerr)
- }
-
- msg.Output = ret
- }
- }
-
- /*
- * XXX The following _should_ replace the above transaction
- * execution (also for regular calls. Will replace / test next
- * phase
- */
- /*
- // Execute transaction
- if tx.CreatesContract() {
- self.rec = MakeContract(tx, self.state)
- }
-
- address := self.Receiver().Address()
- evm := vm.New(NewEnv(state, self.tx, self.block), vm.DebugVmTy)
- exe := NewExecution(evm, address, self.tx.Data, self.gas, self.gas.Price, self.tx.Value)
- ret, err := msg.Exec(address, self.Sender())
- if err != nil {
- statelogger.Debugln(err)
- } else {
- if tx.CreatesContract() {
- self.Receiver().Code = ret
- }
- msg.Output = ret
- }
- */
-
- // Add default LOG. Default = big(sender.addr) + 1
- //addr := ethutil.BigD(receiver.Address())
- //self.state.AddLog(&state.Log{ethutil.U256(addr.Add(addr, ethutil.Big1)).Bytes(), [][]byte{sender.Address()}, nil})
-
- return
-}
-
-func (self *StateTransition) Eval(msg *state.Message, script []byte, context *state.StateObject) (ret []byte, err error) {
- var (
- transactor = self.Sender()
- state = self.state
- env = NewEnv(state, self.tx, self.block)
- callerClosure = vm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice)
- )
-
- evm := vm.New(env, vm.DebugVmTy)
- // TMP this will change in the refactor
- callerClosure.SetExecution(vm.NewExecution(evm, nil, nil, nil, nil, self.tx.Value))
- ret, _, err = callerClosure.Call(evm, self.tx.Data)
-
- return
-}
-
-// Converts an transaction in to a state object
-func MakeContract(tx *types.Transaction, state *state.State) *state.StateObject {
- addr := tx.CreationAddress(state)
-
- contract := state.GetOrNewStateObject(addr)
- contract.InitCode = tx.Data
-
- return contract
-}
diff --git a/chain/vm_env.go b/chain/vm_env.go
deleted file mode 100644
index c1911ff51..000000000
--- a/chain/vm_env.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package chain
-
-import (
- "math/big"
-
- "github.com/ethereum/go-ethereum/chain/types"
- "github.com/ethereum/go-ethereum/state"
- "github.com/ethereum/go-ethereum/vm"
-)
-
-type VMEnv struct {
- state *state.State
- block *types.Block
- tx *types.Transaction
-}
-
-func NewEnv(state *state.State, tx *types.Transaction, block *types.Block) *VMEnv {
- return &VMEnv{
- state: state,
- block: block,
- tx: tx,
- }
-}
-
-func (self *VMEnv) Origin() []byte { return self.tx.Sender() }
-func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number }
-func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
-func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
-func (self *VMEnv) Time() int64 { return self.block.Time }
-func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
-func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
-func (self *VMEnv) Value() *big.Int { return self.tx.Value }
-func (self *VMEnv) State() *state.State { return self.state }
-func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
-func (self *VMEnv) AddLog(log *state.Log) {
- self.state.AddLog(log)
-}
-func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
- return vm.Transfer(from, to, amount)
-}
diff --git a/cmd/ethereum/cmd.go b/cmd/ethereum/cmd.go
index 8710d6136..d8b9ea487 100644
--- a/cmd/ethereum/cmd.go
+++ b/cmd/ethereum/cmd.go
@@ -21,9 +21,9 @@ import (
"io/ioutil"
"os"
- "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/cmd/ethereum/repl"
"github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/javascript"
)
diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go
index 783944cf2..556735491 100644
--- a/cmd/ethereum/flags.go
+++ b/cmd/ethereum/flags.go
@@ -38,7 +38,8 @@ var (
StartRpc bool
StartWebSockets bool
RpcPort int
- UseUPnP bool
+ NatType string
+ PMPGateway string
OutboundPort string
ShowGenesis bool
AddPeer string
@@ -84,7 +85,8 @@ func Init() {
flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use")
flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)")
flag.StringVar(&OutboundPort, "port", "30303", "listening port")
- flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support")
+ flag.StringVar(&NatType, "nat", "", "NAT support (UPNP|PMP) (none)")
+ flag.StringVar(&PMPGateway, "pmp", "", "Gateway IP for PMP")
flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers")
flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go
index aa933c4e7..da09e0b58 100644
--- a/cmd/ethereum/main.go
+++ b/cmd/ethereum/main.go
@@ -21,15 +21,16 @@ import (
"fmt"
"os"
"runtime"
- "github.com/ethereum/go-ethereum/chain/types"
+
"github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
)
const (
ClientIdentifier = "Ethereum(G)"
- Version = "0.7.5"
+ Version = "0.7.9"
)
var clilogger = logger.NewLogger("CLI")
@@ -68,15 +69,15 @@ func main() {
// create, import, export keys
utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
- clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier)
+ clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier, string(keyManager.PublicKey()))
- ethereum := utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer)
+ ethereum := utils.NewEthereum(db, clientIdentity, keyManager, utils.NatType(NatType, PMPGateway), OutboundPort, MaxPeer)
if Dump {
var block *types.Block
if len(DumpHash) == 0 && DumpNumber == -1 {
- block = ethereum.ChainManager().CurrentBlock
+ block = ethereum.ChainManager().CurrentBlock()
} else if len(DumpHash) > 0 {
block = ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(DumpHash))
} else {
diff --git a/cmd/ethereum/repl/repl.go b/cmd/ethereum/repl/repl.go
index a5146fecd..4a7880ff4 100644
--- a/cmd/ethereum/repl/repl.go
+++ b/cmd/ethereum/repl/repl.go
@@ -24,7 +24,7 @@ import (
"os"
"path"
- "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/javascript"
"github.com/ethereum/go-ethereum/logger"
diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go
index 82e1c6d59..94ab779db 100644
--- a/cmd/ethtest/main.go
+++ b/cmd/ethtest/main.go
@@ -82,7 +82,7 @@ func RunVmTest(js string) (failed int) {
state.SetStateObject(obj)
}
- ret, gas, err := helper.RunVm(state, test.Env, test.Exec)
+ ret, _, gas, err := helper.RunVm(state, test.Env, test.Exec)
// When an error is returned it doesn't always mean the tests fails.
// Have to come up with some conditional failing mechanism.
if err != nil {
diff --git a/cmd/evm/code.txt b/cmd/evm/code.txt
new file mode 100644
index 000000000..a964ad9d2
--- /dev/null
+++ b/cmd/evm/code.txt
@@ -0,0 +1 @@
+60006102ff5360003560001a60008114156103395760013560405260216040516020025990590160009052606052604051602002816060513760405160200281019050506002604051121561005957604051602002606051f35b604051602002599059016000905260a052600060c052604051602002599059016000905260e0526000610100526001610120525b604051610120511215610109576060515161012051602002606051015112156100d8576101205160200260605101516101005160200260e051015260016101005101610100526100f9565b61012051602002606051015160c05160200260a0510152600160c0510160c0525b600161012051016101205261008d565b60216020599059016000905260c051808252806020028301925050602082015990590160009052600081538151600182015260218101825160200260a0518260005b8381101561016657808301518186015260208101905061014b565b50505050825160200281019050604059905901600090526102405281610240515283602061024051015261024051905090509050905060c05160200280599059016000905281816020850151855160003060195a03f1508090509050905060a05260216020599059016000905261010051808252806020028301925050602082015990590160009052600081538151600182015260218101825160200260e0518260005b8381101561022557808301518186015260208101905061020a565b50505050825160200281019050604059905901600090526102c052816102c051528360206102c05101526102c05190509050905090506101005160200280599059016000905281816020850151855160003060195a03f1508090509050905060e05260405160200259905901600090526102e0526000610120525b610100516101205112156102d7576101205160200260e0510151610120516020026102e051015260016101205101610120526102a0565b60605151610100516020026102e05101526000610120525b60c05161012051121561032d576101205160200260a05101516101205160016101005101016020026102e051015260016101205101610120526102ef565b6040516020026102e051f35b50
diff --git a/cmd/evm/input.txt b/cmd/evm/input.txt
new file mode 100644
index 000000000..1b6857ab9
--- /dev/null
+++ b/cmd/evm/input.txt
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000023000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000250000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000004700000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000004d000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000004f0000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000520000000000000000000000000000000000000000000000000000000000000053000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000056000000000000000000000000000000000000000000000000000000000000005700000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000059000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000005b000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000006700000000000000000000000000000000000000000000000000000000000000680000000000000000000000000000000000000000000000000000000000000069000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000006b000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000006f0000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000007100000000000000000000000000000000000000000000000000000000000000720000000000000000000000000000000000000000000000000000000000000073000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000007700000000000000000000000000000000000000000000000000000000000000780000000000000000000000000000000000000000000000000000000000000079000000000000000000000000000000000000000000000000000000000000007a000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007c000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008100000000000000000000000000000000000000000000000000000000000000820000000000000000000000000000000000000000000000000000000000000083000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000086000000000000000000000000000000000000000000000000000000000000008700000000000000000000000000000000000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000000000008a000000000000000000000000000000000000000000000000000000000000008b000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000008e000000000000000000000000000000000000000000000000000000000000008f0000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000920000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000000000000000000000000000000000000980000000000000000000000000000000000000000000000000000000000000099000000000000000000000000000000000000000000000000000000000000009a000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000009d000000000000000000000000000000000000000000000000000000000000009e000000000000000000000000000000000000000000000000000000000000009f00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a100000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000a300000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000a500000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000a700000000000000000000000000000000000000000000000000000000000000a800000000000000000000000000000000000000000000000000000000000000a900000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000000000000000ab00000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000ad00000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000b100000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000b500000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000b900000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000bd00000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000bf00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000c500000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000c7
diff --git a/cmd/evm/main.go b/cmd/evm/main.go
index 2b4d47684..c6c986a04 100644
--- a/cmd/evm/main.go
+++ b/cmd/evm/main.go
@@ -32,6 +32,8 @@ import (
"runtime"
"time"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
@@ -43,8 +45,9 @@ import (
var (
code = flag.String("code", "", "evm code")
loglevel = flag.Int("log", 4, "log level")
- gas = flag.String("gas", "1000000", "gas amount")
+ gas = flag.String("gas", "1000000000", "gas amount")
price = flag.String("price", "0", "gas price")
+ value = flag.String("value", "0", "tx value")
dump = flag.Bool("dump", false, "dump state after run")
data = flag.String("data", "", "data")
)
@@ -59,15 +62,20 @@ func main() {
logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.LogLevel(*loglevel)))
- ethutil.ReadConfig("/tm/evmtest", "/tmp/evm", "")
+ ethutil.ReadConfig("/tmp/evmtest", "/tmp/evm", "")
- stateObject := state.NewStateObject([]byte("evmuser"))
- closure := vm.NewClosure(nil, stateObject, stateObject, ethutil.Hex2Bytes(*code), ethutil.Big(*gas), ethutil.Big(*price))
+ db, _ := ethdb.NewMemDatabase()
+ statedb := state.New(trie.New(db, ""))
+ sender := statedb.NewStateObject([]byte("sender"))
+ receiver := statedb.NewStateObject([]byte("receiver"))
+ //receiver.SetCode([]byte(*code))
+ receiver.SetCode(ethutil.Hex2Bytes(*code))
+
+ vmenv := NewEnv(statedb, []byte("evmuser"), ethutil.Big(*value))
tstart := time.Now()
- env := NewVmEnv()
- ret, _, e := closure.Call(vm.New(env, vm.DebugVmTy), ethutil.Hex2Bytes(*data))
+ ret, e := vmenv.Call(sender, receiver.Address(), ethutil.Hex2Bytes(*data), ethutil.Big(*gas), ethutil.Big(*price), ethutil.Big(*value))
logger.Flush()
if e != nil {
@@ -75,7 +83,7 @@ func main() {
}
if *dump {
- fmt.Println(string(env.state.Dump()))
+ fmt.Println(string(statedb.Dump()))
}
var mem runtime.MemStats
@@ -92,26 +100,65 @@ num gc: %d
fmt.Printf("%x\n", ret)
}
-type VmEnv struct {
- state *state.State
+type VMEnv struct {
+ state *state.StateDB
+ block *types.Block
+
+ transactor []byte
+ value *big.Int
+
+ depth int
+ Gas *big.Int
+ time int64
+}
+
+func NewEnv(state *state.StateDB, transactor []byte, value *big.Int) *VMEnv {
+ return &VMEnv{
+ state: state,
+ transactor: transactor,
+ value: value,
+ time: time.Now().Unix(),
+ }
}
-func NewVmEnv() *VmEnv {
- db, _ := ethdb.NewMemDatabase()
- return &VmEnv{state.New(trie.New(db, ""))}
+func (self *VMEnv) State() *state.StateDB { return self.state }
+func (self *VMEnv) Origin() []byte { return self.transactor }
+func (self *VMEnv) BlockNumber() *big.Int { return ethutil.Big0 }
+func (self *VMEnv) PrevHash() []byte { return make([]byte, 32) }
+func (self *VMEnv) Coinbase() []byte { return self.transactor }
+func (self *VMEnv) Time() int64 { return self.time }
+func (self *VMEnv) Difficulty() *big.Int { return ethutil.Big1 }
+func (self *VMEnv) BlockHash() []byte { return make([]byte, 32) }
+func (self *VMEnv) Value() *big.Int { return self.value }
+func (self *VMEnv) GasLimit() *big.Int { return big.NewInt(1000000000) }
+func (self *VMEnv) Depth() int { return 0 }
+func (self *VMEnv) SetDepth(i int) { self.depth = i }
+func (self *VMEnv) AddLog(log state.Log) {
+ self.state.AddLog(log)
+}
+func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
+ return vm.Transfer(from, to, amount)
+}
+
+func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execution {
+ evm := vm.New(self, vm.DebugVmTy)
+
+ return core.NewExecution(evm, addr, data, gas, price, value)
+}
+
+func (self *VMEnv) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(addr, data, gas, price, value)
+ ret, err := exe.Call(addr, caller)
+ self.Gas = exe.Gas
+
+ return ret, err
+}
+func (self *VMEnv) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(caller.Address(), data, gas, price, value)
+ return exe.Call(addr, caller)
}
-func (VmEnv) Origin() []byte { return nil }
-func (VmEnv) BlockNumber() *big.Int { return nil }
-func (VmEnv) BlockHash() []byte { return nil }
-func (VmEnv) PrevHash() []byte { return nil }
-func (VmEnv) Coinbase() []byte { return nil }
-func (VmEnv) Time() int64 { return 0 }
-func (VmEnv) GasLimit() *big.Int { return nil }
-func (VmEnv) Difficulty() *big.Int { return nil }
-func (VmEnv) Value() *big.Int { return nil }
-func (self *VmEnv) State() *state.State { return self.state }
-func (VmEnv) AddLog(*state.Log) {}
-func (VmEnv) Transfer(from, to vm.Account, amount *big.Int) error {
- return nil
+func (self *VMEnv) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
+ exe := self.vm(addr, data, gas, price, value)
+ return exe.Create(caller)
}
diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml
index 9f1f214a6..285757080 100644
--- a/cmd/mist/assets/qml/main.qml
+++ b/cmd/mist/assets/qml/main.qml
@@ -50,6 +50,7 @@ ApplicationWindow {
addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true});
addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"});
+ addPlugin("./views/whisper.qml", {noAdd: true, close: false, section: "legacy"});
addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"});
addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"});
addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"});
diff --git a/cmd/mist/assets/qml/views/miner.qml b/cmd/mist/assets/qml/views/miner.qml
index 2d59bb3a4..e0182649f 100644
--- a/cmd/mist/assets/qml/views/miner.qml
+++ b/cmd/mist/assets/qml/views/miner.qml
@@ -119,12 +119,14 @@ Rectangle {
}
}
Component.onCompleted: {
+ /*
// XXX Temp. replace with above eventually
var tmpItems = ["JEVCoin", "Some coin", "Other coin", "Etc coin"];
var address = "e6716f9544a56c530d868e4bfbacb172315bdead";
for (var i = 0; i < tmpItems.length; i++) {
mergedMiningModel.append({checked: false, name: tmpItems[i], address: address, id: 0, itemId: i});
}
+ */
}
}
}
diff --git a/cmd/mist/assets/qml/views/wallet.qml b/cmd/mist/assets/qml/views/wallet.qml
index a57e7869a..9727ef35c 100644
--- a/cmd/mist/assets/qml/views/wallet.qml
+++ b/cmd/mist/assets/qml/views/wallet.qml
@@ -16,7 +16,13 @@ Rectangle {
anchors.fill: parent
function onReady() {
- menuItem.secondaryTitle = eth.numberToHuman(eth.balanceAt(eth.key().address))
+ setBalance()
+ }
+
+ function setBalance() {
+ balance.text = "<b>Balance</b>: " + eth.numberToHuman(eth.balanceAt(eth.key().address))
+ if(menuItem)
+ menuItem.secondaryTitle = eth.numberToHuman(eth.balanceAt(eth.key().address))
}
ListModel {
@@ -39,7 +45,6 @@ Rectangle {
Text {
id: balance
- text: "<b>Balance</b>: " + eth.numberToHuman(eth.balanceAt(eth.key().address))
font.pixelSize: 24
anchors {
horizontalCenter: parent.horizontalCenter
@@ -126,7 +131,6 @@ Rectangle {
var value = txValue.text + denomModel.get(valueDenom.currentIndex).zeros;
var gasPrice = "10000000000000"
var res = eth.transact({from: eth.key().privateKey, to: txTo.text, value: value, gas: "500", gasPrice: gasPrice})
- console.log(res)
}
}
}
@@ -144,24 +148,35 @@ Rectangle {
id: txTableView
anchors.fill : parent
TableViewColumn{ role: "num" ; title: "#" ; width: 30 }
- TableViewColumn{ role: "from" ; title: "From" ; width: 280 }
- TableViewColumn{ role: "to" ; title: "To" ; width: 280 }
+ TableViewColumn{ role: "from" ; title: "From" ; width: 340 }
+ TableViewColumn{ role: "to" ; title: "To" ; width: 340 }
TableViewColumn{ role: "value" ; title: "Amount" ; width: 100 }
model: ListModel {
id: txModel
Component.onCompleted: {
- var filter = ethx.watch({latest: -1, from: eth.key().address});
- filter.changed(addTxs)
-
- addTxs(filter.messages())
+ var me = eth.key().address;
+ var filterTo = ethx.watch({latest: -1, to: me});
+ var filterFrom = ethx.watch({latest: -1, from: me});
+ filterTo.changed(addTxs)
+ filterFrom.changed(addTxs)
+
+ addTxs(filterTo.messages())
+ addTxs(filterFrom.messages())
}
function addTxs(messages) {
+ setBalance()
+
for(var i = 0; i < messages.length; i++) {
var message = messages.get(i);
var to = eth.lookupName(message.to);
- var from = eth.lookupName(message.from);
+ var from;
+ if(message.from.length == 0) {
+ from = "- MINED -";
+ } else {
+ from = eth.lookupName(message.from);
+ }
txModel.insert(0, {num: txModel.count, from: from, to: to, value: eth.numberToHuman(message.value)})
}
}
diff --git a/cmd/mist/assets/qml/views/whisper.qml b/cmd/mist/assets/qml/views/whisper.qml
new file mode 100644
index 000000000..b50841ba5
--- /dev/null
+++ b/cmd/mist/assets/qml/views/whisper.qml
@@ -0,0 +1,47 @@
+
+import QtQuick 2.0
+import QtQuick.Controls 1.0;
+import QtQuick.Layouts 1.0;
+import QtQuick.Dialogs 1.0;
+import QtQuick.Window 2.1;
+import QtQuick.Controls.Styles 1.1
+import Ethereum 1.0
+
+Rectangle {
+ id: root
+ property var title: "Whisper"
+ property var iconSource: "../facet.png"
+ property var menuItem
+
+ objectName: "whisperView"
+ anchors.fill: parent
+
+ property var identity: ""
+ Component.onCompleted: {
+ identity = shh.newIdentity()
+ console.log("New identity:", identity)
+
+ var t = shh.watch({topics: ["chat"]})
+ }
+
+ RowLayout {
+ TextField {
+ id: to
+ placeholderText: "To"
+ }
+ TextField {
+ id: data
+ placeholderText: "Data"
+ }
+ TextField {
+ id: topics
+ placeholderText: "topic1, topic2, topic3, ..."
+ }
+ Button {
+ text: "Send"
+ onClicked: {
+ shh.post(eth.toHex(data.text), "", identity, topics.text.split(","), 500, 50)
+ }
+ }
+ }
+}
diff --git a/cmd/mist/bindings.go b/cmd/mist/bindings.go
index eb78c3acc..6d2342c87 100644
--- a/cmd/mist/bindings.go
+++ b/cmd/mist/bindings.go
@@ -21,11 +21,11 @@ import (
"encoding/json"
"os"
"strconv"
- "github.com/ethereum/go-ethereum/chain/types"
+
"github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/xeth"
)
type plugin struct {
@@ -45,12 +45,12 @@ func (gui *Gui) LogPrint(level logger.LogLevel, msg string) {
}
*/
}
-func (gui *Gui) Transact(recipient, value, gas, gasPrice, d string) (*xeth.JSReceipt, error) {
+func (gui *Gui) Transact(recipient, value, gas, gasPrice, d string) (string, error) {
var data string
if len(recipient) == 0 {
code, err := ethutil.Compile(d, false)
if err != nil {
- return nil, err
+ return "", err
}
data = ethutil.Bytes2Hex(code)
} else {
@@ -103,7 +103,7 @@ func (self *Gui) DumpState(hash, path string) {
var stateDump []byte
if len(hash) == 0 {
- stateDump = self.eth.BlockManager().CurrentState().Dump()
+ stateDump = self.eth.ChainManager().State().Dump()
} else {
var block *types.Block
if hash[0] == '#' {
diff --git a/cmd/mist/debugger.go b/cmd/mist/debugger.go
index a2aae6f0b..a7a286e23 100644
--- a/cmd/mist/debugger.go
+++ b/cmd/mist/debugger.go
@@ -24,8 +24,8 @@ import (
"strings"
"unicode"
- "github.com/ethereum/go-ethereum/chain"
"github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm"
@@ -40,7 +40,7 @@ type DebuggerWindow struct {
vm *vm.DebugVm
Db *Debugger
- state *state.State
+ state *state.StateDB
}
func NewDebuggerWindow(lib *UiLib) *DebuggerWindow {
@@ -81,7 +81,7 @@ func (self *DebuggerWindow) SetData(data string) {
func (self *DebuggerWindow) SetAsm(data []byte) {
self.win.Root().Call("clearAsm")
- dis := chain.Disassemble(data)
+ dis := core.Disassemble(data)
for _, str := range dis {
self.win.Root().Call("setAsm", str)
}
@@ -141,27 +141,24 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
keyPair = self.lib.eth.KeyManager().KeyPair()
)
- statedb := self.lib.eth.BlockManager().TransState()
- account := self.lib.eth.BlockManager().TransState().GetAccount(keyPair.Address())
+ statedb := self.lib.eth.ChainManager().TransState()
+ account := self.lib.eth.ChainManager().TransState().GetAccount(keyPair.Address())
contract := statedb.NewStateObject([]byte{0})
+ contract.SetCode(script)
contract.SetBalance(value)
self.SetAsm(script)
- block := self.lib.eth.ChainManager().CurrentBlock
+ block := self.lib.eth.ChainManager().CurrentBlock()
- callerClosure := vm.NewClosure(&state.Message{}, account, contract, script, gas, gasPrice)
env := utils.NewEnv(statedb, block, account.Address(), value)
- evm := vm.NewDebugVm(env)
- evm.Dbg = self.Db
- self.vm = evm
- self.Db.done = false
self.Logf("callsize %d", len(script))
go func() {
- ret, g, err := callerClosure.Call(evm, data)
- tot := new(big.Int).Mul(g, gasPrice)
- self.Logf("gas usage %v total price = %v (%v)", g, tot, ethutil.CurrencyToString(tot))
+ ret, err := env.Call(account, contract.Address(), data, gas, gasPrice, ethutil.Big0)
+ //ret, g, err := callerClosure.Call(evm, data)
+ tot := new(big.Int).Mul(env.Gas, gasPrice)
+ self.Logf("gas usage %v total price = %v (%v)", env.Gas, tot, ethutil.CurrencyToString(tot))
if err != nil {
self.Logln("exited with errors:", err)
} else {
diff --git a/cmd/mist/ext_app.go b/cmd/mist/ext_app.go
index 22fa4bfaf..33c420a7a 100644
--- a/cmd/mist/ext_app.go
+++ b/cmd/mist/ext_app.go
@@ -20,8 +20,8 @@ package main
import (
"encoding/json"
- "github.com/ethereum/go-ethereum/chain"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/javascript"
"github.com/ethereum/go-ethereum/state"
@@ -45,12 +45,12 @@ type AppContainer interface {
type ExtApplication struct {
*xeth.JSXEth
- eth chain.EthManager
+ eth core.EthManager
events event.Subscription
watcherQuitChan chan bool
- filters map[string]*chain.Filter
+ filters map[string]*core.Filter
container AppContainer
lib *UiLib
@@ -61,7 +61,7 @@ func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication {
JSXEth: xeth.NewJSXEth(lib.eth),
eth: lib.eth,
watcherQuitChan: make(chan bool),
- filters: make(map[string]*chain.Filter),
+ filters: make(map[string]*core.Filter),
container: container,
lib: lib,
}
@@ -81,7 +81,7 @@ func (app *ExtApplication) run() {
// Subscribe to events
mux := app.lib.eth.EventMux()
- app.events = mux.Subscribe(chain.NewBlockEvent{}, state.Messages(nil))
+ app.events = mux.Subscribe(core.NewBlockEvent{}, state.Messages(nil))
// Call the main loop
go app.mainLoop()
@@ -107,7 +107,7 @@ func (app *ExtApplication) stop() {
func (app *ExtApplication) mainLoop() {
for ev := range app.events.Chan() {
switch ev := ev.(type) {
- case chain.NewBlockEvent:
+ case core.NewBlockEvent:
app.container.NewBlock(ev.Block)
case state.Messages:
diff --git a/cmd/mist/flags.go b/cmd/mist/flags.go
index 2ae0a0487..1d77532d9 100644
--- a/cmd/mist/flags.go
+++ b/cmd/mist/flags.go
@@ -36,10 +36,12 @@ var (
Identifier string
KeyRing string
KeyStore string
+ PMPGateway string
StartRpc bool
StartWebSockets bool
RpcPort int
UseUPnP bool
+ NatType string
OutboundPort string
ShowGenesis bool
AddPeer string
@@ -111,10 +113,12 @@ func Init() {
flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
flag.BoolVar(&UseSeed, "seed", true, "seed peers")
flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key")
+ flag.StringVar(&NatType, "nat", "", "NAT support (UPNP|PMP) (none)")
flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)")
flag.StringVar(&ExportDir, "export", "", "exports the session keyring to files in the directory given")
flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)")
flag.StringVar(&Datadir, "datadir", defaultDataDir(), "specifies the datadir to use")
+ flag.StringVar(&PMPGateway, "pmp", "", "Gateway IP for PMP")
flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file")
flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)")
flag.IntVar(&LogLevel, "loglevel", int(logger.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)")
diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go
index 61b66cce3..e858d7c61 100644
--- a/cmd/mist/gui.go
+++ b/cmd/mist/gui.go
@@ -30,14 +30,15 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/chain"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/miner"
- "github.com/ethereum/go-ethereum/wire"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/ui/qt/qwhisper"
"github.com/ethereum/go-ethereum/xeth"
"gopkg.in/qml.v1"
)
@@ -87,7 +88,8 @@ type Gui struct {
eth *eth.Ethereum
// The public Ethereum library
- uiLib *UiLib
+ uiLib *UiLib
+ whisper *qwhisper.Whisper
txDb *ethdb.LDBDatabase
@@ -97,7 +99,7 @@ type Gui struct {
pipe *xeth.JSXEth
Session string
- clientIdentity *wire.SimpleClientIdentity
+ clientIdentity *p2p.SimpleClientIdentity
config *ethutil.ConfigManager
plugins map[string]plugin
@@ -107,7 +109,7 @@ type Gui struct {
}
// Create GUI, but doesn't start it
-func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIdentity *wire.SimpleClientIdentity, session string, logLevel int) *Gui {
+func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIdentity *p2p.SimpleClientIdentity, session string, logLevel int) *Gui {
db, err := ethdb.NewLDBDatabase("tx_database")
if err != nil {
panic(err)
@@ -138,10 +140,12 @@ func (gui *Gui) Start(assetPath string) {
gui.engine = qml.NewEngine()
context := gui.engine.Context()
gui.uiLib = NewUiLib(gui.engine, gui.eth, assetPath)
+ gui.whisper = qwhisper.New(gui.eth.Whisper())
// Expose the eth library and the ui library to QML
context.SetVar("gui", gui)
context.SetVar("eth", gui.uiLib)
+ context.SetVar("shh", gui.whisper)
// Load the main QML interface
data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
@@ -246,7 +250,7 @@ func (gui *Gui) CreateAndSetPrivKey() (string, string, string, string) {
}
func (gui *Gui) setInitialChain(ancientBlocks bool) {
- sBlk := gui.eth.ChainManager().LastBlockHash
+ sBlk := gui.eth.ChainManager().LastBlockHash()
blk := gui.eth.ChainManager().GetBlock(sBlk)
for ; blk != nil; blk = gui.eth.ChainManager().GetBlock(sBlk) {
sBlk = blk.PrevHash
@@ -297,7 +301,7 @@ func (gui *Gui) insertTransaction(window string, tx *types.Transaction) {
addr := gui.address()
var inout string
- if bytes.Compare(tx.Sender(), addr) == 0 {
+ if bytes.Compare(tx.From(), addr) == 0 {
inout = "send"
} else {
inout = "recv"
@@ -305,27 +309,27 @@ func (gui *Gui) insertTransaction(window string, tx *types.Transaction) {
var (
ptx = xeth.NewJSTx(tx, pipe.World().State())
- send = nameReg.Storage(tx.Sender())
- rec = nameReg.Storage(tx.Recipient)
+ send = nameReg.Storage(tx.From())
+ rec = nameReg.Storage(tx.To())
s, r string
)
- if tx.CreatesContract() {
- rec = nameReg.Storage(tx.CreationAddress(pipe.World().State()))
+ if core.MessageCreatesContract(tx) {
+ rec = nameReg.Storage(core.AddressFromMessage(tx))
}
if send.Len() != 0 {
s = strings.Trim(send.Str(), "\x00")
} else {
- s = ethutil.Bytes2Hex(tx.Sender())
+ s = ethutil.Bytes2Hex(tx.From())
}
if rec.Len() != 0 {
r = strings.Trim(rec.Str(), "\x00")
} else {
- if tx.CreatesContract() {
- r = ethutil.Bytes2Hex(tx.CreationAddress(pipe.World().State()))
+ if core.MessageCreatesContract(tx) {
+ r = ethutil.Bytes2Hex(core.AddressFromMessage(tx))
} else {
- r = ethutil.Bytes2Hex(tx.Recipient)
+ r = ethutil.Bytes2Hex(tx.To())
}
}
ptx.Sender = s
@@ -389,9 +393,10 @@ func (gui *Gui) update() {
gui.loadAddressBook()
gui.loadMergedMiningOptions()
gui.setPeerInfo()
- //gui.readPreviousTransactions()
}()
+ gui.whisper.SetView(gui.win.Root().ObjectByName("whisperView"))
+
for _, plugin := range gui.plugins {
guilogger.Infoln("Loading plugin ", plugin.Name)
@@ -402,25 +407,20 @@ func (gui *Gui) update() {
generalUpdateTicker := time.NewTicker(500 * time.Millisecond)
statsUpdateTicker := time.NewTicker(5 * time.Second)
- state := gui.eth.BlockManager().TransState()
+ state := gui.eth.ChainManager().TransState()
- unconfirmedFunds := new(big.Int)
gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Balance())))
lastBlockLabel := gui.getObjectByName("lastBlockLabel")
miningLabel := gui.getObjectByName("miningLabel")
events := gui.eth.EventMux().Subscribe(
- eth.ChainSyncEvent{},
- eth.PeerListEvent{},
- chain.NewBlockEvent{},
- chain.TxPreEvent{},
- chain.TxPostEvent{},
+ //eth.PeerListEvent{},
+ core.NewBlockEvent{},
+ core.TxPreEvent{},
+ core.TxPostEvent{},
)
- // nameReg := gui.pipe.World().Config().Get("NameReg")
- // mux.Subscribe("object:"+string(nameReg.Address()), objectChan)
-
go func() {
defer events.Unsubscribe()
for {
@@ -430,77 +430,62 @@ func (gui *Gui) update() {
return
}
switch ev := ev.(type) {
- case chain.NewBlockEvent:
+ case core.NewBlockEvent:
gui.processBlock(ev.Block, false)
if bytes.Compare(ev.Block.Coinbase, gui.address()) == 0 {
- gui.setWalletValue(gui.eth.BlockManager().CurrentState().GetAccount(gui.address()).Balance(), nil)
+ gui.setWalletValue(gui.eth.ChainManager().State().GetBalance(gui.address()), nil)
}
- case chain.TxPreEvent:
+ case core.TxPreEvent:
tx := ev.Tx
- object := state.GetAccount(gui.address())
- if bytes.Compare(tx.Sender(), gui.address()) == 0 {
- unconfirmedFunds.Sub(unconfirmedFunds, tx.Value)
- } else if bytes.Compare(tx.Recipient, gui.address()) == 0 {
- unconfirmedFunds.Add(unconfirmedFunds, tx.Value)
- }
+ tstate := gui.eth.ChainManager().TransState()
+ cstate := gui.eth.ChainManager().State()
- gui.setWalletValue(object.Balance(), unconfirmedFunds)
+ taccount := tstate.GetAccount(gui.address())
+ caccount := cstate.GetAccount(gui.address())
+ unconfirmedFunds := new(big.Int).Sub(taccount.Balance(), caccount.Balance())
+
+ gui.setWalletValue(taccount.Balance(), unconfirmedFunds)
gui.insertTransaction("pre", tx)
- case chain.TxPostEvent:
+ case core.TxPostEvent:
tx := ev.Tx
object := state.GetAccount(gui.address())
- if bytes.Compare(tx.Sender(), gui.address()) == 0 {
- object.SubAmount(tx.Value)
+ if bytes.Compare(tx.From(), gui.address()) == 0 {
+ object.SubAmount(tx.Value())
- //gui.getObjectByName("transactionView").Call("addTx", xeth.NewJSTx(tx), "send")
gui.txDb.Put(tx.Hash(), tx.RlpEncode())
- } else if bytes.Compare(tx.Recipient, gui.address()) == 0 {
- object.AddAmount(tx.Value)
+ } else if bytes.Compare(tx.To(), gui.address()) == 0 {
+ object.AddAmount(tx.Value())
- //gui.getObjectByName("transactionView").Call("addTx", xeth.NewJSTx(tx), "recv")
gui.txDb.Put(tx.Hash(), tx.RlpEncode())
}
gui.setWalletValue(object.Balance(), nil)
state.UpdateStateObject(object)
-
- // case object:
- // gui.loadAddressBook()
-
- case eth.PeerListEvent:
- gui.setPeerInfo()
-
- /*
- case miner.Event:
- if ev.Type == miner.Started {
- gui.miner = ev.Miner
- } else {
- gui.miner = nil
- }
- */
}
case <-peerUpdateTicker.C:
gui.setPeerInfo()
case <-generalUpdateTicker.C:
- statusText := "#" + gui.eth.ChainManager().CurrentBlock.Number.String()
+ statusText := "#" + gui.eth.ChainManager().CurrentBlock().Number.String()
lastBlockLabel.Set("text", statusText)
miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.GetPow().GetHashrate(), 10)+"Khash")
- blockLength := gui.eth.BlockPool().BlocksProcessed
- chainLength := gui.eth.BlockPool().ChainLength
+ /*
+ blockLength := gui.eth.BlockPool().BlocksProcessed
+ chainLength := gui.eth.BlockPool().ChainLength
- var (
- pct float64 = 1.0 / float64(chainLength) * float64(blockLength)
- dlWidget = gui.win.Root().ObjectByName("downloadIndicator")
- dlLabel = gui.win.Root().ObjectByName("downloadLabel")
- )
- dlWidget.Set("value", pct)
- dlLabel.Set("text", fmt.Sprintf("%d / %d", blockLength, chainLength))
+ var (
+ pct float64 = 1.0 / float64(chainLength) * float64(blockLength)
+ dlWidget = gui.win.Root().ObjectByName("downloadIndicator")
+ dlLabel = gui.win.Root().ObjectByName("downloadLabel")
+ )
+ dlWidget.Set("value", pct)
+ dlLabel.Set("text", fmt.Sprintf("%d / %d", blockLength, chainLength))
+ */
case <-statsUpdateTicker.C:
gui.setStatsPane()
@@ -528,7 +513,7 @@ Heap Alloc: %d
CGNext: %x
NumGC: %d
`, Version, runtime.Version(),
- eth.ProtocolVersion, eth.P2PVersion,
+ eth.ProtocolVersion, 2,
runtime.NumCPU, runtime.NumGoroutine(), runtime.NumCgoCall(),
memStats.Alloc, memStats.HeapAlloc,
memStats.NextGC, memStats.NumGC,
diff --git a/cmd/mist/html_container.go b/cmd/mist/html_container.go
index 4c6609a95..b3fc219fa 100644
--- a/cmd/mist/html_container.go
+++ b/cmd/mist/html_container.go
@@ -26,7 +26,8 @@ import (
"os"
"path"
"path/filepath"
- "github.com/ethereum/go-ethereum/chain/types"
+
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/javascript"
"github.com/ethereum/go-ethereum/state"
diff --git a/cmd/mist/main.go b/cmd/mist/main.go
index bc05d4f3d..3ea6e8e91 100644
--- a/cmd/mist/main.go
+++ b/cmd/mist/main.go
@@ -23,15 +23,15 @@ import (
"runtime"
"time"
- "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/logger"
"gopkg.in/qml.v1"
)
const (
ClientIdentifier = "Mist"
- Version = "0.7.5"
+ Version = "0.7.9"
)
var ethereum *eth.Ethereum
@@ -58,8 +58,8 @@ func run() error {
// create, import, export keys
utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
- clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier)
- ethereum = utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer)
+ clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier, string(keyManager.PublicKey()))
+ ethereum := utils.NewEthereum(db, clientIdentity, keyManager, utils.NatType(NatType, PMPGateway), OutboundPort, MaxPeer)
if ShowGenesis {
utils.ShowGenesis(ethereum)
@@ -69,6 +69,10 @@ func run() error {
utils.StartRpc(ethereum, RpcPort)
}
+ if StartWebSockets {
+ utils.StartWebSockets(ethereum)
+ }
+
gui := NewWindow(ethereum, config, clientIdentity, KeyRing, LogLevel)
gui.stdLog = stdLog
@@ -100,16 +104,10 @@ func main() {
utils.HandleInterrupt()
- if StartWebSockets {
- utils.StartWebSockets(ethereum)
- }
-
// we need to run the interrupt callbacks in case gui is closed
// this skips if we got here by actual interrupt stopping the GUI
if !interrupted {
utils.RunInterruptCallbacks(os.Interrupt)
}
- // this blocks the thread
- ethereum.WaitForShutdown()
logger.Flush()
}
diff --git a/cmd/mist/qml_container.go b/cmd/mist/qml_container.go
index b5986c16e..a0a46f9b1 100644
--- a/cmd/mist/qml_container.go
+++ b/cmd/mist/qml_container.go
@@ -20,7 +20,8 @@ package main
import (
"fmt"
"runtime"
- "github.com/ethereum/go-ethereum/chain/types"
+
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/xeth"
diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go
index 01352f192..68f333563 100644
--- a/cmd/mist/ui_lib.go
+++ b/cmd/mist/ui_lib.go
@@ -24,11 +24,12 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/chain"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/event/filter"
"github.com/ethereum/go-ethereum/javascript"
"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/state"
@@ -57,6 +58,7 @@ type UiLib struct {
jsEngine *javascript.JSRE
filterCallbacks map[int][]int
+ filterManager *filter.FilterManager
miner *miner.Miner
}
@@ -64,6 +66,7 @@ type UiLib struct {
func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib {
lib := &UiLib{JSXEth: xeth.NewJSXEth(eth), engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(eth), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*xeth.JSFilter)}
lib.miner = miner.New(eth.KeyManager().Address(), eth)
+ lib.filterManager = filter.NewFilterManager(eth.EventMux())
return lib
}
@@ -123,12 +126,16 @@ func (self *UiLib) LookupAddress(name string) string {
}
func (self *UiLib) PastPeers() *ethutil.List {
- return ethutil.NewList(eth.PastPeers())
+ return ethutil.NewList([]string{})
+ //return ethutil.NewList(eth.PastPeers())
}
func (self *UiLib) ImportTx(rlpTx string) {
tx := types.NewTransactionFromBytes(ethutil.Hex2Bytes(rlpTx))
- self.eth.TxPool().QueueTransaction(tx)
+ err := self.eth.TxPool().Add(tx)
+ if err != nil {
+ guilogger.Infoln("import tx failed ", err)
+ }
}
func (self *UiLib) EvalJavascriptFile(path string) {
@@ -188,7 +195,7 @@ func (ui *UiLib) Connect(button qml.Object) {
}
func (ui *UiLib) ConnectToPeer(addr string) {
- ui.eth.ConnectToPeer(addr)
+ ui.eth.SuggestPeer(addr)
}
func (ui *UiLib) AssetPath(p string) string {
@@ -197,7 +204,7 @@ func (ui *UiLib) AssetPath(p string) string {
func (self *UiLib) StartDbWithContractAndData(contractHash, data string) {
dbWindow := NewDebuggerWindow(self)
- object := self.eth.BlockManager().CurrentState().GetStateObject(ethutil.Hex2Bytes(contractHash))
+ object := self.eth.ChainManager().State().GetStateObject(ethutil.Hex2Bytes(contractHash))
if len(object.Code) > 0 {
dbWindow.SetCode("0x" + ethutil.Bytes2Hex(object.Code))
}
@@ -223,12 +230,12 @@ func (self *UiLib) NewFilter(object map[string]interface{}) (id int) {
filter.MessageCallback = func(messages state.Messages) {
self.win.Root().Call("invokeFilterCallback", xeth.ToJSMessages(messages), id)
}
- id = self.eth.InstallFilter(filter)
+ id = self.filterManager.InstallFilter(filter)
return id
}
func (self *UiLib) NewFilterString(typ string) (id int) {
- filter := chain.NewFilter(self.eth)
+ filter := core.NewFilter(self.eth)
filter.BlockCallback = func(block *types.Block) {
if self.win != nil && self.win.Root() != nil {
self.win.Root().Call("invokeFilterCallback", "{}", id)
@@ -236,12 +243,12 @@ func (self *UiLib) NewFilterString(typ string) (id int) {
fmt.Println("QML is lagging")
}
}
- id = self.eth.InstallFilter(filter)
+ id = self.filterManager.InstallFilter(filter)
return id
}
func (self *UiLib) Messages(id int) *ethutil.List {
- filter := self.eth.GetFilter(id)
+ filter := self.filterManager.GetFilter(id)
if filter != nil {
messages := xeth.ToJSMessages(filter.Find())
@@ -252,7 +259,7 @@ func (self *UiLib) Messages(id int) *ethutil.List {
}
func (self *UiLib) UninstallFilter(id int) {
- self.eth.UninstallFilter(id)
+ self.filterManager.UninstallFilter(id)
}
func mapToTxParams(object map[string]interface{}) map[string]string {
@@ -306,7 +313,7 @@ func mapToTxParams(object map[string]interface{}) map[string]string {
return conv
}
-func (self *UiLib) Transact(params map[string]interface{}) (*xeth.JSReceipt, error) {
+func (self *UiLib) Transact(params map[string]interface{}) (string, error) {
object := mapToTxParams(params)
return self.JSXEth.Transact(
@@ -369,3 +376,16 @@ func (self *UiLib) ToggleMining() bool {
return false
}
}
+
+func (self *UiLib) ToHex(data string) string {
+ return "0x" + ethutil.Bytes2Hex([]byte(data))
+}
+
+/*
+// XXX Refactor me & MOVE
+func (self *Ethereum) InstallFilter(filter *core.Filter) (id int) {
+ return self.filterManager.InstallFilter(filter)
+}
+func (self *Ethereum) UninstallFilter(id int) { self.filterManager.UninstallFilter(id) }
+func (self *Ethereum) GetFilter(id int) *core.Filter { return self.filterManager.GetFilter(id) }
+*/
diff --git a/cmd/peerserver/main.go b/cmd/peerserver/main.go
new file mode 100644
index 000000000..0fa7a9b44
--- /dev/null
+++ b/cmd/peerserver/main.go
@@ -0,0 +1,40 @@
+package main
+
+import (
+ "crypto/elliptic"
+ "fmt"
+ "log"
+ "net"
+ "os"
+
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/p2p"
+)
+
+func main() {
+ logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.InfoLevel))
+ key, _ := crypto.GenerateKey()
+ marshaled := elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y)
+
+ srv := p2p.Server{
+ MaxPeers: 10,
+ Identity: p2p.NewSimpleClientIdentity("Ethereum(G)", "0.1", "Peer Server Two", string(marshaled)),
+ ListenAddr: ":30301",
+ NAT: p2p.UPNP(),
+ }
+ if err := srv.Start(); err != nil {
+ fmt.Println("could not start server:", err)
+ os.Exit(1)
+ }
+
+ // add seed peers
+ seed, err := net.ResolveTCPAddr("tcp", "poc-7.ethdev.com:30300")
+ if err != nil {
+ fmt.Println("couldn't resolve:", err)
+ os.Exit(1)
+ }
+ srv.SuggestPeer(seed.IP, seed.Port, nil)
+
+ select {}
+}
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index 96590b20f..3e3ac617a 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -4,23 +4,23 @@ import (
"fmt"
"io"
"log"
+ "net"
"os"
"os/signal"
"path"
"path/filepath"
"regexp"
"runtime"
- "time"
"bitbucket.org/kardianos/osext"
- "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/miner"
+ "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/wire"
"github.com/ethereum/go-ethereum/xeth"
)
@@ -144,18 +144,32 @@ func NewDatabase() ethutil.Database {
return db
}
-func NewClientIdentity(clientIdentifier, version, customIdentifier string) *wire.SimpleClientIdentity {
- clilogger.Infoln("identity created")
- return wire.NewSimpleClientIdentity(clientIdentifier, version, customIdentifier)
+func NewClientIdentity(clientIdentifier, version, customIdentifier string, pubkey string) *p2p.SimpleClientIdentity {
+ return p2p.NewSimpleClientIdentity(clientIdentifier, version, customIdentifier, pubkey)
}
-func NewEthereum(db ethutil.Database, clientIdentity wire.ClientIdentity, keyManager *crypto.KeyManager, usePnp bool, OutboundPort string, MaxPeer int) *eth.Ethereum {
- ethereum, err := eth.New(db, clientIdentity, keyManager, eth.CapDefault, usePnp)
+func NatType(natType string, gateway string) (nat p2p.NAT) {
+ switch natType {
+ case "UPNP":
+ nat = p2p.UPNP()
+ case "PMP":
+ ip := net.ParseIP(gateway)
+ if ip == nil {
+ clilogger.Fatalf("cannot resolve PMP gateway IP %s", gateway)
+ }
+ nat = p2p.PMP(ip)
+ case "":
+ default:
+ clilogger.Fatalf("unrecognised NAT type '%s'", natType)
+ }
+ return
+}
+
+func NewEthereum(db ethutil.Database, clientIdentity p2p.ClientIdentity, keyManager *crypto.KeyManager, nat p2p.NAT, OutboundPort string, MaxPeer int) *eth.Ethereum {
+ ethereum, err := eth.New(db, clientIdentity, keyManager, nat, OutboundPort, MaxPeer)
if err != nil {
clilogger.Fatalln("eth start err:", err)
}
- ethereum.Port = OutboundPort
- ethereum.MaxPeers = MaxPeer
return ethereum
}
@@ -240,6 +254,7 @@ func KeyTasks(keyManager *crypto.KeyManager, KeyRing string, GenAddr bool, Secre
exit(err)
}
}
+ clilogger.Infof("Main address %x\n", keyManager.Address())
}
func StartRpc(ethereum *eth.Ethereum, RpcPort int) {
@@ -268,11 +283,6 @@ func StartMining(ethereum *eth.Ethereum) bool {
if gminer == nil {
gminer = miner.New(addr, ethereum)
}
- // Give it some time to connect with peers
- time.Sleep(3 * time.Second)
- for !ethereum.IsUpToDate() {
- time.Sleep(5 * time.Second)
- }
gminer.Start()
}()
RegisterInterrupt(func(os.Signal) {
@@ -317,7 +327,7 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
parent := ethereum.ChainManager().GetBlock(block.PrevHash)
- _, err := ethereum.BlockManager().ApplyDiff(parent.State(), parent, block)
+ _, err := ethereum.BlockManager().TransitionState(parent.State(), parent, block)
if err != nil {
return err
}
diff --git a/cmd/utils/vm_env.go b/cmd/utils/vm_env.go
index b2788efa1..461a797c2 100644
--- a/cmd/utils/vm_env.go
+++ b/cmd/utils/vm_env.go
@@ -2,20 +2,25 @@ package utils
import (
"math/big"
- "github.com/ethereum/go-ethereum/chain/types"
+
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm"
)
type VMEnv struct {
- state *state.State
+ state *state.StateDB
block *types.Block
transactor []byte
value *big.Int
+
+ depth int
+ Gas *big.Int
}
-func NewEnv(state *state.State, block *types.Block, transactor []byte, value *big.Int) *VMEnv {
+func NewEnv(state *state.StateDB, block *types.Block, transactor []byte, value *big.Int) *VMEnv {
return &VMEnv{
state: state,
block: block,
@@ -32,9 +37,34 @@ func (self *VMEnv) Time() int64 { return self.block.Time }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
func (self *VMEnv) Value() *big.Int { return self.value }
-func (self *VMEnv) State() *state.State { return self.state }
+func (self *VMEnv) State() *state.StateDB { return self.state }
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
-func (self *VMEnv) AddLog(*state.Log) {}
+func (self *VMEnv) Depth() int { return self.depth }
+func (self *VMEnv) SetDepth(i int) { self.depth = i }
+func (self *VMEnv) AddLog(log state.Log) {
+ self.state.AddLog(log)
+}
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
return vm.Transfer(from, to, amount)
}
+
+func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execution {
+ return core.NewExecution(self, addr, data, gas, price, value)
+}
+
+func (self *VMEnv) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(addr, data, gas, price, value)
+ ret, err := exe.Call(addr, caller)
+ self.Gas = exe.Gas
+
+ return ret, err
+}
+func (self *VMEnv) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(caller.Address(), data, gas, price, value)
+ return exe.Call(addr, caller)
+}
+
+func (self *VMEnv) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
+ exe := self.vm(addr, data, gas, price, value)
+ return exe.Create(caller)
+}
diff --git a/cmd/utils/websockets.go b/cmd/utils/websockets.go
index d3ba50e78..29f9b8aeb 100644
--- a/cmd/utils/websockets.go
+++ b/cmd/utils/websockets.go
@@ -1,7 +1,7 @@
package utils
import (
- "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/websocket"
"github.com/ethereum/go-ethereum/xeth"
diff --git a/chain/.gitignore b/core/.gitignore
index f725d58d1..f725d58d1 100644
--- a/chain/.gitignore
+++ b/core/.gitignore
diff --git a/chain/asm.go b/core/asm.go
index 5a2e961ac..a8b3023f4 100644
--- a/chain/asm.go
+++ b/core/asm.go
@@ -1,4 +1,4 @@
-package chain
+package core
import (
"fmt"
diff --git a/chain/block_manager.go b/core/block_manager.go
index e652ad10e..85b4891a5 100644
--- a/chain/block_manager.go
+++ b/core/block_manager.go
@@ -1,21 +1,22 @@
-package chain
+package core
import (
"bytes"
- "container/list"
"errors"
"fmt"
"math/big"
"sync"
"time"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/pow"
+ "github.com/ethereum/go-ethereum/pow/ezp"
"github.com/ethereum/go-ethereum/state"
- "github.com/ethereum/go-ethereum/wire"
)
var statelogger = logger.NewLogger("BLOCK")
@@ -36,13 +37,12 @@ type EthManager interface {
BlockManager() *BlockManager
ChainManager() *ChainManager
TxPool() *TxPool
- Broadcast(msgType wire.MsgType, data []interface{})
PeerCount() int
IsMining() bool
IsListening() bool
- Peers() *list.List
+ Peers() []*p2p.Peer
KeyManager() *crypto.KeyManager
- ClientIdentity() wire.ClientIdentity
+ ClientIdentity() p2p.ClientIdentity
Db() ethutil.Database
EventMux() *event.TypeMux
}
@@ -55,17 +55,9 @@ type BlockManager struct {
// non-persistent key/value memory storage
mem map[string]*big.Int
// Proof of work used for validating
- Pow PoW
- // The ethereum manager interface
- eth EthManager
- // The managed states
- // Transiently state. The trans state isn't ever saved, validated and
- // it could be used for setting account nonces without effecting
- // the main states.
- transState *state.State
- // Mining state. The mining state is used purely and solely by the mining
- // operation.
- miningState *state.State
+ Pow pow.PoW
+
+ txpool *TxPool
// The last attempted block is mainly used for debugging purposes
// This does not have to be a valid block and will be set during
@@ -73,58 +65,43 @@ type BlockManager struct {
lastAttemptedBlock *types.Block
events event.Subscription
+
+ eventMux *event.TypeMux
}
-func NewBlockManager(ethereum EthManager) *BlockManager {
+func NewBlockManager(txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockManager {
sm := &BlockManager{
- mem: make(map[string]*big.Int),
- Pow: &EasyPow{},
- eth: ethereum,
- bc: ethereum.ChainManager(),
+ mem: make(map[string]*big.Int),
+ Pow: ezp.New(),
+ bc: chainManager,
+ eventMux: eventMux,
+ txpool: txpool,
}
- sm.transState = ethereum.ChainManager().CurrentBlock.State().Copy()
- sm.miningState = ethereum.ChainManager().CurrentBlock.State().Copy()
return sm
}
-func (self *BlockManager) Start() {
- statelogger.Debugln("Starting block manager")
-}
-
-func (self *BlockManager) Stop() {
- statelogger.Debugln("Stopping state manager")
-}
-
-func (sm *BlockManager) CurrentState() *state.State {
- return sm.eth.ChainManager().CurrentBlock.State()
-}
-
-func (sm *BlockManager) TransState() *state.State {
- return sm.transState
-}
-
-func (sm *BlockManager) MiningState() *state.State {
- return sm.miningState
-}
-
-func (sm *BlockManager) NewMiningState() *state.State {
- sm.miningState = sm.eth.ChainManager().CurrentBlock.State().Copy()
+func (sm *BlockManager) TransitionState(statedb *state.StateDB, parent, block *types.Block) (receipts types.Receipts, err error) {
+ coinbase := statedb.GetOrNewStateObject(block.Coinbase)
+ coinbase.SetGasPool(block.CalcGasLimit(parent))
- return sm.miningState
-}
+ // Process the transactions on to current block
+ receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), false)
+ if err != nil {
+ return nil, err
+ }
-func (sm *BlockManager) ChainManager() *ChainManager {
- return sm.bc
+ return receipts, nil
}
-func (self *BlockManager) ProcessTransactions(coinbase *state.StateObject, state *state.State, block, parent *types.Block, txs types.Transactions) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) {
+func (self *BlockManager) ApplyTransactions(coinbase *state.StateObject, state *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) {
var (
receipts types.Receipts
handled, unhandled types.Transactions
erroneous types.Transactions
totalUsedGas = big.NewInt(0)
err error
+ cumulativeSum = new(big.Int)
)
done:
@@ -132,13 +109,12 @@ done:
// If we are mining this block and validating we want to set the logs back to 0
state.EmptyLogs()
- txGas := new(big.Int).Set(tx.Gas)
+ txGas := new(big.Int).Set(tx.Gas())
cb := state.GetStateObject(coinbase.Address())
st := NewStateTransition(cb, tx, state, block)
- err = st.TransitionState()
+ _, err = st.TransitionState()
if err != nil {
- statelogger.Infoln(err)
switch {
case IsNonceErr(err):
err = nil // ignore error
@@ -155,17 +131,21 @@ done:
}
}
+ txGas.Sub(txGas, st.gas)
+ cumulativeSum.Add(cumulativeSum, new(big.Int).Mul(txGas, tx.GasPrice()))
+
// Update the state with pending changes
- state.Update()
+ state.Update(txGas)
- txGas.Sub(txGas, st.gas)
cumulative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
receipt := types.NewReceipt(state.Root(), cumulative)
receipt.SetLogs(state.Logs())
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
// Notify all subscribers
- go self.eth.EventMux().Post(TxPostEvent{tx})
+ if !transientProcess {
+ go self.eventMux.Post(TxPostEvent{tx})
+ }
receipts = append(receipts, receipt)
handled = append(handled, tx)
@@ -175,6 +155,7 @@ done:
}
}
+ block.Reward = cumulativeSum
block.GasUsed = totalUsedGas
return receipts, handled, unhandled, erroneous, err
@@ -186,7 +167,7 @@ func (sm *BlockManager) Process(block *types.Block) (td *big.Int, msgs state.Mes
defer sm.mutex.Unlock()
if sm.bc.HasBlock(block.Hash()) {
- return nil, nil, nil
+ return nil, nil, &KnownBlockError{block.Number, block.Hash()}
}
if !sm.bc.HasBlock(block.PrevHash) {
@@ -208,15 +189,22 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
// before that.
defer state.Reset()
- if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
- fmt.Printf("## %x %x ##\n", block.Hash(), block.Number)
+ // Block validation
+ if err = sm.ValidateBlock(block, parent); err != nil {
+ return
}
- receipts, err := sm.ApplyDiff(state, parent, block)
+ receipts, err := sm.TransitionState(state, parent, block)
if err != nil {
return
}
+ rbloom := types.CreateBloom(receipts)
+ if bytes.Compare(rbloom, block.LogsBloom) != 0 {
+ err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
+ return
+ }
+
txSha := types.DeriveSha(block.Transactions())
if bytes.Compare(txSha, block.TxSha) != 0 {
err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha)
@@ -229,25 +217,11 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
return
}
- // Block validation
- if err = sm.ValidateBlock(block, parent); err != nil {
- statelogger.Errorln("validating block:", err)
- return
- }
-
if err = sm.AccumelateRewards(state, block, parent); err != nil {
- statelogger.Errorln("accumulating reward", err)
- return
- }
-
- //block.receipts = receipts // although this isn't necessary it be in the future
- rbloom := types.CreateBloom(receipts)
- if bytes.Compare(rbloom, block.LogsBloom) != 0 {
- err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
return
}
- state.Update()
+ state.Update(ethutil.Big0)
if !block.State().Cmp(state) {
err = fmt.Errorf("invalid merkle root. received=%x got=%x", block.Root(), state.Root())
@@ -264,9 +238,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
chainlogger.Infof("Processed block #%d (%x...)\n", block.Number, block.Hash()[0:4])
- sm.transState = state.Copy()
-
- sm.eth.TxPool().RemoveSet(block.Transactions())
+ sm.txpool.RemoveSet(block.Transactions())
return td, messages, nil
} else {
@@ -274,19 +246,6 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
}
}
-func (sm *BlockManager) ApplyDiff(state *state.State, parent, block *types.Block) (receipts types.Receipts, err error) {
- coinbase := state.GetOrNewStateObject(block.Coinbase)
- coinbase.SetGasPool(block.CalcGasLimit(parent))
-
- // Process the transactions on to current block
- receipts, _, _, _, err = sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions())
- if err != nil {
- return nil, err
- }
-
- return receipts, nil
-}
-
func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
uncleDiff := new(big.Int)
for _, uncle := range block.Uncles {
@@ -295,16 +254,13 @@ func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
// TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty
td := new(big.Int)
- td = td.Add(sm.bc.TD, uncleDiff)
+ td = td.Add(sm.bc.Td(), uncleDiff)
td = td.Add(td, block.Difficulty)
// The new TD will only be accepted if the new difficulty is
// is greater than the previous.
- if td.Cmp(sm.bc.TD) > 0 {
+ if td.Cmp(sm.bc.Td()) > 0 {
return td, true
-
- // Set the new total difficulty back to the block chain
- //sm.bc.SetTotalDifficulty(td)
}
return nil, false
@@ -321,7 +277,7 @@ func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
diff := block.Time - parent.Time
if diff < 0 {
- return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock.Time)
+ return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock().Time)
}
/* XXX
@@ -332,14 +288,14 @@ func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
*/
// Verify the nonce of the block. Return an error if it's not valid
- if !sm.Pow.Verify(block.HashNoNonce(), block.Difficulty, block.Nonce) {
+ if !sm.Pow.Verify(block /*block.HashNoNonce(), block.Difficulty, block.Nonce*/) {
return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Nonce))
}
return nil
}
-func (sm *BlockManager) AccumelateRewards(state *state.State, block, parent *types.Block) error {
+func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent *types.Block) error {
reward := new(big.Int).Set(BlockReward)
knownUncles := ethutil.Set(parent.Uncles)
@@ -368,17 +324,25 @@ func (sm *BlockManager) AccumelateRewards(state *state.State, block, parent *typ
r := new(big.Int)
r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16))
- uncleAccount := state.GetAccount(uncle.Coinbase)
+ uncleAccount := statedb.GetAccount(uncle.Coinbase)
uncleAccount.AddAmount(r)
reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32)))
}
// Get the account associated with the coinbase
- account := state.GetAccount(block.Coinbase)
+ account := statedb.GetAccount(block.Coinbase)
// Reward amount of ether to the coinbase address
account.AddAmount(reward)
+ statedb.Manifest().AddMessage(&state.Message{
+ To: block.Coinbase,
+ Input: nil,
+ Origin: nil,
+ Block: block.Hash(), Timestamp: block.Time, Coinbase: block.Coinbase, Number: block.Number,
+ Value: new(big.Int).Add(reward, block.Reward),
+ })
+
return nil
}
@@ -396,8 +360,7 @@ func (sm *BlockManager) GetMessages(block *types.Block) (messages []*state.Messa
defer state.Reset()
- sm.ApplyDiff(state, parent, block)
-
+ sm.TransitionState(state, parent, block)
sm.AccumelateRewards(state, block, parent)
return state.Manifest().Messages, nil
diff --git a/chain/chain_manager.go b/core/chain_manager.go
index 11e16fa7d..e6268c01e 100644
--- a/chain/chain_manager.go
+++ b/core/chain_manager.go
@@ -1,13 +1,13 @@
-package chain
+package core
import (
- "bytes"
- "container/list"
"fmt"
"math/big"
+ "sync"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
)
@@ -48,32 +48,77 @@ func CalcDifficulty(block, parent *types.Block) *big.Int {
type ChainManager struct {
//eth EthManager
processor types.BlockProcessor
+ eventMux *event.TypeMux
genesisBlock *types.Block
// Last known total difficulty
- TD *big.Int
+ mu sync.RWMutex
+ td *big.Int
+ lastBlockNumber uint64
+ currentBlock *types.Block
+ lastBlockHash []byte
- LastBlockNumber uint64
+ transState *state.StateDB
+}
+
+func (self *ChainManager) Td() *big.Int {
+ self.mu.RLock()
+ defer self.mu.RUnlock()
+
+ return self.td
+}
+
+func (self *ChainManager) LastBlockNumber() uint64 {
+ self.mu.RLock()
+ defer self.mu.RUnlock()
+
+ return self.lastBlockNumber
+}
+
+func (self *ChainManager) LastBlockHash() []byte {
+ self.mu.RLock()
+ defer self.mu.RUnlock()
+
+ return self.lastBlockHash
+}
- CurrentBlock *types.Block
- LastBlockHash []byte
+func (self *ChainManager) CurrentBlock() *types.Block {
+ self.mu.RLock()
+ defer self.mu.RUnlock()
- workingChain *BlockChain
+ return self.currentBlock
}
-func NewChainManager() *ChainManager {
+func NewChainManager(mux *event.TypeMux) *ChainManager {
bc := &ChainManager{}
bc.genesisBlock = types.NewBlockFromBytes(ethutil.Encode(Genesis))
- //bc.eth = ethereum
+ bc.eventMux = mux
bc.setLastBlock()
+ bc.transState = bc.State().Copy()
+
return bc
}
+func (self *ChainManager) Status() (td *big.Int, currentBlock []byte, genesisBlock []byte) {
+ self.mu.RLock()
+ defer self.mu.RUnlock()
+
+ return self.td, self.currentBlock.Hash(), self.Genesis().Hash()
+}
+
func (self *ChainManager) SetProcessor(proc types.BlockProcessor) {
self.processor = proc
}
+func (self *ChainManager) State() *state.StateDB {
+ return self.CurrentBlock().State()
+}
+
+func (self *ChainManager) TransState() *state.StateDB {
+ return self.transState
+}
+
func (bc *ChainManager) setLastBlock() {
data, _ := ethutil.Config.Db.Get([]byte("LastBlock"))
if len(data) != 0 {
@@ -81,27 +126,30 @@ func (bc *ChainManager) setLastBlock() {
AddTestNetFunds(bc.genesisBlock)
block := types.NewBlockFromBytes(data)
- bc.CurrentBlock = block
- bc.LastBlockHash = block.Hash()
- bc.LastBlockNumber = block.Number.Uint64()
+ bc.currentBlock = block
+ bc.lastBlockHash = block.Hash()
+ bc.lastBlockNumber = block.Number.Uint64()
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
- bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
+ bc.td = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
} else {
bc.Reset()
}
- chainlogger.Infof("Last block (#%d) %x\n", bc.LastBlockNumber, bc.CurrentBlock.Hash())
+ chainlogger.Infof("Last block (#%d) %x\n", bc.lastBlockNumber, bc.currentBlock.Hash())
}
// Block creation & chain handling
func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block {
+ bc.mu.RLock()
+ defer bc.mu.RUnlock()
+
var root interface{}
hash := ZeroHash256
if bc.CurrentBlock != nil {
- root = bc.CurrentBlock.Root()
- hash = bc.LastBlockHash
+ root = bc.currentBlock.Root()
+ hash = bc.lastBlockHash
}
block := types.CreateBlock(
@@ -112,13 +160,11 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block {
nil,
"")
- block.MinGasPrice = big.NewInt(10000000000000)
-
- parent := bc.CurrentBlock
+ parent := bc.currentBlock
if parent != nil {
block.Difficulty = CalcDifficulty(block, parent)
- block.Number = new(big.Int).Add(bc.CurrentBlock.Number, ethutil.Big1)
- block.GasLimit = block.CalcGasLimit(bc.CurrentBlock)
+ block.Number = new(big.Int).Add(bc.currentBlock.Number, ethutil.Big1)
+ block.GasLimit = block.CalcGasLimit(bc.currentBlock)
}
@@ -126,31 +172,49 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block {
}
func (bc *ChainManager) Reset() {
+ bc.mu.Lock()
+ defer bc.mu.Unlock()
+
AddTestNetFunds(bc.genesisBlock)
bc.genesisBlock.Trie().Sync()
// Prepare the genesis block
- bc.add(bc.genesisBlock)
- bc.CurrentBlock = bc.genesisBlock
+ bc.write(bc.genesisBlock)
+ bc.insert(bc.genesisBlock)
+ bc.currentBlock = bc.genesisBlock
- bc.SetTotalDifficulty(ethutil.Big("0"))
+ bc.setTotalDifficulty(ethutil.Big("0"))
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
- bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
+ bc.td = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
}
-// Add a block to the chain and record addition information
-func (bc *ChainManager) add(block *types.Block) {
- bc.writeBlockInfo(block)
+func (self *ChainManager) Export() []byte {
+ self.mu.RLock()
+ defer self.mu.RUnlock()
- bc.CurrentBlock = block
- bc.LastBlockHash = block.Hash()
+ chainlogger.Infof("exporting %v blocks...\n", self.currentBlock.Number)
+
+ blocks := make([]*types.Block, int(self.currentBlock.Number.Int64())+1)
+ for block := self.currentBlock; block != nil; block = self.GetBlock(block.PrevHash) {
+ blocks[block.Number.Int64()] = block
+ }
+ return ethutil.Encode(blocks)
+}
+
+func (bc *ChainManager) insert(block *types.Block) {
encodedBlock := block.RlpEncode()
- ethutil.Config.Db.Put(block.Hash(), encodedBlock)
ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock)
+ bc.currentBlock = block
+ bc.lastBlockHash = block.Hash()
+}
- //chainlogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4])
+func (bc *ChainManager) write(block *types.Block) {
+ bc.writeBlockInfo(block)
+
+ encodedBlock := block.RlpEncode()
+ ethutil.Config.Db.Put(block.Hash(), encodedBlock)
}
// Accessors
@@ -164,7 +228,7 @@ func (bc *ChainManager) HasBlock(hash []byte) bool {
return len(data) != 0
}
-func (self *ChainManager) GetChainHashesFromHash(hash []byte, max uint64) (chain [][]byte) {
+func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain [][]byte) {
block := self.GetBlock(hash)
if block == nil {
return
@@ -172,7 +236,6 @@ func (self *ChainManager) GetChainHashesFromHash(hash []byte, max uint64) (chain
// XXX Could be optimised by using a different database which only holds hashes (i.e., linked list)
for i := uint64(0); i < max; i++ {
-
chain = append(chain, block.Hash())
if block.Number.Cmp(ethutil.Big0) <= 0 {
@@ -188,15 +251,6 @@ func (self *ChainManager) GetChainHashesFromHash(hash []byte, max uint64) (chain
func (self *ChainManager) GetBlock(hash []byte) *types.Block {
data, _ := ethutil.Config.Db.Get(hash)
if len(data) == 0 {
- if self.workingChain != nil {
- // Check the temp chain
- for e := self.workingChain.Front(); e != nil; e = e.Next() {
- if bytes.Compare(e.Value.(*link).Block.Hash(), hash) == 0 {
- return e.Value.(*link).Block
- }
- }
- }
-
return nil
}
@@ -204,7 +258,10 @@ func (self *ChainManager) GetBlock(hash []byte) *types.Block {
}
func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
- block := self.CurrentBlock
+ self.mu.RLock()
+ defer self.mu.RUnlock()
+
+ block := self.currentBlock
for ; block != nil; block = self.GetBlock(block.PrevHash) {
if block.Number.Uint64() == num {
break
@@ -218,9 +275,9 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
return block
}
-func (bc *ChainManager) SetTotalDifficulty(td *big.Int) {
+func (bc *ChainManager) setTotalDifficulty(td *big.Int) {
ethutil.Config.Db.Put([]byte("LTD"), td.Bytes())
- bc.TD = td
+ bc.td = td
}
func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) {
@@ -253,8 +310,8 @@ func (bc *ChainManager) BlockInfo(block *types.Block) types.BlockInfo {
// Unexported method for writing extra non-essential block info to the db
func (bc *ChainManager) writeBlockInfo(block *types.Block) {
- bc.LastBlockNumber++
- bi := types.BlockInfo{Number: bc.LastBlockNumber, Hash: block.Hash(), Parent: block.PrevHash, TD: bc.TD}
+ bc.lastBlockNumber++
+ bi := types.BlockInfo{Number: bc.lastBlockNumber, Hash: block.Hash(), Parent: block.PrevHash, TD: bc.td}
// For now we use the block hash with the words "info" appended as key
ethutil.Config.Db.Put(append(block.Hash(), []byte("Info")...), bi.RlpEncode())
@@ -266,103 +323,40 @@ func (bc *ChainManager) Stop() {
}
}
-func (self *ChainManager) NewIterator(startHash []byte) *ChainIterator {
- return &ChainIterator{self, self.GetBlock(startHash)}
-}
-
-// This function assumes you've done your checking. No checking is done at this stage anymore
-func (self *ChainManager) InsertChain(chain *BlockChain, call func(*types.Block, state.Messages)) {
- for e := chain.Front(); e != nil; e = e.Next() {
- link := e.Value.(*link)
-
- self.add(link.Block)
- self.SetTotalDifficulty(link.Td)
-
- call(link.Block, link.Messages)
- }
-
- b, e := chain.Front(), chain.Back()
- if b != nil && e != nil {
- front, back := b.Value.(*link).Block, e.Value.(*link).Block
- chainlogger.Infof("Imported %d blocks. #%v (%x) / %#v (%x)", chain.Len(), front.Number, front.Hash()[0:4], back.Number, back.Hash()[0:4])
- }
-}
-
-func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error) {
- self.workingChain = chain
- defer func() { self.workingChain = nil }()
-
- for e := chain.Front(); e != nil; e = e.Next() {
- var (
- l = e.Value.(*link)
- block = l.Block
- parent = self.GetBlock(block.PrevHash)
- )
-
- if parent == nil {
- err = fmt.Errorf("incoming chain broken on hash %x\n", block.PrevHash[0:4])
- return
- }
-
- var messages state.Messages
- td, messages, err = self.processor.ProcessWithParent(block, parent) //self.eth.BlockManager().ProcessWithParent(block, parent)
+func (self *ChainManager) InsertChain(chain types.Blocks) error {
+ for _, block := range chain {
+ td, messages, err := self.processor.Process(block)
if err != nil {
- chainlogger.Infoln(err)
- chainlogger.Debugf("Block #%v failed (%x...)\n", block.Number, block.Hash()[0:4])
- chainlogger.Debugln(block)
+ if IsKnownBlockErr(err) {
+ continue
+ }
- err = fmt.Errorf("incoming chain failed %v\n", err)
- return
+ chainlogger.Infof("block #%v process failed (%x)\n", block.Number, block.Hash()[:4])
+ chainlogger.Infoln(block)
+ chainlogger.Infoln(err)
+ return err
}
- l.Td = td
- l.Messages = messages
- }
- if td.Cmp(self.TD) <= 0 {
- err = &TDError{td, self.TD}
- return
- }
-
- self.workingChain = nil
-
- return
-}
-
-type link struct {
- Block *types.Block
- Messages state.Messages
- Td *big.Int
-}
-
-type BlockChain struct {
- *list.List
-}
+ self.mu.Lock()
+ {
-func NewChain(blocks types.Blocks) *BlockChain {
- chain := &BlockChain{list.New()}
+ self.write(block)
+ if td.Cmp(self.td) > 0 {
+ if block.Number.Cmp(new(big.Int).Add(self.currentBlock.Number, ethutil.Big1)) < 0 {
+ chainlogger.Infof("Split detected. New head #%v (%x), was #%v (%x)\n", block.Number, block.Hash()[:4], self.currentBlock.Number, self.currentBlock.Hash()[:4])
+ }
- for _, block := range blocks {
- chain.PushBack(&link{block, nil, nil})
- }
+ self.setTotalDifficulty(td)
+ self.insert(block)
+ self.transState = self.currentBlock.State().Copy()
+ }
- return chain
-}
+ }
+ self.mu.Unlock()
-func (self *BlockChain) RlpEncode() []byte {
- dat := make([]interface{}, 0)
- for e := self.Front(); e != nil; e = e.Next() {
- dat = append(dat, e.Value.(*link).Block.RlpData())
+ self.eventMux.Post(NewBlockEvent{block})
+ self.eventMux.Post(messages)
}
- return ethutil.Encode(dat)
-}
-
-type ChainIterator struct {
- cm *ChainManager
- block *types.Block // current block in the iterator
-}
-
-func (self *ChainIterator) Prev() *types.Block {
- self.block = self.cm.GetBlock(self.block.PrevHash)
- return self.block
+ return nil
}
diff --git a/core/chain_manager_test.go b/core/chain_manager_test.go
new file mode 100644
index 000000000..52be8b0ea
--- /dev/null
+++ b/core/chain_manager_test.go
@@ -0,0 +1,77 @@
+package core
+
+import (
+ "fmt"
+ "path"
+ "runtime"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/event"
+ //logpkg "github.com/ethereum/go-ethereum/logger"
+)
+
+//var Logger logpkg.LogSystem
+//var Log = logpkg.NewLogger("TEST")
+
+func init() {
+ runtime.GOMAXPROCS(runtime.NumCPU())
+ //Logger = logpkg.NewStdLogSystem(os.Stdout, log.LstdFlags, logpkg.InfoLevel)
+ //logpkg.AddLogSystem(Logger)
+
+ ethutil.ReadConfig("/tmp/ethtest", "/tmp/ethtest", "ETH")
+
+ db, err := ethdb.NewMemDatabase()
+ if err != nil {
+ panic("Could not create mem-db, failing")
+ }
+ ethutil.Config.Db = db
+}
+
+func loadChain(fn string, t *testing.T) types.Blocks {
+ c1, err := ethutil.ReadAllFile(path.Join("..", "_data", fn))
+ if err != nil {
+ fmt.Println(err)
+ t.FailNow()
+ }
+ value := ethutil.NewValueFromBytes([]byte(c1))
+ blocks := make(types.Blocks, value.Len())
+ it := value.NewIterator()
+ for it.Next() {
+ blocks[it.Idx()] = types.NewBlockFromRlpValue(it.Value())
+ }
+
+ return blocks
+}
+
+func insertChain(done chan bool, chainMan *ChainManager, chain types.Blocks, t *testing.T) {
+ err := chainMan.InsertChain(chain)
+ if err != nil {
+ fmt.Println(err)
+ t.FailNow()
+ }
+ done <- true
+}
+
+func TestChainInsertions(t *testing.T) {
+ chain1 := loadChain("chain1", t)
+ chain2 := loadChain("chain2", t)
+ var eventMux event.TypeMux
+ chainMan := NewChainManager(&eventMux)
+ txPool := NewTxPool(chainMan, nil, &eventMux)
+ blockMan := NewBlockManager(txPool, chainMan, &eventMux)
+ chainMan.SetProcessor(blockMan)
+
+ const max = 2
+ done := make(chan bool, max)
+
+ go insertChain(done, chainMan, chain1, t)
+ go insertChain(done, chainMan, chain2, t)
+
+ for i := 0; i < max; i++ {
+ <-done
+ }
+ fmt.Println(chainMan.CurrentBlock())
+}
diff --git a/chain/dagger.go b/core/dagger.go
index f7e2229e9..3039d8995 100644
--- a/chain/dagger.go
+++ b/core/dagger.go
@@ -1,4 +1,4 @@
-package chain
+package core
import (
"hash"
@@ -6,8 +6,6 @@ import (
"math/rand"
"time"
- "github.com/ethereum/go-ethereum/chain/types"
- "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/obscuren/sha3"
@@ -15,85 +13,6 @@ import (
var powlogger = logger.NewLogger("POW")
-type PoW interface {
- Search(block *types.Block, stop <-chan struct{}) []byte
- Verify(hash []byte, diff *big.Int, nonce []byte) bool
- GetHashrate() int64
- Turbo(bool)
-}
-
-type EasyPow struct {
- hash *big.Int
- HashRate int64
- turbo bool
-}
-
-func (pow *EasyPow) GetHashrate() int64 {
- return pow.HashRate
-}
-
-func (pow *EasyPow) Turbo(on bool) {
- pow.turbo = on
-}
-
-func (pow *EasyPow) Search(block *types.Block, stop <-chan struct{}) []byte {
- r := rand.New(rand.NewSource(time.Now().UnixNano()))
- hash := block.HashNoNonce()
- diff := block.Difficulty
- i := int64(0)
- start := time.Now().UnixNano()
- t := time.Now()
-
- for {
- select {
- case <-stop:
- powlogger.Infoln("Breaking from mining")
- pow.HashRate = 0
- return nil
- default:
- i++
-
- if time.Since(t) > (1 * time.Second) {
- elapsed := time.Now().UnixNano() - start
- hashes := ((float64(1e9) / float64(elapsed)) * float64(i)) / 1000
- pow.HashRate = int64(hashes)
- powlogger.Infoln("Hashing @", pow.HashRate, "khash")
-
- t = time.Now()
- }
-
- sha := crypto.Sha3(big.NewInt(r.Int63()).Bytes())
- if pow.Verify(hash, diff, sha) {
- return sha
- }
- }
-
- if !pow.turbo {
- time.Sleep(20 * time.Microsecond)
- }
- }
-
- return nil
-}
-
-func (pow *EasyPow) Verify(hash []byte, diff *big.Int, nonce []byte) bool {
- sha := sha3.NewKeccak256()
-
- d := append(hash, nonce...)
- sha.Write(d)
-
- v := ethutil.BigPow(2, 256)
- ret := new(big.Int).Div(v, diff)
-
- res := new(big.Int)
- res.SetBytes(sha.Sum(nil))
-
- return res.Cmp(ret) == -1
-}
-
-func (pow *EasyPow) SetHash(hash *big.Int) {
-}
-
type Dagger struct {
hash *big.Int
xn *big.Int
diff --git a/chain/dagger_test.go b/core/dagger_test.go
index b40cd9742..e80064e6b 100644
--- a/chain/dagger_test.go
+++ b/core/dagger_test.go
@@ -1,4 +1,4 @@
-package chain
+package core
import (
"math/big"
diff --git a/chain/error.go b/core/error.go
index 540eda95a..11d8c1653 100644
--- a/chain/error.go
+++ b/core/error.go
@@ -1,4 +1,4 @@
-package chain
+package core
import (
"fmt"
@@ -126,3 +126,16 @@ func IsTDError(e error) bool {
_, ok := e.(*TDError)
return ok
}
+
+type KnownBlockError struct {
+ number *big.Int
+ hash []byte
+}
+
+func (self *KnownBlockError) Error() string {
+ return fmt.Sprintf("block %v already known (%x)", self.number, self.hash[0:4])
+}
+func IsKnownBlockErr(e error) bool {
+ _, ok := e.(*KnownBlockError)
+ return ok
+}
diff --git a/chain/events.go b/core/events.go
index 06ab6be79..fe106da49 100644
--- a/chain/events.go
+++ b/core/events.go
@@ -1,6 +1,6 @@
-package chain
+package core
-import "github.com/ethereum/go-ethereum/chain/types"
+import "github.com/ethereum/go-ethereum/core/types"
// TxPreEvent is posted when a transaction enters the transaction pool.
type TxPreEvent struct{ Tx *types.Transaction }
@@ -10,3 +10,6 @@ type TxPostEvent struct{ Tx *types.Transaction }
// NewBlockEvent is posted when a block has been imported.
type NewBlockEvent struct{ Block *types.Block }
+
+// NewMinedBlockEvent is posted when a block has been imported.
+type NewMinedBlockEvent struct{ Block *types.Block }
diff --git a/core/execution.go b/core/execution.go
new file mode 100644
index 000000000..cd98746c4
--- /dev/null
+++ b/core/execution.go
@@ -0,0 +1,76 @@
+package core
+
+import (
+ "fmt"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/state"
+ "github.com/ethereum/go-ethereum/vm"
+)
+
+type Execution struct {
+ vm vm.VirtualMachine
+ address, input []byte
+ Gas, price, value *big.Int
+ object *state.StateObject
+ SkipTransfer bool
+}
+
+func NewExecution(env vm.Environment, address, input []byte, gas, gasPrice, value *big.Int) *Execution {
+ evm := vm.New(env, vm.DebugVmTy)
+
+ return &Execution{vm: evm, address: address, input: input, Gas: gas, price: gasPrice, value: value}
+}
+
+func (self *Execution) Addr() []byte {
+ return self.address
+}
+
+func (self *Execution) Call(codeAddr []byte, caller vm.ClosureRef) ([]byte, error) {
+ // Retrieve the executing code
+ code := self.vm.Env().State().GetCode(codeAddr)
+
+ return self.exec(code, codeAddr, caller)
+}
+
+func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret []byte, err error) {
+ env := self.vm.Env()
+ chainlogger.Debugf("pre state %x\n", env.State().Root())
+
+ if self.vm.Env().Depth() == vm.MaxCallDepth {
+ // Consume all gas (by not returning it) and return a depth error
+ return nil, vm.DepthError{}
+ }
+
+ from, to := env.State().GetStateObject(caller.Address()), env.State().GetOrNewStateObject(self.address)
+ // Skipping transfer is used on testing for the initial call
+ if !self.SkipTransfer {
+ err = env.Transfer(from, to, self.value)
+ if err != nil {
+ caller.ReturnGas(self.Gas, self.price)
+
+ err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, from.Balance)
+ return
+ }
+ }
+
+ snapshot := env.State().Copy()
+ defer func() {
+ if /*vm.IsDepthErr(err) ||*/ vm.IsOOGErr(err) {
+ env.State().Set(snapshot)
+ }
+ chainlogger.Debugf("post state %x\n", env.State().Root())
+ }()
+
+ self.object = to
+ ret, err = self.vm.Run(to, caller, code, self.value, self.Gas, self.price, self.input)
+
+ return
+}
+
+func (self *Execution) Create(caller vm.ClosureRef) (ret []byte, err error, account *state.StateObject) {
+ ret, err = self.exec(self.input, nil, caller)
+ account = self.vm.Env().State().GetStateObject(self.address)
+
+ return
+}
diff --git a/chain/fees.go b/core/fees.go
index 4df6d365d..bbce01b84 100644
--- a/chain/fees.go
+++ b/core/fees.go
@@ -1,4 +1,4 @@
-package chain
+package core
import (
"math/big"
diff --git a/chain/filter.go b/core/filter.go
index fd8adaa8f..fb992782d 100644
--- a/chain/filter.go
+++ b/core/filter.go
@@ -1,11 +1,11 @@
-package chain
+package core
import (
"bytes"
"math"
"math/big"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
)
@@ -78,11 +78,11 @@ func (self *Filter) SetSkip(skip int) {
func (self *Filter) Find() []*state.Message {
var earliestBlockNo uint64 = uint64(self.earliest)
if self.earliest == -1 {
- earliestBlockNo = self.eth.ChainManager().CurrentBlock.Number.Uint64()
+ earliestBlockNo = self.eth.ChainManager().CurrentBlock().Number.Uint64()
}
var latestBlockNo uint64 = uint64(self.latest)
if self.latest == -1 {
- latestBlockNo = self.eth.ChainManager().CurrentBlock.Number.Uint64()
+ latestBlockNo = self.eth.ChainManager().CurrentBlock().Number.Uint64()
}
var (
@@ -176,7 +176,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
var fromIncluded, toIncluded bool
if len(self.from) > 0 {
for _, from := range self.from {
- if types.BloomLookup(block.LogsBloom, from) {
+ if types.BloomLookup(block.LogsBloom, from) || bytes.Equal(block.Coinbase, from) {
fromIncluded = true
break
}
@@ -187,7 +187,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
if len(self.to) > 0 {
for _, to := range self.to {
- if types.BloomLookup(block.LogsBloom, ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) {
+ if types.BloomLookup(block.LogsBloom, ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) || bytes.Equal(block.Coinbase, to) {
toIncluded = true
break
}
diff --git a/core/filter_test.go b/core/filter_test.go
new file mode 100644
index 000000000..9a8bc9592
--- /dev/null
+++ b/core/filter_test.go
@@ -0,0 +1 @@
+package core
diff --git a/chain/genesis.go b/core/genesis.go
index 14117a82c..707154759 100644
--- a/chain/genesis.go
+++ b/core/genesis.go
@@ -1,4 +1,4 @@
-package chain
+package core
import (
"math/big"
@@ -37,8 +37,6 @@ var GenesisHeader = []interface{}{
big.NewInt(131072),
// Number
ethutil.Big0,
- // Block minimum gas price
- ethutil.Big0,
// Block upper gas bound
big.NewInt(1000000),
// Block gas used
diff --git a/chain/helper_test.go b/core/helper_test.go
index 8c7532111..b340144fd 100644
--- a/chain/helper_test.go
+++ b/core/helper_test.go
@@ -1,10 +1,10 @@
-package chain
+package core
import (
"container/list"
"fmt"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
diff --git a/core/simple_pow.go b/core/simple_pow.go
new file mode 100644
index 000000000..9a8bc9592
--- /dev/null
+++ b/core/simple_pow.go
@@ -0,0 +1 @@
+package core
diff --git a/core/state_transition.go b/core/state_transition.go
new file mode 100644
index 000000000..9e81ddf28
--- /dev/null
+++ b/core/state_transition.go
@@ -0,0 +1,232 @@
+package core
+
+import (
+ "fmt"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/state"
+ "github.com/ethereum/go-ethereum/vm"
+)
+
+/*
+ * The State transitioning model
+ *
+ * A state transition is a change made when a transaction is applied to the current world state
+ * The state transitioning model does all all the necessary work to work out a valid new state root.
+ * 1) Nonce handling
+ * 2) Pre pay / buy gas of the coinbase (miner)
+ * 3) Create a new state object if the recipient is \0*32
+ * 4) Value transfer
+ * == If contract creation ==
+ * 4a) Attempt to run transaction data
+ * 4b) If valid, use result as code for the new state object
+ * == end ==
+ * 5) Run Script section
+ * 6) Derive new state root
+ */
+type StateTransition struct {
+ coinbase, receiver []byte
+ msg Message
+ gas, gasPrice *big.Int
+ initialGas *big.Int
+ value *big.Int
+ data []byte
+ state *state.StateDB
+ block *types.Block
+
+ cb, rec, sen *state.StateObject
+
+ Env vm.Environment
+}
+
+type Message interface {
+ Hash() []byte
+
+ From() []byte
+ To() []byte
+
+ GasPrice() *big.Int
+ Gas() *big.Int
+ Value() *big.Int
+
+ Nonce() uint64
+ Data() []byte
+}
+
+func AddressFromMessage(msg Message) []byte {
+ // Generate a new address
+ return crypto.Sha3(ethutil.NewValue([]interface{}{msg.From(), msg.Nonce()}).Encode())[12:]
+}
+
+func MessageCreatesContract(msg Message) bool {
+ return len(msg.To()) == 0
+}
+
+func MessageGasValue(msg Message) *big.Int {
+ return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
+}
+
+func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition {
+ return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), new(big.Int), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil}
+}
+
+func (self *StateTransition) VmEnv() vm.Environment {
+ if self.Env == nil {
+ self.Env = NewEnv(self.state, self.msg, self.block)
+ }
+
+ return self.Env
+}
+
+func (self *StateTransition) Coinbase() *state.StateObject {
+ return self.state.GetOrNewStateObject(self.coinbase)
+}
+func (self *StateTransition) From() *state.StateObject {
+ return self.state.GetOrNewStateObject(self.msg.From())
+}
+func (self *StateTransition) To() *state.StateObject {
+ if self.msg != nil && MessageCreatesContract(self.msg) {
+ return nil
+ }
+ return self.state.GetOrNewStateObject(self.msg.To())
+}
+
+func (self *StateTransition) UseGas(amount *big.Int) error {
+ if self.gas.Cmp(amount) < 0 {
+ return OutOfGasError()
+ }
+ self.gas.Sub(self.gas, amount)
+
+ return nil
+}
+
+func (self *StateTransition) AddGas(amount *big.Int) {
+ self.gas.Add(self.gas, amount)
+}
+
+func (self *StateTransition) BuyGas() error {
+ var err error
+
+ sender := self.From()
+ if sender.Balance().Cmp(MessageGasValue(self.msg)) < 0 {
+ return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", MessageGasValue(self.msg), sender.Balance())
+ }
+
+ coinbase := self.Coinbase()
+ err = coinbase.BuyGas(self.msg.Gas(), self.msg.GasPrice())
+ if err != nil {
+ return err
+ }
+
+ self.AddGas(self.msg.Gas())
+ self.initialGas.Set(self.msg.Gas())
+ sender.SubAmount(MessageGasValue(self.msg))
+
+ return nil
+}
+
+func (self *StateTransition) preCheck() (err error) {
+ var (
+ msg = self.msg
+ sender = self.From()
+ )
+
+ // Make sure this transaction's nonce is correct
+ if sender.Nonce != msg.Nonce() {
+ return NonceError(msg.Nonce(), sender.Nonce)
+ }
+
+ // Pre-pay gas / Buy gas of the coinbase account
+ if err = self.BuyGas(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (self *StateTransition) TransitionState() (ret []byte, err error) {
+ statelogger.Debugf("(~) %x\n", self.msg.Hash())
+
+ // XXX Transactions after this point are considered valid.
+ if err = self.preCheck(); err != nil {
+ return
+ }
+
+ var (
+ msg = self.msg
+ sender = self.From()
+ )
+
+ defer self.RefundGas()
+
+ // Increment the nonce for the next transaction
+ sender.Nonce += 1
+
+ // Transaction gas
+ if err = self.UseGas(vm.GasTx); err != nil {
+ return
+ }
+
+ // Pay data gas
+ var dgas int64
+ for _, byt := range self.data {
+ if byt != 0 {
+ dgas += vm.GasData.Int64()
+ } else {
+ dgas += 1 // This is 1/5. If GasData changes this fails
+ }
+ }
+ if err = self.UseGas(big.NewInt(dgas)); err != nil {
+ return
+ }
+
+ vmenv := self.VmEnv()
+ var ref vm.ClosureRef
+ if MessageCreatesContract(msg) {
+ self.rec = MakeContract(msg, self.state)
+
+ ret, err, ref = vmenv.Create(sender, self.rec.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
+ ref.SetCode(ret)
+ } else {
+ ret, err = vmenv.Call(self.From(), self.To().Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
+ }
+ if err != nil {
+ statelogger.Debugln(err)
+ }
+
+ return
+}
+
+// Converts an transaction in to a state object
+func MakeContract(msg Message, state *state.StateDB) *state.StateObject {
+ addr := AddressFromMessage(msg)
+
+ contract := state.GetOrNewStateObject(addr)
+ contract.InitCode = msg.Data()
+
+ return contract
+}
+
+func (self *StateTransition) RefundGas() {
+ coinbaseSub := new(big.Int).Set(self.gas)
+ uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2)
+ for addr, ref := range self.state.Refunds() {
+ refund := ethutil.BigMin(uhalf, ref)
+ coinbaseSub.Add(self.gas, refund)
+ self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice()))
+ }
+
+ coinbase, sender := self.Coinbase(), self.From()
+ coinbase.RefundGas(coinbaseSub, self.msg.GasPrice())
+
+ // Return remaining gas
+ remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice())
+ sender.AddAmount(remaining)
+}
+
+func (self *StateTransition) GasUsed() *big.Int {
+ return new(big.Int).Sub(self.initialGas, self.gas)
+}
diff --git a/chain/transaction_pool.go b/core/transaction_pool.go
index ae96b0251..1149d4cfb 100644
--- a/chain/transaction_pool.go
+++ b/core/transaction_pool.go
@@ -1,4 +1,4 @@
-package chain
+package core
import (
"bytes"
@@ -7,10 +7,10 @@ import (
"math/big"
"sync"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
- "github.com/ethereum/go-ethereum/wire"
)
var txplogger = logger.NewLogger("TXP")
@@ -18,7 +18,9 @@ var txplogger = logger.NewLogger("TXP")
const txPoolQueueSize = 50
type TxPoolHook chan *types.Transaction
-type TxMsgTy byte
+type TxMsg struct {
+ Tx *types.Transaction
+}
const (
minGasPrice = 1000000
@@ -26,11 +28,6 @@ const (
var MinGasPrice = big.NewInt(10000000000000)
-type TxMsg struct {
- Tx *types.Transaction
- Type TxMsgTy
-}
-
func EachTx(pool *list.List, it func(*types.Transaction, *list.Element) bool) {
for e := pool.Front(); e != nil; e = e.Next() {
if it(e.Value.(*types.Transaction), e) {
@@ -61,7 +58,6 @@ type TxProcessor interface {
// pool is being drained or synced for whatever reason the transactions
// will simple queue up and handled when the mutex is freed.
type TxPool struct {
- Ethereum EthManager
// The mutex for accessing the Tx pool.
mutex sync.Mutex
// Queueing channel for reading and writing incoming
@@ -75,14 +71,18 @@ type TxPool struct {
SecondaryProcessor TxProcessor
subscribers []chan TxMsg
+
+ chainManager *ChainManager
+ eventMux *event.TypeMux
}
-func NewTxPool(ethereum EthManager) *TxPool {
+func NewTxPool(chainManager *ChainManager, eventMux *event.TypeMux) *TxPool {
return &TxPool{
- pool: list.New(),
- queueChan: make(chan *types.Transaction, txPoolQueueSize),
- quit: make(chan bool),
- Ethereum: ethereum,
+ pool: list.New(),
+ queueChan: make(chan *types.Transaction, txPoolQueueSize),
+ quit: make(chan bool),
+ chainManager: chainManager,
+ eventMux: eventMux,
}
}
@@ -94,45 +94,39 @@ func (pool *TxPool) addTransaction(tx *types.Transaction) {
pool.pool.PushBack(tx)
// Broadcast the transaction to the rest of the peers
- pool.Ethereum.Broadcast(wire.MsgTxTy, []interface{}{tx.RlpData()})
+ pool.eventMux.Post(TxPreEvent{tx})
}
func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
// Get the last block so we can retrieve the sender and receiver from
// the merkle trie
- block := pool.Ethereum.ChainManager().CurrentBlock
+ block := pool.chainManager.CurrentBlock
// Something has gone horribly wrong if this happens
if block == nil {
- return fmt.Errorf("[TXPL] No last block on the block chain")
+ return fmt.Errorf("No last block on the block chain")
}
- if len(tx.Recipient) != 0 && len(tx.Recipient) != 20 {
- return fmt.Errorf("[TXPL] Invalid recipient. len = %d", len(tx.Recipient))
+ if len(tx.To()) != 0 && len(tx.To()) != 20 {
+ return fmt.Errorf("Invalid recipient. len = %d", len(tx.To()))
}
- if tx.GasPrice.Cmp(MinGasPrice) < 0 {
- return fmt.Errorf("Gas price to low. Require %v > Got %v", MinGasPrice, tx.GasPrice)
+ v, _, _ := tx.Curve()
+ if v > 28 || v < 27 {
+ return fmt.Errorf("tx.v != (28 || 27)")
}
// Get the sender
- //sender := pool.Ethereum.BlockManager().procState.GetAccount(tx.Sender())
- senderAddr := tx.Sender()
+ senderAddr := tx.From()
if senderAddr == nil {
- return fmt.Errorf("Invalid sender")
+ return fmt.Errorf("invalid sender")
}
- sender := pool.Ethereum.BlockManager().CurrentState().GetAccount(senderAddr)
+ sender := pool.chainManager.State().GetAccount(senderAddr)
- totAmount := new(big.Int).Set(tx.Value)
+ totAmount := new(big.Int).Set(tx.Value())
// Make sure there's enough in the sender's account. Having insufficient
// funds won't invalidate this transaction but simple ignores it.
if sender.Balance().Cmp(totAmount) < 0 {
- return fmt.Errorf("[TXPL] Insufficient amount in sender's (%x) account", tx.Sender())
- }
-
- if tx.IsContract() {
- if tx.GasPrice.Cmp(big.NewInt(minGasPrice)) < 0 {
- return fmt.Errorf("[TXPL] Gasprice too low, %s given should be at least %d.", tx.GasPrice, minGasPrice)
- }
+ return fmt.Errorf("Insufficient amount in sender's (%x) account", tx.From())
}
// Increment the nonce making each tx valid only once to prevent replay
@@ -141,47 +135,46 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
return nil
}
-func (pool *TxPool) queueHandler() {
-out:
- for {
- select {
- case tx := <-pool.queueChan:
- hash := tx.Hash()
- foundTx := FindTx(pool.pool, func(tx *types.Transaction, e *list.Element) bool {
- return bytes.Compare(tx.Hash(), hash) == 0
- })
+func (self *TxPool) Add(tx *types.Transaction) error {
+ hash := tx.Hash()
+ foundTx := FindTx(self.pool, func(tx *types.Transaction, e *list.Element) bool {
+ return bytes.Compare(tx.Hash(), hash) == 0
+ })
- if foundTx != nil {
- break
- }
+ if foundTx != nil {
+ return fmt.Errorf("Known transaction (%x)", hash[0:4])
+ }
- // Validate the transaction
- err := pool.ValidateTransaction(tx)
- if err != nil {
- txplogger.Debugln("Validating Tx failed", err)
- } else {
- // Call blocking version.
- pool.addTransaction(tx)
+ err := self.ValidateTransaction(tx)
+ if err != nil {
+ return err
+ }
- tmp := make([]byte, 4)
- copy(tmp, tx.Recipient)
+ self.addTransaction(tx)
- txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tmp, tx.Value, tx.Hash())
+ txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.From()[:4], tx.To()[:4], tx.Value, tx.Hash())
- // Notify the subscribers
- pool.Ethereum.EventMux().Post(TxPreEvent{tx})
- }
- case <-pool.quit:
- break out
- }
- }
+ // Notify the subscribers
+ go self.eventMux.Post(TxPreEvent{tx})
+
+ return nil
}
-func (pool *TxPool) QueueTransaction(tx *types.Transaction) {
- pool.queueChan <- tx
+func (self *TxPool) Size() int {
+ return self.pool.Len()
}
-func (pool *TxPool) CurrentTransactions() []*types.Transaction {
+func (self *TxPool) AddTransactions(txs []*types.Transaction) {
+ for _, tx := range txs {
+ if err := self.Add(tx); err != nil {
+ txplogger.Infoln(err)
+ } else {
+ txplogger.Infof("tx %x\n", tx.Hash()[0:4])
+ }
+ }
+}
+
+func (pool *TxPool) GetTransactions() []*types.Transaction {
pool.mutex.Lock()
defer pool.mutex.Unlock()
@@ -198,15 +191,15 @@ func (pool *TxPool) CurrentTransactions() []*types.Transaction {
return txList
}
-func (pool *TxPool) RemoveInvalid(state *state.State) {
+func (pool *TxPool) RemoveInvalid(state *state.StateDB) {
pool.mutex.Lock()
defer pool.mutex.Unlock()
for e := pool.pool.Front(); e != nil; e = e.Next() {
tx := e.Value.(*types.Transaction)
- sender := state.GetAccount(tx.Sender())
+ sender := state.GetAccount(tx.From())
err := pool.ValidateTransaction(tx)
- if err != nil || sender.Nonce >= tx.Nonce {
+ if err != nil || sender.Nonce >= tx.Nonce() {
pool.pool.Remove(e)
}
}
@@ -228,7 +221,7 @@ func (self *TxPool) RemoveSet(txs types.Transactions) {
}
func (pool *TxPool) Flush() []*types.Transaction {
- txList := pool.CurrentTransactions()
+ txList := pool.GetTransactions()
// Recreate a new list all together
// XXX Is this the fastest way?
@@ -238,12 +231,10 @@ func (pool *TxPool) Flush() []*types.Transaction {
}
func (pool *TxPool) Start() {
- go pool.queueHandler()
+ //go pool.queueHandler()
}
func (pool *TxPool) Stop() {
- close(pool.quit)
-
pool.Flush()
txplogger.Infoln("Stopped")
diff --git a/chain/types/block.go b/core/types/block.go
index b311433e3..2d889f35f 100644
--- a/chain/types/block.go
+++ b/core/types/block.go
@@ -77,15 +77,13 @@ type Block struct {
Coinbase []byte
// Block Trie state
//state *ethutil.Trie
- state *state.State
+ state *state.StateDB
// Difficulty for the current block
Difficulty *big.Int
// Creation time
Time int64
// The block number
Number *big.Int
- // Minimum Gas Price
- MinGasPrice *big.Int
// Gas limit
GasLimit *big.Int
// Gas used
@@ -99,6 +97,8 @@ type Block struct {
receipts Receipts
TxSha, ReceiptSha []byte
LogsBloom []byte
+
+ Reward *big.Int
}
func NewBlockFromBytes(raw []byte) *Block {
@@ -124,16 +124,15 @@ func CreateBlock(root interface{},
extra string) *Block {
block := &Block{
- PrevHash: prevHash,
- Coinbase: base,
- Difficulty: Difficulty,
- Nonce: Nonce,
- Time: time.Now().Unix(),
- Extra: extra,
- UncleSha: nil,
- GasUsed: new(big.Int),
- MinGasPrice: new(big.Int),
- GasLimit: new(big.Int),
+ PrevHash: prevHash,
+ Coinbase: base,
+ Difficulty: Difficulty,
+ Nonce: Nonce,
+ Time: time.Now().Unix(),
+ Extra: extra,
+ UncleSha: nil,
+ GasUsed: new(big.Int),
+ GasLimit: new(big.Int),
}
block.SetUncles([]*Block{})
@@ -152,7 +151,7 @@ func (block *Block) HashNoNonce() []byte {
return crypto.Sha3(ethutil.Encode(block.miningHeader()))
}
-func (block *Block) State() *state.State {
+func (block *Block) State() *state.StateDB {
return block.state
}
@@ -300,12 +299,11 @@ func (self *Block) setHeader(header *ethutil.Value) {
self.LogsBloom = header.Get(6).Bytes()
self.Difficulty = header.Get(7).BigInt()
self.Number = header.Get(8).BigInt()
- self.MinGasPrice = header.Get(9).BigInt()
- self.GasLimit = header.Get(10).BigInt()
- self.GasUsed = header.Get(11).BigInt()
- self.Time = int64(header.Get(12).BigInt().Uint64())
- self.Extra = header.Get(13).Str()
- self.Nonce = header.Get(14).Bytes()
+ self.GasLimit = header.Get(9).BigInt()
+ self.GasUsed = header.Get(10).BigInt()
+ self.Time = int64(header.Get(11).BigInt().Uint64())
+ self.Extra = header.Get(12).Str()
+ self.Nonce = header.Get(13).Bytes()
}
func NewUncleBlockFromValue(header *ethutil.Value) *Block {
@@ -351,8 +349,6 @@ func (block *Block) miningHeader() []interface{} {
block.Difficulty,
// The block number
block.Number,
- // Block minimum gas price
- block.MinGasPrice,
// Block upper gas bound
block.GasLimit,
// Block gas used
@@ -380,7 +376,6 @@ func (block *Block) String() string {
Bloom: %x
Difficulty: %v
Number: %v
- MinGas: %v
MaxLimit: %v
GasUsed: %v
Time: %v
@@ -399,7 +394,6 @@ func (block *Block) String() string {
block.LogsBloom,
block.Difficulty,
block.Number,
- block.MinGasPrice,
block.GasLimit,
block.GasUsed,
block.Time,
@@ -415,5 +409,8 @@ func (self *Block) Size() ethutil.StorageSize {
// Implement RlpEncodable
func (self *Block) RlpData() interface{} {
- return self.Value().Val
+ return []interface{}{self.header(), self.transactions, self.rlpUncles()}
}
+
+// Implement pow.Block
+func (self *Block) N() []byte { return self.Nonce }
diff --git a/chain/types/bloom9.go b/core/types/bloom9.go
index 626711cca..c1841e553 100644
--- a/chain/types/bloom9.go
+++ b/core/types/bloom9.go
@@ -11,27 +11,25 @@ import (
func CreateBloom(receipts Receipts) []byte {
bin := new(big.Int)
for _, receipt := range receipts {
- bin.Or(bin, logsBloom(receipt.logs))
+ bin.Or(bin, LogsBloom(receipt.logs))
}
return ethutil.LeftPadBytes(bin.Bytes(), 64)
}
-func logsBloom(logs state.Logs) *big.Int {
+func LogsBloom(logs state.Logs) *big.Int {
bin := new(big.Int)
for _, log := range logs {
- data := [][]byte{log.Address}
- for _, topic := range log.Topics {
- data = append(data, topic)
+ data := make([][]byte, len(log.Topics())+1)
+ data[0] = log.Address()
+
+ for i, topic := range log.Topics() {
+ data[i+1] = topic
}
for _, b := range data {
bin.Or(bin, ethutil.BigD(bloom9(crypto.Sha3(b)).Bytes()))
}
-
- //if log.Data != nil {
- // data = append(data, log.Data)
- //}
}
return bin
diff --git a/chain/types/bloom9_test.go b/core/types/bloom9_test.go
index 74e00cac6..74e00cac6 100644
--- a/chain/types/bloom9_test.go
+++ b/core/types/bloom9_test.go
diff --git a/chain/types/common.go b/core/types/common.go
index ae0e7c3fa..ba88b77e1 100644
--- a/chain/types/common.go
+++ b/core/types/common.go
@@ -2,9 +2,10 @@ package types
import (
"math/big"
+
"github.com/ethereum/go-ethereum/state"
)
type BlockProcessor interface {
- ProcessWithParent(*Block, *Block) (*big.Int, state.Messages, error)
+ Process(*Block) (*big.Int, state.Messages, error)
}
diff --git a/chain/types/derive_sha.go b/core/types/derive_sha.go
index 1897ff198..1897ff198 100644
--- a/chain/types/derive_sha.go
+++ b/core/types/derive_sha.go
diff --git a/chain/types/receipt.go b/core/types/receipt.go
index 25fa8fb07..bac64e41d 100644
--- a/chain/types/receipt.go
+++ b/core/types/receipt.go
@@ -64,5 +64,18 @@ func (self *Receipt) String() string {
type Receipts []*Receipt
+func (self Receipts) RlpData() interface{} {
+ data := make([]interface{}, len(self))
+ for i, receipt := range self {
+ data[i] = receipt.RlpData()
+ }
+
+ return data
+}
+
+func (self Receipts) RlpEncode() []byte {
+ return ethutil.Encode(self.RlpData())
+}
+
func (self Receipts) Len() int { return len(self) }
func (self Receipts) GetRlp(i int) []byte { return ethutil.Rlp(self[i]) }
diff --git a/chain/types/transaction.go b/core/types/transaction.go
index 5599512f6..95a256a76 100644
--- a/chain/types/transaction.go
+++ b/core/types/transaction.go
@@ -6,37 +6,30 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/state"
"github.com/obscuren/secp256k1-go"
)
-var ContractAddr = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-
func IsContractAddr(addr []byte) bool {
return len(addr) == 0
- //return bytes.Compare(addr, ContractAddr) == 0
}
type Transaction struct {
- Nonce uint64
- Recipient []byte
- Value *big.Int
- Gas *big.Int
- GasPrice *big.Int
- Data []byte
+ nonce uint64
+ recipient []byte
+ value *big.Int
+ gas *big.Int
+ gasPrice *big.Int
+ data []byte
v byte
r, s []byte
-
- // Indicates whether this tx is a contract creation transaction
- contractCreation bool
}
func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction {
- return &Transaction{Recipient: nil, Value: value, Gas: gas, GasPrice: gasPrice, Data: script, contractCreation: true}
+ return &Transaction{recipient: nil, value: value, gas: gas, gasPrice: gasPrice, data: script}
}
func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction {
- return &Transaction{Recipient: to, Value: value, GasPrice: gasPrice, Gas: gas, Data: data, contractCreation: IsContractAddr(to)}
+ return &Transaction{recipient: to, value: value, gasPrice: gasPrice, gas: gas, data: data}
}
func NewTransactionFromBytes(data []byte) *Transaction {
@@ -53,38 +46,50 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
return tx
}
-func (self *Transaction) GasValue() *big.Int {
- return new(big.Int).Mul(self.Gas, self.GasPrice)
+func (tx *Transaction) Hash() []byte {
+ data := []interface{}{tx.Nonce, tx.gasPrice, tx.gas, tx.recipient, tx.Value, tx.Data}
+
+ return crypto.Sha3(ethutil.NewValue(data).Encode())
}
-func (self *Transaction) TotalValue() *big.Int {
- v := self.GasValue()
- return v.Add(v, self.Value)
+func (self *Transaction) Data() []byte {
+ return self.data
}
-func (tx *Transaction) Hash() []byte {
- data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data}
+func (self *Transaction) Gas() *big.Int {
+ return self.gas
+}
- return crypto.Sha3(ethutil.NewValue(data).Encode())
+func (self *Transaction) GasPrice() *big.Int {
+ return self.gasPrice
}
-func (tx *Transaction) CreatesContract() bool {
- return tx.contractCreation
+func (self *Transaction) Value() *big.Int {
+ return self.value
}
-/* Deprecated */
-func (tx *Transaction) IsContract() bool {
- return tx.CreatesContract()
+func (self *Transaction) Nonce() uint64 {
+ return self.nonce
}
-func (tx *Transaction) CreationAddress(state *state.State) []byte {
- // Generate a new address
- addr := crypto.Sha3(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:]
- //for i := uint64(0); state.GetStateObject(addr) != nil; i++ {
- // addr = crypto.Sha3(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce + i}).Encode())[12:]
- //}
+func (self *Transaction) SetNonce(nonce uint64) {
+ self.nonce = nonce
+}
+
+func (self *Transaction) From() []byte {
+ return self.sender()
+}
+
+func (self *Transaction) To() []byte {
+ return self.recipient
+}
+
+func (tx *Transaction) Curve() (v byte, r []byte, s []byte) {
+ v = tx.v
+ r = ethutil.LeftPadBytes(tx.r, 32)
+ s = ethutil.LeftPadBytes(tx.s, 32)
- return addr
+ return
}
func (tx *Transaction) Signature(key []byte) []byte {
@@ -98,12 +103,10 @@ func (tx *Transaction) Signature(key []byte) []byte {
func (tx *Transaction) PublicKey() []byte {
hash := tx.Hash()
- // TODO
- r := ethutil.LeftPadBytes(tx.r, 32)
- s := ethutil.LeftPadBytes(tx.s, 32)
+ v, r, s := tx.Curve()
sig := append(r, s...)
- sig = append(sig, tx.v-27)
+ sig = append(sig, v-27)
pubkey := crypto.Ecrecover(append(hash, sig...))
//pubkey, _ := secp256k1.RecoverPubkey(hash, sig)
@@ -111,7 +114,7 @@ func (tx *Transaction) PublicKey() []byte {
return pubkey
}
-func (tx *Transaction) Sender() []byte {
+func (tx *Transaction) sender() []byte {
pubkey := tx.PublicKey()
// Validate the returned key.
@@ -135,7 +138,7 @@ func (tx *Transaction) Sign(privk []byte) error {
}
func (tx *Transaction) RlpData() interface{} {
- data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data}
+ data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.recipient, tx.Value, tx.Data}
// TODO Remove prefixing zero's
@@ -155,20 +158,16 @@ func (tx *Transaction) RlpDecode(data []byte) {
}
func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
- tx.Nonce = decoder.Get(0).Uint()
- tx.GasPrice = decoder.Get(1).BigInt()
- tx.Gas = decoder.Get(2).BigInt()
- tx.Recipient = decoder.Get(3).Bytes()
- tx.Value = decoder.Get(4).BigInt()
- tx.Data = decoder.Get(5).Bytes()
+ tx.nonce = decoder.Get(0).Uint()
+ tx.gasPrice = decoder.Get(1).BigInt()
+ tx.gas = decoder.Get(2).BigInt()
+ tx.recipient = decoder.Get(3).Bytes()
+ tx.value = decoder.Get(4).BigInt()
+ tx.data = decoder.Get(5).Bytes()
tx.v = byte(decoder.Get(6).Uint())
tx.r = decoder.Get(7).Bytes()
tx.s = decoder.Get(8).Bytes()
-
- if IsContractAddr(tx.Recipient) {
- tx.contractCreation = true
- }
}
func (tx *Transaction) String() string {
@@ -187,12 +186,12 @@ func (tx *Transaction) String() string {
S: 0x%x
`,
tx.Hash(),
- len(tx.Recipient) == 0,
- tx.Sender(),
- tx.Recipient,
- tx.Nonce,
- tx.GasPrice,
- tx.Gas,
+ len(tx.recipient) == 0,
+ tx.From(),
+ tx.recipient,
+ tx.nonce,
+ tx.gasPrice,
+ tx.gas,
tx.Value,
tx.Data,
tx.v,
@@ -220,5 +219,5 @@ func (s Transactions) GetRlp(i int) []byte { return ethutil.Rlp(s[i]) }
type TxByNonce struct{ Transactions }
func (s TxByNonce) Less(i, j int) bool {
- return s.Transactions[i].Nonce < s.Transactions[j].Nonce
+ return s.Transactions[i].nonce < s.Transactions[j].nonce
}
diff --git a/chain/types/transaction_test.go b/core/types/transaction_test.go
index ab1254f4c..ab1254f4c 100644
--- a/chain/types/transaction_test.go
+++ b/core/types/transaction_test.go
diff --git a/core/vm_env.go b/core/vm_env.go
new file mode 100644
index 000000000..ad63ecf9c
--- /dev/null
+++ b/core/vm_env.go
@@ -0,0 +1,61 @@
+package core
+
+import (
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/state"
+ "github.com/ethereum/go-ethereum/vm"
+)
+
+type VMEnv struct {
+ state *state.StateDB
+ block *types.Block
+ msg Message
+ depth int
+}
+
+func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
+ return &VMEnv{
+ state: state,
+ block: block,
+ msg: msg,
+ }
+}
+
+func (self *VMEnv) Origin() []byte { return self.msg.From() }
+func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number }
+func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
+func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
+func (self *VMEnv) Time() int64 { return self.block.Time }
+func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
+func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
+func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
+func (self *VMEnv) State() *state.StateDB { return self.state }
+func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
+func (self *VMEnv) Depth() int { return self.depth }
+func (self *VMEnv) SetDepth(i int) { self.depth = i }
+func (self *VMEnv) AddLog(log state.Log) {
+ self.state.AddLog(log)
+}
+func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
+ return vm.Transfer(from, to, amount)
+}
+
+func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *Execution {
+ return NewExecution(self, addr, data, gas, price, value)
+}
+
+func (self *VMEnv) Call(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(addr, data, gas, price, value)
+ return exe.Call(addr, me)
+}
+func (self *VMEnv) CallCode(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(me.Address(), data, gas, price, value)
+ return exe.Call(addr, me)
+}
+
+func (self *VMEnv) Create(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
+ exe := self.vm(addr, data, gas, price, value)
+ return exe.Create(me)
+}
diff --git a/crypto/crypto.go b/crypto/crypto.go
index e10a9e81f..b8fd78fa2 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -1,15 +1,23 @@
package crypto
import (
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
"crypto/sha256"
"code.google.com/p/go.crypto/ripemd160"
"github.com/ethereum/go-ethereum/ethutil"
+ "github.com/obscuren/ecies"
"github.com/obscuren/secp256k1-go"
"github.com/obscuren/sha3"
)
-// TODO refactor, remove (bin)
+func init() {
+ // specify the params for the s256 curve
+ ecies.AddParamsForCurve(S256(), ecies.ECIES_AES128_SHA256)
+}
+
func Sha3(data []byte) []byte {
d := sha3.NewKeccak256()
d.Write(data)
@@ -45,3 +53,63 @@ func Ecrecover(data []byte) []byte {
return r
}
+
+// New methods using proper ecdsa keys from the stdlib
+func ToECDSA(prv []byte) *ecdsa.PrivateKey {
+ if len(prv) == 0 {
+ return nil
+ }
+
+ priv := new(ecdsa.PrivateKey)
+ priv.PublicKey.Curve = S256()
+ priv.D = ethutil.BigD(prv)
+ priv.PublicKey.X, priv.PublicKey.Y = S256().ScalarBaseMult(prv)
+ return priv
+}
+
+func FromECDSA(prv *ecdsa.PrivateKey) []byte {
+ if prv == nil {
+ return nil
+ }
+ return prv.D.Bytes()
+}
+
+func ToECDSAPub(pub []byte) *ecdsa.PublicKey {
+ if len(pub) == 0 {
+ return nil
+ }
+ x, y := elliptic.Unmarshal(S256(), pub)
+ return &ecdsa.PublicKey{S256(), x, y}
+}
+
+func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
+ if pub == nil {
+ return nil
+ }
+ return elliptic.Marshal(S256(), pub.X, pub.Y)
+}
+
+func GenerateKey() (*ecdsa.PrivateKey, error) {
+ return ecdsa.GenerateKey(S256(), rand.Reader)
+}
+
+func SigToPub(hash, sig []byte) *ecdsa.PublicKey {
+ s := Ecrecover(append(hash, sig...))
+ x, y := elliptic.Unmarshal(S256(), s)
+
+ return &ecdsa.PublicKey{S256(), x, y}
+}
+
+func Sign(hash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
+ sig, err = secp256k1.Sign(hash, prv.D.Bytes())
+ return
+}
+
+func Encrypt(pub *ecdsa.PublicKey, message []byte) ([]byte, error) {
+ return ecies.Encrypt(rand.Reader, ecies.ImportECDSAPublic(pub), message, nil, nil)
+}
+
+func Decrypt(prv *ecdsa.PrivateKey, ct []byte) ([]byte, error) {
+ key := ecies.ImportECDSA(prv)
+ return key.Decrypt(rand.Reader, ct, nil, nil)
+}
diff --git a/crypto/curve.go b/crypto/curve.go
new file mode 100644
index 000000000..131a0dd2f
--- /dev/null
+++ b/crypto/curve.go
@@ -0,0 +1,363 @@
+package crypto
+
+// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2011 ThePiachu. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package bitelliptic implements several Koblitz elliptic curves over prime
+// fields.
+
+// This package operates, internally, on Jacobian coordinates. For a given
+// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
+// where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole
+// calculation can be performed within the transform (as in ScalarMult and
+// ScalarBaseMult). But even for Add and Double, it's faster to apply and
+// reverse the transform than to operate in affine coordinates.
+
+import (
+ "crypto/elliptic"
+ "io"
+ "math/big"
+ "sync"
+)
+
+// A BitCurve represents a Koblitz Curve with a=0.
+// See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
+type BitCurve struct {
+ P *big.Int // the order of the underlying field
+ N *big.Int // the order of the base point
+ B *big.Int // the constant of the BitCurve equation
+ Gx, Gy *big.Int // (x,y) of the base point
+ BitSize int // the size of the underlying field
+}
+
+func (BitCurve *BitCurve) Params() *elliptic.CurveParams {
+ return &elliptic.CurveParams{BitCurve.P, BitCurve.N, BitCurve.B, BitCurve.Gx, BitCurve.Gy, BitCurve.BitSize}
+}
+
+// IsOnBitCurve returns true if the given (x,y) lies on the BitCurve.
+func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
+ // y² = x³ + b
+ y2 := new(big.Int).Mul(y, y) //y²
+ y2.Mod(y2, BitCurve.P) //y²%P
+
+ x3 := new(big.Int).Mul(x, x) //x²
+ x3.Mul(x3, x) //x³
+
+ x3.Add(x3, BitCurve.B) //x³+B
+ x3.Mod(x3, BitCurve.P) //(x³+B)%P
+
+ return x3.Cmp(y2) == 0
+}
+
+//TODO: double check if the function is okay
+// affineFromJacobian reverses the Jacobian transform. See the comment at the
+// top of the file.
+func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
+ zinv := new(big.Int).ModInverse(z, BitCurve.P)
+ zinvsq := new(big.Int).Mul(zinv, zinv)
+
+ xOut = new(big.Int).Mul(x, zinvsq)
+ xOut.Mod(xOut, BitCurve.P)
+ zinvsq.Mul(zinvsq, zinv)
+ yOut = new(big.Int).Mul(y, zinvsq)
+ yOut.Mod(yOut, BitCurve.P)
+ return
+}
+
+// Add returns the sum of (x1,y1) and (x2,y2)
+func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
+ z := new(big.Int).SetInt64(1)
+ return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z))
+}
+
+// addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
+// (x2, y2, z2) and returns their sum, also in Jacobian form.
+func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
+ // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
+ z1z1 := new(big.Int).Mul(z1, z1)
+ z1z1.Mod(z1z1, BitCurve.P)
+ z2z2 := new(big.Int).Mul(z2, z2)
+ z2z2.Mod(z2z2, BitCurve.P)
+
+ u1 := new(big.Int).Mul(x1, z2z2)
+ u1.Mod(u1, BitCurve.P)
+ u2 := new(big.Int).Mul(x2, z1z1)
+ u2.Mod(u2, BitCurve.P)
+ h := new(big.Int).Sub(u2, u1)
+ if h.Sign() == -1 {
+ h.Add(h, BitCurve.P)
+ }
+ i := new(big.Int).Lsh(h, 1)
+ i.Mul(i, i)
+ j := new(big.Int).Mul(h, i)
+
+ s1 := new(big.Int).Mul(y1, z2)
+ s1.Mul(s1, z2z2)
+ s1.Mod(s1, BitCurve.P)
+ s2 := new(big.Int).Mul(y2, z1)
+ s2.Mul(s2, z1z1)
+ s2.Mod(s2, BitCurve.P)
+ r := new(big.Int).Sub(s2, s1)
+ if r.Sign() == -1 {
+ r.Add(r, BitCurve.P)
+ }
+ r.Lsh(r, 1)
+ v := new(big.Int).Mul(u1, i)
+
+ x3 := new(big.Int).Set(r)
+ x3.Mul(x3, x3)
+ x3.Sub(x3, j)
+ x3.Sub(x3, v)
+ x3.Sub(x3, v)
+ x3.Mod(x3, BitCurve.P)
+
+ y3 := new(big.Int).Set(r)
+ v.Sub(v, x3)
+ y3.Mul(y3, v)
+ s1.Mul(s1, j)
+ s1.Lsh(s1, 1)
+ y3.Sub(y3, s1)
+ y3.Mod(y3, BitCurve.P)
+
+ z3 := new(big.Int).Add(z1, z2)
+ z3.Mul(z3, z3)
+ z3.Sub(z3, z1z1)
+ if z3.Sign() == -1 {
+ z3.Add(z3, BitCurve.P)
+ }
+ z3.Sub(z3, z2z2)
+ if z3.Sign() == -1 {
+ z3.Add(z3, BitCurve.P)
+ }
+ z3.Mul(z3, h)
+ z3.Mod(z3, BitCurve.P)
+
+ return x3, y3, z3
+}
+
+// Double returns 2*(x,y)
+func (BitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
+ z1 := new(big.Int).SetInt64(1)
+ return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z1))
+}
+
+// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
+// returns its double, also in Jacobian form.
+func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
+ // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
+
+ a := new(big.Int).Mul(x, x) //X1²
+ b := new(big.Int).Mul(y, y) //Y1²
+ c := new(big.Int).Mul(b, b) //B²
+
+ d := new(big.Int).Add(x, b) //X1+B
+ d.Mul(d, d) //(X1+B)²
+ d.Sub(d, a) //(X1+B)²-A
+ d.Sub(d, c) //(X1+B)²-A-C
+ d.Mul(d, big.NewInt(2)) //2*((X1+B)²-A-C)
+
+ e := new(big.Int).Mul(big.NewInt(3), a) //3*A
+ f := new(big.Int).Mul(e, e) //E²
+
+ x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D
+ x3.Sub(f, x3) //F-2*D
+ x3.Mod(x3, BitCurve.P)
+
+ y3 := new(big.Int).Sub(d, x3) //D-X3
+ y3.Mul(e, y3) //E*(D-X3)
+ y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C
+ y3.Mod(y3, BitCurve.P)
+
+ z3 := new(big.Int).Mul(y, z) //Y1*Z1
+ z3.Mul(big.NewInt(2), z3) //3*Y1*Z1
+ z3.Mod(z3, BitCurve.P)
+
+ return x3, y3, z3
+}
+
+//TODO: double check if it is okay
+// ScalarMult returns k*(Bx,By) where k is a number in big-endian form.
+func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
+ // We have a slight problem in that the identity of the group (the
+ // point at infinity) cannot be represented in (x, y) form on a finite
+ // machine. Thus the standard add/double algorithm has to be tweaked
+ // slightly: our initial state is not the identity, but x, and we
+ // ignore the first true bit in |k|. If we don't find any true bits in
+ // |k|, then we return nil, nil, because we cannot return the identity
+ // element.
+
+ Bz := new(big.Int).SetInt64(1)
+ x := Bx
+ y := By
+ z := Bz
+
+ seenFirstTrue := false
+ for _, byte := range k {
+ for bitNum := 0; bitNum < 8; bitNum++ {
+ if seenFirstTrue {
+ x, y, z = BitCurve.doubleJacobian(x, y, z)
+ }
+ if byte&0x80 == 0x80 {
+ if !seenFirstTrue {
+ seenFirstTrue = true
+ } else {
+ x, y, z = BitCurve.addJacobian(Bx, By, Bz, x, y, z)
+ }
+ }
+ byte <<= 1
+ }
+ }
+
+ if !seenFirstTrue {
+ return nil, nil
+ }
+
+ return BitCurve.affineFromJacobian(x, y, z)
+}
+
+// ScalarBaseMult returns k*G, where G is the base point of the group and k is
+// an integer in big-endian form.
+func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
+ return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k)
+}
+
+var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
+
+//TODO: double check if it is okay
+// GenerateKey returns a public/private key pair. The private key is generated
+// using the given reader, which must return random data.
+func (BitCurve *BitCurve) GenerateKey(rand io.Reader) (priv []byte, x, y *big.Int, err error) {
+ byteLen := (BitCurve.BitSize + 7) >> 3
+ priv = make([]byte, byteLen)
+
+ for x == nil {
+ _, err = io.ReadFull(rand, priv)
+ if err != nil {
+ return
+ }
+ // We have to mask off any excess bits in the case that the size of the
+ // underlying field is not a whole number of bytes.
+ priv[0] &= mask[BitCurve.BitSize%8]
+ // This is because, in tests, rand will return all zeros and we don't
+ // want to get the point at infinity and loop forever.
+ priv[1] ^= 0x42
+ x, y = BitCurve.ScalarBaseMult(priv)
+ }
+ return
+}
+
+// Marshal converts a point into the form specified in section 4.3.6 of ANSI
+// X9.62.
+func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte {
+ byteLen := (BitCurve.BitSize + 7) >> 3
+
+ ret := make([]byte, 1+2*byteLen)
+ ret[0] = 4 // uncompressed point
+
+ xBytes := x.Bytes()
+ copy(ret[1+byteLen-len(xBytes):], xBytes)
+ yBytes := y.Bytes()
+ copy(ret[1+2*byteLen-len(yBytes):], yBytes)
+ return ret
+}
+
+// Unmarshal converts a point, serialised by Marshal, into an x, y pair. On
+// error, x = nil.
+func (BitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) {
+ byteLen := (BitCurve.BitSize + 7) >> 3
+ if len(data) != 1+2*byteLen {
+ return
+ }
+ if data[0] != 4 { // uncompressed form
+ return
+ }
+ x = new(big.Int).SetBytes(data[1 : 1+byteLen])
+ y = new(big.Int).SetBytes(data[1+byteLen:])
+ return
+}
+
+//curve parameters taken from:
+//http://www.secg.org/collateral/sec2_final.pdf
+
+var initonce sync.Once
+var ecp160k1 *BitCurve
+var ecp192k1 *BitCurve
+var ecp224k1 *BitCurve
+var ecp256k1 *BitCurve
+
+func initAll() {
+ initS160()
+ initS192()
+ initS224()
+ initS256()
+}
+
+func initS160() {
+ // See SEC 2 section 2.4.1
+ ecp160k1 = new(BitCurve)
+ ecp160k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", 16)
+ ecp160k1.N, _ = new(big.Int).SetString("0100000000000000000001B8FA16DFAB9ACA16B6B3", 16)
+ ecp160k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000007", 16)
+ ecp160k1.Gx, _ = new(big.Int).SetString("3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", 16)
+ ecp160k1.Gy, _ = new(big.Int).SetString("938CF935318FDCED6BC28286531733C3F03C4FEE", 16)
+ ecp160k1.BitSize = 160
+}
+
+func initS192() {
+ // See SEC 2 section 2.5.1
+ ecp192k1 = new(BitCurve)
+ ecp192k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", 16)
+ ecp192k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 16)
+ ecp192k1.B, _ = new(big.Int).SetString("000000000000000000000000000000000000000000000003", 16)
+ ecp192k1.Gx, _ = new(big.Int).SetString("DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", 16)
+ ecp192k1.Gy, _ = new(big.Int).SetString("9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", 16)
+ ecp192k1.BitSize = 192
+}
+
+func initS224() {
+ // See SEC 2 section 2.6.1
+ ecp224k1 = new(BitCurve)
+ ecp224k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", 16)
+ ecp224k1.N, _ = new(big.Int).SetString("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 16)
+ ecp224k1.B, _ = new(big.Int).SetString("00000000000000000000000000000000000000000000000000000005", 16)
+ ecp224k1.Gx, _ = new(big.Int).SetString("A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", 16)
+ ecp224k1.Gy, _ = new(big.Int).SetString("7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", 16)
+ ecp224k1.BitSize = 224
+}
+
+func initS256() {
+ // See SEC 2 section 2.7.1
+ ecp256k1 = new(BitCurve)
+ ecp256k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
+ ecp256k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
+ ecp256k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16)
+ ecp256k1.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16)
+ ecp256k1.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16)
+ ecp256k1.BitSize = 256
+}
+
+// S160 returns a BitCurve which implements secp160k1 (see SEC 2 section 2.4.1)
+func S160() *BitCurve {
+ initonce.Do(initAll)
+ return ecp160k1
+}
+
+// S192 returns a BitCurve which implements secp192k1 (see SEC 2 section 2.5.1)
+func S192() *BitCurve {
+ initonce.Do(initAll)
+ return ecp192k1
+}
+
+// S224 returns a BitCurve which implements secp224k1 (see SEC 2 section 2.6.1)
+func S224() *BitCurve {
+ initonce.Do(initAll)
+ return ecp224k1
+}
+
+// S256 returns a BitCurve which implements secp256k1 (see SEC 2 section 2.7.1)
+func S256() *BitCurve {
+ initonce.Do(initAll)
+ return ecp256k1
+}
diff --git a/crypto/encrypt_decrypt_test.go b/crypto/encrypt_decrypt_test.go
new file mode 100644
index 000000000..85b43c406
--- /dev/null
+++ b/crypto/encrypt_decrypt_test.go
@@ -0,0 +1,40 @@
+package crypto
+
+import (
+ "bytes"
+ "fmt"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/ethutil"
+)
+
+func TestBox(t *testing.T) {
+ prv1 := ToECDSA(ethutil.Hex2Bytes("4b50fa71f5c3eeb8fdc452224b2395af2fcc3d125e06c32c82e048c0559db03f"))
+ prv2 := ToECDSA(ethutil.Hex2Bytes("d0b043b4c5d657670778242d82d68a29d25d7d711127d17b8e299f156dad361a"))
+ pub2 := ToECDSAPub(ethutil.Hex2Bytes("04bd27a63c91fe3233c5777e6d3d7b39204d398c8f92655947eb5a373d46e1688f022a1632d264725cbc7dc43ee1cfebde42fa0a86d08b55d2acfbb5e9b3b48dc5"))
+
+ message := []byte("Hello, world.")
+ ct, err := Encrypt(pub2, message)
+ if err != nil {
+ fmt.Println(err.Error())
+ t.FailNow()
+ }
+
+ pt, err := Decrypt(prv2, ct)
+ if err != nil {
+ fmt.Println(err.Error())
+ t.FailNow()
+ }
+
+ if !bytes.Equal(pt, message) {
+ fmt.Println("ecies: plaintext doesn't match message")
+ t.FailNow()
+ }
+
+ _, err = Decrypt(prv1, pt)
+ if err == nil {
+ fmt.Println("ecies: encryption should not have succeeded")
+ t.FailNow()
+ }
+
+}
diff --git a/crypto/key_manager.go b/crypto/key_manager.go
index cc2b9ff90..326e559e0 100644
--- a/crypto/key_manager.go
+++ b/crypto/key_manager.go
@@ -5,8 +5,11 @@ import (
"sync"
"github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/logger"
)
+var keylogger = logger.NewLogger("KEY")
+
type KeyManager struct {
keyRing *KeyRing
session string
@@ -104,6 +107,7 @@ func (k *KeyManager) Init(session string, cursor int, force bool) error {
}
if keyRing == nil {
keyRing = NewGeneratedKeyRing(1)
+ keylogger.Infof("Created keypair. Private key: %x\n", keyRing.keys[0].PrivateKey)
}
return k.reset(session, cursor, keyRing)
}
diff --git a/eth/backend.go b/eth/backend.go
new file mode 100644
index 000000000..0aad6a514
--- /dev/null
+++ b/eth/backend.go
@@ -0,0 +1,249 @@
+package eth
+
+import (
+ "net"
+ "sync"
+
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/event"
+ ethlogger "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/pow/ezp"
+ "github.com/ethereum/go-ethereum/rpc"
+ "github.com/ethereum/go-ethereum/whisper"
+)
+
+const (
+ seedNodeAddress = "poc-7.ethdev.com:30300"
+)
+
+var logger = ethlogger.NewLogger("SERV")
+
+type Ethereum struct {
+ // Channel for shutting down the ethereum
+ shutdownChan chan bool
+ quit chan bool
+
+ // DB interface
+ db ethutil.Database
+ blacklist p2p.Blacklist
+
+ //*** SERVICES ***
+ // State manager for processing new blocks and managing the over all states
+ blockManager *core.BlockManager
+ txPool *core.TxPool
+ chainManager *core.ChainManager
+ blockPool *BlockPool
+ whisper *whisper.Whisper
+
+ server *p2p.Server
+ eventMux *event.TypeMux
+ txSub event.Subscription
+ blockSub event.Subscription
+
+ RpcServer *rpc.JsonRpcServer
+ keyManager *crypto.KeyManager
+
+ clientIdentity p2p.ClientIdentity
+
+ synclock sync.Mutex
+ syncGroup sync.WaitGroup
+
+ Mining bool
+}
+
+func New(db ethutil.Database, identity p2p.ClientIdentity, keyManager *crypto.KeyManager, nat p2p.NAT, port string, maxPeers int) (*Ethereum, error) {
+
+ saveProtocolVersion(db)
+ ethutil.Config.Db = db
+
+ eth := &Ethereum{
+ shutdownChan: make(chan bool),
+ quit: make(chan bool),
+ db: db,
+ keyManager: keyManager,
+ clientIdentity: identity,
+ blacklist: p2p.NewBlacklist(),
+ eventMux: &event.TypeMux{},
+ }
+
+ eth.chainManager = core.NewChainManager(eth.EventMux())
+ eth.txPool = core.NewTxPool(eth.chainManager, eth.EventMux())
+ eth.blockManager = core.NewBlockManager(eth.txPool, eth.chainManager, eth.EventMux())
+ eth.chainManager.SetProcessor(eth.blockManager)
+ eth.whisper = whisper.New()
+
+ hasBlock := eth.chainManager.HasBlock
+ insertChain := eth.chainManager.InsertChain
+ eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify)
+
+ // Start services
+ eth.txPool.Start()
+
+ ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool)
+ protocols := []p2p.Protocol{ethProto, eth.whisper.Protocol()}
+
+ server := &p2p.Server{
+ Identity: identity,
+ MaxPeers: maxPeers,
+ Protocols: protocols,
+ ListenAddr: ":" + port,
+ Blacklist: eth.blacklist,
+ NAT: nat,
+ }
+
+ eth.server = server
+
+ return eth, nil
+}
+
+func (s *Ethereum) KeyManager() *crypto.KeyManager {
+ return s.keyManager
+}
+
+func (s *Ethereum) ClientIdentity() p2p.ClientIdentity {
+ return s.clientIdentity
+}
+
+func (s *Ethereum) ChainManager() *core.ChainManager {
+ return s.chainManager
+}
+
+func (s *Ethereum) BlockManager() *core.BlockManager {
+ return s.blockManager
+}
+
+func (s *Ethereum) TxPool() *core.TxPool {
+ return s.txPool
+}
+
+func (s *Ethereum) BlockPool() *BlockPool {
+ return s.blockPool
+}
+
+func (s *Ethereum) Whisper() *whisper.Whisper {
+ return s.whisper
+}
+
+func (s *Ethereum) EventMux() *event.TypeMux {
+ return s.eventMux
+}
+func (self *Ethereum) Db() ethutil.Database {
+ return self.db
+}
+
+func (s *Ethereum) IsMining() bool {
+ return s.Mining
+}
+
+func (s *Ethereum) IsListening() bool {
+ // XXX TODO
+ return false
+}
+
+func (s *Ethereum) PeerCount() int {
+ return s.server.PeerCount()
+}
+
+func (s *Ethereum) Peers() []*p2p.Peer {
+ return s.server.Peers()
+}
+
+func (s *Ethereum) MaxPeers() int {
+ return s.server.MaxPeers
+}
+
+// Start the ethereum
+func (s *Ethereum) Start(seed bool) error {
+ err := s.server.Start()
+ if err != nil {
+ return err
+ }
+ s.blockPool.Start()
+ s.whisper.Start()
+
+ // broadcast transactions
+ s.txSub = s.eventMux.Subscribe(core.TxPreEvent{})
+ go s.txBroadcastLoop()
+
+ // broadcast mined blocks
+ s.blockSub = s.eventMux.Subscribe(core.NewMinedBlockEvent{})
+ go s.blockBroadcastLoop()
+
+ // TODO: read peers here
+ if seed {
+ logger.Infof("Connect to seed node %v", seedNodeAddress)
+ if err := s.SuggestPeer(seedNodeAddress); err != nil {
+ return err
+ }
+ }
+
+ logger.Infoln("Server started")
+ return nil
+}
+
+func (self *Ethereum) SuggestPeer(addr string) error {
+ netaddr, err := net.ResolveTCPAddr("tcp", addr)
+ if err != nil {
+ logger.Errorf("couldn't resolve %s:", addr, err)
+ return err
+ }
+
+ self.server.SuggestPeer(netaddr.IP, netaddr.Port, nil)
+ return nil
+}
+
+func (s *Ethereum) Stop() {
+ // Close the database
+ defer s.db.Close()
+
+ close(s.quit)
+
+ s.txSub.Unsubscribe() // quits txBroadcastLoop
+ s.blockSub.Unsubscribe() // quits blockBroadcastLoop
+
+ if s.RpcServer != nil {
+ s.RpcServer.Stop()
+ }
+ s.txPool.Stop()
+ s.eventMux.Stop()
+ s.blockPool.Stop()
+ s.whisper.Stop()
+
+ logger.Infoln("Server stopped")
+ close(s.shutdownChan)
+}
+
+// This function will wait for a shutdown and resumes main thread execution
+func (s *Ethereum) WaitForShutdown() {
+ <-s.shutdownChan
+}
+
+// now tx broadcasting is taken out of txPool
+// handled here via subscription, efficiency?
+func (self *Ethereum) txBroadcastLoop() {
+ // automatically stops if unsubscribe
+ for obj := range self.txSub.Chan() {
+ event := obj.(core.TxPreEvent)
+ self.server.Broadcast("eth", TxMsg, []interface{}{event.Tx.RlpData()})
+ }
+}
+
+func (self *Ethereum) blockBroadcastLoop() {
+ // automatically stops if unsubscribe
+ for obj := range self.txSub.Chan() {
+ event := obj.(core.NewMinedBlockEvent)
+ self.server.Broadcast("eth", NewBlockMsg, event.Block.Value().Val)
+ }
+}
+
+func saveProtocolVersion(db ethutil.Database) {
+ d, _ := db.Get([]byte("ProtocolVersion"))
+ protocolVersion := ethutil.NewValue(d).Uint()
+
+ if protocolVersion == 0 {
+ db.Put([]byte("ProtocolVersion"), ethutil.NewValue(ProtocolVersion).Bytes())
+ }
+}
diff --git a/eth/block_pool.go b/eth/block_pool.go
new file mode 100644
index 000000000..7cfbc63f8
--- /dev/null
+++ b/eth/block_pool.go
@@ -0,0 +1,1015 @@
+package eth
+
+import (
+ "math"
+ "math/big"
+ "math/rand"
+ "sort"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/ethutil"
+ ethlogger "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/pow"
+)
+
+var poolLogger = ethlogger.NewLogger("Blockpool")
+
+const (
+ blockHashesBatchSize = 256
+ blockBatchSize = 64
+ blocksRequestInterval = 10 // seconds
+ blocksRequestRepetition = 1
+ blockHashesRequestInterval = 10 // seconds
+ blocksRequestMaxIdleRounds = 10
+ cacheTimeout = 3 // minutes
+ blockTimeout = 5 // minutes
+)
+
+type poolNode struct {
+ lock sync.RWMutex
+ hash []byte
+ block *types.Block
+ child *poolNode
+ parent *poolNode
+ section *section
+ knownParent bool
+ peer string
+ source string
+ complete bool
+}
+
+type BlockPool struct {
+ lock sync.RWMutex
+ pool map[string]*poolNode
+
+ peersLock sync.RWMutex
+ peers map[string]*peerInfo
+ peer *peerInfo
+
+ quit chan bool
+ wg sync.WaitGroup
+ running bool
+
+ // the minimal interface with blockchain
+ hasBlock func(hash []byte) bool
+ insertChain func(types.Blocks) error
+ verifyPoW func(pow.Block) bool
+}
+
+type peerInfo struct {
+ lock sync.RWMutex
+
+ td *big.Int
+ currentBlock []byte
+ id string
+
+ requestBlockHashes func([]byte) error
+ requestBlocks func([][]byte) error
+ peerError func(int, string, ...interface{})
+
+ sections map[string]*section
+ roots []*poolNode
+ quitC chan bool
+}
+
+func NewBlockPool(hasBlock func(hash []byte) bool, insertChain func(types.Blocks) error, verifyPoW func(pow.Block) bool,
+) *BlockPool {
+ return &BlockPool{
+ hasBlock: hasBlock,
+ insertChain: insertChain,
+ verifyPoW: verifyPoW,
+ }
+}
+
+// allows restart
+func (self *BlockPool) Start() {
+ self.lock.Lock()
+ if self.running {
+ self.lock.Unlock()
+ return
+ }
+ self.running = true
+ self.quit = make(chan bool)
+ self.pool = make(map[string]*poolNode)
+ self.lock.Unlock()
+
+ self.peersLock.Lock()
+ self.peers = make(map[string]*peerInfo)
+ self.peersLock.Unlock()
+
+ poolLogger.Infoln("Started")
+
+}
+
+func (self *BlockPool) Stop() {
+ self.lock.Lock()
+ if !self.running {
+ self.lock.Unlock()
+ return
+ }
+ self.running = false
+ self.lock.Unlock()
+
+ poolLogger.Infoln("Stopping")
+
+ close(self.quit)
+ self.lock.Lock()
+ self.peersLock.Lock()
+ self.peers = nil
+ self.pool = nil
+ self.peer = nil
+ self.wg.Wait()
+ self.lock.Unlock()
+ self.peersLock.Unlock()
+ poolLogger.Infoln("Stopped")
+
+}
+
+// AddPeer is called by the eth protocol instance running on the peer after
+// the status message has been received with total difficulty and current block hash
+// AddPeer can only be used once, RemovePeer needs to be called when the peer disconnects
+func (self *BlockPool) AddPeer(td *big.Int, currentBlock []byte, peerId string, requestBlockHashes func([]byte) error, requestBlocks func([][]byte) error, peerError func(int, string, ...interface{})) bool {
+ self.peersLock.Lock()
+ defer self.peersLock.Unlock()
+ if self.peers[peerId] != nil {
+ panic("peer already added")
+ }
+ peer := &peerInfo{
+ td: td,
+ currentBlock: currentBlock,
+ id: peerId, //peer.Identity().Pubkey()
+ requestBlockHashes: requestBlockHashes,
+ requestBlocks: requestBlocks,
+ peerError: peerError,
+ }
+ self.peers[peerId] = peer
+ poolLogger.Debugf("add new peer %v with td %v", peerId, td)
+ currentTD := ethutil.Big0
+ if self.peer != nil {
+ currentTD = self.peer.td
+ }
+ if td.Cmp(currentTD) > 0 {
+ self.peer.stop(peer)
+ peer.start(self.peer)
+ poolLogger.Debugf("peer %v promoted to best peer", peerId)
+ self.peer = peer
+ return true
+ }
+ return false
+}
+
+// RemovePeer is called by the eth protocol when the peer disconnects
+func (self *BlockPool) RemovePeer(peerId string) {
+ self.peersLock.Lock()
+ defer self.peersLock.Unlock()
+ peer := self.peers[peerId]
+ if peer == nil {
+ return
+ }
+ self.peers[peerId] = nil
+ poolLogger.Debugf("remove peer %v", peerId[0:4])
+
+ // if current best peer is removed, need find a better one
+ if self.peer != nil && peerId == self.peer.id {
+ var newPeer *peerInfo
+ max := ethutil.Big0
+ // peer with the highest self-acclaimed TD is chosen
+ for _, info := range self.peers {
+ if info.td.Cmp(max) > 0 {
+ max = info.td
+ newPeer = info
+ }
+ }
+ self.peer.stop(peer)
+ peer.start(self.peer)
+ if newPeer != nil {
+ poolLogger.Debugf("peer %v with td %v promoted to best peer", newPeer.id[0:4], newPeer.td)
+ } else {
+ poolLogger.Warnln("no peers left")
+ }
+ }
+}
+
+// Entry point for eth protocol to add block hashes received via BlockHashesMsg
+// only hashes from the best peer is handled
+// this method is always responsible to initiate further hash requests until
+// a known parent is reached unless cancelled by a peerChange event
+// this process also launches all request processes on each chain section
+// this function needs to run asynchronously for one peer since the message is discarded???
+func (self *BlockPool) AddBlockHashes(next func() ([]byte, bool), peerId string) {
+
+ // check if this peer is the best
+ peer, best := self.getPeer(peerId)
+ if !best {
+ return
+ }
+ // peer is still the best
+
+ var child *poolNode
+ var depth int
+
+ // iterate using next (rlp stream lazy decoder) feeding hashesC
+ self.wg.Add(1)
+ go func() {
+ for {
+ select {
+ case <-self.quit:
+ return
+ case <-peer.quitC:
+ // if the peer is demoted, no more hashes taken
+ break
+ default:
+ hash, ok := next()
+ if !ok {
+ // message consumed chain skeleton built
+ break
+ }
+ // check if known block connecting the downloaded chain to our blockchain
+ if self.hasBlock(hash) {
+ poolLogger.Infof("known block (%x...)\n", hash[0:4])
+ if child != nil {
+ child.Lock()
+ // mark child as absolute pool root with parent known to blockchain
+ child.knownParent = true
+ child.Unlock()
+ }
+ break
+ }
+ //
+ var parent *poolNode
+ // look up node in pool
+ parent = self.get(hash)
+ if parent != nil {
+ // reached a known chain in the pool
+ // request blocks on the newly added part of the chain
+ if child != nil {
+ self.link(parent, child)
+
+ // activate the current chain
+ self.activateChain(parent, peer, true)
+ poolLogger.Debugf("potential chain of %v blocks added, reached blockpool, activate chain", depth)
+ break
+ }
+ // if this is the first hash, we expect to find it
+ parent.RLock()
+ grandParent := parent.parent
+ parent.RUnlock()
+ if grandParent != nil {
+ // activate the current chain
+ self.activateChain(parent, peer, true)
+ poolLogger.Debugf("block hash found, activate chain")
+ break
+ }
+ // the first node is the root of a chain in the pool, rejoice and continue
+ }
+ // if node does not exist, create it and index in the pool
+ section := &section{}
+ if child == nil {
+ section.top = parent
+ }
+ parent = &poolNode{
+ hash: hash,
+ child: child,
+ section: section,
+ peer: peerId,
+ }
+ self.set(hash, parent)
+ poolLogger.Debugf("create potential block for %x...", hash[0:4])
+
+ depth++
+ child = parent
+ }
+ }
+ if child != nil {
+ poolLogger.Debugf("chain of %v hashes added", depth)
+ // start a processSection on the last node, but switch off asking
+ // hashes and blocks until next peer confirms this chain
+ section := self.processSection(child)
+ peer.addSection(child.hash, section)
+ section.start()
+ }
+ }()
+}
+
+// AddBlock is the entry point for the eth protocol when blockmsg is received upon requests
+// It has a strict interpretation of the protocol in that if the block received has not been requested, it results in an error (which can be ignored)
+// block is checked for PoW
+// only the first PoW-valid block for a hash is considered legit
+func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
+ hash := block.Hash()
+ node := self.get(hash)
+ node.RLock()
+ b := node.block
+ node.RUnlock()
+ if b != nil {
+ return
+ }
+ if node == nil && !self.hasBlock(hash) {
+ self.peerError(peerId, ErrUnrequestedBlock, "%x", hash)
+ return
+ }
+ // validate block for PoW
+ if !self.verifyPoW(block) {
+ self.peerError(peerId, ErrInvalidPoW, "%x", hash)
+ }
+ node.Lock()
+ node.block = block
+ node.source = peerId
+ node.Unlock()
+}
+
+// iterates down a known poolchain and activates fetching processes
+// on each chain section for the peer
+// stops if the peer is demoted
+// registers last section root as root for the peer (in case peer is promoted a second time, to remember)
+func (self *BlockPool) activateChain(node *poolNode, peer *peerInfo, on bool) {
+ self.wg.Add(1)
+ go func() {
+ for {
+ node.sectionRLock()
+ bottom := node.section.bottom
+ if bottom == nil { // the chain section is being created or killed
+ break
+ }
+ // register this section with the peer
+ if peer != nil {
+ peer.addSection(bottom.hash, bottom.section)
+ if on {
+ bottom.section.start()
+ } else {
+ bottom.section.start()
+ }
+ }
+ if bottom.parent == nil {
+ node = bottom
+ break
+ }
+ // if peer demoted stop activation
+ select {
+ case <-peer.quitC:
+ break
+ default:
+ }
+
+ node = bottom.parent
+ bottom.sectionRUnlock()
+ }
+ // remember root for this peer
+ peer.addRoot(node)
+ self.wg.Done()
+ }()
+}
+
+// main worker thread on each section in the poolchain
+// - kills the section if there are blocks missing after an absolute time
+// - kills the section if there are maxIdleRounds of idle rounds of block requests with no response
+// - periodically polls the chain section for missing blocks which are then requested from peers
+// - registers the process controller on the peer so that if the peer is promoted as best peer the second time (after a disconnect of a better one), all active processes are switched back on unless they expire and killed ()
+// - when turned off (if peer disconnects and new peer connects with alternative chain), no blockrequests are made but absolute expiry timer is ticking
+// - when turned back on it recursively calls itself on the root of the next chain section
+// - when exits, signals to
+func (self *BlockPool) processSection(node *poolNode) *section {
+ // absolute time after which sub-chain is killed if not complete (some blocks are missing)
+ suicideTimer := time.After(blockTimeout * time.Minute)
+ var blocksRequestTimer, blockHashesRequestTimer <-chan time.Time
+ var nodeC, missingC, processC chan *poolNode
+ controlC := make(chan bool)
+ resetC := make(chan bool)
+ var hashes [][]byte
+ var i, total, missing, lastMissing, depth int
+ var blockHashesRequests, blocksRequests int
+ var idle int
+ var init, alarm, done, same, running, once bool
+ orignode := node
+ hash := node.hash
+
+ node.sectionLock()
+ defer node.sectionUnlock()
+ section := &section{controlC: controlC, resetC: resetC}
+ node.section = section
+
+ go func() {
+ self.wg.Add(1)
+ for {
+ node.sectionRLock()
+ controlC = node.section.controlC
+ node.sectionRUnlock()
+
+ if init {
+ // missing blocks read from nodeC
+ // initialized section
+ if depth == 0 {
+ break
+ }
+ // enable select case to read missing block when ready
+ processC = missingC
+ missingC = make(chan *poolNode, lastMissing)
+ nodeC = nil
+ // only do once
+ init = false
+ } else {
+ if !once {
+ missingC = nil
+ processC = nil
+ i = 0
+ total = 0
+ lastMissing = 0
+ }
+ }
+
+ // went through all blocks in section
+ if i != 0 && i == lastMissing {
+ if len(hashes) > 0 {
+ // send block requests to peers
+ self.requestBlocks(blocksRequests, hashes)
+ }
+ blocksRequests++
+ poolLogger.Debugf("[%x] block request attempt %v: missing %v/%v/%v", hash[0:4], blocksRequests, missing, total, depth)
+ if missing == lastMissing {
+ // idle round
+ if same {
+ // more than once
+ idle++
+ // too many idle rounds
+ if idle > blocksRequestMaxIdleRounds {
+ poolLogger.Debugf("[%x] block requests had %v idle rounds (%v total attempts): missing %v/%v/%v\ngiving up...", hash[0:4], idle, blocksRequests, missing, total, depth)
+ self.killChain(node, nil)
+ break
+ }
+ } else {
+ idle = 0
+ }
+ same = true
+ } else {
+ if missing == 0 {
+ // no missing nodes
+ poolLogger.Debugf("block request process complete on section %x... (%v total blocksRequests): missing %v/%v/%v", hash[0:4], blockHashesRequests, blocksRequests, missing, total, depth)
+ node.Lock()
+ orignode.complete = true
+ node.Unlock()
+ blocksRequestTimer = nil
+ if blockHashesRequestTimer == nil {
+ // not waiting for hashes any more
+ poolLogger.Debugf("hash request on root %x... successful (%v total attempts)\nquitting...", hash[0:4], blockHashesRequests)
+ break
+ } // otherwise suicide if no hashes coming
+ }
+ same = false
+ }
+ lastMissing = missing
+ i = 0
+ missing = 0
+ // ready for next round
+ done = true
+ }
+ if done && alarm {
+ poolLogger.Debugf("start checking if new blocks arrived (attempt %v): missing %v/%v/%v", blocksRequests, missing, total, depth)
+ blocksRequestTimer = time.After(blocksRequestInterval * time.Second)
+ alarm = false
+ done = false
+ // processC supposed to be empty and never closed so just swap, no need to allocate
+ tempC := processC
+ processC = missingC
+ missingC = tempC
+ }
+ select {
+ case <-self.quit:
+ break
+ case <-suicideTimer:
+ self.killChain(node, nil)
+ poolLogger.Warnf("[%x] timeout. (%v total attempts): missing %v/%v/%v", hash[0:4], blocksRequests, missing, total, depth)
+ break
+ case <-blocksRequestTimer:
+ alarm = true
+ case <-blockHashesRequestTimer:
+ orignode.RLock()
+ parent := orignode.parent
+ orignode.RUnlock()
+ if parent != nil {
+ // if not root of chain, switch off
+ poolLogger.Debugf("[%x] parent found, hash requests deactivated (after %v total attempts)\n", hash[0:4], blockHashesRequests)
+ blockHashesRequestTimer = nil
+ } else {
+ blockHashesRequests++
+ poolLogger.Debugf("[%x] hash request on root (%v total attempts)\n", hash[0:4], blockHashesRequests)
+ self.requestBlockHashes(parent.hash)
+ blockHashesRequestTimer = time.After(blockHashesRequestInterval * time.Second)
+ }
+ case r, ok := <-controlC:
+ if !ok {
+ break
+ }
+ if running && !r {
+ poolLogger.Debugf("process on section %x... (%v total attempts): missing %v/%v/%v", hash[0:4], blocksRequests, missing, total, depth)
+
+ alarm = false
+ blocksRequestTimer = nil
+ blockHashesRequestTimer = nil
+ processC = nil
+ }
+ if !running && r {
+ poolLogger.Debugf("[%x] on", hash[0:4])
+
+ orignode.RLock()
+ parent := orignode.parent
+ complete := orignode.complete
+ knownParent := orignode.knownParent
+ orignode.RUnlock()
+ if !complete {
+ poolLogger.Debugf("[%x] activate block requests", hash[0:4])
+ blocksRequestTimer = time.After(0)
+ }
+ if parent == nil && !knownParent {
+ // if no parent but not connected to blockchain
+ poolLogger.Debugf("[%x] activate block hashes requests", hash[0:4])
+ blockHashesRequestTimer = time.After(0)
+ } else {
+ blockHashesRequestTimer = nil
+ }
+ alarm = true
+ processC = missingC
+ if !once {
+ // if not run at least once fully, launch iterator
+ processC = make(chan *poolNode)
+ missingC = make(chan *poolNode)
+ self.foldUp(orignode, processC)
+ once = true
+ }
+ }
+ total = lastMissing
+ case <-resetC:
+ once = false
+ init = false
+ done = false
+ case node, ok := <-processC:
+ if !ok {
+ // channel closed, first iteration finished
+ init = true
+ once = true
+ continue
+ }
+ i++
+ // if node has no block
+ node.RLock()
+ block := node.block
+ nhash := node.hash
+ knownParent := node.knownParent
+ node.RUnlock()
+ if !init {
+ depth++
+ }
+ if block == nil {
+ missing++
+ if !init {
+ total++
+ }
+ hashes = append(hashes, nhash)
+ if len(hashes) == blockBatchSize {
+ self.requestBlocks(blocksRequests, hashes)
+ hashes = nil
+ }
+ missingC <- node
+ } else {
+ // block is found
+ if knownParent {
+ // connected to the blockchain, insert the longest chain of blocks
+ var blocks types.Blocks
+ child := node
+ parent := node
+ node.sectionRLock()
+ for child != nil && child.block != nil {
+ parent = child
+ blocks = append(blocks, parent.block)
+ child = parent.child
+ }
+ node.sectionRUnlock()
+ poolLogger.Debugf("[%x] insert %v blocks into blockchain", hash[0:4], len(blocks))
+ if err := self.insertChain(blocks); err != nil {
+ // TODO: not clear which peer we need to address
+ // peerError should dispatch to peer if still connected and disconnect
+ self.peerError(node.source, ErrInvalidBlock, "%v", err)
+ poolLogger.Debugf("invalid block %v", node.hash)
+ poolLogger.Debugf("penalise peers %v (hash), %v (block)", node.peer, node.source)
+ // penalise peer in node.source
+ self.killChain(node, nil)
+ // self.disconnect()
+ break
+ }
+ // if suceeded mark the next one (no block yet) as connected to blockchain
+ if child != nil {
+ child.Lock()
+ child.knownParent = true
+ child.Unlock()
+ }
+ // reset starting node to first node with missing block
+ orignode = child
+ // pop the inserted ancestors off the channel
+ for i := 1; i < len(blocks); i++ {
+ <-processC
+ }
+ // delink inserted chain section
+ self.killChain(node, parent)
+ }
+ }
+ }
+ }
+ poolLogger.Debugf("[%x] quit after\n%v block hashes requests\n%v block requests: missing %v/%v/%v", hash[0:4], blockHashesRequests, blocksRequests, missing, total, depth)
+
+ self.wg.Done()
+ node.sectionLock()
+ node.section.controlC = nil
+ node.sectionUnlock()
+ // this signals that controller not available
+ }()
+ return section
+
+}
+
+func (self *BlockPool) peerError(peerId string, code int, format string, params ...interface{}) {
+ self.peersLock.RLock()
+ defer self.peersLock.RUnlock()
+ peer, ok := self.peers[peerId]
+ if ok {
+ peer.peerError(code, format, params...)
+ }
+}
+
+func (self *BlockPool) requestBlockHashes(hash []byte) {
+ self.peersLock.Lock()
+ defer self.peersLock.Unlock()
+ if self.peer != nil {
+ self.peer.requestBlockHashes(hash)
+ }
+}
+
+func (self *BlockPool) requestBlocks(attempts int, hashes [][]byte) {
+ // distribute block request among known peers
+ self.peersLock.Lock()
+ defer self.peersLock.Unlock()
+ peerCount := len(self.peers)
+ // on first attempt use the best peer
+ if attempts == 0 {
+ self.peer.requestBlocks(hashes)
+ return
+ }
+ repetitions := int(math.Min(float64(peerCount), float64(blocksRequestRepetition)))
+ poolLogger.Debugf("request %v missing blocks from %v/%v peers", len(hashes), repetitions, peerCount)
+ i := 0
+ indexes := rand.Perm(peerCount)[0:(repetitions - 1)]
+ sort.Ints(indexes)
+ for _, peer := range self.peers {
+ if i == indexes[0] {
+ peer.requestBlocks(hashes)
+ indexes = indexes[1:]
+ if len(indexes) == 0 {
+ break
+ }
+ }
+ i++
+ }
+}
+
+func (self *BlockPool) getPeer(peerId string) (*peerInfo, bool) {
+ self.peersLock.RLock()
+ defer self.peersLock.RUnlock()
+ if self.peer != nil && self.peer.id == peerId {
+ return self.peer, true
+ }
+ info, ok := self.peers[peerId]
+ if !ok {
+ panic("unknown peer")
+ }
+ return info, false
+}
+
+func (self *peerInfo) addSection(hash []byte, section *section) {
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ self.sections[string(hash)] = section
+}
+
+func (self *peerInfo) addRoot(node *poolNode) {
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ self.roots = append(self.roots, node)
+}
+
+// (re)starts processes registered for this peer (self)
+func (self *peerInfo) start(peer *peerInfo) {
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ self.quitC = make(chan bool)
+ for _, root := range self.roots {
+ root.sectionRLock()
+ if root.section.bottom != nil {
+ if root.parent == nil {
+ self.requestBlockHashes(root.hash)
+ }
+ }
+ root.sectionRUnlock()
+ }
+ self.roots = nil
+ self.controlSections(peer, true)
+}
+
+// (re)starts process without requests, only suicide timer
+func (self *peerInfo) stop(peer *peerInfo) {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ close(self.quitC)
+ self.controlSections(peer, false)
+}
+
+func (self *peerInfo) controlSections(peer *peerInfo, on bool) {
+ if peer != nil {
+ peer.lock.RLock()
+ defer peer.lock.RUnlock()
+ }
+ for hash, section := range peer.sections {
+ if section.done() {
+ delete(self.sections, hash)
+ }
+ _, exists := peer.sections[hash]
+ if on || peer == nil || exists {
+ if on {
+ // self is best peer
+ section.start()
+ } else {
+ // (re)starts process without requests, only suicide timer
+ section.stop()
+ }
+ }
+ }
+}
+
+// called when parent is found in pool
+// parent and child are guaranteed to be on different sections
+func (self *BlockPool) link(parent, child *poolNode) {
+ var top bool
+ parent.sectionLock()
+ if child != nil {
+ child.sectionLock()
+ }
+ if parent == parent.section.top && parent.section.top != nil {
+ top = true
+ }
+ var bottom bool
+
+ if child == child.section.bottom {
+ bottom = true
+ }
+ if parent.child != child {
+ orphan := parent.child
+ if orphan != nil {
+ // got a fork in the chain
+ if top {
+ orphan.lock.Lock()
+ // make old child orphan
+ orphan.parent = nil
+ orphan.lock.Unlock()
+ } else { // we are under section lock
+ // make old child orphan
+ orphan.parent = nil
+ // reset section objects above the fork
+ nchild := orphan.child
+ node := orphan
+ section := &section{bottom: orphan}
+ for node.section == nchild.section {
+ node = nchild
+ node.section = section
+ nchild = node.child
+ }
+ section.top = node
+ // set up a suicide
+ self.processSection(orphan).stop()
+ }
+ } else {
+ // child is on top of a chain need to close section
+ child.section.bottom = child
+ }
+ // adopt new child
+ parent.child = child
+ if !top {
+ parent.section.top = parent
+ // restart section process so that shorter section is scanned for blocks
+ parent.section.reset()
+ }
+ }
+
+ if child != nil {
+ if child.parent != parent {
+ stepParent := child.parent
+ if stepParent != nil {
+ if bottom {
+ stepParent.Lock()
+ stepParent.child = nil
+ stepParent.Unlock()
+ } else {
+ // we are on the same section
+ // if it is a aberrant reverse fork,
+ stepParent.child = nil
+ node := stepParent
+ nparent := stepParent.child
+ section := &section{top: stepParent}
+ for node.section == nparent.section {
+ node = nparent
+ node.section = section
+ node = node.parent
+ }
+ }
+ } else {
+ // linking to a root node, ie. parent is under the root of a chain
+ parent.section.top = parent
+ }
+ }
+ child.parent = parent
+ child.section.bottom = child
+ }
+ // this needed if someone lied about the parent before
+ child.knownParent = false
+
+ parent.sectionUnlock()
+ if child != nil {
+ child.sectionUnlock()
+ }
+}
+
+// this immediately kills the chain from node to end (inclusive) section by section
+func (self *BlockPool) killChain(node *poolNode, end *poolNode) {
+ poolLogger.Debugf("kill chain section with root node %v", node)
+
+ node.sectionLock()
+ node.section.abort()
+ self.set(node.hash, nil)
+ child := node.child
+ top := node.section.top
+ i := 1
+ self.wg.Add(1)
+ go func() {
+ var quit bool
+ for node != top && node != end && child != nil {
+ node = child
+ select {
+ case <-self.quit:
+ quit = true
+ break
+ default:
+ }
+ self.set(node.hash, nil)
+ child = node.child
+ }
+ poolLogger.Debugf("killed chain section of %v blocks with root node %v", i, node)
+ if !quit {
+ if node == top {
+ if node != end && child != nil && end != nil {
+ //
+ self.killChain(child, end)
+ }
+ } else {
+ if child != nil {
+ // delink rest of this section if ended midsection
+ child.section.bottom = child
+ child.parent = nil
+ }
+ }
+ }
+ node.section.bottom = nil
+ node.sectionUnlock()
+ self.wg.Done()
+ }()
+}
+
+// structure to store long range links on chain to skip along
+type section struct {
+ lock sync.RWMutex
+ bottom *poolNode
+ top *poolNode
+ controlC chan bool
+ resetC chan bool
+}
+
+func (self *section) start() {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if self.controlC != nil {
+ self.controlC <- true
+ }
+}
+
+func (self *section) stop() {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if self.controlC != nil {
+ self.controlC <- false
+ }
+}
+
+func (self *section) reset() {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if self.controlC != nil {
+ self.resetC <- true
+ self.controlC <- false
+ }
+}
+
+func (self *section) abort() {
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ if self.controlC != nil {
+ close(self.controlC)
+ self.controlC = nil
+ }
+}
+
+func (self *section) done() bool {
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ if self.controlC != nil {
+ return true
+ }
+ return false
+}
+
+func (self *BlockPool) get(hash []byte) (node *poolNode) {
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ return self.pool[string(hash)]
+}
+
+func (self *BlockPool) set(hash []byte, node *poolNode) {
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ self.pool[string(hash)] = node
+}
+
+// first time for block request, this iteration retrieves nodes of the chain
+// from node up to top (all the way if nil) via child links
+// copies the controller
+// and feeds nodeC channel
+// this is performed under section readlock to prevent top from going away
+// when
+func (self *BlockPool) foldUp(node *poolNode, nodeC chan *poolNode) {
+ self.wg.Add(1)
+ go func() {
+ node.sectionRLock()
+ defer node.sectionRUnlock()
+ for node != nil {
+ select {
+ case <-self.quit:
+ break
+ case nodeC <- node:
+ if node == node.section.top {
+ break
+ }
+ node = node.child
+ }
+ }
+ close(nodeC)
+ self.wg.Done()
+ }()
+}
+
+func (self *poolNode) Lock() {
+ self.sectionLock()
+ self.lock.Lock()
+}
+
+func (self *poolNode) Unlock() {
+ self.lock.Unlock()
+ self.sectionUnlock()
+}
+
+func (self *poolNode) RLock() {
+ self.lock.RLock()
+}
+
+func (self *poolNode) RUnlock() {
+ self.lock.RUnlock()
+}
+
+func (self *poolNode) sectionLock() {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ self.section.lock.Lock()
+}
+
+func (self *poolNode) sectionUnlock() {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ self.section.lock.Unlock()
+}
+
+func (self *poolNode) sectionRLock() {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ self.section.lock.RLock()
+}
+
+func (self *poolNode) sectionRUnlock() {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ self.section.lock.RUnlock()
+}
diff --git a/eth/block_pool_test.go b/eth/block_pool_test.go
new file mode 100644
index 000000000..315cc748d
--- /dev/null
+++ b/eth/block_pool_test.go
@@ -0,0 +1,198 @@
+package eth
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+ "os"
+ "sync"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethutil"
+ ethlogger "github.com/ethereum/go-ethereum/logger"
+)
+
+var sys = ethlogger.NewStdLogSystem(os.Stdout, log.LstdFlags, ethlogger.LogLevel(ethlogger.DebugDetailLevel))
+
+type testChainManager struct {
+ knownBlock func(hash []byte) bool
+ addBlock func(*types.Block) error
+ checkPoW func(*types.Block) bool
+}
+
+func (self *testChainManager) KnownBlock(hash []byte) bool {
+ if self.knownBlock != nil {
+ return self.knownBlock(hash)
+ }
+ return false
+}
+
+func (self *testChainManager) AddBlock(block *types.Block) error {
+ if self.addBlock != nil {
+ return self.addBlock(block)
+ }
+ return nil
+}
+
+func (self *testChainManager) CheckPoW(block *types.Block) bool {
+ if self.checkPoW != nil {
+ return self.checkPoW(block)
+ }
+ return false
+}
+
+func knownBlock(hashes ...[]byte) (f func([]byte) bool) {
+ f = func(block []byte) bool {
+ for _, hash := range hashes {
+ if bytes.Compare(block, hash) == 0 {
+ return true
+ }
+ }
+ return false
+ }
+ return
+}
+
+func addBlock(hashes ...[]byte) (f func(*types.Block) error) {
+ f = func(block *types.Block) error {
+ for _, hash := range hashes {
+ if bytes.Compare(block.Hash(), hash) == 0 {
+ return fmt.Errorf("invalid by test")
+ }
+ }
+ return nil
+ }
+ return
+}
+
+func checkPoW(hashes ...[]byte) (f func(*types.Block) bool) {
+ f = func(block *types.Block) bool {
+ for _, hash := range hashes {
+ if bytes.Compare(block.Hash(), hash) == 0 {
+ return false
+ }
+ }
+ return true
+ }
+ return
+}
+
+func newTestChainManager(knownBlocks [][]byte, invalidBlocks [][]byte, invalidPoW [][]byte) *testChainManager {
+ return &testChainManager{
+ knownBlock: knownBlock(knownBlocks...),
+ addBlock: addBlock(invalidBlocks...),
+ checkPoW: checkPoW(invalidPoW...),
+ }
+}
+
+type intToHash map[int][]byte
+
+type hashToInt map[string]int
+
+type testHashPool struct {
+ intToHash
+ hashToInt
+}
+
+func newHash(i int) []byte {
+ return crypto.Sha3([]byte(string(i)))
+}
+
+func newTestBlockPool(knownBlockIndexes []int, invalidBlockIndexes []int, invalidPoWIndexes []int) (hashPool *testHashPool, blockPool *BlockPool) {
+ hashPool = &testHashPool{make(intToHash), make(hashToInt)}
+ knownBlocks := hashPool.indexesToHashes(knownBlockIndexes)
+ invalidBlocks := hashPool.indexesToHashes(invalidBlockIndexes)
+ invalidPoW := hashPool.indexesToHashes(invalidPoWIndexes)
+ blockPool = NewBlockPool(newTestChainManager(knownBlocks, invalidBlocks, invalidPoW))
+ return
+}
+
+func (self *testHashPool) indexesToHashes(indexes []int) (hashes [][]byte) {
+ for _, i := range indexes {
+ hash, found := self.intToHash[i]
+ if !found {
+ hash = newHash(i)
+ self.intToHash[i] = hash
+ self.hashToInt[string(hash)] = i
+ }
+ hashes = append(hashes, hash)
+ }
+ return
+}
+
+func (self *testHashPool) hashesToIndexes(hashes [][]byte) (indexes []int) {
+ for _, hash := range hashes {
+ i, found := self.hashToInt[string(hash)]
+ if !found {
+ i = -1
+ }
+ indexes = append(indexes, i)
+ }
+ return
+}
+
+type protocolChecker struct {
+ blockHashesRequests []int
+ blocksRequests [][]int
+ invalidBlocks []error
+ hashPool *testHashPool
+ lock sync.Mutex
+}
+
+// -1 is special: not found (a hash never seen)
+func (self *protocolChecker) requestBlockHashesCallBack() (requestBlockHashesCallBack func([]byte) error) {
+ requestBlockHashesCallBack = func(hash []byte) error {
+ indexes := self.hashPool.hashesToIndexes([][]byte{hash})
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ self.blockHashesRequests = append(self.blockHashesRequests, indexes[0])
+ return nil
+ }
+ return
+}
+
+func (self *protocolChecker) requestBlocksCallBack() (requestBlocksCallBack func([][]byte) error) {
+ requestBlocksCallBack = func(hashes [][]byte) error {
+ indexes := self.hashPool.hashesToIndexes(hashes)
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ self.blocksRequests = append(self.blocksRequests, indexes)
+ return nil
+ }
+ return
+}
+
+func (self *protocolChecker) invalidBlockCallBack() (invalidBlockCallBack func(error)) {
+ invalidBlockCallBack = func(err error) {
+ self.invalidBlocks = append(self.invalidBlocks, err)
+ }
+ return
+}
+
+func TestAddPeer(t *testing.T) {
+ ethlogger.AddLogSystem(sys)
+ knownBlockIndexes := []int{0, 1}
+ invalidBlockIndexes := []int{2, 3}
+ invalidPoWIndexes := []int{4, 5}
+ hashPool, blockPool := newTestBlockPool(knownBlockIndexes, invalidBlockIndexes, invalidPoWIndexes)
+ // TODO:
+ // hashPool, blockPool, blockChainChecker = newTestBlockPool(knownBlockIndexes, invalidBlockIndexes, invalidPoWIndexes)
+ peer0 := &protocolChecker{
+ // blockHashesRequests: make([]int),
+ // blocksRequests: make([][]int),
+ // invalidBlocks: make([]error),
+ hashPool: hashPool,
+ }
+ best := blockPool.AddPeer(ethutil.Big1, newHash(100), "0",
+ peer0.requestBlockHashesCallBack(),
+ peer0.requestBlocksCallBack(),
+ peer0.invalidBlockCallBack(),
+ )
+ if !best {
+ t.Errorf("peer not accepted as best")
+ }
+ blockPool.Stop()
+
+}
diff --git a/eth/error.go b/eth/error.go
new file mode 100644
index 000000000..d1daad575
--- /dev/null
+++ b/eth/error.go
@@ -0,0 +1,71 @@
+package eth
+
+import (
+ "fmt"
+)
+
+const (
+ ErrMsgTooLarge = iota
+ ErrDecode
+ ErrInvalidMsgCode
+ ErrProtocolVersionMismatch
+ ErrNetworkIdMismatch
+ ErrGenesisBlockMismatch
+ ErrNoStatusMsg
+ ErrExtraStatusMsg
+ ErrInvalidBlock
+ ErrInvalidPoW
+ ErrUnrequestedBlock
+)
+
+var errorToString = map[int]string{
+ ErrMsgTooLarge: "Message too long",
+ ErrDecode: "Invalid message",
+ ErrInvalidMsgCode: "Invalid message code",
+ ErrProtocolVersionMismatch: "Protocol version mismatch",
+ ErrNetworkIdMismatch: "NetworkId mismatch",
+ ErrGenesisBlockMismatch: "Genesis block mismatch",
+ ErrNoStatusMsg: "No status message",
+ ErrExtraStatusMsg: "Extra status message",
+ ErrInvalidBlock: "Invalid block",
+ ErrInvalidPoW: "Invalid PoW",
+ ErrUnrequestedBlock: "Unrequested block",
+}
+
+type protocolError struct {
+ Code int
+ fatal bool
+ message string
+ format string
+ params []interface{}
+ // size int
+}
+
+func newProtocolError(code int, format string, params ...interface{}) *protocolError {
+ return &protocolError{Code: code, format: format, params: params}
+}
+
+func ProtocolError(code int, format string, params ...interface{}) (err *protocolError) {
+ err = newProtocolError(code, format, params...)
+ // report(err)
+ return
+}
+
+func (self protocolError) Error() (message string) {
+ message = self.message
+ if message == "" {
+ message, ok := errorToString[self.Code]
+ if !ok {
+ panic("invalid error code")
+ }
+ if self.format != "" {
+ message += ": " + fmt.Sprintf(self.format, self.params...)
+ }
+ self.message = message
+ }
+ return
+}
+
+func (self *protocolError) Fatal() bool {
+ return self.fatal
+}
diff --git a/eth/peer_util.go b/eth/peer_util.go
new file mode 100644
index 000000000..6cf80cde2
--- /dev/null
+++ b/eth/peer_util.go
@@ -0,0 +1,23 @@
+package eth
+
+import (
+ "encoding/json"
+
+ "github.com/ethereum/go-ethereum/ethutil"
+)
+
+func WritePeers(path string, addresses []string) {
+ if len(addresses) > 0 {
+ data, _ := json.MarshalIndent(addresses, "", " ")
+ ethutil.WriteFile(path, data)
+ }
+}
+
+func ReadPeers(path string) (ips []string, err error) {
+ var data string
+ data, err = ethutil.ReadAllFile(path)
+ if err != nil {
+ json.Unmarshal([]byte(data), &ips)
+ }
+ return
+}
diff --git a/eth/protocol.go b/eth/protocol.go
new file mode 100644
index 000000000..3b6f95d44
--- /dev/null
+++ b/eth/protocol.go
@@ -0,0 +1,319 @@
+package eth
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/rlp"
+)
+
+const (
+ ProtocolVersion = 49
+ NetworkId = 0
+ ProtocolLength = uint64(8)
+ ProtocolMaxMsgSize = 10 * 1024 * 1024
+)
+
+// eth protocol message codes
+const (
+ StatusMsg = iota
+ GetTxMsg // unused
+ TxMsg
+ GetBlockHashesMsg
+ BlockHashesMsg
+ GetBlocksMsg
+ BlocksMsg
+ NewBlockMsg
+)
+
+// ethProtocol represents the ethereum wire protocol
+// instance is running on each peer
+type ethProtocol struct {
+ txPool txPool
+ chainManager chainManager
+ blockPool blockPool
+ peer *p2p.Peer
+ id string
+ rw p2p.MsgReadWriter
+}
+
+// backend is the interface the ethereum protocol backend should implement
+// used as an argument to EthProtocol
+type txPool interface {
+ AddTransactions([]*types.Transaction)
+}
+
+type chainManager interface {
+ GetBlockHashesFromHash(hash []byte, amount uint64) (hashes [][]byte)
+ GetBlock(hash []byte) (block *types.Block)
+ Status() (td *big.Int, currentBlock []byte, genesisBlock []byte)
+}
+
+type blockPool interface {
+ AddBlockHashes(next func() ([]byte, bool), peerId string)
+ AddBlock(block *types.Block, peerId string)
+ AddPeer(td *big.Int, currentBlock []byte, peerId string, requestHashes func([]byte) error, requestBlocks func([][]byte) error, peerError func(int, string, ...interface{})) (best bool)
+ RemovePeer(peerId string)
+}
+
+// message structs used for rlp decoding
+type newBlockMsgData struct {
+ Block *types.Block
+ TD *big.Int
+}
+
+type getBlockHashesMsgData struct {
+ Hash []byte
+ Amount uint64
+}
+
+// main entrypoint, wrappers starting a server running the eth protocol
+// use this constructor to attach the protocol ("class") to server caps
+// the Dev p2p layer then runs the protocol instance on each peer
+func EthProtocol(txPool txPool, chainManager chainManager, blockPool blockPool) p2p.Protocol {
+ return p2p.Protocol{
+ Name: "eth",
+ Version: ProtocolVersion,
+ Length: ProtocolLength,
+ Run: func(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
+ return runEthProtocol(txPool, chainManager, blockPool, peer, rw)
+ },
+ }
+}
+
+// the main loop that handles incoming messages
+// note RemovePeer in the post-disconnect hook
+func runEthProtocol(txPool txPool, chainManager chainManager, blockPool blockPool, peer *p2p.Peer, rw p2p.MsgReadWriter) (err error) {
+ self := &ethProtocol{
+ txPool: txPool,
+ chainManager: chainManager,
+ blockPool: blockPool,
+ rw: rw,
+ peer: peer,
+ id: (string)(peer.Identity().Pubkey()),
+ }
+ err = self.handleStatus()
+ if err == nil {
+ for {
+ err = self.handle()
+ if err != nil {
+ fmt.Println(err)
+ self.blockPool.RemovePeer(self.id)
+ break
+ }
+ }
+ }
+ return
+}
+
+func (self *ethProtocol) handle() error {
+ msg, err := self.rw.ReadMsg()
+ if err != nil {
+ return err
+ }
+ if msg.Size > ProtocolMaxMsgSize {
+ return ProtocolError(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize)
+ }
+ // make sure that the payload has been fully consumed
+ defer msg.Discard()
+
+ switch msg.Code {
+
+ case StatusMsg:
+ return ProtocolError(ErrExtraStatusMsg, "")
+
+ case TxMsg:
+ // TODO: rework using lazy RLP stream
+ var txs []*types.Transaction
+ if err := msg.Decode(&txs); err != nil {
+ return ProtocolError(ErrDecode, "%v", err)
+ }
+ self.txPool.AddTransactions(txs)
+
+ case GetBlockHashesMsg:
+ var request getBlockHashesMsgData
+ if err := msg.Decode(&request); err != nil {
+ return ProtocolError(ErrDecode, "%v", err)
+ }
+ hashes := self.chainManager.GetBlockHashesFromHash(request.Hash, request.Amount)
+ return self.rw.EncodeMsg(BlockHashesMsg, ethutil.ByteSliceToInterface(hashes)...)
+
+ case BlockHashesMsg:
+ // TODO: redo using lazy decode , this way very inefficient on known chains
+ msgStream := rlp.NewListStream(msg.Payload, uint64(msg.Size))
+ var err error
+ iter := func() (hash []byte, ok bool) {
+ hash, err = msgStream.Bytes()
+ if err == nil {
+ ok = true
+ }
+ return
+ }
+ self.blockPool.AddBlockHashes(iter, self.id)
+ if err != nil && err != rlp.EOL {
+ return ProtocolError(ErrDecode, "%v", err)
+ }
+
+ case GetBlocksMsg:
+ var blockHashes [][]byte
+ if err := msg.Decode(&blockHashes); err != nil {
+ return ProtocolError(ErrDecode, "%v", err)
+ }
+ max := int(math.Min(float64(len(blockHashes)), blockHashesBatchSize))
+ var blocks []interface{}
+ for i, hash := range blockHashes {
+ if i >= max {
+ break
+ }
+ block := self.chainManager.GetBlock(hash)
+ if block != nil {
+ blocks = append(blocks, block.Value().Raw())
+ }
+ }
+ return self.rw.EncodeMsg(BlocksMsg, blocks...)
+
+ case BlocksMsg:
+ msgStream := rlp.NewListStream(msg.Payload, uint64(msg.Size))
+ for {
+ var block *types.Block
+ if err := msgStream.Decode(&block); err != nil {
+ if err == rlp.EOL {
+ break
+ } else {
+ return ProtocolError(ErrDecode, "%v", err)
+ }
+ }
+ self.blockPool.AddBlock(block, self.id)
+ }
+
+ case NewBlockMsg:
+ var request newBlockMsgData
+ if err := msg.Decode(&request); err != nil {
+ return ProtocolError(ErrDecode, "%v", err)
+ }
+ hash := request.Block.Hash()
+ // to simplify backend interface adding a new block
+ // uses AddPeer followed by AddHashes, AddBlock only if peer is the best peer
+ // (or selected as new best peer)
+ if self.blockPool.AddPeer(request.TD, hash, self.id, self.requestBlockHashes, self.requestBlocks, self.protoErrorDisconnect) {
+ called := true
+ iter := func() (hash []byte, ok bool) {
+ if called {
+ called = false
+ return hash, true
+ } else {
+ return
+ }
+ }
+ self.blockPool.AddBlockHashes(iter, self.id)
+ self.blockPool.AddBlock(request.Block, self.id)
+ }
+
+ default:
+ return ProtocolError(ErrInvalidMsgCode, "%v", msg.Code)
+ }
+ return nil
+}
+
+type statusMsgData struct {
+ ProtocolVersion uint
+ NetworkId uint
+ TD *big.Int
+ CurrentBlock []byte
+ GenesisBlock []byte
+}
+
+func (self *ethProtocol) statusMsg() p2p.Msg {
+ td, currentBlock, genesisBlock := self.chainManager.Status()
+
+ return p2p.NewMsg(StatusMsg,
+ uint32(ProtocolVersion),
+ uint32(NetworkId),
+ td,
+ currentBlock,
+ genesisBlock,
+ )
+}
+
+func (self *ethProtocol) handleStatus() error {
+ // send precanned status message
+ if err := self.rw.WriteMsg(self.statusMsg()); err != nil {
+ return err
+ }
+
+ // read and handle remote status
+ msg, err := self.rw.ReadMsg()
+ if err != nil {
+ return err
+ }
+
+ if msg.Code != StatusMsg {
+ return ProtocolError(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, StatusMsg)
+ }
+
+ if msg.Size > ProtocolMaxMsgSize {
+ return ProtocolError(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize)
+ }
+
+ var status statusMsgData
+ if err := msg.Decode(&status); err != nil {
+ return ProtocolError(ErrDecode, "%v", err)
+ }
+
+ _, _, genesisBlock := self.chainManager.Status()
+
+ if bytes.Compare(status.GenesisBlock, genesisBlock) != 0 {
+ return ProtocolError(ErrGenesisBlockMismatch, "%x (!= %x)", status.GenesisBlock, genesisBlock)
+ }
+
+ if status.NetworkId != NetworkId {
+ return ProtocolError(ErrNetworkIdMismatch, "%d (!= %d)", status.NetworkId, NetworkId)
+ }
+
+ if ProtocolVersion != status.ProtocolVersion {
+ return ProtocolError(ErrProtocolVersionMismatch, "%d (!= %d)", status.ProtocolVersion, ProtocolVersion)
+ }
+
+ self.peer.Infof("Peer is [eth] capable (%d/%d). TD=%v H=%x\n", status.ProtocolVersion, status.NetworkId, status.TD, status.CurrentBlock[:4])
+
+ //self.blockPool.AddPeer(status.TD, status.CurrentBlock, self.id, self.requestBlockHashes, self.requestBlocks, self.protoErrorDisconnect)
+ self.peer.Infoln("AddPeer(IGNORED)")
+
+ return nil
+}
+
+func (self *ethProtocol) requestBlockHashes(from []byte) error {
+ self.peer.Debugf("fetching hashes (%d) %x...\n", blockHashesBatchSize, from[0:4])
+ return self.rw.EncodeMsg(GetBlockHashesMsg, from, blockHashesBatchSize)
+}
+
+func (self *ethProtocol) requestBlocks(hashes [][]byte) error {
+ self.peer.Debugf("fetching %v blocks", len(hashes))
+ return self.rw.EncodeMsg(GetBlocksMsg, ethutil.ByteSliceToInterface(hashes))
+}
+
+func (self *ethProtocol) protoError(code int, format string, params ...interface{}) (err *protocolError) {
+ err = ProtocolError(code, format, params...)
+ if err.Fatal() {
+ self.peer.Errorln(err)
+ } else {
+ self.peer.Debugln(err)
+ }
+ return
+}
+
+func (self *ethProtocol) protoErrorDisconnect(code int, format string, params ...interface{}) {
+ err := ProtocolError(code, format, params...)
+ if err.Fatal() {
+ self.peer.Errorln(err)
+ // disconnect
+ } else {
+ self.peer.Debugln(err)
+ }
+
+}
diff --git a/eth/protocol_test.go b/eth/protocol_test.go
new file mode 100644
index 000000000..322aec7b7
--- /dev/null
+++ b/eth/protocol_test.go
@@ -0,0 +1,232 @@
+package eth
+
+import (
+ "io"
+ "math/big"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/p2p"
+)
+
+type testMsgReadWriter struct {
+ in chan p2p.Msg
+ out chan p2p.Msg
+}
+
+func (self *testMsgReadWriter) In(msg p2p.Msg) {
+ self.in <- msg
+}
+
+func (self *testMsgReadWriter) Out(msg p2p.Msg) {
+ self.in <- msg
+}
+
+func (self *testMsgReadWriter) WriteMsg(msg p2p.Msg) error {
+ self.out <- msg
+ return nil
+}
+
+func (self *testMsgReadWriter) EncodeMsg(code uint64, data ...interface{}) error {
+ return self.WriteMsg(p2p.NewMsg(code, data))
+}
+
+func (self *testMsgReadWriter) ReadMsg() (p2p.Msg, error) {
+ msg, ok := <-self.in
+ if !ok {
+ return msg, io.EOF
+ }
+ return msg, nil
+}
+
+func errorCheck(t *testing.T, expCode int, err error) {
+ perr, ok := err.(*protocolError)
+ if ok && perr != nil {
+ if code := perr.Code; code != expCode {
+ ok = false
+ }
+ }
+ if !ok {
+ t.Errorf("expected error code %v, got %v", ErrNoStatusMsg, err)
+ }
+}
+
+type TestBackend struct {
+ getTransactions func() []*types.Transaction
+ addTransactions func(txs []*types.Transaction)
+ getBlockHashes func(hash []byte, amount uint32) (hashes [][]byte)
+ addBlockHashes func(next func() ([]byte, bool), peerId string)
+ getBlock func(hash []byte) *types.Block
+ addBlock func(block *types.Block, peerId string) (err error)
+ addPeer func(td *big.Int, currentBlock []byte, peerId string, requestHashes func([]byte) error, requestBlocks func([][]byte) error, invalidBlock func(error)) (best bool)
+ removePeer func(peerId string)
+ status func() (td *big.Int, currentBlock []byte, genesisBlock []byte)
+}
+
+func (self *TestBackend) GetTransactions() (txs []*types.Transaction) {
+ if self.getTransactions != nil {
+ txs = self.getTransactions()
+ }
+ return
+}
+
+func (self *TestBackend) AddTransactions(txs []*types.Transaction) {
+ if self.addTransactions != nil {
+ self.addTransactions(txs)
+ }
+}
+
+func (self *TestBackend) GetBlockHashes(hash []byte, amount uint32) (hashes [][]byte) {
+ if self.getBlockHashes != nil {
+ hashes = self.getBlockHashes(hash, amount)
+ }
+ return
+}
+
+<<<<<<< HEAD
+<<<<<<< HEAD
+func (self *TestBackend) AddBlockHashes(next func() ([]byte, bool), peerId string) {
+ if self.addBlockHashes != nil {
+ self.addBlockHashes(next, peerId)
+ }
+}
+
+=======
+func (self *TestBackend) AddHash(hash []byte, peer *p2p.Peer) (more bool) {
+ if self.addHash != nil {
+ more = self.addHash(hash, peer)
+=======
+func (self *TestBackend) AddBlockHashes(next func() ([]byte, bool), peerId string) {
+ if self.addBlockHashes != nil {
+ self.addBlockHashes(next, peerId)
+>>>>>>> eth protocol changes
+ }
+}
+<<<<<<< HEAD
+>>>>>>> initial commit for eth-p2p integration
+=======
+
+>>>>>>> eth protocol changes
+func (self *TestBackend) GetBlock(hash []byte) (block *types.Block) {
+ if self.getBlock != nil {
+ block = self.getBlock(hash)
+ }
+ return
+}
+
+<<<<<<< HEAD
+<<<<<<< HEAD
+func (self *TestBackend) AddBlock(block *types.Block, peerId string) (err error) {
+ if self.addBlock != nil {
+ err = self.addBlock(block, peerId)
+=======
+func (self *TestBackend) AddBlock(td *big.Int, block *types.Block, peer *p2p.Peer) (fetchHashes bool, err error) {
+ if self.addBlock != nil {
+ fetchHashes, err = self.addBlock(td, block, peer)
+>>>>>>> initial commit for eth-p2p integration
+=======
+func (self *TestBackend) AddBlock(block *types.Block, peerId string) (err error) {
+ if self.addBlock != nil {
+ err = self.addBlock(block, peerId)
+>>>>>>> eth protocol changes
+ }
+ return
+}
+
+<<<<<<< HEAD
+<<<<<<< HEAD
+func (self *TestBackend) AddPeer(td *big.Int, currentBlock []byte, peerId string, requestBlockHashes func([]byte) error, requestBlocks func([][]byte) error, invalidBlock func(error)) (best bool) {
+ if self.addPeer != nil {
+ best = self.addPeer(td, currentBlock, peerId, requestBlockHashes, requestBlocks, invalidBlock)
+=======
+func (self *TestBackend) AddPeer(td *big.Int, currentBlock []byte, peer *p2p.Peer) (fetchHashes bool) {
+ if self.addPeer != nil {
+ fetchHashes = self.addPeer(td, currentBlock, peer)
+>>>>>>> initial commit for eth-p2p integration
+=======
+func (self *TestBackend) AddPeer(td *big.Int, currentBlock []byte, peerId string, requestBlockHashes func([]byte) error, requestBlocks func([][]byte) error, invalidBlock func(error)) (best bool) {
+ if self.addPeer != nil {
+ best = self.addPeer(td, currentBlock, peerId, requestBlockHashes, requestBlocks, invalidBlock)
+>>>>>>> eth protocol changes
+ }
+ return
+}
+
+<<<<<<< HEAD
+<<<<<<< HEAD
+=======
+>>>>>>> eth protocol changes
+func (self *TestBackend) RemovePeer(peerId string) {
+ if self.removePeer != nil {
+ self.removePeer(peerId)
+ }
+}
+
+<<<<<<< HEAD
+=======
+>>>>>>> initial commit for eth-p2p integration
+=======
+>>>>>>> eth protocol changes
+func (self *TestBackend) Status() (td *big.Int, currentBlock []byte, genesisBlock []byte) {
+ if self.status != nil {
+ td, currentBlock, genesisBlock = self.status()
+ }
+ return
+}
+
+<<<<<<< HEAD
+<<<<<<< HEAD
+=======
+>>>>>>> eth protocol changes
+// TODO: refactor this into p2p/client_identity
+type peerId struct {
+ pubkey []byte
+}
+
+func (self *peerId) String() string {
+ return "test peer"
+}
+
+func (self *peerId) Pubkey() (pubkey []byte) {
+ pubkey = self.pubkey
+ if len(pubkey) == 0 {
+ pubkey = crypto.GenerateNewKeyPair().PublicKey
+ self.pubkey = pubkey
+ }
+ return
+}
+
+func testPeer() *p2p.Peer {
+ return p2p.NewPeer(&peerId{}, []p2p.Cap{})
+}
+
+func TestErrNoStatusMsg(t *testing.T) {
+<<<<<<< HEAD
+=======
+func TestEth(t *testing.T) {
+>>>>>>> initial commit for eth-p2p integration
+=======
+>>>>>>> eth protocol changes
+ quit := make(chan bool)
+ rw := &testMsgReadWriter{make(chan p2p.Msg, 10), make(chan p2p.Msg, 10)}
+ testBackend := &TestBackend{}
+ var err error
+ go func() {
+<<<<<<< HEAD
+<<<<<<< HEAD
+ err = runEthProtocol(testBackend, testPeer(), rw)
+=======
+ err = runEthProtocol(testBackend, nil, rw)
+>>>>>>> initial commit for eth-p2p integration
+=======
+ err = runEthProtocol(testBackend, testPeer(), rw)
+>>>>>>> eth protocol changes
+ close(quit)
+ }()
+ statusMsg := p2p.NewMsg(4)
+ rw.In(statusMsg)
+ <-quit
+ errorCheck(t, ErrNoStatusMsg, err)
+ // read(t, remote, []byte("hello, world"), nil)
+}
diff --git a/ethereum.go b/ethereum.go
deleted file mode 100644
index 879a14bd5..000000000
--- a/ethereum.go
+++ /dev/null
@@ -1,661 +0,0 @@
-package eth
-
-import (
- "container/list"
- "encoding/json"
- "fmt"
- "math/big"
- "math/rand"
- "net"
- "path"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/ethereum/go-ethereum/chain"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/state"
- "github.com/ethereum/go-ethereum/wire"
-)
-
-const (
- seedTextFileUri string = "http://www.ethereum.org/servers.poc3.txt"
- seedNodeAddress = "poc-7.ethdev.com:30303"
-)
-
-var loggerger = logger.NewLogger("SERV")
-
-func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) {
- // Loop thru the peers and close them (if we had them)
- for e := peers.Front(); e != nil; e = e.Next() {
- callback(e.Value.(*Peer), e)
- }
-}
-
-const (
- processReapingTimeout = 60 // TODO increase
-)
-
-type Ethereum struct {
- // Channel for shutting down the ethereum
- shutdownChan chan bool
- quit chan bool
-
- // DB interface
- db ethutil.Database
- // State manager for processing new blocks and managing the over all states
- blockManager *chain.BlockManager
- // The transaction pool. Transaction can be pushed on this pool
- // for later including in the blocks
- txPool *chain.TxPool
- // The canonical chain
- blockChain *chain.ChainManager
- // The block pool
- blockPool *BlockPool
- // Eventer
- eventMux event.TypeMux
- // Peers
- peers *list.List
- // Nonce
- Nonce uint64
-
- Addr net.Addr
- Port string
-
- blacklist [][]byte
-
- peerMut sync.Mutex
-
- // Capabilities for outgoing peers
- serverCaps Caps
-
- nat NAT
-
- // Specifies the desired amount of maximum peers
- MaxPeers int
-
- Mining bool
-
- listening bool
-
- RpcServer *rpc.JsonRpcServer
-
- keyManager *crypto.KeyManager
-
- clientIdentity wire.ClientIdentity
-
- isUpToDate bool
-
- filterMu sync.RWMutex
- filterId int
- filters map[int]*chain.Filter
-}
-
-func New(db ethutil.Database, clientIdentity wire.ClientIdentity, keyManager *crypto.KeyManager, caps Caps, usePnp bool) (*Ethereum, error) {
- var err error
- var nat NAT
-
- if usePnp {
- nat, err = Discover()
- if err != nil {
- loggerger.Debugln("UPnP failed", err)
- }
- }
-
- bootstrapDb(db)
-
- ethutil.Config.Db = db
-
- nonce, _ := ethutil.RandomUint64()
- ethereum := &Ethereum{
- shutdownChan: make(chan bool),
- quit: make(chan bool),
- db: db,
- peers: list.New(),
- Nonce: nonce,
- serverCaps: caps,
- nat: nat,
- keyManager: keyManager,
- clientIdentity: clientIdentity,
- isUpToDate: true,
- filters: make(map[int]*chain.Filter),
- }
-
- ethereum.blockPool = NewBlockPool(ethereum)
- ethereum.txPool = chain.NewTxPool(ethereum)
- ethereum.blockChain = chain.NewChainManager()
- ethereum.blockManager = chain.NewBlockManager(ethereum)
- ethereum.blockChain.SetProcessor(ethereum.blockManager)
-
- // Start the tx pool
- ethereum.txPool.Start()
-
- return ethereum, nil
-}
-
-func (s *Ethereum) KeyManager() *crypto.KeyManager {
- return s.keyManager
-}
-
-func (s *Ethereum) ClientIdentity() wire.ClientIdentity {
- return s.clientIdentity
-}
-
-func (s *Ethereum) ChainManager() *chain.ChainManager {
- return s.blockChain
-}
-
-func (s *Ethereum) BlockManager() *chain.BlockManager {
- return s.blockManager
-}
-
-func (s *Ethereum) TxPool() *chain.TxPool {
- return s.txPool
-}
-func (s *Ethereum) BlockPool() *BlockPool {
- return s.blockPool
-}
-func (s *Ethereum) EventMux() *event.TypeMux {
- return &s.eventMux
-}
-func (self *Ethereum) Db() ethutil.Database {
- return self.db
-}
-
-func (s *Ethereum) ServerCaps() Caps {
- return s.serverCaps
-}
-func (s *Ethereum) IsMining() bool {
- return s.Mining
-}
-func (s *Ethereum) PeerCount() int {
- return s.peers.Len()
-}
-func (s *Ethereum) IsUpToDate() bool {
- upToDate := true
- eachPeer(s.peers, func(peer *Peer, e *list.Element) {
- if atomic.LoadInt32(&peer.connected) == 1 {
- if peer.catchingUp == true && peer.versionKnown {
- upToDate = false
- }
- }
- })
- return upToDate
-}
-func (s *Ethereum) PushPeer(peer *Peer) {
- s.peers.PushBack(peer)
-}
-func (s *Ethereum) IsListening() bool {
- return s.listening
-}
-
-func (s *Ethereum) HighestTDPeer() (td *big.Int) {
- td = big.NewInt(0)
-
- eachPeer(s.peers, func(p *Peer, v *list.Element) {
- if p.td.Cmp(td) > 0 {
- td = p.td
- }
- })
-
- return
-}
-
-func (self *Ethereum) BlacklistPeer(peer *Peer) {
- self.blacklist = append(self.blacklist, peer.pubkey)
-}
-
-func (s *Ethereum) AddPeer(conn net.Conn) {
- peer := NewPeer(conn, s, true)
-
- if peer != nil {
- if s.peers.Len() < s.MaxPeers {
- peer.Start()
- } else {
- loggerger.Debugf("Max connected peers reached. Not adding incoming peer.")
- }
- }
-}
-
-func (s *Ethereum) ProcessPeerList(addrs []string) {
- for _, addr := range addrs {
- // TODO Probably requires some sanity checks
- s.ConnectToPeer(addr)
- }
-}
-
-func (s *Ethereum) ConnectToPeer(addr string) error {
- if s.peers.Len() < s.MaxPeers {
- var alreadyConnected bool
-
- ahost, aport, _ := net.SplitHostPort(addr)
- var chost string
-
- ips, err := net.LookupIP(ahost)
-
- if err != nil {
- return err
- } else {
- // If more then one ip is available try stripping away the ipv6 ones
- if len(ips) > 1 {
- var ipsv4 []net.IP
- // For now remove the ipv6 addresses
- for _, ip := range ips {
- if strings.Contains(ip.String(), "::") {
- continue
- } else {
- ipsv4 = append(ipsv4, ip)
- }
- }
- if len(ipsv4) == 0 {
- return fmt.Errorf("[SERV] No IPV4 addresses available for hostname")
- }
-
- // Pick a random ipv4 address, simulating round-robin DNS.
- rand.Seed(time.Now().UTC().UnixNano())
- i := rand.Intn(len(ipsv4))
- chost = ipsv4[i].String()
- } else {
- if len(ips) == 0 {
- return fmt.Errorf("[SERV] No IPs resolved for the given hostname")
- return nil
- }
- chost = ips[0].String()
- }
- }
-
- eachPeer(s.peers, func(p *Peer, v *list.Element) {
- if p.conn == nil {
- return
- }
- phost, pport, _ := net.SplitHostPort(p.conn.RemoteAddr().String())
-
- if phost == chost && pport == aport {
- alreadyConnected = true
- //loggerger.Debugf("Peer %s already added.\n", chost)
- return
- }
- })
-
- if alreadyConnected {
- return nil
- }
-
- NewOutboundPeer(addr, s, s.serverCaps)
- }
-
- return nil
-}
-
-func (s *Ethereum) OutboundPeers() []*Peer {
- // Create a new peer slice with at least the length of the total peers
- outboundPeers := make([]*Peer, s.peers.Len())
- length := 0
- eachPeer(s.peers, func(p *Peer, e *list.Element) {
- if !p.inbound && p.conn != nil {
- outboundPeers[length] = p
- length++
- }
- })
-
- return outboundPeers[:length]
-}
-
-func (s *Ethereum) InboundPeers() []*Peer {
- // Create a new peer slice with at least the length of the total peers
- inboundPeers := make([]*Peer, s.peers.Len())
- length := 0
- eachPeer(s.peers, func(p *Peer, e *list.Element) {
- if p.inbound {
- inboundPeers[length] = p
- length++
- }
- })
-
- return inboundPeers[:length]
-}
-
-func (s *Ethereum) InOutPeers() []*Peer {
- // Reap the dead peers first
- s.reapPeers()
-
- // Create a new peer slice with at least the length of the total peers
- inboundPeers := make([]*Peer, s.peers.Len())
- length := 0
- eachPeer(s.peers, func(p *Peer, e *list.Element) {
- // Only return peers with an actual ip
- if len(p.host) > 0 {
- inboundPeers[length] = p
- length++
- }
- })
-
- return inboundPeers[:length]
-}
-
-func (s *Ethereum) Broadcast(msgType wire.MsgType, data []interface{}) {
- msg := wire.NewMessage(msgType, data)
- s.BroadcastMsg(msg)
-}
-
-func (s *Ethereum) BroadcastMsg(msg *wire.Msg) {
- eachPeer(s.peers, func(p *Peer, e *list.Element) {
- p.QueueMessage(msg)
- })
-}
-
-func (s *Ethereum) Peers() *list.List {
- return s.peers
-}
-
-func (s *Ethereum) reapPeers() {
- eachPeer(s.peers, func(p *Peer, e *list.Element) {
- if atomic.LoadInt32(&p.disconnect) == 1 || (p.inbound && (time.Now().Unix()-p.lastPong) > int64(5*time.Minute)) {
- s.removePeerElement(e)
- }
- })
-}
-
-func (s *Ethereum) removePeerElement(e *list.Element) {
- s.peerMut.Lock()
- defer s.peerMut.Unlock()
-
- s.peers.Remove(e)
-
- s.eventMux.Post(PeerListEvent{s.peers})
-}
-
-func (s *Ethereum) RemovePeer(p *Peer) {
- eachPeer(s.peers, func(peer *Peer, e *list.Element) {
- if peer == p {
- s.removePeerElement(e)
- }
- })
-}
-
-func (s *Ethereum) reapDeadPeerHandler() {
- reapTimer := time.NewTicker(processReapingTimeout * time.Second)
-
- for {
- select {
- case <-reapTimer.C:
- s.reapPeers()
- }
- }
-}
-
-// Start the ethereum
-func (s *Ethereum) Start(seed bool) {
- s.blockPool.Start()
- s.blockManager.Start()
-
- // Bind to addr and port
- ln, err := net.Listen("tcp", ":"+s.Port)
- if err != nil {
- loggerger.Warnf("Port %s in use. Connection listening disabled. Acting as client", s.Port)
- s.listening = false
- } else {
- s.listening = true
- // Starting accepting connections
- loggerger.Infoln("Ready and accepting connections")
- // Start the peer handler
- go s.peerHandler(ln)
- }
-
- if s.nat != nil {
- go s.upnpUpdateThread()
- }
-
- // Start the reaping processes
- go s.reapDeadPeerHandler()
- go s.update()
- go s.filterLoop()
-
- if seed {
- s.Seed()
- }
- s.ConnectToPeer("localhost:40404")
- loggerger.Infoln("Server started")
-}
-
-func (s *Ethereum) Seed() {
- // Sorry Py person. I must blacklist. you perform badly
- s.blacklist = append(s.blacklist, ethutil.Hex2Bytes("64656330303561383532336435376331616537643864663236623336313863373537353163636634333530626263396330346237336262623931383064393031"))
- ips := PastPeers()
- if len(ips) > 0 {
- for _, ip := range ips {
- loggerger.Infoln("Connecting to previous peer ", ip)
- s.ConnectToPeer(ip)
- }
- } else {
- loggerger.Debugln("Retrieving seed nodes")
-
- // Eth-Go Bootstrapping
- ips, er := net.LookupIP("seed.bysh.me")
- if er == nil {
- peers := []string{}
- for _, ip := range ips {
- node := fmt.Sprintf("%s:%d", ip.String(), 30303)
- loggerger.Debugln("Found DNS Go Peer:", node)
- peers = append(peers, node)
- }
- s.ProcessPeerList(peers)
- }
-
- // Official DNS Bootstrapping
- _, nodes, err := net.LookupSRV("eth", "tcp", "ethereum.org")
- if err == nil {
- peers := []string{}
- // Iterate SRV nodes
- for _, n := range nodes {
- target := n.Target
- port := strconv.Itoa(int(n.Port))
- // Resolve target to ip (Go returns list, so may resolve to multiple ips?)
- addr, err := net.LookupHost(target)
- if err == nil {
- for _, a := range addr {
- // Build string out of SRV port and Resolved IP
- peer := net.JoinHostPort(a, port)
- loggerger.Debugln("Found DNS Bootstrap Peer:", peer)
- peers = append(peers, peer)
- }
- } else {
- loggerger.Debugln("Couldn't resolve :", target)
- }
- }
- // Connect to Peer list
- s.ProcessPeerList(peers)
- }
-
- s.ConnectToPeer(seedNodeAddress)
- }
-}
-
-func (s *Ethereum) peerHandler(listener net.Listener) {
- for {
- conn, err := listener.Accept()
- if err != nil {
- loggerger.Debugln(err)
-
- continue
- }
-
- go s.AddPeer(conn)
- }
-}
-
-func (s *Ethereum) Stop() {
- // Stop eventMux first, it will close all subscriptions.
- s.eventMux.Stop()
-
- // Close the database
- defer s.db.Close()
-
- var ips []string
- eachPeer(s.peers, func(p *Peer, e *list.Element) {
- ips = append(ips, p.conn.RemoteAddr().String())
- })
-
- if len(ips) > 0 {
- d, _ := json.MarshalIndent(ips, "", " ")
- ethutil.WriteFile(path.Join(ethutil.Config.ExecPath, "known_peers.json"), d)
- }
-
- eachPeer(s.peers, func(p *Peer, e *list.Element) {
- p.Stop()
- })
-
- close(s.quit)
-
- if s.RpcServer != nil {
- s.RpcServer.Stop()
- }
- s.txPool.Stop()
- s.blockManager.Stop()
- s.blockPool.Stop()
-
- loggerger.Infoln("Server stopped")
- close(s.shutdownChan)
-}
-
-// This function will wait for a shutdown and resumes main thread execution
-func (s *Ethereum) WaitForShutdown() {
- <-s.shutdownChan
-}
-
-func (s *Ethereum) upnpUpdateThread() {
- // Go off immediately to prevent code duplication, thereafter we renew
- // lease every 15 minutes.
- timer := time.NewTimer(5 * time.Minute)
- lport, _ := strconv.ParseInt(s.Port, 10, 16)
- first := true
-out:
- for {
- select {
- case <-timer.C:
- var err error
- _, err = s.nat.AddPortMapping("TCP", int(lport), int(lport), "eth listen port", 20*60)
- if err != nil {
- loggerger.Debugln("can't add UPnP port mapping:", err)
- break out
- }
- if first && err == nil {
- _, err = s.nat.GetExternalAddress()
- if err != nil {
- loggerger.Debugln("UPnP can't get external address:", err)
- continue out
- }
- first = false
- }
- timer.Reset(time.Minute * 15)
- case <-s.quit:
- break out
- }
- }
-
- timer.Stop()
-
- if err := s.nat.DeletePortMapping("TCP", int(lport), int(lport)); err != nil {
- loggerger.Debugln("unable to remove UPnP port mapping:", err)
- } else {
- loggerger.Debugln("succesfully disestablished UPnP port mapping")
- }
-}
-
-func (self *Ethereum) update() {
- upToDateTimer := time.NewTicker(1 * time.Second)
-
-out:
- for {
- select {
- case <-upToDateTimer.C:
- if self.IsUpToDate() && !self.isUpToDate {
- self.eventMux.Post(ChainSyncEvent{false})
- self.isUpToDate = true
- } else if !self.IsUpToDate() && self.isUpToDate {
- self.eventMux.Post(ChainSyncEvent{true})
- self.isUpToDate = false
- }
- case <-self.quit:
- break out
- }
- }
-}
-
-// InstallFilter adds filter for blockchain events.
-// The filter's callbacks will run for matching blocks and messages.
-// The filter should not be modified after it has been installed.
-func (self *Ethereum) InstallFilter(filter *chain.Filter) (id int) {
- self.filterMu.Lock()
- id = self.filterId
- self.filters[id] = filter
- self.filterId++
- self.filterMu.Unlock()
- return id
-}
-
-func (self *Ethereum) UninstallFilter(id int) {
- self.filterMu.Lock()
- delete(self.filters, id)
- self.filterMu.Unlock()
-}
-
-// GetFilter retrieves a filter installed using InstallFilter.
-// The filter may not be modified.
-func (self *Ethereum) GetFilter(id int) *chain.Filter {
- self.filterMu.RLock()
- defer self.filterMu.RUnlock()
- return self.filters[id]
-}
-
-func (self *Ethereum) filterLoop() {
- // Subscribe to events
- events := self.eventMux.Subscribe(chain.NewBlockEvent{}, state.Messages(nil))
- for event := range events.Chan() {
- switch event := event.(type) {
- case chain.NewBlockEvent:
- self.filterMu.RLock()
- for _, filter := range self.filters {
- if filter.BlockCallback != nil {
- filter.BlockCallback(event.Block)
- }
- }
- self.filterMu.RUnlock()
-
- case state.Messages:
- self.filterMu.RLock()
- for _, filter := range self.filters {
- if filter.MessageCallback != nil {
- msgs := filter.FilterMessages(event)
- if len(msgs) > 0 {
- filter.MessageCallback(msgs)
- }
- }
- }
- self.filterMu.RUnlock()
- }
- }
-}
-
-func bootstrapDb(db ethutil.Database) {
- d, _ := db.Get([]byte("ProtocolVersion"))
- protov := ethutil.NewValue(d).Uint()
-
- if protov == 0 {
- db.Put([]byte("ProtocolVersion"), ethutil.NewValue(ProtocolVersion).Bytes())
- }
-}
-
-func PastPeers() []string {
- var ips []string
- data, _ := ethutil.ReadAllFile(path.Join(ethutil.Config.ExecPath, "known_peers.json"))
- json.Unmarshal([]byte(data), &ips)
-
- return ips
-}
diff --git a/ethutil/big.go b/ethutil/big.go
index 07d1386e1..2ff1c72d8 100644
--- a/ethutil/big.go
+++ b/ethutil/big.go
@@ -62,6 +62,16 @@ func S256(x *big.Int) *big.Int {
}
}
+func FirstBitSet(v *big.Int) int {
+ for i := 0; i < v.BitLen(); i++ {
+ if v.Bit(i) > 0 {
+ return i
+ }
+ }
+
+ return v.BitLen()
+}
+
// Big to bytes
//
// Returns the bytes of a big integer with the size specified by **base**
diff --git a/ethutil/rlp.go b/ethutil/rlp.go
index 1fff2b28a..1bc1a58a7 100644
--- a/ethutil/rlp.go
+++ b/ethutil/rlp.go
@@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"math/big"
+ "reflect"
)
type RlpEncode interface {
@@ -97,6 +98,14 @@ var (
zeroRlp = big.NewInt(0x0)
)
+func intlen(i int64) (length int) {
+ for i > 0 {
+ i = i >> 8
+ length++
+ }
+ return
+}
+
func Encode(object interface{}) []byte {
var buff bytes.Buffer
@@ -168,6 +177,31 @@ func Encode(object interface{}) []byte {
}
WriteSliceHeader(len(b.Bytes()))
buff.Write(b.Bytes())
+ default:
+ // This is how it should have been from the start
+ // needs refactoring (@fjl)
+ v := reflect.ValueOf(t)
+ switch v.Kind() {
+ case reflect.Slice:
+ var b bytes.Buffer
+ for i := 0; i < v.Len(); i++ {
+ b.Write(Encode(v.Index(i).Interface()))
+ }
+
+ blen := b.Len()
+ if blen < 56 {
+ buff.WriteByte(byte(blen) + 0xc0)
+ } else {
+ ilen := byte(intlen(int64(blen)))
+ buff.WriteByte(ilen + 0xf7)
+ t := make([]byte, ilen)
+ for i := byte(0); i < ilen; i++ {
+ t[ilen-i-1] = byte(blen >> (i * 8))
+ }
+ buff.Write(t)
+ }
+ buff.ReadFrom(&b)
+ }
}
} else {
// Empty list for nil
diff --git a/ethutil/rlp_test.go b/ethutil/rlp_test.go
index 90057ab42..ff98d3269 100644
--- a/ethutil/rlp_test.go
+++ b/ethutil/rlp_test.go
@@ -7,6 +7,16 @@ import (
"testing"
)
+func TestNonInterfaceSlice(t *testing.T) {
+ vala := []string{"value1", "value2", "value3"}
+ valb := []interface{}{"value1", "value2", "value3"}
+ resa := Encode(vala)
+ resb := Encode(valb)
+ if !bytes.Equal(resa, resb) {
+ t.Errorf("expected []string & []interface{} to be equal")
+ }
+}
+
func TestRlpValueEncoding(t *testing.T) {
val := EmptyValue()
val.AppendList().Append(1).Append(2).Append(3)
diff --git a/ethutil/script_unix.go b/ethutil/script_unix.go
index 6827d4e2f..9250dda57 100644
--- a/ethutil/script_unix.go
+++ b/ethutil/script_unix.go
@@ -2,47 +2,17 @@
package ethutil
-import (
- "fmt"
- "strings"
-
- "github.com/ethereum/serpent-go"
- "github.com/obscuren/mutan"
- "github.com/obscuren/mutan/backends"
-)
+import "github.com/ethereum/serpent-go"
// General compile function
func Compile(script string, silent bool) (ret []byte, err error) {
if len(script) > 2 {
- line := strings.Split(script, "\n")[0]
-
- if len(line) > 1 && line[0:2] == "#!" {
- switch line {
- case "#!serpent":
- byteCode, err := serpent.Compile(script)
- if err != nil {
- return nil, err
- }
-
- return byteCode, nil
- }
- } else {
-
- compiler := mutan.NewCompiler(backend.NewEthereumBackend())
- compiler.Silent = silent
- byteCode, errors := compiler.Compile(strings.NewReader(script))
- if len(errors) > 0 {
- var errs string
- for _, er := range errors {
- if er != nil {
- errs += er.Error()
- }
- }
- return nil, fmt.Errorf("%v", errs)
- }
-
- return byteCode, nil
+ byteCode, err := serpent.Compile(script)
+ if err != nil {
+ return nil, err
}
+
+ return byteCode, nil
}
return nil, nil
diff --git a/ethutil/script_windows.go b/ethutil/script_windows.go
index ef239cd51..1dedc5f60 100644
--- a/ethutil/script_windows.go
+++ b/ethutil/script_windows.go
@@ -2,31 +2,10 @@
package ethutil
-import (
- "fmt"
- "strings"
-
- "github.com/obscuren/mutan"
- "github.com/obscuren/mutan/backends"
-)
-
// General compile function
func Compile(script string, silent bool) (ret []byte, err error) {
if len(script) > 2 {
- compiler := mutan.NewCompiler(backend.NewEthereumBackend())
- compiler.Silent = silent
- byteCode, errors := compiler.Compile(strings.NewReader(script))
- if len(errors) > 0 {
- var errs string
- for _, er := range errors {
- if er != nil {
- errs += er.Error()
- }
- }
- return nil, fmt.Errorf("%v", errs)
- }
-
- return byteCode, nil
+ return nil, nil
}
return nil, nil
diff --git a/ethutil/value.go b/ethutil/value.go
index 6417b0008..7d4a7d98c 100644
--- a/ethutil/value.go
+++ b/ethutil/value.go
@@ -397,5 +397,5 @@ func (it *ValueIterator) Value() *Value {
}
func (it *ValueIterator) Idx() int {
- return it.idx
+ return it.idx - 1
}
diff --git a/event/filter/filter.go b/event/filter/filter.go
new file mode 100644
index 000000000..9817d5782
--- /dev/null
+++ b/event/filter/filter.go
@@ -0,0 +1,70 @@
+package filter
+
+import "reflect"
+
+type Filter interface {
+ Compare(Filter) bool
+ Trigger(data interface{})
+}
+
+type FilterEvent struct {
+ filter Filter
+ data interface{}
+}
+
+type Filters struct {
+ id int
+ watchers map[int]Filter
+ ch chan FilterEvent
+
+ quit chan struct{}
+}
+
+func New() *Filters {
+ return &Filters{
+ ch: make(chan FilterEvent),
+ watchers: make(map[int]Filter),
+ quit: make(chan struct{}),
+ }
+}
+
+func (self *Filters) Start() {
+ go self.loop()
+}
+
+func (self *Filters) Stop() {
+ close(self.quit)
+}
+
+func (self *Filters) Notify(filter Filter, data interface{}) {
+ self.ch <- FilterEvent{filter, data}
+}
+
+func (self *Filters) Install(watcher Filter) int {
+ self.watchers[self.id] = watcher
+ self.id++
+
+ return self.id - 1
+}
+
+func (self *Filters) Uninstall(id int) {
+ delete(self.watchers, id)
+}
+
+func (self *Filters) loop() {
+out:
+ for {
+ select {
+ case <-self.quit:
+ break out
+ case event := <-self.ch:
+ for _, watcher := range self.watchers {
+ if reflect.TypeOf(watcher) == reflect.TypeOf(event.filter) {
+ if watcher.Compare(event.filter) {
+ watcher.Trigger(event.data)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/event/filter/filter_test.go b/event/filter/filter_test.go
new file mode 100644
index 000000000..815deb63a
--- /dev/null
+++ b/event/filter/filter_test.go
@@ -0,0 +1,34 @@
+package filter
+
+import "testing"
+
+func TestFilters(t *testing.T) {
+ var success bool
+ var failure bool
+
+ fm := New()
+ fm.Start()
+ fm.Install(Generic{
+ Str1: "hello",
+ Fn: func(data interface{}) {
+ success = data.(bool)
+ },
+ })
+ fm.Install(Generic{
+ Str1: "hello1",
+ Str2: "hello",
+ Fn: func(data interface{}) {
+ failure = true
+ },
+ })
+ fm.Notify(Generic{Str1: "hello"}, true)
+ fm.Stop()
+
+ if !success {
+ t.Error("expected 'hello' to be posted")
+ }
+
+ if failure {
+ t.Error("hello1 was triggered")
+ }
+}
diff --git a/event/filter/generic_filter.go b/event/filter/generic_filter.go
new file mode 100644
index 000000000..2ce0f0642
--- /dev/null
+++ b/event/filter/generic_filter.go
@@ -0,0 +1,32 @@
+package filter
+
+type Generic struct {
+ Str1, Str2, Str3 string
+ Data map[string]struct{}
+
+ Fn func(data interface{})
+}
+
+// self = registered, f = incoming
+func (self Generic) Compare(f Filter) bool {
+ var strMatch, dataMatch = true, true
+
+ filter := f.(Generic)
+ if (len(self.Str1) > 0 && filter.Str1 != self.Str1) ||
+ (len(self.Str2) > 0 && filter.Str2 != self.Str2) ||
+ (len(self.Str3) > 0 && filter.Str3 != self.Str3) {
+ strMatch = false
+ }
+
+ for k, _ := range self.Data {
+ if _, ok := filter.Data[k]; !ok {
+ return false
+ }
+ }
+
+ return strMatch && dataMatch
+}
+
+func (self Generic) Trigger(data interface{}) {
+ self.Fn(data)
+}
diff --git a/event/filter/old_filter.go b/event/filter/old_filter.go
new file mode 100644
index 000000000..1a9a88173
--- /dev/null
+++ b/event/filter/old_filter.go
@@ -0,0 +1,94 @@
+// XXX This is the old filter system specifically for messages. This is till in used and could use some refactoring
+package filter
+
+import (
+ "sync"
+
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/event"
+ "github.com/ethereum/go-ethereum/state"
+)
+
+type FilterManager struct {
+ eventMux *event.TypeMux
+
+ filterMu sync.RWMutex
+ filterId int
+ filters map[int]*core.Filter
+
+ quit chan struct{}
+}
+
+func NewFilterManager(mux *event.TypeMux) *FilterManager {
+ return &FilterManager{
+ eventMux: mux,
+ filters: make(map[int]*core.Filter),
+ }
+}
+
+func (self *FilterManager) Start() {
+ go self.filterLoop()
+}
+
+func (self *FilterManager) Stop() {
+ close(self.quit)
+}
+
+func (self *FilterManager) InstallFilter(filter *core.Filter) (id int) {
+ self.filterMu.Lock()
+ id = self.filterId
+ self.filters[id] = filter
+ self.filterId++
+ self.filterMu.Unlock()
+ return id
+}
+
+func (self *FilterManager) UninstallFilter(id int) {
+ self.filterMu.Lock()
+ delete(self.filters, id)
+ self.filterMu.Unlock()
+}
+
+// GetFilter retrieves a filter installed using InstallFilter.
+// The filter may not be modified.
+func (self *FilterManager) GetFilter(id int) *core.Filter {
+ self.filterMu.RLock()
+ defer self.filterMu.RUnlock()
+ return self.filters[id]
+}
+
+func (self *FilterManager) filterLoop() {
+ // Subscribe to events
+ events := self.eventMux.Subscribe(core.NewBlockEvent{}, state.Messages(nil))
+
+out:
+ for {
+ select {
+ case <-self.quit:
+ break out
+ case event := <-events.Chan():
+ switch event := event.(type) {
+ case core.NewBlockEvent:
+ self.filterMu.RLock()
+ for _, filter := range self.filters {
+ if filter.BlockCallback != nil {
+ filter.BlockCallback(event.Block)
+ }
+ }
+ self.filterMu.RUnlock()
+
+ case state.Messages:
+ self.filterMu.RLock()
+ for _, filter := range self.filters {
+ if filter.MessageCallback != nil {
+ msgs := filter.FilterMessages(event)
+ if len(msgs) > 0 {
+ filter.MessageCallback(msgs)
+ }
+ }
+ }
+ self.filterMu.RUnlock()
+ }
+ }
+ }
+}
diff --git a/events.go b/events.go
deleted file mode 100644
index 5fff1d831..000000000
--- a/events.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package eth
-
-import "container/list"
-
-type PeerListEvent struct {
- Peers *list.List
-}
-
-type ChainSyncEvent struct {
- InSync bool
-}
diff --git a/install.sh b/install.sh
index f6232af83..30a3802e4 100755
--- a/install.sh
+++ b/install.sh
@@ -1,15 +1,20 @@
#!/bin/sh
if [ "$1" == "" ]; then
- echo "Usage $0 executable branch ethereum develop"
- echo "executable ethereum or mist"
- echo "branch develop or master"
+ echo "Usage $0 executable branch"
+ echo "executable ethereum | mist"
+ echo "branch develop | master"
exit
fi
exe=$1
+path=$exe
branch=$2
+if [ "$branch" == "develop" ]; then
+ path="cmd/$exe"
+fi
+
# Test if go is installed
command -v go >/dev/null 2>&1 || { echo >&2 "Unable to find 'go'. This script requires go."; exit 1; }
@@ -19,20 +24,23 @@ if [ "$GOPATH" == "" ]; then
exit
fi
-echo "go get -u -d github.com/ethereum/go-ethereum/$exe"
-go get -v -u -d github.com/ethereum/go-ethereum/$exe
-if [ $? != 0 ]; then
- echo "go get failed"
- exit
-fi
-
-echo "eth-go"
+echo "changing branch to $branch"
cd $GOPATH/src/github.com/ethereum/go-ethereum
git checkout $branch
-echo "go-ethereum"
-cd $GOPATH/src/github.com/ethereum/go-ethereum/$exe
-git checkout $branch
+# installing package dependencies doesn't work for develop
+# branch as go get always pulls from master head
+# so build will continue to fail, but this installs locally
+# for people who git clone since go install will manage deps
+
+#echo "go get -u -d github.com/ethereum/go-ethereum/$path"
+#go get -v -u -d github.com/ethereum/go-ethereum/$path
+#if [ $? != 0 ]; then
+# echo "go get failed"
+# exit
+#fi
+
+cd $GOPATH/src/github.com/ethereum/go-ethereum/$path
if [ "$exe" == "mist" ]; then
echo "Building Mist GUI. Assuming Qt is installed. If this step"
@@ -42,9 +50,4 @@ else
fi
go install
-if [ $? == 0 ]; then
- echo "go install failed"
- exit
-fi
-
echo "done. Please run $exe :-)"
diff --git a/javascript/javascript_runtime.go b/javascript/javascript_runtime.go
index e8b785f50..af1405049 100644
--- a/javascript/javascript_runtime.go
+++ b/javascript/javascript_runtime.go
@@ -7,10 +7,10 @@ import (
"path"
"path/filepath"
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/chain"
- "github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
@@ -63,7 +63,7 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE {
// Subscribe to events
mux := ethereum.EventMux()
- re.events = mux.Subscribe(chain.NewBlockEvent{})
+ re.events = mux.Subscribe(core.NewBlockEvent{})
// We have to make sure that, whoever calls this, calls "Stop"
go re.mainLoop()
@@ -121,6 +121,7 @@ func (self *JSRE) initStdFuncs() {
eth.Set("startMining", self.startMining)
eth.Set("execBlock", self.execBlock)
eth.Set("dump", self.dump)
+ eth.Set("export", self.export)
}
/*
@@ -128,7 +129,7 @@ func (self *JSRE) initStdFuncs() {
*/
func (self *JSRE) dump(call otto.FunctionCall) otto.Value {
- var state *state.State
+ var state *state.StateDB
if len(call.ArgumentList) > 0 {
var block *types.Block
@@ -150,7 +151,7 @@ func (self *JSRE) dump(call otto.FunctionCall) otto.Value {
state = block.State()
} else {
- state = self.ethereum.BlockManager().CurrentState()
+ state = self.ethereum.ChainManager().State()
}
v, _ := self.Vm.ToValue(state.Dump())
@@ -202,7 +203,7 @@ func (self *JSRE) addPeer(call otto.FunctionCall) otto.Value {
if err != nil {
return otto.FalseValue()
}
- self.ethereum.ConnectToPeer(host)
+ self.ethereum.SuggestPeer(host)
return otto.TrueValue()
}
@@ -236,3 +237,20 @@ func (self *JSRE) execBlock(call otto.FunctionCall) otto.Value {
return otto.TrueValue()
}
+
+func (self *JSRE) export(call otto.FunctionCall) otto.Value {
+ fn, err := call.Argument(0).ToString()
+ if err != nil {
+ fmt.Println(err)
+ return otto.FalseValue()
+ }
+
+ data := self.ethereum.ChainManager().Export()
+
+ if err := ethutil.WriteFile(fn, data); err != nil {
+ fmt.Println(err)
+ return otto.FalseValue()
+ }
+
+ return otto.TrueValue()
+}
diff --git a/javascript/types.go b/javascript/types.go
index d5acaecce..cf5a6677b 100644
--- a/javascript/types.go
+++ b/javascript/types.go
@@ -3,7 +3,7 @@ package javascript
import (
"fmt"
- "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/ui"
diff --git a/miner/miner.go b/miner/miner.go
index 795385424..d909c228b 100644
--- a/miner/miner.go
+++ b/miner/miner.go
@@ -27,15 +27,15 @@ import (
"math/big"
"sort"
- "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/state"
+ "github.com/ethereum/go-ethereum/pow"
+ "github.com/ethereum/go-ethereum/pow/ezp"
- "github.com/ethereum/go-ethereum/chain"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/wire"
)
type LocalTx struct {
@@ -60,7 +60,7 @@ type Miner struct {
localTxs map[int]*LocalTx
localTxId int
- pow chain.PoW
+ pow pow.PoW
quitCh chan struct{}
powQuitCh chan struct{}
@@ -75,7 +75,7 @@ func New(coinbase []byte, eth *eth.Ethereum) *Miner {
return &Miner{
eth: eth,
powQuitCh: make(chan struct{}),
- pow: &chain.EasyPow{},
+ pow: ezp.New(),
mining: false,
localTxs: make(map[int]*LocalTx),
MinAcceptedGasPrice: big.NewInt(10000000000000),
@@ -83,7 +83,7 @@ func New(coinbase []byte, eth *eth.Ethereum) *Miner {
}
}
-func (self *Miner) GetPow() chain.PoW {
+func (self *Miner) GetPow() pow.PoW {
return self.pow
}
@@ -117,7 +117,7 @@ func (self *Miner) Start() {
self.powQuitCh = make(chan struct{})
mux := self.eth.EventMux()
- self.events = mux.Subscribe(chain.NewBlockEvent{}, chain.TxPreEvent{}, &LocalTx{})
+ self.events = mux.Subscribe(core.NewBlockEvent{}, core.TxPreEvent{}, &LocalTx{})
go self.update()
go self.mine()
@@ -148,7 +148,7 @@ out:
select {
case event := <-self.events.Chan():
switch event := event.(type) {
- case chain.NewBlockEvent:
+ case core.NewBlockEvent:
block := event.Block
if self.eth.ChainManager().HasBlock(block.Hash()) {
self.reset()
@@ -157,7 +157,7 @@ out:
} else if true {
// do uncle stuff
}
- case chain.TxPreEvent, *LocalTx:
+ case core.TxPreEvent, *LocalTx:
self.reset()
go self.mine()
}
@@ -168,7 +168,6 @@ out:
}
func (self *Miner) reset() {
- println("reset")
close(self.powQuitCh)
self.powQuitCh = make(chan struct{})
}
@@ -179,7 +178,6 @@ func (self *Miner) mine() {
chainMan = self.eth.ChainManager()
block = chainMan.NewBlock(self.Coinbase)
)
- block.MinGasPrice = self.MinAcceptedGasPrice
// Apply uncles
if len(self.uncles) > 0 {
@@ -194,7 +192,7 @@ func (self *Miner) mine() {
// Accumulate all valid transactions and apply them to the new state
// Error may be ignored. It's not important during mining
- receipts, txs, _, erroneous, err := blockManager.ProcessTransactions(coinbase, block.State(), block, block, transactions)
+ receipts, txs, _, erroneous, err := blockManager.ApplyTransactions(coinbase, block.State(), block, transactions, true)
if err != nil {
minerlogger.Debugln(err)
}
@@ -206,7 +204,7 @@ func (self *Miner) mine() {
// Accumulate the rewards included for this block
blockManager.AccumelateRewards(block.State(), block, parent)
- block.State().Update()
+ block.State().Update(ethutil.Big0)
minerlogger.Infof("Mining on block. Includes %v transactions", len(transactions))
@@ -214,16 +212,11 @@ func (self *Miner) mine() {
nonce := self.pow.Search(block, self.powQuitCh)
if nonce != nil {
block.Nonce = nonce
- lchain := chain.NewChain(types.Blocks{block})
- _, err := chainMan.TestChain(lchain)
+ err := chainMan.InsertChain(types.Blocks{block})
if err != nil {
minerlogger.Infoln(err)
} else {
- chainMan.InsertChain(lchain, func(block *types.Block, _ state.Messages) {
- self.eth.EventMux().Post(chain.NewBlockEvent{block})
- })
-
- self.eth.Broadcast(wire.MsgBlockTy, []interface{}{block.Value().Val})
+ self.eth.EventMux().Post(core.NewMinedBlockEvent{block})
minerlogger.Infof("🔨 Mined block %x\n", block.Hash())
minerlogger.Infoln(block)
@@ -235,23 +228,33 @@ func (self *Miner) mine() {
func (self *Miner) finiliseTxs() types.Transactions {
// Sort the transactions by nonce in case of odd network propagation
- var txs types.Transactions
+ actualSize := len(self.localTxs) // See copy below
+ txs := make(types.Transactions, actualSize+self.eth.TxPool().Size())
- state := self.eth.BlockManager().TransState()
+ state := self.eth.ChainManager().TransState()
// XXX This has to change. Coinbase is, for new, same as key.
key := self.eth.KeyManager()
- for _, ltx := range self.localTxs {
+ for i, ltx := range self.localTxs {
tx := types.NewTransactionMessage(ltx.To, ethutil.Big(ltx.Value), ethutil.Big(ltx.Gas), ethutil.Big(ltx.GasPrice), ltx.Data)
- tx.Nonce = state.GetNonce(self.Coinbase)
- state.SetNonce(self.Coinbase, tx.Nonce+1)
+ tx.SetNonce(state.GetNonce(self.Coinbase))
+ state.SetNonce(self.Coinbase, tx.Nonce()+1)
tx.Sign(key.PrivateKey())
- txs = append(txs, tx)
+ txs[i] = tx
+ }
+
+ // Faster than append
+ for _, tx := range self.eth.TxPool().GetTransactions() {
+ if tx.GasPrice().Cmp(self.MinAcceptedGasPrice) >= 0 {
+ txs[actualSize] = tx
+ actualSize++
+ }
}
- txs = append(txs, self.eth.TxPool().CurrentTransactions()...)
- sort.Sort(types.TxByNonce{txs})
+ newTransactions := make(types.Transactions, actualSize)
+ copy(newTransactions, txs[:actualSize])
+ sort.Sort(types.TxByNonce{newTransactions})
- return txs
+ return newTransactions
}
diff --git a/nat.go b/nat.go
deleted file mode 100644
index 999308eb2..000000000
--- a/nat.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package eth
-
-import (
- "net"
-)
-
-// protocol is either "udp" or "tcp"
-type NAT interface {
- GetExternalAddress() (addr net.IP, err error)
- AddPortMapping(protocol string, externalPort, internalPort int, description string, timeout int) (mappedExternalPort int, err error)
- DeletePortMapping(protocol string, externalPort, internalPort int) (err error)
-}
diff --git a/natpmp.go b/natpmp.go
deleted file mode 100644
index 489342a4b..000000000
--- a/natpmp.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package eth
-
-import (
- "fmt"
- "net"
-
- natpmp "github.com/jackpal/go-nat-pmp"
-)
-
-// Adapt the NAT-PMP protocol to the NAT interface
-
-// TODO:
-// + Register for changes to the external address.
-// + Re-register port mapping when router reboots.
-// + A mechanism for keeping a port mapping registered.
-
-type natPMPClient struct {
- client *natpmp.Client
-}
-
-func NewNatPMP(gateway net.IP) (nat NAT) {
- return &natPMPClient{natpmp.NewClient(gateway)}
-}
-
-func (n *natPMPClient) GetExternalAddress() (addr net.IP, err error) {
- response, err := n.client.GetExternalAddress()
- if err != nil {
- return
- }
- ip := response.ExternalIPAddress
- addr = net.IPv4(ip[0], ip[1], ip[2], ip[3])
- return
-}
-
-func (n *natPMPClient) AddPortMapping(protocol string, externalPort, internalPort int,
- description string, timeout int) (mappedExternalPort int, err error) {
- if timeout <= 0 {
- err = fmt.Errorf("timeout must not be <= 0")
- return
- }
- // Note order of port arguments is switched between our AddPortMapping and the client's AddPortMapping.
- response, err := n.client.AddPortMapping(protocol, internalPort, externalPort, timeout)
- if err != nil {
- return
- }
- mappedExternalPort = int(response.MappedExternalPort)
- return
-}
-
-func (n *natPMPClient) DeletePortMapping(protocol string, externalPort, internalPort int) (err error) {
- // To destroy a mapping, send an add-port with
- // an internalPort of the internal port to destroy, an external port of zero and a time of zero.
- _, err = n.client.AddPortMapping(protocol, internalPort, 0, 0)
- return
-}
diff --git a/natupnp.go b/natupnp.go
deleted file mode 100644
index c7f9eeb62..000000000
--- a/natupnp.go
+++ /dev/null
@@ -1,338 +0,0 @@
-package eth
-
-// Just enough UPnP to be able to forward ports
-//
-
-import (
- "bytes"
- "encoding/xml"
- "errors"
- "net"
- "net/http"
- "os"
- "strconv"
- "strings"
- "time"
-)
-
-type upnpNAT struct {
- serviceURL string
- ourIP string
-}
-
-func Discover() (nat NAT, err error) {
- ssdp, err := net.ResolveUDPAddr("udp4", "239.255.255.250:1900")
- if err != nil {
- return
- }
- conn, err := net.ListenPacket("udp4", ":0")
- if err != nil {
- return
- }
- socket := conn.(*net.UDPConn)
- defer socket.Close()
-
- err = socket.SetDeadline(time.Now().Add(10 * time.Second))
- if err != nil {
- return
- }
-
- st := "ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n"
- buf := bytes.NewBufferString(
- "M-SEARCH * HTTP/1.1\r\n" +
- "HOST: 239.255.255.250:1900\r\n" +
- st +
- "MAN: \"ssdp:discover\"\r\n" +
- "MX: 2\r\n\r\n")
- message := buf.Bytes()
- answerBytes := make([]byte, 1024)
- for i := 0; i < 3; i++ {
- _, err = socket.WriteToUDP(message, ssdp)
- if err != nil {
- return
- }
- var n int
- n, _, err = socket.ReadFromUDP(answerBytes)
- if err != nil {
- continue
- // socket.Close()
- // return
- }
- answer := string(answerBytes[0:n])
- if strings.Index(answer, "\r\n"+st) < 0 {
- continue
- }
- // HTTP header field names are case-insensitive.
- // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
- locString := "\r\nlocation: "
- answer = strings.ToLower(answer)
- locIndex := strings.Index(answer, locString)
- if locIndex < 0 {
- continue
- }
- loc := answer[locIndex+len(locString):]
- endIndex := strings.Index(loc, "\r\n")
- if endIndex < 0 {
- continue
- }
- locURL := loc[0:endIndex]
- var serviceURL string
- serviceURL, err = getServiceURL(locURL)
- if err != nil {
- return
- }
- var ourIP string
- ourIP, err = getOurIP()
- if err != nil {
- return
- }
- nat = &upnpNAT{serviceURL: serviceURL, ourIP: ourIP}
- return
- }
- err = errors.New("UPnP port discovery failed.")
- return
-}
-
-// service represents the Service type in an UPnP xml description.
-// Only the parts we care about are present and thus the xml may have more
-// fields than present in the structure.
-type service struct {
- ServiceType string `xml:"serviceType"`
- ControlURL string `xml:"controlURL"`
-}
-
-// deviceList represents the deviceList type in an UPnP xml description.
-// Only the parts we care about are present and thus the xml may have more
-// fields than present in the structure.
-type deviceList struct {
- XMLName xml.Name `xml:"deviceList"`
- Device []device `xml:"device"`
-}
-
-// serviceList represents the serviceList type in an UPnP xml description.
-// Only the parts we care about are present and thus the xml may have more
-// fields than present in the structure.
-type serviceList struct {
- XMLName xml.Name `xml:"serviceList"`
- Service []service `xml:"service"`
-}
-
-// device represents the device type in an UPnP xml description.
-// Only the parts we care about are present and thus the xml may have more
-// fields than present in the structure.
-type device struct {
- XMLName xml.Name `xml:"device"`
- DeviceType string `xml:"deviceType"`
- DeviceList deviceList `xml:"deviceList"`
- ServiceList serviceList `xml:"serviceList"`
-}
-
-// specVersion represents the specVersion in a UPnP xml description.
-// Only the parts we care about are present and thus the xml may have more
-// fields than present in the structure.
-type specVersion struct {
- XMLName xml.Name `xml:"specVersion"`
- Major int `xml:"major"`
- Minor int `xml:"minor"`
-}
-
-// root represents the Root document for a UPnP xml description.
-// Only the parts we care about are present and thus the xml may have more
-// fields than present in the structure.
-type root struct {
- XMLName xml.Name `xml:"root"`
- SpecVersion specVersion
- Device device
-}
-
-func getChildDevice(d *device, deviceType string) *device {
- dl := d.DeviceList.Device
- for i := 0; i < len(dl); i++ {
- if dl[i].DeviceType == deviceType {
- return &dl[i]
- }
- }
- return nil
-}
-
-func getChildService(d *device, serviceType string) *service {
- sl := d.ServiceList.Service
- for i := 0; i < len(sl); i++ {
- if sl[i].ServiceType == serviceType {
- return &sl[i]
- }
- }
- return nil
-}
-
-func getOurIP() (ip string, err error) {
- hostname, err := os.Hostname()
- if err != nil {
- return
- }
- p, err := net.LookupIP(hostname)
- if err != nil && len(p) > 0 {
- return
- }
- return p[0].String(), nil
-}
-
-func getServiceURL(rootURL string) (url string, err error) {
- r, err := http.Get(rootURL)
- if err != nil {
- return
- }
- defer r.Body.Close()
- if r.StatusCode >= 400 {
- err = errors.New(string(r.StatusCode))
- return
- }
- var root root
- err = xml.NewDecoder(r.Body).Decode(&root)
-
- if err != nil {
- return
- }
- a := &root.Device
- if a.DeviceType != "urn:schemas-upnp-org:device:InternetGatewayDevice:1" {
- err = errors.New("No InternetGatewayDevice")
- return
- }
- b := getChildDevice(a, "urn:schemas-upnp-org:device:WANDevice:1")
- if b == nil {
- err = errors.New("No WANDevice")
- return
- }
- c := getChildDevice(b, "urn:schemas-upnp-org:device:WANConnectionDevice:1")
- if c == nil {
- err = errors.New("No WANConnectionDevice")
- return
- }
- d := getChildService(c, "urn:schemas-upnp-org:service:WANIPConnection:1")
- if d == nil {
- err = errors.New("No WANIPConnection")
- return
- }
- url = combineURL(rootURL, d.ControlURL)
- return
-}
-
-func combineURL(rootURL, subURL string) string {
- protocolEnd := "://"
- protoEndIndex := strings.Index(rootURL, protocolEnd)
- a := rootURL[protoEndIndex+len(protocolEnd):]
- rootIndex := strings.Index(a, "/")
- return rootURL[0:protoEndIndex+len(protocolEnd)+rootIndex] + subURL
-}
-
-func soapRequest(url, function, message string) (r *http.Response, err error) {
- fullMessage := "<?xml version=\"1.0\" ?>" +
- "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" +
- "<s:Body>" + message + "</s:Body></s:Envelope>"
-
- req, err := http.NewRequest("POST", url, strings.NewReader(fullMessage))
- if err != nil {
- return nil, err
- }
- req.Header.Set("Content-Type", "text/xml ; charset=\"utf-8\"")
- req.Header.Set("User-Agent", "Darwin/10.0.0, UPnP/1.0, MiniUPnPc/1.3")
- //req.Header.Set("Transfer-Encoding", "chunked")
- req.Header.Set("SOAPAction", "\"urn:schemas-upnp-org:service:WANIPConnection:1#"+function+"\"")
- req.Header.Set("Connection", "Close")
- req.Header.Set("Cache-Control", "no-cache")
- req.Header.Set("Pragma", "no-cache")
-
- // log.Stderr("soapRequest ", req)
- //fmt.Println(fullMessage)
-
- r, err = http.DefaultClient.Do(req)
- if err != nil {
- return
- }
-
- if r.Body != nil {
- defer r.Body.Close()
- }
-
- if r.StatusCode >= 400 {
- // log.Stderr(function, r.StatusCode)
- err = errors.New("Error " + strconv.Itoa(r.StatusCode) + " for " + function)
- r = nil
- return
- }
- return
-}
-
-type statusInfo struct {
- externalIpAddress string
-}
-
-func (n *upnpNAT) getStatusInfo() (info statusInfo, err error) {
-
- message := "<u:GetStatusInfo xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\r\n" +
- "</u:GetStatusInfo>"
-
- var response *http.Response
- response, err = soapRequest(n.serviceURL, "GetStatusInfo", message)
- if err != nil {
- return
- }
-
- // TODO: Write a soap reply parser. It has to eat the Body and envelope tags...
-
- response.Body.Close()
- return
-}
-
-func (n *upnpNAT) GetExternalAddress() (addr net.IP, err error) {
- info, err := n.getStatusInfo()
- if err != nil {
- return
- }
- addr = net.ParseIP(info.externalIpAddress)
- return
-}
-
-func (n *upnpNAT) AddPortMapping(protocol string, externalPort, internalPort int, description string, timeout int) (mappedExternalPort int, err error) {
- // A single concatenation would break ARM compilation.
- message := "<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\r\n" +
- "<NewRemoteHost></NewRemoteHost><NewExternalPort>" + strconv.Itoa(externalPort)
- message += "</NewExternalPort><NewProtocol>" + protocol + "</NewProtocol>"
- message += "<NewInternalPort>" + strconv.Itoa(internalPort) + "</NewInternalPort>" +
- "<NewInternalClient>" + n.ourIP + "</NewInternalClient>" +
- "<NewEnabled>1</NewEnabled><NewPortMappingDescription>"
- message += description +
- "</NewPortMappingDescription><NewLeaseDuration>" + strconv.Itoa(timeout) +
- "</NewLeaseDuration></u:AddPortMapping>"
-
- var response *http.Response
- response, err = soapRequest(n.serviceURL, "AddPortMapping", message)
- if err != nil {
- return
- }
-
- // TODO: check response to see if the port was forwarded
- // log.Println(message, response)
- mappedExternalPort = externalPort
- _ = response
- return
-}
-
-func (n *upnpNAT) DeletePortMapping(protocol string, externalPort, internalPort int) (err error) {
-
- message := "<u:DeletePortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\r\n" +
- "<NewRemoteHost></NewRemoteHost><NewExternalPort>" + strconv.Itoa(externalPort) +
- "</NewExternalPort><NewProtocol>" + protocol + "</NewProtocol>" +
- "</u:DeletePortMapping>"
-
- var response *http.Response
- response, err = soapRequest(n.serviceURL, "DeletePortMapping", message)
- if err != nil {
- return
- }
-
- // TODO: check response to see if the port was deleted
- // log.Println(message, response)
- _ = response
- return
-}
diff --git a/p2p/client_identity.go b/p2p/client_identity.go
index 236b23106..bc865b63b 100644
--- a/p2p/client_identity.go
+++ b/p2p/client_identity.go
@@ -5,10 +5,10 @@ import (
"runtime"
)
-// should be used in Peer handleHandshake, incorporate Caps, ProtocolVersion, Pubkey etc.
+// ClientIdentity represents the identity of a peer.
type ClientIdentity interface {
- String() string
- Pubkey() []byte
+ String() string // human readable identity
+ Pubkey() []byte // 512-bit public key
}
type SimpleClientIdentity struct {
diff --git a/p2p/connection.go b/p2p/connection.go
deleted file mode 100644
index be366235d..000000000
--- a/p2p/connection.go
+++ /dev/null
@@ -1,275 +0,0 @@
-package p2p
-
-import (
- "bytes"
- // "fmt"
- "net"
- "time"
-
- "github.com/ethereum/go-ethereum/ethutil"
-)
-
-type Connection struct {
- conn net.Conn
- // conn NetworkConnection
- timeout time.Duration
- in chan []byte
- out chan []byte
- err chan *PeerError
- closingIn chan chan bool
- closingOut chan chan bool
-}
-
-// const readBufferLength = 2 //for testing
-
-const readBufferLength = 1440
-const partialsQueueSize = 10
-const maxPendingQueueSize = 1
-const defaultTimeout = 500
-
-var magicToken = []byte{34, 64, 8, 145}
-
-func (self *Connection) Open() {
- go self.startRead()
- go self.startWrite()
-}
-
-func (self *Connection) Close() {
- self.closeIn()
- self.closeOut()
-}
-
-func (self *Connection) closeIn() {
- errc := make(chan bool)
- self.closingIn <- errc
- <-errc
-}
-
-func (self *Connection) closeOut() {
- errc := make(chan bool)
- self.closingOut <- errc
- <-errc
-}
-
-func NewConnection(conn net.Conn, errchan chan *PeerError) *Connection {
- return &Connection{
- conn: conn,
- timeout: defaultTimeout,
- in: make(chan []byte),
- out: make(chan []byte),
- err: errchan,
- closingIn: make(chan chan bool, 1),
- closingOut: make(chan chan bool, 1),
- }
-}
-
-func (self *Connection) Read() <-chan []byte {
- return self.in
-}
-
-func (self *Connection) Write() chan<- []byte {
- return self.out
-}
-
-func (self *Connection) Error() <-chan *PeerError {
- return self.err
-}
-
-func (self *Connection) startRead() {
- payloads := make(chan []byte)
- done := make(chan *PeerError)
- pending := [][]byte{}
- var head []byte
- var wait time.Duration // initally 0 (no delay)
- read := time.After(wait * time.Millisecond)
-
- for {
- // if pending empty, nil channel blocks
- var in chan []byte
- if len(pending) > 0 {
- in = self.in // enable send case
- head = pending[0]
- } else {
- in = nil
- }
-
- select {
- case <-read:
- go self.read(payloads, done)
- case err := <-done:
- if err == nil { // no error but nothing to read
- if len(pending) < maxPendingQueueSize {
- wait = 100
- } else if wait == 0 {
- wait = 100
- } else {
- wait = 2 * wait
- }
- } else {
- self.err <- err // report error
- wait = 100
- }
- read = time.After(wait * time.Millisecond)
- case payload := <-payloads:
- pending = append(pending, payload)
- if len(pending) < maxPendingQueueSize {
- wait = 0
- } else {
- wait = 100
- }
- read = time.After(wait * time.Millisecond)
- case in <- head:
- pending = pending[1:]
- case errc := <-self.closingIn:
- errc <- true
- close(self.in)
- return
- }
-
- }
-}
-
-func (self *Connection) startWrite() {
- pending := [][]byte{}
- done := make(chan *PeerError)
- writing := false
- for {
- if len(pending) > 0 && !writing {
- writing = true
- go self.write(pending[0], done)
- }
- select {
- case payload := <-self.out:
- pending = append(pending, payload)
- case err := <-done:
- if err == nil {
- pending = pending[1:]
- writing = false
- } else {
- self.err <- err // report error
- }
- case errc := <-self.closingOut:
- errc <- true
- close(self.out)
- return
- }
- }
-}
-
-func pack(payload []byte) (packet []byte) {
- length := ethutil.NumberToBytes(uint32(len(payload)), 32)
- // return error if too long?
- // Write magic token and payload length (first 8 bytes)
- packet = append(magicToken, length...)
- packet = append(packet, payload...)
- return
-}
-
-func avoidPanic(done chan *PeerError) {
- if rec := recover(); rec != nil {
- err := NewPeerError(MiscError, " %v", rec)
- logger.Debugln(err)
- done <- err
- }
-}
-
-func (self *Connection) write(payload []byte, done chan *PeerError) {
- defer avoidPanic(done)
- var err *PeerError
- _, ok := self.conn.Write(pack(payload))
- if ok != nil {
- err = NewPeerError(WriteError, " %v", ok)
- logger.Debugln(err)
- }
- done <- err
-}
-
-func (self *Connection) read(payloads chan []byte, done chan *PeerError) {
- //defer avoidPanic(done)
-
- partials := make(chan []byte, partialsQueueSize)
- errc := make(chan *PeerError)
- go self.readPartials(partials, errc)
-
- packet := []byte{}
- length := 8
- start := true
- var err *PeerError
-out:
- for {
- // appends partials read via connection until packet is
- // - either parseable (>=8bytes)
- // - or complete (payload fully consumed)
- for len(packet) < length {
- partial, ok := <-partials
- if !ok { // partials channel is closed
- err = <-errc
- if err == nil && len(packet) > 0 {
- if start {
- err = NewPeerError(PacketTooShort, "%v", packet)
- } else {
- err = NewPeerError(PayloadTooShort, "%d < %d", len(packet), length)
- }
- }
- break out
- }
- packet = append(packet, partial...)
- }
- if start {
- // at least 8 bytes read, can validate packet
- if bytes.Compare(magicToken, packet[:4]) != 0 {
- err = NewPeerError(MagicTokenMismatch, " received %v", packet[:4])
- break
- }
- length = int(ethutil.BytesToNumber(packet[4:8]))
- packet = packet[8:]
-
- if length > 0 {
- start = false // now consuming payload
- } else { //penalize peer but read on
- self.err <- NewPeerError(EmptyPayload, "")
- length = 8
- }
- } else {
- // packet complete (payload fully consumed)
- payloads <- packet[:length]
- packet = packet[length:] // resclice packet
- start = true
- length = 8
- }
- }
-
- // this stops partials read via the connection, should we?
- //if err != nil {
- // select {
- // case errc <- err
- // default:
- //}
- done <- err
-}
-
-func (self *Connection) readPartials(partials chan []byte, errc chan *PeerError) {
- defer close(partials)
- for {
- // Give buffering some time
- self.conn.SetReadDeadline(time.Now().Add(self.timeout * time.Millisecond))
- buffer := make([]byte, readBufferLength)
- // read partial from connection
- bytesRead, err := self.conn.Read(buffer)
- if err == nil || err.Error() == "EOF" {
- if bytesRead > 0 {
- partials <- buffer[:bytesRead]
- }
- if err != nil && err.Error() == "EOF" {
- break
- }
- } else {
- // unexpected error, report to errc
- err := NewPeerError(ReadError, " %v", err)
- logger.Debugln(err)
- errc <- err
- return // will close partials channel
- }
- }
- close(errc)
-}
diff --git a/p2p/connection_test.go b/p2p/connection_test.go
deleted file mode 100644
index 76ee8021c..000000000
--- a/p2p/connection_test.go
+++ /dev/null
@@ -1,222 +0,0 @@
-package p2p
-
-import (
- "bytes"
- "fmt"
- "io"
- "net"
- "testing"
- "time"
-)
-
-type TestNetworkConnection struct {
- in chan []byte
- current []byte
- Out [][]byte
- addr net.Addr
-}
-
-func NewTestNetworkConnection(addr net.Addr) *TestNetworkConnection {
- return &TestNetworkConnection{
- in: make(chan []byte),
- current: []byte{},
- Out: [][]byte{},
- addr: addr,
- }
-}
-
-func (self *TestNetworkConnection) In(latency time.Duration, packets ...[]byte) {
- time.Sleep(latency)
- for _, s := range packets {
- self.in <- s
- }
-}
-
-func (self *TestNetworkConnection) Read(buff []byte) (n int, err error) {
- if len(self.current) == 0 {
- select {
- case self.current = <-self.in:
- default:
- return 0, io.EOF
- }
- }
- length := len(self.current)
- if length > len(buff) {
- copy(buff[:], self.current[:len(buff)])
- self.current = self.current[len(buff):]
- return len(buff), nil
- } else {
- copy(buff[:length], self.current[:])
- self.current = []byte{}
- return length, io.EOF
- }
-}
-
-func (self *TestNetworkConnection) Write(buff []byte) (n int, err error) {
- self.Out = append(self.Out, buff)
- fmt.Printf("net write %v\n%v\n", len(self.Out), buff)
- return len(buff), nil
-}
-
-func (self *TestNetworkConnection) Close() (err error) {
- return
-}
-
-func (self *TestNetworkConnection) LocalAddr() (addr net.Addr) {
- return
-}
-
-func (self *TestNetworkConnection) RemoteAddr() (addr net.Addr) {
- return self.addr
-}
-
-func (self *TestNetworkConnection) SetDeadline(t time.Time) (err error) {
- return
-}
-
-func (self *TestNetworkConnection) SetReadDeadline(t time.Time) (err error) {
- return
-}
-
-func (self *TestNetworkConnection) SetWriteDeadline(t time.Time) (err error) {
- return
-}
-
-func setupConnection() (*Connection, *TestNetworkConnection) {
- addr := &TestAddr{"test:30303"}
- net := NewTestNetworkConnection(addr)
- conn := NewConnection(net, NewPeerErrorChannel())
- conn.Open()
- return conn, net
-}
-
-func TestReadingNilPacket(t *testing.T) {
- conn, net := setupConnection()
- go net.In(0, []byte{})
- // time.Sleep(10 * time.Millisecond)
- select {
- case packet := <-conn.Read():
- t.Errorf("read %v", packet)
- case err := <-conn.Error():
- t.Errorf("incorrect error %v", err)
- default:
- }
- conn.Close()
-}
-
-func TestReadingShortPacket(t *testing.T) {
- conn, net := setupConnection()
- go net.In(0, []byte{0})
- select {
- case packet := <-conn.Read():
- t.Errorf("read %v", packet)
- case err := <-conn.Error():
- if err.Code != PacketTooShort {
- t.Errorf("incorrect error %v, expected %v", err.Code, PacketTooShort)
- }
- }
- conn.Close()
-}
-
-func TestReadingInvalidPacket(t *testing.T) {
- conn, net := setupConnection()
- go net.In(0, []byte{1, 0, 0, 0, 0, 0, 0, 0})
- select {
- case packet := <-conn.Read():
- t.Errorf("read %v", packet)
- case err := <-conn.Error():
- if err.Code != MagicTokenMismatch {
- t.Errorf("incorrect error %v, expected %v", err.Code, MagicTokenMismatch)
- }
- }
- conn.Close()
-}
-
-func TestReadingInvalidPayload(t *testing.T) {
- conn, net := setupConnection()
- go net.In(0, []byte{34, 64, 8, 145, 0, 0, 0, 2, 0})
- select {
- case packet := <-conn.Read():
- t.Errorf("read %v", packet)
- case err := <-conn.Error():
- if err.Code != PayloadTooShort {
- t.Errorf("incorrect error %v, expected %v", err.Code, PayloadTooShort)
- }
- }
- conn.Close()
-}
-
-func TestReadingEmptyPayload(t *testing.T) {
- conn, net := setupConnection()
- go net.In(0, []byte{34, 64, 8, 145, 0, 0, 0, 0})
- time.Sleep(10 * time.Millisecond)
- select {
- case packet := <-conn.Read():
- t.Errorf("read %v", packet)
- default:
- }
- select {
- case err := <-conn.Error():
- code := err.Code
- if code != EmptyPayload {
- t.Errorf("incorrect error, expected EmptyPayload, got %v", code)
- }
- default:
- t.Errorf("no error, expected EmptyPayload")
- }
- conn.Close()
-}
-
-func TestReadingCompletePacket(t *testing.T) {
- conn, net := setupConnection()
- go net.In(0, []byte{34, 64, 8, 145, 0, 0, 0, 1, 1})
- time.Sleep(10 * time.Millisecond)
- select {
- case packet := <-conn.Read():
- if bytes.Compare(packet, []byte{1}) != 0 {
- t.Errorf("incorrect payload read")
- }
- case err := <-conn.Error():
- t.Errorf("incorrect error %v", err)
- default:
- t.Errorf("nothing read")
- }
- conn.Close()
-}
-
-func TestReadingTwoCompletePackets(t *testing.T) {
- conn, net := setupConnection()
- go net.In(0, []byte{34, 64, 8, 145, 0, 0, 0, 1, 0, 34, 64, 8, 145, 0, 0, 0, 1, 1})
-
- for i := 0; i < 2; i++ {
- time.Sleep(10 * time.Millisecond)
- select {
- case packet := <-conn.Read():
- if bytes.Compare(packet, []byte{byte(i)}) != 0 {
- t.Errorf("incorrect payload read")
- }
- case err := <-conn.Error():
- t.Errorf("incorrect error %v", err)
- default:
- t.Errorf("nothing read")
- }
- }
- conn.Close()
-}
-
-func TestWriting(t *testing.T) {
- conn, net := setupConnection()
- conn.Write() <- []byte{0}
- time.Sleep(10 * time.Millisecond)
- if len(net.Out) == 0 {
- t.Errorf("no output")
- } else {
- out := net.Out[0]
- if bytes.Compare(out, []byte{34, 64, 8, 145, 0, 0, 0, 1, 0}) != 0 {
- t.Errorf("incorrect packet %v", out)
- }
- }
- conn.Close()
-}
-
-// hello packet with client id ABC: 0x22 40 08 91 00 00 00 08 84 00 00 00 43414243
diff --git a/p2p/message.go b/p2p/message.go
index 446e74dff..f5418ff47 100644
--- a/p2p/message.go
+++ b/p2p/message.go
@@ -1,75 +1,232 @@
package p2p
import (
- // "fmt"
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "io"
+ "io/ioutil"
+ "math/big"
+ "sync/atomic"
+
"github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/rlp"
)
-type MsgCode uint8
-
+// Msg defines the structure of a p2p message.
+//
+// Note that a Msg can only be sent once since the Payload reader is
+// consumed during sending. It is not possible to create a Msg and
+// send it any number of times. If you want to reuse an encoded
+// structure, encode the payload into a byte array and create a
+// separate Msg with a bytes.Reader as Payload for each send.
type Msg struct {
- code MsgCode // this is the raw code as per adaptive msg code scheme
- data *ethutil.Value
- encoded []byte
-}
-
-func (self *Msg) Code() MsgCode {
- return self.code
-}
-
-func (self *Msg) Data() *ethutil.Value {
- return self.data
-}
-
-func NewMsg(code MsgCode, params ...interface{}) (msg *Msg, err error) {
-
- // // data := [][]interface{}{}
- // data := []interface{}{}
- // for _, value := range params {
- // if encodable, ok := value.(ethutil.RlpEncodeDecode); ok {
- // data = append(data, encodable.RlpValue())
- // } else if raw, ok := value.([]interface{}); ok {
- // data = append(data, raw)
- // } else {
- // // data = append(data, interface{}(raw))
- // err = fmt.Errorf("Unable to encode object of type %T", value)
- // return
- // }
- // }
- return &Msg{
- code: code,
- data: ethutil.NewValue(interface{}(params)),
- }, nil
-}
-
-func NewMsgFromBytes(encoded []byte) (msg *Msg, err error) {
- value := ethutil.NewValueFromBytes(encoded)
- // Type of message
- code := value.Get(0).Uint()
- // Actual data
- data := value.SliceFrom(1)
-
- msg = &Msg{
- code: MsgCode(code),
- data: data,
- // data: ethutil.NewValue(data),
- encoded: encoded,
+ Code uint64
+ Size uint32 // size of the paylod
+ Payload io.Reader
+}
+
+// NewMsg creates an RLP-encoded message with the given code.
+func NewMsg(code uint64, params ...interface{}) Msg {
+ buf := new(bytes.Buffer)
+ for _, p := range params {
+ buf.Write(ethutil.Encode(p))
+ }
+ return Msg{Code: code, Size: uint32(buf.Len()), Payload: buf}
+}
+
+func encodePayload(params ...interface{}) []byte {
+ buf := new(bytes.Buffer)
+ for _, p := range params {
+ buf.Write(ethutil.Encode(p))
+ }
+ return buf.Bytes()
+}
+
+// Decode parse the RLP content of a message into
+// the given value, which must be a pointer.
+//
+// For the decoding rules, please see package rlp.
+func (msg Msg) Decode(val interface{}) error {
+ s := rlp.NewListStream(msg.Payload, uint64(msg.Size))
+ return s.Decode(val)
+}
+
+// Discard reads any remaining payload data into a black hole.
+func (msg Msg) Discard() error {
+ _, err := io.Copy(ioutil.Discard, msg.Payload)
+ return err
+}
+
+type MsgReader interface {
+ ReadMsg() (Msg, error)
+}
+
+type MsgWriter interface {
+ // WriteMsg sends an existing message.
+ // The Payload reader of the message is consumed.
+ // Note that messages can be sent only once.
+ WriteMsg(Msg) error
+
+ // EncodeMsg writes an RLP-encoded message with the given
+ // code and data elements.
+ EncodeMsg(code uint64, data ...interface{}) error
+}
+
+// MsgReadWriter provides reading and writing of encoded messages.
+type MsgReadWriter interface {
+ MsgReader
+ MsgWriter
+}
+
+var magicToken = []byte{34, 64, 8, 145}
+
+func writeMsg(w io.Writer, msg Msg) error {
+ // TODO: handle case when Size + len(code) + len(listhdr) overflows uint32
+ code := ethutil.Encode(uint32(msg.Code))
+ listhdr := makeListHeader(msg.Size + uint32(len(code)))
+ payloadLen := uint32(len(listhdr)) + uint32(len(code)) + msg.Size
+
+ start := make([]byte, 8)
+ copy(start, magicToken)
+ binary.BigEndian.PutUint32(start[4:], payloadLen)
+
+ for _, b := range [][]byte{start, listhdr, code} {
+ if _, err := w.Write(b); err != nil {
+ return err
+ }
+ }
+ _, err := io.CopyN(w, msg.Payload, int64(msg.Size))
+ return err
+}
+
+func makeListHeader(length uint32) []byte {
+ if length < 56 {
+ return []byte{byte(length + 0xc0)}
+ }
+ enc := big.NewInt(int64(length)).Bytes()
+ lenb := byte(len(enc)) + 0xf7
+ return append([]byte{lenb}, enc...)
+}
+
+// readMsg reads a message header from r.
+// It takes an rlp.ByteReader to ensure that the decoding doesn't buffer.
+func readMsg(r rlp.ByteReader) (msg Msg, err error) {
+ // read magic and payload size
+ start := make([]byte, 8)
+ if _, err = io.ReadFull(r, start); err != nil {
+ return msg, newPeerError(errRead, "%v", err)
+ }
+ if !bytes.HasPrefix(start, magicToken) {
+ return msg, newPeerError(errMagicTokenMismatch, "got %x, want %x", start[:4], magicToken)
+ }
+ size := binary.BigEndian.Uint32(start[4:])
+
+ // decode start of RLP message to get the message code
+ posr := &postrack{r, 0}
+ s := rlp.NewStream(posr)
+ if _, err := s.List(); err != nil {
+ return msg, err
+ }
+ code, err := s.Uint()
+ if err != nil {
+ return msg, err
+ }
+ payloadsize := size - posr.p
+ return Msg{code, payloadsize, io.LimitReader(r, int64(payloadsize))}, nil
+}
+
+// postrack wraps an rlp.ByteReader with a position counter.
+type postrack struct {
+ r rlp.ByteReader
+ p uint32
+}
+
+func (r *postrack) Read(buf []byte) (int, error) {
+ n, err := r.r.Read(buf)
+ r.p += uint32(n)
+ return n, err
+}
+
+func (r *postrack) ReadByte() (byte, error) {
+ b, err := r.r.ReadByte()
+ if err == nil {
+ r.p++
}
- return
+ return b, err
+}
+
+// MsgPipe creates a message pipe. Reads on one end are matched
+// with writes on the other. The pipe is full-duplex, both ends
+// implement MsgReadWriter.
+func MsgPipe() (*MsgPipeRW, *MsgPipeRW) {
+ var (
+ c1, c2 = make(chan Msg), make(chan Msg)
+ closing = make(chan struct{})
+ closed = new(int32)
+ rw1 = &MsgPipeRW{c1, c2, closing, closed}
+ rw2 = &MsgPipeRW{c2, c1, closing, closed}
+ )
+ return rw1, rw2
+}
+
+// ErrPipeClosed is returned from pipe operations after the
+// pipe has been closed.
+var ErrPipeClosed = errors.New("p2p: read or write on closed message pipe")
+
+// MsgPipeRW is an endpoint of a MsgReadWriter pipe.
+type MsgPipeRW struct {
+ w chan<- Msg
+ r <-chan Msg
+ closing chan struct{}
+ closed *int32
}
-func (self *Msg) Decode(offset MsgCode) {
- self.code = self.code - offset
+// WriteMsg sends a messsage on the pipe.
+// It blocks until the receiver has consumed the message payload.
+func (p *MsgPipeRW) WriteMsg(msg Msg) error {
+ if atomic.LoadInt32(p.closed) == 0 {
+ consumed := make(chan struct{}, 1)
+ msg.Payload = &eofSignal{msg.Payload, int64(msg.Size), consumed}
+ select {
+ case p.w <- msg:
+ if msg.Size > 0 {
+ // wait for payload read or discard
+ <-consumed
+ }
+ return nil
+ case <-p.closing:
+ }
+ }
+ return ErrPipeClosed
+}
+
+// EncodeMsg is a convenient shorthand for sending an RLP-encoded message.
+func (p *MsgPipeRW) EncodeMsg(code uint64, data ...interface{}) error {
+ return p.WriteMsg(NewMsg(code, data...))
+}
+
+// ReadMsg returns a message sent on the other end of the pipe.
+func (p *MsgPipeRW) ReadMsg() (Msg, error) {
+ if atomic.LoadInt32(p.closed) == 0 {
+ select {
+ case msg := <-p.r:
+ return msg, nil
+ case <-p.closing:
+ }
+ }
+ return Msg{}, ErrPipeClosed
}
-// encode takes an offset argument to implement adaptive message coding
-// the encoded message is memoized to make msgs relayed to several peers more efficient
-func (self *Msg) Encode(offset MsgCode) (res []byte) {
- if len(self.encoded) == 0 {
- res = ethutil.NewValue(append([]interface{}{byte(self.code + offset)}, self.data.Slice()...)).Encode()
- self.encoded = res
- } else {
- res = self.encoded
+// Close unblocks any pending ReadMsg and WriteMsg calls on both ends
+// of the pipe. They will return ErrPipeClosed. Note that Close does
+// not interrupt any reads from a message payload.
+func (p *MsgPipeRW) Close() error {
+ if atomic.AddInt32(p.closed, 1) != 1 {
+ // someone else is already closing
+ atomic.StoreInt32(p.closed, 1) // avoid overflow
+ return nil
}
- return
+ close(p.closing)
+ return nil
}
diff --git a/p2p/message_test.go b/p2p/message_test.go
index e9d46f2c3..066d2516d 100644
--- a/p2p/message_test.go
+++ b/p2p/message_test.go
@@ -1,38 +1,133 @@
package p2p
import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "runtime"
"testing"
+ "time"
+
+ "github.com/ethereum/go-ethereum/ethutil"
)
func TestNewMsg(t *testing.T) {
- msg, _ := NewMsg(3, 1, "000")
- if msg.Code() != 3 {
- t.Errorf("incorrect code %v", msg.Code())
+ msg := NewMsg(3, 1, "000")
+ if msg.Code != 3 {
+ t.Errorf("incorrect code %d, want %d", msg.Code)
}
- data0 := msg.Data().Get(0).Uint()
- data1 := string(msg.Data().Get(1).Bytes())
- if data0 != 1 {
- t.Errorf("incorrect data %v", data0)
+ if msg.Size != 5 {
+ t.Errorf("incorrect size %d, want %d", msg.Size, 5)
}
- if data1 != "000" {
- t.Errorf("incorrect data %v", data1)
+ pl, _ := ioutil.ReadAll(msg.Payload)
+ expect := []byte{0x01, 0x83, 0x30, 0x30, 0x30}
+ if !bytes.Equal(pl, expect) {
+ t.Errorf("incorrect payload content, got %x, want %x", pl, expect)
}
}
func TestEncodeDecodeMsg(t *testing.T) {
- msg, _ := NewMsg(3, 1, "000")
- encoded := msg.Encode(3)
- msg, _ = NewMsgFromBytes(encoded)
- msg.Decode(3)
- if msg.Code() != 3 {
- t.Errorf("incorrect code %v", msg.Code())
- }
- data0 := msg.Data().Get(0).Uint()
- data1 := msg.Data().Get(1).Str()
- if data0 != 1 {
- t.Errorf("incorrect data %v", data0)
- }
- if data1 != "000" {
- t.Errorf("incorrect data %v", data1)
+ msg := NewMsg(3, 1, "000")
+ buf := new(bytes.Buffer)
+ if err := writeMsg(buf, msg); err != nil {
+ t.Fatalf("encodeMsg error: %v", err)
+ }
+ // t.Logf("encoded: %x", buf.Bytes())
+
+ decmsg, err := readMsg(buf)
+ if err != nil {
+ t.Fatalf("readMsg error: %v", err)
+ }
+ if decmsg.Code != 3 {
+ t.Errorf("incorrect code %d, want %d", decmsg.Code, 3)
+ }
+ if decmsg.Size != 5 {
+ t.Errorf("incorrect size %d, want %d", decmsg.Size, 5)
+ }
+
+ var data struct {
+ I uint
+ S string
+ }
+ if err := decmsg.Decode(&data); err != nil {
+ t.Fatalf("Decode error: %v", err)
+ }
+ if data.I != 1 {
+ t.Errorf("incorrect data.I: got %v, expected %d", data.I, 1)
+ }
+ if data.S != "000" {
+ t.Errorf("incorrect data.S: got %q, expected %q", data.S, "000")
+ }
+}
+
+func TestDecodeRealMsg(t *testing.T) {
+ data := ethutil.Hex2Bytes("2240089100000080f87e8002b5457468657265756d282b2b292f5065657220536572766572204f6e652f76302e372e382f52656c656173652f4c696e75782f672b2bc082765fb84086dd80b7aefd6a6d2e3b93f4f300a86bfb6ef7bdc97cb03f793db6bb")
+ msg, err := readMsg(bytes.NewReader(data))
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+
+ if msg.Code != 0 {
+ t.Errorf("incorrect code %d, want %d", msg.Code, 0)
+ }
+}
+
+func ExampleMsgPipe() {
+ rw1, rw2 := MsgPipe()
+ go func() {
+ rw1.EncodeMsg(8, []byte{0, 0})
+ rw1.EncodeMsg(5, []byte{1, 1})
+ rw1.Close()
+ }()
+
+ for {
+ msg, err := rw2.ReadMsg()
+ if err != nil {
+ break
+ }
+ var data [1][]byte
+ msg.Decode(&data)
+ fmt.Printf("msg: %d, %x\n", msg.Code, data[0])
+ }
+ // Output:
+ // msg: 8, 0000
+ // msg: 5, 0101
+}
+
+func TestMsgPipeUnblockWrite(t *testing.T) {
+loop:
+ for i := 0; i < 100; i++ {
+ rw1, rw2 := MsgPipe()
+ done := make(chan struct{})
+ go func() {
+ if err := rw1.EncodeMsg(1); err == nil {
+ t.Error("EncodeMsg returned nil error")
+ } else if err != ErrPipeClosed {
+ t.Error("EncodeMsg returned wrong error: got %v, want %v", err, ErrPipeClosed)
+ }
+ close(done)
+ }()
+
+ // this call should ensure that EncodeMsg is waiting to
+ // deliver sometimes. if this isn't done, Close is likely to
+ // be executed before EncodeMsg starts and then we won't test
+ // all the cases.
+ runtime.Gosched()
+
+ rw2.Close()
+ select {
+ case <-done:
+ case <-time.After(200 * time.Millisecond):
+ t.Errorf("write didn't unblock")
+ break loop
+ }
+ }
+}
+
+// This test should panic if concurrent close isn't implemented correctly.
+func TestMsgPipeConcurrentClose(t *testing.T) {
+ rw1, _ := MsgPipe()
+ for i := 0; i < 10; i++ {
+ go rw1.Close()
}
}
diff --git a/p2p/messenger.go b/p2p/messenger.go
deleted file mode 100644
index d42ba1720..000000000
--- a/p2p/messenger.go
+++ /dev/null
@@ -1,220 +0,0 @@
-package p2p
-
-import (
- "fmt"
- "sync"
- "time"
-)
-
-const (
- handlerTimeout = 1000
-)
-
-type Handlers map[string](func(p *Peer) Protocol)
-
-type Messenger struct {
- conn *Connection
- peer *Peer
- handlers Handlers
- protocolLock sync.RWMutex
- protocols []Protocol
- offsets []MsgCode // offsets for adaptive message idss
- protocolTable map[string]int
- quit chan chan bool
- err chan *PeerError
- pulse chan bool
-}
-
-func NewMessenger(peer *Peer, conn *Connection, errchan chan *PeerError, handlers Handlers) *Messenger {
- baseProtocol := NewBaseProtocol(peer)
- return &Messenger{
- conn: conn,
- peer: peer,
- offsets: []MsgCode{baseProtocol.Offset()},
- handlers: handlers,
- protocols: []Protocol{baseProtocol},
- protocolTable: make(map[string]int),
- err: errchan,
- pulse: make(chan bool, 1),
- quit: make(chan chan bool, 1),
- }
-}
-
-func (self *Messenger) Start() {
- self.conn.Open()
- go self.messenger()
- self.protocolLock.RLock()
- defer self.protocolLock.RUnlock()
- self.protocols[0].Start()
-}
-
-func (self *Messenger) Stop() {
- // close pulse to stop ping pong monitoring
- close(self.pulse)
- self.protocolLock.RLock()
- defer self.protocolLock.RUnlock()
- for _, protocol := range self.protocols {
- protocol.Stop() // could be parallel
- }
- q := make(chan bool)
- self.quit <- q
- <-q
- self.conn.Close()
-}
-
-func (self *Messenger) messenger() {
- in := self.conn.Read()
- for {
- select {
- case payload, ok := <-in:
- //dispatches message to the protocol asynchronously
- if ok {
- go self.handle(payload)
- } else {
- return
- }
- case q := <-self.quit:
- q <- true
- return
- }
- }
-}
-
-// handles each message by dispatching to the appropriate protocol
-// using adaptive message codes
-// this function is started as a separate go routine for each message
-// it waits for the protocol response
-// then encodes and sends outgoing messages to the connection's write channel
-func (self *Messenger) handle(payload []byte) {
- // send ping to heartbeat channel signalling time of last message
- // select {
- // case self.pulse <- true:
- // default:
- // }
- self.pulse <- true
- // initialise message from payload
- msg, err := NewMsgFromBytes(payload)
- if err != nil {
- self.err <- NewPeerError(MiscError, " %v", err)
- return
- }
- // retrieves protocol based on message Code
- protocol, offset, peerErr := self.getProtocol(msg.Code())
- if err != nil {
- self.err <- peerErr
- return
- }
- // reset message code based on adaptive offset
- msg.Decode(offset)
- // dispatches
- response := make(chan *Msg)
- go protocol.HandleIn(msg, response)
- // protocol reponse timeout to prevent leaks
- timer := time.After(handlerTimeout * time.Millisecond)
- for {
- select {
- case outgoing, ok := <-response:
- // we check if response channel is not closed
- if ok {
- self.conn.Write() <- outgoing.Encode(offset)
- } else {
- return
- }
- case <-timer:
- return
- }
- }
-}
-
-// negotiated protocols
-// stores offsets needed for adaptive message id scheme
-
-// based on offsets set at handshake
-// get the right protocol to handle the message
-func (self *Messenger) getProtocol(code MsgCode) (Protocol, MsgCode, *PeerError) {
- self.protocolLock.RLock()
- defer self.protocolLock.RUnlock()
- base := MsgCode(0)
- for index, offset := range self.offsets {
- if code < offset {
- return self.protocols[index], base, nil
- }
- base = offset
- }
- return nil, MsgCode(0), NewPeerError(InvalidMsgCode, " %v", code)
-}
-
-func (self *Messenger) PingPong(timeout time.Duration, gracePeriod time.Duration, pingCallback func(), timeoutCallback func()) {
- fmt.Printf("pingpong keepalive started at %v", time.Now())
-
- timer := time.After(timeout)
- pinged := false
- for {
- select {
- case _, ok := <-self.pulse:
- if ok {
- pinged = false
- timer = time.After(timeout)
- } else {
- // pulse is closed, stop monitoring
- return
- }
- case <-timer:
- if pinged {
- fmt.Printf("timeout at %v", time.Now())
- timeoutCallback()
- return
- } else {
- fmt.Printf("pinged at %v", time.Now())
- pingCallback()
- timer = time.After(gracePeriod)
- pinged = true
- }
- }
- }
-}
-
-func (self *Messenger) AddProtocols(protocols []string) {
- self.protocolLock.Lock()
- defer self.protocolLock.Unlock()
- i := len(self.offsets)
- offset := self.offsets[i-1]
- for _, name := range protocols {
- protocolFunc, ok := self.handlers[name]
- if ok {
- protocol := protocolFunc(self.peer)
- self.protocolTable[name] = i
- i++
- offset += protocol.Offset()
- fmt.Println("offset ", name, offset)
-
- self.offsets = append(self.offsets, offset)
- self.protocols = append(self.protocols, protocol)
- protocol.Start()
- } else {
- fmt.Println("no ", name)
- // protocol not handled
- }
- }
-}
-
-func (self *Messenger) Write(protocol string, msg *Msg) error {
- self.protocolLock.RLock()
- defer self.protocolLock.RUnlock()
- i := 0
- offset := MsgCode(0)
- if len(protocol) > 0 {
- var ok bool
- i, ok = self.protocolTable[protocol]
- if !ok {
- return fmt.Errorf("protocol %v not handled by peer", protocol)
- }
- offset = self.offsets[i-1]
- }
- handler := self.protocols[i]
- // checking if protocol status/caps allows the message to be sent out
- if handler.HandleOut(msg) {
- self.conn.Write() <- msg.Encode(offset)
- }
- return nil
-}
diff --git a/p2p/messenger_test.go b/p2p/messenger_test.go
deleted file mode 100644
index 472d74515..000000000
--- a/p2p/messenger_test.go
+++ /dev/null
@@ -1,147 +0,0 @@
-package p2p
-
-import (
- // "fmt"
- "bytes"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/ethutil"
-)
-
-func setupMessenger(handlers Handlers) (*TestNetworkConnection, chan *PeerError, *Messenger) {
- errchan := NewPeerErrorChannel()
- addr := &TestAddr{"test:30303"}
- net := NewTestNetworkConnection(addr)
- conn := NewConnection(net, errchan)
- mess := NewMessenger(nil, conn, errchan, handlers)
- mess.Start()
- return net, errchan, mess
-}
-
-type TestProtocol struct {
- Msgs []*Msg
-}
-
-func (self *TestProtocol) Start() {
-}
-
-func (self *TestProtocol) Stop() {
-}
-
-func (self *TestProtocol) Offset() MsgCode {
- return MsgCode(5)
-}
-
-func (self *TestProtocol) HandleIn(msg *Msg, response chan *Msg) {
- self.Msgs = append(self.Msgs, msg)
- close(response)
-}
-
-func (self *TestProtocol) HandleOut(msg *Msg) bool {
- if msg.Code() > 3 {
- return false
- } else {
- return true
- }
-}
-
-func (self *TestProtocol) Name() string {
- return "a"
-}
-
-func Packet(offset MsgCode, code MsgCode, params ...interface{}) []byte {
- msg, _ := NewMsg(code, params...)
- encoded := msg.Encode(offset)
- packet := []byte{34, 64, 8, 145}
- packet = append(packet, ethutil.NumberToBytes(uint32(len(encoded)), 32)...)
- return append(packet, encoded...)
-}
-
-func TestRead(t *testing.T) {
- handlers := make(Handlers)
- testProtocol := &TestProtocol{Msgs: []*Msg{}}
- handlers["a"] = func(p *Peer) Protocol { return testProtocol }
- net, _, mess := setupMessenger(handlers)
- mess.AddProtocols([]string{"a"})
- defer mess.Stop()
- wait := 1 * time.Millisecond
- packet := Packet(16, 1, uint32(1), "000")
- go net.In(0, packet)
- time.Sleep(wait)
- if len(testProtocol.Msgs) != 1 {
- t.Errorf("msg not relayed to correct protocol")
- } else {
- if testProtocol.Msgs[0].Code() != 1 {
- t.Errorf("incorrect msg code relayed to protocol")
- }
- }
-}
-
-func TestWrite(t *testing.T) {
- handlers := make(Handlers)
- testProtocol := &TestProtocol{Msgs: []*Msg{}}
- handlers["a"] = func(p *Peer) Protocol { return testProtocol }
- net, _, mess := setupMessenger(handlers)
- mess.AddProtocols([]string{"a"})
- defer mess.Stop()
- wait := 1 * time.Millisecond
- msg, _ := NewMsg(3, uint32(1), "000")
- err := mess.Write("b", msg)
- if err == nil {
- t.Errorf("expect error for unknown protocol")
- }
- err = mess.Write("a", msg)
- if err != nil {
- t.Errorf("expect no error for known protocol: %v", err)
- } else {
- time.Sleep(wait)
- if len(net.Out) != 1 {
- t.Errorf("msg not written")
- } else {
- out := net.Out[0]
- packet := Packet(16, 3, uint32(1), "000")
- if bytes.Compare(out, packet) != 0 {
- t.Errorf("incorrect packet %v", out)
- }
- }
- }
-}
-
-func TestPulse(t *testing.T) {
- net, _, mess := setupMessenger(make(Handlers))
- defer mess.Stop()
- ping := false
- timeout := false
- pingTimeout := 10 * time.Millisecond
- gracePeriod := 200 * time.Millisecond
- go mess.PingPong(pingTimeout, gracePeriod, func() { ping = true }, func() { timeout = true })
- net.In(0, Packet(0, 1))
- if ping {
- t.Errorf("ping sent too early")
- }
- time.Sleep(pingTimeout + 100*time.Millisecond)
- if !ping {
- t.Errorf("no ping sent after timeout")
- }
- if timeout {
- t.Errorf("timeout too early")
- }
- ping = false
- net.In(0, Packet(0, 1))
- time.Sleep(pingTimeout + 100*time.Millisecond)
- if !ping {
- t.Errorf("no ping sent after timeout")
- }
- if timeout {
- t.Errorf("timeout too early")
- }
- ping = false
- time.Sleep(gracePeriod)
- if ping {
- t.Errorf("ping called twice")
- }
- if !timeout {
- t.Errorf("no timeout after grace period")
- }
-}
diff --git a/p2p/natpmp.go b/p2p/natpmp.go
index ff966d070..6714678c4 100644
--- a/p2p/natpmp.go
+++ b/p2p/natpmp.go
@@ -3,6 +3,7 @@ package p2p
import (
"fmt"
"net"
+ "time"
natpmp "github.com/jackpal/go-nat-pmp"
)
@@ -13,38 +14,37 @@ import (
// + Register for changes to the external address.
// + Re-register port mapping when router reboots.
// + A mechanism for keeping a port mapping registered.
+// + Discover gateway address automatically.
type natPMPClient struct {
client *natpmp.Client
}
-func NewNatPMP(gateway net.IP) (nat NAT) {
+// PMP returns a NAT traverser that uses NAT-PMP. The provided gateway
+// address should be the IP of your router.
+func PMP(gateway net.IP) (nat NAT) {
return &natPMPClient{natpmp.NewClient(gateway)}
}
-func (n *natPMPClient) GetExternalAddress() (addr net.IP, err error) {
+func (*natPMPClient) String() string {
+ return "NAT-PMP"
+}
+
+func (n *natPMPClient) GetExternalAddress() (net.IP, error) {
response, err := n.client.GetExternalAddress()
if err != nil {
- return
+ return nil, err
}
- ip := response.ExternalIPAddress
- addr = net.IPv4(ip[0], ip[1], ip[2], ip[3])
- return
+ return response.ExternalIPAddress[:], nil
}
-func (n *natPMPClient) AddPortMapping(protocol string, externalPort, internalPort int,
- description string, timeout int) (mappedExternalPort int, err error) {
- if timeout <= 0 {
- err = fmt.Errorf("timeout must not be <= 0")
- return
+func (n *natPMPClient) AddPortMapping(protocol string, extport, intport int, name string, lifetime time.Duration) error {
+ if lifetime <= 0 {
+ return fmt.Errorf("lifetime must not be <= 0")
}
// Note order of port arguments is switched between our AddPortMapping and the client's AddPortMapping.
- response, err := n.client.AddPortMapping(protocol, internalPort, externalPort, timeout)
- if err != nil {
- return
- }
- mappedExternalPort = int(response.MappedExternalPort)
- return
+ _, err := n.client.AddPortMapping(protocol, intport, extport, int(lifetime/time.Second))
+ return err
}
func (n *natPMPClient) DeletePortMapping(protocol string, externalPort, internalPort int) (err error) {
diff --git a/p2p/natupnp.go b/p2p/natupnp.go
index fa9798d4d..2e0d8ce8d 100644
--- a/p2p/natupnp.go
+++ b/p2p/natupnp.go
@@ -7,6 +7,7 @@ import (
"bytes"
"encoding/xml"
"errors"
+ "fmt"
"net"
"net/http"
"os"
@@ -15,28 +16,46 @@ import (
"time"
)
+const (
+ upnpDiscoverAttempts = 3
+ upnpDiscoverTimeout = 5 * time.Second
+)
+
+// UPNP returns a NAT port mapper that uses UPnP. It will attempt to
+// discover the address of your router using UDP broadcasts.
+func UPNP() NAT {
+ return &upnpNAT{}
+}
+
type upnpNAT struct {
serviceURL string
ourIP string
}
-func upnpDiscover(attempts int) (nat NAT, err error) {
+func (n *upnpNAT) String() string {
+ return "UPNP"
+}
+
+func (n *upnpNAT) discover() error {
+ if n.serviceURL != "" {
+ // already discovered
+ return nil
+ }
+
ssdp, err := net.ResolveUDPAddr("udp4", "239.255.255.250:1900")
if err != nil {
- return
+ return err
}
+ // TODO: try on all network interfaces simultaneously.
+ // Broadcasting on 0.0.0.0 could select a random interface
+ // to send on (platform specific).
conn, err := net.ListenPacket("udp4", ":0")
if err != nil {
- return
- }
- socket := conn.(*net.UDPConn)
- defer socket.Close()
-
- err = socket.SetDeadline(time.Now().Add(10 * time.Second))
- if err != nil {
- return
+ return err
}
+ defer conn.Close()
+ conn.SetDeadline(time.Now().Add(10 * time.Second))
st := "ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n"
buf := bytes.NewBufferString(
"M-SEARCH * HTTP/1.1\r\n" +
@@ -46,19 +65,16 @@ func upnpDiscover(attempts int) (nat NAT, err error) {
"MX: 2\r\n\r\n")
message := buf.Bytes()
answerBytes := make([]byte, 1024)
- for i := 0; i < attempts; i++ {
- _, err = socket.WriteToUDP(message, ssdp)
+ for i := 0; i < upnpDiscoverAttempts; i++ {
+ _, err = conn.WriteTo(message, ssdp)
if err != nil {
- return
+ return err
}
- var n int
- n, _, err = socket.ReadFromUDP(answerBytes)
+ nn, _, err := conn.ReadFrom(answerBytes)
if err != nil {
continue
- // socket.Close()
- // return
}
- answer := string(answerBytes[0:n])
+ answer := string(answerBytes[0:nn])
if strings.Index(answer, "\r\n"+st) < 0 {
continue
}
@@ -79,17 +95,81 @@ func upnpDiscover(attempts int) (nat NAT, err error) {
var serviceURL string
serviceURL, err = getServiceURL(locURL)
if err != nil {
- return
+ return err
}
var ourIP string
ourIP, err = getOurIP()
if err != nil {
- return
+ return err
}
- nat = &upnpNAT{serviceURL: serviceURL, ourIP: ourIP}
+ n.serviceURL = serviceURL
+ n.ourIP = ourIP
+ return nil
+ }
+ return errors.New("UPnP port discovery failed.")
+}
+
+func (n *upnpNAT) GetExternalAddress() (addr net.IP, err error) {
+ if err := n.discover(); err != nil {
+ return nil, err
+ }
+ info, err := n.getStatusInfo()
+ return net.ParseIP(info.externalIpAddress), err
+}
+
+func (n *upnpNAT) AddPortMapping(protocol string, extport, intport int, description string, lifetime time.Duration) error {
+ if err := n.discover(); err != nil {
+ return err
+ }
+
+ // A single concatenation would break ARM compilation.
+ message := "<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\r\n" +
+ "<NewRemoteHost></NewRemoteHost><NewExternalPort>" + strconv.Itoa(extport)
+ message += "</NewExternalPort><NewProtocol>" + protocol + "</NewProtocol>"
+ message += "<NewInternalPort>" + strconv.Itoa(extport) + "</NewInternalPort>" +
+ "<NewInternalClient>" + n.ourIP + "</NewInternalClient>" +
+ "<NewEnabled>1</NewEnabled><NewPortMappingDescription>"
+ message += description +
+ "</NewPortMappingDescription><NewLeaseDuration>" + fmt.Sprint(lifetime/time.Second) +
+ "</NewLeaseDuration></u:AddPortMapping>"
+
+ // TODO: check response to see if the port was forwarded
+ _, err := soapRequest(n.serviceURL, "AddPortMapping", message)
+ return err
+}
+
+func (n *upnpNAT) DeletePortMapping(protocol string, externalPort, internalPort int) error {
+ if err := n.discover(); err != nil {
+ return err
+ }
+
+ message := "<u:DeletePortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\r\n" +
+ "<NewRemoteHost></NewRemoteHost><NewExternalPort>" + strconv.Itoa(externalPort) +
+ "</NewExternalPort><NewProtocol>" + protocol + "</NewProtocol>" +
+ "</u:DeletePortMapping>"
+
+ // TODO: check response to see if the port was deleted
+ _, err := soapRequest(n.serviceURL, "DeletePortMapping", message)
+ return err
+}
+
+type statusInfo struct {
+ externalIpAddress string
+}
+
+func (n *upnpNAT) getStatusInfo() (info statusInfo, err error) {
+ message := "<u:GetStatusInfo xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\r\n" +
+ "</u:GetStatusInfo>"
+
+ var response *http.Response
+ response, err = soapRequest(n.serviceURL, "GetStatusInfo", message)
+ if err != nil {
return
}
- err = errors.New("UPnP port discovery failed.")
+
+ // TODO: Write a soap reply parser. It has to eat the Body and envelope tags...
+
+ response.Body.Close()
return
}
@@ -259,77 +339,3 @@ func soapRequest(url, function, message string) (r *http.Response, err error) {
}
return
}
-
-type statusInfo struct {
- externalIpAddress string
-}
-
-func (n *upnpNAT) getStatusInfo() (info statusInfo, err error) {
-
- message := "<u:GetStatusInfo xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\r\n" +
- "</u:GetStatusInfo>"
-
- var response *http.Response
- response, err = soapRequest(n.serviceURL, "GetStatusInfo", message)
- if err != nil {
- return
- }
-
- // TODO: Write a soap reply parser. It has to eat the Body and envelope tags...
-
- response.Body.Close()
- return
-}
-
-func (n *upnpNAT) GetExternalAddress() (addr net.IP, err error) {
- info, err := n.getStatusInfo()
- if err != nil {
- return
- }
- addr = net.ParseIP(info.externalIpAddress)
- return
-}
-
-func (n *upnpNAT) AddPortMapping(protocol string, externalPort, internalPort int, description string, timeout int) (mappedExternalPort int, err error) {
- // A single concatenation would break ARM compilation.
- message := "<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\r\n" +
- "<NewRemoteHost></NewRemoteHost><NewExternalPort>" + strconv.Itoa(externalPort)
- message += "</NewExternalPort><NewProtocol>" + protocol + "</NewProtocol>"
- message += "<NewInternalPort>" + strconv.Itoa(internalPort) + "</NewInternalPort>" +
- "<NewInternalClient>" + n.ourIP + "</NewInternalClient>" +
- "<NewEnabled>1</NewEnabled><NewPortMappingDescription>"
- message += description +
- "</NewPortMappingDescription><NewLeaseDuration>" + strconv.Itoa(timeout) +
- "</NewLeaseDuration></u:AddPortMapping>"
-
- var response *http.Response
- response, err = soapRequest(n.serviceURL, "AddPortMapping", message)
- if err != nil {
- return
- }
-
- // TODO: check response to see if the port was forwarded
- // log.Println(message, response)
- mappedExternalPort = externalPort
- _ = response
- return
-}
-
-func (n *upnpNAT) DeletePortMapping(protocol string, externalPort, internalPort int) (err error) {
-
- message := "<u:DeletePortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\r\n" +
- "<NewRemoteHost></NewRemoteHost><NewExternalPort>" + strconv.Itoa(externalPort) +
- "</NewExternalPort><NewProtocol>" + protocol + "</NewProtocol>" +
- "</u:DeletePortMapping>"
-
- var response *http.Response
- response, err = soapRequest(n.serviceURL, "DeletePortMapping", message)
- if err != nil {
- return
- }
-
- // TODO: check response to see if the port was deleted
- // log.Println(message, response)
- _ = response
- return
-}
diff --git a/p2p/network.go b/p2p/network.go
deleted file mode 100644
index 820cef1a9..000000000
--- a/p2p/network.go
+++ /dev/null
@@ -1,196 +0,0 @@
-package p2p
-
-import (
- "fmt"
- "math/rand"
- "net"
- "strconv"
- "time"
-)
-
-const (
- DialerTimeout = 180 //seconds
- KeepAlivePeriod = 60 //minutes
- portMappingUpdateInterval = 900 // seconds = 15 mins
- upnpDiscoverAttempts = 3
-)
-
-// Dialer is not an interface in net, so we define one
-// *net.Dialer conforms to this
-type Dialer interface {
- Dial(network, address string) (net.Conn, error)
-}
-
-type Network interface {
- Start() error
- Listener(net.Addr) (net.Listener, error)
- Dialer(net.Addr) (Dialer, error)
- NewAddr(string, int) (addr net.Addr, err error)
- ParseAddr(string) (addr net.Addr, err error)
-}
-
-type NAT interface {
- GetExternalAddress() (addr net.IP, err error)
- AddPortMapping(protocol string, externalPort, internalPort int, description string, timeout int) (mappedExternalPort int, err error)
- DeletePortMapping(protocol string, externalPort, internalPort int) (err error)
-}
-
-type TCPNetwork struct {
- nat NAT
- natType NATType
- quit chan chan bool
- ports chan string
-}
-
-type NATType int
-
-const (
- NONE = iota
- UPNP
- PMP
-)
-
-const (
- portMappingTimeout = 1200 // 20 mins
-)
-
-func NewTCPNetwork(natType NATType) (net *TCPNetwork) {
- return &TCPNetwork{
- natType: natType,
- ports: make(chan string),
- }
-}
-
-func (self *TCPNetwork) Dialer(addr net.Addr) (Dialer, error) {
- return &net.Dialer{
- Timeout: DialerTimeout * time.Second,
- // KeepAlive: KeepAlivePeriod * time.Minute,
- LocalAddr: addr,
- }, nil
-}
-
-func (self *TCPNetwork) Listener(addr net.Addr) (net.Listener, error) {
- if self.natType == UPNP {
- _, port, _ := net.SplitHostPort(addr.String())
- if self.quit == nil {
- self.quit = make(chan chan bool)
- go self.updatePortMappings()
- }
- self.ports <- port
- }
- return net.Listen(addr.Network(), addr.String())
-}
-
-func (self *TCPNetwork) Start() (err error) {
- switch self.natType {
- case NONE:
- case UPNP:
- nat, uerr := upnpDiscover(upnpDiscoverAttempts)
- if uerr != nil {
- err = fmt.Errorf("UPNP failed: ", uerr)
- } else {
- self.nat = nat
- }
- case PMP:
- err = fmt.Errorf("PMP not implemented")
- default:
- err = fmt.Errorf("Invalid NAT type: %v", self.natType)
- }
- return
-}
-
-func (self *TCPNetwork) Stop() {
- q := make(chan bool)
- self.quit <- q
- <-q
-}
-
-func (self *TCPNetwork) addPortMapping(lport int) (err error) {
- _, err = self.nat.AddPortMapping("TCP", lport, lport, "p2p listen port", portMappingTimeout)
- if err != nil {
- logger.Errorf("unable to add port mapping on %v: %v", lport, err)
- } else {
- logger.Debugf("succesfully added port mapping on %v", lport)
- }
- return
-}
-
-func (self *TCPNetwork) updatePortMappings() {
- timer := time.NewTimer(portMappingUpdateInterval * time.Second)
- lports := []int{}
-out:
- for {
- select {
- case port := <-self.ports:
- int64lport, _ := strconv.ParseInt(port, 10, 16)
- lport := int(int64lport)
- if err := self.addPortMapping(lport); err != nil {
- lports = append(lports, lport)
- }
- case <-timer.C:
- for lport := range lports {
- if err := self.addPortMapping(lport); err != nil {
- }
- }
- case errc := <-self.quit:
- errc <- true
- break out
- }
- }
-
- timer.Stop()
- for lport := range lports {
- if err := self.nat.DeletePortMapping("TCP", lport, lport); err != nil {
- logger.Debugf("unable to remove port mapping on %v: %v", lport, err)
- } else {
- logger.Debugf("succesfully removed port mapping on %v", lport)
- }
- }
-}
-
-func (self *TCPNetwork) NewAddr(host string, port int) (net.Addr, error) {
- ip, err := self.lookupIP(host)
- if err == nil {
- return &net.TCPAddr{
- IP: ip,
- Port: port,
- }, nil
- }
- return nil, err
-}
-
-func (self *TCPNetwork) ParseAddr(address string) (net.Addr, error) {
- host, port, err := net.SplitHostPort(address)
- if err == nil {
- iport, _ := strconv.Atoi(port)
- addr, e := self.NewAddr(host, iport)
- return addr, e
- }
- return nil, err
-}
-
-func (*TCPNetwork) lookupIP(host string) (ip net.IP, err error) {
- if ip = net.ParseIP(host); ip != nil {
- return
- }
-
- var ips []net.IP
- ips, err = net.LookupIP(host)
- if err != nil {
- logger.Warnln(err)
- return
- }
- if len(ips) == 0 {
- err = fmt.Errorf("No IP addresses available for %v", host)
- logger.Warnln(err)
- return
- }
- if len(ips) > 1 {
- // Pick a random IP address, simulating round-robin DNS.
- rand.Seed(time.Now().UTC().UnixNano())
- ip = ips[rand.Intn(len(ips))]
- } else {
- ip = ips[0]
- }
- return
-}
diff --git a/p2p/peer.go b/p2p/peer.go
index f4b68a007..86c4d7ab5 100644
--- a/p2p/peer.go
+++ b/p2p/peer.go
@@ -1,83 +1,462 @@
package p2p
import (
+ "bufio"
+ "bytes"
"fmt"
+ "io"
+ "io/ioutil"
"net"
- "strconv"
+ "sort"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum/event"
+ "github.com/ethereum/go-ethereum/logger"
)
+// peerAddr is the structure of a peer list element.
+// It is also a valid net.Addr.
+type peerAddr struct {
+ IP net.IP
+ Port uint64
+ Pubkey []byte // optional
+}
+
+func newPeerAddr(addr net.Addr, pubkey []byte) *peerAddr {
+ n := addr.Network()
+ if n != "tcp" && n != "tcp4" && n != "tcp6" {
+ // for testing with non-TCP
+ return &peerAddr{net.ParseIP("127.0.0.1"), 30303, pubkey}
+ }
+ ta := addr.(*net.TCPAddr)
+ return &peerAddr{ta.IP, uint64(ta.Port), pubkey}
+}
+
+func (d peerAddr) Network() string {
+ if d.IP.To4() != nil {
+ return "tcp4"
+ } else {
+ return "tcp6"
+ }
+}
+
+func (d peerAddr) String() string {
+ return fmt.Sprintf("%v:%d", d.IP, d.Port)
+}
+
+func (d peerAddr) RlpData() interface{} {
+ return []interface{}{d.IP, d.Port, d.Pubkey}
+}
+
+// Peer represents a remote peer.
type Peer struct {
- // quit chan chan bool
- Inbound bool // inbound (via listener) or outbound (via dialout)
- Address net.Addr
- Host []byte
- Port uint16
- Pubkey []byte
- Id string
- Caps []string
- peerErrorChan chan *PeerError
- messenger *Messenger
- peerErrorHandler *PeerErrorHandler
- server *Server
-}
-
-func (self *Peer) Messenger() *Messenger {
- return self.messenger
-}
-
-func (self *Peer) PeerErrorChan() chan *PeerError {
- return self.peerErrorChan
-}
-
-func (self *Peer) Server() *Server {
- return self.server
-}
-
-func NewPeer(conn net.Conn, address net.Addr, inbound bool, server *Server) *Peer {
- peerErrorChan := NewPeerErrorChannel()
- host, port, _ := net.SplitHostPort(address.String())
- intport, _ := strconv.Atoi(port)
- peer := &Peer{
- Inbound: inbound,
- Address: address,
- Port: uint16(intport),
- Host: net.ParseIP(host),
- peerErrorChan: peerErrorChan,
- server: server,
- }
- connection := NewConnection(conn, peerErrorChan)
- peer.messenger = NewMessenger(peer, connection, peerErrorChan, server.Handlers())
- peer.peerErrorHandler = NewPeerErrorHandler(address, server.PeerDisconnect(), peerErrorChan, server.Blacklist())
+ // Peers have all the log methods.
+ // Use them to display messages related to the peer.
+ *logger.Logger
+
+ infolock sync.Mutex
+ identity ClientIdentity
+ caps []Cap
+ listenAddr *peerAddr // what remote peer is listening on
+ dialAddr *peerAddr // non-nil if dialing
+
+ // The mutex protects the connection
+ // so only one protocol can write at a time.
+ writeMu sync.Mutex
+ conn net.Conn
+ bufconn *bufio.ReadWriter
+
+ // These fields maintain the running protocols.
+ protocols []Protocol
+ runBaseProtocol bool // for testing
+
+ runlock sync.RWMutex // protects running
+ running map[string]*proto
+
+ protoWG sync.WaitGroup
+ protoErr chan error
+ closed chan struct{}
+ disc chan DiscReason
+
+ activity event.TypeMux // for activity events
+
+ slot int // index into Server peer list
+
+ // These fields are kept so base protocol can access them.
+ // TODO: this should be one or more interfaces
+ ourID ClientIdentity // client id of the Server
+ ourListenAddr *peerAddr // listen addr of Server, nil if not listening
+ newPeerAddr chan<- *peerAddr // tell server about received peers
+ otherPeers func() []*Peer // should return the list of all peers
+ pubkeyHook func(*peerAddr) error // called at end of handshake to validate pubkey
+}
+
+// NewPeer returns a peer for testing purposes.
+func NewPeer(id ClientIdentity, caps []Cap) *Peer {
+ conn, _ := net.Pipe()
+ peer := newPeer(conn, nil, nil)
+ peer.setHandshakeInfo(id, nil, caps)
+ close(peer.closed)
return peer
}
-func (self *Peer) String() string {
- var kind string
- if self.Inbound {
- kind = "inbound"
- } else {
+func newServerPeer(server *Server, conn net.Conn, dialAddr *peerAddr) *Peer {
+ p := newPeer(conn, server.Protocols, dialAddr)
+ p.ourID = server.Identity
+ p.newPeerAddr = server.peerConnect
+ p.otherPeers = server.Peers
+ p.pubkeyHook = server.verifyPeer
+ p.runBaseProtocol = true
+
+ // laddr can be updated concurrently by NAT traversal.
+ // newServerPeer must be called with the server lock held.
+ if server.laddr != nil {
+ p.ourListenAddr = newPeerAddr(server.laddr, server.Identity.Pubkey())
+ }
+ return p
+}
+
+func newPeer(conn net.Conn, protocols []Protocol, dialAddr *peerAddr) *Peer {
+ p := &Peer{
+ Logger: logger.NewLogger("P2P " + conn.RemoteAddr().String()),
+ conn: conn,
+ dialAddr: dialAddr,
+ bufconn: bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)),
+ protocols: protocols,
+ running: make(map[string]*proto),
+ disc: make(chan DiscReason),
+ protoErr: make(chan error),
+ closed: make(chan struct{}),
+ }
+ return p
+}
+
+// Identity returns the client identity of the remote peer. The
+// identity can be nil if the peer has not yet completed the
+// handshake.
+func (p *Peer) Identity() ClientIdentity {
+ p.infolock.Lock()
+ defer p.infolock.Unlock()
+ return p.identity
+}
+
+// Caps returns the capabilities (supported subprotocols) of the remote peer.
+func (p *Peer) Caps() []Cap {
+ p.infolock.Lock()
+ defer p.infolock.Unlock()
+ return p.caps
+}
+
+func (p *Peer) setHandshakeInfo(id ClientIdentity, laddr *peerAddr, caps []Cap) {
+ p.infolock.Lock()
+ p.identity = id
+ p.listenAddr = laddr
+ p.caps = caps
+ p.infolock.Unlock()
+}
+
+// RemoteAddr returns the remote address of the network connection.
+func (p *Peer) RemoteAddr() net.Addr {
+ return p.conn.RemoteAddr()
+}
+
+// LocalAddr returns the local address of the network connection.
+func (p *Peer) LocalAddr() net.Addr {
+ return p.conn.LocalAddr()
+}
+
+// Disconnect terminates the peer connection with the given reason.
+// It returns immediately and does not wait until the connection is closed.
+func (p *Peer) Disconnect(reason DiscReason) {
+ select {
+ case p.disc <- reason:
+ case <-p.closed:
+ }
+}
+
+// String implements fmt.Stringer.
+func (p *Peer) String() string {
+ kind := "inbound"
+ p.infolock.Lock()
+ if p.dialAddr != nil {
kind = "outbound"
}
- return fmt.Sprintf("%v:%v (%s) v%v %v", self.Host, self.Port, kind, self.Id, self.Caps)
+ p.infolock.Unlock()
+ return fmt.Sprintf("Peer(%p %v %s)", p, p.conn.RemoteAddr(), kind)
}
-func (self *Peer) Write(protocol string, msg *Msg) error {
- return self.messenger.Write(protocol, msg)
+const (
+ // maximum amount of time allowed for reading a message
+ msgReadTimeout = 5 * time.Second
+ // maximum amount of time allowed for writing a message
+ msgWriteTimeout = 5 * time.Second
+ // messages smaller than this many bytes will be read at
+ // once before passing them to a protocol.
+ wholePayloadSize = 64 * 1024
+)
+
+var (
+ inactivityTimeout = 2 * time.Second
+ disconnectGracePeriod = 2 * time.Second
+)
+
+func (p *Peer) loop() (reason DiscReason, err error) {
+ defer p.activity.Stop()
+ defer p.closeProtocols()
+ defer close(p.closed)
+ defer p.conn.Close()
+
+ // read loop
+ readMsg := make(chan Msg)
+ readErr := make(chan error)
+ readNext := make(chan bool, 1)
+ protoDone := make(chan struct{}, 1)
+ go p.readLoop(readMsg, readErr, readNext)
+ readNext <- true
+
+ if p.runBaseProtocol {
+ p.startBaseProtocol()
+ }
+
+loop:
+ for {
+ select {
+ case msg := <-readMsg:
+ // a new message has arrived.
+ var wait bool
+ if wait, err = p.dispatch(msg, protoDone); err != nil {
+ p.Errorf("msg dispatch error: %v\n", err)
+ reason = discReasonForError(err)
+ break loop
+ }
+ if !wait {
+ // Msg has already been read completely, continue with next message.
+ readNext <- true
+ }
+ p.activity.Post(time.Now())
+ case <-protoDone:
+ // protocol has consumed the message payload,
+ // we can continue reading from the socket.
+ readNext <- true
+
+ case err := <-readErr:
+ // read failed. there is no need to run the
+ // polite disconnect sequence because the connection
+ // is probably dead anyway.
+ // TODO: handle write errors as well
+ return DiscNetworkError, err
+ case err = <-p.protoErr:
+ reason = discReasonForError(err)
+ break loop
+ case reason = <-p.disc:
+ break loop
+ }
+ }
+
+ // wait for read loop to return.
+ close(readNext)
+ <-readErr
+ // tell the remote end to disconnect
+ done := make(chan struct{})
+ go func() {
+ p.conn.SetDeadline(time.Now().Add(disconnectGracePeriod))
+ p.writeMsg(NewMsg(discMsg, reason), disconnectGracePeriod)
+ io.Copy(ioutil.Discard, p.conn)
+ close(done)
+ }()
+ select {
+ case <-done:
+ case <-time.After(disconnectGracePeriod):
+ }
+ return reason, err
+}
+
+func (p *Peer) readLoop(msgc chan<- Msg, errc chan<- error, unblock <-chan bool) {
+ for _ = range unblock {
+ p.conn.SetReadDeadline(time.Now().Add(msgReadTimeout))
+ if msg, err := readMsg(p.bufconn); err != nil {
+ errc <- err
+ } else {
+ msgc <- msg
+ }
+ }
+ close(errc)
+}
+
+func (p *Peer) dispatch(msg Msg, protoDone chan struct{}) (wait bool, err error) {
+ proto, err := p.getProto(msg.Code)
+ if err != nil {
+ return false, err
+ }
+ if msg.Size <= wholePayloadSize {
+ // optimization: msg is small enough, read all
+ // of it and move on to the next message
+ buf, err := ioutil.ReadAll(msg.Payload)
+ if err != nil {
+ return false, err
+ }
+ msg.Payload = bytes.NewReader(buf)
+ proto.in <- msg
+ } else {
+ wait = true
+ pr := &eofSignal{msg.Payload, int64(msg.Size), protoDone}
+ msg.Payload = pr
+ proto.in <- msg
+ }
+ return wait, nil
+}
+
+func (p *Peer) startBaseProtocol() {
+ p.runlock.Lock()
+ defer p.runlock.Unlock()
+ p.running[""] = p.startProto(0, Protocol{
+ Length: baseProtocolLength,
+ Run: runBaseProtocol,
+ })
+}
+
+// startProtocols starts matching named subprotocols.
+func (p *Peer) startSubprotocols(caps []Cap) {
+ sort.Sort(capsByName(caps))
+
+ p.runlock.Lock()
+ defer p.runlock.Unlock()
+ offset := baseProtocolLength
+outer:
+ for _, cap := range caps {
+ for _, proto := range p.protocols {
+ if proto.Name == cap.Name &&
+ proto.Version == cap.Version &&
+ p.running[cap.Name] == nil {
+ p.running[cap.Name] = p.startProto(offset, proto)
+ offset += proto.Length
+ continue outer
+ }
+ }
+ }
+}
+
+func (p *Peer) startProto(offset uint64, impl Protocol) *proto {
+ rw := &proto{
+ in: make(chan Msg),
+ offset: offset,
+ maxcode: impl.Length,
+ peer: p,
+ }
+ p.protoWG.Add(1)
+ go func() {
+ err := impl.Run(p, rw)
+ if err == nil {
+ p.Infof("protocol %q returned", impl.Name)
+ err = newPeerError(errMisc, "protocol returned")
+ } else {
+ p.Errorf("protocol %q error: %v\n", impl.Name, err)
+ }
+ select {
+ case p.protoErr <- err:
+ case <-p.closed:
+ }
+ p.protoWG.Done()
+ }()
+ return rw
+}
+
+// getProto finds the protocol responsible for handling
+// the given message code.
+func (p *Peer) getProto(code uint64) (*proto, error) {
+ p.runlock.RLock()
+ defer p.runlock.RUnlock()
+ for _, proto := range p.running {
+ if code >= proto.offset && code < proto.offset+proto.maxcode {
+ return proto, nil
+ }
+ }
+ return nil, newPeerError(errInvalidMsgCode, "%d", code)
+}
+
+func (p *Peer) closeProtocols() {
+ p.runlock.RLock()
+ for _, p := range p.running {
+ close(p.in)
+ }
+ p.runlock.RUnlock()
+ p.protoWG.Wait()
+}
+
+// writeProtoMsg sends the given message on behalf of the given named protocol.
+func (p *Peer) writeProtoMsg(protoName string, msg Msg) error {
+ p.runlock.RLock()
+ proto, ok := p.running[protoName]
+ p.runlock.RUnlock()
+ if !ok {
+ return fmt.Errorf("protocol %s not handled by peer", protoName)
+ }
+ if msg.Code >= proto.maxcode {
+ return newPeerError(errInvalidMsgCode, "code %x is out of range for protocol %q", msg.Code, protoName)
+ }
+ msg.Code += proto.offset
+ return p.writeMsg(msg, msgWriteTimeout)
+}
+
+// writeMsg writes a message to the connection.
+func (p *Peer) writeMsg(msg Msg, timeout time.Duration) error {
+ p.writeMu.Lock()
+ defer p.writeMu.Unlock()
+ p.conn.SetWriteDeadline(time.Now().Add(timeout))
+ if err := writeMsg(p.bufconn, msg); err != nil {
+ return newPeerError(errWrite, "%v", err)
+ }
+ return p.bufconn.Flush()
+}
+
+type proto struct {
+ name string
+ in chan Msg
+ maxcode, offset uint64
+ peer *Peer
+}
+
+func (rw *proto) WriteMsg(msg Msg) error {
+ if msg.Code >= rw.maxcode {
+ return newPeerError(errInvalidMsgCode, "not handled")
+ }
+ msg.Code += rw.offset
+ return rw.peer.writeMsg(msg, msgWriteTimeout)
+}
+
+func (rw *proto) EncodeMsg(code uint64, data ...interface{}) error {
+ return rw.WriteMsg(NewMsg(code, data))
}
-func (self *Peer) Start() {
- self.peerErrorHandler.Start()
- self.messenger.Start()
+func (rw *proto) ReadMsg() (Msg, error) {
+ msg, ok := <-rw.in
+ if !ok {
+ return msg, io.EOF
+ }
+ msg.Code -= rw.offset
+ return msg, nil
}
-func (self *Peer) Stop() {
- self.peerErrorHandler.Stop()
- self.messenger.Stop()
- // q := make(chan bool)
- // self.quit <- q
- // <-q
+// eofSignal wraps a reader with eof signaling. the eof channel is
+// closed when the wrapped reader returns an error or when count bytes
+// have been read.
+//
+type eofSignal struct {
+ wrapped io.Reader
+ count int64
+ eof chan<- struct{}
}
-func (p *Peer) Encode() []interface{} {
- return []interface{}{p.Host, p.Port, p.Pubkey}
+// note: when using eofSignal to detect whether a message payload
+// has been read, Read might not be called for zero sized messages.
+
+func (r *eofSignal) Read(buf []byte) (int, error) {
+ n, err := r.wrapped.Read(buf)
+ r.count -= int64(n)
+ if (err != nil || r.count <= 0) && r.eof != nil {
+ r.eof <- struct{}{} // tell Peer that msg has been consumed
+ r.eof = nil
+ }
+ return n, err
}
diff --git a/p2p/peer_error.go b/p2p/peer_error.go
index de921878a..0eb7ec838 100644
--- a/p2p/peer_error.go
+++ b/p2p/peer_error.go
@@ -4,73 +4,130 @@ import (
"fmt"
)
-type ErrorCode int
-
-const errorChanCapacity = 10
-
const (
- PacketTooShort = iota
- PayloadTooShort
- MagicTokenMismatch
- EmptyPayload
- ReadError
- WriteError
- MiscError
- InvalidMsgCode
- InvalidMsg
- P2PVersionMismatch
- PubkeyMissing
- PubkeyInvalid
- PubkeyForbidden
- ProtocolBreach
- PortMismatch
- PingTimeout
- InvalidGenesis
- InvalidNetworkId
- InvalidProtocolVersion
+ errMagicTokenMismatch = iota
+ errRead
+ errWrite
+ errMisc
+ errInvalidMsgCode
+ errInvalidMsg
+ errP2PVersionMismatch
+ errPubkeyMissing
+ errPubkeyInvalid
+ errPubkeyForbidden
+ errProtocolBreach
+ errPingTimeout
+ errInvalidNetworkId
+ errInvalidProtocolVersion
)
-var errorToString = map[ErrorCode]string{
- PacketTooShort: "Packet too short",
- PayloadTooShort: "Payload too short",
- MagicTokenMismatch: "Magic token mismatch",
- EmptyPayload: "Empty payload",
- ReadError: "Read error",
- WriteError: "Write error",
- MiscError: "Misc error",
- InvalidMsgCode: "Invalid message code",
- InvalidMsg: "Invalid message",
- P2PVersionMismatch: "P2P Version Mismatch",
- PubkeyMissing: "Public key missing",
- PubkeyInvalid: "Public key invalid",
- PubkeyForbidden: "Public key forbidden",
- ProtocolBreach: "Protocol Breach",
- PortMismatch: "Port mismatch",
- PingTimeout: "Ping timeout",
- InvalidGenesis: "Invalid genesis block",
- InvalidNetworkId: "Invalid network id",
- InvalidProtocolVersion: "Invalid protocol version",
+var errorToString = map[int]string{
+ errMagicTokenMismatch: "Magic token mismatch",
+ errRead: "Read error",
+ errWrite: "Write error",
+ errMisc: "Misc error",
+ errInvalidMsgCode: "Invalid message code",
+ errInvalidMsg: "Invalid message",
+ errP2PVersionMismatch: "P2P Version Mismatch",
+ errPubkeyMissing: "Public key missing",
+ errPubkeyInvalid: "Public key invalid",
+ errPubkeyForbidden: "Public key forbidden",
+ errProtocolBreach: "Protocol Breach",
+ errPingTimeout: "Ping timeout",
+ errInvalidNetworkId: "Invalid network id",
+ errInvalidProtocolVersion: "Invalid protocol version",
}
-type PeerError struct {
- Code ErrorCode
+type peerError struct {
+ Code int
message string
}
-func NewPeerError(code ErrorCode, format string, v ...interface{}) *PeerError {
+func newPeerError(code int, format string, v ...interface{}) *peerError {
desc, ok := errorToString[code]
if !ok {
panic("invalid error code")
}
- format = desc + ": " + format
- message := fmt.Sprintf(format, v...)
- return &PeerError{code, message}
+ err := &peerError{code, desc}
+ if format != "" {
+ err.message += ": " + fmt.Sprintf(format, v...)
+ }
+ return err
}
-func (self *PeerError) Error() string {
+func (self *peerError) Error() string {
return self.message
}
-func NewPeerErrorChannel() chan *PeerError {
- return make(chan *PeerError, errorChanCapacity)
+type DiscReason byte
+
+const (
+ DiscRequested DiscReason = 0x00
+ DiscNetworkError = 0x01
+ DiscProtocolError = 0x02
+ DiscUselessPeer = 0x03
+ DiscTooManyPeers = 0x04
+ DiscAlreadyConnected = 0x05
+ DiscIncompatibleVersion = 0x06
+ DiscInvalidIdentity = 0x07
+ DiscQuitting = 0x08
+ DiscUnexpectedIdentity = 0x09
+ DiscSelf = 0x0a
+ DiscReadTimeout = 0x0b
+ DiscSubprotocolError = 0x10
+)
+
+var discReasonToString = [DiscSubprotocolError + 1]string{
+ DiscRequested: "Disconnect requested",
+ DiscNetworkError: "Network error",
+ DiscProtocolError: "Breach of protocol",
+ DiscUselessPeer: "Useless peer",
+ DiscTooManyPeers: "Too many peers",
+ DiscAlreadyConnected: "Already connected",
+ DiscIncompatibleVersion: "Incompatible P2P protocol version",
+ DiscInvalidIdentity: "Invalid node identity",
+ DiscQuitting: "Client quitting",
+ DiscUnexpectedIdentity: "Unexpected identity",
+ DiscSelf: "Connected to self",
+ DiscReadTimeout: "Read timeout",
+ DiscSubprotocolError: "Subprotocol error",
+}
+
+func (d DiscReason) String() string {
+ if len(discReasonToString) < int(d) {
+ return fmt.Sprintf("Unknown Reason(%d)", d)
+ }
+ return discReasonToString[d]
+}
+
+type discRequestedError DiscReason
+
+func (err discRequestedError) Error() string {
+ return fmt.Sprintf("disconnect requested: %v", DiscReason(err))
+}
+
+func discReasonForError(err error) DiscReason {
+ if reason, ok := err.(discRequestedError); ok {
+ return DiscReason(reason)
+ }
+ peerError, ok := err.(*peerError)
+ if !ok {
+ return DiscSubprotocolError
+ }
+ switch peerError.Code {
+ case errP2PVersionMismatch:
+ return DiscIncompatibleVersion
+ case errPubkeyMissing, errPubkeyInvalid:
+ return DiscInvalidIdentity
+ case errPubkeyForbidden:
+ return DiscUselessPeer
+ case errInvalidMsgCode, errMagicTokenMismatch, errProtocolBreach:
+ return DiscProtocolError
+ case errPingTimeout:
+ return DiscReadTimeout
+ case errRead, errWrite, errMisc:
+ return DiscNetworkError
+ default:
+ return DiscSubprotocolError
+ }
}
diff --git a/p2p/peer_error_handler.go b/p2p/peer_error_handler.go
deleted file mode 100644
index ca6cae4db..000000000
--- a/p2p/peer_error_handler.go
+++ /dev/null
@@ -1,101 +0,0 @@
-package p2p
-
-import (
- "net"
-)
-
-const (
- severityThreshold = 10
-)
-
-type DisconnectRequest struct {
- addr net.Addr
- reason DiscReason
-}
-
-type PeerErrorHandler struct {
- quit chan chan bool
- address net.Addr
- peerDisconnect chan DisconnectRequest
- severity int
- peerErrorChan chan *PeerError
- blacklist Blacklist
-}
-
-func NewPeerErrorHandler(address net.Addr, peerDisconnect chan DisconnectRequest, peerErrorChan chan *PeerError, blacklist Blacklist) *PeerErrorHandler {
- return &PeerErrorHandler{
- quit: make(chan chan bool),
- address: address,
- peerDisconnect: peerDisconnect,
- peerErrorChan: peerErrorChan,
- blacklist: blacklist,
- }
-}
-
-func (self *PeerErrorHandler) Start() {
- go self.listen()
-}
-
-func (self *PeerErrorHandler) Stop() {
- q := make(chan bool)
- self.quit <- q
- <-q
-}
-
-func (self *PeerErrorHandler) listen() {
- for {
- select {
- case peerError, ok := <-self.peerErrorChan:
- if ok {
- logger.Debugf("error %v\n", peerError)
- go self.handle(peerError)
- } else {
- return
- }
- case q := <-self.quit:
- q <- true
- return
- }
- }
-}
-
-func (self *PeerErrorHandler) handle(peerError *PeerError) {
- reason := DiscReason(' ')
- switch peerError.Code {
- case P2PVersionMismatch:
- reason = DiscIncompatibleVersion
- case PubkeyMissing, PubkeyInvalid:
- reason = DiscInvalidIdentity
- case PubkeyForbidden:
- reason = DiscUselessPeer
- case InvalidMsgCode, PacketTooShort, PayloadTooShort, MagicTokenMismatch, EmptyPayload, ProtocolBreach:
- reason = DiscProtocolError
- case PingTimeout:
- reason = DiscReadTimeout
- case WriteError, MiscError:
- reason = DiscNetworkError
- case InvalidGenesis, InvalidNetworkId, InvalidProtocolVersion:
- reason = DiscSubprotocolError
- default:
- self.severity += self.getSeverity(peerError)
- }
-
- if self.severity >= severityThreshold {
- reason = DiscSubprotocolError
- }
- if reason != DiscReason(' ') {
- self.peerDisconnect <- DisconnectRequest{
- addr: self.address,
- reason: reason,
- }
- }
-}
-
-func (self *PeerErrorHandler) getSeverity(peerError *PeerError) int {
- switch peerError.Code {
- case ReadError:
- return 4 //tolerate 3 :)
- default:
- return 1
- }
-}
diff --git a/p2p/peer_error_handler_test.go b/p2p/peer_error_handler_test.go
deleted file mode 100644
index 790a7443b..000000000
--- a/p2p/peer_error_handler_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package p2p
-
-import (
- // "fmt"
- "net"
- "testing"
- "time"
-)
-
-func TestPeerErrorHandler(t *testing.T) {
- address := &net.TCPAddr{IP: net.IP([]byte{1, 2, 3, 4}), Port: 30303}
- peerDisconnect := make(chan DisconnectRequest)
- peerErrorChan := NewPeerErrorChannel()
- peh := NewPeerErrorHandler(address, peerDisconnect, peerErrorChan, NewBlacklist())
- peh.Start()
- defer peh.Stop()
- for i := 0; i < 11; i++ {
- select {
- case <-peerDisconnect:
- t.Errorf("expected no disconnect request")
- default:
- }
- peerErrorChan <- NewPeerError(MiscError, "")
- }
- time.Sleep(1 * time.Millisecond)
- select {
- case request := <-peerDisconnect:
- if request.addr.String() != address.String() {
- t.Errorf("incorrect address %v != %v", request.addr, address)
- }
- default:
- t.Errorf("expected disconnect request")
- }
-}
diff --git a/p2p/peer_test.go b/p2p/peer_test.go
index c37540bef..f7759786e 100644
--- a/p2p/peer_test.go
+++ b/p2p/peer_test.go
@@ -1,96 +1,295 @@
package p2p
import (
+ "bufio"
"bytes"
- "fmt"
- // "net"
+ "encoding/hex"
+ "io"
+ "io/ioutil"
+ "net"
+ "reflect"
"testing"
"time"
)
-func TestPeer(t *testing.T) {
- handlers := make(Handlers)
- testProtocol := &TestProtocol{Msgs: []*Msg{}}
- handlers["aaa"] = func(p *Peer) Protocol { return testProtocol }
- handlers["ccc"] = func(p *Peer) Protocol { return testProtocol }
- addr := &TestAddr{"test:30"}
- conn := NewTestNetworkConnection(addr)
- _, server := SetupTestServer(handlers)
- server.Handshake()
- peer := NewPeer(conn, addr, true, server)
- // peer.Messenger().AddProtocols([]string{"aaa", "ccc"})
- peer.Start()
- defer peer.Stop()
- time.Sleep(2 * time.Millisecond)
- if len(conn.Out) != 1 {
- t.Errorf("handshake not sent")
- } else {
- out := conn.Out[0]
- packet := Packet(0, HandshakeMsg, P2PVersion, []byte(peer.server.identity.String()), []interface{}{peer.server.protocols}, peer.server.port, peer.server.identity.Pubkey()[1:])
- if bytes.Compare(out, packet) != 0 {
- t.Errorf("incorrect handshake packet %v != %v", out, packet)
+var discard = Protocol{
+ Name: "discard",
+ Length: 1,
+ Run: func(p *Peer, rw MsgReadWriter) error {
+ for {
+ msg, err := rw.ReadMsg()
+ if err != nil {
+ return err
+ }
+ if err = msg.Discard(); err != nil {
+ return err
+ }
}
- }
+ },
+}
- packet := Packet(0, HandshakeMsg, P2PVersion, []byte("peer"), []interface{}{"bbb", "aaa", "ccc"}, 30, []byte("0000000000000000000000000000000000000000000000000000000000000000"))
- conn.In(0, packet)
- time.Sleep(10 * time.Millisecond)
+func testPeer(protos []Protocol) (net.Conn, *Peer, <-chan error) {
+ conn1, conn2 := net.Pipe()
+ id := NewSimpleClientIdentity("test", "0", "0", "public key")
+ peer := newPeer(conn1, protos, nil)
+ peer.ourID = id
+ peer.pubkeyHook = func(*peerAddr) error { return nil }
+ errc := make(chan error, 1)
+ go func() {
+ _, err := peer.loop()
+ errc <- err
+ }()
+ return conn2, peer, errc
+}
- pro, _ := peer.Messenger().protocols[0].(*BaseProtocol)
- if pro.state != handshakeReceived {
- t.Errorf("handshake not received")
- }
- if peer.Port != 30 {
- t.Errorf("port incorrectly set")
+func TestPeerProtoReadMsg(t *testing.T) {
+ defer testlog(t).detach()
+
+ done := make(chan struct{})
+ proto := Protocol{
+ Name: "a",
+ Length: 5,
+ Run: func(peer *Peer, rw MsgReadWriter) error {
+ msg, err := rw.ReadMsg()
+ if err != nil {
+ t.Errorf("read error: %v", err)
+ }
+ if msg.Code != 2 {
+ t.Errorf("incorrect msg code %d relayed to protocol", msg.Code)
+ }
+ data, err := ioutil.ReadAll(msg.Payload)
+ if err != nil {
+ t.Errorf("payload read error: %v", err)
+ }
+ expdata, _ := hex.DecodeString("0183303030")
+ if !bytes.Equal(expdata, data) {
+ t.Errorf("incorrect msg data %x", data)
+ }
+ close(done)
+ return nil
+ },
}
- if peer.Id != "peer" {
- t.Errorf("id incorrectly set")
+
+ net, peer, errc := testPeer([]Protocol{proto})
+ defer net.Close()
+ peer.startSubprotocols([]Cap{proto.cap()})
+
+ writeMsg(net, NewMsg(18, 1, "000"))
+ select {
+ case <-done:
+ case err := <-errc:
+ t.Errorf("peer returned: %v", err)
+ case <-time.After(2 * time.Second):
+ t.Errorf("receive timeout")
}
- if string(peer.Pubkey) != "0000000000000000000000000000000000000000000000000000000000000000" {
- t.Errorf("pubkey incorrectly set")
+}
+
+func TestPeerProtoReadLargeMsg(t *testing.T) {
+ defer testlog(t).detach()
+
+ msgsize := uint32(10 * 1024 * 1024)
+ done := make(chan struct{})
+ proto := Protocol{
+ Name: "a",
+ Length: 5,
+ Run: func(peer *Peer, rw MsgReadWriter) error {
+ msg, err := rw.ReadMsg()
+ if err != nil {
+ t.Errorf("read error: %v", err)
+ }
+ if msg.Size != msgsize+4 {
+ t.Errorf("incorrect msg.Size, got %d, expected %d", msg.Size, msgsize)
+ }
+ msg.Discard()
+ close(done)
+ return nil
+ },
}
- fmt.Println(peer.Caps)
- if len(peer.Caps) != 3 || peer.Caps[0] != "aaa" || peer.Caps[1] != "bbb" || peer.Caps[2] != "ccc" {
- t.Errorf("protocols incorrectly set")
+
+ net, peer, errc := testPeer([]Protocol{proto})
+ defer net.Close()
+ peer.startSubprotocols([]Cap{proto.cap()})
+
+ writeMsg(net, NewMsg(18, make([]byte, msgsize)))
+ select {
+ case <-done:
+ case err := <-errc:
+ t.Errorf("peer returned: %v", err)
+ case <-time.After(2 * time.Second):
+ t.Errorf("receive timeout")
}
+}
- msg, _ := NewMsg(3)
- err := peer.Write("aaa", msg)
- if err != nil {
- t.Errorf("expect no error for known protocol: %v", err)
- } else {
- time.Sleep(1 * time.Millisecond)
- if len(conn.Out) != 2 {
- t.Errorf("msg not written")
- } else {
- out := conn.Out[1]
- packet := Packet(16, 3)
- if bytes.Compare(out, packet) != 0 {
- t.Errorf("incorrect packet %v != %v", out, packet)
+func TestPeerProtoEncodeMsg(t *testing.T) {
+ defer testlog(t).detach()
+
+ proto := Protocol{
+ Name: "a",
+ Length: 2,
+ Run: func(peer *Peer, rw MsgReadWriter) error {
+ if err := rw.EncodeMsg(2); err == nil {
+ t.Error("expected error for out-of-range msg code, got nil")
}
- }
+ if err := rw.EncodeMsg(1); err != nil {
+ t.Errorf("write error: %v", err)
+ }
+ return nil
+ },
}
+ net, peer, _ := testPeer([]Protocol{proto})
+ defer net.Close()
+ peer.startSubprotocols([]Cap{proto.cap()})
- msg, _ = NewMsg(2)
- err = peer.Write("ccc", msg)
+ bufr := bufio.NewReader(net)
+ msg, err := readMsg(bufr)
if err != nil {
+ t.Errorf("read error: %v", err)
+ }
+ if msg.Code != 17 {
+ t.Errorf("incorrect message code: got %d, expected %d", msg.Code, 17)
+ }
+}
+
+func TestPeerWrite(t *testing.T) {
+ defer testlog(t).detach()
+
+ net, peer, peerErr := testPeer([]Protocol{discard})
+ defer net.Close()
+ peer.startSubprotocols([]Cap{discard.cap()})
+
+ // test write errors
+ if err := peer.writeProtoMsg("b", NewMsg(3)); err == nil {
+ t.Errorf("expected error for unknown protocol, got nil")
+ }
+ if err := peer.writeProtoMsg("discard", NewMsg(8)); err == nil {
+ t.Errorf("expected error for out-of-range msg code, got nil")
+ } else if perr, ok := err.(*peerError); !ok || perr.Code != errInvalidMsgCode {
+ t.Errorf("wrong error for out-of-range msg code, got %#v", err)
+ }
+
+ // setup for reading the message on the other end
+ read := make(chan struct{})
+ go func() {
+ bufr := bufio.NewReader(net)
+ msg, err := readMsg(bufr)
+ if err != nil {
+ t.Errorf("read error: %v", err)
+ } else if msg.Code != 16 {
+ t.Errorf("wrong code, got %d, expected %d", msg.Code, 16)
+ }
+ msg.Discard()
+ close(read)
+ }()
+
+ // test succcessful write
+ if err := peer.writeProtoMsg("discard", NewMsg(0)); err != nil {
t.Errorf("expect no error for known protocol: %v", err)
- } else {
- time.Sleep(1 * time.Millisecond)
- if len(conn.Out) != 3 {
- t.Errorf("msg not written")
- } else {
- out := conn.Out[2]
- packet := Packet(21, 2)
- if bytes.Compare(out, packet) != 0 {
- t.Errorf("incorrect packet %v != %v", out, packet)
- }
+ }
+ select {
+ case <-read:
+ case err := <-peerErr:
+ t.Fatalf("peer stopped: %v", err)
+ }
+}
+
+func TestPeerActivity(t *testing.T) {
+ // shorten inactivityTimeout while this test is running
+ oldT := inactivityTimeout
+ defer func() { inactivityTimeout = oldT }()
+ inactivityTimeout = 20 * time.Millisecond
+
+ net, peer, peerErr := testPeer([]Protocol{discard})
+ defer net.Close()
+ peer.startSubprotocols([]Cap{discard.cap()})
+
+ sub := peer.activity.Subscribe(time.Time{})
+ defer sub.Unsubscribe()
+
+ for i := 0; i < 6; i++ {
+ writeMsg(net, NewMsg(16))
+ select {
+ case <-sub.Chan():
+ case <-time.After(inactivityTimeout / 2):
+ t.Fatal("no event within ", inactivityTimeout/2)
+ case err := <-peerErr:
+ t.Fatal("peer error", err)
}
}
- err = peer.Write("bbb", msg)
- time.Sleep(1 * time.Millisecond)
- if err == nil {
- t.Errorf("expect error for unknown protocol")
+ select {
+ case <-time.After(inactivityTimeout * 2):
+ case <-sub.Chan():
+ t.Fatal("got activity event while connection was inactive")
+ case err := <-peerErr:
+ t.Fatal("peer error", err)
+ }
+}
+
+func TestNewPeer(t *testing.T) {
+ id := NewSimpleClientIdentity("clientid", "version", "customid", "pubkey")
+ caps := []Cap{{"foo", 2}, {"bar", 3}}
+ p := NewPeer(id, caps)
+ if !reflect.DeepEqual(p.Caps(), caps) {
+ t.Errorf("Caps mismatch: got %v, expected %v", p.Caps(), caps)
+ }
+ if p.Identity() != id {
+ t.Errorf("Identity mismatch: got %v, expected %v", p.Identity(), id)
+ }
+ // Should not hang.
+ p.Disconnect(DiscAlreadyConnected)
+}
+
+func TestEOFSignal(t *testing.T) {
+ rb := make([]byte, 10)
+
+ // empty reader
+ eof := make(chan struct{}, 1)
+ sig := &eofSignal{new(bytes.Buffer), 0, eof}
+ if n, err := sig.Read(rb); n != 0 || err != io.EOF {
+ t.Errorf("Read returned unexpected values: (%v, %v)", n, err)
+ }
+ select {
+ case <-eof:
+ default:
+ t.Error("EOF chan not signaled")
+ }
+
+ // count before error
+ eof = make(chan struct{}, 1)
+ sig = &eofSignal{bytes.NewBufferString("aaaaaaaa"), 4, eof}
+ if n, err := sig.Read(rb); n != 8 || err != nil {
+ t.Errorf("Read returned unexpected values: (%v, %v)", n, err)
+ }
+ select {
+ case <-eof:
+ default:
+ t.Error("EOF chan not signaled")
+ }
+
+ // error before count
+ eof = make(chan struct{}, 1)
+ sig = &eofSignal{bytes.NewBufferString("aaaa"), 999, eof}
+ if n, err := sig.Read(rb); n != 4 || err != nil {
+ t.Errorf("Read returned unexpected values: (%v, %v)", n, err)
+ }
+ if n, err := sig.Read(rb); n != 0 || err != io.EOF {
+ t.Errorf("Read returned unexpected values: (%v, %v)", n, err)
+ }
+ select {
+ case <-eof:
+ default:
+ t.Error("EOF chan not signaled")
+ }
+
+ // no signal if neither occurs
+ eof = make(chan struct{}, 1)
+ sig = &eofSignal{bytes.NewBufferString("aaaaaaaaaaaaaaaaaaaaa"), 999, eof}
+ if n, err := sig.Read(rb); n != 10 || err != nil {
+ t.Errorf("Read returned unexpected values: (%v, %v)", n, err)
+ }
+ select {
+ case <-eof:
+ t.Error("unexpected EOF signal")
+ default:
}
}
diff --git a/p2p/protocol.go b/p2p/protocol.go
index 5d05ced7d..3f52205f5 100644
--- a/p2p/protocol.go
+++ b/p2p/protocol.go
@@ -2,277 +2,293 @@ package p2p
import (
"bytes"
- "fmt"
- "net"
- "sort"
- "sync"
"time"
-)
-
-type Protocol interface {
- Start()
- Stop()
- HandleIn(*Msg, chan *Msg)
- HandleOut(*Msg) bool
- Offset() MsgCode
- Name() string
-}
-const (
- P2PVersion = 0
- pingTimeout = 2
- pingGracePeriod = 2
+ "github.com/ethereum/go-ethereum/ethutil"
)
-const (
- HandshakeMsg = iota
- DiscMsg
- PingMsg
- PongMsg
- GetPeersMsg
- PeersMsg
- offset = 16
-)
+// Protocol represents a P2P subprotocol implementation.
+type Protocol struct {
+ // Name should contain the official protocol name,
+ // often a three-letter word.
+ Name string
+
+ // Version should contain the version number of the protocol.
+ Version uint
+
+ // Length should contain the number of message codes used
+ // by the protocol.
+ Length uint64
+
+ // Run is called in a new groutine when the protocol has been
+ // negotiated with a peer. It should read and write messages from
+ // rw. The Payload for each message must be fully consumed.
+ //
+ // The peer connection is closed when Start returns. It should return
+ // any protocol-level error (such as an I/O error) that is
+ // encountered.
+ Run func(peer *Peer, rw MsgReadWriter) error
+}
-type ProtocolState uint8
+func (p Protocol) cap() Cap {
+ return Cap{p.Name, p.Version}
+}
const (
- nullState = iota
- handshakeReceived
+ baseProtocolVersion = 2
+ baseProtocolLength = uint64(16)
+ baseProtocolMaxMsgSize = 10 * 1024 * 1024
)
-type DiscReason byte
-
const (
- // Values are given explicitly instead of by iota because these values are
- // defined by the wire protocol spec; it is easier for humans to ensure
- // correctness when values are explicit.
- DiscRequested = 0x00
- DiscNetworkError = 0x01
- DiscProtocolError = 0x02
- DiscUselessPeer = 0x03
- DiscTooManyPeers = 0x04
- DiscAlreadyConnected = 0x05
- DiscIncompatibleVersion = 0x06
- DiscInvalidIdentity = 0x07
- DiscQuitting = 0x08
- DiscUnexpectedIdentity = 0x09
- DiscSelf = 0x0a
- DiscReadTimeout = 0x0b
- DiscSubprotocolError = 0x10
+ // devp2p message codes
+ handshakeMsg = 0x00
+ discMsg = 0x01
+ pingMsg = 0x02
+ pongMsg = 0x03
+ getPeersMsg = 0x04
+ peersMsg = 0x05
)
-var discReasonToString = map[DiscReason]string{
- DiscRequested: "Disconnect requested",
- DiscNetworkError: "Network error",
- DiscProtocolError: "Breach of protocol",
- DiscUselessPeer: "Useless peer",
- DiscTooManyPeers: "Too many peers",
- DiscAlreadyConnected: "Already connected",
- DiscIncompatibleVersion: "Incompatible P2P protocol version",
- DiscInvalidIdentity: "Invalid node identity",
- DiscQuitting: "Client quitting",
- DiscUnexpectedIdentity: "Unexpected identity",
- DiscSelf: "Connected to self",
- DiscReadTimeout: "Read timeout",
- DiscSubprotocolError: "Subprotocol error",
-}
-
-func (d DiscReason) String() string {
- if len(discReasonToString) < int(d) {
- return "Unknown"
- }
-
- return discReasonToString[d]
-}
-
-type BaseProtocol struct {
- peer *Peer
- state ProtocolState
- stateLock sync.RWMutex
+// handshake is the structure of a handshake list.
+type handshake struct {
+ Version uint64
+ ID string
+ Caps []Cap
+ ListenPort uint64
+ NodeID []byte
}
-func NewBaseProtocol(peer *Peer) *BaseProtocol {
- self := &BaseProtocol{
- peer: peer,
- }
-
- return self
+func (h *handshake) String() string {
+ return h.ID
}
-
-func (self *BaseProtocol) Start() {
- if self.peer != nil {
- self.peer.Write("", self.peer.Server().Handshake())
- go self.peer.Messenger().PingPong(
- pingTimeout*time.Second,
- pingGracePeriod*time.Second,
- self.Ping,
- self.Timeout,
- )
- }
+func (h *handshake) Pubkey() []byte {
+ return h.NodeID
}
-func (self *BaseProtocol) Stop() {
+// Cap is the structure of a peer capability.
+type Cap struct {
+ Name string
+ Version uint
}
-func (self *BaseProtocol) Ping() {
- msg, _ := NewMsg(PingMsg)
- self.peer.Write("", msg)
+func (cap Cap) RlpData() interface{} {
+ return []interface{}{cap.Name, cap.Version}
}
-func (self *BaseProtocol) Timeout() {
- self.peerError(PingTimeout, "")
-}
+type capsByName []Cap
-func (self *BaseProtocol) Name() string {
- return ""
-}
+func (cs capsByName) Len() int { return len(cs) }
+func (cs capsByName) Less(i, j int) bool { return cs[i].Name < cs[j].Name }
+func (cs capsByName) Swap(i, j int) { cs[i], cs[j] = cs[j], cs[i] }
-func (self *BaseProtocol) Offset() MsgCode {
- return offset
+type baseProtocol struct {
+ rw MsgReadWriter
+ peer *Peer
}
-func (self *BaseProtocol) CheckState(state ProtocolState) bool {
- self.stateLock.RLock()
- self.stateLock.RUnlock()
- if self.state != state {
- return false
- } else {
- return true
+func runBaseProtocol(peer *Peer, rw MsgReadWriter) error {
+ bp := &baseProtocol{rw, peer}
+ if err := bp.doHandshake(rw); err != nil {
+ return err
}
+ // run main loop
+ quit := make(chan error, 1)
+ go func() {
+ for {
+ if err := bp.handle(rw); err != nil {
+ quit <- err
+ break
+ }
+ }
+ }()
+ return bp.loop(quit)
}
-func (self *BaseProtocol) HandleIn(msg *Msg, response chan *Msg) {
- if msg.Code() == HandshakeMsg {
- self.handleHandshake(msg)
- } else {
- if !self.CheckState(handshakeReceived) {
- self.peerError(ProtocolBreach, "message code %v not allowed", msg.Code())
- close(response)
- return
- }
- switch msg.Code() {
- case DiscMsg:
- logger.Infof("Disconnect requested from peer %v, reason", DiscReason(msg.Data().Get(0).Uint()))
- self.peer.Server().PeerDisconnect() <- DisconnectRequest{
- addr: self.peer.Address,
- reason: DiscRequested,
- }
- case PingMsg:
- out, _ := NewMsg(PongMsg)
- response <- out
- case PongMsg:
- case GetPeersMsg:
- // Peer asked for list of connected peers
- if out, err := self.peer.Server().PeersMessage(); err != nil {
- response <- out
+var pingTimeout = 2 * time.Second
+
+func (bp *baseProtocol) loop(quit <-chan error) error {
+ ping := time.NewTimer(pingTimeout)
+ activity := bp.peer.activity.Subscribe(time.Time{})
+ lastActive := time.Time{}
+ defer ping.Stop()
+ defer activity.Unsubscribe()
+
+ getPeersTick := time.NewTicker(10 * time.Second)
+ defer getPeersTick.Stop()
+ err := bp.rw.EncodeMsg(getPeersMsg)
+
+ for err == nil {
+ select {
+ case err = <-quit:
+ return err
+ case <-getPeersTick.C:
+ err = bp.rw.EncodeMsg(getPeersMsg)
+ case event := <-activity.Chan():
+ ping.Reset(pingTimeout)
+ lastActive = event.(time.Time)
+ case t := <-ping.C:
+ if lastActive.Add(pingTimeout * 2).Before(t) {
+ err = newPeerError(errPingTimeout, "")
+ } else if lastActive.Add(pingTimeout).Before(t) {
+ err = bp.rw.EncodeMsg(pingMsg)
}
- case PeersMsg:
- self.handlePeers(msg)
- default:
- self.peerError(InvalidMsgCode, "unknown message code %v", msg.Code())
}
}
- close(response)
+ return err
}
-func (self *BaseProtocol) HandleOut(msg *Msg) (allowed bool) {
- // somewhat overly paranoid
- allowed = msg.Code() == HandshakeMsg || msg.Code() == DiscMsg || msg.Code() < self.Offset() && self.CheckState(handshakeReceived)
- return
-}
-
-func (self *BaseProtocol) peerError(errorCode ErrorCode, format string, v ...interface{}) {
- err := NewPeerError(errorCode, format, v...)
- logger.Warnln(err)
- fmt.Println(self.peer, err)
- if self.peer != nil {
- self.peer.PeerErrorChan() <- err
+func (bp *baseProtocol) handle(rw MsgReadWriter) error {
+ msg, err := rw.ReadMsg()
+ if err != nil {
+ return err
}
-}
-
-func (self *BaseProtocol) handlePeers(msg *Msg) {
- it := msg.Data().NewIterator()
- for it.Next() {
- ip := net.IP(it.Value().Get(0).Bytes())
- port := it.Value().Get(1).Uint()
- address := &net.TCPAddr{IP: ip, Port: int(port)}
- go self.peer.Server().PeerConnect(address)
+ if msg.Size > baseProtocolMaxMsgSize {
+ return newPeerError(errMisc, "message too big")
}
-}
+ // make sure that the payload has been fully consumed
+ defer msg.Discard()
-func (self *BaseProtocol) handleHandshake(msg *Msg) {
- self.stateLock.Lock()
- defer self.stateLock.Unlock()
- if self.state != nullState {
- self.peerError(ProtocolBreach, "extra handshake")
- return
- }
+ switch msg.Code {
+ case handshakeMsg:
+ return newPeerError(errProtocolBreach, "extra handshake received")
- c := msg.Data()
+ case discMsg:
+ var reason [1]DiscReason
+ if err := msg.Decode(&reason); err != nil {
+ return err
+ }
+ return discRequestedError(reason[0])
+
+ case pingMsg:
+ return bp.rw.EncodeMsg(pongMsg)
+
+ case pongMsg:
+
+ case getPeersMsg:
+ peers := bp.peerList()
+ // this is dangerous. the spec says that we should _delay_
+ // sending the response if no new information is available.
+ // this means that would need to send a response later when
+ // new peers become available.
+ //
+ // TODO: add event mechanism to notify baseProtocol for new peers
+ if len(peers) > 0 {
+ return bp.rw.EncodeMsg(peersMsg, peers)
+ }
- var (
- p2pVersion = c.Get(0).Uint()
- id = c.Get(1).Str()
- caps = c.Get(2)
- port = c.Get(3).Uint()
- pubkey = c.Get(4).Bytes()
- )
- fmt.Printf("handshake received %v, %v, %v, %v, %v ", p2pVersion, id, caps, port, pubkey)
+ case peersMsg:
+ var peers []*peerAddr
+ if err := msg.Decode(&peers); err != nil {
+ return err
+ }
+ for _, addr := range peers {
+ bp.peer.Debugf("received peer suggestion: %v", addr)
+ bp.peer.newPeerAddr <- addr
+ }
- // Check correctness of p2p protocol version
- if p2pVersion != P2PVersion {
- self.peerError(P2PVersionMismatch, "Require protocol %d, received %d\n", P2PVersion, p2pVersion)
- return
+ default:
+ return newPeerError(errInvalidMsgCode, "unknown message code %v", msg.Code)
}
+ return nil
+}
- // Handle the pub key (validation, uniqueness)
- if len(pubkey) == 0 {
- self.peerError(PubkeyMissing, "not supplied in handshake.")
- return
+func (bp *baseProtocol) doHandshake(rw MsgReadWriter) error {
+ // send our handshake
+ if err := rw.WriteMsg(bp.handshakeMsg()); err != nil {
+ return err
}
- if len(pubkey) != 64 {
- self.peerError(PubkeyInvalid, "require 512 bit, got %v", len(pubkey)*8)
- return
+ // read and handle remote handshake
+ msg, err := rw.ReadMsg()
+ if err != nil {
+ return err
}
-
- // Self connect detection
- if bytes.Compare(self.peer.Server().ClientIdentity().Pubkey()[1:], pubkey) == 0 {
- self.peerError(PubkeyForbidden, "not allowed to connect to self")
- return
+ if msg.Code != handshakeMsg {
+ return newPeerError(errProtocolBreach, "first message must be handshake, got %x", msg.Code)
+ }
+ if msg.Size > baseProtocolMaxMsgSize {
+ return newPeerError(errMisc, "message too big")
}
- // register pubkey on server. this also sets the pubkey on the peer (need lock)
- if err := self.peer.Server().RegisterPubkey(self.peer, pubkey); err != nil {
- self.peerError(PubkeyForbidden, err.Error())
- return
+ var hs handshake
+ if err := msg.Decode(&hs); err != nil {
+ return err
}
- // check port
- if self.peer.Inbound {
- uint16port := uint16(port)
- if self.peer.Port > 0 && self.peer.Port != uint16port {
- self.peerError(PortMismatch, "port mismatch: %v != %v", self.peer.Port, port)
- return
- } else {
- self.peer.Port = uint16port
+ // validate handshake info
+ if hs.Version != baseProtocolVersion {
+ return newPeerError(errP2PVersionMismatch, "Require protocol %d, received %d\n",
+ baseProtocolVersion, hs.Version)
+ }
+ if len(hs.NodeID) == 0 {
+ return newPeerError(errPubkeyMissing, "")
+ }
+ if len(hs.NodeID) != 64 {
+ return newPeerError(errPubkeyInvalid, "require 512 bit, got %v", len(hs.NodeID)*8)
+ }
+ if da := bp.peer.dialAddr; da != nil {
+ // verify that the peer we wanted to connect to
+ // actually holds the target public key.
+ if da.Pubkey != nil && !bytes.Equal(da.Pubkey, hs.NodeID) {
+ return newPeerError(errPubkeyForbidden, "dial address pubkey mismatch")
}
}
-
- capsIt := caps.NewIterator()
- for capsIt.Next() {
- cap := capsIt.Value().Str()
- self.peer.Caps = append(self.peer.Caps, cap)
+ pa := newPeerAddr(bp.peer.conn.RemoteAddr(), hs.NodeID)
+ if err := bp.peer.pubkeyHook(pa); err != nil {
+ return newPeerError(errPubkeyForbidden, "%v", err)
}
- sort.Strings(self.peer.Caps)
- self.peer.Messenger().AddProtocols(self.peer.Caps)
- self.peer.Id = id
+ // TODO: remove Caps with empty name
- self.state = handshakeReceived
+ var addr *peerAddr
+ if hs.ListenPort != 0 {
+ addr = newPeerAddr(bp.peer.conn.RemoteAddr(), hs.NodeID)
+ addr.Port = hs.ListenPort
+ }
+ bp.peer.setHandshakeInfo(&hs, addr, hs.Caps)
+ bp.peer.startSubprotocols(hs.Caps)
+ return nil
+}
+
+func (bp *baseProtocol) handshakeMsg() Msg {
+ var (
+ port uint64
+ caps []interface{}
+ )
+ if bp.peer.ourListenAddr != nil {
+ port = bp.peer.ourListenAddr.Port
+ }
+ for _, proto := range bp.peer.protocols {
+ caps = append(caps, proto.cap())
+ }
+ return NewMsg(handshakeMsg,
+ baseProtocolVersion,
+ bp.peer.ourID.String(),
+ caps,
+ port,
+ bp.peer.ourID.Pubkey()[1:],
+ )
+}
- //p.ethereum.PushPeer(p)
- // p.ethereum.reactor.Post("peerList", p.ethereum.Peers())
- return
+func (bp *baseProtocol) peerList() []ethutil.RlpEncodable {
+ peers := bp.peer.otherPeers()
+ ds := make([]ethutil.RlpEncodable, 0, len(peers))
+ for _, p := range peers {
+ p.infolock.Lock()
+ addr := p.listenAddr
+ p.infolock.Unlock()
+ // filter out this peer and peers that are not listening or
+ // have not completed the handshake.
+ // TODO: track previously sent peers and exclude them as well.
+ if p == bp.peer || addr == nil {
+ continue
+ }
+ ds = append(ds, addr)
+ }
+ ourAddr := bp.peer.ourListenAddr
+ if ourAddr != nil && !ourAddr.IP.IsLoopback() && !ourAddr.IP.IsUnspecified() {
+ ds = append(ds, ourAddr)
+ }
+ return ds
}
diff --git a/p2p/protocol_test.go b/p2p/protocol_test.go
new file mode 100644
index 000000000..65f26fb12
--- /dev/null
+++ b/p2p/protocol_test.go
@@ -0,0 +1,58 @@
+package p2p
+
+import (
+ "fmt"
+ "testing"
+)
+
+func TestBaseProtocolDisconnect(t *testing.T) {
+ peer := NewPeer(NewSimpleClientIdentity("p1", "", "", "foo"), nil)
+ peer.ourID = NewSimpleClientIdentity("p2", "", "", "bar")
+ peer.pubkeyHook = func(*peerAddr) error { return nil }
+
+ rw1, rw2 := MsgPipe()
+ done := make(chan struct{})
+ go func() {
+ if err := expectMsg(rw2, handshakeMsg); err != nil {
+ t.Error(err)
+ }
+ err := rw2.EncodeMsg(handshakeMsg,
+ baseProtocolVersion,
+ "",
+ []interface{}{},
+ 0,
+ make([]byte, 64),
+ )
+ if err != nil {
+ t.Error(err)
+ }
+ if err := expectMsg(rw2, getPeersMsg); err != nil {
+ t.Error(err)
+ }
+ if err := rw2.EncodeMsg(discMsg, DiscQuitting); err != nil {
+ t.Error(err)
+ }
+ close(done)
+ }()
+
+ if err := runBaseProtocol(peer, rw1); err == nil {
+ t.Errorf("base protocol returned without error")
+ } else if reason, ok := err.(discRequestedError); !ok || reason != DiscQuitting {
+ t.Errorf("base protocol returned wrong error: %v", err)
+ }
+ <-done
+}
+
+func expectMsg(r MsgReader, code uint64) error {
+ msg, err := r.ReadMsg()
+ if err != nil {
+ return err
+ }
+ if err := msg.Discard(); err != nil {
+ return err
+ }
+ if msg.Code != code {
+ return fmt.Errorf("wrong message code: got %d, expected %d", msg.Code, code)
+ }
+ return nil
+}
diff --git a/p2p/server.go b/p2p/server.go
index 91bc4af5c..326781234 100644
--- a/p2p/server.go
+++ b/p2p/server.go
@@ -2,483 +2,462 @@ package p2p
import (
"bytes"
+ "errors"
"fmt"
"net"
- "sort"
- "strconv"
"sync"
"time"
- logpkg "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/logger"
)
const (
- outboundAddressPoolSize = 10
- disconnectGracePeriod = 2
+ outboundAddressPoolSize = 500
+ defaultDialTimeout = 10 * time.Second
+ portMappingUpdateInterval = 15 * time.Minute
+ portMappingTimeout = 20 * time.Minute
)
-type Blacklist interface {
- Get([]byte) (bool, error)
- Put([]byte) error
- Delete([]byte) error
- Exists(pubkey []byte) (ok bool)
-}
+var srvlog = logger.NewLogger("P2P Server")
+
+// Server manages all peer connections.
+//
+// The fields of Server are used as configuration parameters.
+// You should set them before starting the Server. Fields may not be
+// modified while the server is running.
+type Server struct {
+ // This field must be set to a valid client identity.
+ Identity ClientIdentity
+
+ // MaxPeers is the maximum number of peers that can be
+ // connected. It must be greater than zero.
+ MaxPeers int
+
+ // Protocols should contain the protocols supported
+ // by the server. Matching protocols are launched for
+ // each peer.
+ Protocols []Protocol
+
+ // If Blacklist is set to a non-nil value, the given Blacklist
+ // is used to verify peer connections.
+ Blacklist Blacklist
+
+ // If ListenAddr is set to a non-nil address, the server
+ // will listen for incoming connections.
+ //
+ // If the port is zero, the operating system will pick a port. The
+ // ListenAddr field will be updated with the actual address when
+ // the server is started.
+ ListenAddr string
+
+ // If set to a non-nil value, the given NAT port mapper
+ // is used to make the listening port available to the
+ // Internet.
+ NAT NAT
+
+ // If Dialer is set to a non-nil value, the given Dialer
+ // is used to dial outbound peer connections.
+ Dialer *net.Dialer
+
+ // If NoDial is true, the server will not dial any peers.
+ NoDial bool
+
+ // Hook for testing. This is useful because we can inhibit
+ // the whole protocol stack.
+ newPeerFunc peerFunc
-type BlacklistMap struct {
- blacklist map[string]bool
lock sync.RWMutex
+ running bool
+ listener net.Listener
+ laddr *net.TCPAddr // real listen addr
+ peers []*Peer
+ peerSlots chan int
+ peerCount int
+
+ quit chan struct{}
+ wg sync.WaitGroup
+ peerConnect chan *peerAddr
+ peerDisconnect chan *Peer
}
-func NewBlacklist() *BlacklistMap {
- return &BlacklistMap{
- blacklist: make(map[string]bool),
- }
-}
+// NAT is implemented by NAT traversal methods.
+type NAT interface {
+ GetExternalAddress() (net.IP, error)
+ AddPortMapping(protocol string, extport, intport int, name string, lifetime time.Duration) error
+ DeletePortMapping(protocol string, extport, intport int) error
-func (self *BlacklistMap) Get(pubkey []byte) (bool, error) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- v, ok := self.blacklist[string(pubkey)]
- var err error
- if !ok {
- err = fmt.Errorf("not found")
- }
- return v, err
+ // Should return name of the method.
+ String() string
}
-func (self *BlacklistMap) Exists(pubkey []byte) (ok bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- _, ok = self.blacklist[string(pubkey)]
+type peerFunc func(srv *Server, c net.Conn, dialAddr *peerAddr) *Peer
+
+// Peers returns all connected peers.
+func (srv *Server) Peers() (peers []*Peer) {
+ srv.lock.RLock()
+ defer srv.lock.RUnlock()
+ for _, peer := range srv.peers {
+ if peer != nil {
+ peers = append(peers, peer)
+ }
+ }
return
}
-func (self *BlacklistMap) Put(pubkey []byte) error {
- self.lock.RLock()
- defer self.lock.RUnlock()
- self.blacklist[string(pubkey)] = true
- return nil
+// PeerCount returns the number of connected peers.
+func (srv *Server) PeerCount() int {
+ srv.lock.RLock()
+ defer srv.lock.RUnlock()
+ return srv.peerCount
}
-func (self *BlacklistMap) Delete(pubkey []byte) error {
- self.lock.RLock()
- defer self.lock.RUnlock()
- delete(self.blacklist, string(pubkey))
- return nil
+// SuggestPeer injects an address into the outbound address pool.
+func (srv *Server) SuggestPeer(ip net.IP, port int, nodeID []byte) {
+ select {
+ case srv.peerConnect <- &peerAddr{ip, uint64(port), nodeID}:
+ default: // don't block
+ }
}
-type Server struct {
- network Network
- listening bool //needed?
- dialing bool //needed?
- closed bool
- identity ClientIdentity
- addr net.Addr
- port uint16
- protocols []string
-
- quit chan chan bool
- peersLock sync.RWMutex
-
- maxPeers int
- peers []*Peer
- peerSlots chan int
- peersTable map[string]int
- peersMsg *Msg
- peerCount int
-
- peerConnect chan net.Addr
- peerDisconnect chan DisconnectRequest
- blacklist Blacklist
- handlers Handlers
+// Broadcast sends an RLP-encoded message to all connected peers.
+// This method is deprecated and will be removed later.
+func (srv *Server) Broadcast(protocol string, code uint64, data ...interface{}) {
+ var payload []byte
+ if data != nil {
+ payload = encodePayload(data...)
+ }
+ srv.lock.RLock()
+ defer srv.lock.RUnlock()
+ for _, peer := range srv.peers {
+ if peer != nil {
+ var msg = Msg{Code: code}
+ if data != nil {
+ msg.Payload = bytes.NewReader(payload)
+ msg.Size = uint32(len(payload))
+ }
+ peer.writeProtoMsg(protocol, msg)
+ }
+ }
}
-var logger = logpkg.NewLogger("P2P")
-
-func New(network Network, addr net.Addr, identity ClientIdentity, handlers Handlers, maxPeers int, blacklist Blacklist) *Server {
- // get alphabetical list of protocol names from handlers map
- protocols := []string{}
- for protocol := range handlers {
- protocols = append(protocols, protocol)
+// Start starts running the server.
+// Servers can be re-used and started again after stopping.
+func (srv *Server) Start() (err error) {
+ srv.lock.Lock()
+ defer srv.lock.Unlock()
+ if srv.running {
+ return errors.New("server already running")
}
- sort.Strings(protocols)
+ srvlog.Infoln("Starting Server")
- _, port, _ := net.SplitHostPort(addr.String())
- intport, _ := strconv.Atoi(port)
-
- self := &Server{
- // NewSimpleClientIdentity(clientIdentifier, version, customIdentifier)
- network: network,
- identity: identity,
- addr: addr,
- port: uint16(intport),
- protocols: protocols,
-
- quit: make(chan chan bool),
-
- maxPeers: maxPeers,
- peers: make([]*Peer, maxPeers),
- peerSlots: make(chan int, maxPeers),
- peersTable: make(map[string]int),
-
- peerConnect: make(chan net.Addr, outboundAddressPoolSize),
- peerDisconnect: make(chan DisconnectRequest),
- blacklist: blacklist,
-
- handlers: handlers,
+ // initialize fields
+ if srv.Identity == nil {
+ return fmt.Errorf("Server.Identity must be set to a non-nil identity")
}
- for i := 0; i < maxPeers; i++ {
- self.peerSlots <- i // fill up with indexes
+ if srv.MaxPeers <= 0 {
+ return fmt.Errorf("Server.MaxPeers must be > 0")
}
- return self
-}
-
-func (self *Server) NewAddr(host string, port int) (addr net.Addr, err error) {
- addr, err = self.network.NewAddr(host, port)
- return
-}
-
-func (self *Server) ParseAddr(address string) (addr net.Addr, err error) {
- addr, err = self.network.ParseAddr(address)
- return
-}
-
-func (self *Server) ClientIdentity() ClientIdentity {
- return self.identity
-}
-
-func (self *Server) PeersMessage() (msg *Msg, err error) {
- // TODO: memoize and reset when peers change
- self.peersLock.RLock()
- defer self.peersLock.RUnlock()
- msg = self.peersMsg
- if msg == nil {
- var peerData []interface{}
- for _, i := range self.peersTable {
- peer := self.peers[i]
- peerData = append(peerData, peer.Encode())
- }
- if len(peerData) == 0 {
- err = fmt.Errorf("no peers")
- } else {
- msg, err = NewMsg(PeersMsg, peerData...)
- self.peersMsg = msg //memoize
- }
+ srv.quit = make(chan struct{})
+ srv.peers = make([]*Peer, srv.MaxPeers)
+ srv.peerSlots = make(chan int, srv.MaxPeers)
+ srv.peerConnect = make(chan *peerAddr, outboundAddressPoolSize)
+ srv.peerDisconnect = make(chan *Peer)
+ if srv.newPeerFunc == nil {
+ srv.newPeerFunc = newServerPeer
+ }
+ if srv.Blacklist == nil {
+ srv.Blacklist = NewBlacklist()
+ }
+ if srv.Dialer == nil {
+ srv.Dialer = &net.Dialer{Timeout: defaultDialTimeout}
}
- return
-}
-func (self *Server) Peers() (peers []*Peer) {
- self.peersLock.RLock()
- defer self.peersLock.RUnlock()
- for _, peer := range self.peers {
- if peer != nil {
- peers = append(peers, peer)
+ if srv.ListenAddr != "" {
+ if err := srv.startListening(); err != nil {
+ return err
}
}
- return
-}
-
-func (self *Server) PeerCount() int {
- self.peersLock.RLock()
- defer self.peersLock.RUnlock()
- return self.peerCount
-}
-
-var getPeersMsg, _ = NewMsg(GetPeersMsg)
+ if !srv.NoDial {
+ srv.wg.Add(1)
+ go srv.dialLoop()
+ }
+ if srv.NoDial && srv.ListenAddr == "" {
+ srvlog.Warnln("I will be kind-of useless, neither dialing nor listening.")
+ }
-func (self *Server) PeerConnect(addr net.Addr) {
- // TODO: should buffer, filter and uniq
- // send GetPeersMsg if not blocking
- select {
- case self.peerConnect <- addr: // not enough peers
- self.Broadcast("", getPeersMsg)
- default: // we dont care
+ // make all slots available
+ for i := range srv.peers {
+ srv.peerSlots <- i
}
+ // note: discLoop is not part of WaitGroup
+ go srv.discLoop()
+ srv.running = true
+ return nil
}
-func (self *Server) PeerDisconnect() chan DisconnectRequest {
- return self.peerDisconnect
+func (srv *Server) startListening() error {
+ listener, err := net.Listen("tcp", srv.ListenAddr)
+ if err != nil {
+ return err
+ }
+ srv.ListenAddr = listener.Addr().String()
+ srv.laddr = listener.Addr().(*net.TCPAddr)
+ srv.listener = listener
+ srv.wg.Add(1)
+ go srv.listenLoop()
+ if !srv.laddr.IP.IsLoopback() && srv.NAT != nil {
+ srv.wg.Add(1)
+ go srv.natLoop(srv.laddr.Port)
+ }
+ return nil
}
-func (self *Server) Blacklist() Blacklist {
- return self.blacklist
-}
+// Stop terminates the server and all active peer connections.
+// It blocks until all active connections have been closed.
+func (srv *Server) Stop() {
+ srv.lock.Lock()
+ if !srv.running {
+ srv.lock.Unlock()
+ return
+ }
+ srv.running = false
+ srv.lock.Unlock()
-func (self *Server) Handlers() Handlers {
- return self.handlers
-}
+ srvlog.Infoln("Stopping server")
+ if srv.listener != nil {
+ // this unblocks listener Accept
+ srv.listener.Close()
+ }
+ close(srv.quit)
+ for _, peer := range srv.Peers() {
+ peer.Disconnect(DiscQuitting)
+ }
+ srv.wg.Wait()
-func (self *Server) Broadcast(protocol string, msg *Msg) {
- self.peersLock.RLock()
- defer self.peersLock.RUnlock()
- for _, peer := range self.peers {
- if peer != nil {
- peer.Write(protocol, msg)
- }
+ // wait till they actually disconnect
+ // this is checked by claiming all peerSlots.
+ // slots become available as the peers disconnect.
+ for i := 0; i < cap(srv.peerSlots); i++ {
+ <-srv.peerSlots
}
+ // terminate discLoop
+ close(srv.peerDisconnect)
}
-// Start the server
-func (self *Server) Start(listen bool, dial bool) {
- self.network.Start()
- if listen {
- listener, err := self.network.Listener(self.addr)
- if err != nil {
- logger.Warnf("Error initializing listener: %v", err)
- logger.Warnf("Connection listening disabled")
- self.listening = false
- } else {
- self.listening = true
- logger.Infoln("Listen on %v: ready and accepting connections", listener.Addr())
- go self.inboundPeerHandler(listener)
- }
+func (srv *Server) discLoop() {
+ for peer := range srv.peerDisconnect {
+ srv.removePeer(peer)
}
- if dial {
- dialer, err := self.network.Dialer(self.addr)
- if err != nil {
- logger.Warnf("Error initializing dialer: %v", err)
- logger.Warnf("Connection dialout disabled")
- self.dialing = false
- } else {
- self.dialing = true
- logger.Infoln("Dial peers watching outbound address pool")
- go self.outboundPeerHandler(dialer)
- }
- }
- logger.Infoln("server started")
}
-func (self *Server) Stop() {
- logger.Infoln("server stopping...")
- // // quit one loop if dialing
- if self.dialing {
- logger.Infoln("stop dialout...")
- dialq := make(chan bool)
- self.quit <- dialq
- <-dialq
- fmt.Println("quit another")
- }
- // quit the other loop if listening
- if self.listening {
- logger.Infoln("stop listening...")
- listenq := make(chan bool)
- self.quit <- listenq
- <-listenq
- fmt.Println("quit one")
- }
-
- fmt.Println("quit waited")
-
- logger.Infoln("stopping peers...")
- peers := []net.Addr{}
- self.peersLock.RLock()
- self.closed = true
- for _, peer := range self.peers {
- if peer != nil {
- peers = append(peers, peer.Address)
- }
- }
- self.peersLock.RUnlock()
- for _, address := range peers {
- go self.removePeer(DisconnectRequest{
- addr: address,
- reason: DiscQuitting,
- })
- }
- // wait till they actually disconnect
- // this is checked by draining the peerSlots (slots are released back if a peer is removed)
- i := 0
- fmt.Println("draining peers")
+// main loop for adding connections via listening
+func (srv *Server) listenLoop() {
+ defer srv.wg.Done()
-FOR:
+ srvlog.Infoln("Listening on", srv.listener.Addr())
for {
select {
- case slot := <-self.peerSlots:
- i++
- fmt.Printf("%v: found slot %v", i, slot)
- if i == self.maxPeers {
- break FOR
+ case slot := <-srv.peerSlots:
+ conn, err := srv.listener.Accept()
+ if err != nil {
+ srv.peerSlots <- slot
+ return
}
+ srvlog.Debugf("Accepted conn %v (slot %d)\n", conn.RemoteAddr(), slot)
+ srv.addPeer(conn, nil, slot)
+ case <-srv.quit:
+ return
}
}
- logger.Infoln("server stopped")
}
-// main loop for adding connections via listening
-func (self *Server) inboundPeerHandler(listener net.Listener) {
+func (srv *Server) natLoop(port int) {
+ defer srv.wg.Done()
for {
+ srv.updatePortMapping(port)
select {
- case slot := <-self.peerSlots:
- go self.connectInboundPeer(listener, slot)
- case errc := <-self.quit:
- listener.Close()
- fmt.Println("quit listenloop")
- errc <- true
+ case <-time.After(portMappingUpdateInterval):
+ // one more round
+ case <-srv.quit:
+ srv.removePortMapping(port)
return
}
}
}
-// main loop for adding outbound peers based on peerConnect address pool
-// this same loop handles peer disconnect requests as well
-func (self *Server) outboundPeerHandler(dialer Dialer) {
- // addressChan initially set to nil (only watches peerConnect if we need more peers)
- var addressChan chan net.Addr
- slots := self.peerSlots
- var slot *int
+func (srv *Server) updatePortMapping(port int) {
+ srvlog.Infoln("Attempting to map port", port, "with", srv.NAT)
+ err := srv.NAT.AddPortMapping("tcp", port, port, "ethereum p2p", portMappingTimeout)
+ if err != nil {
+ srvlog.Errorln("Port mapping error:", err)
+ return
+ }
+ extip, err := srv.NAT.GetExternalAddress()
+ if err != nil {
+ srvlog.Errorln("Error getting external IP:", err)
+ return
+ }
+ srv.lock.Lock()
+ extaddr := *(srv.listener.Addr().(*net.TCPAddr))
+ extaddr.IP = extip
+ srvlog.Infoln("Mapped port, external addr is", &extaddr)
+ srv.laddr = &extaddr
+ srv.lock.Unlock()
+}
+
+func (srv *Server) removePortMapping(port int) {
+ srvlog.Infoln("Removing port mapping for", port, "with", srv.NAT)
+ srv.NAT.DeletePortMapping("tcp", port, port)
+}
+
+func (srv *Server) dialLoop() {
+ defer srv.wg.Done()
+ var (
+ suggest chan *peerAddr
+ slot *int
+ slots = srv.peerSlots
+ )
for {
select {
case i := <-slots:
// we need a peer in slot i, slot reserved
slot = &i
// now we can watch for candidate peers in the next loop
- addressChan = self.peerConnect
+ suggest = srv.peerConnect
// do not consume more until candidate peer is found
slots = nil
- case address := <-addressChan:
+
+ case desc := <-suggest:
// candidate peer found, will dial out asyncronously
// if connection fails slot will be released
- go self.connectOutboundPeer(dialer, address, *slot)
+ go srv.dialPeer(desc, *slot)
// we can watch if more peers needed in the next loop
- slots = self.peerSlots
+ slots = srv.peerSlots
// until then we dont care about candidate peers
- addressChan = nil
- case request := <-self.peerDisconnect:
- go self.removePeer(request)
- case errc := <-self.quit:
- if addressChan != nil && slot != nil {
- self.peerSlots <- *slot
+ suggest = nil
+
+ case <-srv.quit:
+ // give back the currently reserved slot
+ if slot != nil {
+ srv.peerSlots <- *slot
}
- fmt.Println("quit dialloop")
- errc <- true
return
}
}
}
-// check if peer address already connected
-func (self *Server) connected(address net.Addr) (err error) {
- self.peersLock.RLock()
- defer self.peersLock.RUnlock()
- // fmt.Printf("address: %v\n", address)
- slot, found := self.peersTable[address.String()]
- if found {
- err = fmt.Errorf("already connected as peer %v (%v)", slot, address)
- }
- return
-}
-
-// connect to peer via listener.Accept()
-func (self *Server) connectInboundPeer(listener net.Listener, slot int) {
- var address net.Addr
- conn, err := listener.Accept()
- if err == nil {
- address = conn.RemoteAddr()
- err = self.connected(address)
- if err != nil {
- conn.Close()
- }
- }
- if err != nil {
- logger.Debugln(err)
- self.peerSlots <- slot
- } else {
- fmt.Printf("adding %v\n", address)
- go self.addPeer(conn, address, true, slot)
- }
-}
-
// connect to peer via dial out
-func (self *Server) connectOutboundPeer(dialer Dialer, address net.Addr, slot int) {
- var conn net.Conn
- err := self.connected(address)
- if err == nil {
- conn, err = dialer.Dial(address.Network(), address.String())
- }
+func (srv *Server) dialPeer(desc *peerAddr, slot int) {
+ srvlog.Debugf("Dialing %v (slot %d)\n", desc, slot)
+ conn, err := srv.Dialer.Dial(desc.Network(), desc.String())
if err != nil {
- logger.Debugln(err)
- self.peerSlots <- slot
- } else {
- go self.addPeer(conn, address, false, slot)
+ srvlog.Errorf("Dial error: %v", err)
+ srv.peerSlots <- slot
+ return
}
+ go srv.addPeer(conn, desc, slot)
}
// creates the new peer object and inserts it into its slot
-func (self *Server) addPeer(conn net.Conn, address net.Addr, inbound bool, slot int) {
- self.peersLock.Lock()
- defer self.peersLock.Unlock()
- if self.closed {
- fmt.Println("oopsy, not no longer need peer")
- conn.Close() //oopsy our bad
- self.peerSlots <- slot // release slot
- } else {
- peer := NewPeer(conn, address, inbound, self)
- self.peers[slot] = peer
- self.peersTable[address.String()] = slot
- self.peerCount++
- // reset peersmsg
- self.peersMsg = nil
- fmt.Printf("added peer %v %v (slot %v)\n", address, peer, slot)
- peer.Start()
+func (srv *Server) addPeer(conn net.Conn, desc *peerAddr, slot int) *Peer {
+ srv.lock.Lock()
+ defer srv.lock.Unlock()
+ if !srv.running {
+ conn.Close()
+ srv.peerSlots <- slot // release slot
+ return nil
}
+ peer := srv.newPeerFunc(srv, conn, desc)
+ peer.slot = slot
+ srv.peers[slot] = peer
+ srv.peerCount++
+ go func() { peer.loop(); srv.peerDisconnect <- peer }()
+ return peer
}
// removes peer: sending disconnect msg, stop peer, remove rom list/table, release slot
-func (self *Server) removePeer(request DisconnectRequest) {
- self.peersLock.Lock()
-
- address := request.addr
- slot := self.peersTable[address.String()]
- peer := self.peers[slot]
- fmt.Printf("removing peer %v %v (slot %v)\n", address, peer, slot)
- if peer == nil {
- logger.Debugf("already removed peer on %v", address)
- self.peersLock.Unlock()
+func (srv *Server) removePeer(peer *Peer) {
+ srv.lock.Lock()
+ defer srv.lock.Unlock()
+ srvlog.Debugf("Removing %v (slot %v)\n", peer, peer.slot)
+ if srv.peers[peer.slot] != peer {
+ srvlog.Warnln("Invalid peer to remove:", peer)
return
}
// remove from list and index
- self.peerCount--
- self.peers[slot] = nil
- delete(self.peersTable, address.String())
- // reset peersmsg
- self.peersMsg = nil
- fmt.Printf("removed peer %v (slot %v)\n", peer, slot)
- self.peersLock.Unlock()
-
- // sending disconnect message
- disconnectMsg, _ := NewMsg(DiscMsg, request.reason)
- peer.Write("", disconnectMsg)
- // be nice and wait
- time.Sleep(disconnectGracePeriod * time.Second)
- // switch off peer and close connections etc.
- fmt.Println("stopping peer")
- peer.Stop()
- fmt.Println("stopped peer")
+ srv.peerCount--
+ srv.peers[peer.slot] = nil
// release slot to signal need for a new peer, last!
- self.peerSlots <- slot
+ srv.peerSlots <- peer.slot
+}
+
+func (srv *Server) verifyPeer(addr *peerAddr) error {
+ if srv.Blacklist.Exists(addr.Pubkey) {
+ return errors.New("blacklisted")
+ }
+ if bytes.Equal(srv.Identity.Pubkey()[1:], addr.Pubkey) {
+ return newPeerError(errPubkeyForbidden, "not allowed to connect to srv")
+ }
+ srv.lock.RLock()
+ defer srv.lock.RUnlock()
+ for _, peer := range srv.peers {
+ if peer != nil {
+ id := peer.Identity()
+ if id != nil && bytes.Equal(id.Pubkey(), addr.Pubkey) {
+ return errors.New("already connected")
+ }
+ }
+ }
+ return nil
}
-// fix handshake message to push to peers
-func (self *Server) Handshake() *Msg {
- fmt.Println(self.identity.Pubkey()[1:])
- msg, _ := NewMsg(HandshakeMsg, P2PVersion, []byte(self.identity.String()), []interface{}{self.protocols}, self.port, self.identity.Pubkey()[1:])
- return msg
+// TODO replace with "Set"
+type Blacklist interface {
+ Get([]byte) (bool, error)
+ Put([]byte) error
+ Delete([]byte) error
+ Exists(pubkey []byte) (ok bool)
}
-func (self *Server) RegisterPubkey(candidate *Peer, pubkey []byte) error {
- // Check for blacklisting
- if self.blacklist.Exists(pubkey) {
- return fmt.Errorf("blacklisted")
+type BlacklistMap struct {
+ blacklist map[string]bool
+ lock sync.RWMutex
+}
+
+func NewBlacklist() *BlacklistMap {
+ return &BlacklistMap{
+ blacklist: make(map[string]bool),
}
+}
- self.peersLock.RLock()
- defer self.peersLock.RUnlock()
- for _, peer := range self.peers {
- if peer != nil && peer != candidate && bytes.Compare(peer.Pubkey, pubkey) == 0 {
- return fmt.Errorf("already connected")
- }
+func (self *BlacklistMap) Get(pubkey []byte) (bool, error) {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ v, ok := self.blacklist[string(pubkey)]
+ var err error
+ if !ok {
+ err = fmt.Errorf("not found")
}
- candidate.Pubkey = pubkey
+ return v, err
+}
+
+func (self *BlacklistMap) Exists(pubkey []byte) (ok bool) {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ _, ok = self.blacklist[string(pubkey)]
+ return
+}
+
+func (self *BlacklistMap) Put(pubkey []byte) error {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ self.blacklist[string(pubkey)] = true
+ return nil
+}
+
+func (self *BlacklistMap) Delete(pubkey []byte) error {
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ delete(self.blacklist, string(pubkey))
return nil
}
diff --git a/p2p/server_test.go b/p2p/server_test.go
index f749cc490..5c0d08d39 100644
--- a/p2p/server_test.go
+++ b/p2p/server_test.go
@@ -2,207 +2,160 @@ package p2p
import (
"bytes"
- "fmt"
+ "io"
"net"
+ "sync"
"testing"
"time"
)
-type TestNetwork struct {
- connections map[string]*TestNetworkConnection
- dialer Dialer
- maxinbound int
-}
-
-func NewTestNetwork(maxinbound int) *TestNetwork {
- connections := make(map[string]*TestNetworkConnection)
- return &TestNetwork{
- connections: connections,
- dialer: &TestDialer{connections},
- maxinbound: maxinbound,
+func startTestServer(t *testing.T, pf peerFunc) *Server {
+ server := &Server{
+ Identity: NewSimpleClientIdentity("clientIdentifier", "version", "customIdentifier", "pubkey"),
+ MaxPeers: 10,
+ ListenAddr: "127.0.0.1:0",
+ newPeerFunc: pf,
}
-}
-
-func (self *TestNetwork) Dialer(addr net.Addr) (Dialer, error) {
- return self.dialer, nil
-}
-
-func (self *TestNetwork) Listener(addr net.Addr) (net.Listener, error) {
- return &TestListener{
- connections: self.connections,
- addr: addr,
- max: self.maxinbound,
- }, nil
-}
-
-func (self *TestNetwork) Start() error {
- return nil
-}
-
-func (self *TestNetwork) NewAddr(string, int) (addr net.Addr, err error) {
- return
-}
-
-func (self *TestNetwork) ParseAddr(string) (addr net.Addr, err error) {
- return
-}
-
-type TestAddr struct {
- name string
-}
-
-func (self *TestAddr) String() string {
- return self.name
-}
-
-func (*TestAddr) Network() string {
- return "test"
-}
-
-type TestDialer struct {
- connections map[string]*TestNetworkConnection
-}
-
-func (self *TestDialer) Dial(network string, addr string) (conn net.Conn, err error) {
- address := &TestAddr{addr}
- tconn := NewTestNetworkConnection(address)
- self.connections[addr] = tconn
- conn = net.Conn(tconn)
- return
-}
-
-type TestListener struct {
- connections map[string]*TestNetworkConnection
- addr net.Addr
- max int
- i int
-}
-
-func (self *TestListener) Accept() (conn net.Conn, err error) {
- self.i++
- if self.i > self.max {
- err = fmt.Errorf("no more")
- } else {
- addr := &TestAddr{fmt.Sprintf("inboundpeer-%d", self.i)}
- tconn := NewTestNetworkConnection(addr)
- key := tconn.RemoteAddr().String()
- self.connections[key] = tconn
- conn = net.Conn(tconn)
- fmt.Printf("accepted connection from: %v \n", addr)
+ if err := server.Start(); err != nil {
+ t.Fatalf("Could not start server: %v", err)
}
- return
-}
-
-func (self *TestListener) Close() error {
- return nil
+ return server
}
-func (self *TestListener) Addr() net.Addr {
- return self.addr
-}
-
-func SetupTestServer(handlers Handlers) (network *TestNetwork, server *Server) {
- network = NewTestNetwork(1)
- addr := &TestAddr{"test:30303"}
- identity := NewSimpleClientIdentity("clientIdentifier", "version", "customIdentifier", "pubkey")
- maxPeers := 2
- if handlers == nil {
- handlers = make(Handlers)
- }
- blackist := NewBlacklist()
- server = New(network, addr, identity, handlers, maxPeers, blackist)
- fmt.Println(server.identity.Pubkey())
- return
-}
+func TestServerListen(t *testing.T) {
+ defer testlog(t).detach()
-func TestServerListener(t *testing.T) {
- network, server := SetupTestServer(nil)
- server.Start(true, false)
- time.Sleep(10 * time.Millisecond)
- server.Stop()
- peer1, ok := network.connections["inboundpeer-1"]
- if !ok {
- t.Error("not found inbound peer 1")
- } else {
- fmt.Printf("out: %v\n", peer1.Out)
- if len(peer1.Out) != 2 {
- t.Errorf("not enough messages sent to peer 1: %v ", len(peer1.Out))
+ // start the test server
+ connected := make(chan *Peer)
+ srv := startTestServer(t, func(srv *Server, conn net.Conn, dialAddr *peerAddr) *Peer {
+ if conn == nil {
+ t.Error("peer func called with nil conn")
+ }
+ if dialAddr != nil {
+ t.Error("peer func called with non-nil dialAddr")
}
+ peer := newPeer(conn, nil, dialAddr)
+ connected <- peer
+ return peer
+ })
+ defer close(connected)
+ defer srv.Stop()
+
+ // dial the test server
+ conn, err := net.DialTimeout("tcp", srv.ListenAddr, 5*time.Second)
+ if err != nil {
+ t.Fatalf("could not dial: %v", err)
}
+ defer conn.Close()
-}
-
-func TestServerDialer(t *testing.T) {
- network, server := SetupTestServer(nil)
- server.Start(false, true)
- server.peerConnect <- &TestAddr{"outboundpeer-1"}
- time.Sleep(10 * time.Millisecond)
- server.Stop()
- peer1, ok := network.connections["outboundpeer-1"]
- if !ok {
- t.Error("not found outbound peer 1")
- } else {
- fmt.Printf("out: %v\n", peer1.Out)
- if len(peer1.Out) != 2 {
- t.Errorf("not enough messages sent to peer 1: %v ", len(peer1.Out))
+ select {
+ case peer := <-connected:
+ if peer.conn.LocalAddr().String() != conn.RemoteAddr().String() {
+ t.Errorf("peer started with wrong conn: got %v, want %v",
+ peer.conn.LocalAddr(), conn.RemoteAddr())
}
+ case <-time.After(1 * time.Second):
+ t.Error("server did not accept within one second")
}
}
-func TestServerBroadcast(t *testing.T) {
- handlers := make(Handlers)
- testProtocol := &TestProtocol{Msgs: []*Msg{}}
- handlers["aaa"] = func(p *Peer) Protocol { return testProtocol }
- network, server := SetupTestServer(handlers)
- server.Start(true, true)
- server.peerConnect <- &TestAddr{"outboundpeer-1"}
- time.Sleep(10 * time.Millisecond)
- msg, _ := NewMsg(0)
- server.Broadcast("", msg)
- packet := Packet(0, 0)
- time.Sleep(10 * time.Millisecond)
- server.Stop()
- peer1, ok := network.connections["outboundpeer-1"]
- if !ok {
- t.Error("not found outbound peer 1")
- } else {
- fmt.Printf("out: %v\n", peer1.Out)
- if len(peer1.Out) != 3 {
- t.Errorf("not enough messages sent to peer 1: %v ", len(peer1.Out))
- } else {
- if bytes.Compare(peer1.Out[1], packet) != 0 {
- t.Errorf("incorrect broadcast packet %v != %v", peer1.Out[1], packet)
- }
- }
+func TestServerDial(t *testing.T) {
+ defer testlog(t).detach()
+
+ // run a fake TCP server to handle the connection.
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatalf("could not setup listener: %v")
}
- peer2, ok := network.connections["inboundpeer-1"]
- if !ok {
- t.Error("not found inbound peer 2")
- } else {
- fmt.Printf("out: %v\n", peer2.Out)
- if len(peer1.Out) != 3 {
- t.Errorf("not enough messages sent to peer 2: %v ", len(peer2.Out))
- } else {
- if bytes.Compare(peer2.Out[1], packet) != 0 {
- t.Errorf("incorrect broadcast packet %v != %v", peer2.Out[1], packet)
+ defer listener.Close()
+ accepted := make(chan net.Conn)
+ go func() {
+ conn, err := listener.Accept()
+ if err != nil {
+ t.Error("acccept error:", err)
+ }
+ conn.Close()
+ accepted <- conn
+ }()
+
+ // start the test server
+ connected := make(chan *Peer)
+ srv := startTestServer(t, func(srv *Server, conn net.Conn, dialAddr *peerAddr) *Peer {
+ if conn == nil {
+ t.Error("peer func called with nil conn")
+ }
+ peer := newPeer(conn, nil, dialAddr)
+ connected <- peer
+ return peer
+ })
+ defer close(connected)
+ defer srv.Stop()
+
+ // tell the server to connect.
+ connAddr := newPeerAddr(listener.Addr(), nil)
+ srv.peerConnect <- connAddr
+
+ select {
+ case conn := <-accepted:
+ select {
+ case peer := <-connected:
+ if peer.conn.RemoteAddr().String() != conn.LocalAddr().String() {
+ t.Errorf("peer started with wrong conn: got %v, want %v",
+ peer.conn.RemoteAddr(), conn.LocalAddr())
}
+ if peer.dialAddr != connAddr {
+ t.Errorf("peer started with wrong dialAddr: got %v, want %v",
+ peer.dialAddr, connAddr)
+ }
+ case <-time.After(1 * time.Second):
+ t.Error("server did not launch peer within one second")
}
+
+ case <-time.After(1 * time.Second):
+ t.Error("server did not connect within one second")
}
}
-func TestServerPeersMessage(t *testing.T) {
- handlers := make(Handlers)
- _, server := SetupTestServer(handlers)
- server.Start(true, true)
- defer server.Stop()
- server.peerConnect <- &TestAddr{"outboundpeer-1"}
- time.Sleep(10 * time.Millisecond)
- peersMsg, err := server.PeersMessage()
- fmt.Println(peersMsg)
- if err != nil {
- t.Errorf("expect no error, got %v", err)
+func TestServerBroadcast(t *testing.T) {
+ defer testlog(t).detach()
+ var connected sync.WaitGroup
+ srv := startTestServer(t, func(srv *Server, c net.Conn, dialAddr *peerAddr) *Peer {
+ peer := newPeer(c, []Protocol{discard}, dialAddr)
+ peer.startSubprotocols([]Cap{discard.cap()})
+ connected.Done()
+ return peer
+ })
+ defer srv.Stop()
+
+ // dial a bunch of conns
+ var conns = make([]net.Conn, 8)
+ connected.Add(len(conns))
+ deadline := time.Now().Add(3 * time.Second)
+ dialer := &net.Dialer{Deadline: deadline}
+ for i := range conns {
+ conn, err := dialer.Dial("tcp", srv.ListenAddr)
+ if err != nil {
+ t.Fatalf("conn %d: dial error: %v", i, err)
+ }
+ defer conn.Close()
+ conn.SetDeadline(deadline)
+ conns[i] = conn
}
- if c := server.PeerCount(); c != 2 {
- t.Errorf("expect 2 peers, got %v", c)
+ connected.Wait()
+
+ // broadcast one message
+ srv.Broadcast("discard", 0, "foo")
+ goldbuf := new(bytes.Buffer)
+ writeMsg(goldbuf, NewMsg(16, "foo"))
+ golden := goldbuf.Bytes()
+
+ // check that the message has been written everywhere
+ for i, conn := range conns {
+ buf := make([]byte, len(golden))
+ if _, err := io.ReadFull(conn, buf); err != nil {
+ t.Errorf("conn %d: read error: %v", i, err)
+ } else if !bytes.Equal(buf, golden) {
+ t.Errorf("conn %d: msg mismatch\ngot: %x\nwant: %x", i, buf, golden)
+ }
}
}
diff --git a/p2p/testlog_test.go b/p2p/testlog_test.go
new file mode 100644
index 000000000..951d43243
--- /dev/null
+++ b/p2p/testlog_test.go
@@ -0,0 +1,28 @@
+package p2p
+
+import (
+ "testing"
+
+ "github.com/ethereum/go-ethereum/logger"
+)
+
+type testLogger struct{ t *testing.T }
+
+func testlog(t *testing.T) testLogger {
+ logger.Reset()
+ l := testLogger{t}
+ logger.AddLogSystem(l)
+ return l
+}
+
+func (testLogger) GetLogLevel() logger.LogLevel { return logger.DebugLevel }
+func (testLogger) SetLogLevel(logger.LogLevel) {}
+
+func (l testLogger) LogPrint(level logger.LogLevel, msg string) {
+ l.t.Logf("%s", msg)
+}
+
+func (testLogger) detach() {
+ logger.Flush()
+ logger.Reset()
+}
diff --git a/p2p/testpoc7.go b/p2p/testpoc7.go
new file mode 100644
index 000000000..c0cc5c544
--- /dev/null
+++ b/p2p/testpoc7.go
@@ -0,0 +1,40 @@
+// +build none
+
+package main
+
+import (
+ "fmt"
+ "log"
+ "net"
+ "os"
+
+ "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/obscuren/secp256k1-go"
+)
+
+func main() {
+ logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.DebugLevel))
+
+ pub, _ := secp256k1.GenerateKeyPair()
+ srv := p2p.Server{
+ MaxPeers: 10,
+ Identity: p2p.NewSimpleClientIdentity("test", "1.0", "", string(pub)),
+ ListenAddr: ":30303",
+ NAT: p2p.PMP(net.ParseIP("10.0.0.1")),
+ }
+ if err := srv.Start(); err != nil {
+ fmt.Println("could not start server:", err)
+ os.Exit(1)
+ }
+
+ // add seed peers
+ seed, err := net.ResolveTCPAddr("tcp", "poc-7.ethdev.com:30303")
+ if err != nil {
+ fmt.Println("couldn't resolve:", err)
+ os.Exit(1)
+ }
+ srv.SuggestPeer(seed.IP, seed.Port, nil)
+
+ select {}
+}
diff --git a/peer.go b/peer.go
deleted file mode 100644
index ff3593604..000000000
--- a/peer.go
+++ /dev/null
@@ -1,892 +0,0 @@
-package eth
-
-import (
- "bytes"
- "container/list"
- "fmt"
- "math"
- "math/big"
- "net"
- "strconv"
- "strings"
- "sync/atomic"
- "time"
-
- "github.com/ethereum/go-ethereum/chain/types"
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/wire"
-)
-
-var peerlogger = logger.NewLogger("PEER")
-
-const (
- // The size of the output buffer for writing messages
- outputBufferSize = 50
- // Current protocol version
- ProtocolVersion = 43
- // Current P2P version
- P2PVersion = 2
- // Ethereum network version
- NetVersion = 0
- // Interval for ping/pong message
- pingPongTimer = 2 * time.Second
-)
-
-type DiscReason byte
-
-const (
- // Values are given explicitly instead of by iota because these values are
- // defined by the wire protocol spec; it is easier for humans to ensure
- // correctness when values are explicit.
- DiscRequested DiscReason = iota
- DiscReTcpSysErr
- DiscBadProto
- DiscBadPeer
- DiscTooManyPeers
- DiscConnDup
- DiscGenesisErr
- DiscProtoErr
- DiscQuitting
-)
-
-var discReasonToString = []string{
- "requested",
- "TCP sys error",
- "bad protocol",
- "useless peer",
- "too many peers",
- "already connected",
- "wrong genesis block",
- "incompatible network",
- "quitting",
-}
-
-func (d DiscReason) String() string {
- if len(discReasonToString) < int(d) {
- return "Unknown"
- }
-
- return discReasonToString[d]
-}
-
-// Peer capabilities
-type Caps byte
-
-const (
- CapPeerDiscTy Caps = 1 << iota
- CapTxTy
- CapChainTy
-
- CapDefault = CapChainTy | CapTxTy | CapPeerDiscTy
-)
-
-var capsToString = map[Caps]string{
- CapPeerDiscTy: "Peer discovery",
- CapTxTy: "Transaction relaying",
- CapChainTy: "Block chain relaying",
-}
-
-func (c Caps) IsCap(cap Caps) bool {
- return c&cap > 0
-}
-
-func (c Caps) String() string {
- var caps []string
- if c.IsCap(CapPeerDiscTy) {
- caps = append(caps, capsToString[CapPeerDiscTy])
- }
- if c.IsCap(CapChainTy) {
- caps = append(caps, capsToString[CapChainTy])
- }
- if c.IsCap(CapTxTy) {
- caps = append(caps, capsToString[CapTxTy])
- }
-
- return strings.Join(caps, " | ")
-}
-
-type Peer struct {
- // Ethereum interface
- ethereum *Ethereum
- // Net connection
- conn net.Conn
- // Output queue which is used to communicate and handle messages
- outputQueue chan *wire.Msg
- // Quit channel
- quit chan bool
- // Determines whether it's an inbound or outbound peer
- inbound bool
- // Flag for checking the peer's connectivity state
- connected int32
- disconnect int32
- // Last known message send
- lastSend time.Time
- // Indicated whether a verack has been send or not
- // This flag is used by writeMessage to check if messages are allowed
- // to be send or not. If no version is known all messages are ignored.
- versionKnown bool
- statusKnown bool
-
- // Last received pong message
- lastPong int64
- lastBlockReceived time.Time
- doneFetchingHashes bool
-
- host []byte
- port uint16
- caps Caps
- td *big.Int
- bestHash []byte
- lastReceivedHash []byte
- requestedHashes [][]byte
-
- // This peer's public key
- pubkey []byte
-
- // Indicated whether the node is catching up or not
- catchingUp bool
- diverted bool
- blocksRequested int
-
- version string
-
- // We use this to give some kind of pingtime to a node, not very accurate, could be improved.
- pingTime time.Duration
- pingStartTime time.Time
-
- lastRequestedBlock *types.Block
-
- protocolCaps *ethutil.Value
-}
-
-func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer {
- pubkey := ethereum.KeyManager().PublicKey()[1:]
-
- return &Peer{
- outputQueue: make(chan *wire.Msg, outputBufferSize),
- quit: make(chan bool),
- ethereum: ethereum,
- conn: conn,
- inbound: inbound,
- disconnect: 0,
- connected: 1,
- port: 30303,
- pubkey: pubkey,
- blocksRequested: 10,
- caps: ethereum.ServerCaps(),
- version: ethereum.ClientIdentity().String(),
- protocolCaps: ethutil.NewValue(nil),
- td: big.NewInt(0),
- doneFetchingHashes: true,
- }
-}
-
-func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
- p := &Peer{
- outputQueue: make(chan *wire.Msg, outputBufferSize),
- quit: make(chan bool),
- ethereum: ethereum,
- inbound: false,
- connected: 0,
- disconnect: 0,
- port: 30303,
- caps: caps,
- version: ethereum.ClientIdentity().String(),
- protocolCaps: ethutil.NewValue(nil),
- td: big.NewInt(0),
- doneFetchingHashes: true,
- }
-
- // Set up the connection in another goroutine so we don't block the main thread
- go func() {
- conn, err := p.Connect(addr)
- if err != nil {
- //peerlogger.Debugln("Connection to peer failed. Giving up.", err)
- p.Stop()
- return
- }
- p.conn = conn
-
- // Atomically set the connection state
- atomic.StoreInt32(&p.connected, 1)
- atomic.StoreInt32(&p.disconnect, 0)
-
- p.Start()
- }()
-
- return p
-}
-
-func (self *Peer) Connect(addr string) (conn net.Conn, err error) {
- const maxTries = 3
- for attempts := 0; attempts < maxTries; attempts++ {
- conn, err = net.DialTimeout("tcp", addr, 10*time.Second)
- if err != nil {
- time.Sleep(time.Duration(attempts*20) * time.Second)
- continue
- }
-
- // Success
- return
- }
-
- return
-}
-
-// Getters
-func (p *Peer) PingTime() string {
- return p.pingTime.String()
-}
-func (p *Peer) Inbound() bool {
- return p.inbound
-}
-func (p *Peer) LastSend() time.Time {
- return p.lastSend
-}
-func (p *Peer) LastPong() int64 {
- return p.lastPong
-}
-func (p *Peer) Host() []byte {
- return p.host
-}
-func (p *Peer) Port() uint16 {
- return p.port
-}
-func (p *Peer) Version() string {
- return p.version
-}
-func (p *Peer) Connected() *int32 {
- return &p.connected
-}
-
-// Setters
-func (p *Peer) SetVersion(version string) {
- p.version = version
-}
-
-// Outputs any RLP encoded data to the peer
-func (p *Peer) QueueMessage(msg *wire.Msg) {
- if atomic.LoadInt32(&p.connected) != 1 {
- return
- }
- p.outputQueue <- msg
-}
-
-func (p *Peer) writeMessage(msg *wire.Msg) {
- // Ignore the write if we're not connected
- if atomic.LoadInt32(&p.connected) != 1 {
- return
- }
-
- if !p.versionKnown {
- switch msg.Type {
- case wire.MsgHandshakeTy: // Ok
- default: // Anything but ack is allowed
- return
- }
- } else {
- /*
- if !p.statusKnown {
- switch msg.Type {
- case wire.MsgStatusTy: // Ok
- default: // Anything but ack is allowed
- return
- }
- }
- */
- }
-
- peerlogger.DebugDetailf("(%v) <= %v\n", p.conn.RemoteAddr(), formatMessage(msg))
-
- err := wire.WriteMessage(p.conn, msg)
- if err != nil {
- peerlogger.Debugln(" Can't send message:", err)
- // Stop the client if there was an error writing to it
- p.Stop()
- return
- }
-}
-
-// Outbound message handler. Outbound messages are handled here
-func (p *Peer) HandleOutbound() {
- // The ping timer. Makes sure that every 2 minutes a ping is send to the peer
- pingTimer := time.NewTicker(pingPongTimer)
- serviceTimer := time.NewTicker(10 * time.Second)
-
-out:
- for {
- skip:
- select {
- // Main message queue. All outbound messages are processed through here
- case msg := <-p.outputQueue:
- if !p.statusKnown {
- switch msg.Type {
- case wire.MsgTxTy, wire.MsgGetBlockHashesTy, wire.MsgBlockHashesTy, wire.MsgGetBlocksTy, wire.MsgBlockTy:
- break skip
- }
- }
-
- p.writeMessage(msg)
- p.lastSend = time.Now()
-
- // Ping timer
- case <-pingTimer.C:
- /*
- timeSince := time.Since(time.Unix(p.lastPong, 0))
- if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+30*time.Second) {
- peerlogger.Infof("Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince)
- p.Stop()
- return
- }
- */
- p.writeMessage(wire.NewMessage(wire.MsgPingTy, ""))
- p.pingStartTime = time.Now()
-
- // Service timer takes care of peer broadcasting, transaction
- // posting or block posting
- case <-serviceTimer.C:
- p.QueueMessage(wire.NewMessage(wire.MsgGetPeersTy, ""))
-
- case <-p.quit:
- // Break out of the for loop if a quit message is posted
- break out
- }
- }
-
-clean:
- // This loop is for draining the output queue and anybody waiting for us
- for {
- select {
- case <-p.outputQueue:
- // TODO
- default:
- break clean
- }
- }
-}
-
-func formatMessage(msg *wire.Msg) (ret string) {
- ret = fmt.Sprintf("%v %v", msg.Type, msg.Data)
-
- /*
- XXX Commented out because I need the log level here to determine
- if i should or shouldn't generate this message
- */
- /*
- switch msg.Type {
- case wire.MsgPeersTy:
- ret += fmt.Sprintf("(%d entries)", msg.Data.Len())
- case wire.MsgBlockTy:
- b1, b2 := chain.NewBlockFromRlpValue(msg.Data.Get(0)), ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len()-1))
- ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), b1.Hash()[0:4], b2.Hash()[0:4])
- case wire.MsgBlockHashesTy:
- h1, h2 := msg.Data.Get(0).Bytes(), msg.Data.Get(msg.Data.Len()-1).Bytes()
- ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), h1, h2)
- }
- */
-
- return
-}
-
-// Inbound handler. Inbound messages are received here and passed to the appropriate methods
-func (p *Peer) HandleInbound() {
- for atomic.LoadInt32(&p.disconnect) == 0 {
-
- // HMM?
- time.Sleep(50 * time.Millisecond)
- // Wait for a message from the peer
- msgs, err := wire.ReadMessages(p.conn)
- if err != nil {
- peerlogger.Debugln(err)
- }
- for _, msg := range msgs {
- peerlogger.DebugDetailf("(%v) => %v\n", p.conn.RemoteAddr(), formatMessage(msg))
-
- switch msg.Type {
- case wire.MsgHandshakeTy:
- // Version message
- p.handleHandshake(msg)
-
- //if p.caps.IsCap(CapPeerDiscTy) {
- p.QueueMessage(wire.NewMessage(wire.MsgGetPeersTy, ""))
- //}
-
- case wire.MsgDiscTy:
- p.Stop()
- peerlogger.Infoln("Disconnect peer: ", DiscReason(msg.Data.Get(0).Uint()))
- case wire.MsgPingTy:
- // Respond back with pong
- p.QueueMessage(wire.NewMessage(wire.MsgPongTy, ""))
- case wire.MsgPongTy:
- // If we received a pong back from a peer we set the
- // last pong so the peer handler knows this peer is still
- // active.
- p.lastPong = time.Now().Unix()
- p.pingTime = time.Since(p.pingStartTime)
- case wire.MsgTxTy:
- // If the message was a transaction queue the transaction
- // in the TxPool where it will undergo validation and
- // processing when a new block is found
- for i := 0; i < msg.Data.Len(); i++ {
- tx := types.NewTransactionFromValue(msg.Data.Get(i))
- p.ethereum.TxPool().QueueTransaction(tx)
- }
- case wire.MsgGetPeersTy:
- // Peer asked for list of connected peers
- //p.pushPeers()
- case wire.MsgPeersTy:
- // Received a list of peers (probably because MsgGetPeersTy was send)
- data := msg.Data
- // Create new list of possible peers for the ethereum to process
- peers := make([]string, data.Len())
- // Parse each possible peer
- for i := 0; i < data.Len(); i++ {
- value := data.Get(i)
- peers[i] = unpackAddr(value.Get(0), value.Get(1).Uint())
- }
-
- // Connect to the list of peers
- p.ethereum.ProcessPeerList(peers)
-
- case wire.MsgStatusTy:
- // Handle peer's status msg
- p.handleStatus(msg)
- }
-
- // TMP
- if p.statusKnown {
- switch msg.Type {
- /*
- case wire.MsgGetTxsTy:
- // Get the current transactions of the pool
- txs := p.ethereum.TxPool().CurrentTransactions()
- // Get the RlpData values from the txs
- txsInterface := make([]interface{}, len(txs))
- for i, tx := range txs {
- txsInterface[i] = tx.RlpData()
- }
- // Broadcast it back to the peer
- p.QueueMessage(wire.NewMessage(wire.MsgTxTy, txsInterface))
- */
-
- case wire.MsgGetBlockHashesTy:
- if msg.Data.Len() < 2 {
- peerlogger.Debugln("err: argument length invalid ", msg.Data.Len())
- }
-
- hash := msg.Data.Get(0).Bytes()
- amount := msg.Data.Get(1).Uint()
-
- hashes := p.ethereum.ChainManager().GetChainHashesFromHash(hash, amount)
-
- p.QueueMessage(wire.NewMessage(wire.MsgBlockHashesTy, ethutil.ByteSliceToInterface(hashes)))
-
- case wire.MsgGetBlocksTy:
- // Limit to max 300 blocks
- max := int(math.Min(float64(msg.Data.Len()), 300.0))
- var blocks []interface{}
-
- for i := 0; i < max; i++ {
- hash := msg.Data.Get(i).Bytes()
- block := p.ethereum.ChainManager().GetBlock(hash)
- if block != nil {
- blocks = append(blocks, block.Value().Raw())
- }
- }
-
- p.QueueMessage(wire.NewMessage(wire.MsgBlockTy, blocks))
-
- case wire.MsgBlockHashesTy:
- p.catchingUp = true
-
- blockPool := p.ethereum.blockPool
-
- foundCommonHash := false
-
- it := msg.Data.NewIterator()
- for it.Next() {
- hash := it.Value().Bytes()
- p.lastReceivedHash = hash
-
- if blockPool.HasCommonHash(hash) {
- foundCommonHash = true
-
- break
- }
-
- blockPool.AddHash(hash, p)
- }
-
- if !foundCommonHash {
- //if !p.FetchHashes() {
- // p.doneFetchingHashes = true
- //}
- p.FetchHashes()
- } else {
- peerlogger.Infof("Found common hash (%x...)\n", p.lastReceivedHash[0:4])
- p.doneFetchingHashes = true
- }
-
- case wire.MsgBlockTy:
- p.catchingUp = true
-
- blockPool := p.ethereum.blockPool
-
- it := msg.Data.NewIterator()
- for it.Next() {
- block := types.NewBlockFromRlpValue(it.Value())
- blockPool.Add(block, p)
-
- p.lastBlockReceived = time.Now()
- }
- case wire.MsgNewBlockTy:
- var (
- blockPool = p.ethereum.blockPool
- block = types.NewBlockFromRlpValue(msg.Data.Get(0))
- td = msg.Data.Get(1).BigInt()
- )
-
- if td.Cmp(blockPool.td) > 0 {
- p.ethereum.blockPool.AddNew(block, p)
- }
- }
-
- }
- }
- }
-
- p.Stop()
-}
-
-func (self *Peer) FetchBlocks(hashes [][]byte) {
- if len(hashes) > 0 {
- peerlogger.Debugf("Fetching blocks (%d)\n", len(hashes))
-
- self.QueueMessage(wire.NewMessage(wire.MsgGetBlocksTy, ethutil.ByteSliceToInterface(hashes)))
- }
-}
-
-func (self *Peer) FetchHashes() bool {
- blockPool := self.ethereum.blockPool
-
- return blockPool.FetchHashes(self)
-}
-
-func (self *Peer) FetchingHashes() bool {
- return !self.doneFetchingHashes
-}
-
-// General update method
-func (self *Peer) update() {
- serviceTimer := time.NewTicker(100 * time.Millisecond)
-
-out:
- for {
- select {
- case <-serviceTimer.C:
- if self.IsCap("eth") {
- var (
- sinceBlock = time.Since(self.lastBlockReceived)
- )
-
- if sinceBlock > 5*time.Second {
- self.catchingUp = false
- }
- }
- case <-self.quit:
- break out
- }
- }
-
- serviceTimer.Stop()
-}
-
-func (p *Peer) Start() {
- peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String())
- servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String())
-
- if p.inbound {
- p.host, p.port = packAddr(peerHost, peerPort)
- } else {
- p.host, p.port = packAddr(servHost, servPort)
- }
-
- err := p.pushHandshake()
- if err != nil {
- peerlogger.Debugln("Peer can't send outbound version ack", err)
-
- p.Stop()
-
- return
- }
-
- go p.HandleOutbound()
- // Run the inbound handler in a new goroutine
- go p.HandleInbound()
- // Run the general update handler
- go p.update()
-
- // Wait a few seconds for startup and then ask for an initial ping
- time.Sleep(2 * time.Second)
- p.writeMessage(wire.NewMessage(wire.MsgPingTy, ""))
- p.pingStartTime = time.Now()
-
-}
-
-func (p *Peer) Stop() {
- p.StopWithReason(DiscRequested)
-}
-
-func (p *Peer) StopWithReason(reason DiscReason) {
- if atomic.AddInt32(&p.disconnect, 1) != 1 {
- return
- }
-
- // Pre-emptively remove the peer; don't wait for reaping. We already know it's dead if we are here
- p.ethereum.RemovePeer(p)
-
- close(p.quit)
- if atomic.LoadInt32(&p.connected) != 0 {
- p.writeMessage(wire.NewMessage(wire.MsgDiscTy, reason))
- p.conn.Close()
- }
-}
-
-func (p *Peer) peersMessage() *wire.Msg {
- outPeers := make([]interface{}, len(p.ethereum.InOutPeers()))
- // Serialise each peer
- for i, peer := range p.ethereum.InOutPeers() {
- // Don't return localhost as valid peer
- if !net.ParseIP(peer.conn.RemoteAddr().String()).IsLoopback() {
- outPeers[i] = peer.RlpData()
- }
- }
-
- // Return the message to the peer with the known list of connected clients
- return wire.NewMessage(wire.MsgPeersTy, outPeers)
-}
-
-// Pushes the list of outbound peers to the client when requested
-func (p *Peer) pushPeers() {
- p.QueueMessage(p.peersMessage())
-}
-
-func (self *Peer) pushStatus() {
- msg := wire.NewMessage(wire.MsgStatusTy, []interface{}{
- uint32(ProtocolVersion),
- uint32(NetVersion),
- self.ethereum.ChainManager().TD,
- self.ethereum.ChainManager().CurrentBlock.Hash(),
- self.ethereum.ChainManager().Genesis().Hash(),
- })
-
- self.QueueMessage(msg)
-}
-
-func (self *Peer) handleStatus(msg *wire.Msg) {
- c := msg.Data
-
- var (
- //protoVersion = c.Get(0).Uint()
- netVersion = c.Get(1).Uint()
- td = c.Get(2).BigInt()
- bestHash = c.Get(3).Bytes()
- genesis = c.Get(4).Bytes()
- )
-
- if bytes.Compare(self.ethereum.ChainManager().Genesis().Hash(), genesis) != 0 {
- loggerger.Warnf("Invalid genisis hash %x. Disabling [eth]\n", genesis)
- return
- }
-
- if netVersion != NetVersion {
- loggerger.Warnf("Invalid network version %d. Disabling [eth]\n", netVersion)
- return
- }
-
- /*
- if protoVersion != ProtocolVersion {
- loggerger.Warnf("Invalid protocol version %d. Disabling [eth]\n", protoVersion)
- return
- }
- */
-
- // Get the td and last hash
- self.td = td
- self.bestHash = bestHash
- self.lastReceivedHash = bestHash
-
- self.statusKnown = true
-
- // Compare the total TD with the blockchain TD. If remote is higher
- // fetch hashes from highest TD node.
- self.FetchHashes()
-
- loggerger.Infof("Peer is [eth] capable. (TD = %v ~ %x)", self.td, self.bestHash)
-
-}
-
-func (p *Peer) pushHandshake() error {
- pubkey := p.ethereum.KeyManager().PublicKey()
- msg := wire.NewMessage(wire.MsgHandshakeTy, []interface{}{
- P2PVersion, []byte(p.version), []interface{}{[]interface{}{"eth", ProtocolVersion}}, p.port, pubkey[1:],
- })
-
- p.QueueMessage(msg)
-
- return nil
-}
-
-func (p *Peer) handleHandshake(msg *wire.Msg) {
- c := msg.Data
-
- var (
- p2pVersion = c.Get(0).Uint()
- clientId = c.Get(1).Str()
- caps = c.Get(2)
- port = c.Get(3).Uint()
- pub = c.Get(4).Bytes()
- )
-
- // Check correctness of p2p protocol version
- if p2pVersion != P2PVersion {
- fmt.Println(p)
- peerlogger.Debugf("Invalid P2P version. Require protocol %d, received %d\n", P2PVersion, p2pVersion)
- p.Stop()
- return
- }
-
- // Handle the pub key (validation, uniqueness)
- if len(pub) == 0 {
- peerlogger.Warnln("Pubkey required, not supplied in handshake.")
- p.Stop()
- return
- }
-
- // Self connect detection
- pubkey := p.ethereum.KeyManager().PublicKey()
- if bytes.Compare(pubkey[1:], pub) == 0 {
- p.Stop()
-
- return
- }
-
- // Check for blacklisting
- for _, pk := range p.ethereum.blacklist {
- if bytes.Compare(pk, pub) == 0 {
- peerlogger.Debugf("Blacklisted peer tried to connect (%x...)\n", pubkey[0:4])
- p.StopWithReason(DiscBadPeer)
-
- return
- }
- }
-
- usedPub := 0
- // This peer is already added to the peerlist so we expect to find a double pubkey at least once
- eachPeer(p.ethereum.Peers(), func(peer *Peer, e *list.Element) {
- if bytes.Compare(pub, peer.pubkey) == 0 {
- usedPub++
- }
- })
-
- if usedPub > 0 {
- peerlogger.Debugf("Pubkey %x found more then once. Already connected to client.", p.pubkey)
- p.Stop()
- return
- }
- p.pubkey = pub
-
- // If this is an inbound connection send an ack back
- if p.inbound {
- p.port = uint16(port)
- }
-
- p.SetVersion(clientId)
-
- p.versionKnown = true
-
- p.ethereum.PushPeer(p)
- p.ethereum.eventMux.Post(PeerListEvent{p.ethereum.Peers()})
-
- p.protocolCaps = caps
-
- it := caps.NewIterator()
- var capsStrs []string
- for it.Next() {
- cap := it.Value().Get(0).Str()
- ver := it.Value().Get(1).Uint()
- switch cap {
- case "eth":
- if ver != ProtocolVersion {
- loggerger.Warnf("Invalid protocol version %d. Disabling [eth]\n", ver)
- continue
- }
- p.pushStatus()
- }
-
- capsStrs = append(capsStrs, fmt.Sprintf("%s/%d", cap, ver))
- }
-
- peerlogger.Infof("Added peer (%s) %d / %d (%v)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, capsStrs)
-
- peerlogger.Debugln(p)
-}
-
-func (self *Peer) IsCap(cap string) bool {
- capsIt := self.protocolCaps.NewIterator()
- for capsIt.Next() {
- if capsIt.Value().Str() == cap {
- return true
- }
- }
-
- return false
-}
-
-func (self *Peer) Caps() *ethutil.Value {
- return self.protocolCaps
-}
-
-func (p *Peer) String() string {
- var strBoundType string
- if p.inbound {
- strBoundType = "inbound"
- } else {
- strBoundType = "outbound"
- }
- var strConnectType string
- if atomic.LoadInt32(&p.disconnect) == 0 {
- strConnectType = "connected"
- } else {
- strConnectType = "disconnected"
- }
-
- return fmt.Sprintf("[%s] (%s) %v %s", strConnectType, strBoundType, p.conn.RemoteAddr(), p.version)
-
-}
-
-func (p *Peer) RlpData() []interface{} {
- return []interface{}{p.host, p.port, p.pubkey}
-}
-
-func packAddr(address, _port string) (host []byte, port uint16) {
- p, _ := strconv.Atoi(_port)
- port = uint16(p)
-
- h := net.ParseIP(address)
- if ip := h.To4(); ip != nil {
- host = []byte(ip)
- } else {
- host = []byte(h)
- }
-
- return
-}
-
-func unpackAddr(value *ethutil.Value, p uint64) string {
- host, _ := net.IP(value.Bytes()).MarshalText()
- prt := strconv.Itoa(int(p))
-
- return net.JoinHostPort(string(host), prt)
-}
diff --git a/pow/block.go b/pow/block.go
new file mode 100644
index 000000000..4759e19fb
--- /dev/null
+++ b/pow/block.go
@@ -0,0 +1,9 @@
+package pow
+
+import "math/big"
+
+type Block interface {
+ Diff() *big.Int
+ HashNoNonce() []byte
+ N() []byte
+}
diff --git a/pow/ezp/pow.go b/pow/ezp/pow.go
new file mode 100644
index 000000000..f669f8aa4
--- /dev/null
+++ b/pow/ezp/pow.go
@@ -0,0 +1,93 @@
+package ezp
+
+import (
+ "math/big"
+ "math/rand"
+ "time"
+
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/pow"
+ "github.com/obscuren/sha3"
+)
+
+var powlogger = logger.NewLogger("POW")
+
+type EasyPow struct {
+ hash *big.Int
+ HashRate int64
+ turbo bool
+}
+
+func New() *EasyPow {
+ return &EasyPow{turbo: true}
+}
+
+func (pow *EasyPow) GetHashrate() int64 {
+ return pow.HashRate
+}
+
+func (pow *EasyPow) Turbo(on bool) {
+ pow.turbo = on
+}
+
+func (pow *EasyPow) Search(block pow.Block, stop <-chan struct{}) []byte {
+ r := rand.New(rand.NewSource(time.Now().UnixNano()))
+ hash := block.HashNoNonce()
+ diff := block.Diff()
+ i := int64(0)
+ start := time.Now().UnixNano()
+ t := time.Now()
+
+ for {
+ select {
+ case <-stop:
+ powlogger.Infoln("Breaking from mining")
+ pow.HashRate = 0
+ return nil
+ default:
+ i++
+
+ if time.Since(t) > (1 * time.Second) {
+ elapsed := time.Now().UnixNano() - start
+ hashes := ((float64(1e9) / float64(elapsed)) * float64(i)) / 1000
+ pow.HashRate = int64(hashes)
+ powlogger.Infoln("Hashing @", pow.HashRate, "khash")
+
+ t = time.Now()
+ }
+
+ sha := crypto.Sha3(big.NewInt(r.Int63()).Bytes())
+ if verify(hash, diff, sha) {
+ return sha
+ }
+ }
+
+ if !pow.turbo {
+ time.Sleep(20 * time.Microsecond)
+ }
+ }
+
+ return nil
+}
+
+func (pow *EasyPow) Verify(block pow.Block) bool {
+ return Verify(block)
+}
+
+func verify(hash []byte, diff *big.Int, nonce []byte) bool {
+ sha := sha3.NewKeccak256()
+
+ d := append(hash, nonce...)
+ sha.Write(d)
+
+ verification := new(big.Int).Div(ethutil.BigPow(2, 256), diff)
+ res := ethutil.U256(ethutil.BigD(sha.Sum(nil)))
+
+ return res.Cmp(verification) <= 0
+}
+
+func Verify(block pow.Block) bool {
+ return verify(block.HashNoNonce(), block.Diff(), block.N())
+}
diff --git a/pow/pow.go b/pow/pow.go
new file mode 100644
index 000000000..c94ee40ba
--- /dev/null
+++ b/pow/pow.go
@@ -0,0 +1,8 @@
+package pow
+
+type PoW interface {
+ Search(block Block, stop <-chan struct{}) []byte
+ Verify(block Block) bool
+ GetHashrate() int64
+ Turbo(bool)
+}
diff --git a/rlp/decode.go b/rlp/decode.go
index 96d912f56..712d9fcf1 100644
--- a/rlp/decode.go
+++ b/rlp/decode.go
@@ -1,6 +1,7 @@
package rlp
import (
+ "bufio"
"encoding/binary"
"errors"
"fmt"
@@ -24,8 +25,9 @@ type Decoder interface {
DecodeRLP(*Stream) error
}
-// Decode parses RLP-encoded data from r and stores the result
-// in the value pointed to by val. Val must be a non-nil pointer.
+// Decode parses RLP-encoded data from r and stores the result in the
+// value pointed to by val. Val must be a non-nil pointer. If r does
+// not implement ByteReader, Decode will do its own buffering.
//
// Decode uses the following type-dependent decoding rules:
//
@@ -52,7 +54,7 @@ type Decoder interface {
// To decode into a Go string, the input must be an RLP string. The
// bytes are taken as-is and will not necessarily be valid UTF-8.
//
-// To decode into an integer type, the input must also be an RLP
+// To decode into an unsigned integer type, the input must also be an RLP
// string. The bytes are interpreted as a big endian representation of
// the integer. If the RLP string is larger than the bit size of the
// type, Decode will return an error. Decode also supports *big.Int.
@@ -64,37 +66,74 @@ type Decoder interface {
// []interface{}, for RLP lists
// []byte, for RLP strings
//
-// Non-empty interface types are not supported, nor are bool, float32,
-// float64, maps, channel types and functions.
-func Decode(r ByteReader, val interface{}) error {
+// Non-empty interface types are not supported, nor are booleans,
+// signed integers, floating point numbers, maps, channels and
+// functions.
+func Decode(r io.Reader, val interface{}) error {
return NewStream(r).Decode(val)
}
-func makeNumDecoder(typ reflect.Type) decoder {
- kind := typ.Kind()
- switch {
- case kind <= reflect.Int64:
- return decodeInt
- case kind <= reflect.Uint64:
- return decodeUint
- default:
- panic("fallthrough")
+type decodeError struct {
+ msg string
+ typ reflect.Type
+}
+
+func (err decodeError) Error() string {
+ return fmt.Sprintf("rlp: %s for %v", err.msg, err.typ)
+}
+
+func wrapStreamError(err error, typ reflect.Type) error {
+ switch err {
+ case ErrExpectedList:
+ return decodeError{"expected input list", typ}
+ case ErrExpectedString:
+ return decodeError{"expected input string or byte", typ}
+ case errUintOverflow:
+ return decodeError{"input string too long", typ}
+ case errNotAtEOL:
+ return decodeError{"input list has too many elements", typ}
}
+ return err
}
-func decodeInt(s *Stream, val reflect.Value) error {
- num, err := s.uint(val.Type().Bits())
- if err != nil {
- return err
+var (
+ decoderInterface = reflect.TypeOf(new(Decoder)).Elem()
+ bigInt = reflect.TypeOf(big.Int{})
+)
+
+func makeDecoder(typ reflect.Type) (dec decoder, err error) {
+ kind := typ.Kind()
+ switch {
+ case typ.Implements(decoderInterface):
+ return decodeDecoder, nil
+ case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(decoderInterface):
+ return decodeDecoderNoPtr, nil
+ case typ.AssignableTo(reflect.PtrTo(bigInt)):
+ return decodeBigInt, nil
+ case typ.AssignableTo(bigInt):
+ return decodeBigIntNoPtr, nil
+ case isUint(kind):
+ return decodeUint, nil
+ case kind == reflect.String:
+ return decodeString, nil
+ case kind == reflect.Slice || kind == reflect.Array:
+ return makeListDecoder(typ)
+ case kind == reflect.Struct:
+ return makeStructDecoder(typ)
+ case kind == reflect.Ptr:
+ return makePtrDecoder(typ)
+ case kind == reflect.Interface && typ.NumMethod() == 0:
+ return decodeInterface, nil
+ default:
+ return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ)
}
- val.SetInt(int64(num))
- return nil
}
func decodeUint(s *Stream, val reflect.Value) error {
- num, err := s.uint(val.Type().Bits())
+ typ := val.Type()
+ num, err := s.uint(typ.Bits())
if err != nil {
- return err
+ return wrapStreamError(err, val.Type())
}
val.SetUint(num)
return nil
@@ -103,7 +142,7 @@ func decodeUint(s *Stream, val reflect.Value) error {
func decodeString(s *Stream, val reflect.Value) error {
b, err := s.Bytes()
if err != nil {
- return err
+ return wrapStreamError(err, val.Type())
}
val.SetString(string(b))
return nil
@@ -116,7 +155,7 @@ func decodeBigIntNoPtr(s *Stream, val reflect.Value) error {
func decodeBigInt(s *Stream, val reflect.Value) error {
b, err := s.Bytes()
if err != nil {
- return err
+ return wrapStreamError(err, val.Type())
}
i := val.Interface().(*big.Int)
if i == nil {
@@ -127,8 +166,6 @@ func decodeBigInt(s *Stream, val reflect.Value) error {
return nil
}
-const maxInt = int(^uint(0) >> 1)
-
func makeListDecoder(typ reflect.Type) (decoder, error) {
etype := typ.Elem()
if etype.Kind() == reflect.Uint8 && !reflect.PtrTo(etype).Implements(decoderInterface) {
@@ -142,55 +179,41 @@ func makeListDecoder(typ reflect.Type) (decoder, error) {
if err != nil {
return nil, err
}
- var maxLen = maxInt
+
if typ.Kind() == reflect.Array {
- maxLen = typ.Len()
+ return func(s *Stream, val reflect.Value) error {
+ return decodeListArray(s, val, etypeinfo.decoder)
+ }, nil
}
- dec := func(s *Stream, val reflect.Value) error {
- return decodeList(s, val, etypeinfo.decoder, maxLen)
- }
- return dec, nil
+ return func(s *Stream, val reflect.Value) error {
+ return decodeListSlice(s, val, etypeinfo.decoder)
+ }, nil
}
-// decodeList decodes RLP list elements into slices and arrays.
-//
-// The approach here is stolen from package json, although we differ
-// in the semantics for arrays. package json discards remaining
-// elements that would not fit into the array. We generate an error in
-// this case because we'd be losing information.
-func decodeList(s *Stream, val reflect.Value, elemdec decoder, maxelem int) error {
+func decodeListSlice(s *Stream, val reflect.Value, elemdec decoder) error {
size, err := s.List()
if err != nil {
- return err
+ return wrapStreamError(err, val.Type())
}
if size == 0 {
- if val.Kind() == reflect.Slice {
- val.Set(reflect.MakeSlice(val.Type(), 0, 0))
- } else {
- zero(val, 0)
- }
+ val.Set(reflect.MakeSlice(val.Type(), 0, 0))
return s.ListEnd()
}
i := 0
- for {
- if i > maxelem {
- return fmt.Errorf("rlp: input List has more than %d elements", maxelem)
- }
- if val.Kind() == reflect.Slice {
- // grow slice if necessary
- if i >= val.Cap() {
- newcap := val.Cap() + val.Cap()/2
- if newcap < 4 {
- newcap = 4
- }
- newv := reflect.MakeSlice(val.Type(), val.Len(), newcap)
- reflect.Copy(newv, val)
- val.Set(newv)
- }
- if i >= val.Len() {
- val.SetLen(i + 1)
+ for ; ; i++ {
+ // grow slice if necessary
+ if i >= val.Cap() {
+ newcap := val.Cap() + val.Cap()/2
+ if newcap < 4 {
+ newcap = 4
}
+ newv := reflect.MakeSlice(val.Type(), val.Len(), newcap)
+ reflect.Copy(newv, val)
+ val.Set(newv)
+ }
+ if i >= val.Len() {
+ val.SetLen(i + 1)
}
// decode into element
if err := elemdec(s, val.Index(i)); err == EOL {
@@ -198,26 +221,49 @@ func decodeList(s *Stream, val reflect.Value, elemdec decoder, maxelem int) erro
} else if err != nil {
return err
}
- i++
}
if i < val.Len() {
- if val.Kind() == reflect.Array {
- // zero the rest of the array.
- zero(val, i)
- } else {
- val.SetLen(i)
- }
+ val.SetLen(i)
}
return s.ListEnd()
}
+func decodeListArray(s *Stream, val reflect.Value, elemdec decoder) error {
+ size, err := s.List()
+ if err != nil {
+ return err
+ }
+ if size == 0 {
+ zero(val, 0)
+ return s.ListEnd()
+ }
+
+ // The approach here is stolen from package json, although we differ
+ // in the semantics for arrays. package json discards remaining
+ // elements that would not fit into the array. We generate an error in
+ // this case because we'd be losing information.
+ vlen := val.Len()
+ i := 0
+ for ; i < vlen; i++ {
+ if err := elemdec(s, val.Index(i)); err == EOL {
+ break
+ } else if err != nil {
+ return err
+ }
+ }
+ if i < vlen {
+ zero(val, i)
+ }
+ return wrapStreamError(s.ListEnd(), val.Type())
+}
+
func decodeByteSlice(s *Stream, val reflect.Value) error {
kind, _, err := s.Kind()
if err != nil {
return err
}
if kind == List {
- return decodeList(s, val, decodeUint, maxInt)
+ return decodeListSlice(s, val, decodeUint)
}
b, err := s.Bytes()
if err == nil {
@@ -226,8 +272,6 @@ func decodeByteSlice(s *Stream, val reflect.Value) error {
return err
}
-var errStringDoesntFitArray = errors.New("rlp: string value doesn't fit into target array")
-
func decodeByteArray(s *Stream, val reflect.Value) error {
kind, size, err := s.Kind()
if err != nil {
@@ -236,14 +280,14 @@ func decodeByteArray(s *Stream, val reflect.Value) error {
switch kind {
case Byte:
if val.Len() == 0 {
- return errStringDoesntFitArray
+ return decodeError{"input string too long", val.Type()}
}
bv, _ := s.Uint()
val.Index(0).SetUint(bv)
zero(val, 1)
case String:
if uint64(val.Len()) < size {
- return errStringDoesntFitArray
+ return decodeError{"input string too long", val.Type()}
}
slice := val.Slice(0, int(size)).Interface().([]byte)
if err := s.readFull(slice); err != nil {
@@ -251,14 +295,15 @@ func decodeByteArray(s *Stream, val reflect.Value) error {
}
zero(val, int(size))
case List:
- return decodeList(s, val, decodeUint, val.Len())
+ return decodeListArray(s, val, decodeUint)
}
return nil
}
func zero(val reflect.Value, start int) {
z := reflect.Zero(val.Type().Elem())
- for i := start; i < val.Len(); i++ {
+ end := val.Len()
+ for i := start; i < end; i++ {
val.Index(i).Set(z)
}
}
@@ -281,7 +326,7 @@ func makeStructDecoder(typ reflect.Type) (decoder, error) {
}
dec := func(s *Stream, val reflect.Value) (err error) {
if _, err = s.List(); err != nil {
- return err
+ return wrapStreamError(err, typ)
}
for _, f := range fields {
err = f.info.decoder(s, val.Field(f.index))
@@ -292,10 +337,7 @@ func makeStructDecoder(typ reflect.Type) (decoder, error) {
return err
}
}
- if err = s.ListEnd(); err == errNotAtEOL {
- err = errors.New("rlp: input List has too many elements")
- }
- return err
+ return wrapStreamError(s.ListEnd(), typ)
}
return dec, nil
}
@@ -333,7 +375,7 @@ func decodeInterface(s *Stream, val reflect.Value) error {
}
if kind == List {
slice := reflect.New(ifsliceType).Elem()
- if err := decodeList(s, slice, decodeInterface, maxInt); err != nil {
+ if err := decodeListSlice(s, slice, decodeInterface); err != nil {
return err
}
val.Set(slice)
@@ -432,8 +474,23 @@ type Stream struct {
type listpos struct{ pos, size uint64 }
-func NewStream(r ByteReader) *Stream {
- return &Stream{r: r, uintbuf: make([]byte, 8), kind: -1}
+// NewStream creates a new stream reading from r.
+// If r does not implement ByteReader, the Stream will
+// introduce its own buffering.
+func NewStream(r io.Reader) *Stream {
+ s := new(Stream)
+ s.Reset(r)
+ return s
+}
+
+// NewListStream creates a new stream that pretends to be positioned
+// at an encoded list of the given length.
+func NewListStream(r io.Reader, len uint64) *Stream {
+ s := new(Stream)
+ s.Reset(r)
+ s.kind = List
+ s.size = len
+ return s
}
// Bytes reads an RLP string and returns its contents as a byte slice.
@@ -459,6 +516,8 @@ func (s *Stream) Bytes() ([]byte, error) {
}
}
+var errUintOverflow = errors.New("rlp: uint overflow")
+
// Uint reads an RLP string of up to 8 bytes and returns its contents
// as an unsigned integer. If the input does not contain an RLP string, the
// returned error will be ErrExpectedString.
@@ -477,7 +536,7 @@ func (s *Stream) uint(maxbits int) (uint64, error) {
return uint64(s.byteval), nil
case String:
if size > uint64(maxbits/8) {
- return 0, fmt.Errorf("rlp: string is larger than %d bits", maxbits)
+ return 0, errUintOverflow
}
return s.readUint(byte(size))
default:
@@ -543,6 +602,23 @@ func (s *Stream) Decode(val interface{}) error {
return info.decoder(s, rval.Elem())
}
+// Reset discards any information about the current decoding context
+// and starts reading from r. If r does not also implement ByteReader,
+// Stream will do its own buffering.
+func (s *Stream) Reset(r io.Reader) {
+ bufr, ok := r.(ByteReader)
+ if !ok {
+ bufr = bufio.NewReader(r)
+ }
+ s.r = bufr
+ s.stack = s.stack[:0]
+ s.size = 0
+ s.kind = -1
+ if s.uintbuf == nil {
+ s.uintbuf = make([]byte, 8)
+ }
+}
+
// Kind returns the kind and size of the next value in the
// input stream.
//
diff --git a/rlp/decode_test.go b/rlp/decode_test.go
index eb1618299..7a1743937 100644
--- a/rlp/decode_test.go
+++ b/rlp/decode_test.go
@@ -3,7 +3,6 @@ package rlp
import (
"bytes"
"encoding/hex"
- "errors"
"fmt"
"io"
"math/big"
@@ -54,6 +53,24 @@ func TestStreamKind(t *testing.T) {
}
}
+func TestNewListStream(t *testing.T) {
+ ls := NewListStream(bytes.NewReader(unhex("0101010101")), 3)
+ if k, size, err := ls.Kind(); k != List || size != 3 || err != nil {
+ t.Errorf("Kind() returned (%v, %d, %v), expected (List, 3, nil)", k, size, err)
+ }
+ if size, err := ls.List(); size != 3 || err != nil {
+ t.Errorf("List() returned (%d, %v), expected (3, nil)", size, err)
+ }
+ for i := 0; i < 3; i++ {
+ if val, err := ls.Uint(); val != 1 || err != nil {
+ t.Errorf("Uint() returned (%d, %v), expected (1, nil)", val, err)
+ }
+ }
+ if err := ls.ListEnd(); err != nil {
+ t.Errorf("ListEnd() returned %v, expected (3, nil)", err)
+ }
+}
+
func TestStreamErrors(t *testing.T) {
type calls []string
tests := []struct {
@@ -69,7 +86,7 @@ func TestStreamErrors(t *testing.T) {
{"81", calls{"Bytes"}, io.ErrUnexpectedEOF},
{"81", calls{"Uint"}, io.ErrUnexpectedEOF},
{"BFFFFFFFFFFFFFFF", calls{"Bytes"}, io.ErrUnexpectedEOF},
- {"89000000000000000001", calls{"Uint"}, errors.New("rlp: string is larger than 64 bits")},
+ {"89000000000000000001", calls{"Uint"}, errUintOverflow},
{"00", calls{"List"}, ErrExpectedList},
{"80", calls{"List"}, ErrExpectedList},
{"C0", calls{"List", "Uint"}, EOL},
@@ -154,7 +171,7 @@ func TestDecodeErrors(t *testing.T) {
t.Errorf("Decode(r, new(chan bool)) error mismatch, got %q, want %q", err, expectErr)
}
- if err := Decode(r, new(int)); err != io.EOF {
+ if err := Decode(r, new(uint)); err != io.EOF {
t.Errorf("Decode(r, new(int)) error mismatch, got %q, want %q", err, io.EOF)
}
}
@@ -163,16 +180,16 @@ type decodeTest struct {
input string
ptr interface{}
value interface{}
- error error
+ error string
}
type simplestruct struct {
- A int
+ A uint
B string
}
type recstruct struct {
- I int
+ I uint
Child *recstruct
}
@@ -185,7 +202,7 @@ var (
var (
sharedByteArray [5]byte
- sharedPtr = new(*int)
+ sharedPtr = new(*uint)
)
var decodeTests = []decodeTest{
@@ -196,17 +213,17 @@ var decodeTests = []decodeTest{
{input: "820505", ptr: new(uint32), value: uint32(0x0505)},
{input: "83050505", ptr: new(uint32), value: uint32(0x050505)},
{input: "8405050505", ptr: new(uint32), value: uint32(0x05050505)},
- {input: "850505050505", ptr: new(uint32), error: errors.New("rlp: string is larger than 32 bits")},
- {input: "C0", ptr: new(uint32), error: ErrExpectedString},
+ {input: "850505050505", ptr: new(uint32), error: "rlp: input string too long for uint32"},
+ {input: "C0", ptr: new(uint32), error: "rlp: expected input string or byte for uint32"},
// slices
- {input: "C0", ptr: new([]int), value: []int{}},
- {input: "C80102030405060708", ptr: new([]int), value: []int{1, 2, 3, 4, 5, 6, 7, 8}},
+ {input: "C0", ptr: new([]uint), value: []uint{}},
+ {input: "C80102030405060708", ptr: new([]uint), value: []uint{1, 2, 3, 4, 5, 6, 7, 8}},
// arrays
- {input: "C0", ptr: new([5]int), value: [5]int{}},
- {input: "C50102030405", ptr: new([5]int), value: [5]int{1, 2, 3, 4, 5}},
- {input: "C6010203040506", ptr: new([5]int), error: errors.New("rlp: input List has more than 5 elements")},
+ {input: "C0", ptr: new([5]uint), value: [5]uint{}},
+ {input: "C50102030405", ptr: new([5]uint), value: [5]uint{1, 2, 3, 4, 5}},
+ {input: "C6010203040506", ptr: new([5]uint), error: "rlp: input list has too many elements for [5]uint"},
// byte slices
{input: "01", ptr: new([]byte), value: []byte{1}},
@@ -214,7 +231,7 @@ var decodeTests = []decodeTest{
{input: "8D6162636465666768696A6B6C6D", ptr: new([]byte), value: []byte("abcdefghijklm")},
{input: "C0", ptr: new([]byte), value: []byte{}},
{input: "C3010203", ptr: new([]byte), value: []byte{1, 2, 3}},
- {input: "C3820102", ptr: new([]byte), error: errors.New("rlp: string is larger than 8 bits")},
+ {input: "C3820102", ptr: new([]byte), error: "rlp: input string too long for uint8"},
// byte arrays
{input: "01", ptr: new([5]byte), value: [5]byte{1}},
@@ -222,9 +239,9 @@ var decodeTests = []decodeTest{
{input: "850102030405", ptr: new([5]byte), value: [5]byte{1, 2, 3, 4, 5}},
{input: "C0", ptr: new([5]byte), value: [5]byte{}},
{input: "C3010203", ptr: new([5]byte), value: [5]byte{1, 2, 3, 0, 0}},
- {input: "C3820102", ptr: new([5]byte), error: errors.New("rlp: string is larger than 8 bits")},
- {input: "86010203040506", ptr: new([5]byte), error: errStringDoesntFitArray},
- {input: "850101", ptr: new([5]byte), error: io.ErrUnexpectedEOF},
+ {input: "C3820102", ptr: new([5]byte), error: "rlp: input string too long for uint8"},
+ {input: "86010203040506", ptr: new([5]byte), error: "rlp: input string too long for [5]uint8"},
+ {input: "850101", ptr: new([5]byte), error: io.ErrUnexpectedEOF.Error()},
// byte array reuse (should be zeroed)
{input: "850102030405", ptr: &sharedByteArray, value: [5]byte{1, 2, 3, 4, 5}},
@@ -237,25 +254,25 @@ var decodeTests = []decodeTest{
// zero sized byte arrays
{input: "80", ptr: new([0]byte), value: [0]byte{}},
{input: "C0", ptr: new([0]byte), value: [0]byte{}},
- {input: "01", ptr: new([0]byte), error: errStringDoesntFitArray},
- {input: "8101", ptr: new([0]byte), error: errStringDoesntFitArray},
+ {input: "01", ptr: new([0]byte), error: "rlp: input string too long for [0]uint8"},
+ {input: "8101", ptr: new([0]byte), error: "rlp: input string too long for [0]uint8"},
// strings
{input: "00", ptr: new(string), value: "\000"},
{input: "8D6162636465666768696A6B6C6D", ptr: new(string), value: "abcdefghijklm"},
- {input: "C0", ptr: new(string), error: ErrExpectedString},
+ {input: "C0", ptr: new(string), error: "rlp: expected input string or byte for string"},
// big ints
{input: "01", ptr: new(*big.Int), value: big.NewInt(1)},
{input: "89FFFFFFFFFFFFFFFFFF", ptr: new(*big.Int), value: veryBigInt},
{input: "10", ptr: new(big.Int), value: *big.NewInt(16)}, // non-pointer also works
- {input: "C0", ptr: new(*big.Int), error: ErrExpectedString},
+ {input: "C0", ptr: new(*big.Int), error: "rlp: expected input string or byte for *big.Int"},
// structs
{input: "C0", ptr: new(simplestruct), value: simplestruct{0, ""}},
{input: "C105", ptr: new(simplestruct), value: simplestruct{5, ""}},
{input: "C50583343434", ptr: new(simplestruct), value: simplestruct{5, "444"}},
- {input: "C3010101", ptr: new(simplestruct), error: errors.New("rlp: input List has too many elements")},
+ {input: "C3010101", ptr: new(simplestruct), error: "rlp: input list has too many elements for rlp.simplestruct"},
{
input: "C501C302C103",
ptr: new(recstruct),
@@ -263,17 +280,17 @@ var decodeTests = []decodeTest{
},
// pointers
- {input: "00", ptr: new(*int), value: (*int)(nil)},
- {input: "80", ptr: new(*int), value: (*int)(nil)},
- {input: "C0", ptr: new(*int), value: (*int)(nil)},
- {input: "07", ptr: new(*int), value: intp(7)},
- {input: "8108", ptr: new(*int), value: intp(8)},
- {input: "C109", ptr: new(*[]int), value: &[]int{9}},
+ {input: "00", ptr: new(*uint), value: (*uint)(nil)},
+ {input: "80", ptr: new(*uint), value: (*uint)(nil)},
+ {input: "C0", ptr: new(*uint), value: (*uint)(nil)},
+ {input: "07", ptr: new(*uint), value: uintp(7)},
+ {input: "8108", ptr: new(*uint), value: uintp(8)},
+ {input: "C109", ptr: new(*[]uint), value: &[]uint{9}},
{input: "C58403030303", ptr: new(*[][]byte), value: &[][]byte{{3, 3, 3, 3}}},
// pointer should be reset to nil
- {input: "05", ptr: sharedPtr, value: intp(5)},
- {input: "80", ptr: sharedPtr, value: (*int)(nil)},
+ {input: "05", ptr: sharedPtr, value: uintp(5)},
+ {input: "80", ptr: sharedPtr, value: (*uint)(nil)},
// interface{}
{input: "00", ptr: new(interface{}), value: []byte{0}},
@@ -284,22 +301,22 @@ var decodeTests = []decodeTest{
{input: "C50183040404", ptr: new(interface{}), value: []interface{}{[]byte{1}, []byte{4, 4, 4}}},
}
-func intp(i int) *int { return &i }
+func uintp(i uint) *uint { return &i }
-func TestDecode(t *testing.T) {
+func runTests(t *testing.T, decode func([]byte, interface{}) error) {
for i, test := range decodeTests {
input, err := hex.DecodeString(test.input)
if err != nil {
t.Errorf("test %d: invalid hex input %q", i, test.input)
continue
}
- err = Decode(bytes.NewReader(input), test.ptr)
- if err != nil && test.error == nil {
+ err = decode(input, test.ptr)
+ if err != nil && test.error == "" {
t.Errorf("test %d: unexpected Decode error: %v\ndecoding into %T\ninput %q",
i, err, test.ptr, test.input)
continue
}
- if test.error != nil && fmt.Sprint(err) != fmt.Sprint(test.error) {
+ if test.error != "" && fmt.Sprint(err) != test.error {
t.Errorf("test %d: Decode error mismatch\ngot %v\nwant %v\ndecoding into %T\ninput %q",
i, err, test.error, test.ptr, test.input)
continue
@@ -312,6 +329,40 @@ func TestDecode(t *testing.T) {
}
}
+func TestDecodeWithByteReader(t *testing.T) {
+ runTests(t, func(input []byte, into interface{}) error {
+ return Decode(bytes.NewReader(input), into)
+ })
+}
+
+// dumbReader reads from a byte slice but does not
+// implement ReadByte.
+type dumbReader []byte
+
+func (r *dumbReader) Read(buf []byte) (n int, err error) {
+ if len(*r) == 0 {
+ return 0, io.EOF
+ }
+ n = copy(buf, *r)
+ *r = (*r)[n:]
+ return n, nil
+}
+
+func TestDecodeWithNonByteReader(t *testing.T) {
+ runTests(t, func(input []byte, into interface{}) error {
+ r := dumbReader(input)
+ return Decode(&r, into)
+ })
+}
+
+func TestDecodeStreamReset(t *testing.T) {
+ s := NewStream(nil)
+ runTests(t, func(input []byte, into interface{}) error {
+ s.Reset(bytes.NewReader(input))
+ return s.Decode(into)
+ })
+}
+
type testDecoder struct{ called bool }
func (t *testDecoder) DecodeRLP(s *Stream) error {
@@ -383,8 +434,8 @@ func ExampleDecode() {
input, _ := hex.DecodeString("C90A1486666F6F626172")
type example struct {
- A, B int
- private int // private fields are ignored
+ A, B uint
+ private uint // private fields are ignored
String string
}
@@ -396,7 +447,7 @@ func ExampleDecode() {
fmt.Printf("Decoded value: %#v\n", s)
}
// Output:
- // Decoded value: rlp.example{A:10, B:20, private:0, String:"foobar"}
+ // Decoded value: rlp.example{A:0xa, B:0x14, private:0x0, String:"foobar"}
}
func ExampleStream() {
diff --git a/rlp/typecache.go b/rlp/typecache.go
index 75dbb43c2..52e68a3c5 100644
--- a/rlp/typecache.go
+++ b/rlp/typecache.go
@@ -1,8 +1,6 @@
package rlp
import (
- "fmt"
- "math/big"
"reflect"
"sync"
)
@@ -51,41 +49,14 @@ func cachedTypeInfo1(typ reflect.Type) (*typeinfo, error) {
return typeCache[typ], err
}
-var (
- decoderInterface = reflect.TypeOf(new(Decoder)).Elem()
- bigInt = reflect.TypeOf(big.Int{})
-)
-
func genTypeInfo(typ reflect.Type) (info *typeinfo, err error) {
info = new(typeinfo)
- kind := typ.Kind()
- switch {
- case typ.Implements(decoderInterface):
- info.decoder = decodeDecoder
- case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(decoderInterface):
- info.decoder = decodeDecoderNoPtr
- case typ.AssignableTo(reflect.PtrTo(bigInt)):
- info.decoder = decodeBigInt
- case typ.AssignableTo(bigInt):
- info.decoder = decodeBigIntNoPtr
- case isInteger(kind):
- info.decoder = makeNumDecoder(typ)
- case kind == reflect.String:
- info.decoder = decodeString
- case kind == reflect.Slice || kind == reflect.Array:
- info.decoder, err = makeListDecoder(typ)
- case kind == reflect.Struct:
- info.decoder, err = makeStructDecoder(typ)
- case kind == reflect.Ptr:
- info.decoder, err = makePtrDecoder(typ)
- case kind == reflect.Interface && typ.NumMethod() == 0:
- info.decoder = decodeInterface
- default:
- err = fmt.Errorf("rlp: type %v is not RLP-serializable", typ)
+ if info.decoder, err = makeDecoder(typ); err != nil {
+ return nil, err
}
- return info, err
+ return info, nil
}
-func isInteger(k reflect.Kind) bool {
- return k >= reflect.Int && k <= reflect.Uintptr
+func isUint(k reflect.Kind) bool {
+ return k >= reflect.Uint && k <= reflect.Uintptr
}
diff --git a/state/dump.go b/state/dump.go
index 186c6dd73..c1f5ecf3a 100644
--- a/state/dump.go
+++ b/state/dump.go
@@ -20,7 +20,7 @@ type World struct {
Accounts map[string]Account `json:"accounts"`
}
-func (self *State) Dump() []byte {
+func (self *StateDB) Dump() []byte {
world := World{
Root: ethutil.Bytes2Hex(self.Trie.GetRoot()),
Accounts: make(map[string]Account),
diff --git a/state/log.go b/state/log.go
index 49da30535..46360f4aa 100644
--- a/state/log.go
+++ b/state/log.go
@@ -2,40 +2,63 @@ package state
import (
"fmt"
- "strings"
"github.com/ethereum/go-ethereum/ethutil"
)
-type Log struct {
- Address []byte
- Topics [][]byte
- Data []byte
+type Log interface {
+ ethutil.RlpEncodable
+
+ Address() []byte
+ Topics() [][]byte
+ Data() []byte
+}
+
+type StateLog struct {
+ address []byte
+ topics [][]byte
+ data []byte
+}
+
+func NewLog(address []byte, topics [][]byte, data []byte) *StateLog {
+ return &StateLog{address, topics, data}
+}
+
+func (self *StateLog) Address() []byte {
+ return self.address
+}
+
+func (self *StateLog) Topics() [][]byte {
+ return self.topics
}
-func NewLogFromValue(decoder *ethutil.Value) *Log {
- log := &Log{
- Address: decoder.Get(0).Bytes(),
- Data: decoder.Get(2).Bytes(),
+func (self *StateLog) Data() []byte {
+ return self.data
+}
+
+func NewLogFromValue(decoder *ethutil.Value) *StateLog {
+ log := &StateLog{
+ address: decoder.Get(0).Bytes(),
+ data: decoder.Get(2).Bytes(),
}
it := decoder.Get(1).NewIterator()
for it.Next() {
- log.Topics = append(log.Topics, it.Value().Bytes())
+ log.topics = append(log.topics, it.Value().Bytes())
}
return log
}
-func (self *Log) RlpData() interface{} {
- return []interface{}{self.Address, ethutil.ByteSliceToInterface(self.Topics), self.Data}
+func (self *StateLog) RlpData() interface{} {
+ return []interface{}{self.address, ethutil.ByteSliceToInterface(self.topics), self.data}
}
-func (self *Log) String() string {
- return fmt.Sprintf(`log: %x %x %x`, self.Address, self.Topics, self.Data)
+func (self *StateLog) String() string {
+ return fmt.Sprintf(`log: %x %x %x`, self.address, self.topics, self.data)
}
-type Logs []*Log
+type Logs []Log
func (self Logs) RlpData() interface{} {
data := make([]interface{}, len(self))
@@ -46,10 +69,10 @@ func (self Logs) RlpData() interface{} {
return data
}
-func (self Logs) String() string {
- var logs []string
+func (self Logs) String() (ret string) {
for _, log := range self {
- logs = append(logs, log.String())
+ ret += fmt.Sprintf("%v", log)
}
- return "[ " + strings.Join(logs, ", ") + " ]"
+
+ return "[" + ret + "]"
}
diff --git a/state/state.go b/state/state.go
index 3abf1545b..a8d611668 100644
--- a/state/state.go
+++ b/state/state.go
@@ -10,12 +10,12 @@ import (
var statelogger = logger.NewLogger("STATE")
-// States within the ethereum protocol are used to store anything
-// within the merkle trie. States take care of caching and storing
+// StateDBs within the ethereum protocol are used to store anything
+// within the merkle trie. StateDBs take care of caching and storing
// nested states. It's the general query interface to retrieve:
// * Contracts
// * Accounts
-type State struct {
+type StateDB struct {
// The trie for this structure
Trie *trie.Trie
@@ -29,24 +29,24 @@ type State struct {
}
// Create a new state from a given trie
-func New(trie *trie.Trie) *State {
- return &State{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)}
+func New(trie *trie.Trie) *StateDB {
+ return &StateDB{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)}
}
-func (self *State) EmptyLogs() {
+func (self *StateDB) EmptyLogs() {
self.logs = nil
}
-func (self *State) AddLog(log *Log) {
+func (self *StateDB) AddLog(log Log) {
self.logs = append(self.logs, log)
}
-func (self *State) Logs() Logs {
+func (self *StateDB) Logs() Logs {
return self.logs
}
// Retrieve the balance from the given address or 0 if object not found
-func (self *State) GetBalance(addr []byte) *big.Int {
+func (self *StateDB) GetBalance(addr []byte) *big.Int {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
return stateObject.balance
@@ -55,24 +55,21 @@ func (self *State) GetBalance(addr []byte) *big.Int {
return ethutil.Big0
}
-func (self *State) Refund(addr []byte, gas, price *big.Int) {
- amount := new(big.Int).Mul(gas, price)
-
+func (self *StateDB) Refund(addr []byte, gas *big.Int) {
if self.refund[string(addr)] == nil {
self.refund[string(addr)] = new(big.Int)
}
-
- self.refund[string(addr)].Add(self.refund[string(addr)], amount)
+ self.refund[string(addr)].Add(self.refund[string(addr)], gas)
}
-func (self *State) AddBalance(addr []byte, amount *big.Int) {
+func (self *StateDB) AddBalance(addr []byte, amount *big.Int) {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
stateObject.AddBalance(amount)
}
}
-func (self *State) GetNonce(addr []byte) uint64 {
+func (self *StateDB) GetNonce(addr []byte) uint64 {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
return stateObject.Nonce
@@ -81,14 +78,14 @@ func (self *State) GetNonce(addr []byte) uint64 {
return 0
}
-func (self *State) SetNonce(addr []byte, nonce uint64) {
+func (self *StateDB) SetNonce(addr []byte, nonce uint64) {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
stateObject.Nonce = nonce
}
}
-func (self *State) GetCode(addr []byte) []byte {
+func (self *StateDB) GetCode(addr []byte) []byte {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
return stateObject.Code
@@ -97,7 +94,7 @@ func (self *State) GetCode(addr []byte) []byte {
return nil
}
-func (self *State) GetState(a, b []byte) []byte {
+func (self *StateDB) GetState(a, b []byte) []byte {
stateObject := self.GetStateObject(a)
if stateObject != nil {
return stateObject.GetState(b).Bytes()
@@ -106,14 +103,14 @@ func (self *State) GetState(a, b []byte) []byte {
return nil
}
-func (self *State) SetState(addr, key []byte, value interface{}) {
+func (self *StateDB) SetState(addr, key []byte, value interface{}) {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
stateObject.SetState(key, ethutil.NewValue(value))
}
}
-func (self *State) Delete(addr []byte) bool {
+func (self *StateDB) Delete(addr []byte) bool {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
stateObject.MarkForDeletion()
@@ -129,7 +126,7 @@ func (self *State) Delete(addr []byte) bool {
//
// Update the given state object and apply it to state trie
-func (self *State) UpdateStateObject(stateObject *StateObject) {
+func (self *StateDB) UpdateStateObject(stateObject *StateObject) {
addr := stateObject.Address()
if len(stateObject.CodeHash()) > 0 {
@@ -140,14 +137,14 @@ func (self *State) UpdateStateObject(stateObject *StateObject) {
}
// Delete the given state object and delete it from the state trie
-func (self *State) DeleteStateObject(stateObject *StateObject) {
+func (self *StateDB) DeleteStateObject(stateObject *StateObject) {
self.Trie.Delete(string(stateObject.Address()))
delete(self.stateObjects, string(stateObject.Address()))
}
// Retrieve a state object given my the address. Nil if not found
-func (self *State) GetStateObject(addr []byte) *StateObject {
+func (self *StateDB) GetStateObject(addr []byte) *StateObject {
addr = ethutil.Address(addr)
stateObject := self.stateObjects[string(addr)]
@@ -166,12 +163,12 @@ func (self *State) GetStateObject(addr []byte) *StateObject {
return stateObject
}
-func (self *State) SetStateObject(object *StateObject) {
+func (self *StateDB) SetStateObject(object *StateObject) {
self.stateObjects[string(object.address)] = object
}
// Retrieve a state object or create a new state object if nil
-func (self *State) GetOrNewStateObject(addr []byte) *StateObject {
+func (self *StateDB) GetOrNewStateObject(addr []byte) *StateObject {
stateObject := self.GetStateObject(addr)
if stateObject == nil {
stateObject = self.NewStateObject(addr)
@@ -181,7 +178,7 @@ func (self *State) GetOrNewStateObject(addr []byte) *StateObject {
}
// Create a state object whether it exist in the trie or not
-func (self *State) NewStateObject(addr []byte) *StateObject {
+func (self *StateDB) NewStateObject(addr []byte) *StateObject {
addr = ethutil.Address(addr)
statelogger.Debugf("(+) %x\n", addr)
@@ -193,7 +190,7 @@ func (self *State) NewStateObject(addr []byte) *StateObject {
}
// Deprecated
-func (self *State) GetAccount(addr []byte) *StateObject {
+func (self *StateDB) GetAccount(addr []byte) *StateObject {
return self.GetOrNewStateObject(addr)
}
@@ -201,11 +198,11 @@ func (self *State) GetAccount(addr []byte) *StateObject {
// Setting, copying of the state methods
//
-func (s *State) Cmp(other *State) bool {
+func (s *StateDB) Cmp(other *StateDB) bool {
return s.Trie.Cmp(other.Trie)
}
-func (self *State) Copy() *State {
+func (self *StateDB) Copy() *StateDB {
if self.Trie != nil {
state := New(self.Trie.Copy())
for k, stateObject := range self.stateObjects {
@@ -213,7 +210,7 @@ func (self *State) Copy() *State {
}
for addr, refund := range self.refund {
- state.refund[addr] = refund
+ state.refund[addr] = new(big.Int).Set(refund)
}
logs := make(Logs, len(self.logs))
@@ -226,7 +223,7 @@ func (self *State) Copy() *State {
return nil
}
-func (self *State) Set(state *State) {
+func (self *StateDB) Set(state *StateDB) {
if state == nil {
panic("Tried setting 'state' to nil through 'Set'")
}
@@ -237,12 +234,12 @@ func (self *State) Set(state *State) {
self.logs = state.logs
}
-func (s *State) Root() []byte {
+func (s *StateDB) Root() []byte {
return s.Trie.GetRoot()
}
// Resets the trie and all siblings
-func (s *State) Reset() {
+func (s *StateDB) Reset() {
s.Trie.Undo()
// Reset all nested states
@@ -251,7 +248,6 @@ func (s *State) Reset() {
continue
}
- //stateObject.state.Reset()
stateObject.Reset()
}
@@ -259,7 +255,7 @@ func (s *State) Reset() {
}
// Syncs the trie and all siblings
-func (s *State) Sync() {
+func (s *StateDB) Sync() {
// Sync all nested states
for _, stateObject := range s.stateObjects {
if stateObject.State == nil {
@@ -274,18 +270,19 @@ func (s *State) Sync() {
s.Empty()
}
-func (self *State) Empty() {
+func (self *StateDB) Empty() {
self.stateObjects = make(map[string]*StateObject)
self.refund = make(map[string]*big.Int)
}
-func (self *State) Update() {
+func (self *StateDB) Refunds() map[string]*big.Int {
+ return self.refund
+}
+
+func (self *StateDB) Update(gasUsed *big.Int) {
var deleted bool
- // Refund any gas that's left
- for addr, amount := range self.refund {
- self.GetStateObject([]byte(addr)).AddBalance(amount)
- }
+ self.refund = make(map[string]*big.Int)
for _, stateObject := range self.stateObjects {
if stateObject.remove {
@@ -309,12 +306,12 @@ func (self *State) Update() {
}
}
-func (self *State) Manifest() *Manifest {
+func (self *StateDB) Manifest() *Manifest {
return self.manifest
}
// Debug stuff
-func (self *State) CreateOutputForDiff() {
+func (self *StateDB) CreateOutputForDiff() {
for _, stateObject := range self.stateObjects {
stateObject.CreateOutputForDiff()
}
diff --git a/state/state_object.go b/state/state_object.go
index f02d1b5ab..b8af4e702 100644
--- a/state/state_object.go
+++ b/state/state_object.go
@@ -35,7 +35,7 @@ type StateObject struct {
codeHash []byte
Nonce uint64
// Contract related attributes
- State *State
+ State *StateDB
Code Code
InitCode Code
@@ -212,7 +212,7 @@ func (c *StateObject) ConvertGas(gas, price *big.Int) error {
func (self *StateObject) SetGasPool(gasLimit *big.Int) {
self.gasPool = new(big.Int).Set(gasLimit)
- statelogger.DebugDetailf("%x: fuel (+ %v)", self.Address(), self.gasPool)
+ statelogger.Debugf("%x: gas (+ %v)", self.Address(), self.gasPool)
}
func (self *StateObject) BuyGas(gas, price *big.Int) error {
@@ -276,15 +276,14 @@ func (c *StateObject) Init() Code {
return c.InitCode
}
-// To satisfy ClosureRef
-func (self *StateObject) Object() *StateObject {
- return self
-}
-
func (self *StateObject) Root() []byte {
return self.State.Trie.GetRoot()
}
+func (self *StateObject) SetCode(code []byte) {
+ self.Code = code
+}
+
//
// Encoding
//
diff --git a/state/state_test.go b/state/state_test.go
index 825d21fcc..28e4fc5da 100644
--- a/state/state_test.go
+++ b/state/state_test.go
@@ -9,7 +9,7 @@ import (
)
type StateSuite struct {
- state *State
+ state *StateDB
}
var _ = checker.Suite(&StateSuite{})
diff --git a/tests/files/BasicTests/genesishashestest.json b/tests/files/BasicTests/genesishashestest.json
index 0ff3c3ed7..ba733e36e 100644
--- a/tests/files/BasicTests/genesishashestest.json
+++ b/tests/files/BasicTests/genesishashestest.json
@@ -1,5 +1,5 @@
{
- "genesis_rlp_hex": "f9012ff9012aa00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0c67c70f5d7d3049337d1dcc0503a249881120019a8e7322774dbfe57b463718ca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b84000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008080830f4240808080a004994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829c0c0",
+ "genesis_rlp_hex": "f9012ef90129a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0c67c70f5d7d3049337d1dcc0503a249881120019a8e7322774dbfe57b463718ca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080830f4240808080a004994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829c0c0",
"genesis_state_root": "c67c70f5d7d3049337d1dcc0503a249881120019a8e7322774dbfe57b463718c",
"initial_alloc": {
"51ba59315b3a95761d0863b05ccc7a7f54703d99": "1606938044258990275541962092341162602522202993782792835301376",
@@ -11,5 +11,5 @@
"e6716f9544a56c530d868e4bfbacb172315bdead": "1606938044258990275541962092341162602522202993782792835301376",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4": "1606938044258990275541962092341162602522202993782792835301376"
},
- "genesis_hash": "955f36d073ccb026b78ab3424c15cf966a7563aa270413859f78702b9e8e22cb"
+ "genesis_hash": "779b1b620b03c0fb24963e183d5e88e3dbe4484e3f6e2aa05942e3be7b48e179"
}
diff --git a/tests/files/StateTests/stExample.json b/tests/files/StateTests/stExample.json
index 875cf379c..34bb4dd8e 100644
--- a/tests/files/StateTests/stExample.json
+++ b/tests/files/StateTests/stExample.json
@@ -8,6 +8,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
diff --git a/tests/files/StateTests/stInitCodeTest.json b/tests/files/StateTests/stInitCodeTest.json
new file mode 100644
index 000000000..67aa42853
--- /dev/null
+++ b/tests/files/StateTests/stInitCodeTest.json
@@ -0,0 +1,870 @@
+{
+ "CallRecursiveContract" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "04110d816c380812a427968ece99b1c963dfbce6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x04110d816c380812a427968ece99b1c963dfbce6"
+ }
+ },
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1",
+ "code" : "0x3060025560206000600039602060006000f0",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x095e7baea6a6c7c4c2dfeb977efac326af552d87"
+ }
+ },
+ "0a517d755cebbf66312b30fff713666a9cb917e0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x0a517d755cebbf66312b30fff713666a9cb917e0"
+ }
+ },
+ "24dd378f51adc67a50e339e8031fe9bd4aafab36" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x24dd378f51adc67a50e339e8031fe9bd4aafab36"
+ }
+ },
+ "293f982d000532a7861ab122bdc4bbfd26bf9030" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x293f982d000532a7861ab122bdc4bbfd26bf9030"
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "10000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2cf5732f017b0cf1b1f13a1478e10239716bf6b5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x2cf5732f017b0cf1b1f13a1478e10239716bf6b5"
+ }
+ },
+ "31c640b92c21a1f1465c91070b4b3b4d6854195f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "37f998764813b136ddf5a754f34063fd03065e36" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x37f998764813b136ddf5a754f34063fd03065e36"
+ }
+ },
+ "37fa399a749c121f8a15ce77e3d9f9bec8020d7a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x37fa399a749c121f8a15ce77e3d9f9bec8020d7a"
+ }
+ },
+ "4f36659fa632310b6ec438dea4085b522a2dd077" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x4f36659fa632310b6ec438dea4085b522a2dd077"
+ }
+ },
+ "62c01474f089b07dae603491675dc5b5748f7049" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x62c01474f089b07dae603491675dc5b5748f7049"
+ }
+ },
+ "729af7294be595a0efd7d891c9e51f89c07950c7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x729af7294be595a0efd7d891c9e51f89c07950c7"
+ }
+ },
+ "83e3e5a16d3b696a0314b30b2534804dd5e11197" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x83e3e5a16d3b696a0314b30b2534804dd5e11197"
+ }
+ },
+ "8703df2417e0d7c59d063caa9583cb10a4d20532" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x8703df2417e0d7c59d063caa9583cb10a4d20532"
+ }
+ },
+ "8dffcd74e5b5923512916c6a64b502689cfa65e1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x8dffcd74e5b5923512916c6a64b502689cfa65e1"
+ }
+ },
+ "95a4d7cccb5204733874fa87285a176fe1e9e240" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x95a4d7cccb5204733874fa87285a176fe1e9e240"
+ }
+ },
+ "99b2fcba8120bedd048fe79f5262a6690ed38c39" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x99b2fcba8120bedd048fe79f5262a6690ed38c39"
+ }
+ },
+ "a4202b8b8afd5354e3e40a219bdc17f6001bf2cf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xa4202b8b8afd5354e3e40a219bdc17f6001bf2cf"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "89999",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a9647f4a0a14042d91dc33c0328030a7157c93ae" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xa9647f4a0a14042d91dc33c0328030a7157c93ae"
+ }
+ },
+ "aa6cffe5185732689c18f37a7f86170cb7304c2a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xaa6cffe5185732689c18f37a7f86170cb7304c2a"
+ }
+ },
+ "aae4a2e3c51c04606dcb3723456e58f3ed214f45" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xaae4a2e3c51c04606dcb3723456e58f3ed214f45"
+ }
+ },
+ "c37a43e940dfb5baf581a0b82b351d48305fc885" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xc37a43e940dfb5baf581a0b82b351d48305fc885"
+ }
+ },
+ "d2571607e241ecf590ed94b12d87c94babe36db6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xd2571607e241ecf590ed94b12d87c94babe36db6"
+ }
+ },
+ "f735071cbee190d76b704ce68384fc21e389fbe7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xf735071cbee190d76b704ce68384fc21e389fbe7"
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "0",
+ "code" : "0x3060025560206000600039602060006000f0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "100000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "0x00",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "1"
+ }
+ },
+ "CallTheContractToCreateContractWithInitCode" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "04110d816c380812a427968ece99b1c963dfbce6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x04110d816c380812a427968ece99b1c963dfbce6"
+ }
+ },
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "10001",
+ "code" : "0x3060025560206000600039602060006000f0",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x095e7baea6a6c7c4c2dfeb977efac326af552d87"
+ }
+ },
+ "0a517d755cebbf66312b30fff713666a9cb917e0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x0a517d755cebbf66312b30fff713666a9cb917e0"
+ }
+ },
+ "24dd378f51adc67a50e339e8031fe9bd4aafab36" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x24dd378f51adc67a50e339e8031fe9bd4aafab36"
+ }
+ },
+ "293f982d000532a7861ab122bdc4bbfd26bf9030" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x293f982d000532a7861ab122bdc4bbfd26bf9030"
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "10000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2cf5732f017b0cf1b1f13a1478e10239716bf6b5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x2cf5732f017b0cf1b1f13a1478e10239716bf6b5"
+ }
+ },
+ "31c640b92c21a1f1465c91070b4b3b4d6854195f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "37f998764813b136ddf5a754f34063fd03065e36" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x37f998764813b136ddf5a754f34063fd03065e36"
+ }
+ },
+ "37fa399a749c121f8a15ce77e3d9f9bec8020d7a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x37fa399a749c121f8a15ce77e3d9f9bec8020d7a"
+ }
+ },
+ "4f36659fa632310b6ec438dea4085b522a2dd077" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x4f36659fa632310b6ec438dea4085b522a2dd077"
+ }
+ },
+ "62c01474f089b07dae603491675dc5b5748f7049" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x62c01474f089b07dae603491675dc5b5748f7049"
+ }
+ },
+ "729af7294be595a0efd7d891c9e51f89c07950c7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x729af7294be595a0efd7d891c9e51f89c07950c7"
+ }
+ },
+ "83e3e5a16d3b696a0314b30b2534804dd5e11197" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x83e3e5a16d3b696a0314b30b2534804dd5e11197"
+ }
+ },
+ "8703df2417e0d7c59d063caa9583cb10a4d20532" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x8703df2417e0d7c59d063caa9583cb10a4d20532"
+ }
+ },
+ "8dffcd74e5b5923512916c6a64b502689cfa65e1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x8dffcd74e5b5923512916c6a64b502689cfa65e1"
+ }
+ },
+ "95a4d7cccb5204733874fa87285a176fe1e9e240" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x95a4d7cccb5204733874fa87285a176fe1e9e240"
+ }
+ },
+ "99b2fcba8120bedd048fe79f5262a6690ed38c39" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0x99b2fcba8120bedd048fe79f5262a6690ed38c39"
+ }
+ },
+ "a4202b8b8afd5354e3e40a219bdc17f6001bf2cf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xa4202b8b8afd5354e3e40a219bdc17f6001bf2cf"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "89999",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a9647f4a0a14042d91dc33c0328030a7157c93ae" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xa9647f4a0a14042d91dc33c0328030a7157c93ae"
+ }
+ },
+ "aa6cffe5185732689c18f37a7f86170cb7304c2a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xaa6cffe5185732689c18f37a7f86170cb7304c2a"
+ }
+ },
+ "aae4a2e3c51c04606dcb3723456e58f3ed214f45" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xaae4a2e3c51c04606dcb3723456e58f3ed214f45"
+ }
+ },
+ "c37a43e940dfb5baf581a0b82b351d48305fc885" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xc37a43e940dfb5baf581a0b82b351d48305fc885"
+ }
+ },
+ "d2571607e241ecf590ed94b12d87c94babe36db6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xd2571607e241ecf590ed94b12d87c94babe36db6"
+ }
+ },
+ "f735071cbee190d76b704ce68384fc21e389fbe7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ "0x02" : "0xf735071cbee190d76b704ce68384fc21e389fbe7"
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "10000",
+ "code" : "0x3060025560206000600039602060006000f0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "100000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "0x00",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "1"
+ }
+ },
+ "CallTheContractToCreateEmptyContract" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1",
+ "code" : "0x602060006000f0",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "605",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "99394",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d2571607e241ecf590ed94b12d87c94babe36db6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "0",
+ "code" : "0x602060006000f0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "100000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "0x00",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "1"
+ }
+ },
+ "NotEnoughCashContractCreation" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "2",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "2",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "0x600a80600c6000396000f200600160008035811a8100",
+ "gasLimit" : "599",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "",
+ "value" : "1"
+ }
+ },
+ "OutOfGasContractCreation" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1770",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
+ "balance" : "1",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "8229",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "10000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "0x600a80600c6000396000f200600160008035811a8100",
+ "gasLimit" : "590",
+ "gasPrice" : "3",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "",
+ "value" : "1"
+ }
+ },
+ "TransactionContractCreation" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "599",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
+ "balance" : "1",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "99400",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "100000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "0x600a80600c6000396000f200600160008035811a8100",
+ "gasLimit" : "599",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "",
+ "value" : "1"
+ }
+ },
+ "TransactionCreateSuicideContract" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
+ "balance" : "1",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "8999",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "10000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "0x600a80600c6000396000f200ff600160008035811a81",
+ "gasLimit" : "1000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "",
+ "value" : "1"
+ }
+ },
+ "TransactionStopInitCode" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "599",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
+ "balance" : "1",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "9400",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "10000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "0x600a80600c600039600000f20000600160008035811a81",
+ "gasLimit" : "1000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "",
+ "value" : "1"
+ }
+ },
+ "TransactionSuicideInitCode" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0000000000000000000000000000000000000000" : {
+ "balance" : "1",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "611",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "9388",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "10000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "0x600a80600c6000396000fff2ffff600160008035811a81",
+ "gasLimit" : "1000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "",
+ "value" : "1"
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/files/StateTests/stLogTests.json b/tests/files/StateTests/stLogTests.json
new file mode 100644
index 000000000..888f6c5bb
--- /dev/null
+++ b/tests/files/StateTests/stLogTests.json
@@ -0,0 +1,3712 @@
+{
+ "log0_emptyMem" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x60006000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "862",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899138",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log0_logMemStartTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1628",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898372",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log0_logMemsizeTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1628",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898372",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log0_logMemsizeZero" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006001a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "866",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899134",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006001a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log0_nonEmptyMem" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "898",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899102",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log0_nonEmptyMem_logMemSize1" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xaa",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260016000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "867",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899133",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260016000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log0_nonEmptyMem_logMemSize1_logMemStart31" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xdd",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526001601fa0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "867",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899133",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526001601fa0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log1_Caller" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000002880000000000000000000010000004000000000000000000000000000000000000000000000",
+ "data" : "0xff00000000000000000000000000000000000000000000000000000000000000",
+ "topics" : [
+ "000000000000000000000000095e7baea6a6c7c4c2dfeb977efac326af552d87"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x60ff6000533360206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "931",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899069",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff6000533360206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log1_MaxTopic" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000200000800000000000000000000000000000000880000000000000000000000000000000000000000000000010000000000000000000000020",
+ "data" : "0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd",
+ "topics" : [
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "931",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899069",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log1_emptyMem" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x600060006000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "895",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899105",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600060006000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log1_logMemStartTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1628",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898372",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log1_logMemsizeTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1628",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898372",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log1_logMemsizeZero" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006001a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "899",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899101",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006001a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log1_nonEmptyMem" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "931",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899069",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log1_nonEmptyMem_logMemSize1" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xaa",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060016000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "900",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899100",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060016000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log1_nonEmptyMem_logMemSize1_logMemStart31" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xdd",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006001601fa1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "900",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899100",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006001601fa1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log2_Caller" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000002880000020000000000002010000004000000000080000000000000000000000000000000000",
+ "data" : "0xff00000000000000000000000000000000000000000000000000000000000000",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000095e7baea6a6c7c4c2dfeb977efac326af552d87"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x60ff60005333600060206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "964",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899036",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff60005333600060206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log2_MaxTopic" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000200000800000000000000000000000000000000880000000000000000000000000000000000000000000000010000000000000000000000020",
+ "data" : "0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd",
+ "topics" : [
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "964",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899036",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log2_emptyMem" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x6000600060006000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "928",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899072",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6000600060006000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log2_logMemStartTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1628",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898372",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log2_logMemsizeTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1628",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898372",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log2_logMemsizeZero" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060006001a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "932",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899068",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060006001a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log2_nonEmptyMem" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526000600060206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "964",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899036",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526000600060206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log2_nonEmptyMem_logMemSize1" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xaa",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060016000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "933",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899067",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060016000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log2_nonEmptyMem_logMemSize1_logMemStart31" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xdd",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006001601fa2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "933",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899067",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006001601fa2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log3_Caller" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000002880000020000000000002010000004000000000080000000000000000000000000000000000",
+ "data" : "0xff00000000000000000000000000000000000000000000000000000000000000",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000095e7baea6a6c7c4c2dfeb977efac326af552d87"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x60ff600053336000600060206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "997",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899003",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff600053336000600060206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log3_MaxTopic" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000200000800000000000000000000000000000000880000000000000000000000000000000000000000000000010000000000000000000000020",
+ "data" : "0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd",
+ "topics" : [
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "997",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899003",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log3_PC" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00003004000000000000800000000010000008000000000000000980000000000000000000000000000000000000000000001000000400000000000800000000",
+ "data" : "0xff00000000000000000000000000000000000000000000000000000000000000",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000007",
+ "0000000000000000000000000000000000000000000000000000000000000006",
+ "0000000000000000000000000000000000000000000000000000000000000005"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x60ff60005358585860206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "997",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899003",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff60005358585860206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log3_emptyMem" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x60006000600060006000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "961",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899039",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log3_logMemStartTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1628",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898372",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log3_logMemsizeTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1628",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898372",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log3_logMemsizeZero" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060006001a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "965",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899035",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060006001a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log3_nonEmptyMem" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260006000600060206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "997",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899003",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260006000600060206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log3_nonEmptyMem_logMemSize1" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xaa",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060016000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "966",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899034",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060016000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log3_nonEmptyMem_logMemSize1_logMemStart31" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xdd",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060006001601fa3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "966",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899034",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060006001601fa3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log4_Caller" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "828",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899172",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log4_MaxTopic" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000200000800000000000000000000000000000000880000000000000000000000000000000000000000000000010000000000000000000000020",
+ "data" : "0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd",
+ "topics" : [
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1030",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898970",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log4_PC" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "828",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899172",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log4_emptyMem" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x600060006000600060006000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "994",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899006",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600060006000600060006000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log4_logMemStartTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1628",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898372",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log4_logMemsizeTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1628",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898372",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log4_logMemsizeZero" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060006001a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "998",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899002",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060006001a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log4_nonEmptyMem" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060006000600060206000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1030",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898970",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060006000600060206000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log4_nonEmptyMem_logMemSize1" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xaa",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060016000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "999",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899001",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060016000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "log4_nonEmptyMem_logMemSize1_logMemStart31" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xdd",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000099977",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0x01"
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060006001601fa4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "999",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999899001",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006017730f572e5295c57f15886f9b263e2f6d2d6c7b5ec66103e8f1600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060006001601fa4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/files/StateTests/stPreCompiledContracts.json b/tests/files/StateTests/stPreCompiledContracts.json
index df4b07ca7..0f1db1275 100644
--- a/tests/files/StateTests/stPreCompiledContracts.json
+++ b/tests/files/StateTests/stPreCompiledContracts.json
@@ -8,6 +8,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000001" : {
@@ -19,22 +21,23 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016103e8f15060a060020a608051066000556000543214600155",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016103e8f160025560a060020a608051066000556000543214600155",
"nonce" : "0",
"storage" : {
"0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
- "0x01" : "0x01"
+ "0x01" : "0x01",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "1676",
+ "balance" : "1977",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999898324",
+ "balance" : "999999999999898023",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -44,7 +47,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016103e8f15060a060020a608051066000556000543214600155",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016103e8f160025560a060020a608051066000556000543214600155",
"nonce" : "0",
"storage" : {
}
@@ -76,6 +79,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000001" : {
@@ -87,20 +92,21 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x6020608060806000600060016103e8f15060a060020a60805106600055",
+ "code" : "0x6020608060806000600060016103e8f160025560a060020a60805106600055",
"nonce" : "0",
"storage" : {
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "1140",
+ "balance" : "1441",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999898860",
+ "balance" : "999999999999898559",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -110,7 +116,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x6020608060806000600060016103e8f15060a060020a60805106600055",
+ "code" : "0x6020608060806000600060016103e8f160025560a060020a60805106600055",
"nonce" : "0",
"storage" : {
}
@@ -142,6 +148,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000001" : {
@@ -153,20 +161,20 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016101f3f15060a060020a608051066000556000543214600155",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016101f3f160025560a060020a608051066000556000543214600155",
"nonce" : "0",
"storage" : {
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "776",
+ "balance" : "1376",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899224",
+ "balance" : "999999999999898624",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -176,7 +184,77 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016101f3f15060a060020a608051066000556000543214600155",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016101f3f160025560a060020a608051066000556000543214600155",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "365224",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "CallEcrecover0_completeReturnValue" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "10000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0000000000000000000000000000000000000001" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20100000",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016103e8f1600255608051600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+ "0x02" : "0x01"
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1648",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898352",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20000000",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016103e8f1600255608051600055",
"nonce" : "0",
"storage" : {
}
@@ -208,6 +286,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000001" : {
@@ -219,22 +299,23 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016101f4f15060a060020a608051066000556000543214600155",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016101f4f160025560a060020a608051066000556000543214600155",
"nonce" : "0",
"storage" : {
"0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
- "0x01" : "0x01"
+ "0x01" : "0x01",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "1676",
+ "balance" : "1977",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999898324",
+ "balance" : "999999999999898023",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -244,7 +325,78 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016101f4f15060a060020a608051066000556000543214600155",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016101f4f160025560a060020a608051066000556000543214600155",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "365224",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "CallEcrecover0_overlappingInputOutput" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "10000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0000000000000000000000000000000000000001" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20100000",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020604060806000600060016103e8f160025560a060020a604051066000556000543214600155",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+ "0x01" : "0x01",
+ "0x02" : "0x01"
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1976",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898024",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20000000",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020604060806000600060016103e8f160025560a060020a604051066000556000543214600155",
"nonce" : "0",
"storage" : {
}
@@ -276,6 +428,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000001" : {
@@ -287,20 +441,21 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c60005260016020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016103e8f15060a060020a608051066000556000543214600155",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c60005260016020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016103e8f160025560a060020a608051066000556000543214600155",
"nonce" : "0",
"storage" : {
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "1276",
+ "balance" : "1577",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999898724",
+ "balance" : "999999999999898423",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -310,7 +465,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c60005260016020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016103e8f15060a060020a608051066000556000543214600155",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c60005260016020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496060526020608060806000600060016103e8f160025560a060020a608051066000556000543214600155",
"nonce" : "0",
"storage" : {
}
@@ -342,6 +497,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000001" : {
@@ -353,21 +510,21 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6021527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496041526020606160616000600060016103e8f15060a060020a606151066000556000543214600155",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6021527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496041526020606160616000600060016103e8f160025560a060020a606151066000556000543214600155",
"nonce" : "0",
"storage" : {
- "0x" : "0xe5266519f86dbf1bac6021c6ba9711b43ac8561c"
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "1476",
+ "balance" : "1577",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999898524",
+ "balance" : "999999999999898423",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -377,7 +534,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6021527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496041526020606160616000600060016103e8f15060a060020a606151066000556000543214600155",
+ "code" : "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6021527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c45496041526020606160616000600060016103e8f160025560a060020a606151066000556000543214600155",
"nonce" : "0",
"storage" : {
}
@@ -409,6 +566,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000001" : {
@@ -420,21 +579,22 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7f2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9600052601b6020527f6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a6040527f37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d46060526020608060806000600060016103e8f15060a060020a608051066000556000543214600155",
+ "code" : "0x7f2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9600052601b6020527f6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a6040527f37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d46060526020608060806000600060016103e8f160025560a060020a608051066000556000543214600155",
"nonce" : "0",
"storage" : {
- "0x" : "0xe4319f4b631c6d0fcfc84045dbcb676865fe5e13"
+ "0x" : "0xe4319f4b631c6d0fcfc84045dbcb676865fe5e13",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "1476",
+ "balance" : "1777",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999898524",
+ "balance" : "999999999999898223",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -444,7 +604,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7f2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9600052601b6020527f6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a6040527f37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d46060526020608060806000600060016103e8f15060a060020a608051066000556000543214600155",
+ "code" : "0x7f2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9600052601b6020527f6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a6040527f37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d46060526020608060806000600060016103e8f160025560a060020a608051066000556000543214600155",
"nonce" : "0",
"storage" : {
}
@@ -476,6 +636,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000003" : {
@@ -543,6 +705,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000003" : {
@@ -554,21 +718,22 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x6020600060006000600060036101f4f150600051600055",
+ "code" : "0x6020600060006000600060036101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
- "0x" : "0x9c1185a5c5e9fc54612808977ee8f548b2258d31"
+ "0x" : "0x9c1185a5c5e9fc54612808977ee8f548b2258d31",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "932",
+ "balance" : "1182",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899068",
+ "balance" : "999999999999898818",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -578,7 +743,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x6020600060006000600060036101f4f150600051600055",
+ "code" : "0x6020600060006000600060036101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -610,6 +775,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000003" : {
@@ -621,21 +788,22 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x64f34578907f6005526020600060256000600060036101f4f150600051600055",
+ "code" : "0x64f34578907f6005526020600060256000600060036101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
- "0x" : "0xdbc100f916bfbc53535573d98cf0cbb3a5b36124"
+ "0x" : "0xdbc100f916bfbc53535573d98cf0cbb3a5b36124",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "936",
+ "balance" : "1286",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899064",
+ "balance" : "999999999999898714",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -645,7 +813,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x64f34578907f6005526020600060256000600060036101f4f150600051600055",
+ "code" : "0x64f34578907f6005526020600060256000600060036101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -677,6 +845,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000003" : {
@@ -688,21 +858,22 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x64f34578907f6000526020600060256000600060036101f4f150600051600055",
+ "code" : "0x64f34578907f6000526020600060256000600060036101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
- "0x" : "0x316750573f9be26bc17727b47cacedbd0ab3e6ca"
+ "0x" : "0x316750573f9be26bc17727b47cacedbd0ab3e6ca",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "936",
+ "balance" : "1286",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899064",
+ "balance" : "999999999999898714",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -712,7 +883,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x64f34578907f6000526020600060256000600060036101f4f150600051600055",
+ "code" : "0x64f34578907f6000526020600060256000600060036101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -744,6 +915,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000003" : {
@@ -755,21 +928,22 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060036064f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060036064f1600255600051600055",
"nonce" : "0",
"storage" : {
- "0x" : "0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3"
+ "0x" : "0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "935",
+ "balance" : "1235",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899065",
+ "balance" : "999999999999898765",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -779,7 +953,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060036064f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060036064f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -811,6 +985,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000003" : {
@@ -822,21 +998,21 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060036063f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060036063f1600255600051600055",
"nonce" : "0",
"storage" : {
"0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "835",
+ "balance" : "1034",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899165",
+ "balance" : "999999999999898966",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -846,7 +1022,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060036063f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060036063f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -878,6 +1054,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000003" : {
@@ -889,21 +1067,21 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000620f42406000600060036101f4f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000620f42406000600060036101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
- "0x" : "0x953450193f7389363135b31dc0f371f22f3947db"
+ "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "32184",
+ "balance" : "32684",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999867816",
+ "balance" : "999999999999867316",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -913,7 +1091,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000620f42406000600060036101f4f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000620f42406000600060036101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -945,6 +1123,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000002" : {
@@ -1012,6 +1192,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000002" : {
@@ -1023,21 +1205,92 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x6020600060006000600060026101f4f150600051600055",
+ "code" : "0x6020600060006000600060026101f4f1600255600051600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "0x02" : "0x01"
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "1182",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999898818",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20000000",
+ "code" : "0x6020600060006000600060026101f4f1600255600051600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "365224",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "CallSha256_1_nonzeroValue" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "10000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0000000000000000000000000000000000000002" : {
+ "balance" : "19",
+ "code" : "0x",
"nonce" : "0",
"storage" : {
- "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20099981",
+ "code" : "0x6020600060006000601360026101f4f1600255600051600055",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "932",
+ "balance" : "1182",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899068",
+ "balance" : "999999999999898818",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -1047,7 +1300,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x6020600060006000600060026101f4f150600051600055",
+ "code" : "0x6020600060006000601360026101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -1079,6 +1332,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000002" : {
@@ -1090,21 +1345,22 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x64f34578907f6005526020600060256000600060026101f4f150600051600055",
+ "code" : "0x64f34578907f6005526020600060256000600060026101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
- "0x" : "0xcb39b3bde22925b2f931111130c774761d8895e0e08437c9b396c1e97d10f34d"
+ "0x" : "0xcb39b3bde22925b2f931111130c774761d8895e0e08437c9b396c1e97d10f34d",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "936",
+ "balance" : "1286",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899064",
+ "balance" : "999999999999898714",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -1114,7 +1370,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x64f34578907f6005526020600060256000600060026101f4f150600051600055",
+ "code" : "0x64f34578907f6005526020600060256000600060026101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -1146,6 +1402,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000002" : {
@@ -1157,21 +1415,22 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x64f34578907f6000526020600060256000600060026101f4f150600051600055",
+ "code" : "0x64f34578907f6000526020600060256000600060026101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
- "0x" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35"
+ "0x" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "936",
+ "balance" : "1286",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899064",
+ "balance" : "999999999999898714",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -1181,7 +1440,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x64f34578907f6000526020600060256000600060026101f4f150600051600055",
+ "code" : "0x64f34578907f6000526020600060256000600060026101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -1213,6 +1472,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000002" : {
@@ -1224,21 +1485,22 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060026064f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060026064f1600255600051600055",
"nonce" : "0",
"storage" : {
- "0x" : "0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051"
+ "0x" : "0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051",
+ "0x02" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "935",
+ "balance" : "1235",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899065",
+ "balance" : "999999999999898765",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -1248,7 +1510,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060026064f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060026064f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -1280,6 +1542,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000002" : {
@@ -1291,21 +1555,21 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060026063f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060026063f1600255600051600055",
"nonce" : "0",
"storage" : {
"0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "835",
+ "balance" : "1034",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899165",
+ "balance" : "999999999999898966",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -1315,7 +1579,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060026063f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526020600060206000600060026063f1600255600051600055",
"nonce" : "0",
"storage" : {
}
@@ -1347,6 +1611,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000002" : {
@@ -1358,21 +1624,21 @@
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20100000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000620f42406000600060026101f4f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000620f42406000600060026101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
- "0x" : "0x739d5000bbe364e92a2fe28d62c17a6dfd4f32105420c30b97ec0180300a2dae"
+ "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "32184",
+ "balance" : "32684",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999867816",
+ "balance" : "999999999999867316",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -1382,7 +1648,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000620f42406000600060026101f4f150600051600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000620f42406000600060026101f4f1600255600051600055",
"nonce" : "0",
"storage" : {
}
diff --git a/tests/files/StateTests/stRecursiveCreate.json b/tests/files/StateTests/stRecursiveCreate.json
new file mode 100644
index 000000000..983431484
--- /dev/null
+++ b/tests/files/StateTests/stRecursiveCreate.json
@@ -0,0 +1,7231 @@
+{
+ "recursiveCreate" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "10000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0007318879928543f66b36e58900a870dfa83312" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "001864a1fbee8126e530b9242353d9cb76b043f9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "002b88d7e31f20b1cec3ae31ef8ae3f017820cf7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "00ae33b99c24c45ce086aa9a1844fe8ed55ec312" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "00c3d96a0eaddf7975da5c8718c26d65de0de59b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "00eb1775a16c0965c299f06a0873e11825f915e3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "00eb67f5e410e28c16861fea7a2ecc1e0011a75f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0116be8937cb591d6db17246c91dc3deb1fd0e1e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "012255fe8647bfe207603a62536ac6ae7a230ca9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "014337758eb4abf60a8e458a97acbd8b47fa0c31" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "01619145d576c5b3130eeed16f29501f2773c958" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "016cfb16ce1ab4c15eab782e1ac3b0d7f5bb264b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0177fee01c15eede3b794e761753c1f6d108b7f3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "018b456893203c6e3a5661e7328b5a858904cdc1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0199dd91369b5ce0467b68d57beaf1d96fdc769a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "01b26e834122a942828698305a84789ec47c0454" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "02391d38c9b4f03e9225ae5b28230284fa397a09" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "029f9045d1904fe6076c4dbe77bd33290f390714" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "02c577c9c1b247c0ea60b1dd50fa895c086e2f2a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "02c7efe87a470a521338ba476a0eaf7a535c9c56" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "02fa5c7476f2d423f27ac8afa1e357db95f920fd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "02fee10ca6c1ed23e651f29c97a310b1b4dad13f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "033b61ab81ffc5adce16d365458629d9f3482129" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "03b685fb90981f103fde64c3bbb5fd701c84dd0d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "03f3095f9e46a8ac62005c42aaccbc0fcdc3aa32" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "04110d816c380812a427968ece99b1c963dfbce6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "04308fa2e7af944dd7008a7edbe5221a52e2bc87" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0441738f9f0a045afd77a72ef8398475c1111471" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0462dd089e0519c581654520d17763635011fdff" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0473710fb4277459429e0c4a862ad3e4b45692e4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "04929feafa156581a24d8a0bfe8154ffab39fb37" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "04a104904b31f401966da211ef40874d6e97ae46" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0581dee4d5420c2f6b1614ca62a4d66bcf383d0e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "059ec3d5a255df8a5b592659ea5fdd963e9bd0c2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "05e29ccc32df8edacbc5bd6fe19fb4ca02928969" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0602479ffb0636a1ce0fb57bf7949cc978250d2a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "060e7bcadd084fcf19db5cc1ea769550bd8f7508" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "065c627bc67fca3636da49c34994b6efb2adaad0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "06c4341ea63b3431260716e2162ba90abd9628c3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0723789d0c7093f6e97c3fdeb1324a75427ca6e8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "076ad7e168093f590a74f6fdce56b492a23baa2b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0801871b468dfdcc2d3bc0c0d01cb6ee02afe581" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0802fc1dc1a5dec7fcbf1d50f3d8a944099ad72e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "080e2ae63ad3891bfba9ec5200f4ba383209ecde" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0891a47ead61f684dc876e12d5261ab614d0fa09" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "08d19f247ca974ee89d4f988cac4becf7a177723" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "08f86cd9e45cd0f821b6088ce2f1b3c0f70dba07" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20100000",
+ "code" : "0x60206000600039602060006000f0",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "098de34931d0d159e2631aee55524c217624d095" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "09957f64c3396f36daa03c68fa6c997eb7903df1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "09986b78d02ae7c8eaa8b62053a3ee78deba79ab" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0a1960fde1fc2010660dc9cdc299facac4502363" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0a517d755cebbf66312b30fff713666a9cb917e0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0a9015286f76ca4fbcc33e74e9c414be9774a67c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0b4b7f08623d9b3d6514baf529399e4f1c0ad944" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0b98f3276e76e9982d7f6996878ea5196fda62f1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0ba7f30a90b699e3f906bff7599b230890bbd56b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0bec2514a2a40586ec75e27442352d1dd2bce537" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0c0cd995ac9e488544723e3e8e90a5fed98a6958" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0c1e13b0604290abd900eba3fb6b7560b3401f58" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0d11b1966fa90191f6927943c476d36fa3a31556" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0d1e5ab3b0c2d1ad5a562c123b7f01f4145074ce" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0e0905211a442bb5838d2d6860f4f21e6b9c6593" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0e639c40606e9329259d2f945f59dbcc6c5c5cfe" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0e700a2aba22bd639abf05addbb24c53c3f0f3cb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0e8dab5716375707d97656230beb5f1445e56309" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0eca69ecf3068082cff932c044fe39142ab6268b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0f065de4c5c4a842f52a30fdf7b0162594df70a3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0f0f333b14cae00e0f74e1de336437d5644ae336" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0f2fc64833681664e54ca74ea756c7233a05dd85" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "0f8f271215cf51a0646c8a60ed626515b3ddb739" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1039c22c55420b0d7e65e6e6e65798f3f4c1e725" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "104f577c92f14f3684c13eb179b9969c05115604" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1057c6ef671b124fc14b5641c167c6e6756d8cb8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1121c3fb4f490140339dabac59a62dd59a9912de" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "11895349d40ea4683803f8eb7ad1d2355ff906d8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "11fde66f162bbb0e19d68f0c774c997d0165fa56" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1209046d7bf46e81d8202422e630719c906653da" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "120e38f3899a4e2f9f848a82c7afee288d14e7a4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1236efbead5ada892f61e7e4e59faa143e3bc01a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "128aabc28c928691ad3415e3c57010c40694cd6e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "12eed250610e4d59e841381dc46deaea3d9305b1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "130d08c2381d23796ff403d8f1fbaf204d90e3b8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "134c36c64db09ad23fde5b43a3a7a92d84dd5300" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "13911c90a6ddef5182a772116c1d9e98f27fb1af" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "141182812579a73e13dd878d8a94bb628143b097" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1456fa2cf6376b40069504e491e64aa40484fe3f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1480213270423eae9d6b0a603541e989998453d1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "149d393bffe9be2336e7ffd6a109f05318dc798c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "14a76e43bc292a0e69bace56681c4eb50d8e52d7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "15146e7f5a3d2db1c655ba9d8eaea6c62ca34496" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1555dfd05f003c056dc219415443be1a502fdee1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "157f8c66dd3cae32485b2d68a51c1dd7923bf91e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1588c83de3fa7b22bf6aa67a4e91f303b490cbb8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1591af76c716952018e52e54c716e8b2226d494b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "15c4f7ebfc781a41226d61bdc0fcdc98fdd8bf45" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "15e75e648b604b0b8028f7955647eac6bc850088" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "161f83bac94d326e2a8debba84379ab72a14c6d6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1622e5aa3015448c3a7560b15a289d9aacc5370e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1660ada72b0a07040df8d063f2f3f3fee891f1d0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "16c5f61453cff59c6b7e2a690cd902b72208427f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "16cab73035afa73268745a3c2937b551813c4960" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "16f5ee37c60dfd70f8281ac16cda47d665ef8789" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1756aed6799c904988cc7a1dfabe77fcca058655" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "17c7a85a071c3dee708baeaf56c208752c362e56" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "18500d6a8e3e20ace9aeb507c213b6261b23f5d3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1872142d84f7023b181766b790a4487f4012527c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "18731575d0a6339f6317c2a1b628d8a4c145328e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "187749fd89567f9519f0d50b4a19ad2600440e3a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "187dea0407359c9579adbdf1ba9fad4a92fb358b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "188921ab89b5b8bcbe443676626e6012a1ed7dfb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1889f5317912e414fda653c710d2c17b7d5651e2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "18934934c2f7d8b6b645fcc90460a966df3a716f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "18e0cdfc5a23465cfb3566091849c044d2210b55" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1963ac8fc10167891e91b4d3f53e09e0b7c9b55d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1a6bbe5380998bea238848b7a5927fa87e7b9fe1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1ab2ec9fb4e5d9d8cd15a1ad495ff314b97869c6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1ac3dd6a958d88e45c2c55d938dba74fa892084e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1b6ec3b2772285abeba8f53839fd96de995c4bd1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1b8a6f09f8fc9743b59ddbb2f105034e32262552" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1bce33a58c2741f74daab60067f759e9fc5f8c40" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1c2749b3a6c574b21622761bef7274261597ef2e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1c32901c93008d3e09928bdf3385f32ecff9500e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1c6c53405b0eb8800a527cc5990fe3b259b50a4a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1c827d36ec915dae96fdc0b164fb7bc1be9467b6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1cd063768378c77cbcb93dab0ba4c345d76bb0fe" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1cd52bab323ca2180a747d3c8b8405397003feb9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1d3289a828d2bb4a86cda52b7772e2d0d508bac9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1e1505a86f6b0fb5f7a4500cca953462cde929e4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1ea264b74c8f6e50586097e2e7c9a39419fd88de" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1ec05c9f7c0ececff5088a06157f47f3e9dac9c0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1ec26f14651cc567ce691ce83ef09eced6b12a6e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1f01dbf8bd02bed14cc0a21831e044faa3f66fca" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1f1960aa296fd1f00ff131357138001afcd858a9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1f323b00b7be1e9c0713b080cadc05f45e5e7ec3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1f5cdfaf598bd8002997b576e9ba849636c8431f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1f95c6da6a9e0abe74900ec00388094d32d98a42" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1fce5879444d729719c03b5af6e074b87a49d933" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "1fdfe5402a88f71bfbaf9c65f6df05b8eb6232c1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "202474905af37a5074cfbc2d2dd0f2f205a099ab" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2040d98a367ea817f76fcf8574d4df51234eb492" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "208d07e7177b2e975c6b6d0eb3c5566900b87dfc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2099c5bdda1d98ce3b99988d768fa9f812a21f24" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "21115fe08f7ec434d4ec27e8dcfdf31a6e50aa09" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "21190aebff29feb773919d8572f8cc825bbf7144" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "21368af8397276e6e4b284fe36f525dd323bd3da" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "22230d8d10e81e01450aa68bdfbee3c20d969de9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "22affea985c1a1ab7007a55e77e80c54111708be" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "22df73cba33d8fd14fc985fccded670de4041f25" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "22f2f312befc07db595b5d9fcbc4caa7ee8df51c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "23138c70217200a44c58dceaa4f5ab06470213a4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "241b46962af48709f1a19739ffdc7bd3f0d2c7ad" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "24248d1242acc87dc331e87f3142951a977a3d2c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "24ce22b6a7f4227e1e3a6c03c14d07acdb2ec553" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "24cea63a6f0ede9a0fa91907e841ba4174e1cd0c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "24dd378f51adc67a50e339e8031fe9bd4aafab36" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "253a31b068a402910eb30758704b78c375ea349a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2559cea11e9d8fd293253a8ffada7558c9c4db86" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "25c0d5ce71eec198760c001497350ad83df55ea8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "25f81565c6ac2e22d7e320168222450c2cdf4f6d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2600b9122847ee06e201ff6a734fdcfa74b2be73" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2652f49b5ad98503231b3befe7587c231be8a5e8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "269f24e1ae86f63876b0504b7b26e20483fa95f8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "26be5205dce0ce433dca3602886578160e6d52c1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "277c19a0f1e4f5e4339de4d0223fa254a6c8a5df" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "27b3a0698a207d5ed960cf71b1ee9fc54c229eb4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "28313061667479bb25119ca3090cd25c4a99a20f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "284452c049bb65ec77ed7502b19abf699127c21d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "28cd47ab2e86fe040740206eb31fe193df7cbab4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "28ce21f7f28c8a546bca1697ada45cd73473465d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "291cfb4b02976ffde7f1f269a3e7d30940367e55" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "293f982d000532a7861ab122bdc4bbfd26bf9030" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "295882ddd91b2f92c43bad0a51fd0ef7af61e729" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "29799a64a736832cda536d687dd443ef3bc31e57" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "298b8bde7997684bfe4434cf6d24d50ddabb69b2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "299528bfdcf20ff8e19a7a3fbbdfe98eddc2604c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "299f80e93d68725830c27cb084265d0e634e4f77" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "29f147c366199719adcb2ed1d528c4f34c10dc03" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2abef5958c8b283eaeec4557844ff1fe194e6cd3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "465224",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2b5fbc2f7e76f6281861cb4282effb94d609844d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2bab1d9132d47e56f937ef50987cc52c9adddf0b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2bb175c167599417f2192d9f926a5c648d17de8f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2c4a413bc345da77b2d07a17313b6d89aef2c2c1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2c748f96ae0e6e9b01395e8a73dfc351c46658be" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2ccccc0744051db25927d850055234117778c1fd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2cd26944d7baa6d92eee478960d5778375862e85" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2cf5732f017b0cf1b1f13a1478e10239716bf6b5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2d142ccaa1337198d592bc36ce7c5447da73f906" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2d960addf6048f155cfaac4ad513f46429bb58f1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2db5e35091789102bd0019b4ee49bcae42524428" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2dbc14a87a2b5a8b780e460dbe0083d8260326f4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2e070631694c093a9a329ec0b4a1cfa57e20ab77" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2e574f7a4c8f0e80964604262ef68b3168fd31ef" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2e83c90e7fa359705ed2138854a83a9145c27a8e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2ea29d9016f2b1141475e4c3c62e031c0a908a07" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2eabf4237f49d4cd44ec256436b99ba41828d36c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2ed524088290909f92ade6d5f9d9c24071c26662" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2f171d1f2cf19f4a458b7dc4db89fa7cd818dda0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "2f8ac479ce5baade6a63ecadf9599bfb0ecdecde" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "305773e25e157761c9d55cb7d9e24fc1b953a8b9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "30b37f280d6735ee04239de0963b071f83c13a27" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "30c5bc3861dfc5a70325aca029ab5dcb2d72928f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "30f51302b4630ea1b8bdcac380bd97d78c8f60d3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "310782e2f6d97ef0abd4a4ccb75b401a7d348be6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "311f9efa9544b1c8a8277c52e0f1ca47daec8c00" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "312f80de0869a8fed49c8ba843484411c47dd13e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3174a074366bc04bfb7f2a728a725cb01cd575d3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "317f31be5e04361b11b97ff2d6fc682030d8cd8d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "317fda8ec45232a8259546a4ca8ebef16338d47b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "31a87a9e67b2728c14767de26753f205b793c5ac" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "31c640b92c21a1f1465c91070b4b3b4d6854195f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "31e7dce7c8469a6dc612dd8c0a1242846d31c069" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3229e332af8eaf358f44aad3a902a6c47f96983e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "32a48ace80773ad092de1d9bcaa00787353b5fad" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "32de9810bbf442f9209f994556bc9a7f7e6da500" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "32f9418411245a8bc6982ff71436ed2de87e3d96" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "331a1cbbb58594c3636c0e54de517c4a6cedc27b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "33207da78e5ef3dde6fceab85bee1b5bf717e139" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "333872ba7e8ce9c43e158b12a3d038d06672db7e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "33b82c3871bc89d9137c62af099a0c4e5911a047" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "33c85ce982d0996ff7313c1387ab93348a6777d7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3432c3f9f90cb61e79f39d310bdc6cb8dcb3a49a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "34c972120d50fbdbb38ba536e4d61bc8f995d19d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "352e4ddc3153285117254b1cc378d297b7a057b5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3539fe0192009fe1a9d35901b0ba951a59348a97" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "36630619f71ccd89ea6fba8b13099d1483187b17" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3671a99d2a485b30fafa2a65f405b6b03ed32ea9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "36a9d95fe0c701c65370560445c6a80b4e13c8d9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "37609ce3799a1b75ea6090da3d014d59e5e7851c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "379ef6dde2bc54ced45146d4907639ee7cf1c8eb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "37f998764813b136ddf5a754f34063fd03065e36" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "37fa399a749c121f8a15ce77e3d9f9bec8020d7a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3820c20f3f8ee1b164dab460b05a979640a41369" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "38450559e7ed9b72c80aa00855b942f9bac1b281" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "38479ce52243f1a8b358515a084fb41533a723fd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3867a470ae1d99ccc7af287ed95ea4da4fd49e52" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "387b1112283308ce33f63062a7531e6fe0f3af16" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "38813e8d77b07f357888ea1a7805ebf52c59189b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "38ae3c2e0c1fa2eaec3648a2829fa362b5e01351" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "38c622aecb7e84ad4fcfc327ae9a1a17e2dbc36e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "38fe3b47fed5fa6d060bde66598bf5a773b831eb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3917f5ac4614ab7d126adf2f5b1d578f2b91c370" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "39457953215cb93e68bc5b351d63a8b7fd16031e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "39d9b351db53d59af4907116d594ebba910474f2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "39ea196ad4678ac786f9ff4ba12edbb364cd1baf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "39ed2d94ee4aae100b111c773d4f3b78bd4e9291" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3a9d3ead70f9c3cdf9a64b25b5c1bf765fe09fec" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3b7465c98051ca273d8909857047d5dc5b022af7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3b7d7653d3a7c2712d08bd29668163cb775c74a9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3bfd62743dab66288fe0b993d893a41d2dc3fbba" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3c4a4ef39f21e45a8f56e5c8bf8bacfaba78a777" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3c7c94fe8e900964a9885a19e09a4ab80213c5c3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3d082c9477c05d23447d1682257a9d0ac1f948be" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3d64e9c7cee7c3d41cfbeed851fff8642bd0200b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3d7b61ce014d1cb84465f1f908a6a940fd991b39" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3da1b91d461c3220510e60c0c5b87be635068740" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3dd6e0baadd05402f490e3030ef1970d884a1caf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3debce965330c2da68edb1cdd3ac380d5ce67b10" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3dff39a90e67e86536dcc8b4dbfac04da831e0b5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3e0506e272fb9d9369627282cd76a40e4046ee84" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3e1b0d3f5819f63c9621ba4d4af623a7b89b99ae" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3e3069deb6f503bb8bf155eb2f89801140831f5b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3e85699a24243e147ec809e30761d92c0d21392a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3edca986feba79717853d9b91595ae61d953736e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3ef5e42a0012b430169dae579f8dac0f6ef5dc38" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3f5bf6c71c4fae1a91c1cca72b539dd83762a716" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3f8bd9d9410af417dcc6969b64096380e1a6d0b3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3fabe5e3c3a59fd322cb638dc5295d1e94cbcea3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "3fde19fb418799c0e1744b322314c17a863a0c9c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "401f65fb53496c7746dc6477f6f9d67246965d51" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "40652c9cf91678111a21c62d7206ffbca3d47c9b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "40e0cce7d94ab21453c5576f30a598cf9fa80e1a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "411456908355aa037314aa920e8afef3632503fa" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "41493b8488a0ae34cade12733e8df93a87f3ec7f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "41eeae22551bd18167a31036b363bdcec89a7d9c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "42bbb8e2c7347e29f3a679e4cc9d1ca75319fbd3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "42ea619ae1a90979837ad2137458d991ea0613be" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "42f56890357c304762f1c57171cef30f044ea09b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "42f8c6079f5658fc8dc5629b63684f278acb7648" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "43b0edac3c2c58f16fa2380089d841c420a14236" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "43ec9b975f37266d0ff7f044581db559fb9376c4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "444e8af4b323407d02a7f96c209b712a65c6aba9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "44b329f4eb8ebaa00d731472964de821f8e53a26" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "44d13c51fb706efb7394346b00debea9ea46e9f3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "44ed3a04032bf3585faf1dfedb9806eeb8345809" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "44f344790e299b22484749266ea59bbcd58e4b0e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4582048e819b7d55b3c6f47e46ef8dd8fdd12038" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "45eb1861d0701efb338468964c2495db8e7e3411" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "462cf0e5071404ef569338a6f0a5b113d64a11a2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "46aa4a5c336dbecbabd4cdfef3b9fa65a8a12a15" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "479544e8b67a7e82120d3c5d7869b4c55f4a0de3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "483940025f2d36cb32e93ed80caa41f15487ee7f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "48e958f074c27f1d190e69ef8c01f86931b278f9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "49a01a2696857efac9ba53c2705ea4ffdeb30419" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "49fc4b5136601d856188898008375b9c1bf5897e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4a0ec2620d55cefe3e80960f83ebc81219ebabcb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4a1edf2110e4ff29c69b835bdd375ac88525dde6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4a466c64765157e1a9dee46e1a26d95ac2664c4f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4a635e63aadc395c1801c73640f256250d209b25" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4aebaa9fbdb040e8037e78fc37785f33dc3cafec" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4af174d239e86ee19d40026eae04486804602061" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4b2c0c38418eb142d686d124ac5fcb363b061fd7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4b414d48f3871bc957751d5895c96f090b509bbb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4b6dcb9105adc3ccc34c6c180e9e2212c1789975" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4b8558347f669cd9b50f70cb501cdbf05f93b575" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4bb5fc5d686cfb132c177aee8ef426e5de98cc6b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4bdd7615ee906a0c88233acc5816b4fdb4656dfa" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4c0cfb86a402c70e6b110a1237d10c7fc7fe9cd5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4cada4d5773385e68f4ff1efd1a23d75dbf1e61c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4cd33b31663c159fbd73cbb32f616eb46f7b18a2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4d47d935a3a4a4618c67f337a0075d26d9c1f852" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4d4ad735b52df9e88fbebebac2de1ede991f9994" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4d7a1e5009218cf5176a313f6922c3ab01d4970d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4d92228ffbe5ea89389a34a7086e4420d61eb70b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4dbe6269722a6063d594dfb65eba1f2a10488963" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4e36ffe7590f8dd7fa9c4c03cba3120674814abc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4e4ad0ada6b3beffa2436bef1f6a8054f4476be8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4e5cd86dc5f716ebbdf6ef572a369c227986bde4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4e76fc5e619a4200846eecdd5545b39499debb10" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4e86f346747b828937501ebfda05b2b8fa16f87a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4ebc77b7203cce293550d92b2b5587621cf53219" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4ec27065c52d294799b93700dcee6e32778f1b18" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4ec674e8eb6b890cbb7df926def8fbbb2a6bba70" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4f14a61b9f2f99e50b719f1345e76339f7618202" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4f36659fa632310b6ec438dea4085b522a2dd077" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4f5af8eccb582ad30e2702d07577479599461c54" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4f5c55986b93d742d196235aa7329df2c8ae5562" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4f86da4fecade6017d7f15e30d8320446306870a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4fc34bdd654289653ffc904f86ab2f17bad8431d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "4fe8f4ad85487cfe365ca212848f7c970c21e135" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5038bd4d6b5b31100c52c85ae3294d525596836c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "504ba70fca5091ea426c964ac631082e4ad51672" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "50aada85d21c462d9c2803fd3c22beacc61f496b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "50dc3dab5836e25872ec87bb2bb30ab57a35fb0c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "511b33319d0f7df487e07c4f5d149b27cecace46" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5154569b5138f7c1b77d4434860a92ff5707e047" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "51a578dc2949f3881535733a5b1a7b5bd308215f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "51cc4a0bffdbdd8313ed94ebfd5524e8200f4876" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "51fd18c9ab9bbb67c27373e8ad754e253e09dbdd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5216a59dcffc6105f9b58a0b397baad604c0dfb6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "52b774b5fab1f557024bd4a7cbec4cd014b81557" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "52b90967c04ab8adba7c6908b04eabf2c00bcf82" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "52f1ef4cc038ef92d0c1f9e7afd3dd3cd0c25b38" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "52ff6062b4e65231065d5579f870b7f1472a5853" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "533069310b9741214f30aeec58be9d19f40161fe" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "533a4a1adbae2d561beb729c53e46251ab3a407c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "534d2d9ab80a99d598de600ac2843f751e8bef3a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "54819bf1efa86437d2f38b4211bdd5229247d9b5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "54a1706bea8f61e354b5296afa5a9f488f88ba0d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "54d1de66a65ecf30d79037a8c8af99c633113516" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "55010017736ad7e8e14327cf0230ba4c6bab0450" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5503d35e96e76e02db22c51fd7fd3d5c0667c885" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "552e158ca0fbd97f7b3c6208ad3f956a67c8df78" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5555d9bb89b76deec0c8c0cf37dcbf4b9e3449d1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "558fb0163d7794abf1b241aa4728390028291ce7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "559bf1337f14e89aee38a9859ec9bf8035e8f6c1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "560d5f4c8933c5ca0c2c1b4f3e8b22958c9d7cda" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "569e42b9cd8d79ee5c5ea9c68ba948b7b4d8d84e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "56cb9d29e9be519d3fc1cd21fcae7750aaa8b845" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "570dce0f67e367a085e51a47d6c93891a82d452b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "57cb48688d626a12fd4caee130b11e1b06ebaacb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "58cbb2379b1fdac0a036bf75bb598e7d4fa232bb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "59ad59b53c0d9bbdf0ee0912732baa43eacaae99" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5a18f1d5e443321d54d1dafb3e3b5b6f2899378d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5a5e4ae2fd570b079f26dd7f8b9c90456d4b11c8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5affb7ff218092cf60bc1ba4b32ea65a32cd6844" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5b1718e3af89692315a673b5c134361408069b00" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5b2ed45c5376c8359479e1b48f8c07437ec78336" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5b4615bc4b0f10948e46f967ca6e64cf91a7753f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5b71d8cc27346cf6d64e101aab9c88dfd58d26fc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5bcf5f7ba278df5a31f48a5706e69816727a6e9b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5bd96b317d4163401c9b1a2271c03b9439e73e6e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5bf1ac936d2312daf08e481d85e99151cdfdb9e1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5c0ddde0773ca1b8f9b07ecdad9f47f2705640e1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5c45b1eefac6061c7713919b34f5dcae9d5cfc7b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5c70cf636b26ffc099fba8ddd5093e95ca8e7782" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5cf45d08c0b55dd9c34cc4cb718c917333f2e9f9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5d07bd78606705bb5c62fd390123b4e45f7d74d8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5d11f35386d10cfa7121b02056d97dd932659943" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5d3292b79851f68d3907a550dc1a0b569d603f66" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5d57e28e16bcf33b37672eeb891b29c481e89120" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5de8956c0c99e2dc6715201b3a9e1d5fd53b2dd4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5e0ea0c533298d20ebcd19482a8b1e1854dda425" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5e5a0b9c4c36067c8730abecdb29ba97aed877a7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5e74c3c0f3bc39154407e9a3c55cde944d1ca04a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5e76969932c5d314142b23c555af4625fa6b9343" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5e89d5dd43fa9fa54381f234d1f7251387a0692c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5f1703b93938752face6e4657a90825b77f455da" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5f3f9c388dc0c9c01a5fd540bf9eb714a47fc5c1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5ff4d4daf0a832422c4675a77720abbfb5afbba8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "5ff4ef866c3ad4102444d020c1d21c3d35a119eb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "60a2db26238d52510209c569dca17c1f41c9a544" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "61144e43a08b3852bcd531d13f0485743bd835a3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6123d3be4335107712685be2d575958b17501067" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "61306db8b4ac256266cb379b5f686e25cc117590" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "614037f9a7be1ab2131d485845f297f2d62d569a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "615a957b818ce70fec123daafe552c482c59c5a8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6168c5e3b7d7c870e3e7eb53b152fcb920c8e1eb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "62123ac69c46a06f7e3644b0dfcfcded535b8727" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "621ada91fe8f65407ac963de8e75d88d4c388cd3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "624a9bd6345be1a95c7fb509ca4bb77d05138adb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "629fdbc407b70b57eaa1523ab12c5178e81a5d52" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "62c01474f089b07dae603491675dc5b5748f7049" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "62cde2103198f54d31cdb9e9495fd7e1243c2c27" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "62e75c838a732abab87e1846f361721f03e7d973" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "636b02091904e5b452d19455f484306b8fe62dd6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "64134c8f0ed52a13bd0a00ff9fc6db6e0832e39e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6454029b19b69bcda3ba156684d58283636dea40" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "65e3776618742b90f1d9844c907b276854869abc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "66e68e1d0f65b4379c2864f5228d98de265c5e30" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "674840a9e918ae6b7560a4ddfb60b96a32636ba4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6792d18ead88bff9193e50fa12c02779f2a0f4bd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "67a66435543da4130940ccc47e3d9d164db65fd1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "67df3bc5f86456f2bc57f75c99a0389bca7e5850" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "689a40b4f540d145f6dc4ba4079e17f84b650f9c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "68ec6ebf20b30a31b09c7a35d847da342e24a3c4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "692a1a4da0b418dd701f5133e2b3c5686015a3df" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "697f8deffc4b33738f1dc02e792b5cb4a37ead06" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "69afd0683057a214d3bb3cc7d438961cf8c8b200" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "69fd2b9233b83e54861436496ad6b9fb28afaf40" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6a22049b6339e13438521842386a7118d6a1a15b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6a31cc57646f3d9ae3b63e1f604dde04d1ba52b7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6ac56f1ceee102b85819d789e6b29308eabc373c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6ad37e86c8d4b961b0302ebf0a540ae83f3679ec" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6af2602221d2477af828ddb2c1dec8f70a24abe0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6afeffe32a56293f23d655a1d1b2bf31d616c2ea" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6b0105812868d533882ea4f08bb628e5e9d811db" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6b5ced188780878d8a72b3e6f02618db2bb97584" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6b5fe85d1513c1a29fa825a343db7a80558e6de5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6b6945d5fd5172355825871803b93e57c5040653" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6bd29846f9fdbf3efcd3c5f3beff837ecbe9f4cd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6bda06aef03a04b8eb3e4c7d1ef001fc806f5f6f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6bed38b822d8823a2cb71883522f932cdde95b0a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6c14bbac448312636b86fe713185cf7d8ea6f1be" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6c3bed6efc677ccb136c0d886a6f3fdb375798c1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6cc6da179301a7ec4290cc0a5860a42ad188399f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6cdf4bc6759fe45be60aae1cb72d3fc2bb7f2d23" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6d1f3f15f36d76d52d65b1b78a4ac85e91f33d25" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6d27b8cb6b9af8a56fca98f13033d15f10f66da4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6d33e2eaa419844043bc41073bf3a2bc0a6c1b1e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6d9834013a85a25df2e3dead1986d753457d7b67" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6e0a20c94065e338c7715046a320ff4495b4fa84" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6e24d18a80aeccbace499b6d26b655633c0bee99" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6e2da6b24262f419933bd63b03d470ba019350e3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6e53f8efbbec77187f733cb053a53a28e14ade81" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6f257471f06ece199232aaaa082d2b1ae7ddb483" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6f3dda610ec5a3722ff4ab49d1f215dd26bd8ad6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6f562b4994dff65756e316febb8d5a5b99e11420" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6fc7016fa33af287b3b9cacd092c26bd9a054569" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "6ff9622ab3c22e4357e90274d00291c527991d21" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "702433f6bfbd76274ec1bb641c4a0428298487f1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "711b5163728968ec016a924238f743fa04f2d11f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "714213a080e1d2988acadbfc5e441df5173f81ba" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7161527e54370ad8fe44bc83d692b10b9f9b877e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "71a2fa577619a37c2e2336bb6c20fc1af193860f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7213c423e1db8af095bd3cefb15e43c6067635ee" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "723bce7438e7c70d113e954e9aad5dfb4551dbff" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "72969d083705c924922b857922930f2087426ca0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "729af7294be595a0efd7d891c9e51f89c07950c7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7343c0aaebc045465ffebca00e201c1f554c2eea" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "73c85788bca3bc1fb2e9b3056c595a4a7b3d2e46" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "73f9912db6e86599f256f090dffd915a845a9631" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "751c9d6e9b6d91897ab1754b15b72712953de9be" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7528088649b574b14d14f4b5ba45285eb8a78ffc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "752e929cfb45fd739923f562b146db315b8cc4ca" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "754144c0c9b9fe7f9a8e40df23f3c315a7e244bc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7642513288c9da66960a6f3df0c156a8e1dcb119" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "769277251b9d3f0906a338f156238b159bc126dd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "76ca5805dcccf57966da8489d1720fb8c5dc4b81" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "76ea1b9309253b5c03bbd6e9fca6591b51fb3785" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7702eec59b0ee531bef08c14d0e6c89e7e43ebac" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7797a5c4bb655b5ea51bc966875abb3b19c0d105" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "77d724d278fa787544189c4774f03849be2868ef" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "77f14e248490de6b7afb327c0f013c54ae31d2a6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "77f263b8c785ec73f9f77dd11ab64fb0089cb164" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7845e6c6f5d014cabfeffe6d4d9d18c547d00fa7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "784c21d8eb231135ac99a64dd2ee334b045043ad" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "786102f7205ad86bb77b14a1b80d8b26cbf3562b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "791812110230af4583a4a6dff7eb425b0b0dfab4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "79225179187b35144fe9e8505cce2bcff3986ff9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "795d6e09eedae3febc172169c017fb67aa62efbc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "799b6226b099fc75d1fc2cf6f833bdfc1fe63e48" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "799dcaea1d20bf1428807757a84d6792798b74cf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "79cf9a7b86c0a7adb03ecb8967d70413f21b925e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "79f2d463ce2404b3e77db5dea5cc19d76ac223dc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7a315595e01d6e16134063232a01395187c9650e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7ab73fe69000d4087d0b9ceedfda0af8c4fe2d2a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7ba53872256e6762bbfdbefb1bb80b26f94df9f1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7be1a5856ef5951cf1991b57c00f73939c7030f8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7bfac062ec8fd11810639cc02f02aa8c61c6cfb8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7c26d9c9b73a75f1a468d06bd69e08f4d316845b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7c41aaac568600537f36df0e35cb625dfbed75a7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7c7d893aa4fba1deebfc9a5a14b27e2ae7f66403" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7cadcf3f4031ebc2bc85040ea16d1ad26ce1704a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7d3b079a8306f7cc89f1b9b23319ec904e3ad853" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7d4e21638e756b9953576f460037cd702d10211f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7d699e5ea61a26a7f677478cc79887e2f27ab345" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7d8dde5a13af888557ddd5b931dda20ae59e9e23" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7d8e57afa6550a1be621fb6c083aca311a1e229c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7e15566ad3e90f3c4c12c4d7fdb17e12c24da66b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7e2a31e29b84cb193202609dbd86ebaf9a83c119" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7e2bd10d506af5eaada030590c8073495230f37c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7e44d26c7ef8dc51a45248573f6a8e5a9f91a0ae" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7e9f915d9417cd7bc8220546680fa5eeb73a2192" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7ebf86bf849b6097c8af6dae10c52438538a0711" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7ee27699bf52e4db7f72b3f2591f48e8ad7972a4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7f0506a35713c6a2c68152d15a4bfb1ccaec98a8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7f16eb03b09934c61a424e6a1c4649f193d157fb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7f3d23738538a34184e3cf16506685cf0884bac5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7f57dd2b577f0d5cb1fad7bbb2cf8f07ec0f0199" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "7fe4672c6fd2a05c7a91676e5ae2e75ea197567c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8069a4fb09d35f100d18c98d02ec1bfd997bb893" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "80a784f83657ad12a742b94e01c3bbaf3fb2c6bd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8135c9c23bfa97243ea79214772816339552f835" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8142cb33b22222bb9e39a66b53af12c6ca0b5375" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "814a465f554f949e6e2a6878539c705f319c627d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "81b26e12027f5df776edd5539791e683dc2e57f0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "81d6578dc3e3c0fb07a8d62f66c1eaf3b97dc2ae" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8228837a1a7d0ae41b857d852a8dd6b7c6cb3e38" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "82afbc3f6dba388dba71ee35f56ea772a53033a8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "82d03794122107972c0d075f16754791224b507c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "833bafb51e8a34c93f3100430fffc5ba61ef95c9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "83602911153c9c176419a17276ada844bb932527" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "83802f999d793e8985b916465ccf6050195c0167" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "83abf69971313b011ee30466e8f703a460400557" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "83e3e5a16d3b696a0314b30b2534804dd5e11197" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "83ed885c9759d5524052681a5602616a4d565e87" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8405a655c77ae3ebef4410c924cba9ef22a57f42" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "844301835752f15f39550cdf531e07ccef5d133d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8507d90ee605e59469a35fdc78e844c59894e003" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "857109cf04811d5273ec3af3f3d3bb56e93d1dfb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8692f270fea1b23b492dea1755f48cdd1dd78534" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8703df2417e0d7c59d063caa9583cb10a4d20532" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "871986919b8ac4032193739eeae09c66765f0f15" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8719f47f3dd875955760868a4fb23f761cf7d4ad" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "87946e396d4fd04d02f117adf25ac427895878b3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "87b02d6f0e02d90fb05adf14ae74570ea8ca6aeb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "87b27e4b436adde9bf724b4889980331dd038d49" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "87dbe63fcbb0c90d20021f9c01a03e7d94916b3b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "88a16f4f893665cf06d9ad7a7ede8d9cdf833b7a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "891c7f214e32206e8f497fdaa7ee419e2e8f3ddd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "897003bcc0313258e7a3517771982e05e4cfce1f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "89e81283794cb458b9590002ce69ddba3c976a42" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "89f02008028773d99248943a6bcb14200f4509a0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8a05aa8ab787526a0591016c2aee95037b8a478b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8a2cab44ea3d5c52c704f060f4088e505791a57e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8b0c28ef1527a918fc7dc134ee6c00f069c7073a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8b0dfaaf9135721f01f3712572ea9963d70f49c0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8bbe1ac3ee5866589a669dd95744af5ee83e1b72" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8c25b51ae5745b82c7b489b8fd4a9994b9679a0b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8c2e2a704d809931e711b89162391f2dba837406" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8ce9124341c4ca3c690b29f3575f3cb9833c8c3c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8cfda5300d7544327e32aca175840f90860305e7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8d7912a42951e7201c8854b98a36e4203508c3a2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8de072b1fc7f48cb2a42e7ee579a462e50e4cd8c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8dffcd74e5b5923512916c6a64b502689cfa65e1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8e1320b630d8a411819c16dc0edc2cb77ed8049d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8e15b61b6735457672c8d4809e30ca7877e9fabd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8e1f5c577cd5a404507687ef379cd1e41c4a9a9e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8e4354916a56d367dd99d3eb120e27a1d8ec6e66" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8efc24fec9b67ce053a55abaaedcbbcc64e97eaf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8f55e75b453fbb3071e4454119a33477c6028788" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8f75ec2d8d77fd6a26f4c01f7b0384bd60418874" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8faf239455a012d6ef377a83448c8185466f8511" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8fb5af158980be77e5d137ab6f95000407041099" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8fb5f5dc4d66ea0233a652230d44299718cb9f9e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "8ff9fb732fc13f492704a9f47c47db4e877f6dc3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "90344e80aead27d6b007ee73dd8fd8169f870f51" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "90f8d2eba99d7e50525edae64a61a28526eef894" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9137343457792227d68316f6ac0bc3518a7702e3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "91aaa30b2bf342c6bb6a315251ffe5b7e123bfa3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "91acc7d4c4cc7affac116157a53f5614959485f9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "91c87b19dcd811fc5efc567a022bca52d5e2e252" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "925cdeaf40df0ac82648432e65481350417fd848" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "92bbf48cf4a124ffff047cad76c82db1a1889803" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "931543d59701f1a123f3850e4c6e4b0ea097ae5a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "93840036a3c19b1e91ba0ea10f95a5041ef61a3f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "939023fa69f246b709a97f16c37367e36267828c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "93a5ddc7d7b2a2bbb7a61086aa6fd0cc9e202b0d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "93beac08e1b6f1ac32c5ee628bc4356feb5e54ea" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "94602cccae39d50fdc504869eff546d1678f0ae2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "94bcc8632137dd2d666003e33d1e7c2fdd6e95e4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "94cceeb51248e76f0fa711e92986ad36208f6e93" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "954933598dcf8e04d6f4ae5b311673409e85c809" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9580d4c2c6795fcb1ec84bf6a58b873fb2737788" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "95a4d7cccb5204733874fa87285a176fe1e9e240" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "95f36953203283bc9358f396b627dc79480a8ec8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9606aeadd83c5da2a613b0e132f0a6c13cee43bf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "965025b3b611003c82c8c9b69b35b4c5444cde69" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9663275f953d54a345f3dd00e2eeb0f156710129" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "96f4278992ff6da5e8e60456279d9bc5d1f7a845" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "970e2fc1f55b1e2b214f84e155ae6a9403f891b3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "97316b1fd92c5e6611acffe79899064fd9274c8a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9747756fd264dfe7fbb2f46aebb3e9b084ccf45e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "974beeae03d1860c485c0dbb68e5413317770b16" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "97a3956189161fe3d52554c2a599bb619983be5d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "97b61770815f0589776243ec8ffa365b86548b28" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "97c99c7f158206d19196df8d21573126569d918e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "97f0981b0a6cb647dd7b11b52c92bc1a3206d2f5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "980410833d9ce53a0f944ccc629032fb0e6ae6aa" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9848ce910f5874ffb5cad5fdc3507e8d54fd668a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "985e84916da5ee358e1c119c9b12ff133da52d29" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9862b64181c8bf5bd53e51c5f596528ff82bf652" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "986e30c8512ac023f09da460202322a88e98aa66" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "987600e63a25755048e018d1976d8ec4657f359d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "98ae7604effcc8bf6accb109ebf78fb6f5dad01d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "98ae76bbf3fe4b779df55df06eb0081ac95d660f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "98b163f2929e5c92709759e3215879acf32a3a98" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "98cf6cec29c58634b6022fd1e8f54f912921eef3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9917620c3df2e3cae0f0e690b4da82221bc26efe" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9985ca2474151f5ab79a388ec3b0d6fbf42da1fa" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "99b2fcba8120bedd048fe79f5262a6690ed38c39" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "99d6d7fe1a4f0f7d92837486a1f9d7dd500edc11" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9a0ca249b7e4f00f62ba5230a602c3233895cee2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9a0fa2b2dd4993b5ac3370b4047f5e4472121674" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9a2f4d9e7fd12bd7dd8141098bd3363bb644f068" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9a45843cf7ed63ab79f7df4d2bf80512d259b0c2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9b0a69ce744a08c595426d7cfa5fe5f4dc844a25" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9beadb15fd4fe1f0755ce82dd160e1a798544a1b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9c5fc050311de43f7b7d9a66e8319ad3c051a252" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9c89251856283a8e3aed6d801ca965fdc1da4aa7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9cb15938a825ff7c17ae775b6454730983522906" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9cbb5a7f2afe219ffb9b787065cbd94ad44ebd24" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9ce1b776e1a050af28b1034980a628b7728b0831" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9cefc7e38d2a714318e5c36c3c21b226b10218e7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9cfe89d89bfe28ba95777b6a90ac7ed86b0e202f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9d0e24467eaf9b797b9e3f6a6084958889592ba8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9d9fcb724db6738e2ed07f6815a0e5d45b3042bb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9deb7e973e3567140c51750e92d7c5091174f506" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9e30a8e67c1dc0ddcbcb8c0d957101801fd250cc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9e8fe9f31e954787e0f9d01b4a7a0c8d3d320614" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9f28528f2db498c3a0e79b15b97d3b3e9357e942" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9f42a00ab7bea15357b54e16867383fdc02e7060" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9fbf90147bf6ca022818372bf38637738d553552" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "9fdd9d67e3e2c78c419e3ac9bccc7322041c3b1d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a015c57718562f3839cdabd7d4e9c86f1a321a1b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a02b80b54ccc306e042c286172ba903dd53fa4c3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a06ebfd07c3daff1115b82d67be5bf4079ef6ea1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a086d90b189bda22a2ebf3e9b7092f1782e4fe84" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a0ebd1b4fc0821dde34f102f6030fc9c40b29ab0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a1230890b4634e4461d6295fef3b4ca6d8899bd4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a1ef404093a02445fe14243e853a641c23ecaff7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a20b30a1e7723ce15f80e9706fe9c1ea05170a2f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a24089bde6e39fea0d157ab9aa4173882e62f39f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a2442dd71a4e937fd73ff383067f97ad4c83b4a1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a301df371257a12c7bc93194ec045d211a2d4359" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a30dcb9cfbd0e8c874e4f919dbe71be3545464a1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a318ee3c41da839fa1002dba1f9a140274ce59e8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a31b0038c42665206876c410caf02e67405dcfff" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a31be87c0ce167d8e9380a34c7d5004e42f37840" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a3396b3bca8473c21f9ab1fca8a40ecd580bc625" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a381c1eb58a73d7e7c8b857fcf3a1b50c6116e1b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a3a80c15cc0e13dd1aea5949c48ad5b120a8d831" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a3ad081c8f3b79ad20285e881e0e4d011efc012f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a40a11c1f943538e64466de3b3bf8c022b883094" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a4202b8b8afd5354e3e40a219bdc17f6001bf2cf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a479aac07f3b83ee401944a36812d665f54ca6f7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a4a5e07598b0d6a40fe62ca88813b63a1c02710e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a4cd6039bfcc6295533a985631a151bf2e0e8b21" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a5303b50e97dc17384209bdc3723ddc6eda7aea0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a5552ed8dae24eaed9346af3186f634d38ee9aaf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a5ddf08c7de55ca258e346fd1acb1b71cc2f8829" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a5ec829bcc187b6d19e825b5b6f12f86f81cc063" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a60724458ce6cca04016e99826fff8c99c32e3b3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a6495f085bc30ac47e89a9a700e406e26286c3f8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a65929129c13f2405697b704fb1c840987ad36f1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a65ece83e15c7320aa0ef7ff2d69c2ff61fde661" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a686b20553a38e866228ce003657a71200957c3b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a6eab9c538a79d9ffeebc5d4495fed68dccacbd5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a71525ab6694ead3c1be0aad07bac06e69192524" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a724835568fb5e3986c1e87331a18b6628b73e25" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a7547a96b2c999509ae062509a0d426fa46ade62" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a770dccb354eae253f170825000386233ebed231" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a777e559211613e73d9d0cbcdad62c88957d6f25" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a7aaf603309127956371841badc44b69252d142e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a7f111e1b259c9bbd4beba8ebab4dd6d35bb9ee3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a89361425f7403ec9e757b5d1a31993a79189a34" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999434776",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a9647f4a0a14042d91dc33c0328030a7157c93ae" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a9ed1d8a969237243d26f8728287cb3eb8730662" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "a9f73dca799231e385ce5038c826b03eff0d1145" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "aa6cffe5185732689c18f37a7f86170cb7304c2a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "aa839cff1f78242d01a33305e1d9973cd7c66d4d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "aac939ac7c11bbbfb7f4520d14442a2460a51e87" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "aae4a2e3c51c04606dcb3723456e58f3ed214f45" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "aae4f6978a8eb4a7be406a2a787d31dd49cd551e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ab118214a2227c79eab2680df0a96d0ad67dafd3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ab1b93b6a83c275972ec2a6b513c3106dda84f47" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "abf67dec2d1ec31dd111c2f1135818b6af86c662" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ac0dbbd8aa555e012e1b5fde0b4e1f20e30a057e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "acbb287ca3f98d4775dce56e40ffce57ce4ba179" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ad02a5cab29480ea5b67e354b0da540082500327" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "adecbe660a4943fb6feada38775e51259ea15af1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ae17512fd9edf51989081b42962b2fc85de4a2d8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ae5837876e23fcefa0f204d7b6433966ebb854b3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "aecb52facdff422fd67875967e9278a7b872af32" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "aeef5b5a721ea3c03ca909bf1f71c122ebcd32af" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "af3cf705624b239ce07280597a55dc8ca69dd086" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "afbd8818fe046adfa468ea58a217b83f7d5e75a0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b008af759b5359810c78d181f0743ed85c286116" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b021f73dfd1500257934aacddd707e6f67173edf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b03a2acc80fce6d54bd1db95d7ff24123ed6e106" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b0a10fa71a1c4c621345666be094909ac112ec82" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b0a9ac49b7fc9a45c9e7b358cc2e9e09dfe361d1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b0ea2ec7623a1faebead30c8007b260a4c62f99f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b0f8d2e75cd431ef9d818a2552aab19a6a99c1d3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b14b3e0660d147b2603ed92fec4ff337e3c259df" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b15c7770a476be2c77c3bd50d60ea6b2cde3186d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b1691d2608aea9d7a56083dc7dcbfacc93a4287a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b1ec052c576186de285bbd31164de3b19a844dc1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b2c10a1979ac6236e586ed704cf9dcecb034b8b7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b2da69bc3361eaf80dce81a17d610217ebbc7a17" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b2f828407f1a5fcbb1e4ec079c22d791c7fa5478" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b31b1fe90a535ed66dfaf1bf9e1062190fbe88a6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b376b876f7137844ef5e2db1e307713885ee5d33" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b39c43369a4ec5e4b2dfa8b3dbb3a12bad630b30" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b39c8c3ee619a2946cf540cbf16720a881110f83" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b3b4dcc6ba6c6d8c352684bc69a135cccb2d88fe" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b3edb875f0dc5faa556edf77a97e53c9d828d146" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b4429d6274f10ef0b7ba30837c5de603ed4c16ef" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b4481bed4acdd11d8f22f535016a762cc87845c2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b4c315d98fa6cbed10c6331e2a5e4688ed0b7f7d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b4c898e7d827a75d991aec0a837c23aa8d9041e2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b572b99fc06b16a232d74898e587398d25d7d33f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b5f4de69833ef9f1392c74a5ab905c5cd1ab2874" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b6367a493bbaed7334456b3646e4541c9e96012e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b651decbba52842e8fc86afda1168ac549dea7d6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b678cef4a4ba3f3642fa128daef4ed6d50ba1a0f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b6bcc464b7b7f0359e87e9a9517d10823a2e0c93" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b705cdd0dbc620e11fa470f9b4938c5f9f42d84e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b7650fa902a0ad81e8d48deb557323bfcf32efdd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b78428568fc511f4a6ed34c2d57c4e104138ca98" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b7b7c5f65fc11a6bee686b9363884811be247c43" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b7c425948402f9382208346ff48ef6ac4667baab" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b7fbcbcd3389df89233f8bf6bfa8acf892958a33" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b88173b953f6c1b613b6e878cfdb34899e3339ac" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b8fc89fa4eae09e1b4bbb51f4c1791e589368801" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b9261902783bf36bab49f18323a9c8e4ad86519f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b94d3b46afb9954a375e50a6fede26705800a057" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b96672ac912cc5ad6f75157401ccd9003512ffc3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b96982fae6a70aff19c2d99c3b2adc57b151d784" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "b9f7e8e7ea5b1a7f184a152373526ac7acf4477c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ba158ff71047c0322b1474461f94c0246d0dfb2e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ba3adb3b7ccccb748a65932e0254e52ce092c5b5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ba56f0f804625c0ff8b7b119bd03af0a10b5886e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ba70f98f64f041290dd6794e5cbc9e8144c8c914" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "baf332c908b38d0c5e825b41a500525fa990b0cc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bb26680f6bb423720c6437fab35913d0a86e2a78" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bb7a0556525b43c750e380a0ac1ca3bb719e601c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bbdb82e2b1ebae617370e1c27542ea087a4fa937" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bc2929a7819bb70f10676f4bc004fff40ce5a52b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bc843b0159d8f7cf6fa1bda55e3ddcf78e1617b2" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bc845b8623c7af6b07eda7a5363298989cc007db" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bccf73dc6498406a51b4183e22c4be57de5c4975" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bd4f71cc4a8facf8612158e418fa394cabef27b7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bdb0e729f9136a166efc4ddea366fc3b6bf6bf5c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bdd290243af494ef27e986a3cc432ba3f873758d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bddd1619fd3c4703733b1648b7db0ffa6dd09a19" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bea830535682332041ad318232044f5e914af083" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "becf51bad165c4b8544ecc57c7859ee946e610df" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bed1a42fdb56c7d562a773650bb2785737caca3b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bf36bc1d23eebe66f84a0f119552dc7b46fe2402" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "bf574eebdcc7ff3617200fe07c8c7154a8d129f4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c052f8b19df2c41d807bde1c041a8ba2e87f15d5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c06bd5d93ac2ecab95942d1639b700e3a2cc48b8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c071690916c15657eba376c7c6b4b06d38e815be" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c07b721215b231d9820dc8d186e3dcabc6c75e66" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c0cbd80b185007c05f50e6f2fbb03e8d6b2ed652" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c0f36c8efba9e6e4e677faab240ccf0cf3e7d03d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c101a7eb0ac863e824eea705432530c65aa0c518" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c19f48a0a131e8b9f44989bbac80a30ffe2a2e4d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c1ab531ecade623c0c908c1fbf104fb8c647a37e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c1ff6275aeeeacd2c79dc02f8cd5cdb44a81e6be" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c20cf04f10caa057314759a2908524925294efb3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c291bf92ff9bdc0e60f049e6a5b143b940658857" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c2a603dfbb0734c098e5b6b7c8a9b64bab11054e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c2afed79b83fc6b8d98802f52b1fea6648571ee7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c30727a70f64c82d0d8837f1b45b931ebf80b106" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c33582140ad3da6d7fde2c3c73d0530cbde93555" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c37a43e940dfb5baf581a0b82b351d48305fc885" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c37d1d79868b6a4c25db68301b8575ae4a8336fb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c3d826f0bcf2d353afaea99ec55eb9162438e315" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c4170be517e6c67a9e65dddb09220df58e547102" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c44e39eed84adf0c399a9d5af8d0053715d0f5f9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c489e22b54124b98b17b68e7c38676efb81c1862" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c4be49d4dcee6efd96c35ddf346b969db9981091" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c57abf0b9724f82736bee2a05a9238a45de5512a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c5a28cdc8c4b089c87ed4938ed4718253c48dd7a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c5c5d6ad672b24a2ddedbd2418c4c131c212cb0f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c608a6fa0f9f3a6af68270740ed6c998e145eede" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c694bd4edd4e806b9c7d4ad742a3be423391470b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c71253e1b049c2b5acba1893c74007a26797e111" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c71abd039da56d4c1d783ed06a48adf0808e9cef" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c775193c9d81ed6ee806f6005a874b927e96ff19" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c7e31a320a9a7969a6f4c3cf98bd6d92a6119055" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c82d5a989ed7c8ffdf79ea0724b3c9ba3fb84e57" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c8732f022b6c57d291b26c830c651b3617c75b2a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c8b331eb5ad444567964f34dc24757bdd3425943" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c8c3cf855531e1d06c07245e76c5298b4fc90d8a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c8c90ba51e74ac5d9e462ffcafbb6df11795ebe5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c8ca05f5e8391cd5004c3c4020e570ed4a520c20" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c9113ae38fc632738ad4722046d8e07ba9363ca7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c95ee3b530d4b057840c2d9cb542a51e4e3a00cd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "c98b82b246d3eca7562ae19d8ca605e77cd53a3a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "caf720d275e228b58bcd8b2686714ed8819cdc2b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cb0ef5a0d3f9427d66aa2b00d4b25c2445d96cf1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cb5e208c02a68f2d97601da482c419af989e097f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cc0302264a5d0f269e26ca3ac24d7695b562b4f4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cc40f2616fb396bfc25e9b22ba3218b2b217ea3d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cc7c2f8a3070489cfca48f5fa0db9fa2d65e40e4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ccc8cd23dc6755bbb516af6ef2a04cc82a5ce5c7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ccce4f34ac3a550c95747823a00fecce349734f7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cce1e6f23dccba1aa1830b1b7714fe985f9f2032" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cd1171381ba62ff31b56a001b8144e64e365eba1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cd2910fb9ae3395ed149b28a1ce7c3cc58bc5481" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cd5fca46bbc468b84b493f7b52ff50386b174d40" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cdc1f2aa2853b37723f415aeb181583e11ae7b8f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cdcc86f0d7e95ea5b2f9f5e802015c8ff855b257" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ce20ac750c9549b466d48c90352a255f6b7c8294" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ce7600131bfe22040ad75febed54cd4ad181276d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cebebe455b6a15d2e4705ebe51fe5007afda76eb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cedbc4eaa94298536ad368e8ac9819c5e7448738" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ceee86e99b04198c09fc8ebf3e2f45253bddeed5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cf3f58bfe41401084fd1e997e8e36dfb35e363cc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cfb0d9c00c0b7ad292f221584394a3ae7d30e0ab" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "cfb86844738d5373ad23eb3185e1e9fc5d517ae6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d032f83c65a584f6e47f9fff9bc864d51a164a94" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d09a49b1cdb208e2504486267ca2418c87152962" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d0a97217cb0a4211e28a58222c1b038c44a3f211" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d10afb219e80a211c9072b18de0ff2317f67e573" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d111da05d7193bc295a4956543810071fcbe4238" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d19b2ebcfea3994bf30a7e4283b73d4bdd319cbb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d2468d6da54259507d07f74ef0a246f97e52f035" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d2571607e241ecf590ed94b12d87c94babe36db6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d25b7ae72c049f91091a4abedc4d618e5a05e1e0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d269786262f853ed769ef3ea9a7e5b98db3bfb32" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d2a0b130c0834eb0ad2717ad13233242280a6fd0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d2be9413f150b2eaf2666b42ee719fc66e5066f1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d2c8bda3e1481b96b4a3ee0a2e1f3f1aa6299feb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d2e450aa145ce97dc054b1bcf391407fbf202bd5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d3a4f3cc7113eb16572eced68ab395a40ceeda1c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d3ba8bc2aa219ba0aacc8960b92832c3b0693bac" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d3c1c3359ed1906851379272964b7d96e2977654" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d49825eca3314ad0c5918472615055010cf4a4fa" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d49daab5099319cdda477f5ba715ae685c031db7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d5144e55ee02feec18f2ff293f08b8379d1509d3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d577d44f2748e151afdb1ded254c942ca9933b0b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d65386ce109ffa3570dd27e54f32e2528fe01fc3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d7409d185224a0284e7451923e3d094ec309ef92" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d743161f0f7beed30155e171b4d577d5ce2a70d3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d758e9a701769fe9e5a80b3a09180e7631866f55" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d79995f1fbdf19beff429a94fa9dd184827c68c4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d7a36da4e6e26a99b038e34a6eb74d10d422ba9f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d7ae2e59d0776d0ba96fb4b23d1eccb3d57a14eb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d80ba0ac6edb71367c1634ae5bf72970e596a99c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d87693ae6d35928467daf90aac749654e9c57644" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d9860a22b84f982363ab9684d767a347a5c4fb74" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d99befc655ecd5df508569aaadd729af7371687e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d9d8272a3b205f71494f9009705f4f30dd31c607" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "d9dd1aa8519580888c402dd4fae66ca68b4a7b47" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "da1849a4f9df2e58d30c94732ff5f3aea19ccd8d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "da3580da73b2986fe0da9b6caebe17818b7b3645" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "da5828cee8e61bd0d8af71ef5da9a7a9019ade13" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "da7555a43e7a3790290cd20a19ec19032e28a6dd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dae44ad9bfab81783c1dd591ebe3409fa8967883" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "db06ebb361ef006c17f89ad92165185a38f6e630" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "db4ed990c69c3b67a04a96ccf079649facb9c433" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "db58d0b35d26edeb0efcb49f7eb627cf49bb3a47" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dba37eb3483100bc89a7bf11b7f110ad71ecf41c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dc19c28fa6124ee9d0688d0e2879f1269b4b7fc5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dc1baaa8621b513d62e8aeb02543ce5c7b8020c0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dc280f2887ea315f70692eb247e399b18a07bda8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dce512ecde5a4c27da464f846e71c8272da4ad80" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dceb9854f220556f595bd655bf6c023457341e4a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dd0eda6e9a3dccc3d430e5dd333c83b759cc7883" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dd8317eb76e8949315e601fa8a6959e2ffd277c1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ddb6aeb5e1bb4cdb44ca3a9b979996c529d9fa3c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dddb23bf0a55d0197810e062a5a24a1503705ae5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dddda651d375f5352d2ff488eace1de63b6ffca9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dde0b1e9b9ecc980c5614012f9afae25cb1a1c16" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ddfb1c855ea2b2f198d2b6c7dc8ea0ee16d7319a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "de63eef4b269d8572b6b00574ad8e34c471a07d6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "def94fccb1b7dfbe1cf0b3dcaa03a77cf58ae768" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "df50b2ca876e4174d276dac0c64e644cb1b5a118" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "df5767dc4d8111e8641198f637e4423c62e57e27" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dfc26965c20fea217850a28c08021f1468146101" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "dfeb403cff0aabe20cb07d8451caacfe31260132" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e026a4835edf27c2705c97f237e5b59b7b5da1f7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e059d3aac9a568120467ddbba3e4d25bbc82dc64" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e089f14df5e00aff3b03cac5e1236f5cf5832d5f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e0a1885b4057f65dc75636f4fb0e4b57da82429c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e0b3647d7252d53d397fa6af6d9da4749f4caadf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e0e5744863b26418baf12f94f0bdad2ef2546a92" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e0e8eb511c8a93cbc42dec4e3c0b8492ca1d81f4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e0f04368af17d56c8cdb50f0fd5f1847d9a49cb1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e0fbdd03e0e490770d671965ccce5f5ed42bbb9d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e134cc9b2be1a15b9e270a9f7baacbda3c8b3659" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e14b8b08ed9b569d2945b078fe94225924c5987e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e1954d1413f4f50c7bb3aa0ee368b94dfeae7c1b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e19f216f6b8b78ff1e705cb56d0cb07db60a05ec" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e1e31732ce0075070c8d7e2ef7a44b93949493d0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e1f79aa1d6477ffd08d4e5ce185637434147e4f8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e21b2668bb1e9cf057606c44d49648f1c140aa76" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e24778b9ec00cc9bef91643e31885deee719207e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e28a959abf1b36ad7778737d992690cb73a51a91" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e292ba16ee32e94ba88b4b72821bf90fe7b1b845" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e2982af9c977c39cb4633346b916a3897ffeb6f9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e326d4acceedb3e572b98d4a45a6f1e37ee42501" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e32bec776748185042cb02d58fad1d5027bbaeff" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e3443d812bb8204255a1d249b82aa19508dff5c9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e355b484879e20943aca2c6655953ec8121b64e8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e365d9256480b1e9d3cc6eafdcad5912b75ad149" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e3d08fe78f595bede290f820ec0e878572803a6a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e4028c8f2888697e9939562de475f70a841ee713" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e475b2b441a9b1cdf24e0ea992dfaecedd58d6d0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e49d92946422e69977a94d1b4b769f97efcfb8eb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e50c29688b2c3dbe6633797d2a200ed7c2cb1cba" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e59b406835db0d4c63ae28072c64c664da637557" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e5baf7303b008f333c57491345e604d52fce0d63" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e5fa8de537f7665e2aed751b8ca7c6b5bf0cdca0" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e635349c1e038d62f774f4201cbda082b8af403c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e64dff0ba3f0eb9e054a638d4d5f6f0cb47e1e98" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e6df36db61ae2c46d2cda2f6c8d1856ac181e6cc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e6f12dc0baf6536aa75f226bfb0262d8266433d1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e703236fc6d1dcc955b9abf34f490e2bf5057fdd" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e71d6b1facc3de5c246f7d14e35a2b4a2d983c11" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e74299a026e8a481c1db07e6065ca30af9858cbc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e75900e645ce8d1abbb97d408989b159b2a50a1c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e7b8aae66ff70d59fcc5a8b4de5a246081547146" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e81f08cfb60f7c156cf7dcbee1b8790901a1eadc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e8373e7e464120da8a84da82c8137872cda65780" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e857a6c6f502dd2bd0ec341b2d4ed55f2e87e8e7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e908278cc1515f214049c48c3a8908524f2cc407" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e913f5b697154f99bfc159a132c6c253b457ef18" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e93e7128f80bef53e3217782f21f4bd6a6d19c7c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "e9d157e81c306452f8494f681813037b146660eb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ea186a9a4815581b71403480abae5cc7c57c00be" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ea216bc75a65a838ea3d63f7c05588c2840ec1ab" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ea2f1211c66cdabf2b618a4dd965ce133592763b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "eadf36b1baf942879b0b5c45469fa05add1d61b3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "eb203eec55c1da2fd38977032c79ada414cc914c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "eb4e97f22f12995949c371f2df690f68f71070eb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "eb5ad2481a57a6b7ede3a16ad8bfe2991eef3ad7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "eb9414a32f85461cf4ac7c9c73761f3f1e5ab14e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ebff1a1539630b2f7b5260a93ea602372e539366" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ec184f693f222b3e48622f5253c134339e7e2e7d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ec318906ab052a41ef13ea33deee554704a307c1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ec45f260d4d758d6d23ae0297a9516190d935a5b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ec5f2ac1947c51c5982eb0ab63d1e6439f45c2e3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "eca2fc261f07a269c2487e6d1b0539d0950ff792" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ecb643ddbca1cfa6dd22964c20ef57ab47c0fda9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ecd38089d14a75b93afa634276bbe8965f5642dc" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ece9d0b9393f64338ec6ca5b0efbcec2175f19ec" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ed1a5e97e3415b484e6bc8b84bd170dbdd879cb3" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ee21d08004e0b6f2c1cd4bcb2a04ab74f7b7b708" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ee439948c6dead863ab2ba9105b70916d45f9e79" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ee6f3914a1e5d955fd62a29562ee0ab776235ff5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ef36b064bb706bc0540e4ed2b341ae8a0b7756b7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "efe2a6d8859b14ecc69baf66dcd47f4067df18e5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f00d30ecf763691115d2314d14ea1e11f61ad874" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f026ce3f255ef9fc7b93719a3f6926ce4953bfe1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f07ee5b0729c565f7b57995a108f94e4fcb81558" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f0dc197380bc632e5078f75f5ef0b814b7eb2ec6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f12be871bc1a1f3ca254eb027786085dd79494c5" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f134cf7fd6ed2e962db26c4b3d99ee5884102c85" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f191a9c00fe780f63cf4f68a06e895bd53981254" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f1970ea5af8456fee42cc087e79bd5c6a6efaa87" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f1ba5e0a4a27d8dafcf87f049b178fe83574ac06" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f25da1517af0e2fce2b9d75fd964e8827cc0cb72" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f2866fb67103c69f10edaed228d2dd64b7e6df83" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f2d3cbe7357ee858c2b7f6ea28fc95c1af508ca8" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f2d923a66a9684f2268530094ce8e3f8b8cae52e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f3b37fd9258f2c883c44e8ddaa90f91bfe9f5d51" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f3c5a341248911dda9d694ee74bf997365941dbf" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f4489af2af8424c6edf0d0adc525680dea208a31" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f475a28a9649aa00ab8a40af393f1961587c2275" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f48270bfa988db4518f9b1db9e78bb398c954550" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f49ecf0e4378b1957686d8d0b227f83e48e5523c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f4a32ec7fde64e7d3ceb53fcc00511ffe13ff5d4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f4d2d03bf70c2500fe431fdc8fbed2c13437bdc9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f4e76b020a22e8c1929ba2163e413385fc0cf884" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f53e504312e2ff787bbb9ba4ea921e9edb7b18ff" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f5472ede25cb83dc2fe392b01111133b777709b9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f619381383c69659fe81a10d695b2663426624d4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f62f676443b29c513964f01cbb356165ace54b78" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f6ee7d8bf313f837bbfed7f10b16fb2f182fd416" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f735071cbee190d76b704ce68384fc21e389fbe7" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f74f956ea3d122e47f4aa0066b5e3605c80d0282" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f783f583fc06d2c88e9e0d263a6ab66f8b8a0514" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f78b2d97c8af245b705c0a19601b95f983e9aaf6" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f78ff2d350615b858077a50ff85b3a9e2edcc995" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f85aaa082ae886506141245ea3b43ee74babca65" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f86c50909ddce25f4d4e71e16d78b2f6a244e8cb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f8e4de2f36fa5e9861fe3af86d05db4cae1bb1a4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f8fc32491119dea2b7fda5080ef9cf0027590265" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f904cb6a599db50cc635bb70f3c23f056e39914e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f94e8e9f1511f8cede3bfd8e1be0db35085e8e6d" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f9c7db4a48b918ad6e44d2b55e2339fdcde01d26" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "f9d417c0b18ff731a88a17f3b31d9d6ed1e288f1" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fa849bc1ece08222f4bf249ca06a6468b3de5b1a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fa9c2ac45638e511b06ebe051411ebdc2c4c228a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fabaccc45975d14c53b830fd4fa0576da541d22e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fac000880bdfdbd780ffa7c4a1d5d8b4a1d87b03" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fafa31e9b477adf7a26b651aa9913f8664e536a4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fb04fd4e715c760c91ddc0f30b000b52203f66a4" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fb5d7c75f272b07450867579978314661c3e1206" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fbdc8132551b0ed5c50b6c0f279097592b5c87ef" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fc55e6958f11444ae56c09af726f2ec57525db58" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fc70ade160bd76694149f3f439f5d4f78bdc483e" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fc86915f4e8884b49adeb6f23a8f69e643d9db7b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fcdb751de1dc7c5246ce698b4b104016d034cfdb" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fcf47e5c1414303d55afc40c75c41cf42079d560" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fd096ec4540dacfebbabf2dd6ffd3493a09cc38f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fd09bf9b58980d6a5776bb391d8c6881bcca2ae9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fd0dea1a583400fc29051c8192b70022d8d92c48" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fd437bf9d51bac3a2757bf4b8bf38045e78d5ada" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fd5b134edd8931ca2102693d88070dd49fc13350" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fd91b246a065cde3fc10edd6457b9e6c10fb386f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fdc6c80a86ea555b5de26c3db49a779eea6beb0c" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fe4f48d16a7ec27241b987f3545423291c7cce77" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fe686acb3b7cc09ec6379af828b4b3b638898130" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fe8d768de7a723c23583162dbef207b6dcb4fb58" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fed73d1755549bd523a775e81cf80a1a507eec50" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ffb9bfb24fb671413a3aae05e0f21b870eeb2ab9" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "ffc4569dfb86db2e584a1138a75747dffb794466" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "fff1cd2c481ce0fba0c97ef77c79227d3b67832a" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20000000",
+ "code" : "0x60206000600039602060006000f0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "465224",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/files/StateTests/stRefundTest.json b/tests/files/StateTests/stRefundTest.json
new file mode 100644
index 000000000..08ae1fac8
--- /dev/null
+++ b/tests/files/StateTests/stRefundTest.json
@@ -0,0 +1,523 @@
+{
+ "refund500" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600154506002545060ff60020a600a553031600b55600060015560006002556000600355600060045560006005556000600655",
+ "nonce" : "0",
+ "storage" : {
+ "0x0a" : "0x8000000000000000000000000000000000000000000000000000000000000000",
+ "0x0b" : "0x0de0b6b3a7640000"
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "592",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "9408",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600154506002545060ff60020a600a553031600b55600060015560006002556000600355600060045560006005556000600655",
+ "nonce" : "0",
+ "storage" : {
+ "0x01" : "0x01",
+ "0x02" : "0x01",
+ "0x03" : "0x01",
+ "0x04" : "0x01",
+ "0x05" : "0x01",
+ "0x06" : "0x01"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "10000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "0"
+ }
+ },
+ "refund50_1" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006001556000600255600060035560006004556000600555",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "255",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "9745",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006001556000600255600060035560006004556000600555",
+ "nonce" : "0",
+ "storage" : {
+ "0x01" : "0x01",
+ "0x02" : "0x01",
+ "0x03" : "0x01",
+ "0x04" : "0x01",
+ "0x05" : "0x01"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "10000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "0"
+ }
+ },
+ "refund50_2" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6001600a556001600b5560006001556000600255600060035560006004556000600555",
+ "nonce" : "0",
+ "storage" : {
+ "0x0a" : "0x01",
+ "0x0b" : "0x01"
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "614",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "9386",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6001600a556001600b5560006001556000600255600060035560006004556000600555",
+ "nonce" : "0",
+ "storage" : {
+ "0x01" : "0x01",
+ "0x02" : "0x01",
+ "0x03" : "0x01",
+ "0x04" : "0x01",
+ "0x05" : "0x01"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "10000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "0"
+ }
+ },
+ "refund600" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600154506002545061ffff60020a600a553031600b55600060015560006002556000600355600060045560006005556000600655",
+ "nonce" : "0",
+ "storage" : {
+ "0x0b" : "0x0de0b6b3a7640000"
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "492",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "9508",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600154506002545061ffff60020a600a553031600b55600060015560006002556000600355600060045560006005556000600655",
+ "nonce" : "0",
+ "storage" : {
+ "0x01" : "0x01",
+ "0x02" : "0x01",
+ "0x03" : "0x01",
+ "0x04" : "0x01",
+ "0x05" : "0x01",
+ "0x06" : "0x01"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "10000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "10000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "0"
+ }
+ },
+ "refund_NoOOG_1" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6000600155",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "402",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "100",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6000600155",
+ "nonce" : "0",
+ "storage" : {
+ "0x01" : "0x01"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "502",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "502",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "0"
+ }
+ },
+ "refund_OOG" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6000600155",
+ "nonce" : "0",
+ "storage" : {
+ "0x01" : "0x01"
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "500",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6000600155",
+ "nonce" : "0",
+ "storage" : {
+ "0x01" : "0x01"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "500",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "500",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "0"
+ }
+ },
+ "refund_changeNonZeroStorage" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000010",
+ "code" : "0x6017600155",
+ "nonce" : "0",
+ "storage" : {
+ "0x01" : "0x17"
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "602",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "388",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6017600155",
+ "nonce" : "0",
+ "storage" : {
+ "0x01" : "0x01"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "850",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "10"
+ }
+ },
+ "refund_getEtherBack" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000010",
+ "code" : "0x6000600155",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "402",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "588",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6000600155",
+ "nonce" : "0",
+ "storage" : {
+ "0x01" : "0x01"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "850",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "10"
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/files/StateTests/stSpecialTest.json b/tests/files/StateTests/stSpecialTest.json
new file mode 100644
index 000000000..91b51fdb0
--- /dev/null
+++ b/tests/files/StateTests/stSpecialTest.json
@@ -0,0 +1,77 @@
+{
+ "makeMoney" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000010",
+ "code" : "0x7b601080600c6000396000f200600035541560095700602035600035556000526000600060006000601773aaaaaaaaace5edbc8e2a8697c15331677e6ebf0b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecf1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "850",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "140",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ },
+ "aaaaaaaaace5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600160015532600255",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7b601080600c6000396000f200600035541560095700602035600035556000526000600060006000601773aaaaaaaaace5edbc8e2a8697c15331677e6ebf0b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecf1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "aaaaaaaaace5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600160015532600255",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "850",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "10"
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/files/StateTests/stSystemOperationsTest.json b/tests/files/StateTests/stSystemOperationsTest.json
index a4aff1c0f..612331ae3 100644
--- a/tests/files/StateTests/stSystemOperationsTest.json
+++ b/tests/files/StateTests/stSystemOperationsTest.json
@@ -8,6 +8,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -83,6 +85,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -158,6 +162,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -233,6 +239,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -308,6 +316,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
@@ -375,6 +385,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -449,6 +461,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -524,6 +538,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -585,6 +601,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -592,19 +610,19 @@
"code" : "0x600160005401600055600060006000600060003060e05a03f1600155",
"nonce" : "0",
"storage" : {
- "0x" : "0x0400",
+ "0x" : "0x03ff",
"0x01" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "260976",
+ "balance" : "261078",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999639024",
+ "balance" : "999999999999638922",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -646,6 +664,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -698,6 +718,3436 @@
"value" : "100000"
}
},
+ "CallRecursiveBombLog" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "10000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20099977",
+ "code" : "0x6000600060006000601773945304eb96065b2a98b57a48a06ae28d285a71b5620186a0f1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "76859",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000a0600160005401600055600060006000600060003060e05a03f1600155",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0xea",
+ "0x01" : "0x01"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999823141",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20000000",
+ "code" : "0x6000600060006000601773945304eb96065b2a98b57a48a06ae28d285a71b5620186a0f1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000a0600160005401600055600060006000600060003060e05a03f1600155",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "1000000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
+ "CallRecursiveBombLog2" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "10000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001869f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001842d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000018283",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000180d9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000017f2f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000017d85",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000017bdb",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000017a31",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000017887",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000176dd",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000017533",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000017389",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000171df",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000017035",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000016e8b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000016ce1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000016b37",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001698d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000167e3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000016639",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001648f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000162e5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001613b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000015f91",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000015de7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000015c3d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000015a93",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000158e9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001573f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000015595",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000153eb",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000015241",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000015097",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000014eed",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000014d43",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000014b99",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000149ef",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000014845",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001469b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000144f1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000014347",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001419d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000013ff3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000013e49",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000013c9f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000013af5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001394b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000137a1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000135f7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001344d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000132a3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000130f9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000012f4f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000012da5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000012bfb",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000012a51",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000128a7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000126fd",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000012553",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000123a9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000121ff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000012055",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000011eab",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000011d01",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000011b57",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000119ad",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000011803",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000011659",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000114af",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000011305",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001115b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000010fb1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000010e07",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000010c5d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000010ab3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000010909",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001075f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000105b5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000001040b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000010261",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000100b7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000ff0d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000fd63",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000fbb9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000fa0f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000f865",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000f6bb",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000f511",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000f367",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000f1bd",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000f013",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000ee69",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000ecbf",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000eb15",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000e96b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000e7c1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000e617",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000e46d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000e2c3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000e119",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000df6f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000ddc5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000dc1b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000da71",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000d8c7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000d71d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000d573",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000d3c9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000d21f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000d075",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000cecb",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000cd21",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000cb77",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000c9cd",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000c823",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000c679",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000c4cf",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000c325",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000c17b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000bfd1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000be27",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000bc7d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000bad3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000b929",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000b77f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000b5d5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000b42b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000b281",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000b0d7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000af2d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000ad83",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000abd9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000aa2f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000a885",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000a6db",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000a531",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000a387",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000a1dd",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000a033",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000009e89",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000009cdf",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000009b35",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000998b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000097e1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000009637",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000948d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000092e3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000009139",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000008f8f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000008de5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000008c3b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000008a91",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000088e7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000873d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000008593",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000083e9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000823f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000008095",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000007eeb",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000007d41",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000007b97",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000079ed",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000007843",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000007699",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000074ef",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000007345",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000719b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000006ff1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000006e47",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000006c9d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000006af3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000006949",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000679f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000065f5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000644b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000062a1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000060f7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000005f4d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000005da3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000005bf9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000005a4f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000058a5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000056fb",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000005551",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000053a7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000051fd",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000005053",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000004ea9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000004cff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000004b55",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000049ab",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000004801",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000004657",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000044ad",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000004303",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000004159",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000003faf",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000003e05",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000003c5b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000003ab1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000003907",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000375d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000035b3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000003409",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000325f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000030b5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000002f0b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000002d61",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000002bb7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000002a0d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000002863",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000026b9",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000250f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000002365",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000021bb",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000002011",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000001e67",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000001cbd",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000001b13",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000001969",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000017bf",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000001615",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000146b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000012c1",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000001117",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000000f6d",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000000dc3",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000000c19",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000000a6f",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000008c5",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000071b",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x0000000000000000000000000000000000000000000000000000000000000571",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x00000000000000000000000000000000000000000000000000000000000003c7",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
+ "bloom" : "00000000000000040000000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x000000000000000000000000000000000000000000000000000000000000021d",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20099977",
+ "code" : "0x6000600060006000601773945304eb96065b2a98b57a48a06ae28d285a71b5620186a0f1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "76859",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+ "balance" : "1000000000000000023",
+ "code" : "0x5a60005260206000a0600160005401600055600060006000600060003060e05a03f1600155",
+ "nonce" : "0",
+ "storage" : {
+ "0x" : "0xea",
+ "0x01" : "0x01"
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "999999999999823141",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+ "balance" : "20000000",
+ "code" : "0x6000600060006000601773945304eb96065b2a98b57a48a06ae28d285a71b5620186a0f1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x5a60005260206000a0600160005401600055600060006000600060003060e05a03f1600155",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "1000000",
+ "gasPrice" : "1",
+ "nonce" : "0",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+ "value" : "100000"
+ }
+ },
"CallToNameRegistrator0" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
@@ -707,6 +4157,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -782,6 +4234,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -857,6 +4311,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -931,6 +4387,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -1004,6 +4462,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -1077,6 +4537,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -1150,6 +4612,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -1223,6 +4687,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -1242,7 +4708,7 @@
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "46",
- "code" : "0x6001600155603760005360026000f2",
+ "code" : "0x6001600155603760005360026000f3",
"nonce" : "0",
"storage" : {
"0x01" : "0x01"
@@ -1266,7 +4732,7 @@
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
- "code" : "0x6001600155603760005360026000f2",
+ "code" : "0x6001600155603760005360026000f3",
"nonce" : "0",
"storage" : {
}
@@ -1298,6 +4764,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -1371,6 +4839,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -1431,11 +4901,13 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000100000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000604060406000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f3600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000604060406000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f2600055",
"nonce" : "0",
"storage" : {
"0x" : "0x01",
@@ -1467,7 +4939,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000604060406000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f3600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000604060406000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f2600055",
"nonce" : "0",
"storage" : {
}
@@ -1506,11 +4978,13 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000100000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526002600060406000601773945304eb96065b2a98b57a48a06ae28d285a71b56101f4f3600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526002600060406000601773945304eb96065b2a98b57a48a06ae28d285a71b56101f4f2600055",
"nonce" : "0",
"storage" : {
"0x" : "0x01",
@@ -1526,7 +5000,7 @@
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
- "code" : "0x6001600155603760005360026000f2",
+ "code" : "0x6001600155603760005360026000f3",
"nonce" : "0",
"storage" : {
}
@@ -1542,14 +5016,14 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526002600060406000601773945304eb96065b2a98b57a48a06ae28d285a71b56101f4f3600055",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526002600060406000601773945304eb96065b2a98b57a48a06ae28d285a71b56101f4f2600055",
"nonce" : "0",
"storage" : {
}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
- "code" : "0x6001600155603760005360026000f2",
+ "code" : "0x6001600155603760005360026000f3",
"nonce" : "0",
"storage" : {
}
@@ -1581,6 +5055,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
@@ -1655,25 +5131,27 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000099977",
- "code" : "0x7b601080600c6000396000f20060003554156009570060203560003555600052601c60046017f0600055",
+ "code" : "0x7b601080600c6000396000f30060003554156009570060203560003555600052601c60046017f0600055",
"nonce" : "1",
"storage" : {
"0x" : "0xd2571607e241ecf590ed94b12d87c94babe36db6"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
- "balance" : "916",
+ "balance" : "997",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
- "balance" : "999999999999899084",
+ "balance" : "999999999999899003",
"code" : "0x",
"nonce" : "1",
"storage" : {
@@ -1690,7 +5168,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
- "code" : "0x7b601080600c6000396000f20060003554156009570060203560003555600052601c60046017f0600055",
+ "code" : "0x7b601080600c6000396000f30060003554156009570060203560003555600052601c60046017f0600055",
"nonce" : "0",
"storage" : {
}
@@ -1722,11 +5200,13 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000100000",
- "code" : "0x7b601080600c6000396000f20060003554156009570060203560003555600052601c650fffffffffff6017f0600055",
+ "code" : "0x7b601080600c6000396000f30060003554156009570060203560003555600052601c650fffffffffff6017f0600055",
"nonce" : "0",
"storage" : {
}
@@ -1749,7 +5229,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
- "code" : "0x7b601080600c6000396000f20060003554156009570060203560003555600052601c650fffffffffff6017f0600055",
+ "code" : "0x7b601080600c6000396000f30060003554156009570060203560003555600052601c650fffffffffff6017f0600055",
"nonce" : "0",
"storage" : {
}
@@ -1781,11 +5261,13 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000100000",
- "code" : "0x7b601080600c6000396000f20060003554156009570060203560003555600052650fffffffffff60046017f0600055",
+ "code" : "0x7b601080600c6000396000f30060003554156009570060203560003555600052650fffffffffff60046017f0600055",
"nonce" : "0",
"storage" : {
}
@@ -1808,7 +5290,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
- "code" : "0x7b601080600c6000396000f20060003554156009570060203560003555600052650fffffffffff60046017f0600055",
+ "code" : "0x7b601080600c6000396000f30060003554156009570060203560003555600052650fffffffffff60046017f0600055",
"nonce" : "0",
"storage" : {
}
@@ -1840,11 +5322,13 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
- "code" : "0x7b601080600c6000396000f20060003554156009570060203560003555600052601c60046103e8f0600055",
+ "code" : "0x7b601080600c6000396000f30060003554156009570060203560003555600052601c60046103e8f0600055",
"nonce" : "0",
"storage" : {
}
@@ -1860,7 +5344,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
- "code" : "0x7b601080600c6000396000f20060003554156009570060203560003555600052601c60046103e8f0600055",
+ "code" : "0x7b601080600c6000396000f30060003554156009570060203560003555600052601c60046103e8f0600055",
"nonce" : "0",
"storage" : {
}
@@ -1892,11 +5376,13 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x37",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100023",
- "code" : "0x603760005360016000f2",
+ "code" : "0x603760005360016000f3",
"nonce" : "0",
"storage" : {
}
@@ -1919,7 +5405,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "23",
- "code" : "0x603760005360016000f2",
+ "code" : "0x603760005360016000f3",
"nonce" : "0",
"storage" : {
}
@@ -1951,11 +5437,13 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x3700",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100023",
- "code" : "0x603760005360026000f2",
+ "code" : "0x603760005360026000f3",
"nonce" : "0",
"storage" : {
}
@@ -1978,7 +5466,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "23",
- "code" : "0x603760005360026000f2",
+ "code" : "0x603760005360026000f3",
"nonce" : "0",
"storage" : {
}
@@ -2010,11 +5498,13 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x370000000000000000000000000000000000000000000000000000000000000000",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100023",
- "code" : "0x603760005360216000f2",
+ "code" : "0x603760005360216000f3",
"nonce" : "0",
"storage" : {
}
@@ -2037,7 +5527,7 @@
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "23",
- "code" : "0x603760005360216000f2",
+ "code" : "0x603760005360216000f3",
"nonce" : "0",
"storage" : {
}
@@ -2069,6 +5559,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
@@ -2121,6 +5613,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
@@ -2173,6 +5667,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
@@ -2232,6 +5728,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
@@ -2284,6 +5782,8 @@
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
diff --git a/tests/files/StateTests/stTransactionTest.json b/tests/files/StateTests/stTransactionTest.json
new file mode 100644
index 000000000..0de850797
--- /dev/null
+++ b/tests/files/StateTests/stTransactionTest.json
@@ -0,0 +1,277 @@
+{
+ "EmptyTransaction" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "100000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "100000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "",
+ "gasPrice" : "",
+ "nonce" : "",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "",
+ "value" : ""
+ }
+ },
+ "TransactionFromCoinbaseNotEnoughFounds" : {
+ "env" : {
+ "currentCoinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1100",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "600",
+ "gasPrice" : "1",
+ "nonce" : "",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+ "value" : "502"
+ }
+ },
+ "TransactionSendingToEmpty" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "500",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
+ "balance" : "0",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "99500",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "100000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "500",
+ "gasPrice" : "1",
+ "nonce" : "",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "",
+ "value" : ""
+ }
+ },
+ "TransactionSendingToZero" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0000000000000000000000000000000000000000" : {
+ "balance" : "1",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "500",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "99499",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "100000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "5000",
+ "gasPrice" : "1",
+ "nonce" : "",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "0000000000000000000000000000000000000000",
+ "value" : "1"
+ }
+ },
+ "TransactionToItself" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
+ "balance" : "500",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ },
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "99500",
+ "code" : "0x",
+ "nonce" : "1",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "100000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "5000",
+ "gasPrice" : "1",
+ "nonce" : "",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+ "value" : "1"
+ }
+ },
+ "TransactionToItselfNotEnoughFounds" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "45678256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : 1,
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1101",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+ "balance" : "1101",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "transaction" : {
+ "data" : "",
+ "gasLimit" : "600",
+ "gasPrice" : "1",
+ "nonce" : "",
+ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+ "to" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+ "value" : "502"
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/files/TrieTests/trieanyorder.json b/tests/files/TrieTests/trieanyorder.json
new file mode 100644
index 000000000..ebf5fbff0
--- /dev/null
+++ b/tests/files/TrieTests/trieanyorder.json
@@ -0,0 +1,55 @@
+{
+ "singleItem": {
+ "in": {
+ "A": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ },
+ "root": "0xd23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab"
+ },
+ "dogs": {
+ "in": {
+ "doe": "reindeer",
+ "dog": "puppy",
+ "dogglesworth": "cat"
+ },
+ "root": "0x8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3"
+ },
+ "puppy": {
+ "in": {
+ "do": "verb",
+ "horse": "stallion",
+ "doge": "coin",
+ "dog": "puppy"
+ },
+ "root": "0x5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84"
+ },
+ "foo": {
+ "in": {
+ "foo": "bar",
+ "food": "bat",
+ "food": "bass"
+ },
+ "root": "0x17beaa1648bafa633cda809c90c04af50fc8aed3cb40d16efbddee6fdf63c4c3"
+ },
+ "smallValues": {
+ "in": {
+ "be": "e",
+ "dog": "puppy",
+ "bed": "d"
+ },
+ "root": "0x3f67c7a47520f79faa29255d2d3c084a7a6df0453116ed7232ff10277a8be68b"
+ },
+ "testy": {
+ "in": {
+ "test": "test",
+ "te": "testy"
+ },
+ "root": "0x8452568af70d8d140f58d941338542f645fcca50094b20f3c3d8c3df49337928"
+ },
+ "hex": {
+ "in": {
+ "0x0045": "0x0123456789",
+ "0x4500": "0x9876543210"
+ },
+ "root": "0x285505fcabe84badc8aa310e2aae17eddc7d120aabec8a476902c8184b3a3503"
+ }
+}
diff --git a/tests/files/TrieTests/trietest.json b/tests/files/TrieTests/trietest.json
index 317429649..ce5c2d191 100644
--- a/tests/files/TrieTests/trietest.json
+++ b/tests/files/TrieTests/trietest.json
@@ -1,84 +1,31 @@
{
- "singleItem": {
- "in": {
- "A": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- },
- "root": "d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab"
- },
- "dogs": {
- "in": {
- "doe": "reindeer",
- "dog": "puppy",
- "dogglesworth": "cat"
- },
- "root": "8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3"
- },
- "puppy": {
- "in": {
- "do": "verb",
- "horse": "stallion",
- "doge": "coin",
- "dog": "puppy"
- },
- "root": "5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84"
- },
"emptyValues": {
- "in": {
- "do": "verb",
- "ether": "wookiedoo",
- "horse": "stallion",
- "shaman": "horse",
- "doge": "coin",
- "ether": "",
- "dog": "puppy",
- "shaman": ""
- },
- "root": "4505cb6d817068bcd68fb225ab4d5ab70860461d3b35738bf6bcf7b44d702d0d"
- },
- "foo": {
- "in": {
- "foo": "bar",
- "food": "bat",
- "food": "bass"
- },
- "root": "17beaa1648bafa633cda809c90c04af50fc8aed3cb40d16efbddee6fdf63c4c3"
- },
- "smallValues": {
- "in": {
- "be": "e",
- "dog": "puppy",
- "bed": "d"
- },
- "root": "3f67c7a47520f79faa29255d2d3c084a7a6df0453116ed7232ff10277a8be68b"
- },
- "testy": {
- "in": {
- "test": "test",
- "te": "testy"
- },
- "root": "8452568af70d8d140f58d941338542f645fcca50094b20f3c3d8c3df49337928"
+ "in": [
+ ["do", "verb"],
+ ["ether", "wookiedoo"],
+ ["horse", "stallion"],
+ ["shaman", "horse"],
+ ["doge", "coin"],
+ ["ether", null],
+ ["dog", "puppy"],
+ ["shaman", null]
+ ],
+ "root": "0x5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84"
},
- "hex": {
- "in": {
- "0x0045": "0x0123456789",
- "0x4500": "0x9876543210"
- },
- "root": "285505fcabe84badc8aa310e2aae17eddc7d120aabec8a476902c8184b3a3503"
- },
"jeff": {
- "in": {
- "0x0000000000000000000000000000000000000000000000000000000000000045": "0x22b224a1420a802ab51d326e29fa98e34c4f24ea",
- "0x0000000000000000000000000000000000000000000000000000000000000046": "0x67706c2076330000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000001234567890": "0x697c7b8c961b56f675d570498424ac8de1a918f6",
- "0x000000000000000000000000697c7b8c961b56f675d570498424ac8de1a918f6": "0x1234567890",
- "0x0000000000000000000000007ef9e639e2733cb34e4dfc576d4b23f72db776b2": "0x4655474156000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000ec4f34c97e43fbb2816cfd95e388353c7181dab1": "0x4e616d6552656700000000000000000000000000000000000000000000000000",
- "0x4655474156000000000000000000000000000000000000000000000000000000": "0x7ef9e639e2733cb34e4dfc576d4b23f72db776b2",
- "0x4e616d6552656700000000000000000000000000000000000000000000000000": "0xec4f34c97e43fbb2816cfd95e388353c7181dab1",
- "0x0000000000000000000000000000000000000000000000000000001234567890": "",
- "0x000000000000000000000000697c7b8c961b56f675d570498424ac8de1a918f6": "0x6f6f6f6820736f2067726561742c207265616c6c6c793f000000000000000000",
- "0x6f6f6f6820736f2067726561742c207265616c6c6c793f000000000000000000": "0x697c7b8c961b56f675d570498424ac8de1a918f6"
- },
- "root": "088c8e162c91c75ca9efa63f21530bbc6964cff7453a5d6af8404d090292a3e7"
- }
+ "in": [
+ ["0x0000000000000000000000000000000000000000000000000000000000000045", "0x22b224a1420a802ab51d326e29fa98e34c4f24ea"],
+ ["0x0000000000000000000000000000000000000000000000000000000000000046", "0x67706c2076330000000000000000000000000000000000000000000000000000"],
+ ["0x0000000000000000000000000000000000000000000000000000001234567890", "0x697c7b8c961b56f675d570498424ac8de1a918f6"],
+ ["0x000000000000000000000000697c7b8c961b56f675d570498424ac8de1a918f6", "0x1234567890"],
+ ["0x0000000000000000000000007ef9e639e2733cb34e4dfc576d4b23f72db776b2", "0x4655474156000000000000000000000000000000000000000000000000000000"],
+ ["0x000000000000000000000000ec4f34c97e43fbb2816cfd95e388353c7181dab1", "0x4e616d6552656700000000000000000000000000000000000000000000000000"],
+ ["0x4655474156000000000000000000000000000000000000000000000000000000", "0x7ef9e639e2733cb34e4dfc576d4b23f72db776b2"],
+ ["0x4e616d6552656700000000000000000000000000000000000000000000000000", "0xec4f34c97e43fbb2816cfd95e388353c7181dab1"],
+ ["0x0000000000000000000000000000000000000000000000000000001234567890", null],
+ ["0x000000000000000000000000697c7b8c961b56f675d570498424ac8de1a918f6", "0x6f6f6f6820736f2067726561742c207265616c6c6c793f000000000000000000"],
+ ["0x6f6f6f6820736f2067726561742c207265616c6c6c793f000000000000000000", "0x697c7b8c961b56f675d570498424ac8de1a918f6"]
+ ],
+ "root": "0x9f6221ebb8efe7cff60a716ecb886e67dd042014be444669f0159d8e68b42100"
+ }
}
diff --git a/tests/files/VMTests/RandomTests/randomTest.json b/tests/files/VMTests/RandomTests/randomTest.json
new file mode 100644
index 000000000..dad2ee4a2
--- /dev/null
+++ b/tests/files/VMTests/RandomTests/randomTest.json
@@ -0,0 +1,46 @@
+{
+ "randomVMtest" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x675545",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9999",
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x675545",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x675545",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/files/VMTests/vmArithmeticTest.json b/tests/files/VMTests/vmArithmeticTest.json
index ad3846cf9..88d209dfa 100644
--- a/tests/files/VMTests/vmArithmeticTest.json
+++ b/tests/files/VMTests/vmArithmeticTest.json
@@ -12,15 +12,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -55,15 +57,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60047fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -98,15 +102,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "10000",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -140,15 +146,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6000600001600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -182,15 +190,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600101600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -224,15 +234,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60026002600108600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -267,15 +279,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60026002600003600160000308600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9691",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -310,15 +324,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60036001600660000308600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9693",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -353,15 +369,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60036001600660000308600360056000030714600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9887",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -395,15 +413,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60036001600660000308600360056000030614600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9687",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -438,15 +458,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60036000036001600408600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9693",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -481,15 +503,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60026003600003600160040814600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9891",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -523,15 +547,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6002600504600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -566,15 +592,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6018601704600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -608,15 +636,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6018600004600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -650,15 +680,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6001600104600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -693,15 +725,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6000600204600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -735,15 +769,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x600260020a600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "9696",
+ "gas" : "9695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -778,15 +814,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "9696",
+ "gas" : "9664",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -821,15 +859,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x637fffffff637fffffff0a600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "9696",
+ "gas" : "9692",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -864,15 +904,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x637fffffff60000a600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "9896",
+ "gas" : "9892",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -906,15 +948,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6000637fffffff0a600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -949,15 +993,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60016101010a600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "9696",
+ "gas" : "9695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -992,15 +1038,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x61010160010a600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "9696",
+ "gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1035,15 +1083,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x61010160020a600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "9896",
+ "gas" : "9894",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1077,15 +1127,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6003600206600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1120,15 +1172,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff06600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1163,15 +1217,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600006600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1205,15 +1261,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6000600306600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1247,15 +1305,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6003600260000306600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1290,15 +1350,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6003600202600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1333,15 +1395,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1376,15 +1440,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6017600002600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1418,15 +1484,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6001601702600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1461,15 +1529,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f800000000000000000000000000000000000000000000000000000000000000002600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1504,15 +1574,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7f80000000000000000000000000000000000000000000000000000000000000007f800000000000000000000000000000000000000000000000000000000000000002600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1546,15 +1618,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1589,15 +1663,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60026002600109600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9895",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1631,15 +1707,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60036002600003600160000309600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9891",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1673,15 +1751,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60036001600560000309600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9693",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1716,15 +1796,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60036001600560000309600360056000030714600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9887",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1758,15 +1840,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60036001600560000309600360056000030614600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9687",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1801,15 +1885,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60036000036001600509600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9693",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1844,15 +1930,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60026003600003600160050914600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9891",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1886,15 +1974,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60000305600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1929,15 +2019,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff05600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1972,15 +2064,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6004600003600260000305600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9892",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2014,15 +2108,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6002600003600405600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2057,15 +2153,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6000600003600360000305600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9892",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2099,15 +2197,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60000305600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9894",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2141,15 +2241,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x62126af460500b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2184,15 +2286,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x600060000b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2226,15 +2330,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60000b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2269,15 +2375,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2312,15 +2420,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2355,15 +2465,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60ff68f000000000000000010b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2398,15 +2510,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2440,15 +2554,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x62122f6a60000b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2483,15 +2599,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x62126af460010b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2526,15 +2644,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6212faf460010b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2569,15 +2689,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x66f000000000000161ffff0b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2612,15 +2734,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x62122ff460000b600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2655,15 +2779,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6003600003600560000307600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9692",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2698,15 +2824,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6003600003600507600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2741,15 +2869,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6003600560000307600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2784,15 +2914,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600260000307600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9894",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2826,15 +2958,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6000600260000307600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9894",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2868,15 +3002,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x00",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "10000",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2910,15 +3046,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6001601703600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2953,15 +3091,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6003600203600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2996,15 +3136,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x6017600003600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -3039,15 +3181,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600003600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -3082,15 +3226,17 @@
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
- "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"code" : "0x60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
- "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -3112,4 +3258,4 @@
}
}
}
-} \ No newline at end of file
+}
diff --git a/tests/files/VMTests/vmBitwiseLogicOperationTest.json b/tests/files/VMTests/vmBitwiseLogicOperationTest.json
index 3de20ba6b..f72711995 100644
--- a/tests/files/VMTests/vmBitwiseLogicOperationTest.json
+++ b/tests/files/VMTests/vmBitwiseLogicOperationTest.json
@@ -21,6 +21,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -64,6 +66,8 @@
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -106,6 +110,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -149,6 +155,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -192,6 +200,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -235,6 +245,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -278,6 +290,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -321,6 +335,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -364,6 +380,8 @@
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -406,6 +424,8 @@
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -448,6 +468,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -491,6 +513,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -534,6 +558,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -577,6 +603,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -620,6 +648,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -663,6 +693,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -706,6 +738,8 @@
"value" : "1000000000000000000"
},
"gas" : "9894",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -748,6 +782,8 @@
"value" : "1000000000000000000"
},
"gas" : "9894",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -790,6 +826,8 @@
"value" : "1000000000000000000"
},
"gas" : "9892",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -832,6 +870,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -875,6 +915,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -918,6 +960,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -961,6 +1005,8 @@
"value" : "1000000000000000000"
},
"gas" : "9894",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1003,6 +1049,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1046,6 +1094,8 @@
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1088,6 +1138,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1131,6 +1183,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1174,6 +1228,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1217,6 +1273,8 @@
"value" : "1000000000000000000"
},
"gas" : "9894",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1259,6 +1317,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1302,6 +1362,8 @@
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1344,6 +1406,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1387,6 +1451,8 @@
"value" : "1000000000000000000"
},
"gas" : "9697",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1430,6 +1496,8 @@
"value" : "1000000000000000000"
},
"gas" : "9897",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1472,6 +1540,8 @@
"value" : "1000000000000000000"
},
"gas" : "9897",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1514,6 +1584,8 @@
"value" : "1000000000000000000"
},
"gas" : "9895",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1556,6 +1628,8 @@
"value" : "1000000000000000000"
},
"gas" : "9895",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1598,6 +1672,8 @@
"value" : "1000000000000000000"
},
"gas" : "9695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1641,6 +1717,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1684,6 +1762,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1727,6 +1807,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1770,6 +1852,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1813,6 +1897,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1856,6 +1942,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1899,6 +1987,8 @@
"value" : "1000000000000000000"
},
"gas" : "9894",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1941,6 +2031,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1984,6 +2076,8 @@
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2026,6 +2120,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2069,6 +2165,8 @@
"value" : "1000000000000000000"
},
"gas" : "9892",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2111,6 +2209,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2154,6 +2254,8 @@
"value" : "1000000000000000000"
},
"gas" : "9894",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2196,6 +2298,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2239,6 +2343,8 @@
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2281,6 +2387,8 @@
"value" : "1000000000000000000"
},
"gas" : "9692",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2324,6 +2432,8 @@
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2366,6 +2476,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2409,6 +2521,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2452,6 +2566,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2495,6 +2611,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2538,6 +2656,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
diff --git a/tests/files/VMTests/vmBlockInfoTest.json b/tests/files/VMTests/vmBlockInfoTest.json
index 0bdaffe73..90fa77a3d 100644
--- a/tests/files/VMTests/vmBlockInfoTest.json
+++ b/tests/files/VMTests/vmBlockInfoTest.json
@@ -21,6 +21,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -64,6 +66,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -107,6 +111,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -150,6 +156,8 @@
"value" : "1000000000000000000"
},
"gas" : "9898",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -192,6 +200,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -235,6 +245,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
diff --git a/tests/files/VMTests/vmEnvironmentalInfoTest.json b/tests/files/VMTests/vmEnvironmentalInfoTest.json
index 6928155db..37563707b 100644
--- a/tests/files/VMTests/vmEnvironmentalInfoTest.json
+++ b/tests/files/VMTests/vmEnvironmentalInfoTest.json
@@ -21,6 +21,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -64,6 +66,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"cd1722f3947def4cf144679da39c4c32bdc35681" : {
@@ -107,6 +111,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999878",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -156,6 +162,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999678",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -199,6 +207,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999656",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -242,6 +252,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999656",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -291,7 +303,9 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "99999999692",
+ "gas" : "99999999691",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -334,7 +348,9 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "99999999692",
+ "gas" : "99999999691",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -378,6 +394,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999892",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -398,6 +416,94 @@
}
}
},
+ "calldatacopy_DataIndexTooHigh" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x60ff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa600037600051600055",
+ "data" : "0x01234567890abcdef01234567890abcdef",
+ "gas" : "100000000000",
+ "gasPrice" : "1000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "99999999877",
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa600037600051600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa600037600051600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "calldatacopy_DataIndexTooHigh2" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x60097ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa600037600051600055",
+ "data" : "0x01234567890abcdef01234567890abcdef",
+ "gas" : "100000000000",
+ "gasPrice" : "1000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "99999999891",
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60097ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa600037600051600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60097ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa600037600051600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
"calldataload0" : {
"callcreates" : [
],
@@ -420,6 +526,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999697",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -463,6 +571,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999697",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -506,6 +616,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999697",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -527,6 +639,50 @@
}
}
},
+ "calldataloadSizeTooHigh" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa35600055",
+ "data" : "0x0123456789abcdef0000000000000000000000000000000000000000000000000024",
+ "gas" : "100000000000",
+ "gasPrice" : "1000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "99999999897",
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa35600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa35600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
"calldatasize0" : {
"callcreates" : [
],
@@ -549,6 +705,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -592,6 +750,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -635,6 +795,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -678,6 +840,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -721,6 +885,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -763,7 +929,9 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "99999999692",
+ "gas" : "99999999691",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -806,7 +974,9 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "99999999692",
+ "gas" : "99999999691",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -828,6 +998,50 @@
}
}
},
+ "codecopy_DataIndexTooHigh" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x60087ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa600039600051600055",
+ "data" : "0x01234567890abcdef01234567890abcdef",
+ "gas" : "100000000000",
+ "gasPrice" : "1000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "99999999891",
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60087ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa600039600051600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60087ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa600039600051600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
"codesize" : {
"callcreates" : [
],
@@ -850,6 +1064,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -892,7 +1108,9 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "99999999690",
+ "gas" : "99999999689",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -928,6 +1146,50 @@
}
}
},
+ "extcodecopy_DataIndexTooHigh" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x60087ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa6000303c600051600055",
+ "data" : "0x01234567890abcdef01234567890abcdef",
+ "gas" : "100000000000",
+ "gasPrice" : "1000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "99999999890",
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60087ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa6000303c600051600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60087ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa6000303c600051600055",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
"extcodesize0" : {
"callcreates" : [
],
@@ -950,6 +1212,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1007,6 +1271,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999697",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1064,6 +1330,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1107,6 +1375,8 @@
"value" : "1000000000000000000"
},
"gas" : "99999999698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
diff --git a/tests/files/VMTests/vmIOandFlowOperationsTest.json b/tests/files/VMTests/vmIOandFlowOperationsTest.json
index 027328d0d..120977086 100644
--- a/tests/files/VMTests/vmIOandFlowOperationsTest.json
+++ b/tests/files/VMTests/vmIOandFlowOperationsTest.json
@@ -1,5 +1,5 @@
{
- "dupAt51doesNotExistAnymore" : {
+ "dupAt51becameMload" : {
"callcreates" : [
],
"env" : {
@@ -21,6 +21,8 @@
"value" : "1000000000000000000"
},
"gas" : "9695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -64,6 +66,8 @@
"value" : "1000000000000000000"
},
"gas" : "9688",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -107,6 +111,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -150,6 +156,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -172,8 +180,6 @@
}
},
"jump0_foreverOutOfGas" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -192,17 +198,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x600056",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
@@ -235,6 +230,8 @@
"value" : "1000000000000000000"
},
"gas" : "9695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -278,6 +275,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -321,6 +320,8 @@
"value" : "1000000000000000000"
},
"gas" : "9693",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -343,8 +344,6 @@
}
},
"jump0_jumpdest3" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -363,17 +362,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x6023600b6008505660015b600255",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
@@ -385,8 +373,6 @@
}
},
"jump1" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -405,17 +391,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x620fffff620fffff0156",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
@@ -448,6 +423,8 @@
"value" : "1000000000000000000"
},
"gas" : "9695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -491,6 +468,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -534,6 +513,8 @@
"value" : "1000000000000000000"
},
"gas" : "9695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -577,6 +558,8 @@
"value" : "1000000000000000000"
},
"gas" : "9997",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -619,6 +602,8 @@
"value" : "1000000000000000000"
},
"gas" : "9896",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -661,6 +646,8 @@
"value" : "1000000000000000000"
},
"gas" : "9892",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -682,8 +669,6 @@
}
},
"mloadOutOfGasError2" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -702,17 +687,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x6272482551600155",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
@@ -745,6 +719,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -788,6 +764,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -831,6 +809,8 @@
"value" : "1000000000000000000"
},
"gas" : "9690",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -874,6 +854,8 @@
"value" : "1000000000000000000"
},
"gas" : "9688",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -917,6 +899,8 @@
"value" : "1000000000000000000"
},
"gas" : "9692",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -960,6 +944,8 @@
"value" : "1000000000000000000"
},
"gas" : "9690",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1003,6 +989,8 @@
"value" : "1000000000000000000"
},
"gas" : "10000",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1045,6 +1033,8 @@
"value" : "1000000000000000000"
},
"gas" : "9692",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1088,6 +1078,8 @@
"value" : "1000000000000000000"
},
"gas" : "9690",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1131,6 +1123,8 @@
"value" : "1000000000000000000"
},
"gas" : "10000",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1173,6 +1167,8 @@
"value" : "1000000000000000000"
},
"gas" : "9693",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1216,6 +1212,8 @@
"value" : "1000000000000000000"
},
"gas" : "9898",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1258,6 +1256,8 @@
"value" : "1000000000000000000"
},
"gas" : "9596",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1301,6 +1301,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1323,8 +1325,6 @@
}
},
"pop1" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -1343,17 +1343,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x5060026003600455",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
@@ -1386,6 +1375,8 @@
"value" : "1000000000000000000"
},
"gas" : "9074",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1431,6 +1422,8 @@
"value" : "1000000000000000000"
},
"gas" : "9274",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1475,6 +1468,8 @@
"value" : "1000000000000000000"
},
"gas" : "8450",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1500,9 +1495,7 @@
}
}
},
- "swapAt52doesNotExistAnymore" : {
- "callcreates" : [
- ],
+ "swapAt52becameMstore" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -1521,17 +1514,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x600260035255",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
diff --git a/tests/files/VMTests/vmLogTest.json b/tests/files/VMTests/vmLogTest.json
new file mode 100644
index 000000000..48e20ac63
--- /dev/null
+++ b/tests/files/VMTests/vmLogTest.json
@@ -0,0 +1,2190 @@
+{
+ "log0_emptyMem" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x60006000a0",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9966",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log0_logMemStartTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log0_logMemsizeTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a0",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log0_logMemsizeZero" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006001a0",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9962",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006001a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006001a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log0_nonEmptyMem" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000a0",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9930",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log0_nonEmptyMem_logMemSize1" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260016000a0",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9961",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xaa",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260016000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260016000a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log0_nonEmptyMem_logMemSize1_logMemStart31" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526001601fa0",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9961",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xdd",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526001601fa0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526001601fa0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log1_Caller" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x60ff6000533360206000a1",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9897",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000008000000808100000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xff00000000000000000000000000000000000000000000000000000000000000",
+ "topics" : [
+ "000000000000000000000000cd1722f3947def4cf144679da39c4c32bdc35681"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff6000533360206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff6000533360206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log1_MaxTopic" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a1",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9897",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000200000800000000000000000000000000000000880000000000000000000000000000000000000000000000010000000000000000000000020",
+ "data" : "0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd",
+ "topics" : [
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log1_emptyMem" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x600060006000a1",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9933",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600060006000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600060006000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log1_logMemStartTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log1_logMemsizeTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a1",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log1_logMemsizeZero" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006001a1",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9929",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006001a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006001a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log1_nonEmptyMem" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9897",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060206000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log1_nonEmptyMem_logMemSize1" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060016000a1",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9928",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xaa",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060016000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060016000a1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log1_nonEmptyMem_logMemSize1_logMemStart31" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006001601fa1",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9928",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xdd",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006001601fa1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006001601fa1",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log2_Caller" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x60ff60005333600060206000a2",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9864",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000008000000808100000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xff00000000000000000000000000000000000000000000000000000000000000",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000cd1722f3947def4cf144679da39c4c32bdc35681"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff60005333600060206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff60005333600060206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log2_MaxTopic" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a2",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9864",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000200000800000000000000000000000000000000880000000000000000000000000000000000000000000000010000000000000000000000020",
+ "data" : "0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd",
+ "topics" : [
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log2_emptyMem" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x6000600060006000a2",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9900",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6000600060006000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x6000600060006000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log2_logMemStartTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa2",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log2_logMemsizeTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a2",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log2_logMemsizeZero" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060006001a2",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9896",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060006001a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060006001a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log2_nonEmptyMem" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526000600060206000a2",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9864",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526000600060206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000526000600060206000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log2_nonEmptyMem_logMemSize1" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060016000a2",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9895",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xaa",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060016000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060016000a2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log2_nonEmptyMem_logMemSize1_logMemStart31" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006001601fa2",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9895",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xdd",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006001601fa2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006001601fa2",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log3_Caller" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x60ff600053336000600060206000a3",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9831",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000008000000808100000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xff00000000000000000000000000000000000000000000000000000000000000",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000cd1722f3947def4cf144679da39c4c32bdc35681"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff600053336000600060206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff600053336000600060206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log3_MaxTopic" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a3",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9831",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000200000800000000000000000000000000000000880000000000000000000000000000000000000000000000010000000000000000000000020",
+ "data" : "0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd",
+ "topics" : [
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log3_PC" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x60ff60005358585860206000a3",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9831",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00003004000000000000800000000010000008000000000000000980000000000000000000000000000000000000000000001000000400000000000800000000",
+ "data" : "0xff00000000000000000000000000000000000000000000000000000000000000",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000007",
+ "0000000000000000000000000000000000000000000000000000000000000006",
+ "0000000000000000000000000000000000000000000000000000000000000005"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff60005358585860206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60ff60005358585860206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log3_emptyMem" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x60006000600060006000a3",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9867",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x60006000600060006000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log3_logMemStartTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa3",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log3_logMemsizeTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a3",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log3_logMemsizeZero" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060006001a3",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9863",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060006001a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060006001a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log3_nonEmptyMem" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260006000600060206000a3",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9831",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260006000600060206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260006000600060206000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log3_nonEmptyMem_logMemSize1" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060016000a3",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9862",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xaa",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060016000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060016000a3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log3_nonEmptyMem_logMemSize1_logMemStart31" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060006001601fa3",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9862",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xdd",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060006001601fa3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000526000600060006001601fa3",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log4_Caller" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "10000",
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log4_MaxTopic" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a4",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9798",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000200000800000000000000000000000000000000880000000000000000000000000000000000000000000000010000000000000000000000020",
+ "data" : "0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd",
+ "topics" : [
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd6000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60206000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log4_PC" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "10000",
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log4_emptyMem" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x600060006000600060006000a4",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9834",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600060006000600060006000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x600060006000600060006000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log4_logMemStartTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa4",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log4_logMemsizeTooHigh" : {
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a4",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log4_logMemsizeZero" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060006001a4",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9830",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0x",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060006001a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060006001a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log4_nonEmptyMem" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060006000600060206000a4",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9798",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060006000600060206000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600052600060006000600060206000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log4_nonEmptyMem_logMemSize1" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060016000a4",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9829",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xaa",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060016000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd600052600060006000600060016000a4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log4_nonEmptyMem_logMemSize1_logMemStart31" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060006001601fa4",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9829",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000020000000000002000000000000000000080000000000000000000000000000000000",
+ "data" : "0xdd",
+ "topics" : [
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060006001601fa4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7faabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd60005260006000600060006001601fa4",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
+ "log_2logs" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000a060106002a0",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9880",
+ "logs" : [
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ },
+ {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "bloom" : "00000000000000000000800000000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000",
+ "data" : "0xffffffffffffffffffffffffffffffff",
+ "topics" : [
+ ]
+ }
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000a060106002a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260206000a060106002a0",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/files/VMTests/vmPushDupSwapTest.json b/tests/files/VMTests/vmPushDupSwapTest.json
index 873f95061..9c69aed80 100644
--- a/tests/files/VMTests/vmPushDupSwapTest.json
+++ b/tests/files/VMTests/vmPushDupSwapTest.json
@@ -21,6 +21,8 @@
"value" : "1000000000000000000"
},
"gas" : "9697",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -64,6 +66,8 @@
"value" : "1000000000000000000"
},
"gas" : "9688",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -107,6 +111,8 @@
"value" : "1000000000000000000"
},
"gas" : "9687",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -150,6 +156,8 @@
"value" : "1000000000000000000"
},
"gas" : "9686",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -193,6 +201,8 @@
"value" : "1000000000000000000"
},
"gas" : "9685",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -236,6 +246,8 @@
"value" : "1000000000000000000"
},
"gas" : "9684",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -279,6 +291,8 @@
"value" : "1000000000000000000"
},
"gas" : "9683",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -322,6 +336,8 @@
"value" : "1000000000000000000"
},
"gas" : "9682",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -365,6 +381,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -387,8 +405,6 @@
}
},
"dup2error" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -407,17 +423,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x7f10112233445566778899aabbccddeeff00112233445566778899aabbccddeeff81600355",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
@@ -450,6 +455,8 @@
"value" : "1000000000000000000"
},
"gas" : "9695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -493,6 +500,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -536,6 +545,8 @@
"value" : "1000000000000000000"
},
"gas" : "9693",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -579,6 +590,8 @@
"value" : "1000000000000000000"
},
"gas" : "9692",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -622,6 +635,8 @@
"value" : "1000000000000000000"
},
"gas" : "9691",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -665,6 +680,8 @@
"value" : "1000000000000000000"
},
"gas" : "9690",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -708,6 +725,8 @@
"value" : "1000000000000000000"
},
"gas" : "9689",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -751,6 +770,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -794,6 +815,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -837,6 +860,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -880,6 +905,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -923,6 +950,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -966,6 +995,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1009,6 +1040,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1052,6 +1085,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1095,6 +1130,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1138,6 +1175,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1181,6 +1220,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1224,6 +1265,8 @@
"value" : "1000000000000000000"
},
"gas" : "9999",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1266,6 +1309,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1309,6 +1354,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1352,6 +1399,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1395,6 +1444,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1438,6 +1489,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1481,6 +1534,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1524,6 +1579,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1567,6 +1624,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1610,6 +1669,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1653,6 +1714,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1696,6 +1759,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1739,6 +1804,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1782,6 +1849,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1825,6 +1894,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1868,6 +1939,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1889,7 +1962,7 @@
}
}
},
- "push32error" : {
+ "push32AndSuicide" : {
"callcreates" : [
],
"env" : {
@@ -1911,6 +1984,8 @@
"value" : "1000000000000000000"
},
"gas" : "9999",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"bbccddeeff00112233445566778899aabbccddee" : {
@@ -1931,6 +2006,50 @@
}
}
},
+ "push32FillUpInputWithZerosAtTheEnd" : {
+ "callcreates" : [
+ ],
+ "env" : {
+ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
+ "currentDifficulty" : "256",
+ "currentGasLimit" : "1000000",
+ "currentNumber" : "0",
+ "currentTimestamp" : "1",
+ "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
+ },
+ "exec" : {
+ "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
+ "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "code" : "0x7fff10112233445566778899aabbccddeeff00112233445566778899aabbccdd",
+ "data" : "0x",
+ "gas" : "10000",
+ "gasPrice" : "100000000000000",
+ "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
+ "value" : "1000000000000000000"
+ },
+ "gas" : "9999",
+ "logs" : [
+ ],
+ "out" : "0x",
+ "post" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fff10112233445566778899aabbccddeeff00112233445566778899aabbccdd",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ },
+ "pre" : {
+ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
+ "balance" : "1000000000000000000",
+ "code" : "0x7fff10112233445566778899aabbccddeeff00112233445566778899aabbccdd",
+ "nonce" : "0",
+ "storage" : {
+ }
+ }
+ }
+ },
"push4" : {
"callcreates" : [
],
@@ -1953,6 +2072,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -1996,6 +2117,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2039,6 +2162,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2082,6 +2207,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2125,6 +2252,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2168,6 +2297,8 @@
"value" : "1000000000000000000"
},
"gas" : "9698",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2211,6 +2342,8 @@
"value" : "1000000000000000000"
},
"gas" : "9697",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2254,6 +2387,8 @@
"value" : "1000000000000000000"
},
"gas" : "9688",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2297,6 +2432,8 @@
"value" : "1000000000000000000"
},
"gas" : "9687",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2340,6 +2477,8 @@
"value" : "1000000000000000000"
},
"gas" : "9686",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2383,6 +2522,8 @@
"value" : "1000000000000000000"
},
"gas" : "9685",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2426,6 +2567,8 @@
"value" : "1000000000000000000"
},
"gas" : "9684",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2469,6 +2612,8 @@
"value" : "1000000000000000000"
},
"gas" : "9683",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2512,6 +2657,8 @@
"value" : "1000000000000000000"
},
"gas" : "9682",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2555,6 +2702,8 @@
"value" : "1000000000000000000"
},
"gas" : "9696",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2577,8 +2726,6 @@
}
},
"swap2error" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -2597,17 +2744,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x7f10112233445566778899aabbccddeeff00112233445566778899aabbccddeeff60039155",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
@@ -2640,6 +2776,8 @@
"value" : "1000000000000000000"
},
"gas" : "9695",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2683,6 +2821,8 @@
"value" : "1000000000000000000"
},
"gas" : "9694",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2726,6 +2866,8 @@
"value" : "1000000000000000000"
},
"gas" : "9693",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2769,6 +2911,8 @@
"value" : "1000000000000000000"
},
"gas" : "9692",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2812,6 +2956,8 @@
"value" : "1000000000000000000"
},
"gas" : "9691",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2855,6 +3001,8 @@
"value" : "1000000000000000000"
},
"gas" : "9690",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -2898,6 +3046,8 @@
"value" : "1000000000000000000"
},
"gas" : "9689",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
diff --git a/tests/files/VMTests/vmSha3Test.json b/tests/files/VMTests/vmSha3Test.json
index 7723cde5d..b9e6b46a1 100644
--- a/tests/files/VMTests/vmSha3Test.json
+++ b/tests/files/VMTests/vmSha3Test.json
@@ -20,7 +20,9 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "99999999677",
+ "gas" : "99999999687",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -64,6 +66,8 @@
"value" : "1000000000000000000"
},
"gas" : "9676",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -107,6 +111,8 @@
"value" : "1000000000000000000"
},
"gas" : "9676",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -129,8 +135,6 @@
}
},
"sha3_3" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -149,17 +153,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x620fffff6103e820600055",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
@@ -171,8 +164,6 @@
}
},
"sha3_4" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -191,17 +182,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x6064640fffffffff20600055",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
@@ -213,8 +193,6 @@
}
},
"sha3_5" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -233,17 +211,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x640fffffffff61271020600055",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
@@ -255,8 +222,6 @@
}
},
"sha3_6" : {
- "callcreates" : [
- ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
@@ -275,17 +240,6 @@
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
- "gas" : "0",
- "out" : "0x",
- "post" : {
- "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
- "balance" : "1000000000000000000",
- "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20600055",
- "nonce" : "0",
- "storage" : {
- }
- }
- },
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
diff --git a/tests/files/VMTests/vmtests.json b/tests/files/VMTests/vmtests.json
index bdaee2bd2..e1d73ee5d 100644
--- a/tests/files/VMTests/vmtests.json
+++ b/tests/files/VMTests/vmtests.json
@@ -27,6 +27,8 @@
"value" : "1000000000000000000"
},
"gas" : "9949",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -93,6 +95,8 @@
"value" : "1000000000000000000"
},
"gas" : "9824",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -141,6 +145,8 @@
"value" : "1000000000000000000"
},
"gas" : "9971",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
@@ -183,6 +189,8 @@
"value" : "1000000000000000000"
},
"gas" : "9999",
+ "logs" : [
+ ],
"out" : "0x",
"post" : {
"cd1722f3947def4cf144679da39c4c32bdc35681" : {
diff --git a/tests/files/index.js b/tests/files/index.js
index a19fc2978..34a03d8b2 100644
--- a/tests/files/index.js
+++ b/tests/files/index.js
@@ -8,17 +8,25 @@ module.exports = {
trietestnextprev: require('./TrieTests/trietestnextprev'),
txtest: require('./BasicTests/txtest'),
StateTests: {
+ stExample: require('./StateTests/stExample.json'),
+ stInitCodeTest: require('./StateTests/stInitCodeTest.json'),
+ stLogTests: require('./StateTests/stLogTests.json'),
stPreCompiledContracts: require('./StateTests/stPreCompiledContracts'),
+ stRecursiveCreate: require('./StateTests/stRecursiveCreate'),
+ stSpecial: require('./StateTests/stSpecialTest'),
stSystemOperationsTest: require('./StateTests/stSystemOperationsTest'),
+ stTransactionTest: require('./StateTests/stTransactionTest')
},
VMTests: {
+ vmRandom: require('./VMTests/RandomTests/randomTest'),
vmArithmeticTest: require('./VMTests/vmArithmeticTest'),
vmBitwiseLogicOperationTest: require('./VMTests/vmBitwiseLogicOperationTest'),
vmBlockInfoTest: require('./VMTests/vmBlockInfoTest'),
vmEnvironmentalInfoTest: require('./VMTests/vmEnvironmentalInfoTest'),
vmIOandFlowOperationsTest: require('./VMTests/vmIOandFlowOperationsTest'),
+ vmLogTest: require('./VMTests/vmLogTest'),
vmPushDupSwapTest: require('./VMTests/vmPushDupSwapTest'),
vmSha3Test: require('./VMTests/vmSha3Test'),
- vmtestst: require('./VMTests/vmtests'),
+ vmtests: require('./VMTests/vmtests')
}
};
diff --git a/tests/helper/vm.go b/tests/helper/vm.go
index 270fe5470..e174e0892 100644
--- a/tests/helper/vm.go
+++ b/tests/helper/vm.go
@@ -3,13 +3,18 @@ package helper
import (
"math/big"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm"
)
type Env struct {
- state *state.State
+ depth int
+ state *state.StateDB
+ skipTransfer bool
+ Gas *big.Int
origin []byte
parent []byte
@@ -19,15 +24,17 @@ type Env struct {
time int64
difficulty *big.Int
gasLimit *big.Int
+
+ logs state.Logs
}
-func NewEnv(state *state.State) *Env {
+func NewEnv(state *state.StateDB) *Env {
return &Env{
state: state,
}
}
-func NewEnvFromMap(state *state.State, envValues map[string]string, exeValues map[string]string) *Env {
+func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env {
env := NewEnv(state)
env.origin = ethutil.Hex2Bytes(exeValues["caller"])
@@ -37,6 +44,7 @@ func NewEnvFromMap(state *state.State, envValues map[string]string, exeValues ma
env.time = ethutil.Big(envValues["currentTimestamp"]).Int64()
env.difficulty = ethutil.Big(envValues["currentDifficulty"])
env.gasLimit = ethutil.Big(envValues["currentGasLimit"])
+ env.Gas = new(big.Int)
return env
}
@@ -48,21 +56,101 @@ func (self *Env) Coinbase() []byte { return self.coinbase }
func (self *Env) Time() int64 { return self.time }
func (self *Env) Difficulty() *big.Int { return self.difficulty }
func (self *Env) BlockHash() []byte { return nil }
-func (self *Env) State() *state.State { return self.state }
+func (self *Env) State() *state.StateDB { return self.state }
func (self *Env) GasLimit() *big.Int { return self.gasLimit }
-func (self *Env) AddLog(*state.Log) {}
+func (self *Env) AddLog(log state.Log) {
+ self.logs = append(self.logs, log)
+}
+func (self *Env) Depth() int { return self.depth }
+func (self *Env) SetDepth(i int) { self.depth = i }
func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error {
return vm.Transfer(from, to, amount)
}
-func RunVm(state *state.State, env, exec map[string]string) ([]byte, *big.Int, error) {
- address := FromHex(exec["address"])
- caller := state.GetOrNewStateObject(FromHex(exec["caller"]))
+func (self *Env) vm(addr, data []byte, gas, price, value *big.Int) *core.Execution {
+ exec := core.NewExecution(self, addr, data, gas, price, value)
+ exec.SkipTransfer = self.skipTransfer
+
+ return exec
+}
+
+func (self *Env) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(addr, data, gas, price, value)
+ ret, err := exe.Call(addr, caller)
+ self.Gas = exe.Gas
+
+ return ret, err
+}
+func (self *Env) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(caller.Address(), data, gas, price, value)
+ return exe.Call(addr, caller)
+}
+
+func (self *Env) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
+ exe := self.vm(addr, data, gas, price, value)
+ return exe.Create(caller)
+}
+
+func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
+ var (
+ to = FromHex(exec["address"])
+ from = FromHex(exec["caller"])
+ data = FromHex(exec["data"])
+ gas = ethutil.Big(exec["gas"])
+ price = ethutil.Big(exec["gasPrice"])
+ value = ethutil.Big(exec["value"])
+ )
- evm := vm.New(NewEnvFromMap(state, env, exec), vm.DebugVmTy)
- execution := vm.NewExecution(evm, address, FromHex(exec["data"]), ethutil.Big(exec["gas"]), ethutil.Big(exec["gasPrice"]), ethutil.Big(exec["value"]))
- execution.SkipTransfer = true
- ret, err := execution.Exec(address, caller)
+ caller := state.GetOrNewStateObject(from)
- return ret, execution.Gas, err
+ vmenv := NewEnvFromMap(state, env, exec)
+ vmenv.skipTransfer = true
+ ret, err := vmenv.Call(caller, to, data, gas, price, value)
+
+ return ret, vmenv.logs, vmenv.Gas, err
+}
+
+func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) {
+ var (
+ keyPair, _ = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(tx["secretKey"])))
+ to = FromHex(tx["to"])
+ data = FromHex(tx["data"])
+ gas = ethutil.Big(tx["gasLimit"])
+ price = ethutil.Big(tx["gasPrice"])
+ value = ethutil.Big(tx["value"])
+ caddr = FromHex(env["currentCoinbase"])
+ )
+
+ coinbase := statedb.GetOrNewStateObject(caddr)
+ coinbase.SetGasPool(ethutil.Big(env["currentGasLimit"]))
+
+ message := NewMessage(keyPair.Address(), to, data, value, gas, price)
+ Log.DebugDetailf("message{ to: %x, from %x, value: %v, gas: %v, price: %v }\n", message.to[:4], message.from[:4], message.value, message.gas, message.price)
+ st := core.NewStateTransition(coinbase, message, statedb, nil)
+ vmenv := NewEnvFromMap(statedb, env, tx)
+ vmenv.origin = keyPair.Address()
+ st.Env = vmenv
+ ret, err := st.TransitionState()
+ statedb.Update(vmenv.Gas)
+
+ return ret, vmenv.logs, vmenv.Gas, err
}
+
+type Message struct {
+ from, to []byte
+ value, gas, price *big.Int
+ data []byte
+}
+
+func NewMessage(from, to, data []byte, value, gas, price *big.Int) Message {
+ return Message{from, to, value, gas, price, data}
+}
+
+func (self Message) Hash() []byte { return nil }
+func (self Message) From() []byte { return self.from }
+func (self Message) To() []byte { return self.to }
+func (self Message) GasPrice() *big.Int { return self.price }
+func (self Message) Gas() *big.Int { return self.gas }
+func (self Message) Value() *big.Int { return self.value }
+func (self Message) Nonce() uint64 { return 0 }
+func (self Message) Data() []byte { return self.data }
diff --git a/tests/vm/gh_test.go b/tests/vm/gh_test.go
index e25ccb550..1efda7fe0 100644
--- a/tests/vm/gh_test.go
+++ b/tests/vm/gh_test.go
@@ -1,135 +1,238 @@
package vm
-// import (
-// "bytes"
-// "testing"
-
-// "github.com/ethereum/go-ethereum/ethutil"
-// "github.com/ethereum/go-ethereum/state"
-// "github.com/ethereum/go-ethereum/tests/helper"
-// )
-
-// type Account struct {
-// Balance string
-// Code string
-// Nonce string
-// Storage map[string]string
-// }
-
-// func StateObjectFromAccount(addr string, account Account) *state.StateObject {
-// obj := state.NewStateObject(ethutil.Hex2Bytes(addr))
-// obj.SetBalance(ethutil.Big(account.Balance))
-
-// if ethutil.IsHex(account.Code) {
-// account.Code = account.Code[2:]
-// }
-// obj.Code = ethutil.Hex2Bytes(account.Code)
-// obj.Nonce = ethutil.Big(account.Nonce).Uint64()
-
-// return obj
-// }
-
-// type VmTest struct {
-// Callcreates interface{}
-// Env map[string]string
-// Exec map[string]string
-// Gas string
-// Out string
-// Post map[string]Account
-// Pre map[string]Account
-// }
-
-// func RunVmTest(p string, t *testing.T) {
-// tests := make(map[string]VmTest)
-// helper.CreateFileTests(t, p, &tests)
-
-// for name, test := range tests {
-// state := state.New(helper.NewTrie())
-// for addr, account := range test.Pre {
-// obj := StateObjectFromAccount(addr, account)
-// state.SetStateObject(obj)
-// }
-
-// ret, gas, err := helper.RunVm(state, test.Env, test.Exec)
-// // When an error is returned it doesn't always mean the tests fails.
-// // Have to come up with some conditional failing mechanism.
-// if err != nil {
-// t.Errorf("%s", err)
-// helper.Log.Infoln(err)
-// }
-
-// rexp := helper.FromHex(test.Out)
-// if bytes.Compare(rexp, ret) != 0 {
-// t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
-// }
-
-// gexp := ethutil.Big(test.Gas)
-// if gexp.Cmp(gas) != 0 {
-// t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas)
-// }
-
-// for addr, account := range test.Post {
-// obj := state.GetStateObject(helper.FromHex(addr))
-// for addr, value := range account.Storage {
-// v := obj.GetState(helper.FromHex(addr)).Bytes()
-// vexp := helper.FromHex(value)
-
-// if bytes.Compare(v, vexp) != 0 {
-// t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address()[0:4], addr, vexp, v, ethutil.BigD(vexp), ethutil.BigD(v))
-// }
-// }
-// }
-// }
-// }
-
-// // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail.
-// func TestVMArithmetic(t *testing.T) {
-// //helper.Logger.SetLogLevel(5)
-// const fn = "../files/vmtests/vmArithmeticTest.json"
-// RunVmTest(fn, t)
-// }
-
-// /*
-// deleted?
-// func TestVMSystemOperation(t *testing.T) {
-// helper.Logger.SetLogLevel(5)
-// const fn = "../files/vmtests/vmSystemOperationsTest.json"
-// RunVmTest(fn, t)
-// }
-// */
-
-// func TestBitwiseLogicOperation(t *testing.T) {
-// const fn = "../files/vmtests/vmBitwiseLogicOperationTest.json"
-// RunVmTest(fn, t)
-// }
-
-// func TestBlockInfo(t *testing.T) {
-// const fn = "../files/vmtests/vmBlockInfoTest.json"
-// RunVmTest(fn, t)
-// }
-
-// func TestEnvironmentalInfo(t *testing.T) {
-// const fn = "../files/vmtests/vmEnvironmentalInfoTest.json"
-// RunVmTest(fn, t)
-// }
-
-// func TestFlowOperation(t *testing.T) {
-// helper.Logger.SetLogLevel(5)
-// const fn = "../files/vmtests/vmIOandFlowOperationsTest.json"
-// RunVmTest(fn, t)
-// }
-
-// func TestPushDupSwap(t *testing.T) {
-// const fn = "../files/vmtests/vmPushDupSwapTest.json"
-// RunVmTest(fn, t)
-// }
-
-// func TestVMSha3(t *testing.T) {
-// const fn = "../files/vmtests/vmSha3Test.json"
-// RunVmTest(fn, t)
-// }
-
-// func TestVm(t *testing.T) {
-// const fn = "../files/vmtests/vmtests.json"
-// RunVmTest(fn, t)
-// }
+import (
+ "bytes"
+ "math/big"
+ "strconv"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/state"
+ "github.com/ethereum/go-ethereum/tests/helper"
+)
+
+type Account struct {
+ Balance string
+ Code string
+ Nonce string
+ Storage map[string]string
+}
+
+type Log struct {
+ AddressF string `json:"address"`
+ DataF string `json:"data"`
+ TopicsF []string `json:"topics"`
+ BloomF string `json:"bloom"`
+}
+
+func (self Log) Address() []byte { return ethutil.Hex2Bytes(self.AddressF) }
+func (self Log) Data() []byte { return ethutil.Hex2Bytes(self.DataF) }
+func (self Log) RlpData() interface{} { return nil }
+func (self Log) Topics() [][]byte {
+ t := make([][]byte, len(self.TopicsF))
+ for i, topic := range self.TopicsF {
+ t[i] = ethutil.Hex2Bytes(topic)
+ }
+ return t
+}
+
+func StateObjectFromAccount(addr string, account Account) *state.StateObject {
+ obj := state.NewStateObject(ethutil.Hex2Bytes(addr))
+ obj.SetBalance(ethutil.Big(account.Balance))
+
+ if ethutil.IsHex(account.Code) {
+ account.Code = account.Code[2:]
+ }
+ obj.Code = ethutil.Hex2Bytes(account.Code)
+ obj.Nonce = ethutil.Big(account.Nonce).Uint64()
+
+ return obj
+}
+
+type Env struct {
+ CurrentCoinbase string
+ CurrentDifficulty string
+ CurrentGasLimit string
+ CurrentNumber string
+ CurrentTimestamp interface{}
+ PreviousHash string
+}
+
+type VmTest struct {
+ Callcreates interface{}
+ //Env map[string]string
+ Env Env
+ Exec map[string]string
+ Transaction map[string]string
+ Logs []Log
+ Gas string
+ Out string
+ Post map[string]Account
+ Pre map[string]Account
+}
+
+func RunVmTest(p string, t *testing.T) {
+ tests := make(map[string]VmTest)
+ helper.CreateFileTests(t, p, &tests)
+
+ for name, test := range tests {
+ statedb := state.New(helper.NewTrie())
+ for addr, account := range test.Pre {
+ obj := StateObjectFromAccount(addr, account)
+ statedb.SetStateObject(obj)
+ for a, v := range account.Storage {
+ obj.SetState(helper.FromHex(a), ethutil.NewValue(helper.FromHex(v)))
+ }
+ }
+
+ // XXX Yeah, yeah...
+ env := make(map[string]string)
+ env["currentCoinbase"] = test.Env.CurrentCoinbase
+ env["currentDifficulty"] = test.Env.CurrentDifficulty
+ env["currentGasLimit"] = test.Env.CurrentGasLimit
+ env["currentNumber"] = test.Env.CurrentNumber
+ env["previousHash"] = test.Env.PreviousHash
+ if n, ok := test.Env.CurrentTimestamp.(float64); ok {
+ env["currentTimestamp"] = strconv.Itoa(int(n))
+ } else {
+ env["currentTimestamp"] = test.Env.CurrentTimestamp.(string)
+ }
+
+ var (
+ ret []byte
+ gas *big.Int
+ err error
+ logs state.Logs
+ )
+
+ if len(test.Exec) > 0 {
+ ret, logs, gas, err = helper.RunVm(statedb, env, test.Exec)
+ } else {
+ ret, logs, gas, err = helper.RunState(statedb, env, test.Transaction)
+ }
+
+ // When an error is returned it doesn't always mean the tests fails.
+ // Have to come up with some conditional failing mechanism.
+ if err != nil {
+ helper.Log.Infoln(err)
+ }
+
+ rexp := helper.FromHex(test.Out)
+ if bytes.Compare(rexp, ret) != 0 {
+ t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
+ }
+
+ if len(test.Gas) > 0 {
+ gexp := ethutil.Big(test.Gas)
+ if gexp.Cmp(gas) != 0 {
+ t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas)
+ }
+ }
+
+ for addr, account := range test.Post {
+ obj := statedb.GetStateObject(helper.FromHex(addr))
+ if obj == nil {
+ continue
+ }
+
+ if len(test.Exec) == 0 {
+ if obj.Balance().Cmp(ethutil.Big(account.Balance)) != 0 {
+ t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(ethutil.Big(account.Balance), obj.Balance()))
+ }
+ }
+
+ for addr, value := range account.Storage {
+ v := obj.GetState(helper.FromHex(addr)).Bytes()
+ vexp := helper.FromHex(value)
+
+ if bytes.Compare(v, vexp) != 0 {
+ t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address()[0:4], addr, vexp, v, ethutil.BigD(vexp), ethutil.BigD(v))
+ }
+ }
+ }
+
+ if len(test.Logs) > 0 {
+ // Logs within the test itself aren't correct, missing empty fields (32 0s)
+ for i, log := range test.Logs {
+ genBloom := ethutil.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 64)
+ if !bytes.Equal(genBloom, ethutil.Hex2Bytes(log.BloomF)) {
+ t.Errorf("bloom mismatch")
+ }
+ }
+ }
+ }
+ logger.Flush()
+}
+
+// I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail.
+func TestVMArithmetic(t *testing.T) {
+ const fn = "../files/vmtests/vmArithmeticTest.json"
+ RunVmTest(fn, t)
+}
+
+func TestBitwiseLogicOperation(t *testing.T) {
+ const fn = "../files/vmtests/vmBitwiseLogicOperationTest.json"
+ RunVmTest(fn, t)
+}
+
+func TestBlockInfo(t *testing.T) {
+ const fn = "../files/vmtests/vmBlockInfoTest.json"
+ RunVmTest(fn, t)
+}
+
+func TestEnvironmentalInfo(t *testing.T) {
+ const fn = "../files/vmtests/vmEnvironmentalInfoTest.json"
+ RunVmTest(fn, t)
+}
+
+func TestFlowOperation(t *testing.T) {
+ const fn = "../files/vmtests/vmIOandFlowOperationsTest.json"
+ RunVmTest(fn, t)
+}
+
+func TestPushDupSwap(t *testing.T) {
+ const fn = "../files/vmtests/vmPushDupSwapTest.json"
+ RunVmTest(fn, t)
+}
+
+func TestVMSha3(t *testing.T) {
+ const fn = "../files/vmtests/vmSha3Test.json"
+ RunVmTest(fn, t)
+}
+
+func TestVm(t *testing.T) {
+ const fn = "../files/vmtests/vmtests.json"
+ RunVmTest(fn, t)
+}
+
+func TestVmLog(t *testing.T) {
+ const fn = "../files/vmtests/vmLogTest.json"
+ RunVmTest(fn, t)
+}
+
+func TestStateSystemOperations(t *testing.T) {
+ const fn = "../files/StateTests/stSystemOperationsTest.json"
+ RunVmTest(fn, t)
+}
+
+func TestStatePreCompiledContracts(t *testing.T) {
+ const fn = "../files/StateTests/stPreCompiledContracts.json"
+ RunVmTest(fn, t)
+}
+
+func TestStateRecursiveCreate(t *testing.T) {
+ const fn = "../files/StateTests/stRecursiveCreate.json"
+ RunVmTest(fn, t)
+}
+
+func TestStateSpecial(t *testing.T) {
+ const fn = "../files/StateTests/stSpecialTest.json"
+ RunVmTest(fn, t)
+}
+
+func TestStateRefund(t *testing.T) {
+ const fn = "../files/StateTests/stRefundTest.json"
+ RunVmTest(fn, t)
+}
diff --git a/ui/filter.go b/ui/filter.go
index 84209861e..88faad5ca 100644
--- a/ui/filter.go
+++ b/ui/filter.go
@@ -1,12 +1,12 @@
package ui
import (
- "github.com/ethereum/go-ethereum/chain"
+ "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/ethutil"
)
-func NewFilterFromMap(object map[string]interface{}, eth chain.EthManager) *chain.Filter {
- filter := chain.NewFilter(eth)
+func NewFilterFromMap(object map[string]interface{}, eth core.EthManager) *core.Filter {
+ filter := core.NewFilter(eth)
if object["earliest"] != nil {
val := ethutil.NewValue(object["earliest"])
@@ -46,7 +46,7 @@ func NewFilterFromMap(object map[string]interface{}, eth chain.EthManager) *chai
}
// Conversion methodn
-func mapToAccountChange(m map[string]interface{}) (d chain.AccountChange) {
+func mapToAccountChange(m map[string]interface{}) (d core.AccountChange) {
if str, ok := m["id"].(string); ok {
d.Address = ethutil.Hex2Bytes(str)
}
@@ -60,9 +60,9 @@ func mapToAccountChange(m map[string]interface{}) (d chain.AccountChange) {
// data can come in in the following formats:
// ["aabbccdd", {id: "ccddee", at: "11223344"}], "aabbcc", {id: "ccddee", at: "1122"}
-func makeAltered(v interface{}) (d []chain.AccountChange) {
+func makeAltered(v interface{}) (d []core.AccountChange) {
if str, ok := v.(string); ok {
- d = append(d, chain.AccountChange{ethutil.Hex2Bytes(str), nil})
+ d = append(d, core.AccountChange{ethutil.Hex2Bytes(str), nil})
} else if obj, ok := v.(map[string]interface{}); ok {
d = append(d, mapToAccountChange(obj))
} else if slice, ok := v.([]interface{}); ok {
diff --git a/ui/qt/filter.go b/ui/qt/filter.go
index 96c3ab3a3..c68936401 100644
--- a/ui/qt/filter.go
+++ b/ui/qt/filter.go
@@ -3,12 +3,12 @@ package qt
import (
"fmt"
- "github.com/ethereum/go-ethereum/chain"
+ "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/ui"
"gopkg.in/qml.v1"
)
-func NewFilterFromMap(object map[string]interface{}, eth chain.EthManager) *chain.Filter {
+func NewFilterFromMap(object map[string]interface{}, eth core.EthManager) *core.Filter {
filter := ui.NewFilterFromMap(object, eth)
if object["altered"] != nil {
@@ -18,7 +18,7 @@ func NewFilterFromMap(object map[string]interface{}, eth chain.EthManager) *chai
return filter
}
-func makeAltered(v interface{}) (d []chain.AccountChange) {
+func makeAltered(v interface{}) (d []core.AccountChange) {
if qList, ok := v.(*qml.List); ok {
var s []interface{}
qList.Convert(&s)
diff --git a/ui/qt/qwhisper/whisper.go b/ui/qt/qwhisper/whisper.go
new file mode 100644
index 000000000..8f05c0695
--- /dev/null
+++ b/ui/qt/qwhisper/whisper.go
@@ -0,0 +1,98 @@
+package qwhisper
+
+import (
+ "fmt"
+ "time"
+ "unsafe"
+
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/whisper"
+ "gopkg.in/qml.v1"
+)
+
+func fromHex(s string) []byte {
+ if len(s) > 1 {
+ return ethutil.Hex2Bytes(s[2:])
+ }
+ return nil
+}
+func toHex(b []byte) string { return "0x" + ethutil.Bytes2Hex(b) }
+
+type Watch struct {
+}
+
+func (self *Watch) Arrived(v unsafe.Pointer) {
+ fmt.Println(v)
+}
+
+type Whisper struct {
+ *whisper.Whisper
+ view qml.Object
+
+ watches map[int]*Watch
+}
+
+func New(w *whisper.Whisper) *Whisper {
+ return &Whisper{w, nil, make(map[int]*Watch)}
+}
+
+func (self *Whisper) SetView(view qml.Object) {
+ self.view = view
+}
+
+func (self *Whisper) Post(data string, to, from string, topics []string, pow, ttl uint32) {
+ msg := whisper.NewMessage(fromHex(data))
+ envelope, err := msg.Seal(time.Duration(pow), whisper.Opts{
+ Ttl: time.Duration(ttl),
+ To: crypto.ToECDSAPub(fromHex(to)),
+ From: crypto.ToECDSA(fromHex(from)),
+ Topics: whisper.TopicsFromString(topics...),
+ })
+ if err != nil {
+ fmt.Println(err)
+ // handle error
+ return
+ }
+
+ if err := self.Whisper.Send(envelope); err != nil {
+ fmt.Println(err)
+ // handle error
+ return
+ }
+}
+
+func (self *Whisper) NewIdentity() string {
+ return toHex(self.Whisper.NewIdentity().D.Bytes())
+}
+
+func (self *Whisper) HasIdentity(key string) bool {
+ return self.Whisper.HasIdentity(crypto.ToECDSA(fromHex(key)))
+}
+
+func (self *Whisper) Watch(opts map[string]interface{}) *Watch {
+ filter := filterFromMap(opts)
+ filter.Fn = func(msg *whisper.Message) {
+ fmt.Println(msg)
+ }
+ i := self.Whisper.Watch(filter)
+ self.watches[i] = &Watch{}
+
+ return self.watches[i]
+}
+
+func filterFromMap(opts map[string]interface{}) (f whisper.Filter) {
+ if to, ok := opts["to"].(string); ok {
+ f.To = crypto.ToECDSA(fromHex(to))
+ }
+ if from, ok := opts["from"].(string); ok {
+ f.From = crypto.ToECDSAPub(fromHex(from))
+ }
+ if topicList, ok := opts["topics"].(*qml.List); ok {
+ var topics []string
+ topicList.Convert(&topics)
+ f.Topics = whisper.TopicsFromString(topics...)
+ }
+
+ return
+}
diff --git a/ui/qt/qwhisper/whisper_test.go b/ui/qt/qwhisper/whisper_test.go
new file mode 100644
index 000000000..efa4e6238
--- /dev/null
+++ b/ui/qt/qwhisper/whisper_test.go
@@ -0,0 +1,15 @@
+package qwhisper
+
+import (
+ "testing"
+
+ "github.com/ethereum/go-ethereum/whisper"
+)
+
+func TestHasIdentity(t *testing.T) {
+ qw := New(whisper.New())
+ id := qw.NewIdentity()
+ if !qw.HasIdentity(id) {
+ t.Error("expected to have identity")
+ }
+}
diff --git a/vm/address.go b/vm/address.go
index 235143b34..611979c94 100644
--- a/vm/address.go
+++ b/vm/address.go
@@ -11,19 +11,29 @@ type Address interface {
Call(in []byte) []byte
}
-type PrecompiledAddress struct {
- Gas *big.Int
+type PrecompiledAccount struct {
+ Gas func(l int) *big.Int
fn func(in []byte) []byte
}
-func (self PrecompiledAddress) Call(in []byte) []byte {
+func (self PrecompiledAccount) Call(in []byte) []byte {
return self.fn(in)
}
-var Precompiled = map[uint64]*PrecompiledAddress{
- 1: &PrecompiledAddress{big.NewInt(500), ecrecoverFunc},
- 2: &PrecompiledAddress{big.NewInt(100), sha256Func},
- 3: &PrecompiledAddress{big.NewInt(100), ripemd160Func},
+var Precompiled = map[string]*PrecompiledAccount{
+ string(ethutil.LeftPadBytes([]byte{1}, 20)): &PrecompiledAccount{func(l int) *big.Int {
+ return GasEcrecover
+ }, ecrecoverFunc},
+ string(ethutil.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
+ n := big.NewInt(int64(l+31)/32 + 1)
+ n.Mul(n, GasSha256)
+ return n
+ }, sha256Func},
+ string(ethutil.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
+ n := big.NewInt(int64(l+31)/32 + 1)
+ n.Mul(n, GasRipemd)
+ return n
+ }, ripemd160Func},
}
func sha256Func(in []byte) []byte {
@@ -31,12 +41,16 @@ func sha256Func(in []byte) []byte {
}
func ripemd160Func(in []byte) []byte {
- return ethutil.RightPadBytes(crypto.Ripemd160(in), 32)
+ return ethutil.LeftPadBytes(crypto.Ripemd160(in), 32)
}
func ecrecoverFunc(in []byte) []byte {
// In case of an invalid sig. Defaults to return nil
defer func() { recover() }()
- return crypto.Ecrecover(in)
+ hash := in[:32]
+ v := ethutil.BigD(in[32:64]).Bytes()[0] - 27
+ sig := append(in[64:], v)
+
+ return ethutil.LeftPadBytes(crypto.Sha3(crypto.Ecrecover(append(hash, sig...))[1:])[12:], 32)
}
diff --git a/vm/analysis.go b/vm/analysis.go
index 52c7143e0..fef448b7b 100644
--- a/vm/analysis.go
+++ b/vm/analysis.go
@@ -6,17 +6,17 @@ import (
"github.com/ethereum/go-ethereum/ethutil"
)
-func analyseJumpDests(code []byte) (dests map[int64]*big.Int) {
- dests = make(map[int64]*big.Int)
+func analyseJumpDests(code []byte) (dests map[uint64]*big.Int) {
+ dests = make(map[uint64]*big.Int)
lp := false
var lpv *big.Int
- for pc := int64(0); pc < int64(len(code)); pc++ {
+ for pc := uint64(0); pc < uint64(len(code)); pc++ {
var op OpCode = OpCode(code[pc])
switch op {
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
- a := int64(op) - int64(PUSH1) + 1
- if int64(len(code)) > pc+1+a {
+ a := uint64(op) - uint64(PUSH1) + 1
+ if uint64(len(code)) > pc+1+a {
lpv = ethutil.BigD(code[pc+1 : pc+1+a])
}
diff --git a/vm/closure.go b/vm/closure.go
index ef9bbca93..97b31ada0 100644
--- a/vm/closure.go
+++ b/vm/closure.go
@@ -1,29 +1,22 @@
package vm
-// TODO Re write VM to use values instead of big integers?
-
import (
"math/big"
- "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
)
type ClosureRef interface {
ReturnGas(*big.Int, *big.Int)
Address() []byte
- Object() *state.StateObject
- GetStorage(*big.Int) *ethutil.Value
- SetStorage(*big.Int, *ethutil.Value)
+ SetCode([]byte)
}
-// Basic inline closure object which implement the 'closure' interface
type Closure struct {
caller ClosureRef
- object *state.StateObject
+ object ClosureRef
Code []byte
message *state.Message
- exe *Execution
Gas, UsedGas, Price *big.Int
@@ -31,7 +24,7 @@ type Closure struct {
}
// Create a new closure for the given data items
-func NewClosure(msg *state.Message, caller ClosureRef, object *state.StateObject, code []byte, gas, price *big.Int) *Closure {
+func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code []byte, gas, price *big.Int) *Closure {
c := &Closure{message: msg, caller: caller, object: object, Code: code, Args: nil}
// Gas should be a pointer so it can safely be reduced through the run
@@ -45,26 +38,12 @@ func NewClosure(msg *state.Message, caller ClosureRef, object *state.StateObject
return c
}
-// Retuns the x element in data slice
-func (c *Closure) GetStorage(x *big.Int) *ethutil.Value {
- m := c.object.GetStorage(x)
- if m == nil {
- return ethutil.EmptyValue()
- }
-
- return m
-}
-
-func (c *Closure) Get(x *big.Int) *ethutil.Value {
- return c.Gets(x, big.NewInt(1))
-}
-
-func (c *Closure) GetOp(x int) OpCode {
+func (c *Closure) GetOp(x uint64) OpCode {
return OpCode(c.GetByte(x))
}
-func (c *Closure) GetByte(x int) byte {
- if x < len(c.Code) {
+func (c *Closure) GetByte(x uint64) byte {
+ if x < uint64(len(c.Code)) {
return c.Code[x]
}
@@ -79,30 +58,12 @@ func (c *Closure) GetBytes(x, y int) []byte {
return c.Code[x : x+y]
}
-func (c *Closure) Gets(x, y *big.Int) *ethutil.Value {
- if x.Int64() >= int64(len(c.Code)) || y.Int64() >= int64(len(c.Code)) {
- return ethutil.NewValue(0)
+func (c *Closure) GetRangeValue(x, y uint64) []byte {
+ if x >= uint64(len(c.Code)) || y >= uint64(len(c.Code)) {
+ return nil
}
- partial := c.Code[x.Int64() : x.Int64()+y.Int64()]
-
- return ethutil.NewValue(partial)
-}
-
-func (c *Closure) SetStorage(x *big.Int, val *ethutil.Value) {
- c.object.SetStorage(x, val)
-}
-
-func (c *Closure) Address() []byte {
- return c.object.Address()
-}
-
-func (c *Closure) Call(vm VirtualMachine, args []byte) ([]byte, *big.Int, error) {
- c.Args = args
-
- ret, err := vm.RunClosure(c)
-
- return ret, c.UsedGas, err
+ return c.Code[x : x+y]
}
func (c *Closure) Return(ret []byte) []byte {
@@ -112,6 +73,9 @@ func (c *Closure) Return(ret []byte) []byte {
return ret
}
+/*
+ * Gas functions
+ */
func (c *Closure) UseGas(gas *big.Int) bool {
if c.Gas.Cmp(gas) < 0 {
return false
@@ -131,14 +95,13 @@ func (c *Closure) ReturnGas(gas, price *big.Int) {
c.UsedGas.Sub(c.UsedGas, gas)
}
-func (c *Closure) Object() *state.StateObject {
- return c.object
-}
-
-func (c *Closure) Caller() ClosureRef {
- return c.caller
+/*
+ * Set / Get
+ */
+func (c *Closure) Address() []byte {
+ return c.object.Address()
}
-func (self *Closure) SetExecution(exe *Execution) {
- self.exe = exe
+func (self *Closure) SetCode(code []byte) {
+ self.Code = code
}
diff --git a/vm/common.go b/vm/common.go
index 9514ff6d3..529bbdeb1 100644
--- a/vm/common.go
+++ b/vm/common.go
@@ -20,17 +20,24 @@ const (
var (
GasStep = big.NewInt(1)
- GasSha = big.NewInt(20)
+ GasSha = big.NewInt(10)
GasSLoad = big.NewInt(20)
GasSStore = big.NewInt(100)
GasSStoreRefund = big.NewInt(100)
GasBalance = big.NewInt(20)
GasCreate = big.NewInt(100)
GasCall = big.NewInt(20)
+ GasCreateByte = big.NewInt(5)
+ GasSha3Byte = big.NewInt(10)
+ GasSha256Byte = big.NewInt(50)
+ GasRipemdByte = big.NewInt(50)
GasMemory = big.NewInt(1)
GasData = big.NewInt(5)
GasTx = big.NewInt(500)
GasLog = big.NewInt(32)
+ GasSha256 = big.NewInt(50)
+ GasRipemd = big.NewInt(50)
+ GasEcrecover = big.NewInt(500)
Pow256 = ethutil.BigPow(2, 256)
@@ -41,7 +48,7 @@ var (
S256 = ethutil.S256
)
-const MaxCallDepth = 1025
+const MaxCallDepth = 1024
func calcMemSize(off, l *big.Int) *big.Int {
if l.Cmp(ethutil.Big0) == 0 {
diff --git a/vm/environment.go b/vm/environment.go
index 5604989e1..d77fb1419 100644
--- a/vm/environment.go
+++ b/vm/environment.go
@@ -9,7 +9,7 @@ import (
)
type Environment interface {
- State() *state.State
+ State() *state.StateDB
Origin() []byte
BlockNumber() *big.Int
@@ -20,7 +20,14 @@ type Environment interface {
BlockHash() []byte
GasLimit() *big.Int
Transfer(from, to Account, amount *big.Int) error
- AddLog(*state.Log)
+ AddLog(state.Log)
+
+ Depth() int
+ SetDepth(i int)
+
+ Call(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
+ CallCode(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
+ Create(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, ClosureRef)
}
type Object interface {
@@ -43,9 +50,27 @@ func Transfer(from, to Account, amount *big.Int) error {
from.SubBalance(amount)
to.AddBalance(amount)
- // Add default LOG. Default = big(sender.addr) + 1
- //addr := ethutil.BigD(receiver.Address())
- //tx.addLog(vm.Log{sender.Address(), [][]byte{ethutil.U256(addr.Add(addr, ethutil.Big1)).Bytes()}, nil})
-
return nil
}
+
+type Log struct {
+ address []byte
+ topics [][]byte
+ data []byte
+}
+
+func (self *Log) Address() []byte {
+ return self.address
+}
+
+func (self *Log) Topics() [][]byte {
+ return self.topics
+}
+
+func (self *Log) Data() []byte {
+ return self.data
+}
+
+func (self *Log) RlpData() interface{} {
+ return []interface{}{self.address, ethutil.ByteSliceToInterface(self.topics), self.data}
+}
diff --git a/vm/execution.go b/vm/execution.go
deleted file mode 100644
index c23164f82..000000000
--- a/vm/execution.go
+++ /dev/null
@@ -1,95 +0,0 @@
-package vm
-
-import (
- "fmt"
- "math/big"
-
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/state"
-)
-
-type Execution struct {
- vm VirtualMachine
- address, input []byte
- Gas, price, value *big.Int
- object *state.StateObject
- SkipTransfer bool
-}
-
-func NewExecution(vm VirtualMachine, address, input []byte, gas, gasPrice, value *big.Int) *Execution {
- return &Execution{vm: vm, address: address, input: input, Gas: gas, price: gasPrice, value: value}
-}
-
-func (self *Execution) Addr() []byte {
- return self.address
-}
-
-func (self *Execution) Exec(codeAddr []byte, caller ClosureRef) ([]byte, error) {
- // Retrieve the executing code
- code := self.vm.Env().State().GetCode(codeAddr)
-
- return self.exec(code, codeAddr, caller)
-}
-
-func (self *Execution) exec(code, caddr []byte, caller ClosureRef) (ret []byte, err error) {
- env := self.vm.Env()
-
- vmlogger.Debugf("pre state %x\n", env.State().Root())
- snapshot := env.State().Copy()
- defer func() {
- if IsDepthErr(err) || IsOOGErr(err) {
- env.State().Set(snapshot)
- }
- vmlogger.Debugf("post state %x\n", env.State().Root())
- }()
-
- msg := env.State().Manifest().AddMessage(&state.Message{
- To: self.address, From: caller.Address(),
- Input: self.input,
- Origin: env.Origin(),
- Block: env.BlockHash(), Timestamp: env.Time(), Coinbase: env.Coinbase(), Number: env.BlockNumber(),
- Value: self.value,
- })
-
- from, to := caller.Object(), env.State().GetOrNewStateObject(self.address)
- // Skipping transfer is used on testing for the initial call
- if !self.SkipTransfer {
- err = env.Transfer(from, to, self.value)
- }
-
- if err != nil {
- caller.ReturnGas(self.Gas, self.price)
-
- err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, from.Balance)
- } else {
- self.object = to
- // Pre-compiled contracts (address.go) 1, 2 & 3.
- naddr := ethutil.BigD(caddr).Uint64()
- if p := Precompiled[naddr]; p != nil {
- if self.Gas.Cmp(p.Gas) >= 0 {
- ret = p.Call(self.input)
- self.vm.Printf("NATIVE_FUNC(%x) => %x", naddr, ret)
- }
- } else {
- // Create a new callable closure
- c := NewClosure(msg, caller, to, code, self.Gas, self.price)
- c.exe = self
-
- if self.vm.Depth() == MaxCallDepth {
- c.UseGas(self.Gas)
-
- return c.Return(nil), DepthError{}
- }
-
- // Executer the closure and get the return value (if any)
- ret, _, err = c.Call(self.vm, self.input)
- msg.Output = ret
- }
- }
-
- return
-}
-
-func (self *Execution) Create(caller ClosureRef) (ret []byte, err error) {
- return self.exec(self.input, nil, caller)
-}
diff --git a/vm/stack.go b/vm/stack.go
index 2eca60ad1..6091479cb 100644
--- a/vm/stack.go
+++ b/vm/stack.go
@@ -111,10 +111,10 @@ func NewMemory() *Memory {
return &Memory{nil}
}
-func (m *Memory) Set(offset, size int64, value []byte) {
+func (m *Memory) Set(offset, size uint64, value []byte) {
if len(value) > 0 {
totSize := offset + size
- lenSize := int64(len(m.store) - 1)
+ lenSize := uint64(len(m.store) - 1)
if totSize > lenSize {
// Calculate the diff between the sizes
diff := totSize - lenSize
@@ -147,9 +147,8 @@ func (m *Memory) Get(offset, size int64) []byte {
func (self *Memory) Geti(offset, size int64) (cpy []byte) {
if len(self.store) > int(offset) {
- s := int64(math.Min(float64(len(self.store)), float64(offset+size)))
cpy = make([]byte, size)
- copy(cpy, self.store[offset:offset+s])
+ copy(cpy, self.store[offset:offset+size])
return
}
diff --git a/vm/types.go b/vm/types.go
index 0b20fb655..ec9c7e74e 100644
--- a/vm/types.go
+++ b/vm/types.go
@@ -163,8 +163,8 @@ const (
// 0xf0 range - closures
CREATE OpCode = 0xf0 + iota
CALL
- RETURN
CALLCODE
+ RETURN
// 0x70 range - other
SUICIDE = 0xff
@@ -308,12 +308,11 @@ var opCodeToString = map[OpCode]string{
SWAP14: "SWAP14",
SWAP15: "SWAP15",
SWAP16: "SWAP16",
-
- LOG0: "LOG0",
- LOG1: "LOG1",
- LOG2: "LOG2",
- LOG3: "LOG3",
- LOG4: "LOG4",
+ LOG0: "LOG0",
+ LOG1: "LOG1",
+ LOG2: "LOG2",
+ LOG3: "LOG3",
+ LOG4: "LOG4",
// 0xf0 range
CREATE: "CREATE",
diff --git a/vm/virtual_machine.go b/vm/virtual_machine.go
index cc8cd39a9..3b6f98ab2 100644
--- a/vm/virtual_machine.go
+++ b/vm/virtual_machine.go
@@ -1,9 +1,10 @@
package vm
+import "math/big"
+
type VirtualMachine interface {
Env() Environment
- RunClosure(*Closure) ([]byte, error)
- Depth() int
+ Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, data []byte) ([]byte, error)
Printf(string, ...interface{}) VirtualMachine
Endl() VirtualMachine
}
diff --git a/vm/vm.go b/vm/vm.go
index e1c2d9c14..22172cb3a 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -1,12 +1,6 @@
package vm
-import (
- "fmt"
- "math/big"
-
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethutil"
-)
+import "math/big"
// BIG FAT WARNING. THIS VM IS NOT YET IS USE!
// I want to get all VM tests pass first before updating this VM
@@ -26,686 +20,8 @@ func New(env Environment, typ Type) VirtualMachine {
}
}
-func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
- self.depth++
-
- // Recover from any require exception
- defer func() {
- if r := recover(); r != nil {
- ret = closure.Return(nil)
- err = fmt.Errorf("%v", r)
- }
- }()
-
- // Don't bother with the execution if there's no code.
- if len(closure.Code) == 0 {
- return closure.Return(nil), nil
- }
-
- var (
- op OpCode
-
- mem = &Memory{}
- stack = NewStack()
- pc = 0
- step = 0
- require = func(m int) {
- if stack.Len() < m {
- panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, stack.Len(), m))
- }
- }
- )
-
- for {
- // The base for all big integer arithmetic
- base := new(big.Int)
-
- step++
- // Get the memory location of pc
- op := closure.GetOp(pc)
-
- gas := new(big.Int)
- addStepGasUsage := func(amount *big.Int) {
- gas.Add(gas, amount)
- }
-
- addStepGasUsage(GasStep)
-
- var newMemSize *big.Int = ethutil.Big0
- switch op {
- case STOP:
- gas.Set(ethutil.Big0)
- case SUICIDE:
- gas.Set(ethutil.Big0)
- case SLOAD:
- gas.Set(GasSLoad)
- case SSTORE:
- var mult *big.Int
- y, x := stack.Peekn()
- val := closure.GetStorage(x)
- if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 {
- mult = ethutil.Big2
- } else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 {
- mult = ethutil.Big0
- } else {
- mult = ethutil.Big1
- }
- gas = new(big.Int).Mul(mult, GasSStore)
- case BALANCE:
- gas.Set(GasBalance)
- case MSTORE:
- require(2)
- newMemSize = calcMemSize(stack.Peek(), u256(32))
- case MLOAD:
- require(1)
-
- newMemSize = calcMemSize(stack.Peek(), u256(32))
- case MSTORE8:
- require(2)
- newMemSize = calcMemSize(stack.Peek(), u256(1))
- case RETURN:
- require(2)
-
- newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
- case SHA3:
- require(2)
-
- gas.Set(GasSha)
-
- newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
- case CALLDATACOPY:
- require(2)
-
- newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
- case CODECOPY:
- require(3)
-
- newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
- case EXTCODECOPY:
- require(4)
-
- newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
- case CALL, CALLCODE:
- require(7)
- gas.Set(GasCall)
- addStepGasUsage(stack.data[stack.Len()-1])
-
- x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
- y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
-
- newMemSize = ethutil.BigMax(x, y)
- case CREATE:
- require(3)
- gas.Set(GasCreate)
-
- newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
- }
-
- if newMemSize.Cmp(ethutil.Big0) > 0 {
- newMemSize.Add(newMemSize, u256(31))
- newMemSize.Div(newMemSize, u256(32))
- newMemSize.Mul(newMemSize, u256(32))
-
- if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
- memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
- memGasUsage.Mul(GasMemory, memGasUsage)
- memGasUsage.Div(memGasUsage, u256(32))
-
- addStepGasUsage(memGasUsage)
- }
- }
-
- if !closure.UseGas(gas) {
- err := fmt.Errorf("Insufficient gas for %v. req %v has %v", op, gas, closure.Gas)
-
- closure.UseGas(closure.Gas)
-
- return closure.Return(nil), err
- }
-
- mem.Resize(newMemSize.Uint64())
-
- switch op {
- // 0x20 range
- case ADD:
- require(2)
- x, y := stack.Popn()
-
- base.Add(y, x)
-
- U256(base)
-
- // Pop result back on the stack
- stack.Push(base)
- case SUB:
- require(2)
- x, y := stack.Popn()
-
- base.Sub(y, x)
-
- U256(base)
-
- // Pop result back on the stack
- stack.Push(base)
- case MUL:
- require(2)
- x, y := stack.Popn()
-
- base.Mul(y, x)
-
- U256(base)
-
- // Pop result back on the stack
- stack.Push(base)
- case DIV:
- require(2)
- x, y := stack.Popn()
-
- if x.Cmp(ethutil.Big0) != 0 {
- base.Div(y, x)
- }
-
- U256(base)
-
- // Pop result back on the stack
- stack.Push(base)
- case SDIV:
- require(2)
- y, x := S256(stack.Pop()), S256(stack.Pop())
-
- if x.Cmp(ethutil.Big0) == 0 {
- base.Set(ethutil.Big0)
- } else {
- n := new(big.Int)
- if new(big.Int).Mul(y, x).Cmp(ethutil.Big0) < 0 {
- n.SetInt64(-1)
- } else {
- n.SetInt64(1)
- }
-
- base.Div(y.Abs(y), x.Mul(x.Abs(x), n))
-
- U256(base)
- }
-
- stack.Push(base)
- case MOD:
- require(2)
- x, y := stack.Popn()
-
- base.Mod(y, x)
-
- U256(base)
-
- stack.Push(base)
- case SMOD:
- require(2)
- y, x := S256(stack.Pop()), S256(stack.Pop())
-
- if x.Cmp(ethutil.Big0) == 0 {
- base.Set(ethutil.Big0)
- } else {
- n := new(big.Int)
- if y.Cmp(ethutil.Big0) < 0 {
- n.SetInt64(-1)
- } else {
- n.SetInt64(1)
- }
-
- base.Mod(y.Abs(y), x.Mul(x.Abs(x), n))
-
- U256(base)
- }
-
- stack.Push(base)
-
- case EXP:
- require(2)
- x, y := stack.Popn()
-
- base.Exp(y, x, Pow256)
-
- U256(base)
-
- stack.Push(base)
- case NOT:
- require(1)
- base.Sub(Pow256, stack.Pop())
-
- base = U256(base)
-
- stack.Push(base)
- case LT:
- require(2)
- x, y := stack.Popn()
- // x < y
- if y.Cmp(x) < 0 {
- stack.Push(ethutil.BigTrue)
- } else {
- stack.Push(ethutil.BigFalse)
- }
- case GT:
- require(2)
- x, y := stack.Popn()
-
- // x > y
- if y.Cmp(x) > 0 {
- stack.Push(ethutil.BigTrue)
- } else {
- stack.Push(ethutil.BigFalse)
- }
-
- case SLT:
- require(2)
- y, x := S256(stack.Pop()), S256(stack.Pop())
- // x < y
- if y.Cmp(S256(x)) < 0 {
- stack.Push(ethutil.BigTrue)
- } else {
- stack.Push(ethutil.BigFalse)
- }
- case SGT:
- require(2)
- y, x := S256(stack.Pop()), S256(stack.Pop())
-
- // x > y
- if y.Cmp(x) > 0 {
- stack.Push(ethutil.BigTrue)
- } else {
- stack.Push(ethutil.BigFalse)
- }
-
- case EQ:
- require(2)
- x, y := stack.Popn()
-
- // x == y
- if x.Cmp(y) == 0 {
- stack.Push(ethutil.BigTrue)
- } else {
- stack.Push(ethutil.BigFalse)
- }
- case ISZERO:
- require(1)
- x := stack.Pop()
- if x.Cmp(ethutil.BigFalse) > 0 {
- stack.Push(ethutil.BigFalse)
- } else {
- stack.Push(ethutil.BigTrue)
- }
-
- // 0x10 range
- case AND:
- require(2)
- x, y := stack.Popn()
-
- stack.Push(base.And(y, x))
- case OR:
- require(2)
- x, y := stack.Popn()
-
- stack.Push(base.Or(y, x))
- case XOR:
- require(2)
- x, y := stack.Popn()
-
- stack.Push(base.Xor(y, x))
- case BYTE:
- require(2)
- val, th := stack.Popn()
- if th.Cmp(big.NewInt(32)) < 0 && th.Cmp(big.NewInt(int64(len(val.Bytes())))) < 0 {
- byt := big.NewInt(int64(ethutil.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
- stack.Push(byt)
-
- } else {
- stack.Push(ethutil.BigFalse)
- }
- case ADDMOD:
- require(3)
-
- x := stack.Pop()
- y := stack.Pop()
- z := stack.Pop()
-
- base.Add(x, y)
- base.Mod(base, z)
-
- U256(base)
-
- stack.Push(base)
- case MULMOD:
- require(3)
-
- x := stack.Pop()
- y := stack.Pop()
- z := stack.Pop()
-
- base.Mul(x, y)
- base.Mod(base, z)
-
- U256(base)
-
- stack.Push(base)
-
- // 0x20 range
- case SHA3:
- require(2)
- size, offset := stack.Popn()
- data := crypto.Sha3(mem.Get(offset.Int64(), size.Int64()))
-
- stack.Push(ethutil.BigD(data))
-
- // 0x30 range
- case ADDRESS:
- stack.Push(ethutil.BigD(closure.Address()))
-
- case BALANCE:
- require(1)
-
- addr := stack.Pop().Bytes()
- balance := self.env.State().GetBalance(addr)
-
- stack.Push(balance)
-
- case ORIGIN:
- origin := self.env.Origin()
-
- stack.Push(ethutil.BigD(origin))
-
- case CALLER:
- caller := closure.caller.Address()
- stack.Push(ethutil.BigD(caller))
-
- case CALLVALUE:
- value := closure.exe.value
-
- stack.Push(value)
-
- case CALLDATALOAD:
- require(1)
- var (
- offset = stack.Pop()
- data = make([]byte, 32)
- lenData = big.NewInt(int64(len(closure.Args)))
- )
-
- if lenData.Cmp(offset) >= 0 {
- length := new(big.Int).Add(offset, ethutil.Big32)
- length = ethutil.BigMin(length, lenData)
-
- copy(data, closure.Args[offset.Int64():length.Int64()])
- }
-
- stack.Push(ethutil.BigD(data))
- case CALLDATASIZE:
- l := int64(len(closure.Args))
- stack.Push(big.NewInt(l))
-
- case CALLDATACOPY:
- var (
- size = int64(len(closure.Args))
- mOff = stack.Pop().Int64()
- cOff = stack.Pop().Int64()
- l = stack.Pop().Int64()
- )
-
- if cOff > size {
- cOff = 0
- l = 0
- } else if cOff+l > size {
- l = 0
- }
-
- code := closure.Args[cOff : cOff+l]
-
- mem.Set(mOff, l, code)
- case CODESIZE, EXTCODESIZE:
- var code []byte
- if op == EXTCODECOPY {
- addr := stack.Pop().Bytes()
-
- code = self.env.State().GetCode(addr)
- } else {
- code = closure.Code
- }
-
- l := big.NewInt(int64(len(code)))
- stack.Push(l)
-
- case CODECOPY, EXTCODECOPY:
- var code []byte
- if op == EXTCODECOPY {
- addr := stack.Pop().Bytes()
-
- code = self.env.State().GetCode(addr)
- } else {
- code = closure.Code
- }
-
- var (
- size = int64(len(code))
- mOff = stack.Pop().Int64()
- cOff = stack.Pop().Int64()
- l = stack.Pop().Int64()
- )
-
- if cOff > size {
- cOff = 0
- l = 0
- } else if cOff+l > size {
- l = 0
- }
-
- codeCopy := code[cOff : cOff+l]
-
- mem.Set(mOff, l, codeCopy)
- case GASPRICE:
- stack.Push(closure.Price)
-
- // 0x40 range
- case PREVHASH:
- prevHash := self.env.PrevHash()
-
- stack.Push(ethutil.BigD(prevHash))
-
- case COINBASE:
- coinbase := self.env.Coinbase()
-
- stack.Push(ethutil.BigD(coinbase))
-
- case TIMESTAMP:
- time := self.env.Time()
-
- stack.Push(big.NewInt(time))
-
- case NUMBER:
- number := self.env.BlockNumber()
-
- stack.Push(number)
-
- case DIFFICULTY:
- difficulty := self.env.Difficulty()
-
- stack.Push(difficulty)
-
- case GASLIMIT:
- // TODO
- stack.Push(big.NewInt(0))
-
- // 0x50 range
- case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
- a := int(op - PUSH1 + 1)
- val := ethutil.BigD(closure.GetBytes(int(pc+1), a))
- // Push value to stack
- stack.Push(val)
-
- pc += a
-
- step += int(op) - int(PUSH1) + 1
- case POP:
- require(1)
- stack.Pop()
- case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
- n := int(op - DUP1 + 1)
- stack.Dupn(n)
- case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
- n := int(op - SWAP1 + 2)
- stack.Swapn(n)
-
- case MLOAD:
- require(1)
- offset := stack.Pop()
- val := ethutil.BigD(mem.Get(offset.Int64(), 32))
- stack.Push(val)
-
- case MSTORE: // Store the value at stack top-1 in to memory at location stack top
- require(2)
- // Pop value of the stack
- val, mStart := stack.Popn()
- mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256))
-
- case MSTORE8:
- require(2)
- off := stack.Pop()
- val := stack.Pop()
-
- mem.store[off.Int64()] = byte(val.Int64() & 0xff)
-
- case SLOAD:
- require(1)
- loc := stack.Pop()
- val := closure.GetStorage(loc)
-
- stack.Push(val.BigInt())
-
- case SSTORE:
- require(2)
- val, loc := stack.Popn()
- closure.SetStorage(loc, ethutil.NewValue(val))
-
- closure.message.AddStorageChange(loc.Bytes())
-
- case JUMP:
- require(1)
- pc = int(stack.Pop().Int64())
- // Reduce pc by one because of the increment that's at the end of this for loop
-
- continue
- case JUMPI:
- require(2)
- cond, pos := stack.Popn()
- if cond.Cmp(ethutil.BigTrue) >= 0 {
- pc = int(pos.Int64())
-
- if closure.GetOp(int(pc)) != JUMPDEST {
- return closure.Return(nil), fmt.Errorf("JUMP missed JUMPDEST %v", pc)
- }
-
- continue
- }
- case JUMPDEST:
- case PC:
- stack.Push(u256(int64(pc)))
- case MSIZE:
- stack.Push(big.NewInt(int64(mem.Len())))
- case GAS:
- stack.Push(closure.Gas)
- // 0x60 range
- case CREATE:
- require(3)
-
- var (
- err error
- value = stack.Pop()
- size, offset = stack.Popn()
- input = mem.Get(offset.Int64(), size.Int64())
- gas = new(big.Int).Set(closure.Gas)
-
- // Snapshot the current stack so we are able to
- // revert back to it later.
- //snapshot = self.env.State().Copy()
- )
-
- // Generate a new address
- addr := crypto.CreateAddress(closure.Address(), closure.object.Nonce)
- closure.object.Nonce++
-
- closure.UseGas(closure.Gas)
-
- msg := NewExecution(self, addr, input, gas, closure.Price, value)
- ret, err := msg.Exec(addr, closure)
- if err != nil {
- stack.Push(ethutil.BigFalse)
-
- // Revert the state as it was before.
- //self.env.State().Set(snapshot)
-
- } else {
- msg.object.Code = ret
-
- stack.Push(ethutil.BigD(addr))
- }
-
- case CALL, CALLCODE:
- require(7)
-
- gas := stack.Pop()
- // Pop gas and value of the stack.
- value, addr := stack.Popn()
- // Pop input size and offset
- inSize, inOffset := stack.Popn()
- // Pop return size and offset
- retSize, retOffset := stack.Popn()
-
- // Get the arguments from the memory
- args := mem.Get(inOffset.Int64(), inSize.Int64())
-
- var executeAddr []byte
- if op == CALLCODE {
- executeAddr = closure.Address()
- } else {
- executeAddr = addr.Bytes()
- }
-
- msg := NewExecution(self, executeAddr, args, gas, closure.Price, value)
- ret, err := msg.Exec(addr.Bytes(), closure)
- if err != nil {
- stack.Push(ethutil.BigFalse)
- } else {
- stack.Push(ethutil.BigTrue)
-
- mem.Set(retOffset.Int64(), retSize.Int64(), ret)
- }
-
- case RETURN:
- require(2)
- size, offset := stack.Popn()
- ret := mem.Get(offset.Int64(), size.Int64())
-
- return closure.Return(ret), nil
- case SUICIDE:
- require(1)
-
- receiver := self.env.State().GetOrNewStateObject(stack.Pop().Bytes())
-
- receiver.AddAmount(closure.object.Balance())
-
- closure.object.MarkForDeletion()
-
- fallthrough
- case STOP: // Stop the closure
-
- return closure.Return(nil), nil
- default:
- vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
-
- //panic(fmt.Sprintf("Invalid opcode %x", op))
-
- return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
- }
-
- pc++
- }
+func (self *Vm) Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, data []byte) (ret []byte, err error) {
+ panic("not implemented")
}
func (self *Vm) Env() Environment {
diff --git a/vm/vm_debug.go b/vm/vm_debug.go
index 544e04a5f..fd16a3895 100644
--- a/vm/vm_debug.go
+++ b/vm/vm_debug.go
@@ -2,6 +2,7 @@ package vm
import (
"fmt"
+ "math"
"math/big"
"github.com/ethereum/go-ethereum/crypto"
@@ -25,8 +26,6 @@ type DebugVm struct {
Fn string
Recoverable bool
-
- depth int
}
func NewDebugVm(env Environment) *DebugVm {
@@ -38,8 +37,21 @@ func NewDebugVm(env Environment) *DebugVm {
return &DebugVm{env: env, logTy: lt, Recoverable: true}
}
-func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
- self.depth++
+func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
+ self.env.SetDepth(self.env.Depth() + 1)
+
+ msg := self.env.State().Manifest().AddMessage(&state.Message{
+ To: me.Address(), From: caller.Address(),
+ Input: callData,
+ Origin: self.env.Origin(),
+ Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
+ Value: value,
+ })
+ closure := NewClosure(msg, caller, me, code, gas, price)
+
+ if p := Precompiled[string(me.Address())]; p != nil {
+ return self.RunPrecompiled(p, callData, closure)
+ }
if self.Recoverable {
// Recover from any require exception
@@ -60,35 +72,35 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
var (
op OpCode
- destinations = analyseJumpDests(closure.Code)
- mem = NewMemory()
- stack = NewStack()
- pc = big.NewInt(0)
- step = 0
- prevStep = 0
- statedb = self.env.State()
- require = func(m int) {
+ destinations = analyseJumpDests(closure.Code)
+ mem = NewMemory()
+ stack = NewStack()
+ pc uint64 = 0
+ step = 0
+ prevStep = 0
+ statedb = self.env.State()
+ require = func(m int) {
if stack.Len() < m {
panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, stack.Len(), m))
}
}
- jump = func(from, to *big.Int) {
- p := int(to.Int64())
+ jump = func(from uint64, to *big.Int) {
+ p := to.Uint64()
self.Printf(" ~> %v", to)
// Return to start
if p == 0 {
- pc = big.NewInt(0)
+ pc = 0
} else {
nop := OpCode(closure.GetOp(p))
- if !(nop == JUMPDEST || destinations[from.Int64()] != nil) {
- panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p))
+ if !(nop == JUMPDEST || destinations[from] != nil) {
+ panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
} else if nop == JUMP || nop == JUMPI {
panic(fmt.Sprintf("not allowed to JUMP(I) in to JUMP"))
}
- pc = to
+ pc = to.Uint64()
}
@@ -96,17 +108,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
}
)
- // Debug hook
- if self.Dbg != nil {
- self.Dbg.SetCode(closure.Code)
- }
-
// Don't bother with the execution if there's no code.
- if len(closure.Code) == 0 {
+ if len(code) == 0 {
return closure.Return(nil), nil
}
- vmlogger.Debugf("(%d) %x gas: %v (d) %x\n", self.depth, closure.Address(), closure.Gas, closure.Args)
+ vmlogger.Debugf("(%d) (%x) %x gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], closure.Address(), closure.Gas, callData)
for {
prevStep = step
@@ -115,26 +122,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
step++
// Get the memory location of pc
- op = closure.GetOp(int(pc.Uint64()))
-
- // XXX Leave this Println intact. Don't change this to the log system.
- // Used for creating diffs between implementations
- if self.logTy == LogTyDiff {
- switch op {
- case STOP, RETURN, SUICIDE:
- statedb.GetStateObject(closure.Address()).EachStorage(func(key string, value *ethutil.Value) {
- value.Decode()
- fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes())
- })
- }
-
- b := pc.Bytes()
- if len(b) == 0 {
- b = []byte{0}
- }
-
- fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes())
- }
+ op = closure.GetOp(pc)
gas := new(big.Int)
addStepGasUsage := func(amount *big.Int) {
@@ -151,7 +139,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
// Stack checks only
case ISZERO, CALLDATALOAD, POP, JUMP, NOT: // 1
require(1)
- case ADD, SUB, DIV, SDIV, MOD, SMOD, EXP, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE: // 2
+ case ADD, SUB, DIV, SDIV, MOD, SMOD, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE: // 2
require(2)
case ADDMOD, MULMOD: // 3
require(3)
@@ -165,10 +153,17 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
n := int(op - LOG0)
require(n + 2)
- mSize, mStart := stack.Peekn()
gas.Set(GasLog)
addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog))
- addStepGasUsage(new(big.Int).Add(mSize, mStart))
+
+ mSize, mStart := stack.Peekn()
+ addStepGasUsage(mSize)
+
+ newMemSize = calcMemSize(mStart, mSize)
+ case EXP:
+ require(2)
+
+ gas.Set(big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes()) + 1)))
// Gas only
case STOP:
gas.Set(ethutil.Big0)
@@ -186,16 +181,16 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
var mult *big.Int
y, x := stack.Peekn()
- val := closure.GetStorage(x)
- if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 {
+ val := statedb.GetState(closure.Address(), x.Bytes())
+ if len(val) == 0 && len(y.Bytes()) > 0 {
// 0 => non 0
mult = ethutil.Big3
- } else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 {
- statedb.Refund(closure.caller.Address(), GasSStoreRefund, closure.Price)
+ } else if len(val) > 0 && len(y.Bytes()) == 0 {
+ statedb.Refund(caller.Address(), GasSStoreRefund)
mult = ethutil.Big0
} else {
- // non 0 => non 0
+ // non 0 => non 0 (or 0 => 0)
mult = ethutil.Big1
}
gas.Set(new(big.Int).Mul(mult, GasSStore))
@@ -255,6 +250,15 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
newMemSize.Div(newMemSize, u256(32))
newMemSize.Mul(newMemSize, u256(32))
+ switch op {
+ case CALLDATACOPY, CODECOPY, EXTCODECOPY:
+ addStepGasUsage(new(big.Int).Div(newMemSize, u256(32)))
+ case SHA3:
+ g := new(big.Int).Div(newMemSize, u256(32))
+ g.Mul(g, GasSha3Byte)
+ addStepGasUsage(g)
+ }
+
if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
memGasUsage.Mul(GasMemory, memGasUsage)
@@ -262,7 +266,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
addStepGasUsage(memGasUsage)
- mem.Resize(newMemSize.Uint64())
}
}
@@ -280,6 +283,8 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
return closure.Return(nil), OOG(gas, tmp)
}
+ mem.Resize(newMemSize.Uint64())
+
switch op {
// 0x20 range
case ADD:
@@ -576,8 +581,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
self.Printf(" => %x", caller)
case CALLVALUE:
- value := closure.exe.value
-
stack.Push(value)
self.Printf(" => %v", value)
@@ -585,30 +588,30 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
var (
offset = stack.Pop()
data = make([]byte, 32)
- lenData = big.NewInt(int64(len(closure.Args)))
+ lenData = big.NewInt(int64(len(callData)))
)
if lenData.Cmp(offset) >= 0 {
length := new(big.Int).Add(offset, ethutil.Big32)
length = ethutil.BigMin(length, lenData)
- copy(data, closure.Args[offset.Int64():length.Int64()])
+ copy(data, callData[offset.Int64():length.Int64()])
}
self.Printf(" => 0x%x", data)
stack.Push(ethutil.BigD(data))
case CALLDATASIZE:
- l := int64(len(closure.Args))
+ l := int64(len(callData))
stack.Push(big.NewInt(l))
self.Printf(" => %d", l)
case CALLDATACOPY:
var (
- size = int64(len(closure.Args))
- mOff = stack.Pop().Int64()
- cOff = stack.Pop().Int64()
- l = stack.Pop().Int64()
+ size = uint64(len(callData))
+ mOff = stack.Pop().Uint64()
+ cOff = stack.Pop().Uint64()
+ l = stack.Pop().Uint64()
)
if cOff > size {
@@ -618,11 +621,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
l = 0
}
- code := closure.Args[cOff : cOff+l]
+ code := callData[cOff : cOff+l]
mem.Set(mOff, l, code)
- self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, code[cOff:cOff+l])
+ self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, callData[cOff:cOff+l])
case CODESIZE, EXTCODESIZE:
var code []byte
if op == EXTCODESIZE {
@@ -648,17 +651,17 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
}
var (
- size = int64(len(code))
- mOff = stack.Pop().Int64()
- cOff = stack.Pop().Int64()
- l = stack.Pop().Int64()
+ size = uint64(len(code))
+ mOff = stack.Pop().Uint64()
+ cOff = stack.Pop().Uint64()
+ l = stack.Pop().Uint64()
)
if cOff > size {
cOff = 0
l = 0
} else if cOff+l > size {
- l = 0
+ l = uint64(math.Min(float64(cOff+l), float64(size)))
}
codeCopy := code[cOff : cOff+l]
@@ -707,28 +710,25 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
// 0x50 range
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
- a := big.NewInt(int64(op) - int64(PUSH1) + 1)
- pc.Add(pc, ethutil.Big1)
- data := closure.Gets(pc, a)
- val := ethutil.BigD(data.Bytes())
+ //a := big.NewInt(int64(op) - int64(PUSH1) + 1)
+ a := uint64(op - PUSH1 + 1)
+ //pc.Add(pc, ethutil.Big1)
+ val := ethutil.BigD(closure.GetRangeValue(pc+1, a))
// Push value to stack
stack.Push(val)
- pc.Add(pc, a.Sub(a, big.NewInt(1)))
+ pc += a
+ //pc.Add(pc, a.Sub(a, big.NewInt(1)))
step += int(op) - int(PUSH1) + 1
- self.Printf(" => 0x%x", data.Bytes())
+ self.Printf(" => 0x%x", val.Bytes())
case POP:
stack.Pop()
case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
n := int(op - DUP1 + 1)
- v := stack.Dupn(n)
+ stack.Dupn(n)
self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
-
- if OpCode(closure.Get(new(big.Int).Add(pc, ethutil.Big1)).Uint()) == POP && OpCode(closure.Get(new(big.Int).Add(pc, big.NewInt(2))).Uint()) == POP {
- fmt.Println(toValue(v))
- }
case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
n := int(op - SWAP1 + 2)
x, y := stack.Swapn(n)
@@ -737,13 +737,13 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
case LOG0, LOG1, LOG2, LOG3, LOG4:
n := int(op - LOG0)
topics := make([][]byte, n)
- mStart, mSize := stack.Pop().Int64(), stack.Pop().Int64()
- data := mem.Geti(mStart, mSize)
+ mSize, mStart := stack.Popn()
for i := 0; i < n; i++ {
- topics[i] = stack.Pop().Bytes()
+ topics[i] = ethutil.LeftPadBytes(stack.Pop().Bytes(), 32)
}
- log := &state.Log{closure.Address(), topics, data}
+ data := mem.Geti(mStart.Int64(), mSize.Int64())
+ log := &Log{closure.Address(), topics, data}
self.env.AddLog(log)
self.Printf(" => %v", log)
@@ -756,7 +756,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
case MSTORE: // Store the value at stack top-1 in to memory at location stack top
// Pop value of the stack
val, mStart := stack.Popn()
- mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256))
+ mem.Set(mStart.Uint64(), 32, ethutil.BigToBytes(val, 256))
self.Printf(" => 0x%x", val)
case MSTORE8:
@@ -776,14 +776,10 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
val, loc := stack.Popn()
statedb.SetState(closure.Address(), loc.Bytes(), val)
- // Debug sessions are allowed to run without message
- if closure.message != nil {
- closure.message.AddStorageChange(loc.Bytes())
- }
+ closure.message.AddStorageChange(loc.Bytes())
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
case JUMP:
-
jump(pc, stack.Pop())
continue
@@ -798,13 +794,14 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
case JUMPDEST:
case PC:
- stack.Push(pc)
+ stack.Push(big.NewInt(int64(pc)))
case MSIZE:
stack.Push(big.NewInt(int64(mem.Len())))
case GAS:
stack.Push(closure.Gas)
// 0x60 range
case CREATE:
+
var (
err error
value = stack.Pop()
@@ -826,17 +823,19 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
closure.UseGas(closure.Gas)
- msg := NewExecution(self, addr, input, gas, closure.Price, value)
- ret, err := msg.Create(closure)
+ ret, err, ref := self.env.Create(closure, addr, input, gas, price, value)
if err != nil {
stack.Push(ethutil.BigFalse)
- // Revert the state as it was before.
- //self.env.State().Set(snapshot)
-
self.Printf("CREATE err %v", err)
} else {
- msg.object.Code = ret
+ // gas < len(ret) * CreateDataGas == NO_CODE
+ dataGas := big.NewInt(int64(len(ret)))
+ dataGas.Mul(dataGas, GasCreateByte)
+ if closure.UseGas(dataGas) {
+ ref.SetCode(ret)
+ msg.Output = ret
+ }
stack.Push(ethutil.BigD(addr))
}
@@ -861,25 +860,27 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
// Get the arguments from the memory
args := mem.Get(inOffset.Int64(), inSize.Int64())
- var executeAddr []byte
+ var (
+ ret []byte
+ err error
+ )
if op == CALLCODE {
- executeAddr = closure.Address()
+ ret, err = self.env.CallCode(closure, addr.Bytes(), args, gas, price, value)
} else {
- executeAddr = addr.Bytes()
+ ret, err = self.env.Call(closure, addr.Bytes(), args, gas, price, value)
}
- msg := NewExecution(self, executeAddr, args, gas, closure.Price, value)
- ret, err := msg.Exec(addr.Bytes(), closure)
if err != nil {
stack.Push(ethutil.BigFalse)
vmlogger.Debugln(err)
} else {
stack.Push(ethutil.BigTrue)
+ msg.Output = ret
- mem.Set(retOffset.Int64(), retSize.Int64(), ret)
+ mem.Set(retOffset.Uint64(), retSize.Uint64(), ret)
}
- self.Printf("resume %x", closure.Address())
+ self.Printf("resume %x (%v)", closure.Address(), closure.Gas)
// Debug hook
if self.Dbg != nil {
@@ -894,10 +895,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
return closure.Return(ret), nil
case SUICIDE:
-
receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
+ balance := statedb.GetBalance(closure.Address())
- receiver.AddAmount(statedb.GetBalance(closure.Address()))
+ self.Printf(" => (%x) %v", receiver.Address()[:4], balance)
+
+ receiver.AddAmount(balance)
statedb.Delete(closure.Address())
fallthrough
@@ -908,19 +911,18 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
default:
vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
- //panic(fmt.Sprintf("Invalid opcode %x", op))
closure.ReturnGas(big.NewInt(1), nil)
return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
}
- pc.Add(pc, ethutil.Big1)
+ pc++
self.Endl()
if self.Dbg != nil {
for _, instrNo := range self.Dbg.BreakPoints() {
- if pc.Cmp(big.NewInt(instrNo)) == 0 {
+ if pc == uint64(instrNo) {
self.Stepping = true
if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
@@ -937,6 +939,25 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
}
}
+func (self *DebugVm) RunPrecompiled(p *PrecompiledAccount, callData []byte, closure *Closure) (ret []byte, err error) {
+ gas := p.Gas(len(callData))
+ if closure.UseGas(gas) {
+ ret = p.Call(callData)
+ self.Printf("NATIVE_FUNC => %x", ret)
+ self.Endl()
+
+ return closure.Return(ret), nil
+ } else {
+ self.Endl()
+
+ tmp := new(big.Int).Set(closure.Gas)
+
+ closure.UseGas(closure.Gas)
+
+ return closure.Return(nil), OOG(gas, tmp)
+ }
+}
+
func (self *DebugVm) Printf(format string, v ...interface{}) VirtualMachine {
if self.logTy == LogTyPretty {
self.logStr += fmt.Sprintf(format, v...)
@@ -957,7 +978,3 @@ func (self *DebugVm) Endl() VirtualMachine {
func (self *DebugVm) Env() Environment {
return self.env
}
-
-func (self *DebugVm) Depth() int {
- return self.depth
-}
diff --git a/vm/vm_test.go b/vm/vm_test.go
index 19aa171a6..9bd147a72 100644
--- a/vm/vm_test.go
+++ b/vm/vm_test.go
@@ -1,181 +1,3 @@
package vm
-import (
- "fmt"
- "io/ioutil"
- "log"
- "math/big"
- "os"
-
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/state"
- "github.com/ethereum/go-ethereum/trie"
- checker "gopkg.in/check.v1"
- // "github.com/obscuren/mutan"
-)
-
-type VmSuite struct{}
-
-var _ = checker.Suite(&VmSuite{})
-var big9 = ethutil.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000009")
-
-const mutcode = `
-var x = 0;
-for i := 0; i < 10; i++ {
- x = i
-}
-
-return x`
-
-type TestEnv struct{}
-
-func (TestEnv) Origin() []byte { return nil }
-func (TestEnv) BlockNumber() *big.Int { return nil }
-func (TestEnv) BlockHash() []byte { return nil }
-func (TestEnv) PrevHash() []byte { return nil }
-func (TestEnv) Coinbase() []byte { return nil }
-func (TestEnv) Time() int64 { return 0 }
-func (TestEnv) GasLimit() *big.Int { return nil }
-func (TestEnv) Difficulty() *big.Int { return nil }
-func (TestEnv) Value() *big.Int { return nil }
-func (TestEnv) AddLog(*state.Log) {}
-func (TestEnv) Transfer(from, to Account, amount *big.Int) error {
- return nil
-}
-
-// This is likely to fail if anything ever gets looked up in the state trie :-)
-func (TestEnv) State() *state.State {
- return state.New(trie.New(nil, ""))
-}
-
-func setup(level logger.LogLevel, typ Type) (*Closure, VirtualMachine) {
- code, err := ethutil.Compile(mutcode, true)
- if err != nil {
- log.Fatal(err)
- }
-
- // Pipe output to /dev/null
- logger.AddLogSystem(logger.NewStdLogSystem(ioutil.Discard, log.LstdFlags, level))
-
- ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
-
- stateObject := state.NewStateObject([]byte{'j', 'e', 'f', 'f'})
- callerClosure := NewClosure(nil, stateObject, stateObject, code, big.NewInt(1000000), big.NewInt(0))
-
- return callerClosure, New(TestEnv{}, typ)
-}
-
-func (s *VmSuite) TestDebugVm(c *checker.C) {
- // if mutan.Version < "0.6" {
- // t.Skip("skipping for mutan version", mutan.Version, " < 0.6")
- // }
- closure, vm := setup(logger.DebugLevel, DebugVmTy)
- ret, _, e := closure.Call(vm, nil)
- c.Assert(e, checker.NotNil)
- c.Skip("Depends on mutan")
- c.Assert(ret, checker.DeepEquals, big9)
-}
-
-func (s *VmSuite) TestVm(c *checker.C) {
- // if mutan.Version < "0.6" {
- // t.Skip("skipping for mutan version", mutan.Version, " < 0.6")
- // }
- closure, vm := setup(logger.DebugLevel, StandardVmTy)
- ret, _, e := closure.Call(vm, nil)
- c.Assert(e, checker.NotNil)
- c.Skip("Depends on mutan")
- c.Assert(ret, checker.DeepEquals, big9)
-}
-
-func (s *VmSuite) BenchmarkDebugVm(c *checker.C) {
- closure, vm := setup(logger.InfoLevel, StandardVmTy)
-
- c.ResetTimer()
-
- for i := 0; i < c.N; i++ {
- closure.Call(vm, nil)
- }
-}
-
-func (s *VmSuite) BenchmarkVm(c *checker.C) {
- closure, vm := setup(logger.InfoLevel, DebugVmTy)
-
- c.ResetTimer()
-
- for i := 0; i < c.N; i++ {
- closure.Call(vm, nil)
- }
-}
-
-func RunCode(mutCode string, typ Type) []byte {
- code, err := ethutil.Compile(mutCode, true)
- if err != nil {
- log.Fatal(err)
- }
-
- logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.InfoLevel))
-
- ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
-
- stateObject := state.NewStateObject([]byte{'j', 'e', 'f', 'f'})
- closure := NewClosure(nil, stateObject, stateObject, code, big.NewInt(1000000), big.NewInt(0))
-
- vm := New(TestEnv{}, typ)
- ret, _, e := closure.Call(vm, nil)
- if e != nil {
- fmt.Println(e)
- }
-
- return ret
-}
-
-func (s *VmSuite) TestBuildInSha256(c *checker.C) {
- ret := RunCode(`
- var in = 42
- var out = 0
-
- call(0x2, 0, 10000, in, out)
-
- return out
- `, DebugVmTy)
-
- exp := crypto.Sha256(ethutil.LeftPadBytes([]byte{42}, 32))
- c.Skip("Depends on mutan")
- c.Assert(ret, checker.DeepEquals, exp)
-}
-
-func (s *VmSuite) TestBuildInRipemd(c *checker.C) {
- ret := RunCode(`
- var in = 42
- var out = 0
-
- call(0x3, 0, 10000, in, out)
-
- return out
- `, DebugVmTy)
-
- exp := ethutil.RightPadBytes(crypto.Ripemd160(ethutil.LeftPadBytes([]byte{42}, 32)), 32)
- c.Skip("Depends on mutan")
- c.Assert(ret, checker.DeepEquals, exp)
-}
-
-func (s *VmSuite) TestOog(c *checker.C) {
- // This tests takes a long time and will eventually run out of gas
- // t.Skip()
- c.Skip("This tests takes a long time and will eventually run out of gas")
-
- logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.InfoLevel))
-
- ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
-
- stateObject := state.NewStateObject([]byte{'j', 'e', 'f', 'f'})
- closure := NewClosure(nil, stateObject, stateObject, ethutil.Hex2Bytes("60ff60ff600057"), big.NewInt(1000000), big.NewInt(0))
-
- vm := New(TestEnv{}, DebugVmTy)
- _, _, e := closure.Call(vm, nil)
- if e != nil {
- fmt.Println(e)
- }
-}
+// Tests have been removed in favour of general tests. If anything implementation specific needs testing, put it here
diff --git a/whisper/doc.go b/whisper/doc.go
new file mode 100644
index 000000000..986df8fb9
--- /dev/null
+++ b/whisper/doc.go
@@ -0,0 +1,16 @@
+/*
+Package whisper implements the Whisper PoC-1.
+
+(https://github.com/ethereum/wiki/wiki/Whisper-PoC-1-Protocol-Spec)
+
+Whisper combines aspects of both DHTs and datagram messaging systems (e.g. UDP).
+As such it may be likened and compared to both, not dissimilar to the
+matter/energy duality (apologies to physicists for the blatant abuse of a
+fundamental and beautiful natural principle).
+
+Whisper is a pure identity-based messaging system. Whisper provides a low-level
+(non-application-specific) but easily-accessible API without being based upon
+or prejudiced by the low-level hardware attributes and characteristics,
+particularly the notion of singular endpoints.
+*/
+package whisper
diff --git a/whisper/envelope.go b/whisper/envelope.go
new file mode 100644
index 000000000..066e20f6a
--- /dev/null
+++ b/whisper/envelope.go
@@ -0,0 +1,127 @@
+package whisper
+
+import (
+ "bytes"
+ "crypto/ecdsa"
+ "encoding/binary"
+ "fmt"
+ "io"
+ "time"
+
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/rlp"
+ "github.com/obscuren/ecies"
+)
+
+const (
+ DefaultPow = 50 * time.Millisecond
+)
+
+type Envelope struct {
+ Expiry uint32 // Whisper protocol specifies int32, really should be int64
+ Ttl uint32 // ^^^^^^
+ Topics [][]byte
+ Data []byte
+ Nonce uint32
+
+ hash Hash
+}
+
+func NewEnvelopeFromReader(reader io.Reader) (*Envelope, error) {
+ var envelope Envelope
+
+ buf := new(bytes.Buffer)
+ buf.ReadFrom(reader)
+
+ h := H(crypto.Sha3(buf.Bytes()))
+ if err := rlp.Decode(buf, &envelope); err != nil {
+ return nil, err
+ }
+
+ envelope.hash = h
+
+ return &envelope, nil
+}
+
+func (self *Envelope) Hash() Hash {
+ if self.hash == EmptyHash {
+ self.hash = H(crypto.Sha3(ethutil.Encode(self)))
+ }
+
+ return self.hash
+}
+
+func NewEnvelope(ttl time.Duration, topics [][]byte, data *Message) *Envelope {
+ exp := time.Now().Add(ttl)
+
+ return &Envelope{uint32(exp.Unix()), uint32(ttl.Seconds()), topics, data.Bytes(), 0, Hash{}}
+}
+
+func (self *Envelope) Seal(pow time.Duration) {
+ self.proveWork(pow)
+}
+
+func (self *Envelope) Open(prv *ecdsa.PrivateKey) (msg *Message, err error) {
+ data := self.Data
+ var message Message
+ dataStart := 1
+ if data[0] > 0 {
+ if len(data) < 66 {
+ return nil, fmt.Errorf("unable to open envelope. First bit set but len(data) < 66")
+ }
+ dataStart = 66
+ message.Flags = data[0]
+ message.Signature = data[1:66]
+ }
+
+ payload := data[dataStart:]
+ if prv != nil {
+ message.Payload, err = crypto.Decrypt(prv, payload)
+ switch err {
+ case ecies.ErrInvalidPublicKey: // Payload isn't encrypted
+ message.Payload = payload
+ return &message, err
+ default:
+ return nil, fmt.Errorf("unable to open envelope. Decrypt failed: %v", err)
+ }
+ }
+
+ return &message, nil
+}
+
+func (self *Envelope) proveWork(dura time.Duration) {
+ var bestBit int
+ d := make([]byte, 64)
+ copy(d[:32], ethutil.Encode(self.withoutNonce()))
+
+ then := time.Now().Add(dura).UnixNano()
+ for n := uint32(0); time.Now().UnixNano() < then; {
+ for i := 0; i < 1024; i++ {
+ binary.BigEndian.PutUint32(d[60:], n)
+
+ fbs := ethutil.FirstBitSet(ethutil.BigD(crypto.Sha3(d)))
+ if fbs > bestBit {
+ bestBit = fbs
+ self.Nonce = n
+ }
+
+ n++
+ }
+ }
+}
+
+func (self *Envelope) valid() bool {
+ d := make([]byte, 64)
+ copy(d[:32], ethutil.Encode(self.withoutNonce()))
+ binary.BigEndian.PutUint32(d[60:], self.Nonce)
+ return ethutil.FirstBitSet(ethutil.BigD(crypto.Sha3(d))) > 0
+}
+
+func (self *Envelope) withoutNonce() interface{} {
+ return []interface{}{self.Expiry, self.Ttl, ethutil.ByteSliceToInterface(self.Topics), self.Data}
+}
+
+func (self *Envelope) RlpData() interface{} {
+ return []interface{}{self.Expiry, self.Ttl, ethutil.ByteSliceToInterface(self.Topics), self.Data, self.Nonce}
+}
diff --git a/whisper/filter.go b/whisper/filter.go
new file mode 100644
index 000000000..4315aa556
--- /dev/null
+++ b/whisper/filter.go
@@ -0,0 +1,10 @@
+package whisper
+
+import "crypto/ecdsa"
+
+type Filter struct {
+ To *ecdsa.PrivateKey
+ From *ecdsa.PublicKey
+ Topics [][]byte
+ Fn func(*Message)
+}
diff --git a/whisper/main.go b/whisper/main.go
new file mode 100644
index 000000000..edd5f7004
--- /dev/null
+++ b/whisper/main.go
@@ -0,0 +1,37 @@
+// +build none
+
+package main
+
+import (
+ "fmt"
+ "log"
+ "os"
+
+ "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/whisper"
+ "github.com/obscuren/secp256k1-go"
+)
+
+func main() {
+ logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.InfoLevel))
+
+ pub, _ := secp256k1.GenerateKeyPair()
+
+ whisper := whisper.New()
+
+ srv := p2p.Server{
+ MaxPeers: 10,
+ Identity: p2p.NewSimpleClientIdentity("whisper-go", "1.0", "", string(pub)),
+ ListenAddr: ":30300",
+ NAT: p2p.UPNP(),
+
+ Protocols: []p2p.Protocol{whisper.Protocol()},
+ }
+ if err := srv.Start(); err != nil {
+ fmt.Println("could not start server:", err)
+ os.Exit(1)
+ }
+
+ select {}
+}
diff --git a/whisper/message.go b/whisper/message.go
new file mode 100644
index 000000000..db0110b4a
--- /dev/null
+++ b/whisper/message.go
@@ -0,0 +1,74 @@
+package whisper
+
+import (
+ "crypto/ecdsa"
+ "time"
+
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+type Message struct {
+ Flags byte
+ Signature []byte
+ Payload []byte
+}
+
+func NewMessage(payload []byte) *Message {
+ return &Message{Flags: 0, Payload: payload}
+}
+
+func (self *Message) hash() []byte {
+ return crypto.Sha3(append([]byte{self.Flags}, self.Payload...))
+}
+
+func (self *Message) sign(key *ecdsa.PrivateKey) (err error) {
+ self.Flags = 1
+ self.Signature, err = crypto.Sign(self.hash(), key)
+ return
+}
+
+func (self *Message) Recover() *ecdsa.PublicKey {
+ defer func() { recover() }() // in case of invalid sig
+ return crypto.SigToPub(self.hash(), self.Signature)
+}
+
+func (self *Message) Encrypt(to *ecdsa.PublicKey) (err error) {
+ self.Payload, err = crypto.Encrypt(to, self.Payload)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (self *Message) Bytes() []byte {
+ return append([]byte{self.Flags}, append(self.Signature, self.Payload...)...)
+}
+
+type Opts struct {
+ From *ecdsa.PrivateKey
+ To *ecdsa.PublicKey
+ Ttl time.Duration
+ Topics [][]byte
+}
+
+func (self *Message) Seal(pow time.Duration, opts Opts) (*Envelope, error) {
+ if opts.From != nil {
+ err := self.sign(opts.From)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if opts.To != nil {
+ err := self.Encrypt(opts.To)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ envelope := NewEnvelope(DefaultTtl, opts.Topics, self)
+ envelope.Seal(pow)
+
+ return envelope, nil
+}
diff --git a/whisper/messages_test.go b/whisper/messages_test.go
new file mode 100644
index 000000000..cba103011
--- /dev/null
+++ b/whisper/messages_test.go
@@ -0,0 +1,51 @@
+package whisper
+
+import (
+ "bytes"
+ "crypto/elliptic"
+ "fmt"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+func TestSign(t *testing.T) {
+ prv, _ := crypto.GenerateKey()
+ msg := NewMessage([]byte("hello world"))
+ msg.sign(prv)
+
+ pubKey := msg.Recover()
+ p1 := elliptic.Marshal(crypto.S256(), prv.PublicKey.X, prv.PublicKey.Y)
+ p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y)
+
+ if !bytes.Equal(p1, p2) {
+ t.Error("recovered pub key did not match")
+ }
+}
+
+func TestMessageEncryptDecrypt(t *testing.T) {
+ prv1, _ := crypto.GenerateKey()
+ prv2, _ := crypto.GenerateKey()
+
+ data := []byte("hello world")
+ msg := NewMessage(data)
+ envelope, err := msg.Seal(DefaultPow, Opts{
+ From: prv1,
+ To: &prv2.PublicKey,
+ })
+ if err != nil {
+ fmt.Println(err)
+ t.FailNow()
+ }
+
+ msg1, err := envelope.Open(prv2)
+ if err != nil {
+ fmt.Println(err)
+ t.FailNow()
+ }
+
+ if !bytes.Equal(msg1.Payload, data) {
+ fmt.Println("encryption error. data did not match")
+ t.FailNow()
+ }
+}
diff --git a/whisper/peer.go b/whisper/peer.go
new file mode 100644
index 000000000..d42b374b5
--- /dev/null
+++ b/whisper/peer.go
@@ -0,0 +1,128 @@
+package whisper
+
+import (
+ "fmt"
+ "io/ioutil"
+ "time"
+
+ "github.com/ethereum/go-ethereum/p2p"
+ "gopkg.in/fatih/set.v0"
+)
+
+const (
+ protocolVersion = 0x02
+)
+
+type peer struct {
+ host *Whisper
+ peer *p2p.Peer
+ ws p2p.MsgReadWriter
+
+ // XXX Eventually this is going to reach exceptional large space. We need an expiry here
+ known *set.Set
+
+ quit chan struct{}
+}
+
+func NewPeer(host *Whisper, p *p2p.Peer, ws p2p.MsgReadWriter) *peer {
+ return &peer{host, p, ws, set.New(), make(chan struct{})}
+}
+
+func (self *peer) init() error {
+ if err := self.handleStatus(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (self *peer) start() {
+ go self.update()
+ self.peer.Infoln("whisper started")
+}
+
+func (self *peer) stop() {
+ self.peer.Infoln("whisper stopped")
+
+ close(self.quit)
+}
+
+func (self *peer) update() {
+ relay := time.NewTicker(300 * time.Millisecond)
+out:
+ for {
+ select {
+ case <-relay.C:
+ err := self.broadcast(self.host.envelopes())
+ if err != nil {
+ self.peer.Infoln(err)
+ break out
+ }
+
+ case <-self.quit:
+ break out
+ }
+ }
+}
+
+func (self *peer) broadcast(envelopes []*Envelope) error {
+ envs := make([]interface{}, len(envelopes))
+ i := 0
+ for _, envelope := range envelopes {
+ if !self.known.Has(envelope.Hash()) {
+ envs[i] = envelope
+ self.known.Add(envelope.Hash())
+ i++
+ }
+ }
+
+ if i > 0 {
+ msg := p2p.NewMsg(envelopesMsg, envs[:i]...)
+ if err := self.ws.WriteMsg(msg); err != nil {
+ return err
+ }
+ self.peer.Infoln("broadcasted", i, "message(s)")
+ }
+
+ return nil
+}
+
+func (self *peer) addKnown(envelope *Envelope) {
+ self.known.Add(envelope.Hash())
+}
+
+func (self *peer) handleStatus() error {
+ ws := self.ws
+
+ if err := ws.WriteMsg(self.statusMsg()); err != nil {
+ return err
+ }
+
+ msg, err := ws.ReadMsg()
+ if err != nil {
+ return err
+ }
+
+ if msg.Code != statusMsg {
+ return fmt.Errorf("peer send %x before status msg", msg.Code)
+ }
+
+ data, err := ioutil.ReadAll(msg.Payload)
+ if err != nil {
+ return err
+ }
+
+ if len(data) == 0 {
+ return fmt.Errorf("malformed status. data len = 0")
+ }
+
+ if pv := data[0]; pv != protocolVersion {
+ return fmt.Errorf("protocol version mismatch %d != %d", pv, protocolVersion)
+ }
+
+ return nil
+}
+
+func (self *peer) statusMsg() p2p.Msg {
+ return p2p.NewMsg(statusMsg, protocolVersion)
+}
diff --git a/whisper/sort.go b/whisper/sort.go
new file mode 100644
index 000000000..8c5b46e9e
--- /dev/null
+++ b/whisper/sort.go
@@ -0,0 +1,25 @@
+package whisper
+
+import "sort"
+
+type sortedKeys struct {
+ k []int32
+}
+
+func (self *sortedKeys) Len() int { return len(self.k) }
+func (self *sortedKeys) Less(i, j int) bool { return self.k[i] < self.k[j] }
+func (self *sortedKeys) Swap(i, j int) { self.k[i], self.k[j] = self.k[j], self.k[i] }
+
+func sortKeys(m map[int32]Hash) []int32 {
+ sorted := new(sortedKeys)
+ sorted.k = make([]int32, len(m))
+ i := 0
+ for key, _ := range m {
+ sorted.k[i] = key
+ i++
+ }
+
+ sort.Sort(sorted)
+
+ return sorted.k
+}
diff --git a/whisper/sort_test.go b/whisper/sort_test.go
new file mode 100644
index 000000000..5d8177d41
--- /dev/null
+++ b/whisper/sort_test.go
@@ -0,0 +1,19 @@
+package whisper
+
+import "testing"
+
+func TestSorting(t *testing.T) {
+ m := map[int32]Hash{
+ 1: HS("1"),
+ 3: HS("3"),
+ 2: HS("2"),
+ 5: HS("5"),
+ }
+ exp := []int32{1, 2, 3, 5}
+ res := sortKeys(m)
+ for i, k := range res {
+ if k != exp[i] {
+ t.Error(k, "failed. Expected", exp[i])
+ }
+ }
+}
diff --git a/whisper/util.go b/whisper/util.go
new file mode 100644
index 000000000..7a222395f
--- /dev/null
+++ b/whisper/util.go
@@ -0,0 +1,36 @@
+package whisper
+
+import "github.com/ethereum/go-ethereum/crypto"
+
+func hashTopic(topic []byte) []byte {
+ return crypto.Sha3(topic)[:4]
+}
+
+// NOTE this isn't DRY, but I don't want to iterate twice.
+
+// Returns a formatted topics byte slice.
+// data: unformatted data (e.g., no hashes needed)
+func Topics(data [][]byte) [][]byte {
+ d := make([][]byte, len(data))
+ for i, byts := range data {
+ d[i] = hashTopic(byts)
+ }
+ return d
+}
+
+func TopicsFromString(data ...string) [][]byte {
+ d := make([][]byte, len(data))
+ for i, str := range data {
+ d[i] = hashTopic([]byte(str))
+ }
+ return d
+}
+
+func bytesToMap(s [][]byte) map[string]struct{} {
+ m := make(map[string]struct{})
+ for _, topic := range s {
+ m[string(topic)] = struct{}{}
+ }
+
+ return m
+}
diff --git a/whisper/whisper.go b/whisper/whisper.go
new file mode 100644
index 000000000..9721ca9f9
--- /dev/null
+++ b/whisper/whisper.go
@@ -0,0 +1,245 @@
+package whisper
+
+import (
+ "bytes"
+ "crypto/ecdsa"
+ "errors"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/event/filter"
+ "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/obscuren/ecies"
+ "gopkg.in/fatih/set.v0"
+)
+
+// MOVE ME
+type Hash struct {
+ hash string
+}
+
+var EmptyHash Hash
+
+func H(hash []byte) Hash {
+ return Hash{string(hash)}
+}
+func HS(hash string) Hash {
+ return Hash{hash}
+}
+
+func (self Hash) Compare(other Hash) int {
+ return bytes.Compare([]byte(self.hash), []byte(other.hash))
+}
+
+// MOVE ME END
+
+const (
+ statusMsg = 0x0
+ envelopesMsg = 0x01
+)
+
+type MessageEvent struct {
+ To *ecdsa.PrivateKey
+ From *ecdsa.PublicKey
+ Message *Message
+}
+
+const DefaultTtl = 50 * time.Second
+
+var wlogger = logger.NewLogger("SHH")
+
+type Whisper struct {
+ protocol p2p.Protocol
+ filters *filter.Filters
+
+ mmu sync.RWMutex
+ messages map[Hash]*Envelope
+ expiry map[uint32]*set.SetNonTS
+
+ quit chan struct{}
+
+ keys []*ecdsa.PrivateKey
+}
+
+func New() *Whisper {
+ whisper := &Whisper{
+ messages: make(map[Hash]*Envelope),
+ filters: filter.New(),
+ expiry: make(map[uint32]*set.SetNonTS),
+ quit: make(chan struct{}),
+ }
+ whisper.filters.Start()
+
+ // p2p whisper sub protocol handler
+ whisper.protocol = p2p.Protocol{
+ Name: "shh",
+ Version: 2,
+ Length: 2,
+ Run: whisper.msgHandler,
+ }
+
+ return whisper
+}
+
+func (self *Whisper) Start() {
+ wlogger.Infoln("Whisper started")
+ go self.update()
+}
+
+func (self *Whisper) Stop() {
+ close(self.quit)
+}
+
+func (self *Whisper) Send(envelope *Envelope) error {
+ return self.add(envelope)
+}
+
+func (self *Whisper) NewIdentity() *ecdsa.PrivateKey {
+ key, err := crypto.GenerateKey()
+ if err != nil {
+ panic(err)
+ }
+ self.keys = append(self.keys, key)
+
+ return key
+}
+
+func (self *Whisper) HasIdentity(key *ecdsa.PrivateKey) bool {
+ for _, key := range self.keys {
+ if key.D.Cmp(key.D) == 0 {
+ return true
+ }
+ }
+ return false
+}
+
+func (self *Whisper) Watch(opts Filter) int {
+ return self.filters.Install(filter.Generic{
+ Str1: string(crypto.FromECDSA(opts.To)),
+ Str2: string(crypto.FromECDSAPub(opts.From)),
+ Data: bytesToMap(opts.Topics),
+ Fn: func(data interface{}) {
+ opts.Fn(data.(*Message))
+ },
+ })
+}
+
+// Main handler for passing whisper messages to whisper peer objects
+func (self *Whisper) msgHandler(peer *p2p.Peer, ws p2p.MsgReadWriter) error {
+ wpeer := NewPeer(self, peer, ws)
+ // initialise whisper peer (handshake/status)
+ if err := wpeer.init(); err != nil {
+ return err
+ }
+ // kick of the main handler for broadcasting/managing envelopes
+ go wpeer.start()
+ defer wpeer.stop()
+
+ // Main *read* loop. Writing is done by the peer it self.
+ for {
+ msg, err := ws.ReadMsg()
+ if err != nil {
+ return err
+ }
+
+ envelope, err := NewEnvelopeFromReader(msg.Payload)
+ if err != nil {
+ peer.Infoln(err)
+ continue
+ }
+
+ if err := self.add(envelope); err != nil {
+ // TODO Punish peer here. Invalid envelope.
+ peer.Infoln(err)
+ }
+ wpeer.addKnown(envelope)
+ }
+}
+
+// takes care of adding envelopes to the messages pool. At this moment no sanity checks are being performed.
+func (self *Whisper) add(envelope *Envelope) error {
+ if !envelope.valid() {
+ return errors.New("invalid pow provided for envelope")
+ }
+
+ self.mmu.Lock()
+ defer self.mmu.Unlock()
+
+ hash := envelope.Hash()
+ self.messages[hash] = envelope
+ if self.expiry[envelope.Expiry] == nil {
+ self.expiry[envelope.Expiry] = set.NewNonTS()
+ }
+
+ if !self.expiry[envelope.Expiry].Has(hash) {
+ self.expiry[envelope.Expiry].Add(hash)
+ self.postEvent(envelope)
+ }
+
+ return nil
+}
+
+func (self *Whisper) update() {
+ expire := time.NewTicker(800 * time.Millisecond)
+out:
+ for {
+ select {
+ case <-expire.C:
+ self.expire()
+ case <-self.quit:
+ break out
+ }
+ }
+}
+
+func (self *Whisper) expire() {
+ self.mmu.Lock()
+ defer self.mmu.Unlock()
+
+ now := uint32(time.Now().Unix())
+ for then, hashSet := range self.expiry {
+ if then > now {
+ continue
+ }
+
+ hashSet.Each(func(v interface{}) bool {
+ delete(self.messages, v.(Hash))
+ return true
+ })
+ self.expiry[then].Clear()
+ }
+}
+
+func (self *Whisper) envelopes() (envelopes []*Envelope) {
+ self.mmu.RLock()
+ defer self.mmu.RUnlock()
+
+ envelopes = make([]*Envelope, len(self.messages))
+ i := 0
+ for _, envelope := range self.messages {
+ envelopes[i] = envelope
+ i++
+ }
+
+ return
+}
+
+func (self *Whisper) postEvent(envelope *Envelope) {
+ for _, key := range self.keys {
+ if message, err := envelope.Open(key); err == nil || (err != nil && err == ecies.ErrInvalidPublicKey) {
+ // Create a custom filter?
+ self.filters.Notify(filter.Generic{
+ Str1: string(crypto.FromECDSA(key)), Str2: string(crypto.FromECDSAPub(message.Recover())),
+ Data: bytesToMap(envelope.Topics),
+ }, message)
+ } else {
+ wlogger.Infoln(err)
+ }
+ }
+}
+
+func (self *Whisper) Protocol() p2p.Protocol {
+ return self.protocol
+}
diff --git a/whisper/whisper_test.go b/whisper/whisper_test.go
new file mode 100644
index 000000000..107cb8c97
--- /dev/null
+++ b/whisper/whisper_test.go
@@ -0,0 +1,47 @@
+package whisper
+
+import (
+ "fmt"
+ "testing"
+ "time"
+)
+
+func TestKeyManagement(t *testing.T) {
+ whisper := New()
+
+ key := whisper.NewIdentity()
+ if !whisper.HasIdentity(key) {
+ t.Error("expected whisper to have identify")
+ }
+}
+
+func TestEvent(t *testing.T) {
+ res := make(chan *Message, 1)
+ whisper := New()
+ id := whisper.NewIdentity()
+ whisper.Watch(Filter{
+ To: id,
+ Fn: func(msg *Message) {
+ res <- msg
+ },
+ })
+
+ msg := NewMessage([]byte(fmt.Sprintf("Hello world. This is whisper-go. Incase you're wondering; the time is %v", time.Now())))
+ envelope, err := msg.Seal(DefaultPow, Opts{
+ Ttl: DefaultTtl,
+ From: id,
+ To: &id.PublicKey,
+ })
+ if err != nil {
+ fmt.Println(err)
+ t.FailNow()
+ }
+
+ tick := time.NewTicker(time.Second)
+ whisper.postEvent(envelope)
+ select {
+ case <-res:
+ case <-tick.C:
+ t.Error("did not receive message")
+ }
+}
diff --git a/wire/.gitignore b/wire/.gitignore
deleted file mode 100644
index f725d58d1..000000000
--- a/wire/.gitignore
+++ /dev/null
@@ -1,12 +0,0 @@
-# See http://help.github.com/ignore-files/ for more about ignoring files.
-#
-# If you find yourself ignoring temporary files generated by your text editor
-# or operating system, you probably want to add a global ignore instead:
-# git config --global core.excludesfile ~/.gitignore_global
-
-/tmp
-*/**/*un~
-*un~
-.DS_Store
-*/**/.DS_Store
-
diff --git a/wire/README.md b/wire/README.md
deleted file mode 100644
index 7f63688b3..000000000
--- a/wire/README.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# ethwire
-
-The ethwire package contains the ethereum wire protocol. The ethwire
-package is required to write and read from the ethereum network.
-
-# Installation
-
-`go get github.com/ethereum/ethwire-go`
-
-# Messaging overview
-
-The Ethereum Wire protocol defines the communication between the nodes
-running Ethereum. Further reader reading can be done on the
-[Wiki](http://wiki.ethereum.org/index.php/Wire_Protocol).
-
-# Reading Messages
-
-```go
-// Read and validate the next eth message from the provided connection.
-// returns a error message with the details.
-msg, err := ethwire.ReadMessage(conn)
-if err != nil {
- // Handle error
-}
-```
-
-# Writing Messages
-
-```go
-// Constructs a message which can be interpreted by the eth network.
-// Write the inventory to network
-err := ethwire.WriteMessage(conn, &Msg{
- Type: ethwire.MsgInvTy,
- Data : []interface{}{...},
-})
-```
diff --git a/wire/client_identity.go b/wire/client_identity.go
deleted file mode 100644
index 0a268024a..000000000
--- a/wire/client_identity.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package wire
-
-import (
- "fmt"
- "runtime"
-)
-
-// should be used in Peer handleHandshake, incorporate Caps, ProtocolVersion, Pubkey etc.
-type ClientIdentity interface {
- String() string
-}
-
-type SimpleClientIdentity struct {
- clientIdentifier string
- version string
- customIdentifier string
- os string
- implementation string
-}
-
-func NewSimpleClientIdentity(clientIdentifier string, version string, customIdentifier string) *SimpleClientIdentity {
- clientIdentity := &SimpleClientIdentity{
- clientIdentifier: clientIdentifier,
- version: version,
- customIdentifier: customIdentifier,
- os: runtime.GOOS,
- implementation: runtime.Version(),
- }
-
- return clientIdentity
-}
-
-func (c *SimpleClientIdentity) init() {
-}
-
-func (c *SimpleClientIdentity) String() string {
- var id string
- if len(c.customIdentifier) > 0 {
- id = "/" + c.customIdentifier
- }
-
- return fmt.Sprintf("%s/v%s%s/%s/%s",
- c.clientIdentifier,
- c.version,
- id,
- c.os,
- c.implementation)
-}
-
-func (c *SimpleClientIdentity) SetCustomIdentifier(customIdentifier string) {
- c.customIdentifier = customIdentifier
-}
-
-func (c *SimpleClientIdentity) GetCustomIdentifier() string {
- return c.customIdentifier
-}
diff --git a/wire/client_identity_test.go b/wire/client_identity_test.go
deleted file mode 100644
index c0e7a0159..000000000
--- a/wire/client_identity_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package wire
-
-import (
- "fmt"
- "runtime"
- "testing"
-)
-
-func TestClientIdentity(t *testing.T) {
- clientIdentity := NewSimpleClientIdentity("Ethereum(G)", "0.5.16", "test")
- clientString := clientIdentity.String()
- expected := fmt.Sprintf("Ethereum(G)/v0.5.16/test/%s/%s", runtime.GOOS, runtime.Version())
- if clientString != expected {
- t.Errorf("Expected clientIdentity to be %q, got %q", expected, clientString)
- }
- customIdentifier := clientIdentity.GetCustomIdentifier()
- if customIdentifier != "test" {
- t.Errorf("Expected clientIdentity.GetCustomIdentifier() to be 'test', got %q", customIdentifier)
- }
- clientIdentity.SetCustomIdentifier("test2")
- customIdentifier = clientIdentity.GetCustomIdentifier()
- if customIdentifier != "test2" {
- t.Errorf("Expected clientIdentity.GetCustomIdentifier() to be 'test2', got %q", customIdentifier)
- }
- clientString = clientIdentity.String()
- expected = fmt.Sprintf("Ethereum(G)/v0.5.16/test2/%s/%s", runtime.GOOS, runtime.Version())
- if clientString != expected {
- t.Errorf("Expected clientIdentity to be %q, got %q", expected, clientString)
- }
-}
diff --git a/wire/messages2.go b/wire/messages2.go
deleted file mode 100644
index acbd9e0d5..000000000
--- a/wire/messages2.go
+++ /dev/null
@@ -1,199 +0,0 @@
-package wire
-
-import (
- "bytes"
- "errors"
- "fmt"
- "net"
- "time"
-
- "github.com/ethereum/go-ethereum/ethutil"
-)
-
-// The connection object allows you to set up a connection to the Ethereum network.
-// The Connection object takes care of all encoding and sending objects properly over
-// the network.
-type Connection struct {
- conn net.Conn
- nTimeout time.Duration
- pendingMessages Messages
-}
-
-// Create a new connection to the Ethereum network
-func New(conn net.Conn) *Connection {
- return &Connection{conn: conn, nTimeout: 500}
-}
-
-// Read, reads from the network. It will block until the next message is received.
-func (self *Connection) Read() *Msg {
- if len(self.pendingMessages) == 0 {
- self.readMessages()
- }
-
- ret := self.pendingMessages[0]
- self.pendingMessages = self.pendingMessages[1:]
-
- return ret
-
-}
-
-// Write to the Ethereum network specifying the type of the message and
-// the data. Data can be of type RlpEncodable or []interface{}. Returns
-// nil or if something went wrong an error.
-func (self *Connection) Write(typ MsgType, v ...interface{}) error {
- var pack []byte
-
- slice := [][]interface{}{[]interface{}{byte(typ)}}
- for _, value := range v {
- if encodable, ok := value.(ethutil.RlpEncodeDecode); ok {
- slice = append(slice, encodable.RlpValue())
- } else if raw, ok := value.([]interface{}); ok {
- slice = append(slice, raw)
- } else {
- panic(fmt.Sprintf("Unable to 'write' object of type %T", value))
- }
- }
-
- // Encode the type and the (RLP encoded) data for sending over the wire
- encoded := ethutil.NewValue(slice).Encode()
- payloadLength := ethutil.NumberToBytes(uint32(len(encoded)), 32)
-
- // Write magic token and payload length (first 8 bytes)
- pack = append(MagicToken, payloadLength...)
- pack = append(pack, encoded...)
-
- // Write to the connection
- _, err := self.conn.Write(pack)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (self *Connection) readMessage(data []byte) (msg *Msg, remaining []byte, done bool, err error) {
- if len(data) == 0 {
- return nil, nil, true, nil
- }
-
- if len(data) <= 8 {
- return nil, remaining, false, errors.New("Invalid message")
- }
-
- // Check if the received 4 first bytes are the magic token
- if bytes.Compare(MagicToken, data[:4]) != 0 {
- return nil, nil, false, fmt.Errorf("MagicToken mismatch. Received %v", data[:4])
- }
-
- messageLength := ethutil.BytesToNumber(data[4:8])
- remaining = data[8+messageLength:]
- if int(messageLength) > len(data[8:]) {
- return nil, nil, false, fmt.Errorf("message length %d, expected %d", len(data[8:]), messageLength)
- }
-
- message := data[8 : 8+messageLength]
- decoder := ethutil.NewValueFromBytes(message)
- // Type of message
- t := decoder.Get(0).Uint()
- // Actual data
- d := decoder.SliceFrom(1)
-
- msg = &Msg{
- Type: MsgType(t),
- Data: d,
- }
-
- return
-}
-
-// The basic message reader waits for data on the given connection, decoding
-// and doing a few sanity checks such as if there's a data type and
-// unmarhals the given data
-func (self *Connection) readMessages() (err error) {
- // The recovering function in case anything goes horribly wrong
- defer func() {
- if r := recover(); r != nil {
- err = fmt.Errorf("wire.ReadMessage error: %v", r)
- }
- }()
-
- // Buff for writing network message to
- //buff := make([]byte, 1440)
- var buff []byte
- var totalBytes int
- for {
- // Give buffering some time
- self.conn.SetReadDeadline(time.Now().Add(self.nTimeout * time.Millisecond))
- // Create a new temporarily buffer
- b := make([]byte, 1440)
- // Wait for a message from this peer
- n, _ := self.conn.Read(b)
- if err != nil && n == 0 {
- if err.Error() != "EOF" {
- fmt.Println("err now", err)
- return err
- } else {
- break
- }
-
- // Messages can't be empty
- } else if n == 0 {
- break
- }
-
- buff = append(buff, b[:n]...)
- totalBytes += n
- }
-
- // Reslice buffer
- buff = buff[:totalBytes]
- msg, remaining, done, err := self.readMessage(buff)
- for ; done != true; msg, remaining, done, err = self.readMessage(remaining) {
- //log.Println("rx", msg)
-
- if msg != nil {
- self.pendingMessages = append(self.pendingMessages, msg)
- }
- }
-
- return
-}
-
-func ReadMessage(data []byte) (msg *Msg, remaining []byte, done bool, err error) {
- if len(data) == 0 {
- return nil, nil, true, nil
- }
-
- if len(data) <= 8 {
- return nil, remaining, false, errors.New("Invalid message")
- }
-
- // Check if the received 4 first bytes are the magic token
- if bytes.Compare(MagicToken, data[:4]) != 0 {
- return nil, nil, false, fmt.Errorf("MagicToken mismatch. Received %v", data[:4])
- }
-
- messageLength := ethutil.BytesToNumber(data[4:8])
- remaining = data[8+messageLength:]
- if int(messageLength) > len(data[8:]) {
- return nil, nil, false, fmt.Errorf("message length %d, expected %d", len(data[8:]), messageLength)
- }
-
- message := data[8 : 8+messageLength]
- decoder := ethutil.NewValueFromBytes(message)
- // Type of message
- t := decoder.Get(0).Uint()
- // Actual data
- d := decoder.SliceFrom(1)
-
- msg = &Msg{
- Type: MsgType(t),
- Data: d,
- }
-
- return
-}
-
-func bufferedRead(conn net.Conn) ([]byte, error) {
- return nil, nil
-}
diff --git a/wire/messaging.go b/wire/messaging.go
deleted file mode 100644
index b919aa0f4..000000000
--- a/wire/messaging.go
+++ /dev/null
@@ -1,179 +0,0 @@
-// Package wire provides low level access to the Ethereum network and allows
-// you to broadcast data over the network.
-package wire
-
-import (
- "bytes"
- "fmt"
- "net"
- "time"
-
- "github.com/ethereum/go-ethereum/ethutil"
-)
-
-// Connection interface describing the methods required to implement the wire protocol.
-type Conn interface {
- Write(typ MsgType, v ...interface{}) error
- Read() *Msg
-}
-
-// The magic token which should be the first 4 bytes of every message and can be used as separator between messages.
-var MagicToken = []byte{34, 64, 8, 145}
-
-type MsgType byte
-
-const (
- // Values are given explicitly instead of by iota because these values are
- // defined by the wire protocol spec; it is easier for humans to ensure
- // correctness when values are explicit.
- MsgHandshakeTy = 0x00
- MsgDiscTy = 0x01
- MsgPingTy = 0x02
- MsgPongTy = 0x03
- MsgGetPeersTy = 0x04
- MsgPeersTy = 0x05
-
- MsgStatusTy = 0x10
- //MsgGetTxsTy = 0x11
- MsgTxTy = 0x12
- MsgGetBlockHashesTy = 0x13
- MsgBlockHashesTy = 0x14
- MsgGetBlocksTy = 0x15
- MsgBlockTy = 0x16
- MsgNewBlockTy = 0x17
-)
-
-var msgTypeToString = map[MsgType]string{
- MsgHandshakeTy: "Handshake",
- MsgDiscTy: "Disconnect",
- MsgPingTy: "Ping",
- MsgPongTy: "Pong",
- MsgGetPeersTy: "Get peers",
- MsgStatusTy: "Status",
- MsgPeersTy: "Peers",
- MsgTxTy: "Transactions",
- MsgBlockTy: "Blocks",
- //MsgGetTxsTy: "Get Txs",
- MsgGetBlockHashesTy: "Get block hashes",
- MsgBlockHashesTy: "Block hashes",
- MsgGetBlocksTy: "Get blocks",
-}
-
-func (mt MsgType) String() string {
- return msgTypeToString[mt]
-}
-
-type Msg struct {
- Type MsgType // Specifies how the encoded data should be interpreted
- //Data []byte
- Data *ethutil.Value
-}
-
-func NewMessage(msgType MsgType, data interface{}) *Msg {
- return &Msg{
- Type: msgType,
- Data: ethutil.NewValue(data),
- }
-}
-
-type Messages []*Msg
-
-// The basic message reader waits for data on the given connection, decoding
-// and doing a few sanity checks such as if there's a data type and
-// unmarhals the given data
-func ReadMessages(conn net.Conn) (msgs []*Msg, err error) {
- // The recovering function in case anything goes horribly wrong
- defer func() {
- if r := recover(); r != nil {
- err = fmt.Errorf("wire.ReadMessage error: %v", r)
- }
- }()
-
- var (
- buff []byte
- messages [][]byte
- msgLength int
- )
-
- for {
- // Give buffering some time
- conn.SetReadDeadline(time.Now().Add(5 * time.Millisecond))
- // Create a new temporarily buffer
- b := make([]byte, 1440)
- n, _ := conn.Read(b)
- if err != nil && n == 0 {
- if err.Error() != "EOF" {
- fmt.Println("err now", err)
- return nil, err
- } else {
- break
- }
- }
-
- if n == 0 && len(buff) == 0 {
- // If there's nothing on the wire wait for a bit
- time.Sleep(200 * time.Millisecond)
-
- continue
- }
-
- buff = append(buff, b[:n]...)
- if msgLength == 0 {
- // Check if the received 4 first bytes are the magic token
- if bytes.Compare(MagicToken, buff[:4]) != 0 {
- return nil, fmt.Errorf("MagicToken mismatch. Received %v", buff[:4])
- }
-
- // Read the length of the message
- msgLength = int(ethutil.BytesToNumber(buff[4:8]))
-
- // Remove the token and length
- buff = buff[8:]
- }
-
- if len(buff) >= msgLength {
- messages = append(messages, buff[:msgLength])
- buff = buff[msgLength:]
- msgLength = 0
-
- if len(buff) == 0 {
- break
- }
- }
- }
-
- for _, m := range messages {
- decoder := ethutil.NewValueFromBytes(m)
- // Type of message
- t := decoder.Get(0).Uint()
- // Actual data
- d := decoder.SliceFrom(1)
-
- msgs = append(msgs, &Msg{Type: MsgType(t), Data: d})
- }
-
- return
-}
-
-// The basic message writer takes care of writing data over the given
-// connection and does some basic error checking
-func WriteMessage(conn net.Conn, msg *Msg) error {
- var pack []byte
-
- // Encode the type and the (RLP encoded) data for sending over the wire
- encoded := ethutil.NewValue(append([]interface{}{byte(msg.Type)}, msg.Data.Slice()...)).Encode()
- payloadLength := ethutil.NumberToBytes(uint32(len(encoded)), 32)
-
- // Write magic token and payload length (first 8 bytes)
- pack = append(MagicToken, payloadLength...)
- pack = append(pack, encoded...)
- //fmt.Printf("payload %v (%v) %q\n", msg.Type, conn.RemoteAddr(), encoded)
-
- // Write to the connection
- _, err := conn.Write(pack)
- if err != nil {
- return err
- }
-
- return nil
-}
diff --git a/xeth/hexface.go b/xeth/hexface.go
index 5bf9845d4..6c084f947 100644
--- a/xeth/hexface.go
+++ b/xeth/hexface.go
@@ -3,10 +3,9 @@ package xeth
import (
"bytes"
"encoding/json"
- "sync/atomic"
- "github.com/ethereum/go-ethereum/chain"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
@@ -16,7 +15,7 @@ type JSXEth struct {
*XEth
}
-func NewJSXEth(eth chain.EthManager) *JSXEth {
+func NewJSXEth(eth core.EthManager) *JSXEth {
return &JSXEth{New(eth)}
}
@@ -29,7 +28,7 @@ func (self *JSXEth) BlockByHash(strHash string) *JSBlock {
func (self *JSXEth) BlockByNumber(num int32) *JSBlock {
if num == -1 {
- return NewJSBlock(self.obj.ChainManager().CurrentBlock)
+ return NewJSBlock(self.obj.ChainManager().CurrentBlock())
}
return NewJSBlock(self.obj.ChainManager().GetBlockByNumber(uint64(num)))
@@ -63,12 +62,8 @@ func (self *JSXEth) PeerCount() int {
func (self *JSXEth) Peers() []JSPeer {
var peers []JSPeer
- for peer := self.obj.Peers().Front(); peer != nil; peer = peer.Next() {
- p := peer.Value.(chain.Peer)
- // we only want connected peers
- if atomic.LoadInt32(p.Connected()) != 0 {
- peers = append(peers, *NewJSPeer(p))
- }
+ for _, peer := range self.obj.Peers() {
+ peers = append(peers, *NewJSPeer(peer))
}
return peers
@@ -178,39 +173,13 @@ func (self *JSXEth) FromNumber(str string) string {
return ethutil.BigD(ethutil.Hex2Bytes(str)).String()
}
-func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (*JSReceipt, error) {
- var hash []byte
- var contractCreation bool
- if len(toStr) == 0 {
- contractCreation = true
- } else {
- // Check if an address is stored by this address
- addr := self.World().Config().Get("NameReg").StorageString(toStr).Bytes()
- if len(addr) > 0 {
- hash = addr
- } else {
- hash = ethutil.Hex2Bytes(toStr)
- }
- }
-
- var keyPair *crypto.KeyPair
- var err error
- if ethutil.IsHex(key) {
- keyPair, err = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(key[2:])))
- } else {
- keyPair, err = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(key)))
- }
-
- if err != nil {
- return nil, err
- }
-
+func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
var (
- value = ethutil.Big(valueStr)
- gas = ethutil.Big(gasStr)
- gasPrice = ethutil.Big(gasPriceStr)
+ to []byte
+ value = ethutil.NewValue(valueStr)
+ gas = ethutil.NewValue(gasStr)
+ gasPrice = ethutil.NewValue(gasPriceStr)
data []byte
- tx *types.Transaction
)
if ethutil.IsHex(codeStr) {
@@ -219,31 +188,43 @@ func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr
data = ethutil.Hex2Bytes(codeStr)
}
- if contractCreation {
- tx = types.NewContractCreationTx(value, gas, gasPrice, data)
+ if ethutil.IsHex(toStr) {
+ to = ethutil.Hex2Bytes(toStr[2:])
} else {
- tx = types.NewTransactionMessage(hash, value, gas, gasPrice, data)
+ to = ethutil.Hex2Bytes(toStr)
}
- acc := self.obj.BlockManager().TransState().GetOrNewStateObject(keyPair.Address())
- tx.Nonce = acc.Nonce
- acc.Nonce += 1
- self.obj.BlockManager().TransState().UpdateStateObject(acc)
+ var keyPair *crypto.KeyPair
+ var err error
+ if ethutil.IsHex(key) {
+ keyPair, err = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(key[2:])))
+ } else {
+ keyPair, err = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(key)))
+ }
- tx.Sign(keyPair.PrivateKey)
- self.obj.TxPool().QueueTransaction(tx)
+ if err != nil {
+ return "", err
+ }
- if contractCreation {
- pipelogger.Infof("Contract addr %x", tx.CreationAddress(self.World().State()))
+ tx, err := self.XEth.Transact(keyPair, to, value, gas, gasPrice, data)
+ if err != nil {
+ return "", err
+ }
+ if types.IsContractAddr(to) {
+ return ethutil.Bytes2Hex(core.AddressFromMessage(tx)), nil
}
- return NewJSReciept(contractCreation, tx.CreationAddress(self.World().State()), tx.Hash(), keyPair.Address()), nil
+ return ethutil.Bytes2Hex(tx.Hash()), nil
}
func (self *JSXEth) PushTx(txStr string) (*JSReceipt, error) {
tx := types.NewTransactionFromBytes(ethutil.Hex2Bytes(txStr))
- self.obj.TxPool().QueueTransaction(tx)
- return NewJSReciept(tx.CreatesContract(), tx.CreationAddress(self.World().State()), tx.Hash(), tx.Sender()), nil
+ err := self.obj.TxPool().Add(tx)
+ if err != nil {
+ return nil, err
+ }
+
+ return NewJSReciept(core.MessageCreatesContract(tx), core.AddressFromMessage(tx), tx.Hash(), tx.From()), nil
}
func (self *JSXEth) CompileMutan(code string) string {
diff --git a/xeth/js_types.go b/xeth/js_types.go
index cba674416..04018f6a5 100644
--- a/xeth/js_types.go
+++ b/xeth/js_types.go
@@ -1,14 +1,13 @@
package xeth
import (
- "fmt"
- "strconv"
"strings"
- "github.com/ethereum/go-ethereum/chain"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/state"
)
@@ -95,23 +94,23 @@ type JSTransaction struct {
Confirmations int `json:"confirmations"`
}
-func NewJSTx(tx *types.Transaction, state *state.State) *JSTransaction {
+func NewJSTx(tx *types.Transaction, state *state.StateDB) *JSTransaction {
hash := ethutil.Bytes2Hex(tx.Hash())
- receiver := ethutil.Bytes2Hex(tx.Recipient)
+ receiver := ethutil.Bytes2Hex(tx.To())
if receiver == "0000000000000000000000000000000000000000" {
- receiver = ethutil.Bytes2Hex(tx.CreationAddress(state))
+ receiver = ethutil.Bytes2Hex(core.AddressFromMessage(tx))
}
- sender := ethutil.Bytes2Hex(tx.Sender())
- createsContract := tx.CreatesContract()
+ sender := ethutil.Bytes2Hex(tx.From())
+ createsContract := core.MessageCreatesContract(tx)
var data string
- if tx.CreatesContract() {
- data = strings.Join(chain.Disassemble(tx.Data), "\n")
+ if createsContract {
+ data = strings.Join(core.Disassemble(tx.Data()), "\n")
} else {
- data = ethutil.Bytes2Hex(tx.Data)
+ data = ethutil.Bytes2Hex(tx.Data())
}
- return &JSTransaction{ref: tx, Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: receiver, Contract: tx.CreatesContract(), Gas: tx.Gas.String(), GasPrice: tx.GasPrice.String(), Data: data, Sender: sender, CreatesContract: createsContract, RawData: ethutil.Bytes2Hex(tx.Data)}
+ return &JSTransaction{ref: tx, Hash: hash, Value: ethutil.CurrencyToString(tx.Value()), Address: receiver, Contract: createsContract, Gas: tx.Gas().String(), GasPrice: tx.GasPrice().String(), Data: data, Sender: sender, CreatesContract: createsContract, RawData: ethutil.Bytes2Hex(tx.Data())}
}
func (self *JSTransaction) ToString() string {
@@ -155,38 +154,36 @@ func NewPReciept(contractCreation bool, creationAddress, hash, address []byte) *
// Peer interface exposed to QML
type JSPeer struct {
- ref *chain.Peer
- Inbound bool `json:"isInbound"`
- LastSend int64 `json:"lastSend"`
- LastPong int64 `json:"lastPong"`
- Ip string `json:"ip"`
- Port int `json:"port"`
- Version string `json:"version"`
- LastResponse string `json:"lastResponse"`
- Latency string `json:"latency"`
- Caps string `json:"caps"`
-}
-
-func NewJSPeer(peer chain.Peer) *JSPeer {
- if peer == nil {
- return nil
- }
-
- var ip []string
- for _, i := range peer.Host() {
- ip = append(ip, strconv.Itoa(int(i)))
- }
- ipAddress := strings.Join(ip, ".")
-
- var caps []string
- capsIt := peer.Caps().NewIterator()
- for capsIt.Next() {
- cap := capsIt.Value().Get(0).Str()
- ver := capsIt.Value().Get(1).Uint()
- caps = append(caps, fmt.Sprintf("%s/%d", cap, ver))
- }
-
- return &JSPeer{ref: &peer, Inbound: peer.Inbound(), LastSend: peer.LastSend().Unix(), LastPong: peer.LastPong(), Version: peer.Version(), Ip: ipAddress, Port: int(peer.Port()), Latency: peer.PingTime(), Caps: "[" + strings.Join(caps, ", ") + "]"}
+ ref *p2p.Peer
+ // Inbound bool `json:"isInbound"`
+ // LastSend int64 `json:"lastSend"`
+ // LastPong int64 `json:"lastPong"`
+ // Ip string `json:"ip"`
+ // Port int `json:"port"`
+ // Version string `json:"version"`
+ // LastResponse string `json:"lastResponse"`
+ // Latency string `json:"latency"`
+ // Caps string `json:"caps"`
+}
+
+func NewJSPeer(peer *p2p.Peer) *JSPeer {
+
+ // var ip []string
+ // for _, i := range peer.Host() {
+ // ip = append(ip, strconv.Itoa(int(i)))
+ // }
+ // ipAddress := strings.Join(ip, ".")
+
+ // var caps []string
+ // capsIt := peer.Caps().NewIterator()
+ // for capsIt.Next() {
+ // cap := capsIt.Value().Get(0).Str()
+ // ver := capsIt.Value().Get(1).Uint()
+ // caps = append(caps, fmt.Sprintf("%s/%d", cap, ver))
+ // }
+
+ return &JSPeer{ref: peer}
+ // return &JSPeer{ref: &peer, Inbound: peer.Inbound(), LastSend: peer.LastSend().Unix(), LastPong: peer.LastPong(), Version: peer.Version(), Ip: ipAddress, Port: int(peer.Port()), Latency: peer.PingTime(), Caps: "[" + strings.Join(caps, ", ") + "]"}
}
type JSReceipt struct {
diff --git a/xeth/pipe.go b/xeth/pipe.go
index 8130ab72e..06820cc86 100644
--- a/xeth/pipe.go
+++ b/xeth/pipe.go
@@ -5,44 +5,43 @@ package xeth
*/
import (
- "fmt"
- "strings"
-
- "github.com/ethereum/go-ethereum/chain"
- "github.com/ethereum/go-ethereum/chain/types"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
- "github.com/ethereum/go-ethereum/vm"
)
var pipelogger = logger.NewLogger("XETH")
type VmVars struct {
- State *state.State
+ State *state.StateDB
}
type XEth struct {
- obj chain.EthManager
- blockManager *chain.BlockManager
- blockChain *chain.ChainManager
+ obj core.EthManager
+ blockManager *core.BlockManager
+ chainManager *core.ChainManager
world *World
Vm VmVars
}
-func New(obj chain.EthManager) *XEth {
+func New(obj core.EthManager) *XEth {
pipe := &XEth{
obj: obj,
blockManager: obj.BlockManager(),
- blockChain: obj.ChainManager(),
+ chainManager: obj.ChainManager(),
}
pipe.world = NewWorld(pipe)
return pipe
}
+/*
+ * State / Account accessors
+ */
func (self *XEth) Balance(addr []byte) *ethutil.Value {
return ethutil.NewValue(self.World().safeGet(addr).Balance)
}
@@ -51,36 +50,19 @@ func (self *XEth) Nonce(addr []byte) uint64 {
return self.World().safeGet(addr).Nonce
}
-func (self *XEth) Execute(addr []byte, data []byte, value, gas, price *ethutil.Value) ([]byte, error) {
- return self.ExecuteObject(&Object{self.World().safeGet(addr)}, data, value, gas, price)
-}
-
-func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *ethutil.Value) ([]byte, error) {
- var (
- initiator = state.NewStateObject(self.obj.KeyManager().KeyPair().Address())
- block = self.blockChain.CurrentBlock
- )
-
- self.Vm.State = self.World().State().Copy()
-
- evm := vm.New(NewEnv(self.Vm.State, block, value.BigInt(), initiator.Address()), vm.Type(ethutil.Config.VmType))
-
- msg := vm.NewExecution(evm, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt())
- ret, err := msg.Exec(object.Address(), initiator)
-
- fmt.Println("returned from call", ret, err)
-
- return ret, err
-}
-
func (self *XEth) Block(hash []byte) *types.Block {
- return self.blockChain.GetBlock(hash)
+ return self.chainManager.GetBlock(hash)
}
func (self *XEth) Storage(addr, storageAddr []byte) *ethutil.Value {
return self.World().safeGet(addr).GetStorage(ethutil.BigD(storageAddr))
}
+func (self *XEth) Exists(addr []byte) bool {
+ return self.World().Get(addr) != nil
+}
+
+// Converts the given private key to an address
func (self *XEth) ToAddress(priv []byte) []byte {
pair, err := crypto.NewKeyPairFromSec(priv)
if err != nil {
@@ -90,11 +72,29 @@ func (self *XEth) ToAddress(priv []byte) []byte {
return pair.Address()
}
-func (self *XEth) Exists(addr []byte) bool {
- return self.World().Get(addr) != nil
+/*
+ * Execution helpers
+ */
+func (self *XEth) Execute(addr []byte, data []byte, value, gas, price *ethutil.Value) ([]byte, error) {
+ return self.ExecuteObject(&Object{self.World().safeGet(addr)}, data, value, gas, price)
}
-func (self *XEth) TransactString(key *crypto.KeyPair, rec string, value, gas, price *ethutil.Value, data []byte) ([]byte, error) {
+func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *ethutil.Value) ([]byte, error) {
+ var (
+ initiator = state.NewStateObject(self.obj.KeyManager().KeyPair().Address())
+ block = self.chainManager.CurrentBlock()
+ )
+
+ self.Vm.State = self.World().State().Copy()
+
+ vmenv := NewEnv(self.Vm.State, block, value.BigInt(), initiator.Address())
+ return vmenv.Call(initiator, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt())
+}
+
+/*
+ * Transactional methods
+ */
+func (self *XEth) TransactString(key *crypto.KeyPair, rec string, value, gas, price *ethutil.Value, data []byte) (*types.Transaction, error) {
// Check if an address is stored by this address
var hash []byte
addr := self.World().Config().Get("NameReg").StorageString(rec).Bytes()
@@ -109,57 +109,62 @@ func (self *XEth) TransactString(key *crypto.KeyPair, rec string, value, gas, pr
return self.Transact(key, hash, value, gas, price, data)
}
-func (self *XEth) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *ethutil.Value, data []byte) ([]byte, error) {
+func (self *XEth) Transact(key *crypto.KeyPair, to []byte, value, gas, price *ethutil.Value, data []byte) (*types.Transaction, error) {
var hash []byte
var contractCreation bool
- if rec == nil {
+ if types.IsContractAddr(to) {
contractCreation = true
+ } else {
+ // Check if an address is stored by this address
+ addr := self.World().Config().Get("NameReg").Storage(to).Bytes()
+ if len(addr) > 0 {
+ hash = addr
+ } else {
+ hash = to
+ }
}
var tx *types.Transaction
- // Compile and assemble the given data
if contractCreation {
- script, err := ethutil.Compile(string(data), false)
- if err != nil {
- return nil, err
- }
-
- tx = types.NewContractCreationTx(value.BigInt(), gas.BigInt(), price.BigInt(), script)
+ tx = types.NewContractCreationTx(value.BigInt(), gas.BigInt(), price.BigInt(), data)
} else {
- data := ethutil.StringToByteFunc(string(data), func(s string) (ret []byte) {
- slice := strings.Split(s, "\n")
- for _, dataItem := range slice {
- d := ethutil.FormatData(dataItem)
- ret = append(ret, d...)
- }
- return
- })
-
tx = types.NewTransactionMessage(hash, value.BigInt(), gas.BigInt(), price.BigInt(), data)
}
- acc := self.blockManager.TransState().GetOrNewStateObject(key.Address())
- tx.Nonce = acc.Nonce
- acc.Nonce += 1
- self.blockManager.TransState().UpdateStateObject(acc)
+ state := self.chainManager.TransState()
+ nonce := state.GetNonce(key.Address())
+ tx.SetNonce(nonce)
tx.Sign(key.PrivateKey)
- self.obj.TxPool().QueueTransaction(tx)
+
+ // Do some pre processing for our "pre" events and hooks
+ block := self.chainManager.NewBlock(key.Address())
+ coinbase := state.GetStateObject(key.Address())
+ coinbase.SetGasPool(block.GasLimit)
+ self.blockManager.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true)
+
+ err := self.obj.TxPool().Add(tx)
+ if err != nil {
+ return nil, err
+ }
+ state.SetNonce(key.Address(), nonce+1)
if contractCreation {
- addr := tx.CreationAddress(self.World().State())
+ addr := core.AddressFromMessage(tx)
pipelogger.Infof("Contract addr %x\n", addr)
-
- return addr, nil
}
- return tx.Hash(), nil
+ return tx, nil
}
func (self *XEth) PushTx(tx *types.Transaction) ([]byte, error) {
- self.obj.TxPool().QueueTransaction(tx)
- if tx.Recipient == nil {
- addr := tx.CreationAddress(self.World().State())
+ err := self.obj.TxPool().Add(tx)
+ if err != nil {
+ return nil, err
+ }
+
+ if tx.To() == nil {
+ addr := core.AddressFromMessage(tx)
pipelogger.Infof("Contract addr %x\n", addr)
return addr, nil
}
diff --git a/xeth/vm_env.go b/xeth/vm_env.go
index 10575ad79..7fb674a94 100644
--- a/xeth/vm_env.go
+++ b/xeth/vm_env.go
@@ -2,19 +2,23 @@ package xeth
import (
"math/big"
- "github.com/ethereum/go-ethereum/chain/types"
+
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm"
)
type VMEnv struct {
- state *state.State
+ state *state.StateDB
block *types.Block
value *big.Int
sender []byte
+
+ depth int
}
-func NewEnv(state *state.State, block *types.Block, value *big.Int, sender []byte) *VMEnv {
+func NewEnv(state *state.StateDB, block *types.Block, value *big.Int, sender []byte) *VMEnv {
return &VMEnv{
state: state,
block: block,
@@ -31,9 +35,31 @@ func (self *VMEnv) Time() int64 { return self.block.Time }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
func (self *VMEnv) Value() *big.Int { return self.value }
-func (self *VMEnv) State() *state.State { return self.state }
+func (self *VMEnv) State() *state.StateDB { return self.state }
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
-func (self *VMEnv) AddLog(*state.Log) {}
+func (self *VMEnv) Depth() int { return self.depth }
+func (self *VMEnv) SetDepth(i int) { self.depth = i }
+func (self *VMEnv) AddLog(log state.Log) {
+ self.state.AddLog(log)
+}
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
return vm.Transfer(from, to, amount)
}
+
+func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execution {
+ return core.NewExecution(self, addr, data, gas, price, value)
+}
+
+func (self *VMEnv) Call(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(addr, data, gas, price, value)
+ return exe.Call(addr, me)
+}
+func (self *VMEnv) CallCode(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(me.Address(), data, gas, price, value)
+ return exe.Call(addr, me)
+}
+
+func (self *VMEnv) Create(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
+ exe := self.vm(addr, data, gas, price, value)
+ return exe.Create(me)
+}
diff --git a/xeth/world.go b/xeth/world.go
index 6fb757d67..008a08423 100644
--- a/xeth/world.go
+++ b/xeth/world.go
@@ -1,8 +1,7 @@
package xeth
import (
- "container/list"
-
+ "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/state"
)
@@ -22,8 +21,8 @@ func (self *XEth) World() *World {
return self.world
}
-func (self *World) State() *state.State {
- return self.pipe.blockManager.CurrentState()
+func (self *World) State() *state.StateDB {
+ return self.pipe.chainManager.State()
}
func (self *World) Get(addr []byte) *Object {
@@ -55,7 +54,7 @@ func (self *World) IsListening() bool {
return self.pipe.obj.IsListening()
}
-func (self *World) Peers() *list.List {
+func (self *World) Peers() []*p2p.Peer {
return self.pipe.obj.Peers()
}