Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
3af35d92
Commit
3af35d92
authored
May 10, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'release/poc5-rc2'
parents
2096b3a9
dbf8645a
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
300 additions
and
361 deletions
+300
-361
asm.go
ethchain/asm.go
+4
-17
closure.go
ethchain/closure.go
+4
-6
state.go
ethchain/state.go
+41
-41
state_manager.go
ethchain/state_manager.go
+25
-81
state_object.go
ethchain/state_object.go
+3
-28
transaction_pool.go
ethchain/transaction_pool.go
+1
-2
types.go
ethchain/types.go
+114
-20
vm.go
ethchain/vm.go
+29
-34
vm_test.go
ethchain/vm_test.go
+9
-74
ethereum.go
ethereum.go
+46
-40
pub.go
ethpub/pub.go
+12
-2
packages.go
ethrpc/packages.go
+6
-2
common_test.go
ethutil/common_test.go
+1
-1
config.go
ethutil/config.go
+1
-2
rlp_test.go
ethutil/rlp_test.go
+4
-11
No files found.
ethchain/asm.go
View file @
3af35d92
...
...
@@ -21,9 +21,10 @@ func Disassemble(script []byte) (asm []string) {
asm
=
append
(
asm
,
fmt
.
Sprintf
(
"%v"
,
op
))
switch
op
{
case
oPUSH
:
// Push PC+1 on to the stack
case
oPUSH
1
,
oPUSH2
,
oPUSH3
,
oPUSH4
,
oPUSH5
,
oPUSH6
,
oPUSH7
,
oPUSH8
,
oPUSH9
,
oPUSH10
,
oPUSH11
,
oPUSH12
,
oPUSH13
,
oPUSH14
,
oPUSH15
,
oPUSH16
,
oPUSH17
,
oPUSH18
,
oPUSH19
,
oPUSH20
,
oPUSH21
,
oPUSH22
,
oPUSH23
,
oPUSH24
,
oPUSH25
,
oPUSH26
,
oPUSH27
,
oPUSH28
,
oPUSH29
,
oPUSH30
,
oPUSH31
,
oPUSH32
:
pc
.
Add
(
pc
,
ethutil
.
Big1
)
data
:=
script
[
pc
.
Int64
()
:
pc
.
Int64
()
+
32
]
a
:=
int64
(
op
)
-
int64
(
oPUSH1
)
+
1
data
:=
script
[
pc
.
Int64
()
:
pc
.
Int64
()
+
a
]
val
:=
ethutil
.
BigD
(
data
)
var
b
[]
byte
...
...
@@ -35,21 +36,7 @@ func Disassemble(script []byte) (asm []string) {
asm
=
append
(
asm
,
fmt
.
Sprintf
(
"0x%x"
,
b
))
pc
.
Add
(
pc
,
big
.
NewInt
(
31
))
case
oPUSH20
:
pc
.
Add
(
pc
,
ethutil
.
Big1
)
data
:=
script
[
pc
.
Int64
()
:
pc
.
Int64
()
+
20
]
val
:=
ethutil
.
BigD
(
data
)
var
b
[]
byte
if
val
.
Int64
()
==
0
{
b
=
[]
byte
{
0
}
}
else
{
b
=
val
.
Bytes
()
}
asm
=
append
(
asm
,
fmt
.
Sprintf
(
"0x%x"
,
b
))
pc
.
Add
(
pc
,
big
.
NewInt
(
19
))
pc
.
Add
(
pc
,
big
.
NewInt
(
a
-
1
))
}
pc
.
Add
(
pc
,
ethutil
.
Big1
)
...
...
ethchain/closure.go
View file @
3af35d92
...
...
@@ -11,7 +11,7 @@ type ClosureRef interface {
ReturnGas
(
*
big
.
Int
,
*
big
.
Int
,
*
State
)
Address
()
[]
byte
GetMem
(
*
big
.
Int
)
*
ethutil
.
Value
Set
Mem
(
*
big
.
Int
,
*
ethutil
.
Value
)
Set
Store
(
*
big
.
Int
,
*
ethutil
.
Value
)
N
()
*
big
.
Int
}
...
...
@@ -24,20 +24,18 @@ type Closure struct {
Gas
*
big
.
Int
Price
*
big
.
Int
Value
*
big
.
Int
Args
[]
byte
}
// Create a new closure for the given data items
func
NewClosure
(
callee
,
object
*
StateObject
,
script
[]
byte
,
state
*
State
,
gas
,
price
,
val
*
big
.
Int
)
*
Closure
{
func
NewClosure
(
callee
,
object
*
StateObject
,
script
[]
byte
,
state
*
State
,
gas
,
price
*
big
.
Int
)
*
Closure
{
c
:=
&
Closure
{
callee
:
callee
,
object
:
object
,
Script
:
script
,
State
:
state
,
Args
:
nil
}
// In most cases gas, price and value are pointers to transaction objects
// and we don't want the transaction's values to change.
c
.
Gas
=
new
(
big
.
Int
)
.
Set
(
gas
)
c
.
Price
=
new
(
big
.
Int
)
.
Set
(
price
)
c
.
Value
=
new
(
big
.
Int
)
.
Set
(
val
)
return
c
}
...
...
@@ -66,8 +64,8 @@ func (c *Closure) Gets(x, y *big.Int) *ethutil.Value {
return
ethutil
.
NewValue
(
partial
)
}
func
(
c
*
Closure
)
Set
Mem
(
x
*
big
.
Int
,
val
*
ethutil
.
Value
)
{
c
.
object
.
Set
Mem
(
x
,
val
)
func
(
c
*
Closure
)
Set
Storage
(
x
*
big
.
Int
,
val
*
ethutil
.
Value
)
{
c
.
object
.
Set
Storage
(
x
,
val
)
}
func
(
c
*
Closure
)
Address
()
[]
byte
{
...
...
ethchain/state.go
View file @
3af35d92
...
...
@@ -15,11 +15,13 @@ type State struct {
trie
*
ethutil
.
Trie
// Nested states
states
map
[
string
]
*
State
manifest
*
Manifest
}
// Create a new state from a given trie
func
NewState
(
trie
*
ethutil
.
Trie
)
*
State
{
return
&
State
{
trie
:
trie
,
states
:
make
(
map
[
string
]
*
State
)}
return
&
State
{
trie
:
trie
,
states
:
make
(
map
[
string
]
*
State
)
,
manifest
:
NewManifest
()
}
}
// Resets the trie and all siblings
...
...
@@ -114,46 +116,6 @@ func (s *State) Copy() *State {
return
NewState
(
s
.
trie
.
Copy
())
}
type
ObjType
byte
const
(
NilTy
ObjType
=
iota
AccountTy
ContractTy
UnknownTy
)
/*
// Returns the object stored at key and the type stored at key
// Returns nil if nothing is stored
func (s *State) GetStateObject(key []byte) (*ethutil.Value, ObjType) {
// Fetch data from the trie
data := s.trie.Get(string(key))
// Returns the nil type, indicating nothing could be retrieved.
// Anything using this function should check for this ret val
if data == "" {
return nil, NilTy
}
var typ ObjType
val := ethutil.NewValueFromBytes([]byte(data))
// Check the length of the retrieved value.
// Len 2 = Account
// Len 3 = Contract
// Other = invalid for now. If other types emerge, add them here
if val.Len() == 2 {
typ = AccountTy
} else if val.Len() == 3 {
typ = ContractTy
} else {
typ = UnknownTy
}
return val, typ
}
*/
// Updates any given state object
func
(
s
*
State
)
UpdateStateObject
(
object
*
StateObject
)
{
addr
:=
object
.
Address
()
...
...
@@ -163,6 +125,7 @@ func (s *State) UpdateStateObject(object *StateObject) {
}
s
.
trie
.
Update
(
string
(
addr
),
string
(
object
.
RlpEncode
()))
s
.
manifest
.
AddObjectChange
(
object
)
}
func
(
s
*
State
)
Put
(
key
,
object
[]
byte
)
{
...
...
@@ -172,3 +135,40 @@ func (s *State) Put(key, object []byte) {
func
(
s
*
State
)
Root
()
interface
{}
{
return
s
.
trie
.
Root
}
// Object manifest
//
// The object manifest is used to keep changes to the state so we can keep track of the changes
// that occurred during a state transitioning phase.
type
Manifest
struct
{
// XXX These will be handy in the future. Not important for now.
objectAddresses
map
[
string
]
bool
storageAddresses
map
[
string
]
map
[
string
]
bool
objectChanges
map
[
string
]
*
StateObject
storageChanges
map
[
string
]
map
[
string
]
*
big
.
Int
}
func
NewManifest
()
*
Manifest
{
m
:=
&
Manifest
{
objectAddresses
:
make
(
map
[
string
]
bool
),
storageAddresses
:
make
(
map
[
string
]
map
[
string
]
bool
)}
m
.
Reset
()
return
m
}
func
(
m
*
Manifest
)
Reset
()
{
m
.
objectChanges
=
make
(
map
[
string
]
*
StateObject
)
m
.
storageChanges
=
make
(
map
[
string
]
map
[
string
]
*
big
.
Int
)
}
func
(
m
*
Manifest
)
AddObjectChange
(
stateObject
*
StateObject
)
{
m
.
objectChanges
[
string
(
stateObject
.
Address
())]
=
stateObject
}
func
(
m
*
Manifest
)
AddStorageChange
(
stateObject
*
StateObject
,
storageAddr
[]
byte
,
storage
*
big
.
Int
)
{
if
m
.
storageChanges
[
string
(
stateObject
.
Address
())]
==
nil
{
m
.
storageChanges
[
string
(
stateObject
.
Address
())]
=
make
(
map
[
string
]
*
big
.
Int
)
}
m
.
storageChanges
[
string
(
stateObject
.
Address
())][
string
(
storageAddr
)]
=
storage
}
ethchain/state_manager.go
View file @
3af35d92
...
...
@@ -25,24 +25,16 @@ type EthManager interface {
type
StateManager
struct
{
// Mutex for locking the block processor. Blocks can only be handled one at a time
mutex
sync
.
Mutex
// Canonical block chain
bc
*
BlockChain
// States for addresses. You can watch any address
// at any given time
stateObjectCache
*
StateObjectCache
// Stack for processing contracts
stack
*
Stack
// non-persistent key/value memory storage
mem
map
[
string
]
*
big
.
Int
// Proof of work used for validating
Pow
PoW
// The ethereum manager interface
Ethereum
EthManager
SecondaryBlockProcessor
BlockProcessor
// The managed states
// Processor state. Anything processed will be applied to this
// state
...
...
@@ -50,21 +42,28 @@ type StateManager struct {
// Comparative state it used for comparing and validating end
// results
compState
*
State
manifest
*
Manifest
// 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
// Manifest for keeping changes regarding state objects. See `notify`
// XXX Should we move the manifest to the State object. Benefit:
// * All states can keep their own local changes
//manifest *Manifest
}
func
NewStateManager
(
ethereum
EthManager
)
*
StateManager
{
sm
:=
&
StateManager
{
stack
:
NewStack
(),
mem
:
make
(
map
[
string
]
*
big
.
Int
),
Pow
:
&
EasyPow
{},
Ethereum
:
ethereum
,
stateObjectCache
:
NewStateObjectCache
(),
bc
:
ethereum
.
BlockChain
(),
manifest
:
NewManifest
(),
stack
:
NewStack
(),
mem
:
make
(
map
[
string
]
*
big
.
Int
),
Pow
:
&
EasyPow
{},
Ethereum
:
ethereum
,
bc
:
ethereum
.
BlockChain
(),
//manifest: NewManifest(),
}
sm
.
procState
=
ethereum
.
BlockChain
()
.
CurrentBlock
.
State
()
sm
.
transState
=
sm
.
procState
.
Copy
()
return
sm
}
...
...
@@ -72,22 +71,8 @@ func (sm *StateManager) ProcState() *State {
return
sm
.
procState
}
// Watches any given address and puts it in the address state store
func
(
sm
*
StateManager
)
WatchAddr
(
addr
[]
byte
)
*
CachedStateObject
{
//XXX account := sm.bc.CurrentBlock.state.GetAccount(addr)
account
:=
sm
.
procState
.
GetAccount
(
addr
)
return
sm
.
stateObjectCache
.
Add
(
addr
,
account
)
}
func
(
sm
*
StateManager
)
GetAddrState
(
addr
[]
byte
)
*
CachedStateObject
{
account
:=
sm
.
stateObjectCache
.
Get
(
addr
)
if
account
==
nil
{
a
:=
sm
.
procState
.
GetAccount
(
addr
)
account
=
&
CachedStateObject
{
Nonce
:
a
.
Nonce
,
Object
:
a
}
}
return
account
func
(
sm
*
StateManager
)
TransState
()
*
State
{
return
sm
.
transState
}
func
(
sm
*
StateManager
)
BlockChain
()
*
BlockChain
{
...
...
@@ -201,19 +186,13 @@ func (sm *StateManager) ProcessBlock(block *Block, dontReact bool) error {
// Add the block to the chain
sm
.
bc
.
Add
(
block
)
// If there's a block processor present, pass in the block for further
// processing
if
sm
.
SecondaryBlockProcessor
!=
nil
{
sm
.
SecondaryBlockProcessor
.
ProcessBlock
(
block
)
}
ethutil
.
Config
.
Log
.
Infof
(
"[STATE] Added block #%d (%x)
\n
"
,
block
.
BlockInfo
()
.
Number
,
block
.
Hash
())
if
dontReact
==
false
{
sm
.
Ethereum
.
Reactor
()
.
Post
(
"newBlock"
,
block
)
sm
.
notifyChanges
()
sm
.
manifest
.
Reset
()
sm
.
procState
.
manifest
.
Reset
()
}
}
else
{
fmt
.
Println
(
"total diff failed"
)
...
...
@@ -323,7 +302,7 @@ func (sm *StateManager) EvalScript(script []byte, object *StateObject, tx *Trans
return
}
closure
:=
NewClosure
(
account
,
object
,
script
,
sm
.
procState
,
tx
.
Gas
,
tx
.
GasPrice
,
tx
.
Value
)
closure
:=
NewClosure
(
account
,
object
,
script
,
sm
.
procState
,
tx
.
Gas
,
tx
.
GasPrice
)
vm
:=
NewVm
(
sm
.
procState
,
sm
,
RuntimeVars
{
Origin
:
account
.
Address
(),
BlockNumber
:
block
.
BlockInfo
()
.
Number
,
...
...
@@ -331,59 +310,24 @@ func (sm *StateManager) EvalScript(script []byte, object *StateObject, tx *Trans
Coinbase
:
block
.
Coinbase
,
Time
:
block
.
Time
,
Diff
:
block
.
Difficulty
,
Value
:
tx
.
Value
,
//Price: tx.GasPrice,
})
closure
.
Call
(
vm
,
tx
.
Data
,
nil
)
// Update the account (refunds)
sm
.
procState
.
UpdateStateObject
(
account
)
sm
.
manifest
.
AddObjectChange
(
account
)
sm
.
procState
.
UpdateStateObject
(
object
)
sm
.
manifest
.
AddObjectChange
(
object
)
}
func
(
sm
*
StateManager
)
notifyChanges
()
{
for
addr
,
stateObject
:=
range
sm
.
manifest
.
objectChanges
{
for
addr
,
stateObject
:=
range
sm
.
procState
.
manifest
.
objectChanges
{
sm
.
Ethereum
.
Reactor
()
.
Post
(
"object:"
+
addr
,
stateObject
)
}
for
stateObjectAddr
,
mappedObjects
:=
range
sm
.
manifest
.
storageChanges
{
for
stateObjectAddr
,
mappedObjects
:=
range
sm
.
procState
.
manifest
.
storageChanges
{
for
addr
,
value
:=
range
mappedObjects
{
sm
.
Ethereum
.
Reactor
()
.
Post
(
"storage:"
+
stateObjectAddr
+
":"
+
addr
,
&
StorageState
{[]
byte
(
stateObjectAddr
),
[]
byte
(
addr
),
value
})
}
}
}
type
Manifest
struct
{
// XXX These will be handy in the future. Not important for now.
objectAddresses
map
[
string
]
bool
storageAddresses
map
[
string
]
map
[
string
]
bool
objectChanges
map
[
string
]
*
StateObject
storageChanges
map
[
string
]
map
[
string
]
*
big
.
Int
}
func
NewManifest
()
*
Manifest
{
m
:=
&
Manifest
{
objectAddresses
:
make
(
map
[
string
]
bool
),
storageAddresses
:
make
(
map
[
string
]
map
[
string
]
bool
)}
m
.
Reset
()
return
m
}
func
(
m
*
Manifest
)
Reset
()
{
m
.
objectChanges
=
make
(
map
[
string
]
*
StateObject
)
m
.
storageChanges
=
make
(
map
[
string
]
map
[
string
]
*
big
.
Int
)
}
func
(
m
*
Manifest
)
AddObjectChange
(
stateObject
*
StateObject
)
{
m
.
objectChanges
[
string
(
stateObject
.
Address
())]
=
stateObject
}
func
(
m
*
Manifest
)
AddStorageChange
(
stateObject
*
StateObject
,
storageAddr
[]
byte
,
storage
*
big
.
Int
)
{
if
m
.
storageChanges
[
string
(
stateObject
.
Address
())]
==
nil
{
m
.
storageChanges
[
string
(
stateObject
.
Address
())]
=
make
(
map
[
string
]
*
big
.
Int
)
}
m
.
storageChanges
[
string
(
stateObject
.
Address
())][
string
(
storageAddr
)]
=
storage
}
ethchain/state_object.go
View file @
3af35d92
...
...
@@ -77,7 +77,7 @@ func (c *StateObject) SetAddr(addr []byte, value interface{}) {
c
.
state
.
trie
.
Update
(
string
(
addr
),
string
(
ethutil
.
NewValue
(
value
)
.
Encode
()))
}
func
(
c
*
StateObject
)
Set
Mem
(
num
*
big
.
Int
,
val
*
ethutil
.
Value
)
{
func
(
c
*
StateObject
)
Set
Storage
(
num
*
big
.
Int
,
val
*
ethutil
.
Value
)
{
addr
:=
ethutil
.
BigToBytes
(
num
,
256
)
c
.
SetAddr
(
addr
,
val
)
}
...
...
@@ -160,33 +160,8 @@ func (c *StateObject) RlpDecode(data []byte) {
c
.
script
=
decoder
.
Get
(
3
)
.
Bytes
()
}
// The cached state and state object cache are helpers which will give you somewhat
// control over the nonce. When creating new transactions you're interested in the 'next'
// nonce rather than the current nonce. This to avoid creating invalid-nonce transactions.
type
StateObjectCache
struct
{
cachedObjects
map
[
string
]
*
CachedStateObject
}
func
NewStateObjectCache
()
*
StateObjectCache
{
return
&
StateObjectCache
{
cachedObjects
:
make
(
map
[
string
]
*
CachedStateObject
)}
}
func
(
s
*
StateObjectCache
)
Add
(
addr
[]
byte
,
object
*
StateObject
)
*
CachedStateObject
{
state
:=
&
CachedStateObject
{
Nonce
:
object
.
Nonce
,
Object
:
object
}
s
.
cachedObjects
[
string
(
addr
)]
=
state
return
state
}
func
(
s
*
StateObjectCache
)
Get
(
addr
[]
byte
)
*
CachedStateObject
{
return
s
.
cachedObjects
[
string
(
addr
)]
}
type
CachedStateObject
struct
{
Nonce
uint64
Object
*
StateObject
}
// Storage change object. Used by the manifest for notifying changes to
// the sub channels.
type
StorageState
struct
{
StateAddress
[]
byte
Address
[]
byte
...
...
ethchain/transaction_pool.go
View file @
3af35d92
...
...
@@ -148,8 +148,7 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error {
}
// Get the sender
accountState
:=
pool
.
Ethereum
.
StateManager
()
.
GetAddrState
(
tx
.
Sender
())
sender
:=
accountState
.
Object
sender
:=
pool
.
Ethereum
.
StateManager
()
.
procState
.
GetAccount
(
tx
.
Sender
())
totAmount
:=
new
(
big
.
Int
)
.
Add
(
tx
.
Value
,
new
(
big
.
Int
)
.
Mul
(
TxFee
,
TxFeeRat
))
// Make sure there's enough in the sender's account. Having insufficient
...
...
ethchain/types.go
View file @
3af35d92
...
...
@@ -48,8 +48,6 @@ const (
oGASLIMIT
=
0x45
// 0x50 range - 'storage' and execution
oPUSH
=
0x50
oPUSH20
=
0x80
oPOP
=
0x51
oDUP
=
0x52
oSWAP
=
0x53
...
...
@@ -63,14 +61,48 @@ const (
oPC
=
0x5b
oMSIZE
=
0x5c
// 0x60 range - closures
oCREATE
=
0x60
oCALL
=
0x61
oRETURN
=
0x62
// 0x60 range
oPUSH1
=
0x60
oPUSH2
=
0x61
oPUSH3
=
0x62
oPUSH4
=
0x63
oPUSH5
=
0x64
oPUSH6
=
0x65
oPUSH7
=
0x66
oPUSH8
=
0x67
oPUSH9
=
0x68
oPUSH10
=
0x69
oPUSH11
=
0x6a
oPUSH12
=
0x6b
oPUSH13
=
0x6c
oPUSH14
=
0x6d
oPUSH15
=
0x6e
oPUSH16
=
0x6f
oPUSH17
=
0x70
oPUSH18
=
0x71
oPUSH19
=
0x72
oPUSH20
=
0x73
oPUSH21
=
0x74
oPUSH22
=
0x75
oPUSH23
=
0x76
oPUSH24
=
0x77
oPUSH25
=
0x78
oPUSH26
=
0x79
oPUSH27
=
0x7a
oPUSH28
=
0x7b
oPUSH29
=
0x7c
oPUSH30
=
0x7d
oPUSH31
=
0x7e
oPUSH32
=
0x7f
// 0xf0 range - closures
oCREATE
=
0xf0
oCALL
=
0xf1
oRETURN
=
0xf2
// 0x70 range - other
oLOG
=
0x
70
// XXX Unofficial
oSUICIDE
=
0x
7
f
oLOG
=
0x
fe
// XXX Unofficial
oSUICIDE
=
0x
f
f
)
// Since the opcodes aren't all in order we can't use a regular slice
...
...
@@ -119,8 +151,6 @@ var opCodeToString = map[OpCode]string{
oGASLIMIT
:
"GASLIMIT"
,
// 0x50 range - 'storage' and execution
oPUSH
:
"PUSH"
,
oPOP
:
"POP"
,
oDUP
:
"DUP"
,
oSWAP
:
"SWAP"
,
oMLOAD
:
"MLOAD"
,
...
...
@@ -133,7 +163,41 @@ var opCodeToString = map[OpCode]string{
oPC
:
"PC"
,
oMSIZE
:
"MSIZE"
,
// 0x60 range - closures
// 0x60 range - push
oPUSH1
:
"PUSH1"
,
oPUSH2
:
"PUSH2"
,
oPUSH3
:
"PUSH3"
,
oPUSH4
:
"PUSH4"
,
oPUSH5
:
"PUSH5"
,
oPUSH6
:
"PUSH6"
,
oPUSH7
:
"PUSH7"
,
oPUSH8
:
"PUSH8"
,
oPUSH9
:
"PUSH9"
,
oPUSH10
:
"PUSH10"
,
oPUSH11
:
"PUSH11"
,
oPUSH12
:
"PUSH12"
,
oPUSH13
:
"PUSH13"
,
oPUSH14
:
"PUSH14"
,
oPUSH15
:
"PUSH15"
,
oPUSH16
:
"PUSH16"
,
oPUSH17
:
"PUSH17"
,
oPUSH18
:
"PUSH18"
,
oPUSH19
:
"PUSH19"
,
oPUSH20
:
"PUSH20"
,
oPUSH21
:
"PUSH21"
,
oPUSH22
:
"PUSH22"
,
oPUSH23
:
"PUSH23"
,
oPUSH24
:
"PUSH24"
,
oPUSH25
:
"PUSH25"
,
oPUSH26
:
"PUSH26"
,
oPUSH27
:
"PUSH27"
,
oPUSH28
:
"PUSH28"
,
oPUSH29
:
"PUSH29"
,
oPUSH30
:
"PUSH30"
,
oPUSH31
:
"PUSH31"
,
oPUSH32
:
"PUSH32"
,
// 0xf0 range
oCREATE
:
"CREATE"
,
oCALL
:
"CALL"
,
oRETURN
:
"RETURN"
,
...
...
@@ -193,10 +257,6 @@ var OpCodes = map[string]byte{
"GASLIMIT"
:
0x45
,
// 0x50 range - 'storage' and execution
"PUSH"
:
0x50
,
"PUSH20"
:
0x80
,
"POP"
:
0x51
,
"DUP"
:
0x52
,
"SWAP"
:
0x53
,
...
...
@@ -210,13 +270,47 @@ var OpCodes = map[string]byte{
"PC"
:
0x5b
,
"MSIZE"
:
0x5c
,
// 0x60 range - closures
"CREATE"
:
0x60
,
"CALL"
:
0x61
,
"RETURN"
:
0x62
,
// 0x70 range - 'push'
"PUSH1"
:
0x60
,
"PUSH2"
:
0x61
,
"PUSH3"
:
0x62
,
"PUSH4"
:
0x63
,
"PUSH5"
:
0x64
,
"PUSH6"
:
0x65
,
"PUSH7"
:
0x66
,
"PUSH8"
:
0x67
,
"PUSH9"
:
0x68
,
"PUSH10"
:
0x69
,
"PUSH11"
:
0x6a
,
"PUSH12"
:
0x6b
,
"PUSH13"
:
0x6c
,
"PUSH14"
:
0x6d
,
"PUSH15"
:
0x6e
,
"PUSH16"
:
0x6f
,
"PUSH17"
:
0x70
,
"PUSH18"
:
0x71
,
"PUSH19"
:
0x72
,
"PUSH20"
:
0x73
,
"PUSH21"
:
0x74
,
"PUSH22"
:
0x75
,
"PUSH23"
:
0x76
,
"PUSH24"
:
0x77
,
"PUSH25"
:
0x78
,
"PUSH26"
:
0x70
,
"PUSH27"
:
0x7a
,
"PUSH28"
:
0x7b
,
"PUSH29"
:
0x7c
,
"PUSH30"
:
0x7d
,
"PUSH31"
:
0x7e
,
"PUSH32"
:
0x7f
,
// 0xf0 range - closures
"CREATE"
:
0xf0
,
"CALL"
:
0xf1
,
"RETURN"
:
0xf2
,
// 0x70 range - other
"LOG"
:
0x
70
,
"LOG"
:
0x
fe
,
"SUICIDE"
:
0x7f
,
}
...
...
ethchain/vm.go
View file @
3af35d92
...
...
@@ -53,6 +53,7 @@ type RuntimeVars struct {
Time
int64
Diff
*
big
.
Int
TxData
[]
string
Value
*
big
.
Int
}
func
NewVm
(
state
*
State
,
stateManager
*
StateManager
,
vars
RuntimeVars
)
*
Vm
{
...
...
@@ -94,6 +95,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
if
ethutil
.
Config
.
Debug
{
ethutil
.
Config
.
Log
.
Debugf
(
"# op
\n
"
)
}
fmt
.
Println
(
closure
.
Script
)
for
{
// The base for all big integer arithmetic
...
...
@@ -104,11 +106,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
val
:=
closure
.
Get
(
pc
)
// Get the opcode (it must be an opcode!)
op
:=
OpCode
(
val
.
Uint
())
/*
if ethutil.Config.Debug {
ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
}
*/
if
ethutil
.
Config
.
Debug
{
ethutil
.
Config
.
Log
.
Debugf
(
"%-3d %-4s"
,
pc
,
op
.
String
())
}
gas
:=
new
(
big
.
Int
)
useGas
:=
func
(
amount
*
big
.
Int
)
{
...
...
@@ -318,14 +318,13 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
case
oADDRESS
:
stack
.
Push
(
ethutil
.
BigD
(
closure
.
Object
()
.
Address
()))
case
oBALANCE
:
stack
.
Push
(
closure
.
Value
)
stack
.
Push
(
closure
.
object
.
Amount
)
case
oORIGIN
:
stack
.
Push
(
ethutil
.
BigD
(
vm
.
vars
.
Origin
))
case
oCALLER
:
stack
.
Push
(
ethutil
.
BigD
(
closure
.
Callee
()
.
Address
()))
case
oCALLVALUE
:
// FIXME: Original value of the call, not the current value
stack
.
Push
(
closure
.
Value
)
stack
.
Push
(
vm
.
vars
.
Value
)
case
oCALLDATALOAD
:
require
(
1
)
offset
:=
stack
.
Pop
()
.
Int64
()
...
...
@@ -352,27 +351,17 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
// TODO
stack
.
Push
(
big
.
NewInt
(
0
))
// 0x50 range
case
oPUSH
:
// Push PC+1 on to the stack
// 0x50 range
case
oPUSH1
,
oPUSH2
,
oPUSH3
,
oPUSH4
,
oPUSH5
,
oPUSH6
,
oPUSH7
,
oPUSH8
,
oPUSH9
,
oPUSH10
,
oPUSH11
,
oPUSH12
,
oPUSH13
,
oPUSH14
,
oPUSH15
,
oPUSH16
,
oPUSH17
,
oPUSH18
,
oPUSH19
,
oPUSH20
,
oPUSH21
,
oPUSH22
,
oPUSH23
,
oPUSH24
,
oPUSH25
,
oPUSH26
,
oPUSH27
,
oPUSH28
,
oPUSH29
,
oPUSH30
,
oPUSH31
,
oPUSH32
:
a
:=
big
.
NewInt
(
int64
(
op
)
-
int64
(
oPUSH1
)
+
1
)
pc
.
Add
(
pc
,
ethutil
.
Big1
)
data
:=
closure
.
Gets
(
pc
,
big
.
NewInt
(
32
)
)
data
:=
closure
.
Gets
(
pc
,
a
)
val
:=
ethutil
.
BigD
(
data
.
Bytes
())
// Push value to stack
stack
.
Push
(
val
)
pc
.
Add
(
pc
,
big
.
NewInt
(
31
))
pc
.
Add
(
pc
,
a
.
Sub
(
a
,
big
.
NewInt
(
1
)))
step
++
case
oPUSH20
:
pc
.
Add
(
pc
,
ethutil
.
Big1
)
data
:=
closure
.
Gets
(
pc
,
big
.
NewInt
(
20
))
val
:=
ethutil
.
BigD
(
data
.
Bytes
())
// Push value to stack
stack
.
Push
(
val
)
pc
.
Add
(
pc
,
big
.
NewInt
(
19
))
step
++
case
oPOP
:
require
(
1
)
stack
.
Pop
()
...
...
@@ -406,21 +395,23 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
case
oSSTORE
:
require
(
2
)
val
,
loc
:=
stack
.
Popn
()
closure
.
Set
Mem
(
loc
,
ethutil
.
NewValue
(
val
))
closure
.
Set
Storage
(
loc
,
ethutil
.
NewValue
(
val
))
// Add the change to manifest
vm
.
state
Manager
.
manifest
.
AddStorageChange
(
closure
.
Object
(),
loc
.
Bytes
(),
val
)
vm
.
state
.
manifest
.
AddStorageChange
(
closure
.
Object
(),
loc
.
Bytes
(),
val
)
case
oJUMP
:
require
(
1
)
pc
=
stack
.
Pop
()
// Reduce pc by one because of the increment that's at the end of this for loop
pc
.
Sub
(
pc
,
ethutil
.
Big1
)
//pc.Sub(pc, ethutil.Big1)
continue
case
oJUMPI
:
require
(
2
)
cond
,
pos
:=
stack
.
Popn
()
if
cond
.
Cmp
(
ethutil
.
BigTrue
)
==
0
{
pc
=
pos
pc
.
Sub
(
pc
,
ethutil
.
Big1
)
//pc.Sub(pc, ethutil.Big1)
continue
}
case
oPC
:
stack
.
Push
(
pc
)
...
...
@@ -449,8 +440,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
contract
.
initScript
,
vm
.
state
,
gas
,
closure
.
Price
,
value
)
closure
.
Price
)
// Call the closure and set the return value as
// main script.
closure
.
Script
,
err
=
closure
.
Call
(
vm
,
nil
,
hook
)
...
...
@@ -477,8 +467,10 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
break
}
// Get the arguments from the memory
args
:=
mem
.
Get
(
inOffset
.
Int64
(),
inSize
.
Int64
())
// Fetch the contract which will serve as the closure body
contract
:=
vm
.
state
.
GetContract
(
addr
.
Bytes
())
...
...
@@ -490,8 +482,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
gas
=
new
(
big
.
Int
)
.
Set
(
closure
.
Gas
)
}
closure
.
Gas
.
Sub
(
closure
.
Gas
,
gas
)
// Add the value to the state object
contract
.
AddAmount
(
value
)
// Create a new callable closure
closure
:=
NewClosure
(
closure
.
Object
(),
contract
,
contract
.
script
,
vm
.
state
,
gas
,
closure
.
Price
,
value
)
closure
:=
NewClosure
(
closure
.
Object
(),
contract
,
contract
.
script
,
vm
.
state
,
gas
,
closure
.
Price
)
// Executer the closure and get the return value (if any)
ret
,
err
:=
closure
.
Call
(
vm
,
args
,
hook
)
if
err
!=
nil
{
...
...
@@ -500,10 +496,10 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
//contract.State().Reset()
}
else
{
stack
.
Push
(
ethutil
.
BigTrue
)
// Notify of the changes
vm
.
stateManager
.
manifest
.
AddObjectChange
(
contract
)
}
vm
.
state
.
SetStateObject
(
contract
)
mem
.
Set
(
retOffset
.
Int64
(),
retSize
.
Int64
(),
ret
)
}
else
{
ethutil
.
Config
.
Log
.
Debugf
(
"Contract %x not found
\n
"
,
addr
.
Bytes
())
...
...
@@ -520,8 +516,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
receiver
:=
vm
.
state
.
GetAccount
(
stack
.
Pop
()
.
Bytes
())
receiver
.
AddAmount
(
closure
.
object
.
Amount
)
vm
.
stateManager
.
manifest
.
AddObjectChange
(
receiver
)
vm
.
state
.
SetStateObject
(
receiver
)
closure
.
object
.
state
.
Purge
()
...
...
ethchain/vm_test.go
View file @
3af35d92
...
...
@@ -11,71 +11,6 @@ import (
"testing"
)
/*
func TestRun3(t *testing.T) {
ethutil.ReadConfig("")
db, _ := ethdb.NewMemDatabase()
state := NewState(ethutil.NewTrie(db, ""))
script := Compile([]string{
"PUSH", "300",
"PUSH", "0",
"MSTORE",
"PUSH", "32",
"CALLDATA",
"PUSH", "64",
"PUSH", "0",
"RETURN",
})
tx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), script)
addr := tx.Hash()[12:]
contract := MakeContract(tx, state)
state.UpdateContract(contract)
callerScript := ethutil.Assemble(
"PUSH", 1337, // Argument
"PUSH", 65, // argument mem offset
"MSTORE",
"PUSH", 64, // ret size
"PUSH", 0, // ret offset
"PUSH", 32, // arg size
"PUSH", 65, // arg offset
"PUSH", 1000, /// Gas
"PUSH", 0, /// value
"PUSH", addr, // Sender
"CALL",
"PUSH", 64,
"PUSH", 0,
"RETURN",
)
callerTx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), callerScript)
// Contract addr as test address
account := NewAccount(ContractAddr, big.NewInt(10000000))
callerClosure := NewClosure(account, MakeContract(callerTx, state), state, big.NewInt(1000000000), new(big.Int))
vm := NewVm(state, RuntimeVars{
origin: account.Address(),
blockNumber: 1,
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
time: 1,
diff: big.NewInt(256),
// XXX Tx data? Could be just an argument to the closure instead
txData: nil,
})
ret := callerClosure.Call(vm, nil)
exp := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 57}
if bytes.Compare(ret, exp) != 0 {
t.Errorf("expected return value to be %v, got %v", exp, ret)
}
}*/
func
TestRun4
(
t
*
testing
.
T
)
{
ethutil
.
ReadConfig
(
""
)
...
...
@@ -86,7 +21,7 @@ func TestRun4(t *testing.T) {
int32 a = 10
int32 b = 20
if a > b {
int32 c = this.
C
aller()
int32 c = this.
c
aller()
}
Exit()
`
),
false
)
...
...
@@ -98,21 +33,21 @@ func TestRun4(t *testing.T) {
callerScript
,
err
:=
mutan
.
Compile
(
strings
.
NewReader
(
`
// Check if there's any cash in the initial store
if store[1000] == 0 {
store[1000] = 10^20
if
this.
store[1000] == 0 {
this.
store[1000] = 10^20
}
store[1001] = this.V
alue() * 20
store[this.Origin()] = store[this.O
rigin()] + 1000
this.store[1001] = this.v
alue() * 20
this.store[this.origin()] = this.store[this.o
rigin()] + 1000
if store[1001] > 20 {
store[1001] = 10^50
if
this.
store[1001] > 20 {
this.
store[1001] = 10^50
}
int8 ret = 0
int8 arg = 10
C
all(0xe6a12555fad1fb6eaaaed69001a87313d1fd7b54, 0, 100, arg, ret)
c
all(0xe6a12555fad1fb6eaaaed69001a87313d1fd7b54, 0, 100, arg, ret)
big t
for int8 i = 0; i < 10; i++ {
...
...
@@ -142,7 +77,7 @@ func TestRun4(t *testing.T) {
fmt
.
Println
(
err
)
}
fmt
.
Println
(
"account.Amount ="
,
account
.
Amount
)
callerClosure
:=
NewClosure
(
account
,
c
,
c
.
script
,
state
,
gas
,
gasPrice
,
big
.
NewInt
(
0
)
)
callerClosure
:=
NewClosure
(
account
,
c
,
c
.
script
,
state
,
gas
,
gasPrice
)
vm
:=
NewVm
(
state
,
nil
,
RuntimeVars
{
Origin
:
account
.
Address
(),
...
...
ethereum.go
View file @
3af35d92
...
...
@@ -253,7 +253,7 @@ func (s *Ethereum) ReapDeadPeerHandler() {
}
// Start the ethereum
func
(
s
*
Ethereum
)
Start
()
{
func
(
s
*
Ethereum
)
Start
(
seed
bool
)
{
// Bind to addr and port
ln
,
err
:=
net
.
Listen
(
"tcp"
,
":"
+
s
.
Port
)
if
err
!=
nil
{
...
...
@@ -272,47 +272,51 @@ func (s *Ethereum) Start() {
// Start the reaping processes
go
s
.
ReapDeadPeerHandler
()
if
ethutil
.
Config
.
Seed
{
ethutil
.
Config
.
Log
.
Debugln
(
"Seeding"
)
// 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
)
log
.
Println
(
"Found DNS Bootstrap Peer:"
,
peer
)
peers
=
append
(
peers
,
peer
)
}
}
else
{
log
.
Println
(
"Couldn't resolve :"
,
target
)
if
seed
{
s
.
Seed
()
}
}
func
(
s
*
Ethereum
)
Seed
()
{
ethutil
.
Config
.
Log
.
Debugln
(
"Seeding"
)
// 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
)
log
.
Println
(
"Found DNS Bootstrap Peer:"
,
peer
)
peers
=
append
(
peers
,
peer
)
}
}
else
{
log
.
Println
(
"Couldn't resolve :"
,
target
)
}
// Connect to Peer list
s
.
ProcessPeerList
(
peers
)
}
else
{
// Fallback to servers.poc3.txt
resp
,
err
:=
http
.
Get
(
"http://www.ethereum.org/servers.poc3.txt"
)
if
err
!=
nil
{
log
.
Println
(
"Fetching seed failed:"
,
err
)
return
}
defer
resp
.
Body
.
Close
()
body
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
log
.
Println
(
"Reading seed failed:"
,
err
)
return
}
s
.
ConnectToPeer
(
string
(
body
))
}
// Connect to Peer list
s
.
ProcessPeerList
(
peers
)
}
else
{
// Fallback to servers.poc3.txt
resp
,
err
:=
http
.
Get
(
"http://www.ethereum.org/servers.poc3.txt"
)
if
err
!=
nil
{
log
.
Println
(
"Fetching seed failed:"
,
err
)
return
}
defer
resp
.
Body
.
Close
()
body
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
log
.
Println
(
"Reading seed failed:"
,
err
)
return
}
s
.
ConnectToPeer
(
string
(
body
))
}
}
...
...
@@ -339,7 +343,9 @@ func (s *Ethereum) Stop() {
close
(
s
.
quit
)
s
.
RpcServer
.
Stop
()
if
s
.
RpcServer
!=
nil
{
s
.
RpcServer
.
Stop
()
}
s
.
txPool
.
Stop
()
s
.
stateManager
.
Stop
()
...
...
ethpub/pub.go
View file @
3af35d92
...
...
@@ -92,7 +92,14 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, in
hash
=
ethutil
.
FromHex
(
recipient
)
}
keyPair
,
err
:=
ethchain
.
NewKeyPairFromSec
([]
byte
(
ethutil
.
FromHex
(
key
)))
var
keyPair
*
ethchain
.
KeyPair
var
err
error
if
key
[
0
:
2
]
==
"0x"
{
keyPair
,
err
=
ethchain
.
NewKeyPairFromSec
([]
byte
(
ethutil
.
FromHex
(
key
[
0
:
2
])))
}
else
{
keyPair
,
err
=
ethchain
.
NewKeyPairFromSec
([]
byte
(
ethutil
.
FromHex
(
key
)))
}
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -132,8 +139,11 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, in
tx
=
ethchain
.
NewTransactionMessage
(
hash
,
value
,
gas
,
gasPrice
,
ethutil
.
FromHex
(
initStr
))
}
acc
:=
lib
.
stateManager
.
GetAddrState
(
keyPair
.
Address
())
acc
:=
lib
.
stateManager
.
TransState
()
.
GetStateObject
(
keyPair
.
Address
())
//acc := lib.stateManager.GetAddrState(keyPair.Address())
tx
.
Nonce
=
acc
.
Nonce
lib
.
stateManager
.
TransState
()
.
SetStateObject
(
acc
)
tx
.
Sign
(
keyPair
.
PrivateKey
)
lib
.
txPool
.
QueueTransaction
(
tx
)
...
...
ethrpc/packages.go
View file @
3af35d92
...
...
@@ -4,7 +4,8 @@ import (
"encoding/json"
"errors"
"github.com/ethereum/eth-go/ethpub"
_
"log"
"github.com/ethereum/eth-go/ethutil"
"math/big"
)
type
EthereumApi
struct
{
...
...
@@ -173,7 +174,10 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageArgs, reply *string) error {
return
err
}
state
:=
p
.
ethp
.
GetStateObject
(
args
.
Address
)
value
:=
state
.
GetStorage
(
args
.
Key
)
// Convert the incoming string (which is a bigint) into hex
i
,
_
:=
new
(
big
.
Int
)
.
SetString
(
args
.
Key
,
10
)
hx
:=
ethutil
.
Hex
(
i
.
Bytes
())
value
:=
state
.
GetStorage
(
hx
)
*
reply
=
NewSuccessRes
(
GetStorageAtRes
{
Address
:
args
.
Address
,
Key
:
args
.
Key
,
Value
:
value
})
return
nil
}
...
...
ethutil/common_test.go
View file @
3af35d92
...
...
@@ -26,7 +26,7 @@ func TestCommon(t *testing.T) {
t
.
Error
(
"Got"
,
szabo
)
}
if
vito
!=
"10 Vit
o
"
{
if
vito
!=
"10 Vit
a
"
{
t
.
Error
(
"Got"
,
vito
)
}
...
...
ethutil/config.go
View file @
3af35d92
...
...
@@ -27,7 +27,6 @@ type config struct {
Ver
string
ClientString
string
Pubkey
[]
byte
Seed
bool
}
var
Config
*
config
...
...
@@ -51,7 +50,7 @@ func ReadConfig(base string) *config {
}
}
Config
=
&
config
{
ExecPath
:
path
,
Debug
:
true
,
Ver
:
"0.5
RC1
"
}
Config
=
&
config
{
ExecPath
:
path
,
Debug
:
true
,
Ver
:
"0.5
.0 RC2
"
}
Config
.
Log
=
NewLogger
(
LogFile
|
LogStd
,
LogLevelDebug
)
Config
.
SetClientString
(
"/Ethereum(G)"
)
}
...
...
ethutil/rlp_test.go
View file @
3af35d92
...
...
@@ -2,7 +2,6 @@ package ethutil
import
(
"bytes"
"fmt"
"math/big"
"reflect"
"testing"
...
...
@@ -56,15 +55,6 @@ func TestValue(t *testing.T) {
}
}
func
TestEncodeDecodeMaran
(
t
*
testing
.
T
)
{
b
:=
NewValue
([]
interface
{}{
"dog"
,
15
,
[]
interface
{}{
"cat"
,
"cat"
,
[]
interface
{}{}},
1024
,
"tachikoma"
})
a
:=
b
.
Encode
()
fmt
.
Println
(
"voor maran"
,
a
)
f
,
i
:=
Decode
(
a
,
0
)
fmt
.
Println
(
"voor maran 2"
,
f
)
fmt
.
Println
(
i
)
}
func
TestEncode
(
t
*
testing
.
T
)
{
strRes
:=
"
\x83
dog"
bytes
:=
Encode
(
"dog"
)
...
...
@@ -131,7 +121,10 @@ func TestEncodeDecodeBytes(t *testing.T) {
func
TestEncodeZero
(
t
*
testing
.
T
)
{
b
:=
NewValue
(
0
)
.
Encode
()
fmt
.
Println
(
b
)
exp
:=
[]
byte
{
0xc0
}
if
bytes
.
Compare
(
b
,
exp
)
==
0
{
t
.
Error
(
"Expected"
,
exp
,
"got"
,
b
)
}
}
func
BenchmarkEncodeDecode
(
b
*
testing
.
B
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment