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
Hide 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 {
Address
()
[]
byte
}
type
ClosureBody
interface
{
type
Reference
interface
{
Callee
ethutil
.
RlpEncodable
GetMem
(
*
big
.
Int
)
*
ethutil
.
Value
...
...
@@ -22,7 +22,8 @@ type ClosureBody interface {
// Basic inline closure object which implement the 'closure' interface
type
Closure
struct
{
callee
Callee
object
ClosureBody
object
Reference
Script
[]
byte
State
*
State
Gas
*
big
.
Int
...
...
@@ -32,8 +33,8 @@ type Closure struct {
}
// 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
,
nil
}
func
NewClosure
(
callee
Callee
,
object
Reference
,
script
[]
byte
,
state
*
State
,
gas
,
val
*
big
.
Int
)
*
Closure
{
return
&
Closure
{
callee
,
object
,
s
cript
,
s
tate
,
gas
,
val
,
nil
}
}
// Retuns the x element in data slice
...
...
@@ -46,6 +47,20 @@ func (c *Closure) GetMem(x *big.Int) *ethutil.Value {
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
)
{
c
.
object
.
SetMem
(
x
,
val
)
}
...
...
@@ -81,7 +96,7 @@ func (c *Closure) ReturnGas(gas *big.Int, state *State) {
c
.
Gas
.
Add
(
c
.
Gas
,
gas
)
}
func
(
c
*
Closure
)
Object
()
ClosureBody
{
func
(
c
*
Closure
)
Object
()
Reference
{
return
c
.
object
}
...
...
ethchain/contract.go
View file @
7d6ba88d
...
...
@@ -9,8 +9,10 @@ type Contract struct {
Amount
*
big
.
Int
Nonce
uint64
//state *ethutil.Trie
state
*
State
address
[]
byte
state
*
State
address
[]
byte
script
[]
byte
initScript
[]
byte
}
func
NewContract
(
address
[]
byte
,
Amount
*
big
.
Int
,
root
[]
byte
)
*
Contract
{
...
...
@@ -45,6 +47,14 @@ func (c *Contract) GetMem(num *big.Int) *ethutil.Value {
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
)
{
addr
:=
ethutil
.
BigToBytes
(
num
,
256
)
c
.
state
.
trie
.
Update
(
string
(
addr
),
string
(
val
.
Encode
()))
...
...
@@ -60,7 +70,7 @@ func (c *Contract) Address() []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
)
{
...
...
@@ -69,6 +79,8 @@ func (c *Contract) RlpDecode(data []byte) {
c
.
Amount
=
decoder
.
Get
(
0
)
.
BigInt
()
c
.
Nonce
=
decoder
.
Get
(
1
)
.
Uint
()
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
{
...
...
@@ -79,12 +91,17 @@ func MakeContract(tx *Transaction, state *State) *Contract {
value
:=
tx
.
Value
contract
:=
NewContract
(
addr
,
value
,
[]
byte
(
""
))
state
.
trie
.
Update
(
string
(
addr
),
string
(
contract
.
RlpEncode
()))
for
i
,
val
:=
range
tx
.
Data
{
if
len
(
val
)
>
0
{
bytNum
:=
ethutil
.
BigToBytes
(
big
.
NewInt
(
int64
(
i
)),
256
)
contract
.
state
.
trie
.
Update
(
string
(
bytNum
),
string
(
ethutil
.
Encode
(
val
)))
contract
.
script
=
tx
.
Data
contract
.
initScript
=
tx
.
Init
/*
for i, val := range tx.Data {
if len(val) > 0 {
bytNum := ethutil.BigToBytes(big.NewInt(int64(i)), 256)
contract.state.trie.Update(string(bytNum), string(ethutil.Encode(val)))
}
}
}
*/
state
.
trie
.
Update
(
string
(
addr
),
string
(
contract
.
RlpEncode
()))
return
contract
...
...
ethchain/stack.go
View file @
7d6ba88d
...
...
@@ -55,6 +55,7 @@ const (
// 0x50 range - 'storage' and execution
oPUSH
=
0x50
oPUSH20
=
0x80
oPOP
=
0x51
oDUP
=
0x52
oSWAP
=
0x53
...
...
@@ -250,7 +251,7 @@ func (m *Memory) Print() {
if
len
(
m
.
store
)
>
0
{
addr
:=
0
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
++
}
}
else
{
...
...
ethchain/state_manager.go
View file @
7d6ba88d
...
...
@@ -316,7 +316,7 @@ func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, blo
}()
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
{
origin
:
caller
.
Address
(),
blockNumber
:
block
.
BlockInfo
()
.
Number
,
...
...
ethchain/transaction.go
View file @
7d6ba88d
...
...
@@ -14,7 +14,8 @@ type Transaction struct {
Value
*
big
.
Int
Gas
*
big
.
Int
Gasprice
*
big
.
Int
Data
[]
string
Data
[]
byte
Init
[]
byte
v
byte
r
,
s
[]
byte
...
...
@@ -22,11 +23,11 @@ type Transaction struct {
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
}
}
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
}
}
...
...
@@ -45,19 +46,12 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
}
func
(
tx
*
Transaction
)
Hash
()
[]
byte
{
data
:=
make
([]
interface
{},
len
(
tx
.
Data
))
for
i
,
val
:=
range
tx
.
Data
{
data
[
i
]
=
val
data
:=
[]
interface
{}{
tx
.
Nonce
,
tx
.
Value
,
tx
.
Gasprice
,
tx
.
Gas
,
tx
.
Recipient
,
string
(
tx
.
Data
)}
if
tx
.
contractCreation
{
data
=
append
(
data
,
string
(
tx
.
Init
))
}
preEnc
:=
[]
interface
{}{
tx
.
Nonce
,
tx
.
Recipient
,
tx
.
Value
,
data
,
}
return
ethutil
.
Sha3Bin
(
ethutil
.
Encode
(
preEnc
))
return
ethutil
.
Sha3Bin
(
ethutil
.
NewValue
(
data
)
.
Encode
())
}
func
(
tx
*
Transaction
)
IsContract
()
bool
{
...
...
@@ -110,15 +104,17 @@ func (tx *Transaction) Sign(privk []byte) error {
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
{}
{
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
{
data
=
append
(
data
,
tx
.
Recipient
,
tx
.
Gas
)
if
tx
.
contractCreation
{
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
{
...
...
@@ -137,31 +133,19 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
tx
.
Nonce
=
decoder
.
Get
(
0
)
.
Uint
()
tx
.
Value
=
decoder
.
Get
(
1
)
.
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
// is a contract creation tx
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
()
// If the list is of length 10 it's a contract creation tx
if
decoder
.
Len
()
==
10
{
tx
.
contractCreation
=
true
}
else
{
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
.
Init
=
decoder
.
Get
(
6
)
.
Bytes
()
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
.
r
=
decoder
.
Get
(
7
)
.
Bytes
()
tx
.
s
=
decoder
.
Get
(
8
)
.
Bytes
()
...
...
ethchain/transaction_test.go
View file @
7d6ba88d
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
import
(
_
"bytes"
"fmt"
_
"fmt"
"github.com/ethereum/eth-go/ethutil"
_
"github.com/obscuren/secp256k1-go"
_
"math"
...
...
@@ -72,7 +72,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
for
{
step
++
// Get the memory location of pc
val
:=
closure
.
Get
Mem
(
pc
)
val
:=
closure
.
Get
(
pc
)
// Get the opcode (it must be an opcode!)
op
:=
OpCode
(
val
.
Uint
())
if
ethutil
.
Config
.
Debug
{
...
...
@@ -233,13 +233,37 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
// 0x10 range
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
:
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
:
x
,
y
:=
stack
.
Popn
()
stack
.
Push
(
base
.
Xor
(
x
,
y
))
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
case
oSHA3
:
size
,
offset
:=
stack
.
Popn
()
data
:=
mem
.
Get
(
offset
.
Int64
(),
size
.
Int64
())
stack
.
Push
(
ethutil
.
BigD
(
data
))
// 0x30 range
case
oADDRESS
:
stack
.
Push
(
ethutil
.
BigD
(
closure
.
Object
()
.
Address
()))
...
...
@@ -277,9 +301,23 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
// 0x50 range
case
oPUSH
:
// Push PC+1 on to the stack
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
)
pc
.
Add
(
pc
,
big
.
NewInt
(
19
))
case
oPOP
:
stack
.
Pop
()
case
oDUP
:
...
...
@@ -319,21 +357,20 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
stack
.
Push
(
big
.
NewInt
(
int64
(
mem
.
Len
())))
// 0x60 range
case
oCALL
:
// Pop return size and offset
retSize
,
retOffset
:=
stack
.
Popn
()
// Closure addr
addr
:=
stack
.
Pop
()
// Pop gas and value of the stack.
gas
,
value
:=
stack
.
Popn
()
// Pop input size and offset
inSize
,
inOffset
:=
stack
.
Popn
()
fmt
.
Println
(
inSize
,
inOffset
)
// Pop return size and offset
retSize
,
retOffset
:=
stack
.
Popn
()
// Get the arguments from the memory
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
contract
:=
vm
.
state
.
GetContract
(
addr
.
Bytes
())
// 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)
ret
:=
closure
.
Call
(
vm
,
args
)
...
...
@@ -361,7 +398,9 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
break out
*/
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
)
...
...
ethchain/vm_test.go
View file @
7d6ba88d
...
...
@@ -84,27 +84,41 @@ func TestRun4(t *testing.T) {
asm
,
err
:=
mutan
.
Compile
(
strings
.
NewReader
(
`
int32 a = 10
int32 b = 10
if a == b {
int32 c = 10
if c == 10 {
int32 d = 1000
int32 e = 10
}
int32 b = 20
if a > b {
int32 c = this.caller()
}
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
)
store[0] = 20
store[a] = 20
store[b] = this.caller()
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[1001] = this.value() * 20
store[this.origin()] = store[this.origin()] + 1000
int8[10] ret
int8[10] arg
call(1234, 0, 100000000, arg, ret)
if store[1001] > 20 {
store[1001] = 10^50
}
int8 ret = 0
int8 arg = 10
store[1002] = "a46df28529eb8aa8b8c025b0b413c5f4b688352f"
call(store[1002], 0, 100000000, arg, ret)
`
),
false
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
}
//
asm = append(asm, "LOG")
asm
=
append
(
asm
,
"LOG"
)
fmt
.
Println
(
asm
)
callerScript
:=
ethutil
.
Assemble
(
asm
...
)
...
...
@@ -112,7 +126,8 @@ func TestRun4(t *testing.T) {
// Contract addr as test address
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
{
origin
:
account
.
Address
(),
...
...
ethutil/parsing.go
View file @
7d6ba88d
package
ethutil
import
(
_
"fmt"
"math/big"
"strconv"
)
// Op codes
...
...
@@ -51,7 +51,10 @@ var OpCodes = map[string]byte{
"GASLIMIT"
:
0x45
,
// 0x50 range - 'storage' and execution
"PUSH"
:
0x50
,
"PUSH"
:
0x50
,
"PUSH20"
:
0x80
,
"POP"
:
0x51
,
"DUP"
:
0x52
,
"SWAP"
:
0x53
,
...
...
@@ -98,11 +101,16 @@ func CompileInstr(s interface{}) ([]byte, error) {
// Assume regular bytes during compilation
if
!
success
{
num
.
SetBytes
([]
byte
(
str
))
}
else
{
// tmp fix for 32 bytes
n
:=
BigToBytes
(
num
,
256
)
return
n
,
nil
}
return
num
.
Bytes
(),
nil
case
int
:
return
big
.
NewInt
(
int64
(
s
.
(
int
)))
.
Bytes
(),
nil
num
:=
BigToBytes
(
big
.
NewInt
(
int64
(
s
.
(
int
))),
256
)
return
num
,
nil
case
[]
byte
:
return
BigD
(
s
.
([]
byte
))
.
Bytes
(),
nil
}
...
...
@@ -110,34 +118,16 @@ func CompileInstr(s interface{}) ([]byte, error) {
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
// Compiles strings to machine code
func
Assemble
(
instructions
...
interface
{})
(
script
[]
string
)
{
script
=
make
([]
string
,
len
(
instructions
))
func
Assemble
(
instructions
...
interface
{})
(
script
[]
byte
)
{
//
script = make([]string, len(instructions))
for
i
,
val
:=
range
instructions
{
for
_
,
val
:=
range
instructions
{
instr
,
_
:=
CompileInstr
(
val
)
script
[
i
]
=
string
(
instr
)
//script[i] = string(instr)
script
=
append
(
script
,
instr
...
)
}
return
...
...
ethutil/rlp.go
View file @
7d6ba88d
...
...
@@ -186,7 +186,12 @@ func Encode(object interface{}) []byte {
case
byte
:
buff
.
Write
(
Encode
(
big
.
NewInt
(
int64
(
t
))))
case
*
big
.
Int
:
buff
.
Write
(
Encode
(
t
.
Bytes
()))
// Not sure how this is possible while we check for
if
t
==
nil
{
buff
.
WriteByte
(
0xc0
)
}
else
{
buff
.
Write
(
Encode
(
t
.
Bytes
()))
}
case
[]
byte
:
if
len
(
t
)
==
1
&&
t
[
0
]
<=
0x7f
{
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