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
f3d27bf5
Commit
f3d27bf5
authored
Mar 20, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrote opcodes again
parent
c68ff988
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
219 additions
and
247 deletions
+219
-247
stack.go
ethchain/stack.go
+144
-159
state_manager.go
ethchain/state_manager.go
+2
-1
vm.go
ethchain/vm.go
+9
-32
parsing.go
ethutil/parsing.go
+64
-55
No files found.
ethchain/stack.go
View file @
f3d27bf5
...
...
@@ -2,7 +2,7 @@ package ethchain
import
(
"fmt"
"github.com/ethereum/eth-go/ethutil"
_
"github.com/ethereum/eth-go/ethutil"
"math/big"
)
...
...
@@ -10,116 +10,136 @@ type OpCode int
// Op codes
const
(
oSTOP
=
0x00
oADD
=
0x01
oMUL
=
0x02
oSUB
=
0x03
oDIV
=
0x04
oSDIV
=
0x05
oMOD
=
0x06
oSMOD
=
0x07
oEXP
=
0x08
oNEG
=
0x09
oLT
=
0x0a
oLE
=
0x0b
oGT
=
0x0c
oGE
=
0x0d
oEQ
=
0x0e
oNOT
=
0x0f
oMYADDRESS
=
0x10
oTXSENDER
=
0x11
oTXVALUE
=
0x12
oTXDATAN
=
0x13
oTXDATA
=
0x14
oBLK_PREVHASH
=
0x15
oBLK_COINBASE
=
0x16
oBLK_TIMESTAMP
=
0x17
oBLK_NUMBER
=
0x18
oBLK_DIFFICULTY
=
0x19
oBLK_NONCE
=
0x1a
oBASEFEE
=
0x1b
oSHA256
=
0x20
oRIPEMD160
=
0x21
oECMUL
=
0x22
oECADD
=
0x23
oECSIGN
=
0x24
oECRECOVER
=
0x25
oECVALID
=
0x26
oSHA3
=
0x27
oPUSH
=
0x30
oPOP
=
0x31
oDUP
=
0x32
oSWAP
=
0x33
oMLOAD
=
0x34
oMSTORE
=
0x35
oSLOAD
=
0x36
oSSTORE
=
0x37
oJMP
=
0x38
oJMPI
=
0x39
oIND
=
0x3a
oEXTRO
=
0x3b
oBALANCE
=
0x3c
oMKTX
=
0x3d
oSUICIDE
=
0x3f
// TODO FIX OPCODES
oCALL
=
0x40
oRETURN
=
0x41
// 0x0 range - arithmetic ops
oSTOP
=
0x00
oADD
=
0x01
oMUL
=
0x02
oSUB
=
0x03
oDIV
=
0x04
oSDIV
=
0x05
oMOD
=
0x06
oSMOD
=
0x07
oEXP
=
0x08
oNEG
=
0x09
oLT
=
0x0a
oGT
=
0x0b
oEQ
=
0x0c
oNOT
=
0x0d
// 0x10 range - bit ops
oAND
=
0x10
oOR
=
0x11
oXOR
=
0x12
oBYTE
=
0x13
// 0x20 range - crypto
oSHA3
=
0x20
// 0x30 range - closure state
oADDRESS
=
0x30
oBALANCE
=
0x31
oORIGIN
=
0x32
oCALLER
=
0x33
oCALLVALUE
=
0x34
oCALLDATA
=
0x35
oCALLDATASIZE
=
0x36
oRETURNDATASIZE
=
0x37
oTXGASPRICE
=
0x38
// 0x40 range - block operations
oPREVHASH
=
0x40
oPREVNONCE
=
0x41
oCOINBASE
=
0x42
oTIMESTAMP
=
0x43
oNUMBER
=
0x44
oDIFFICULTY
=
0x45
oGASLIMIT
=
0x46
// 0x50 range - 'storage' and execution
oPUSH
=
0x50
oPOP
=
0x51
oDUP
=
0x52
oSWAP
=
0x53
oMLOAD
=
0x54
oMSTORE
=
0x55
oMSTORE8
=
0x56
oSLOAD
=
0x57
oSSTORE
=
0x58
oJUMP
=
0x59
oJUMPI
=
0x5a
oPC
=
0x5b
oMEMSIZE
=
0x5c
// 0x60 range - closures
oCREATE
=
0x60
oCALL
=
0x61
oRETURN
=
0x62
)
// Since the opcodes aren't all in order we can't use a regular slice
var
opCodeToString
=
map
[
OpCode
]
string
{
oSTOP
:
"STOP"
,
oADD
:
"ADD"
,
oMUL
:
"MUL"
,
oSUB
:
"SUB"
,
oDIV
:
"DIV"
,
oSDIV
:
"SDIV"
,
oMOD
:
"MOD"
,
oSMOD
:
"SMOD"
,
oEXP
:
"EXP"
,
oNEG
:
"NEG"
,
oLT
:
"LT"
,
oLE
:
"LE"
,
oGT
:
"GT"
,
oGE
:
"GE"
,
oEQ
:
"EQ"
,
oNOT
:
"NOT"
,
oMYADDRESS
:
"MYADDRESS"
,
oTXSENDER
:
"TXSENDER"
,
oTXVALUE
:
"TXVALUE"
,
oTXDATAN
:
"TXDATAN"
,
oTXDATA
:
"TXDATA"
,
oBLK_PREVHASH
:
"BLK_PREVHASH"
,
oBLK_COINBASE
:
"BLK_COINBASE"
,
oBLK_TIMESTAMP
:
"BLK_TIMESTAMP"
,
oBLK_NUMBER
:
"BLK_NUMBER"
,
oBLK_DIFFICULTY
:
"BLK_DIFFICULTY"
,
oBASEFEE
:
"BASEFEE"
,
oSHA256
:
"SHA256"
,
oRIPEMD160
:
"RIPEMD160"
,
oECMUL
:
"ECMUL"
,
oECADD
:
"ECADD"
,
oECSIGN
:
"ECSIGN"
,
oECRECOVER
:
"ECRECOVER"
,
oECVALID
:
"ECVALID"
,
oSHA3
:
"SHA3"
,
oPUSH
:
"PUSH"
,
oPOP
:
"POP"
,
oDUP
:
"DUP"
,
oSWAP
:
"SWAP"
,
oMLOAD
:
"MLOAD"
,
oMSTORE
:
"MSTORE"
,
oSLOAD
:
"SLOAD"
,
oSSTORE
:
"SSTORE"
,
oJMP
:
"JMP"
,
oJMPI
:
"JMPI"
,
oIND
:
"IND"
,
oEXTRO
:
"EXTRO"
,
// 0x0 range - arithmetic ops
oSTOP
:
"STOP"
,
oADD
:
"ADD"
,
oMUL
:
"MUL"
,
oSUB
:
"SUB"
,
oDIV
:
"DIV"
,
oSDIV
:
"SDIV"
,
oMOD
:
"MOD"
,
oSMOD
:
"SMOD"
,
oEXP
:
"EXP"
,
oNEG
:
"NEG"
,
oLT
:
"LT"
,
oGT
:
"GT"
,
oEQ
:
"EQ"
,
oNOT
:
"NOT"
,
// 0x10 range - bit ops
oAND
:
"AND"
,
oOR
:
"OR"
,
oXOR
:
"XOR"
,
oBYTE
:
"BYTE"
,
// 0x20 range - crypto
oSHA3
:
"SHA3"
,
// 0x30 range - closure state
oADDRESS
:
"ADDRESS"
,
oBALANCE
:
"BALANCE"
,
oMKTX
:
"MKTX"
,
oSUICIDE
:
"SUICIDE"
,
oORIGIN
:
"ORIGIN"
,
oCALLER
:
"CALLER"
,
oCALLVALUE
:
"CALLVALUE"
,
oCALLDATA
:
"CALLDATA"
,
oCALLDATASIZE
:
"CALLDATASIZE"
,
oRETURNDATASIZE
:
"RETURNDATASIZE"
,
oTXGASPRICE
:
"TXGASPRICE"
,
// 0x40 range - block operations
oPREVHASH
:
"PREVHASH"
,
oPREVNONCE
:
"PREVNONCE"
,
oCOINBASE
:
"COINBASE"
,
oTIMESTAMP
:
"TIMESTAMP"
,
oNUMBER
:
"NUMBER"
,
oDIFFICULTY
:
"DIFFICULTY"
,
oGASLIMIT
:
"GASLIMIT"
,
// 0x50 range - 'storage' and execution
oPUSH
:
"PUSH"
,
oPOP
:
"POP"
,
oDUP
:
"DUP"
,
oSWAP
:
"SWAP"
,
oMLOAD
:
"MLOAD"
,
oMSTORE
:
"MSTORE"
,
oMSTORE8
:
"MSTORE8"
,
oSLOAD
:
"SLOAD"
,
oSSTORE
:
"SSTORE"
,
oJUMP
:
"JUMP"
,
oJUMPI
:
"JUMPI"
,
oPC
:
"PC"
,
oMEMSIZE
:
"MEMSIZE"
,
// 0x60 range - closures
oCREATE
:
"CREATE"
,
oCALL
:
"CALL"
,
oRETURN
:
"RETURN"
,
}
...
...
@@ -189,61 +209,26 @@ func (st *Stack) Print() {
fmt
.
Println
(
"#############"
)
}
////////////// TODO this will eventually become the main stack once the big ints are removed from the VM
type
ValueStack
struct
{
data
[]
*
ethutil
.
Value
}
func
NewValueStack
()
*
ValueStack
{
return
&
ValueStack
{}
}
func
(
st
*
ValueStack
)
Pop
()
*
ethutil
.
Value
{
s
:=
len
(
st
.
data
)
str
:=
st
.
data
[
s
-
1
]
st
.
data
=
st
.
data
[
:
s
-
1
]
return
str
}
func
(
st
*
ValueStack
)
Popn
()
(
*
ethutil
.
Value
,
*
ethutil
.
Value
)
{
s
:=
len
(
st
.
data
)
ints
:=
st
.
data
[
s
-
2
:
]
st
.
data
=
st
.
data
[
:
s
-
2
]
return
ints
[
0
],
ints
[
1
]
}
func
(
st
*
ValueStack
)
Peek
()
*
ethutil
.
Value
{
s
:=
len
(
st
.
data
)
str
:=
st
.
data
[
s
-
1
]
return
str
type
Memory
struct
{
store
[]
byte
}
func
(
st
*
ValueStack
)
Peekn
()
(
*
ethutil
.
Value
,
*
ethutil
.
Value
)
{
s
:=
len
(
st
.
data
)
ints
:=
st
.
data
[
s
-
2
:
]
return
ints
[
0
],
ints
[
1
]
}
func
(
st
*
ValueStack
)
Push
(
d
*
ethutil
.
Value
)
{
st
.
data
=
append
(
st
.
data
,
d
)
}
func
(
st
*
ValueStack
)
Print
()
{
fmt
.
Println
(
"### STACK ###"
)
if
len
(
st
.
data
)
>
0
{
for
i
,
val
:=
range
st
.
data
{
fmt
.
Printf
(
"%-3d %v
\n
"
,
i
,
val
)
func
(
m
*
Memory
)
Set
(
offset
,
size
int64
,
value
[]
byte
)
{
totSize
:=
offset
+
size
lenSize
:=
int64
(
len
(
m
.
store
))
if
totSize
>
lenSize
{
// Calculate the diff between the sizes
diff
:=
totSize
-
lenSize
if
diff
>
0
{
// Create a new empty slice and append it
newSlice
:=
make
([]
byte
,
diff
+
1
)
// Resize slice
m
.
store
=
append
(
m
.
store
,
newSlice
...
)
}
}
else
{
fmt
.
Println
(
"-- empty --"
)
}
fmt
.
Println
(
"#############"
)
copy
(
m
.
store
[
offset
:
offset
+
size
+
1
],
value
)
}
func
(
m
*
Memory
)
Get
(
offset
,
size
int64
)
[]
byte
{
return
m
.
store
[
offset
:
offset
+
size
]
}
ethchain/state_manager.go
View file @
f3d27bf5
...
...
@@ -306,8 +306,8 @@ func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, blo
}()
*/
/*TODO to be fixed and replaced by the new vm
vm := &Vm{}
//vm.Process(contract, block.state, RuntimeVars{
vm.Process(contract, sm.procState, RuntimeVars{
address: tx.Hash()[12:],
blockNumber: block.BlockInfo().Number,
...
...
@@ -319,4 +319,5 @@ func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, blo
txValue: tx.Value,
txData: tx.Data,
})
*/
}
ethchain/vm.go
View file @
f3d27bf5
package
ethchain
import
(
"bytes"
_
"bytes"
"fmt"
"github.com/ethereum/eth-go/ethutil"
"github.com/obscuren/secp256k1-go"
_
"github.com/obscuren/secp256k1-go"
"log"
"math"
_
"math"
"math/big"
)
...
...
@@ -45,7 +45,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
}
// Memory for the current closure
var
mem
[]
byte
mem
:=
&
Memory
{}
// New stack (should this be shared?)
stack
:=
NewStack
()
// Instruction pointer
...
...
@@ -86,19 +86,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
case
oMSTORE
:
// Store the value at stack top-1 in to memory at location stack top
// Pop value of the stack
val
,
mStart
:=
stack
.
Popn
()
// Ensure that memory is large enough to hold the data
// If it isn't resize the memory slice so that it may hold the value
bytesLen
:=
big
.
NewInt
(
32
)
totSize
:=
new
(
big
.
Int
)
.
Add
(
mStart
,
bytesLen
)
lenSize
:=
big
.
NewInt
(
int64
(
len
(
mem
)))
if
totSize
.
Cmp
(
lenSize
)
>
0
{
// Calculate the diff between the sizes
diff
:=
new
(
big
.
Int
)
.
Sub
(
totSize
,
lenSize
)
// Create a new empty slice and append it
newSlice
:=
make
([]
byte
,
diff
.
Int64
()
+
1
)
mem
=
append
(
mem
,
newSlice
...
)
}
copy
(
mem
[
mStart
.
Int64
()
:
mStart
.
Int64
()
+
bytesLen
.
Int64
()
+
1
],
ethutil
.
BigToBytes
(
val
,
256
))
mem
.
Set
(
mStart
.
Int64
(),
32
,
ethutil
.
BigToBytes
(
val
,
256
))
case
oCALL
:
// Pop return size and offset
retSize
,
retOffset
:=
stack
.
Popn
()
...
...
@@ -116,23 +104,10 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
closure
:=
NewClosure
(
closure
,
contract
,
vm
.
state
,
gas
,
value
)
// Executer the closure and get the return value (if any)
ret
:=
closure
.
Call
(
vm
,
nil
)
// Ensure that memory is large enough to hold the returned data
// If it isn't resize the memory slice so that it may hold the value
totSize
:=
new
(
big
.
Int
)
.
Add
(
retOffset
,
retSize
)
lenSize
:=
big
.
NewInt
(
int64
(
len
(
mem
)))
if
totSize
.
Cmp
(
lenSize
)
>
0
{
// Calculate the diff between the sizes
diff
:=
new
(
big
.
Int
)
.
Sub
(
totSize
,
lenSize
)
// Create a new empty slice and append it
newSlice
:=
make
([]
byte
,
diff
.
Int64
()
+
1
)
mem
=
append
(
mem
,
newSlice
...
)
}
// Copy over the returned values to the memory given the offset and size
copy
(
mem
[
retOffset
.
Int64
()
:
retOffset
.
Int64
()
+
retSize
.
Int64
()
+
1
],
ret
)
mem
.
Set
(
retOffset
.
Int64
(),
retSize
.
Int64
(),
ret
)
case
oRETURN
:
size
,
offset
:=
stack
.
Popn
()
ret
:=
mem
[
offset
.
Int64
()
:
offset
.
Int64
()
+
size
.
Int64
()
+
1
]
ret
:=
mem
.
Get
(
offset
.
Int64
(),
size
.
Int64
())
return
closure
.
Return
(
ret
)
}
...
...
@@ -141,6 +116,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
}
}
/*
// Old VM code
func (vm *Vm) Process(contract *Contract, state *State, vars RuntimeVars) {
vm.mem = make(map[string]*big.Int)
...
...
@@ -507,6 +483,7 @@ out:
state.UpdateContract(addr, contract)
}
*/
func
makeInlineTx
(
addr
[]
byte
,
value
,
from
,
length
*
big
.
Int
,
contract
*
Contract
,
state
*
State
)
{
ethutil
.
Config
.
Log
.
Debugf
(
" => creating inline tx %x %v %v %v"
,
addr
,
value
,
from
,
length
)
...
...
ethutil/parsing.go
View file @
f3d27bf5
...
...
@@ -7,61 +7,70 @@ import (
// Op codes
var
OpCodes
=
map
[
string
]
byte
{
"STOP"
:
0x00
,
"ADD"
:
0x01
,
"MUL"
:
0x02
,
"SUB"
:
0x03
,
"DIV"
:
0x04
,
"SDIV"
:
0x05
,
"MOD"
:
0x06
,
"SMOD"
:
0x07
,
"EXP"
:
0x08
,
"NEG"
:
0x09
,
"LT"
:
0x0a
,
"LE"
:
0x0b
,
"GT"
:
0x0c
,
"GE"
:
0x0d
,
"EQ"
:
0x0e
,
"NOT"
:
0x0f
,
"MYADDRESS"
:
0x10
,
"TXSENDER"
:
0x11
,
"TXVALUE"
:
0x12
,
"TXDATAN"
:
0x13
,
"TXDATA"
:
0x14
,
"BLK_PREVHASH"
:
0x15
,
"BLK_COINBASE"
:
0x16
,
"BLK_TIMESTAMP"
:
0x17
,
"BLK_NUMBER"
:
0x18
,
"BLK_DIFFICULTY"
:
0x19
,
"BLK_NONCE"
:
0x1a
,
"BASEFEE"
:
0x1b
,
"SHA256"
:
0x20
,
"RIPEMD160"
:
0x21
,
"ECMUL"
:
0x22
,
"ECADD"
:
0x23
,
"ECSIGN"
:
0x24
,
"ECRECOVER"
:
0x25
,
"ECVALID"
:
0x26
,
"SHA3"
:
0x27
,
"PUSH"
:
0x30
,
"POP"
:
0x31
,
"DUP"
:
0x32
,
"SWAP"
:
0x33
,
"MLOAD"
:
0x34
,
"MSTORE"
:
0x35
,
"SLOAD"
:
0x36
,
"SSTORE"
:
0x37
,
"JMP"
:
0x38
,
"JMPI"
:
0x39
,
"IND"
:
0x3a
,
"EXTRO"
:
0x3b
,
"BALANCE"
:
0x3c
,
"MKTX"
:
0x3d
,
"SUICIDE"
:
0x3f
,
// TODO FIX OPCODES
"CALL"
:
0x40
,
"RETURN"
:
0x41
,
// 0x0 range - arithmetic ops
"STOP"
:
0x00
,
"ADD"
:
0x01
,
"MUL"
:
0x02
,
"SUB"
:
0x03
,
"DIV"
:
0x04
,
"SDIV"
:
0x05
,
"MOD"
:
0x06
,
"SMOD"
:
0x07
,
"EXP"
:
0x08
,
"NEG"
:
0x09
,
"LT"
:
0x0a
,
"GT"
:
0x0b
,
"EQ"
:
0x0c
,
"NOT"
:
0x0d
,
// 0x10 range - bit ops
"AND"
:
0x10
,
"OR"
:
0x11
,
"XOR"
:
0x12
,
"BYTE"
:
0x13
,
// 0x20 range - crypto
"SHA3"
:
0x20
,
// 0x30 range - closure state
"ADDRESS"
:
0x30
,
"BALANCE"
:
0x31
,
"ORIGIN"
:
0x32
,
"CALLER"
:
0x33
,
"CALLVALUE"
:
0x34
,
"CALLDATA"
:
0x35
,
"CALLDATASIZE"
:
0x36
,
"RETURNDATASIZE"
:
0x37
,
"TXGASPRICE"
:
0x38
,
// 0x40 range - block operations
"PREVHASH"
:
0x40
,
"PREVNONCE"
:
0x41
,
"COINBASE"
:
0x42
,
"TIMESTAMP"
:
0x43
,
"NUMBER"
:
0x44
,
"DIFFICULTY"
:
0x45
,
"GASLIMIT"
:
0x46
,
// 0x50 range - 'storage' and execution
"PUSH"
:
0x50
,
"POP"
:
0x51
,
"DUP"
:
0x52
,
"SWAP"
:
0x53
,
"MLOAD"
:
0x54
,
"MSTORE"
:
0x55
,
"MSTORE8"
:
0x56
,
"SLOAD"
:
0x57
,
"SSTORE"
:
0x58
,
"JUMP"
:
0x59
,
"JUMPI"
:
0x5a
,
"PC"
:
0x5b
,
"MEMSIZE"
:
0x5c
,
// 0x60 range - closures
"CREATE"
:
0x60
,
"CALL"
:
0x61
,
"RETURN"
:
0x62
,
}
func
IsOpCode
(
s
string
)
bool
{
...
...
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