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
489576b6
Commit
489576b6
authored
Jan 18, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More opcodes
parent
ee61cfcf
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
85 additions
and
59 deletions
+85
-59
block_manager.go
block_manager.go
+80
-53
stack.go
stack.go
+5
-6
No files found.
block_manager.go
View file @
489576b6
...
...
@@ -9,6 +9,7 @@ import (
"log"
"math"
"math/big"
"strconv"
)
type
BlockChain
struct
{
...
...
@@ -52,14 +53,14 @@ type BlockManager struct {
// Stack for processing contracts
stack
*
Stack
// non-persistent key/value memory storage
mem
map
[
string
]
string
mem
map
[
string
]
*
big
.
Int
}
func
NewBlockManager
()
*
BlockManager
{
bm
:=
&
BlockManager
{
bc
:
NewBlockChain
(),
stack
:
NewStack
(),
mem
:
make
(
map
[
string
]
string
),
mem
:
make
(
map
[
string
]
*
big
.
Int
),
}
// Set the last known block number based on the blockchains last
...
...
@@ -276,27 +277,27 @@ out:
base
.
Add
(
x
,
y
)
base
.
Mod
(
base
,
Pow256
)
// Pop result back on the stack
bm
.
stack
.
Push
(
base
.
String
()
)
bm
.
stack
.
Push
(
base
)
case
oSUB
:
x
,
y
:=
bm
.
stack
.
Popn
()
// (x - y) % 2 ** 256
base
.
Sub
(
x
,
y
)
base
.
Mod
(
base
,
Pow256
)
// Pop result back on the stack
bm
.
stack
.
Push
(
base
.
String
()
)
bm
.
stack
.
Push
(
base
)
case
oMUL
:
x
,
y
:=
bm
.
stack
.
Popn
()
// (x * y) % 2 ** 256
base
.
Mul
(
x
,
y
)
base
.
Mod
(
base
,
Pow256
)
// Pop result back on the stack
bm
.
stack
.
Push
(
base
.
String
()
)
bm
.
stack
.
Push
(
base
)
case
oDIV
:
x
,
y
:=
bm
.
stack
.
Popn
()
// floor(x / y)
base
.
Div
(
x
,
y
)
// Pop result back on the stack
bm
.
stack
.
Push
(
base
.
String
()
)
bm
.
stack
.
Push
(
base
)
case
oSDIV
:
x
,
y
:=
bm
.
stack
.
Popn
()
// n > 2**255
...
...
@@ -312,11 +313,11 @@ out:
z
.
Sub
(
Pow256
,
z
)
}
// Push result on to the stack
bm
.
stack
.
Push
(
z
.
String
()
)
bm
.
stack
.
Push
(
z
)
case
oMOD
:
x
,
y
:=
bm
.
stack
.
Popn
()
base
.
Mod
(
x
,
y
)
bm
.
stack
.
Push
(
base
.
String
()
)
bm
.
stack
.
Push
(
base
)
case
oSMOD
:
x
,
y
:=
bm
.
stack
.
Popn
()
// n > 2**255
...
...
@@ -332,87 +333,85 @@ out:
z
.
Sub
(
Pow256
,
z
)
}
// Push result on to the stack
bm
.
stack
.
Push
(
z
.
String
()
)
bm
.
stack
.
Push
(
z
)
case
oEXP
:
x
,
y
:=
bm
.
stack
.
Popn
()
base
.
Exp
(
x
,
y
,
Pow256
)
bm
.
stack
.
Push
(
base
.
String
()
)
bm
.
stack
.
Push
(
base
)
case
oNEG
:
base
.
Sub
(
Pow256
,
ethutil
.
Big
(
bm
.
stack
.
Pop
()
))
bm
.
stack
.
Push
(
base
.
String
()
)
base
.
Sub
(
Pow256
,
bm
.
stack
.
Pop
(
))
bm
.
stack
.
Push
(
base
)
case
oLT
:
x
,
y
:=
bm
.
stack
.
Popn
()
// x < y
if
x
.
Cmp
(
y
)
<
0
{
bm
.
stack
.
Push
(
"1"
)
bm
.
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
bm
.
stack
.
Push
(
"0"
)
bm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oLE
:
x
,
y
:=
bm
.
stack
.
Popn
()
// x <= y
if
x
.
Cmp
(
y
)
<
1
{
bm
.
stack
.
Push
(
"1"
)
bm
.
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
bm
.
stack
.
Push
(
"0"
)
bm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oGT
:
x
,
y
:=
bm
.
stack
.
Popn
()
// x > y
if
x
.
Cmp
(
y
)
>
0
{
bm
.
stack
.
Push
(
"1"
)
bm
.
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
bm
.
stack
.
Push
(
"0"
)
bm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oGE
:
x
,
y
:=
bm
.
stack
.
Popn
()
// x >= y
if
x
.
Cmp
(
y
)
>
-
1
{
bm
.
stack
.
Push
(
"1"
)
bm
.
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
bm
.
stack
.
Push
(
"0"
)
bm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oNOT
:
x
,
y
:=
bm
.
stack
.
Popn
()
// x != y
if
x
.
Cmp
(
y
)
!=
0
{
bm
.
stack
.
Push
(
"1"
)
bm
.
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
bm
.
stack
.
Push
(
"0"
)
bm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
// Please note that the following code contains some
// ugly string casting. This will have to change to big
// ints. TODO :)
case
oMYADDRESS
:
bm
.
stack
.
Push
(
string
(
tx
.
Hash
()))
bm
.
stack
.
Push
(
ethutil
.
BigD
(
tx
.
Hash
()))
case
oTXSENDER
:
bm
.
stack
.
Push
(
string
(
tx
.
Sender
()))
bm
.
stack
.
Push
(
ethutil
.
BigD
(
tx
.
Sender
()))
case
oTXVALUE
:
bm
.
stack
.
Push
(
tx
.
Value
.
String
()
)
bm
.
stack
.
Push
(
tx
.
Value
)
case
oTXDATAN
:
bm
.
stack
.
Push
(
big
.
NewInt
(
int64
(
len
(
tx
.
Data
)))
.
String
()
)
bm
.
stack
.
Push
(
big
.
NewInt
(
int64
(
len
(
tx
.
Data
))))
case
oTXDATA
:
v
:=
ethutil
.
Big
(
bm
.
stack
.
Pop
()
)
v
:=
bm
.
stack
.
Pop
(
)
// v >= len(data)
if
v
.
Cmp
(
big
.
NewInt
(
int64
(
len
(
tx
.
Data
))))
>=
0
{
//I know this will change. It makes no
//sense. Read comment above
bm
.
stack
.
Push
(
ethutil
.
Big
(
"0"
)
.
String
())
bm
.
stack
.
Push
(
ethutil
.
Big
(
"0"
))
}
else
{
bm
.
stack
.
Push
(
ethutil
.
Big
(
tx
.
Data
[
v
.
Uint64
()])
.
String
()
)
bm
.
stack
.
Push
(
ethutil
.
Big
(
tx
.
Data
[
v
.
Uint64
()]))
}
case
oBLK_PREVHASH
:
bm
.
stack
.
Push
(
strin
g
(
block
.
PrevHash
))
bm
.
stack
.
Push
(
ethutil
.
Bi
g
(
block
.
PrevHash
))
case
oBLK_COINBASE
:
bm
.
stack
.
Push
(
block
.
Coinbase
)
bm
.
stack
.
Push
(
ethutil
.
Big
(
block
.
Coinbase
)
)
case
oBLK_TIMESTAMP
:
bm
.
stack
.
Push
(
big
.
NewInt
(
block
.
Time
)
.
String
()
)
bm
.
stack
.
Push
(
big
.
NewInt
(
block
.
Time
))
case
oBLK_NUMBER
:
bm
.
stack
.
Push
(
blockInfo
.
Number
.
String
()
)
bm
.
stack
.
Push
(
blockInfo
.
Number
)
case
oBLK_DIFFICULTY
:
bm
.
stack
.
Push
(
block
.
Difficulty
.
String
()
)
bm
.
stack
.
Push
(
block
.
Difficulty
)
case
oBASEFEE
:
// e = 10^21
e
:=
big
.
NewInt
(
0
)
.
Exp
(
big
.
NewInt
(
10
),
big
.
NewInt
(
21
),
big
.
NewInt
(
0
))
...
...
@@ -429,23 +428,23 @@ out:
x
.
Div
(
e
,
base
)
// x = floor(10^21 / floor(diff^0.5))
bm
.
stack
.
Push
(
x
.
String
()
)
bm
.
stack
.
Push
(
x
)
case
oSHA256
,
oRIPEMD160
:
// This is probably save
// ceil(pop / 32)
length
:=
int
(
math
.
Ceil
(
float64
(
ethutil
.
Big
(
bm
.
stack
.
Pop
()
)
.
Uint64
())
/
32.0
))
length
:=
int
(
math
.
Ceil
(
float64
(
bm
.
stack
.
Pop
(
)
.
Uint64
())
/
32.0
))
// New buffer which will contain the concatenated popped items
data
:=
new
(
bytes
.
Buffer
)
for
i
:=
0
;
i
<
length
;
i
++
{
// Encode the number to bytes and have it 32bytes long
num
:=
ethutil
.
NumberToBytes
(
ethutil
.
Big
(
bm
.
stack
.
Pop
()
)
.
Bytes
(),
256
)
num
:=
ethutil
.
NumberToBytes
(
bm
.
stack
.
Pop
(
)
.
Bytes
(),
256
)
data
.
WriteString
(
string
(
num
))
}
if
op
==
oSHA256
{
bm
.
stack
.
Push
(
base
.
SetBytes
(
ethutil
.
Sha256Bin
(
data
.
Bytes
()))
.
String
()
)
bm
.
stack
.
Push
(
base
.
SetBytes
(
ethutil
.
Sha256Bin
(
data
.
Bytes
())))
}
else
{
bm
.
stack
.
Push
(
base
.
SetBytes
(
ethutil
.
Ripemd160
(
data
.
Bytes
()))
.
String
()
)
bm
.
stack
.
Push
(
base
.
SetBytes
(
ethutil
.
Ripemd160
(
data
.
Bytes
())))
}
case
oECMUL
:
y
:=
bm
.
stack
.
Pop
()
...
...
@@ -454,14 +453,14 @@ out:
//if ethutil.Big(x).Cmp(ethutil.Big(y)) {
data
:=
new
(
bytes
.
Buffer
)
data
.
WriteString
(
x
)
data
.
WriteString
(
y
)
data
.
WriteString
(
x
.
String
()
)
data
.
WriteString
(
y
.
String
()
)
if
secp256k1
.
VerifyPubkeyValidity
(
data
.
Bytes
())
==
1
{
// TODO
}
else
{
// Invalid, push infinity
bm
.
stack
.
Push
(
"0"
)
bm
.
stack
.
Push
(
"0"
)
bm
.
stack
.
Push
(
ethutil
.
Big
(
"0"
)
)
bm
.
stack
.
Push
(
ethutil
.
Big
(
"0"
)
)
}
//} else {
// // Invalid, push infinity
...
...
@@ -475,31 +474,59 @@ out:
case
oECVALID
:
case
oSHA3
:
case
oPUSH
:
// Get the next entry and pushes the value on the stack
pc
++
bm
.
stack
.
Push
(
contract
.
State
()
.
Get
(
string
(
ethutil
.
NumberToBytes
(
uint64
(
pc
),
32
)))
)
bm
.
stack
.
Push
(
bm
.
mem
[
strconv
.
Itoa
(
pc
)]
)
case
oPOP
:
// Pop current value of the stack
bm
.
stack
.
Pop
()
case
oDUP
:
// Dup top stack
x
:=
bm
.
stack
.
Pop
()
bm
.
stack
.
Push
(
x
)
bm
.
stack
.
Push
(
x
)
case
oSWAP
:
// Swap two top most values
x
,
y
:=
bm
.
stack
.
Popn
()
bm
.
stack
.
Push
(
y
)
bm
.
stack
.
Push
(
x
)
case
oMLOAD
:
x
:=
bm
.
stack
.
Pop
()
bm
.
stack
.
Push
(
bm
.
mem
[
x
.
String
()])
case
oMSTORE
:
x
,
y
:=
bm
.
stack
.
Popn
()
bm
.
mem
[
x
.
String
()]
=
y
case
oSLOAD
:
// Load the value in storage and push it on the stack
x
:=
bm
.
stack
.
Pop
()
// decode the object as a big integer
decoder
:=
ethutil
.
NewRlpDecoder
([]
byte
(
contract
.
State
()
.
Get
(
x
.
String
())))
if
!
decoder
.
IsNil
()
{
bm
.
stack
.
Push
(
decoder
.
AsBigInt
())
}
else
{
bm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oSSTORE
:
// Store Y at index X
x
,
y
:=
bm
.
stack
.
Popn
()
contract
.
State
()
.
Update
(
x
.
String
(),
string
(
ethutil
.
Encode
(
y
)))
case
oJMP
:
x
:=
int
(
bm
.
stack
.
Pop
()
.
Uint64
())
// Set pc to x - 1 (minus one so the incrementing at the end won't effect it)
pc
=
x
pc
--
case
oJMPI
:
x
:=
bm
.
stack
.
Pop
()
// Set pc to x if it's non zero
if
x
.
Cmp
(
ethutil
.
BigFalse
)
!=
0
{
pc
=
int
(
x
.
Uint64
())
pc
--
}
case
oIND
:
bm
.
stack
.
Push
(
big
.
NewInt
(
int64
(
pc
)))
case
oEXTRO
:
case
oBALANCE
:
case
oMKTX
:
case
oSUICIDE
:
/*
case oLOAD:
// Load instruction X on the stack
i, _ := strconv.Atoi(bm.stack.Pop())
bm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32))))
*/
}
pc
++
}
...
...
stack.go
View file @
489576b6
...
...
@@ -2,7 +2,6 @@ package main
import
(
"fmt"
"github.com/ethereum/ethutil-go"
"math/big"
)
...
...
@@ -135,14 +134,14 @@ type TxCallback func(opType OpType) bool
// Simple push/pop stack mechanism
type
Stack
struct
{
data
[]
string
data
[]
*
big
.
Int
}
func
NewStack
()
*
Stack
{
return
&
Stack
{}
}
func
(
st
*
Stack
)
Pop
()
string
{
func
(
st
*
Stack
)
Pop
()
*
big
.
Int
{
s
:=
len
(
st
.
data
)
str
:=
st
.
data
[
s
-
1
]
...
...
@@ -154,13 +153,13 @@ func (st *Stack) Pop() string {
func
(
st
*
Stack
)
Popn
()
(
*
big
.
Int
,
*
big
.
Int
)
{
s
:=
len
(
st
.
data
)
str
s
:=
st
.
data
[
s
-
2
:
]
int
s
:=
st
.
data
[
s
-
2
:
]
st
.
data
=
st
.
data
[
:
s
-
2
]
return
ethutil
.
Big
(
strs
[
0
]),
ethutil
.
Big
(
strs
[
1
])
return
ints
[
0
],
ints
[
1
]
}
func
(
st
*
Stack
)
Push
(
d
string
)
{
func
(
st
*
Stack
)
Push
(
d
*
big
.
Int
)
{
st
.
data
=
append
(
st
.
data
,
d
)
}
func
(
st
*
Stack
)
Print
()
{
...
...
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