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
c68ff988
Commit
c68ff988
authored
Mar 20, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed MSTORE and added some more commets
parent
f21eb88a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
51 additions
and
18 deletions
+51
-18
closure.go
ethchain/closure.go
+12
-4
stack.go
ethchain/stack.go
+1
-0
vm.go
ethchain/vm.go
+34
-12
vm_test.go
ethchain/vm_test.go
+4
-2
No files found.
ethchain/closure.go
View file @
c68ff988
...
...
@@ -21,15 +21,17 @@ type ClosureBody interface {
type
Closure
struct
{
callee
Callee
object
ClosureBody
s
tate
*
State
S
tate
*
State
gas
*
big
.
Int
val
*
big
.
Int
args
[]
byte
}
// Create a new closure for the given data items
func
NewClosure
(
callee
Callee
,
object
ClosureBody
,
state
*
State
,
gas
,
val
*
big
.
Int
)
*
Closure
{
return
&
Closure
{
callee
,
object
,
state
,
gas
,
val
}
return
&
Closure
{
callee
,
object
,
state
,
gas
,
val
,
nil
}
}
// Retuns the x element in data slice
...
...
@@ -42,14 +44,20 @@ func (c *Closure) GetMem(x int64) *ethutil.Value {
return
m
}
func
(
c
*
Closure
)
Call
(
vm
*
Vm
,
args
[]
byte
)
[]
byte
{
c
.
args
=
args
return
vm
.
RunClosure
(
c
)
}
func
(
c
*
Closure
)
Return
(
ret
[]
byte
)
[]
byte
{
// Return the remaining gas to the callee
// If no callee is present return it to
// the origin (i.e. contract or tx)
if
c
.
callee
!=
nil
{
c
.
callee
.
ReturnGas
(
c
.
gas
,
c
.
s
tate
)
c
.
callee
.
ReturnGas
(
c
.
gas
,
c
.
S
tate
)
}
else
{
c
.
object
.
ReturnGas
(
c
.
gas
,
c
.
s
tate
)
c
.
object
.
ReturnGas
(
c
.
gas
,
c
.
S
tate
)
// TODO incase it's a POST contract we gotta serialise the contract again.
// But it's not yet defined
}
...
...
ethchain/stack.go
View file @
c68ff988
...
...
@@ -235,6 +235,7 @@ func (st *ValueStack) Peekn() (*ethutil.Value, *ethutil.Value) {
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
{
...
...
ethchain/vm.go
View file @
c68ff988
...
...
@@ -18,6 +18,8 @@ type Vm struct {
mem
map
[
string
]
*
big
.
Int
vars
RuntimeVars
state
*
State
}
type
RuntimeVars
struct
{
...
...
@@ -32,7 +34,11 @@ type RuntimeVars struct {
txData
[]
string
}
func
(
vm
*
Vm
)
RunClosure
(
closure
*
Closure
,
state
*
State
,
vars
RuntimeVars
)
[]
byte
{
func
NewVm
(
state
*
State
,
vars
RuntimeVars
)
*
Vm
{
return
&
Vm
{
vars
:
vars
,
state
:
state
}
}
func
(
vm
*
Vm
)
RunClosure
(
closure
*
Closure
)
[]
byte
{
// If the amount of gas supplied is less equal to 0
if
closure
.
GetGas
()
.
Cmp
(
big
.
NewInt
(
0
))
<=
0
{
// TODO Do something
...
...
@@ -71,17 +77,28 @@ func (vm *Vm) RunClosure(closure *Closure, state *State, vars RuntimeVars) []byt
}
switch
op
{
case
oSTOP
:
case
oSTOP
:
// Stop the closure
return
closure
.
Return
(
nil
)
case
oPUSH
:
case
oPUSH
:
// Push PC+1 on to the stack
pc
++
val
:=
closure
.
GetMem
(
pc
)
.
BigInt
()
stack
.
Push
(
val
)
case
oMSTORE
:
case
oMSTORE
:
// Store the value at stack top-1 in to memory at location stack top
// Pop value of the stack
val
:=
stack
.
Pop
()
// Set the bytes to the memory field
mem
=
append
(
mem
,
ethutil
.
BigToBytes
(
val
,
256
)
...
)
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
))
case
oCALL
:
// Pop return size and offset
retSize
,
retOffset
:=
stack
.
Popn
()
...
...
@@ -93,20 +110,25 @@ func (vm *Vm) RunClosure(closure *Closure, state *State, vars RuntimeVars) []byt
gas
,
value
:=
stack
.
Popn
()
// Closure addr
addr
:=
stack
.
Pop
()
contract
:=
state
.
GetContract
(
addr
.
Bytes
())
closure
:=
NewClosure
(
closure
,
contract
,
state
,
gas
,
value
)
ret
:=
vm
.
RunClosure
(
closure
,
state
,
vars
)
// Fetch the contract which will serve as the closure body
contract
:=
vm
.
state
.
GetContract
(
addr
.
Bytes
())
// Create a new callable closure
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
)))
// Resize the current memory slice so that the return value may fit
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
)
case
oRETURN
:
size
,
offset
:=
stack
.
Popn
()
...
...
ethchain/vm_test.go
View file @
c68ff988
...
...
@@ -117,8 +117,10 @@ func TestRun3(t *testing.T) {
script
:=
Compile
([]
string
{
"PUSH"
,
"300"
,
"PUSH"
,
"0"
,
"MSTORE"
,
"PUSH"
,
"300"
,
"PUSH"
,
"31"
,
"MSTORE"
,
"PUSH"
,
"62"
,
"PUSH"
,
"0"
,
...
...
@@ -147,8 +149,7 @@ func TestRun3(t *testing.T) {
executer
.
Sign
([]
byte
(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
))
callerClosure
:=
NewClosure
(
executer
,
MakeContract
(
callerTx
,
state
),
state
,
big
.
NewInt
(
1000000000
),
new
(
big
.
Int
))
vm
:=
&
Vm
{}
vm
.
RunClosure
(
callerClosure
,
state
,
RuntimeVars
{
vm
:=
NewVm
(
state
,
RuntimeVars
{
address
:
callerAddr
,
blockNumber
:
1
,
sender
:
ethutil
.
FromHex
(
"cd1722f3947def4cf144679da39c4c32bdc35681"
),
...
...
@@ -159,4 +160,5 @@ func TestRun3(t *testing.T) {
txValue
:
big
.
NewInt
(
10000
),
txData
:
nil
,
})
callerClosure
.
Call
(
vm
,
nil
)
}
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