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
83396cd8
Commit
83396cd8
authored
Jan 16, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved stack to its own file. Moved contract processing to block manager
parent
a80a3eeb
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
366 additions
and
5 deletions
+366
-5
block_manager.go
block_manager.go
+202
-5
stack.go
stack.go
+164
-0
No files found.
block_manager.go
View file @
83396cd8
...
...
@@ -6,6 +6,7 @@ import (
"github.com/ethereum/ethutil-go"
"log"
"math/big"
"strconv"
)
type
BlockChain
struct
{
...
...
@@ -40,16 +41,17 @@ func (bc *BlockChain) GenesisBlock() *ethutil.Block {
}
type
BlockManager
struct
{
// Ethereum virtual machine for processing contracts
vm
*
Vm
// The block chain :)
bc
*
BlockChain
// Stack for processing contracts
stack
*
Stack
}
func
NewBlockManager
()
*
BlockManager
{
bm
:=
&
BlockManager
{
vm
:
NewVm
(),
bc
:
NewBlockChain
(),
bc
:
NewBlockChain
(),
stack
:
NewStack
(),
}
return
bm
...
...
@@ -189,7 +191,7 @@ func (bm *BlockManager) ProcessContract(tx *ethutil.Transaction, block *ethutil.
}()
// Process contract
bm
.
vm
.
ProcContract
(
tx
,
block
,
func
(
opType
OpType
)
bool
{
bm
.
ProcContract
(
tx
,
block
,
func
(
opType
OpType
)
bool
{
// TODO turn on once big ints are in place
//if !block.PayFee(tx.Hash(), StepFee.Uint64()) {
// return false
...
...
@@ -201,3 +203,198 @@ func (bm *BlockManager) ProcessContract(tx *ethutil.Transaction, block *ethutil.
// Broadcast we're done
lockChan
<-
true
}
func
(
bm
*
BlockManager
)
ProcContract
(
tx
*
ethutil
.
Transaction
,
block
*
ethutil
.
Block
,
cb
TxCallback
)
{
// Instruction pointer
pc
:=
0
contract
:=
block
.
GetContract
(
tx
.
Hash
())
if
contract
==
nil
{
fmt
.
Println
(
"Contract not found"
)
return
}
Pow256
:=
ethutil
.
BigPow
(
2
,
256
)
//fmt.Printf("# op arg\n")
out
:
for
{
// The base big int for all calculations. Use this for any results.
base
:=
new
(
big
.
Int
)
// XXX Should Instr return big int slice instead of string slice?
// Get the next instruction from the contract
//op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc)))))
nb
:=
ethutil
.
NumberToBytes
(
uint64
(
pc
),
32
)
o
,
_
,
_
:=
ethutil
.
Instr
(
contract
.
State
()
.
Get
(
string
(
nb
)))
op
:=
OpCode
(
o
)
if
!
cb
(
0
)
{
break
}
if
Debug
{
//fmt.Printf("%-3d %-4s\n", pc, op.String())
}
switch
op
{
case
oADD
:
x
,
y
:=
bm
.
stack
.
Popn
()
// (x + y) % 2 ** 256
base
.
Add
(
x
,
y
)
base
.
Mod
(
base
,
Pow256
)
// Pop result back on the stack
bm
.
stack
.
Push
(
base
.
String
())
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
())
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
())
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
())
case
oSDIV
:
x
,
y
:=
bm
.
stack
.
Popn
()
// n > 2**255
if
x
.
Cmp
(
Pow256
)
>
0
{
x
.
Sub
(
Pow256
,
x
)
}
if
y
.
Cmp
(
Pow256
)
>
0
{
y
.
Sub
(
Pow256
,
y
)
}
z
:=
new
(
big
.
Int
)
z
.
Div
(
x
,
y
)
if
z
.
Cmp
(
Pow256
)
>
0
{
z
.
Sub
(
Pow256
,
z
)
}
// Push result on to the stack
bm
.
stack
.
Push
(
z
.
String
())
case
oMOD
:
x
,
y
:=
bm
.
stack
.
Popn
()
base
.
Mod
(
x
,
y
)
bm
.
stack
.
Push
(
base
.
String
())
case
oSMOD
:
x
,
y
:=
bm
.
stack
.
Popn
()
// n > 2**255
if
x
.
Cmp
(
Pow256
)
>
0
{
x
.
Sub
(
Pow256
,
x
)
}
if
y
.
Cmp
(
Pow256
)
>
0
{
y
.
Sub
(
Pow256
,
y
)
}
z
:=
new
(
big
.
Int
)
z
.
Mod
(
x
,
y
)
if
z
.
Cmp
(
Pow256
)
>
0
{
z
.
Sub
(
Pow256
,
z
)
}
// Push result on to the stack
bm
.
stack
.
Push
(
z
.
String
())
case
oEXP
:
x
,
y
:=
bm
.
stack
.
Popn
()
base
.
Exp
(
x
,
y
,
Pow256
)
bm
.
stack
.
Push
(
base
.
String
())
case
oNEG
:
base
.
Sub
(
Pow256
,
ethutil
.
Big
(
bm
.
stack
.
Pop
()))
bm
.
stack
.
Push
(
base
.
String
())
case
oLT
:
x
,
y
:=
bm
.
stack
.
Popn
()
// x < y
if
x
.
Cmp
(
y
)
<
0
{
bm
.
stack
.
Push
(
"1"
)
}
else
{
bm
.
stack
.
Push
(
"0"
)
}
case
oLE
:
x
,
y
:=
bm
.
stack
.
Popn
()
// x <= y
if
x
.
Cmp
(
y
)
<
1
{
bm
.
stack
.
Push
(
"1"
)
}
else
{
bm
.
stack
.
Push
(
"0"
)
}
case
oGT
:
x
,
y
:=
bm
.
stack
.
Popn
()
// x > y
if
x
.
Cmp
(
y
)
>
0
{
bm
.
stack
.
Push
(
"1"
)
}
else
{
bm
.
stack
.
Push
(
"0"
)
}
case
oGE
:
x
,
y
:=
bm
.
stack
.
Popn
()
// x >= y
if
x
.
Cmp
(
y
)
>
-
1
{
bm
.
stack
.
Push
(
"1"
)
}
else
{
bm
.
stack
.
Push
(
"0"
)
}
case
oNOT
:
x
,
y
:=
bm
.
stack
.
Popn
()
// x != y
if
x
.
Cmp
(
y
)
!=
0
{
bm
.
stack
.
Push
(
"1"
)
}
else
{
bm
.
stack
.
Push
(
"0"
)
}
// 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
()))
case
oTXSENDER
:
bm
.
stack
.
Push
(
string
(
tx
.
Sender
()))
case
oTXVALUE
:
bm
.
stack
.
Push
(
tx
.
Value
.
String
())
case
oTXDATAN
:
bm
.
stack
.
Push
(
big
.
NewInt
(
int64
(
len
(
tx
.
Data
)))
.
String
())
case
oTXDATA
:
v
:=
ethutil
.
Big
(
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
())
}
else
{
bm
.
stack
.
Push
(
ethutil
.
Big
(
tx
.
Data
[
v
.
Uint64
()])
.
String
())
}
case
oBLK_PREVHASH
:
bm
.
stack
.
Push
(
string
(
block
.
PrevHash
))
case
oBLK_COINBASE
:
bm
.
stack
.
Push
(
block
.
Coinbase
)
case
oBLK_TIMESTAMP
:
bm
.
stack
.
Push
(
big
.
NewInt
(
block
.
Time
)
.
String
())
case
oBLK_NUMBER
:
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
))))
case
oPOP
:
// Pop current value of the stack
bm
.
stack
.
Pop
()
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
))))
case
oSTOP
:
break
out
}
pc
++
}
bm
.
stack
.
Print
()
}
stack.go
0 → 100644
View file @
83396cd8
package
main
import
(
"fmt"
"github.com/ethereum/ethutil-go"
"math/big"
)
type
OpCode
byte
// Op codes
const
(
oSTOP
OpCode
=
0x00
oADD
OpCode
=
0x01
oMUL
OpCode
=
0x02
oSUB
OpCode
=
0x03
oDIV
OpCode
=
0x04
oSDIV
OpCode
=
0x05
oMOD
OpCode
=
0x06
oSMOD
OpCode
=
0x07
oEXP
OpCode
=
0x08
oNEG
OpCode
=
0x09
oLT
OpCode
=
0x0a
oLE
OpCode
=
0x0b
oGT
OpCode
=
0x0c
oGE
OpCode
=
0x0d
oEQ
OpCode
=
0x0e
oNOT
OpCode
=
0x0f
oMYADDRESS
OpCode
=
0x10
oTXSENDER
OpCode
=
0x11
oTXVALUE
OpCode
=
0x12
oTXFEE
OpCode
=
0x13
oTXDATAN
OpCode
=
0x14
oTXDATA
OpCode
=
0x15
oBLK_PREVHASH
OpCode
=
0x16
oBLK_COINBASE
OpCode
=
0x17
oBLK_TIMESTAMP
OpCode
=
0x18
oBLK_NUMBER
OpCode
=
0x19
oBLK_DIFFICULTY
OpCode
=
0x1a
oSHA256
OpCode
=
0x20
oRIPEMD160
OpCode
=
0x21
oECMUL
OpCode
=
0x22
oECADD
OpCode
=
0x23
oECSIGN
OpCode
=
0x24
oECRECOVER
OpCode
=
0x25
oECVALID
OpCode
=
0x26
oPUSH
OpCode
=
0x30
oPOP
OpCode
=
0x31
oDUP
OpCode
=
0x32
oDUPN
OpCode
=
0x33
oSWAP
OpCode
=
0x34
oSWAPN
OpCode
=
0x35
oLOAD
OpCode
=
0x36
oSTORE
OpCode
=
0x37
oJMP
OpCode
=
0x40
oJMPI
OpCode
=
0x41
oIND
OpCode
=
0x42
oEXTRO
OpCode
=
0x50
oBALANCE
OpCode
=
0x51
oMKTX
OpCode
=
0x60
oSUICIDE
OpCode
=
0xff
)
// 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"
,
oTXFEE
:
"TXFEE"
,
oTXDATAN
:
"TXDATAN"
,
oTXDATA
:
"TXDATA"
,
oBLK_PREVHASH
:
"BLK_PREVHASH"
,
oBLK_COINBASE
:
"BLK_COINBASE"
,
oBLK_TIMESTAMP
:
"BLK_TIMESTAMP"
,
oBLK_NUMBER
:
"BLK_NUMBER"
,
oBLK_DIFFICULTY
:
"BLK_DIFFIFULTY"
,
oSHA256
:
"SHA256"
,
oRIPEMD160
:
"RIPEMD160"
,
oECMUL
:
"ECMUL"
,
oECADD
:
"ECADD"
,
oECSIGN
:
"ECSIGN"
,
oECRECOVER
:
"ECRECOVER"
,
oECVALID
:
"ECVALID"
,
oPUSH
:
"PUSH"
,
oPOP
:
"POP"
,
oDUP
:
"DUP"
,
oDUPN
:
"DUPN"
,
oSWAP
:
"SWAP"
,
oSWAPN
:
"SWAPN"
,
oLOAD
:
"LOAD"
,
oSTORE
:
"STORE"
,
oJMP
:
"JMP"
,
oJMPI
:
"JMPI"
,
oIND
:
"IND"
,
oEXTRO
:
"EXTRO"
,
oBALANCE
:
"BALANCE"
,
oMKTX
:
"MKTX"
,
oSUICIDE
:
"SUICIDE"
,
}
func
(
o
OpCode
)
String
()
string
{
return
opCodeToString
[
o
]
}
type
OpType
int
const
(
tNorm
=
iota
tData
tExtro
tCrypto
)
type
TxCallback
func
(
opType
OpType
)
bool
// Simple push/pop stack mechanism
type
Stack
struct
{
data
[]
string
}
func
NewStack
()
*
Stack
{
return
&
Stack
{}
}
func
(
st
*
Stack
)
Pop
()
string
{
s
:=
len
(
st
.
data
)
str
:=
st
.
data
[
s
-
1
]
st
.
data
=
st
.
data
[
:
s
-
1
]
return
str
}
func
(
st
*
Stack
)
Popn
()
(
*
big
.
Int
,
*
big
.
Int
)
{
s
:=
len
(
st
.
data
)
strs
:=
st
.
data
[
s
-
2
:
]
st
.
data
=
st
.
data
[
:
s
-
2
]
return
ethutil
.
Big
(
strs
[
0
]),
ethutil
.
Big
(
strs
[
1
])
}
func
(
st
*
Stack
)
Push
(
d
string
)
{
st
.
data
=
append
(
st
.
data
,
d
)
}
func
(
st
*
Stack
)
Print
()
{
fmt
.
Println
(
st
.
data
)
}
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