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
7d6ba88d
Commit
7d6ba88d
authored
Apr 11, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'split' into develop
parents
d927c154
25dd4606
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
176 additions
and
163 deletions
+176
-163
closure.go
ethchain/closure.go
+20
-5
contract.go
ethchain/contract.go
+25
-8
stack.go
ethchain/stack.go
+2
-1
state_manager.go
ethchain/state_manager.go
+1
-1
transaction.go
ethchain/transaction.go
+25
-41
transaction_test.go
ethchain/transaction_test.go
+0
-53
vm.go
ethchain/vm.go
+51
-12
vm_test.go
ethchain/vm_test.go
+30
-15
parsing.go
ethutil/parsing.go
+16
-26
rlp.go
ethutil/rlp.go
+6
-1
No files found.
ethchain/closure.go
View file @
7d6ba88d
...
@@ -12,7 +12,7 @@ type Callee interface {
...
@@ -12,7 +12,7 @@ type Callee interface {
Address
()
[]
byte
Address
()
[]
byte
}
}
type
ClosureBody
interface
{
type
Reference
interface
{
Callee
Callee
ethutil
.
RlpEncodable
ethutil
.
RlpEncodable
GetMem
(
*
big
.
Int
)
*
ethutil
.
Value
GetMem
(
*
big
.
Int
)
*
ethutil
.
Value
...
@@ -22,7 +22,8 @@ type ClosureBody interface {
...
@@ -22,7 +22,8 @@ type ClosureBody interface {
// Basic inline closure object which implement the 'closure' interface
// Basic inline closure object which implement the 'closure' interface
type
Closure
struct
{
type
Closure
struct
{
callee
Callee
callee
Callee
object
ClosureBody
object
Reference
Script
[]
byte
State
*
State
State
*
State
Gas
*
big
.
Int
Gas
*
big
.
Int
...
@@ -32,8 +33,8 @@ type Closure struct {
...
@@ -32,8 +33,8 @@ type Closure struct {
}
}
// Create a new closure for the given data items
// Create a new closure for the given data items
func
NewClosure
(
callee
Callee
,
object
ClosureBody
,
state
*
State
,
gas
,
val
*
big
.
Int
)
*
Closure
{
func
NewClosure
(
callee
Callee
,
object
Reference
,
script
[]
byte
,
state
*
State
,
gas
,
val
*
big
.
Int
)
*
Closure
{
return
&
Closure
{
callee
,
object
,
state
,
gas
,
val
,
nil
}
return
&
Closure
{
callee
,
object
,
s
cript
,
s
tate
,
gas
,
val
,
nil
}
}
}
// Retuns the x element in data slice
// Retuns the x element in data slice
...
@@ -46,6 +47,20 @@ func (c *Closure) GetMem(x *big.Int) *ethutil.Value {
...
@@ -46,6 +47,20 @@ func (c *Closure) GetMem(x *big.Int) *ethutil.Value {
return
m
return
m
}
}
func
(
c
*
Closure
)
Get
(
x
*
big
.
Int
)
*
ethutil
.
Value
{
return
c
.
Gets
(
x
,
big
.
NewInt
(
1
))
}
func
(
c
*
Closure
)
Gets
(
x
,
y
*
big
.
Int
)
*
ethutil
.
Value
{
if
x
.
Int64
()
>
int64
(
len
(
c
.
Script
))
||
y
.
Int64
()
>
int64
(
len
(
c
.
Script
))
{
return
ethutil
.
NewValue
(
0
)
}
partial
:=
c
.
Script
[
x
.
Int64
()
:
x
.
Int64
()
+
y
.
Int64
()]
return
ethutil
.
NewValue
(
partial
)
}
func
(
c
*
Closure
)
SetMem
(
x
*
big
.
Int
,
val
*
ethutil
.
Value
)
{
func
(
c
*
Closure
)
SetMem
(
x
*
big
.
Int
,
val
*
ethutil
.
Value
)
{
c
.
object
.
SetMem
(
x
,
val
)
c
.
object
.
SetMem
(
x
,
val
)
}
}
...
@@ -81,7 +96,7 @@ func (c *Closure) ReturnGas(gas *big.Int, state *State) {
...
@@ -81,7 +96,7 @@ func (c *Closure) ReturnGas(gas *big.Int, state *State) {
c
.
Gas
.
Add
(
c
.
Gas
,
gas
)
c
.
Gas
.
Add
(
c
.
Gas
,
gas
)
}
}
func
(
c
*
Closure
)
Object
()
ClosureBody
{
func
(
c
*
Closure
)
Object
()
Reference
{
return
c
.
object
return
c
.
object
}
}
...
...
ethchain/contract.go
View file @
7d6ba88d
...
@@ -11,6 +11,8 @@ type Contract struct {
...
@@ -11,6 +11,8 @@ type Contract struct {
//state *ethutil.Trie
//state *ethutil.Trie
state
*
State
state
*
State
address
[]
byte
address
[]
byte
script
[]
byte
initScript
[]
byte
}
}
func
NewContract
(
address
[]
byte
,
Amount
*
big
.
Int
,
root
[]
byte
)
*
Contract
{
func
NewContract
(
address
[]
byte
,
Amount
*
big
.
Int
,
root
[]
byte
)
*
Contract
{
...
@@ -45,6 +47,14 @@ func (c *Contract) GetMem(num *big.Int) *ethutil.Value {
...
@@ -45,6 +47,14 @@ func (c *Contract) GetMem(num *big.Int) *ethutil.Value {
return
c
.
Addr
(
nb
)
return
c
.
Addr
(
nb
)
}
}
func
(
c
*
Contract
)
GetInstr
(
pc
*
big
.
Int
)
*
ethutil
.
Value
{
if
int64
(
len
(
c
.
script
)
-
1
)
<
pc
.
Int64
()
{
return
ethutil
.
NewValue
(
0
)
}
return
ethutil
.
NewValueFromBytes
([]
byte
{
c
.
script
[
pc
.
Int64
()]})
}
func
(
c
*
Contract
)
SetMem
(
num
*
big
.
Int
,
val
*
ethutil
.
Value
)
{
func
(
c
*
Contract
)
SetMem
(
num
*
big
.
Int
,
val
*
ethutil
.
Value
)
{
addr
:=
ethutil
.
BigToBytes
(
num
,
256
)
addr
:=
ethutil
.
BigToBytes
(
num
,
256
)
c
.
state
.
trie
.
Update
(
string
(
addr
),
string
(
val
.
Encode
()))
c
.
state
.
trie
.
Update
(
string
(
addr
),
string
(
val
.
Encode
()))
...
@@ -60,7 +70,7 @@ func (c *Contract) Address() []byte {
...
@@ -60,7 +70,7 @@ func (c *Contract) Address() []byte {
}
}
func
(
c
*
Contract
)
RlpEncode
()
[]
byte
{
func
(
c
*
Contract
)
RlpEncode
()
[]
byte
{
return
ethutil
.
Encode
([]
interface
{}{
c
.
Amount
,
c
.
Nonce
,
c
.
state
.
trie
.
Root
})
return
ethutil
.
Encode
([]
interface
{}{
c
.
Amount
,
c
.
Nonce
,
c
.
state
.
trie
.
Root
,
c
.
script
,
c
.
initScript
})
}
}
func
(
c
*
Contract
)
RlpDecode
(
data
[]
byte
)
{
func
(
c
*
Contract
)
RlpDecode
(
data
[]
byte
)
{
...
@@ -69,6 +79,8 @@ func (c *Contract) RlpDecode(data []byte) {
...
@@ -69,6 +79,8 @@ func (c *Contract) RlpDecode(data []byte) {
c
.
Amount
=
decoder
.
Get
(
0
)
.
BigInt
()
c
.
Amount
=
decoder
.
Get
(
0
)
.
BigInt
()
c
.
Nonce
=
decoder
.
Get
(
1
)
.
Uint
()
c
.
Nonce
=
decoder
.
Get
(
1
)
.
Uint
()
c
.
state
=
NewState
(
ethutil
.
NewTrie
(
ethutil
.
Config
.
Db
,
decoder
.
Get
(
2
)
.
Interface
()))
c
.
state
=
NewState
(
ethutil
.
NewTrie
(
ethutil
.
Config
.
Db
,
decoder
.
Get
(
2
)
.
Interface
()))
c
.
script
=
decoder
.
Get
(
3
)
.
Bytes
()
c
.
initScript
=
decoder
.
Get
(
4
)
.
Bytes
()
}
}
func
MakeContract
(
tx
*
Transaction
,
state
*
State
)
*
Contract
{
func
MakeContract
(
tx
*
Transaction
,
state
*
State
)
*
Contract
{
...
@@ -79,12 +91,17 @@ func MakeContract(tx *Transaction, state *State) *Contract {
...
@@ -79,12 +91,17 @@ func MakeContract(tx *Transaction, state *State) *Contract {
value
:=
tx
.
Value
value
:=
tx
.
Value
contract
:=
NewContract
(
addr
,
value
,
[]
byte
(
""
))
contract
:=
NewContract
(
addr
,
value
,
[]
byte
(
""
))
state
.
trie
.
Update
(
string
(
addr
),
string
(
contract
.
RlpEncode
()))
state
.
trie
.
Update
(
string
(
addr
),
string
(
contract
.
RlpEncode
()))
contract
.
script
=
tx
.
Data
contract
.
initScript
=
tx
.
Init
/*
for i, val := range tx.Data {
for i, val := range tx.Data {
if len(val) > 0 {
if len(val) > 0 {
bytNum := ethutil.BigToBytes(big.NewInt(int64(i)), 256)
bytNum := ethutil.BigToBytes(big.NewInt(int64(i)), 256)
contract.state.trie.Update(string(bytNum), string(ethutil.Encode(val)))
contract.state.trie.Update(string(bytNum), string(ethutil.Encode(val)))
}
}
}
}
*/
state
.
trie
.
Update
(
string
(
addr
),
string
(
contract
.
RlpEncode
()))
state
.
trie
.
Update
(
string
(
addr
),
string
(
contract
.
RlpEncode
()))
return
contract
return
contract
...
...
ethchain/stack.go
View file @
7d6ba88d
...
@@ -55,6 +55,7 @@ const (
...
@@ -55,6 +55,7 @@ const (
// 0x50 range - 'storage' and execution
// 0x50 range - 'storage' and execution
oPUSH
=
0x50
oPUSH
=
0x50
oPUSH20
=
0x80
oPOP
=
0x51
oPOP
=
0x51
oDUP
=
0x52
oDUP
=
0x52
oSWAP
=
0x53
oSWAP
=
0x53
...
@@ -250,7 +251,7 @@ func (m *Memory) Print() {
...
@@ -250,7 +251,7 @@ func (m *Memory) Print() {
if
len
(
m
.
store
)
>
0
{
if
len
(
m
.
store
)
>
0
{
addr
:=
0
addr
:=
0
for
i
:=
0
;
i
+
32
<=
len
(
m
.
store
);
i
+=
32
{
for
i
:=
0
;
i
+
32
<=
len
(
m
.
store
);
i
+=
32
{
fmt
.
Printf
(
"%03d
%v
\n
"
,
addr
,
m
.
store
[
i
:
i
+
32
])
fmt
.
Printf
(
"%03d
: % x
\n
"
,
addr
,
m
.
store
[
i
:
i
+
32
])
addr
++
addr
++
}
}
}
else
{
}
else
{
...
...
ethchain/state_manager.go
View file @
7d6ba88d
...
@@ -316,7 +316,7 @@ func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, blo
...
@@ -316,7 +316,7 @@ func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, blo
}()
}()
caller
:=
sm
.
procState
.
GetAccount
(
tx
.
Sender
())
caller
:=
sm
.
procState
.
GetAccount
(
tx
.
Sender
())
closure
:=
NewClosure
(
caller
,
contract
,
sm
.
procState
,
tx
.
Gas
,
tx
.
Value
)
closure
:=
NewClosure
(
caller
,
contract
,
contract
.
script
,
sm
.
procState
,
tx
.
Gas
,
tx
.
Value
)
vm
:=
NewVm
(
sm
.
procState
,
RuntimeVars
{
vm
:=
NewVm
(
sm
.
procState
,
RuntimeVars
{
origin
:
caller
.
Address
(),
origin
:
caller
.
Address
(),
blockNumber
:
block
.
BlockInfo
()
.
Number
,
blockNumber
:
block
.
BlockInfo
()
.
Number
,
...
...
ethchain/transaction.go
View file @
7d6ba88d
...
@@ -14,7 +14,8 @@ type Transaction struct {
...
@@ -14,7 +14,8 @@ type Transaction struct {
Value
*
big
.
Int
Value
*
big
.
Int
Gas
*
big
.
Int
Gas
*
big
.
Int
Gasprice
*
big
.
Int
Gasprice
*
big
.
Int
Data
[]
string
Data
[]
byte
Init
[]
byte
v
byte
v
byte
r
,
s
[]
byte
r
,
s
[]
byte
...
@@ -22,11 +23,11 @@ type Transaction struct {
...
@@ -22,11 +23,11 @@ type Transaction struct {
contractCreation
bool
contractCreation
bool
}
}
func
NewContractCreationTx
(
value
,
gasprice
*
big
.
Int
,
data
[]
string
)
*
Transaction
{
func
NewContractCreationTx
(
value
,
gasprice
*
big
.
Int
,
data
[]
byte
)
*
Transaction
{
return
&
Transaction
{
Value
:
value
,
Gasprice
:
gasprice
,
Data
:
data
,
contractCreation
:
true
}
return
&
Transaction
{
Value
:
value
,
Gasprice
:
gasprice
,
Data
:
data
,
contractCreation
:
true
}
}
}
func
NewTransactionMessage
(
to
[]
byte
,
value
,
gasprice
,
gas
*
big
.
Int
,
data
[]
string
)
*
Transaction
{
func
NewTransactionMessage
(
to
[]
byte
,
value
,
gasprice
,
gas
*
big
.
Int
,
data
[]
byte
)
*
Transaction
{
return
&
Transaction
{
Recipient
:
to
,
Value
:
value
,
Gasprice
:
gasprice
,
Gas
:
gas
,
Data
:
data
}
return
&
Transaction
{
Recipient
:
to
,
Value
:
value
,
Gasprice
:
gasprice
,
Gas
:
gas
,
Data
:
data
}
}
}
...
@@ -45,19 +46,12 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
...
@@ -45,19 +46,12 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
}
}
func
(
tx
*
Transaction
)
Hash
()
[]
byte
{
func
(
tx
*
Transaction
)
Hash
()
[]
byte
{
data
:=
make
([]
interface
{},
len
(
tx
.
Data
))
data
:=
[]
interface
{}{
tx
.
Nonce
,
tx
.
Value
,
tx
.
Gasprice
,
tx
.
Gas
,
tx
.
Recipient
,
string
(
tx
.
Data
)}
for
i
,
val
:=
range
tx
.
Data
{
if
tx
.
contractCreation
{
data
[
i
]
=
val
data
=
append
(
data
,
string
(
tx
.
Init
))
}
}
preEnc
:=
[]
interface
{}{
return
ethutil
.
Sha3Bin
(
ethutil
.
NewValue
(
data
)
.
Encode
())
tx
.
Nonce
,
tx
.
Recipient
,
tx
.
Value
,
data
,
}
return
ethutil
.
Sha3Bin
(
ethutil
.
Encode
(
preEnc
))
}
}
func
(
tx
*
Transaction
)
IsContract
()
bool
{
func
(
tx
*
Transaction
)
IsContract
()
bool
{
...
@@ -110,15 +104,17 @@ func (tx *Transaction) Sign(privk []byte) error {
...
@@ -110,15 +104,17 @@ func (tx *Transaction) Sign(privk []byte) error {
return
nil
return
nil
}
}
// [ NONCE, VALUE, GASPRICE, GAS, TO, DATA, V, R, S ]
// [ NONCE, VALUE, GASPRICE, GAS, 0, CODE, INIT, V, R, S ]
func
(
tx
*
Transaction
)
RlpData
()
interface
{}
{
func
(
tx
*
Transaction
)
RlpData
()
interface
{}
{
data
:=
[]
interface
{}{
tx
.
Nonce
,
tx
.
Value
,
tx
.
Gasprice
}
data
:=
[]
interface
{}{
tx
.
Nonce
,
tx
.
Value
,
tx
.
Gasprice
,
tx
.
Gas
,
tx
.
Recipient
,
tx
.
Data
}
if
!
tx
.
contractCreation
{
if
tx
.
contractCreation
{
data
=
append
(
data
,
tx
.
Recipient
,
tx
.
Gas
)
data
=
append
(
data
,
tx
.
Init
)
}
}
d
:=
ethutil
.
NewSliceValue
(
tx
.
Data
)
.
Slice
()
//
d := ethutil.NewSliceValue(tx.Data).Slice()
return
append
(
data
,
d
,
tx
.
v
,
tx
.
r
,
tx
.
s
)
return
append
(
data
,
tx
.
v
,
tx
.
r
,
tx
.
s
)
}
}
func
(
tx
*
Transaction
)
RlpValue
()
*
ethutil
.
Value
{
func
(
tx
*
Transaction
)
RlpValue
()
*
ethutil
.
Value
{
...
@@ -137,31 +133,19 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
...
@@ -137,31 +133,19 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
tx
.
Nonce
=
decoder
.
Get
(
0
)
.
Uint
()
tx
.
Nonce
=
decoder
.
Get
(
0
)
.
Uint
()
tx
.
Value
=
decoder
.
Get
(
1
)
.
BigInt
()
tx
.
Value
=
decoder
.
Get
(
1
)
.
BigInt
()
tx
.
Gasprice
=
decoder
.
Get
(
2
)
.
BigInt
()
tx
.
Gasprice
=
decoder
.
Get
(
2
)
.
BigInt
()
tx
.
Gas
=
decoder
.
Get
(
3
)
.
BigInt
()
tx
.
Recipient
=
decoder
.
Get
(
4
)
.
Bytes
()
tx
.
Data
=
decoder
.
Get
(
5
)
.
Bytes
()
// If the 4th item is a list(slice) this tx
// If the list is of length 10 it's a contract creation tx
// is a contract creation tx
if
decoder
.
Len
()
==
10
{
if
decoder
.
Get
(
3
)
.
IsList
()
{
d
:=
decoder
.
Get
(
3
)
tx
.
Data
=
make
([]
string
,
d
.
Len
())
for
i
:=
0
;
i
<
d
.
Len
();
i
++
{
tx
.
Data
[
i
]
=
d
.
Get
(
i
)
.
Str
()
}
tx
.
v
=
byte
(
decoder
.
Get
(
4
)
.
Uint
())
tx
.
r
=
decoder
.
Get
(
5
)
.
Bytes
()
tx
.
s
=
decoder
.
Get
(
6
)
.
Bytes
()
tx
.
contractCreation
=
true
tx
.
contractCreation
=
true
}
else
{
tx
.
Init
=
decoder
.
Get
(
6
)
.
Bytes
()
tx
.
Recipient
=
decoder
.
Get
(
3
)
.
Bytes
()
tx
.
Gas
=
decoder
.
Get
(
4
)
.
BigInt
()
d
:=
decoder
.
Get
(
5
)
tx
.
Data
=
make
([]
string
,
d
.
Len
())
for
i
:=
0
;
i
<
d
.
Len
();
i
++
{
tx
.
Data
[
i
]
=
d
.
Get
(
i
)
.
Str
()
}
tx
.
v
=
byte
(
decoder
.
Get
(
7
)
.
Uint
())
tx
.
r
=
decoder
.
Get
(
8
)
.
Bytes
()
tx
.
s
=
decoder
.
Get
(
9
)
.
Bytes
()
}
else
{
tx
.
v
=
byte
(
decoder
.
Get
(
6
)
.
Uint
())
tx
.
v
=
byte
(
decoder
.
Get
(
6
)
.
Uint
())
tx
.
r
=
decoder
.
Get
(
7
)
.
Bytes
()
tx
.
r
=
decoder
.
Get
(
7
)
.
Bytes
()
tx
.
s
=
decoder
.
Get
(
8
)
.
Bytes
()
tx
.
s
=
decoder
.
Get
(
8
)
.
Bytes
()
...
...
ethchain/transaction_test.go
View file @
7d6ba88d
package
ethchain
package
ethchain
import
(
"encoding/hex"
"math/big"
"testing"
)
func
TestAddressRetrieval
(
t
*
testing
.
T
)
{
// TODO
// 88f9b82462f6c4bf4a0fb15e5c3971559a316e7f
key
,
_
:=
hex
.
DecodeString
(
"3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4"
)
tx
:=
&
Transaction
{
Nonce
:
0
,
Recipient
:
ZeroHash160
,
Value
:
big
.
NewInt
(
0
),
Data
:
nil
,
}
//fmt.Printf("rlp %x\n", tx.RlpEncode())
//fmt.Printf("sha rlp %x\n", tx.Hash())
tx
.
Sign
(
key
)
//fmt.Printf("hex tx key %x\n", tx.PublicKey())
//fmt.Printf("seder %x\n", tx.Sender())
}
func
TestAddressRetrieval2
(
t
*
testing
.
T
)
{
// TODO
// 88f9b82462f6c4bf4a0fb15e5c3971559a316e7f
key
,
_
:=
hex
.
DecodeString
(
"3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4"
)
addr
,
_
:=
hex
.
DecodeString
(
"944400f4b88ac9589a0f17ed4671da26bddb668b"
)
tx
:=
&
Transaction
{
Nonce
:
0
,
Recipient
:
addr
,
Value
:
big
.
NewInt
(
1000
),
Data
:
nil
,
}
tx
.
Sign
(
key
)
//data, _ := hex.DecodeString("f85d8094944400f4b88ac9589a0f17ed4671da26bddb668b8203e8c01ca0363b2a410de00bc89be40f468d16e70e543b72191fbd8a684a7c5bef51dc451fa02d8ecf40b68f9c64ed623f6ee24c9c878943b812e1e76bd73ccb2bfef65579e7")
//tx := NewTransactionFromData(data)
/*
fmt.Println(tx.RlpValue())
fmt.Printf("rlp %x\n", tx.RlpEncode())
fmt.Printf("sha rlp %x\n", tx.Hash())
//tx.Sign(key)
fmt.Printf("hex tx key %x\n", tx.PublicKey())
fmt.Printf("seder %x\n", tx.Sender())
*/
}
ethchain/vm.go
View file @
7d6ba88d
...
@@ -2,7 +2,7 @@ package ethchain
...
@@ -2,7 +2,7 @@ package ethchain
import
(
import
(
_
"bytes"
_
"bytes"
"fmt"
_
"fmt"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethutil"
_
"github.com/obscuren/secp256k1-go"
_
"github.com/obscuren/secp256k1-go"
_
"math"
_
"math"
...
@@ -72,7 +72,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
...
@@ -72,7 +72,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
for
{
for
{
step
++
step
++
// Get the memory location of pc
// Get the memory location of pc
val
:=
closure
.
Get
Mem
(
pc
)
val
:=
closure
.
Get
(
pc
)
// Get the opcode (it must be an opcode!)
// Get the opcode (it must be an opcode!)
op
:=
OpCode
(
val
.
Uint
())
op
:=
OpCode
(
val
.
Uint
())
if
ethutil
.
Config
.
Debug
{
if
ethutil
.
Config
.
Debug
{
...
@@ -233,13 +233,37 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
...
@@ -233,13 +233,37 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
// 0x10 range
// 0x10 range
case
oAND
:
case
oAND
:
x
,
y
:=
stack
.
Popn
()
if
(
x
.
Cmp
(
ethutil
.
BigTrue
)
>=
0
)
&&
(
y
.
Cmp
(
ethutil
.
BigTrue
)
>=
0
)
{
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oOR
:
case
oOR
:
x
,
y
:=
stack
.
Popn
()
if
(
x
.
Cmp
(
ethutil
.
BigInt0
)
>=
0
)
||
(
y
.
Cmp
(
ethutil
.
BigInt0
)
>=
0
)
{
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oXOR
:
case
oXOR
:
x
,
y
:=
stack
.
Popn
()
stack
.
Push
(
base
.
Xor
(
x
,
y
))
case
oBYTE
:
case
oBYTE
:
val
,
th
:=
stack
.
Popn
()
if
th
.
Cmp
(
big
.
NewInt
(
32
))
<
0
{
stack
.
Push
(
big
.
NewInt
(
int64
(
len
(
val
.
Bytes
())
-
1
)
-
th
.
Int64
()))
}
else
{
stack
.
Push
(
ethutil
.
BigFalse
)
}
// 0x20 range
// 0x20 range
case
oSHA3
:
case
oSHA3
:
size
,
offset
:=
stack
.
Popn
()
data
:=
mem
.
Get
(
offset
.
Int64
(),
size
.
Int64
())
stack
.
Push
(
ethutil
.
BigD
(
data
))
// 0x30 range
// 0x30 range
case
oADDRESS
:
case
oADDRESS
:
stack
.
Push
(
ethutil
.
BigD
(
closure
.
Object
()
.
Address
()))
stack
.
Push
(
ethutil
.
BigD
(
closure
.
Object
()
.
Address
()))
...
@@ -277,9 +301,23 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
...
@@ -277,9 +301,23 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
// 0x50 range
// 0x50 range
case
oPUSH
:
// Push PC+1 on to the stack
case
oPUSH
:
// Push PC+1 on to the stack
pc
.
Add
(
pc
,
ethutil
.
Big1
)
pc
.
Add
(
pc
,
ethutil
.
Big1
)
data
:=
closure
.
Gets
(
pc
,
big
.
NewInt
(
32
))
val
:=
ethutil
.
BigD
(
data
.
Bytes
())
// Push value to stack
stack
.
Push
(
val
)
pc
.
Add
(
pc
,
big
.
NewInt
(
31
))
case
oPUSH20
:
pc
.
Add
(
pc
,
ethutil
.
Big1
)
data
:=
closure
.
Gets
(
pc
,
big
.
NewInt
(
20
))
val
:=
ethutil
.
BigD
(
data
.
Bytes
())
val
:=
closure
.
GetMem
(
pc
)
.
BigInt
()
// Push value to stack
stack
.
Push
(
val
)
stack
.
Push
(
val
)
pc
.
Add
(
pc
,
big
.
NewInt
(
19
))
case
oPOP
:
case
oPOP
:
stack
.
Pop
()
stack
.
Pop
()
case
oDUP
:
case
oDUP
:
...
@@ -319,21 +357,20 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
...
@@ -319,21 +357,20 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
stack
.
Push
(
big
.
NewInt
(
int64
(
mem
.
Len
())))
stack
.
Push
(
big
.
NewInt
(
int64
(
mem
.
Len
())))
// 0x60 range
// 0x60 range
case
oCALL
:
case
oCALL
:
// Pop return size and offset
// Closure addr
retSize
,
retOffset
:=
stack
.
Popn
()
addr
:=
stack
.
Pop
()
// Pop gas and value of the stack.
gas
,
value
:=
stack
.
Popn
()
// Pop input size and offset
// Pop input size and offset
inSize
,
inOffset
:=
stack
.
Popn
()
inSize
,
inOffset
:=
stack
.
Popn
()
fmt
.
Println
(
inSize
,
inOffset
)
// Pop return size and offset
retSize
,
retOffset
:=
stack
.
Popn
()
// Get the arguments from the memory
// Get the arguments from the memory
args
:=
mem
.
Get
(
inOffset
.
Int64
(),
inSize
.
Int64
())
args
:=
mem
.
Get
(
inOffset
.
Int64
(),
inSize
.
Int64
())
// Pop gas and value of the stack.
gas
,
value
:=
stack
.
Popn
()
// Closure addr
addr
:=
stack
.
Pop
()
// Fetch the contract which will serve as the closure body
// Fetch the contract which will serve as the closure body
contract
:=
vm
.
state
.
GetContract
(
addr
.
Bytes
())
contract
:=
vm
.
state
.
GetContract
(
addr
.
Bytes
())
// Create a new callable closure
// Create a new callable closure
closure
:=
NewClosure
(
closure
,
contract
,
vm
.
state
,
gas
,
value
)
closure
:=
NewClosure
(
closure
,
contract
,
contract
.
script
,
vm
.
state
,
gas
,
value
)
// Executer the closure and get the return value (if any)
// Executer the closure and get the return value (if any)
ret
:=
closure
.
Call
(
vm
,
args
)
ret
:=
closure
.
Call
(
vm
,
args
)
...
@@ -361,7 +398,9 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
...
@@ -361,7 +398,9 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
break out
break out
*/
*/
default
:
default
:
ethutil
.
Config
.
Log
.
Debugln
(
"Invalid opcode"
,
op
)
ethutil
.
Config
.
Log
.
Debugf
(
"Invalid opcode %x
\n
"
,
op
)
return
closure
.
Return
(
nil
)
}
}
pc
.
Add
(
pc
,
ethutil
.
Big1
)
pc
.
Add
(
pc
,
ethutil
.
Big1
)
...
...
ethchain/vm_test.go
View file @
7d6ba88d
...
@@ -84,27 +84,41 @@ func TestRun4(t *testing.T) {
...
@@ -84,27 +84,41 @@ func TestRun4(t *testing.T) {
asm
,
err
:=
mutan
.
Compile
(
strings
.
NewReader
(
`
asm
,
err
:=
mutan
.
Compile
(
strings
.
NewReader
(
`
int32 a = 10
int32 a = 10
int32 b = 10
int32 b = 20
if a == b {
if a > b {
int32 c = 10
int32 c = this.caller()
if c == 10 {
int32 d = 1000
int32 e = 10
}
}
exit()
`
),
false
)
script
:=
ethutil
.
Assemble
(
asm
...
)
tx
:=
NewContractCreationTx
(
ethutil
.
Big
(
"0"
),
ethutil
.
Big
(
"1000"
),
script
)
addr
:=
tx
.
Hash
()[
12
:
]
contract
:=
MakeContract
(
tx
,
state
)
state
.
UpdateContract
(
contract
)
fmt
.
Printf
(
"%x
\n
"
,
addr
)
asm
,
err
=
mutan
.
Compile
(
strings
.
NewReader
(
`
// Check if there's any cash in the initial store
if store[1000] == 0 {
store[1000] = 10^20
}
}
store[0] = 20
store[1001] = this.value() * 20
store[a] = 20
store[this.origin()] = store[this.origin()] + 1000
store[b] = this.caller()
if store[1001] > 20 {
store[1001] = 10^50
}
int8[10] ret
int8 ret = 0
int8[10] arg
int8 arg = 10
call(1234, 0, 100000000, arg, ret)
store[1002] = "a46df28529eb8aa8b8c025b0b413c5f4b688352f"
call(store[1002], 0, 100000000, arg, ret)
`
),
false
)
`
),
false
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
err
)
fmt
.
Println
(
err
)
}
}
//
asm = append(asm, "LOG")
asm
=
append
(
asm
,
"LOG"
)
fmt
.
Println
(
asm
)
fmt
.
Println
(
asm
)
callerScript
:=
ethutil
.
Assemble
(
asm
...
)
callerScript
:=
ethutil
.
Assemble
(
asm
...
)
...
@@ -112,7 +126,8 @@ func TestRun4(t *testing.T) {
...
@@ -112,7 +126,8 @@ func TestRun4(t *testing.T) {
// Contract addr as test address
// Contract addr as test address
account
:=
NewAccount
(
ContractAddr
,
big
.
NewInt
(
10000000
))
account
:=
NewAccount
(
ContractAddr
,
big
.
NewInt
(
10000000
))
callerClosure
:=
NewClosure
(
account
,
MakeContract
(
callerTx
,
state
),
state
,
big
.
NewInt
(
1000000000
),
new
(
big
.
Int
))
c
:=
MakeContract
(
callerTx
,
state
)
callerClosure
:=
NewClosure
(
account
,
c
,
c
.
script
,
state
,
big
.
NewInt
(
1000000000
),
new
(
big
.
Int
))
vm
:=
NewVm
(
state
,
RuntimeVars
{
vm
:=
NewVm
(
state
,
RuntimeVars
{
origin
:
account
.
Address
(),
origin
:
account
.
Address
(),
...
...
ethutil/parsing.go
View file @
7d6ba88d
package
ethutil
package
ethutil
import
(
import
(
_
"fmt"
"math/big"
"math/big"
"strconv"
)
)
// Op codes
// Op codes
...
@@ -52,6 +52,9 @@ var OpCodes = map[string]byte{
...
@@ -52,6 +52,9 @@ var OpCodes = map[string]byte{
// 0x50 range - 'storage' and execution
// 0x50 range - 'storage' and execution
"PUSH"
:
0x50
,
"PUSH"
:
0x50
,
"PUSH20"
:
0x80
,
"POP"
:
0x51
,
"POP"
:
0x51
,
"DUP"
:
0x52
,
"DUP"
:
0x52
,
"SWAP"
:
0x53
,
"SWAP"
:
0x53
,
...
@@ -98,11 +101,16 @@ func CompileInstr(s interface{}) ([]byte, error) {
...
@@ -98,11 +101,16 @@ func CompileInstr(s interface{}) ([]byte, error) {
// Assume regular bytes during compilation
// Assume regular bytes during compilation
if
!
success
{
if
!
success
{
num
.
SetBytes
([]
byte
(
str
))
num
.
SetBytes
([]
byte
(
str
))
}
else
{
// tmp fix for 32 bytes
n
:=
BigToBytes
(
num
,
256
)
return
n
,
nil
}
}
return
num
.
Bytes
(),
nil
return
num
.
Bytes
(),
nil
case
int
:
case
int
:
return
big
.
NewInt
(
int64
(
s
.
(
int
)))
.
Bytes
(),
nil
num
:=
BigToBytes
(
big
.
NewInt
(
int64
(
s
.
(
int
))),
256
)
return
num
,
nil
case
[]
byte
:
case
[]
byte
:
return
BigD
(
s
.
([]
byte
))
.
Bytes
(),
nil
return
BigD
(
s
.
([]
byte
))
.
Bytes
(),
nil
}
}
...
@@ -110,34 +118,16 @@ func CompileInstr(s interface{}) ([]byte, error) {
...
@@ -110,34 +118,16 @@ func CompileInstr(s interface{}) ([]byte, error) {
return
nil
,
nil
return
nil
,
nil
}
}
func
Instr
(
instr
string
)
(
int
,
[]
string
,
error
)
{
base
:=
new
(
big
.
Int
)
base
.
SetString
(
instr
,
0
)
args
:=
make
([]
string
,
7
)
for
i
:=
0
;
i
<
7
;
i
++
{
// int(int(val) / int(math.Pow(256,float64(i)))) % 256
exp
:=
BigPow
(
256
,
i
)
num
:=
new
(
big
.
Int
)
num
.
Div
(
base
,
exp
)
args
[
i
]
=
num
.
Mod
(
num
,
big
.
NewInt
(
256
))
.
String
()
}
op
,
_
:=
strconv
.
Atoi
(
args
[
0
])
return
op
,
args
[
1
:
7
],
nil
}
// Script compilation functions
// Script compilation functions
// Compiles strings to machine code
// Compiles strings to machine code
func
Assemble
(
instructions
...
interface
{})
(
script
[]
string
)
{
func
Assemble
(
instructions
...
interface
{})
(
script
[]
byte
)
{
script
=
make
([]
string
,
len
(
instructions
))
//
script = make([]string, len(instructions))
for
i
,
val
:=
range
instructions
{
for
_
,
val
:=
range
instructions
{
instr
,
_
:=
CompileInstr
(
val
)
instr
,
_
:=
CompileInstr
(
val
)
script
[
i
]
=
string
(
instr
)
//script[i] = string(instr)
script
=
append
(
script
,
instr
...
)
}
}
return
return
...
...
ethutil/rlp.go
View file @
7d6ba88d
...
@@ -186,7 +186,12 @@ func Encode(object interface{}) []byte {
...
@@ -186,7 +186,12 @@ func Encode(object interface{}) []byte {
case
byte
:
case
byte
:
buff
.
Write
(
Encode
(
big
.
NewInt
(
int64
(
t
))))
buff
.
Write
(
Encode
(
big
.
NewInt
(
int64
(
t
))))
case
*
big
.
Int
:
case
*
big
.
Int
:
// Not sure how this is possible while we check for
if
t
==
nil
{
buff
.
WriteByte
(
0xc0
)
}
else
{
buff
.
Write
(
Encode
(
t
.
Bytes
()))
buff
.
Write
(
Encode
(
t
.
Bytes
()))
}
case
[]
byte
:
case
[]
byte
:
if
len
(
t
)
==
1
&&
t
[
0
]
<=
0x7f
{
if
len
(
t
)
==
1
&&
t
[
0
]
<=
0x7f
{
buff
.
Write
(
t
)
buff
.
Write
(
t
)
...
...
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