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
377c9951
Commit
377c9951
authored
Feb 24, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Separated the VM from the block manager and added states
parent
3a45cdea
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
599 additions
and
0 deletions
+599
-0
state.go
ethchain/state.go
+56
-0
vm.go
ethchain/vm.go
+437
-0
vm_test.go
ethchain/vm_test.go
+106
-0
No files found.
ethchain/state.go
0 → 100644
View file @
377c9951
package
ethchain
import
(
"github.com/ethereum/eth-go/ethutil"
"math/big"
)
type
State
struct
{
trie
*
ethutil
.
Trie
}
func
NewState
(
trie
*
ethutil
.
Trie
)
*
State
{
return
&
State
{
trie
:
trie
}
}
func
(
s
*
State
)
GetContract
(
addr
[]
byte
)
*
Contract
{
data
:=
s
.
trie
.
Get
(
string
(
addr
))
if
data
==
""
{
return
nil
}
contract
:=
&
Contract
{}
contract
.
RlpDecode
([]
byte
(
data
))
return
contract
}
func
(
s
*
State
)
UpdateContract
(
addr
[]
byte
,
contract
*
Contract
)
{
s
.
trie
.
Update
(
string
(
addr
),
string
(
contract
.
RlpEncode
()))
}
func
Compile
(
code
[]
string
)
(
script
[]
string
)
{
script
=
make
([]
string
,
len
(
code
))
for
i
,
val
:=
range
code
{
instr
,
_
:=
ethutil
.
CompileInstr
(
val
)
script
[
i
]
=
string
(
instr
)
}
return
}
func
(
s
*
State
)
GetAccount
(
addr
[]
byte
)
(
account
*
Address
)
{
data
:=
s
.
trie
.
Get
(
string
(
addr
))
if
data
==
""
{
account
=
NewAddress
(
big
.
NewInt
(
0
))
}
else
{
account
=
NewAddressFromData
([]
byte
(
data
))
}
return
}
func
(
s
*
State
)
UpdateAccount
(
addr
[]
byte
,
account
*
Address
)
{
s
.
trie
.
Update
(
string
(
addr
),
string
(
account
.
RlpEncode
()))
}
ethchain/vm.go
0 → 100644
View file @
377c9951
package
ethchain
import
(
"bytes"
"fmt"
"github.com/ethereum/eth-go/ethutil"
"github.com/obscuren/secp256k1-go"
"log"
"math"
"math/big"
)
type
Vm
struct
{
txPool
*
TxPool
// Stack for processing contracts
stack
*
Stack
// non-persistent key/value memory storage
mem
map
[
string
]
*
big
.
Int
vars
RuntimeVars
}
type
RuntimeVars
struct
{
address
[]
byte
blockNumber
uint64
sender
[]
byte
prevHash
[]
byte
coinbase
[]
byte
time
int64
diff
*
big
.
Int
txValue
*
big
.
Int
txData
[]
string
}
func
(
vm
*
Vm
)
Process
(
contract
*
Contract
,
state
*
State
,
vars
RuntimeVars
)
{
vm
.
mem
=
make
(
map
[
string
]
*
big
.
Int
)
vm
.
stack
=
NewStack
()
addr
:=
vars
.
address
// tx.Hash()[12:]
// Instruction pointer
pc
:=
0
if
contract
==
nil
{
fmt
.
Println
(
"Contract not found"
)
return
}
Pow256
:=
ethutil
.
BigPow
(
2
,
256
)
if
ethutil
.
Config
.
Debug
{
fmt
.
Printf
(
"# op
\n
"
)
}
stepcount
:=
0
totalFee
:=
new
(
big
.
Int
)
out
:
for
{
stepcount
++
// The base big int for all calculations. Use this for any results.
base
:=
new
(
big
.
Int
)
val
:=
contract
.
GetMem
(
pc
)
//fmt.Printf("%x = %d, %v %x\n", r, len(r), v, nb)
op
:=
OpCode
(
val
.
Uint
())
var
fee
*
big
.
Int
=
new
(
big
.
Int
)
var
fee2
*
big
.
Int
=
new
(
big
.
Int
)
if
stepcount
>
16
{
fee
.
Add
(
fee
,
StepFee
)
}
// Calculate the fees
switch
op
{
case
oSSTORE
:
y
,
x
:=
vm
.
stack
.
Peekn
()
val
:=
contract
.
Addr
(
ethutil
.
BigToBytes
(
x
,
256
))
if
val
.
IsEmpty
()
&&
len
(
y
.
Bytes
())
>
0
{
fee2
.
Add
(
DataFee
,
StoreFee
)
}
else
{
fee2
.
Sub
(
DataFee
,
StoreFee
)
}
case
oSLOAD
:
fee
.
Add
(
fee
,
StoreFee
)
case
oEXTRO
,
oBALANCE
:
fee
.
Add
(
fee
,
ExtroFee
)
case
oSHA256
,
oRIPEMD160
,
oECMUL
,
oECADD
,
oECSIGN
,
oECRECOVER
,
oECVALID
:
fee
.
Add
(
fee
,
CryptoFee
)
case
oMKTX
:
fee
.
Add
(
fee
,
ContractFee
)
}
tf
:=
new
(
big
.
Int
)
.
Add
(
fee
,
fee2
)
if
contract
.
Amount
.
Cmp
(
tf
)
<
0
{
fmt
.
Println
(
"Contract fee"
,
ContractFee
)
fmt
.
Println
(
"Insufficient fees to continue running the contract"
,
tf
,
contract
.
Amount
)
break
}
// Add the fee to the total fee. It's subtracted when we're done looping
totalFee
.
Add
(
totalFee
,
tf
)
if
ethutil
.
Config
.
Debug
{
fmt
.
Printf
(
"%-3d %-4s"
,
pc
,
op
.
String
())
}
switch
op
{
case
oSTOP
:
fmt
.
Println
(
""
)
break
out
case
oADD
:
x
,
y
:=
vm
.
stack
.
Popn
()
// (x + y) % 2 ** 256
base
.
Add
(
x
,
y
)
base
.
Mod
(
base
,
Pow256
)
// Pop result back on the stack
vm
.
stack
.
Push
(
base
)
case
oSUB
:
x
,
y
:=
vm
.
stack
.
Popn
()
// (x - y) % 2 ** 256
base
.
Sub
(
x
,
y
)
base
.
Mod
(
base
,
Pow256
)
// Pop result back on the stack
vm
.
stack
.
Push
(
base
)
case
oMUL
:
x
,
y
:=
vm
.
stack
.
Popn
()
// (x * y) % 2 ** 256
base
.
Mul
(
x
,
y
)
base
.
Mod
(
base
,
Pow256
)
// Pop result back on the stack
vm
.
stack
.
Push
(
base
)
case
oDIV
:
x
,
y
:=
vm
.
stack
.
Popn
()
// floor(x / y)
base
.
Div
(
x
,
y
)
// Pop result back on the stack
vm
.
stack
.
Push
(
base
)
case
oSDIV
:
x
,
y
:=
vm
.
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
vm
.
stack
.
Push
(
z
)
case
oMOD
:
x
,
y
:=
vm
.
stack
.
Popn
()
base
.
Mod
(
x
,
y
)
vm
.
stack
.
Push
(
base
)
case
oSMOD
:
x
,
y
:=
vm
.
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
vm
.
stack
.
Push
(
z
)
case
oEXP
:
x
,
y
:=
vm
.
stack
.
Popn
()
base
.
Exp
(
x
,
y
,
Pow256
)
vm
.
stack
.
Push
(
base
)
case
oNEG
:
base
.
Sub
(
Pow256
,
vm
.
stack
.
Pop
())
vm
.
stack
.
Push
(
base
)
case
oLT
:
x
,
y
:=
vm
.
stack
.
Popn
()
// x < y
if
x
.
Cmp
(
y
)
<
0
{
vm
.
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
vm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oLE
:
x
,
y
:=
vm
.
stack
.
Popn
()
// x <= y
if
x
.
Cmp
(
y
)
<
1
{
vm
.
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
vm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oGT
:
x
,
y
:=
vm
.
stack
.
Popn
()
// x > y
if
x
.
Cmp
(
y
)
>
0
{
vm
.
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
vm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oGE
:
x
,
y
:=
vm
.
stack
.
Popn
()
// x >= y
if
x
.
Cmp
(
y
)
>
-
1
{
vm
.
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
vm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oNOT
:
x
,
y
:=
vm
.
stack
.
Popn
()
// x != y
if
x
.
Cmp
(
y
)
!=
0
{
vm
.
stack
.
Push
(
ethutil
.
BigTrue
)
}
else
{
vm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oMYADDRESS
:
vm
.
stack
.
Push
(
ethutil
.
BigD
(
addr
))
case
oTXSENDER
:
vm
.
stack
.
Push
(
ethutil
.
BigD
(
vars
.
sender
))
case
oTXVALUE
:
vm
.
stack
.
Push
(
vars
.
txValue
)
case
oTXDATAN
:
vm
.
stack
.
Push
(
big
.
NewInt
(
int64
(
len
(
vars
.
txData
))))
case
oTXDATA
:
v
:=
vm
.
stack
.
Pop
()
// v >= len(data)
if
v
.
Cmp
(
big
.
NewInt
(
int64
(
len
(
vars
.
txData
))))
>=
0
{
vm
.
stack
.
Push
(
ethutil
.
Big
(
"0"
))
}
else
{
vm
.
stack
.
Push
(
ethutil
.
Big
(
vars
.
txData
[
v
.
Uint64
()]))
}
case
oBLK_PREVHASH
:
vm
.
stack
.
Push
(
ethutil
.
BigD
(
vars
.
prevHash
))
case
oBLK_COINBASE
:
vm
.
stack
.
Push
(
ethutil
.
BigD
(
vars
.
coinbase
))
case
oBLK_TIMESTAMP
:
vm
.
stack
.
Push
(
big
.
NewInt
(
vars
.
time
))
case
oBLK_NUMBER
:
vm
.
stack
.
Push
(
big
.
NewInt
(
int64
(
vars
.
blockNumber
)))
case
oBLK_DIFFICULTY
:
vm
.
stack
.
Push
(
vars
.
diff
)
case
oBASEFEE
:
// e = 10^21
e
:=
big
.
NewInt
(
0
)
.
Exp
(
big
.
NewInt
(
10
),
big
.
NewInt
(
21
),
big
.
NewInt
(
0
))
d
:=
new
(
big
.
Rat
)
d
.
SetInt
(
vars
.
diff
)
c
:=
new
(
big
.
Rat
)
c
.
SetFloat64
(
0.5
)
// d = diff / 0.5
d
.
Quo
(
d
,
c
)
// base = floor(d)
base
.
Div
(
d
.
Num
(),
d
.
Denom
())
x
:=
new
(
big
.
Int
)
x
.
Div
(
e
,
base
)
// x = floor(10^21 / floor(diff^0.5))
vm
.
stack
.
Push
(
x
)
case
oSHA256
,
oSHA3
,
oRIPEMD160
:
// This is probably save
// ceil(pop / 32)
length
:=
int
(
math
.
Ceil
(
float64
(
vm
.
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
(
vm
.
stack
.
Pop
()
.
Bytes
(),
256
)
data
.
WriteString
(
string
(
num
))
}
if
op
==
oSHA256
{
vm
.
stack
.
Push
(
base
.
SetBytes
(
ethutil
.
Sha256Bin
(
data
.
Bytes
())))
}
else
if
op
==
oSHA3
{
vm
.
stack
.
Push
(
base
.
SetBytes
(
ethutil
.
Sha3Bin
(
data
.
Bytes
())))
}
else
{
vm
.
stack
.
Push
(
base
.
SetBytes
(
ethutil
.
Ripemd160
(
data
.
Bytes
())))
}
case
oECMUL
:
y
:=
vm
.
stack
.
Pop
()
x
:=
vm
.
stack
.
Pop
()
//n := vm.stack.Pop()
//if ethutil.Big(x).Cmp(ethutil.Big(y)) {
data
:=
new
(
bytes
.
Buffer
)
data
.
WriteString
(
x
.
String
())
data
.
WriteString
(
y
.
String
())
if
secp256k1
.
VerifyPubkeyValidity
(
data
.
Bytes
())
==
1
{
// TODO
}
else
{
// Invalid, push infinity
vm
.
stack
.
Push
(
ethutil
.
Big
(
"0"
))
vm
.
stack
.
Push
(
ethutil
.
Big
(
"0"
))
}
//} else {
// // Invalid, push infinity
// vm.stack.Push("0")
// vm.stack.Push("0")
//}
case
oECADD
:
case
oECSIGN
:
case
oECRECOVER
:
case
oECVALID
:
case
oPUSH
:
pc
++
vm
.
stack
.
Push
(
contract
.
GetMem
(
pc
)
.
BigInt
())
case
oPOP
:
// Pop current value of the stack
vm
.
stack
.
Pop
()
case
oDUP
:
// Dup top stack
x
:=
vm
.
stack
.
Pop
()
vm
.
stack
.
Push
(
x
)
vm
.
stack
.
Push
(
x
)
case
oSWAP
:
// Swap two top most values
x
,
y
:=
vm
.
stack
.
Popn
()
vm
.
stack
.
Push
(
y
)
vm
.
stack
.
Push
(
x
)
case
oMLOAD
:
x
:=
vm
.
stack
.
Pop
()
vm
.
stack
.
Push
(
vm
.
mem
[
x
.
String
()])
case
oMSTORE
:
x
,
y
:=
vm
.
stack
.
Popn
()
vm
.
mem
[
x
.
String
()]
=
y
case
oSLOAD
:
// Load the value in storage and push it on the stack
x
:=
vm
.
stack
.
Pop
()
// decode the object as a big integer
decoder
:=
ethutil
.
NewValueFromBytes
([]
byte
(
contract
.
State
()
.
Get
(
x
.
String
())))
if
!
decoder
.
IsNil
()
{
vm
.
stack
.
Push
(
decoder
.
BigInt
())
}
else
{
vm
.
stack
.
Push
(
ethutil
.
BigFalse
)
}
case
oSSTORE
:
// Store Y at index X
y
,
x
:=
vm
.
stack
.
Popn
()
addr
:=
ethutil
.
BigToBytes
(
x
,
256
)
fmt
.
Printf
(
" => %x (%v) @ %v"
,
y
.
Bytes
(),
y
,
ethutil
.
BigD
(
addr
))
contract
.
SetAddr
(
addr
,
y
)
//contract.State().Update(string(idx), string(y))
case
oJMP
:
x
:=
int
(
vm
.
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
:=
vm
.
stack
.
Pop
()
// Set pc to x if it's non zero
if
x
.
Cmp
(
ethutil
.
BigFalse
)
!=
0
{
pc
=
int
(
x
.
Uint64
())
pc
--
}
case
oIND
:
vm
.
stack
.
Push
(
big
.
NewInt
(
int64
(
pc
)))
case
oEXTRO
:
memAddr
:=
vm
.
stack
.
Pop
()
contractAddr
:=
vm
.
stack
.
Pop
()
.
Bytes
()
// Push the contract's memory on to the stack
vm
.
stack
.
Push
(
contractMemory
(
state
,
contractAddr
,
memAddr
))
case
oBALANCE
:
// Pushes the balance of the popped value on to the stack
account
:=
state
.
GetAccount
(
vm
.
stack
.
Pop
()
.
Bytes
())
vm
.
stack
.
Push
(
account
.
Amount
)
case
oMKTX
:
addr
,
value
:=
vm
.
stack
.
Popn
()
from
,
length
:=
vm
.
stack
.
Popn
()
makeInlineTx
(
addr
.
Bytes
(),
value
,
from
,
length
,
contract
,
state
)
case
oSUICIDE
:
recAddr
:=
vm
.
stack
.
Pop
()
.
Bytes
()
// Purge all memory
deletedMemory
:=
contract
.
state
.
NewIterator
()
.
Purge
()
// Add refunds to the pop'ed address
refund
:=
new
(
big
.
Int
)
.
Mul
(
StoreFee
,
big
.
NewInt
(
int64
(
deletedMemory
)))
account
:=
state
.
GetAccount
(
recAddr
)
account
.
Amount
.
Add
(
account
.
Amount
,
refund
)
// Update the refunding address
state
.
UpdateAccount
(
recAddr
,
account
)
// Delete the contract
state
.
trie
.
Update
(
string
(
addr
),
""
)
fmt
.
Printf
(
"(%d) => %x
\n
"
,
deletedMemory
,
recAddr
)
break
out
default
:
fmt
.
Printf
(
"Invalid OPCODE: %x
\n
"
,
op
)
}
fmt
.
Println
(
""
)
vm
.
stack
.
Print
()
pc
++
}
state
.
UpdateContract
(
addr
,
contract
)
}
func
makeInlineTx
(
addr
[]
byte
,
value
,
from
,
length
*
big
.
Int
,
contract
*
Contract
,
state
*
State
)
{
fmt
.
Printf
(
" => creating inline tx %x %v %v %v"
,
addr
,
value
,
from
,
length
)
j
:=
0
dataItems
:=
make
([]
string
,
int
(
length
.
Uint64
()))
for
i
:=
from
.
Uint64
();
i
<
length
.
Uint64
();
i
++
{
dataItems
[
j
]
=
contract
.
GetMem
(
j
)
.
Str
()
j
++
}
tx
:=
NewTransaction
(
addr
,
value
,
dataItems
)
if
tx
.
IsContract
()
{
contract
:=
MakeContract
(
tx
,
state
)
state
.
UpdateContract
(
tx
.
Hash
()[
12
:
],
contract
)
}
else
{
account
:=
state
.
GetAccount
(
tx
.
Recipient
)
account
.
Amount
.
Add
(
account
.
Amount
,
tx
.
Value
)
state
.
UpdateAccount
(
tx
.
Recipient
,
account
)
}
}
// Returns an address from the specified contract's address
func
contractMemory
(
state
*
State
,
contractAddr
[]
byte
,
memAddr
*
big
.
Int
)
*
big
.
Int
{
contract
:=
state
.
GetContract
(
contractAddr
)
if
contract
==
nil
{
log
.
Panicf
(
"invalid contract addr %x"
,
contractAddr
)
}
val
:=
state
.
trie
.
Get
(
memAddr
.
String
())
// decode the object as a big integer
decoder
:=
ethutil
.
NewValueFromBytes
([]
byte
(
val
))
if
decoder
.
IsNil
()
{
return
ethutil
.
BigFalse
}
return
decoder
.
BigInt
()
}
ethchain/vm_test.go
0 → 100644
View file @
377c9951
package
ethchain
import
(
"fmt"
"github.com/ethereum/eth-go/ethdb"
"github.com/ethereum/eth-go/ethutil"
"math/big"
"testing"
)
func
TestRun
(
t
*
testing
.
T
)
{
InitFees
()
ethutil
.
ReadConfig
(
""
)
db
,
_
:=
ethdb
.
NewMemDatabase
()
state
:=
NewState
(
ethutil
.
NewTrie
(
db
,
""
))
script
:=
Compile
([]
string
{
"TXSENDER"
,
"SUICIDE"
,
})
tx
:=
NewTransaction
(
ContractAddr
,
big
.
NewInt
(
1e17
),
script
)
fmt
.
Printf
(
"contract addr %x
\n
"
,
tx
.
Hash
()[
12
:
])
contract
:=
MakeContract
(
tx
,
state
)
vm
:=
&
Vm
{}
vm
.
Process
(
contract
,
state
,
RuntimeVars
{
address
:
tx
.
Hash
()[
12
:
],
blockNumber
:
1
,
sender
:
ethutil
.
FromHex
(
"cd1722f3947def4cf144679da39c4c32bdc35681"
),
prevHash
:
ethutil
.
FromHex
(
"5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
),
coinbase
:
ethutil
.
FromHex
(
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
),
time
:
1
,
diff
:
big
.
NewInt
(
256
),
txValue
:
tx
.
Value
,
txData
:
tx
.
Data
,
})
}
func
TestRun1
(
t
*
testing
.
T
)
{
ethutil
.
ReadConfig
(
""
)
db
,
_
:=
ethdb
.
NewMemDatabase
()
state
:=
NewState
(
ethutil
.
NewTrie
(
db
,
""
))
script
:=
Compile
([]
string
{
"PUSH"
,
"0"
,
"PUSH"
,
"0"
,
"TXSENDER"
,
"PUSH"
,
"10000000"
,
"MKTX"
,
})
fmt
.
Println
(
ethutil
.
NewValue
(
script
))
tx
:=
NewTransaction
(
ContractAddr
,
ethutil
.
Big
(
"100000000000000000000000000000000000000000000000000"
),
script
)
fmt
.
Printf
(
"contract addr %x
\n
"
,
tx
.
Hash
()[
12
:
])
contract
:=
MakeContract
(
tx
,
state
)
vm
:=
&
Vm
{}
vm
.
Process
(
contract
,
state
,
RuntimeVars
{
address
:
tx
.
Hash
()[
12
:
],
blockNumber
:
1
,
sender
:
ethutil
.
FromHex
(
"cd1722f3947def4cf144679da39c4c32bdc35681"
),
prevHash
:
ethutil
.
FromHex
(
"5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
),
coinbase
:
ethutil
.
FromHex
(
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
),
time
:
1
,
diff
:
big
.
NewInt
(
256
),
txValue
:
tx
.
Value
,
txData
:
tx
.
Data
,
})
}
func
TestRun2
(
t
*
testing
.
T
)
{
ethutil
.
ReadConfig
(
""
)
db
,
_
:=
ethdb
.
NewMemDatabase
()
state
:=
NewState
(
ethutil
.
NewTrie
(
db
,
""
))
script
:=
Compile
([]
string
{
"PUSH"
,
"0"
,
"PUSH"
,
"0"
,
"TXSENDER"
,
"PUSH"
,
"10000000"
,
"MKTX"
,
})
fmt
.
Println
(
ethutil
.
NewValue
(
script
))
tx
:=
NewTransaction
(
ContractAddr
,
ethutil
.
Big
(
"100000000000000000000000000000000000000000000000000"
),
script
)
fmt
.
Printf
(
"contract addr %x
\n
"
,
tx
.
Hash
()[
12
:
])
contract
:=
MakeContract
(
tx
,
state
)
vm
:=
&
Vm
{}
vm
.
Process
(
contract
,
state
,
RuntimeVars
{
address
:
tx
.
Hash
()[
12
:
],
blockNumber
:
1
,
sender
:
ethutil
.
FromHex
(
"cd1722f3947def4cf144679da39c4c32bdc35681"
),
prevHash
:
ethutil
.
FromHex
(
"5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
),
coinbase
:
ethutil
.
FromHex
(
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
),
time
:
1
,
diff
:
big
.
NewInt
(
256
),
txValue
:
tx
.
Value
,
txData
:
tx
.
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