Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
3a9a252f
G
go-ethereum
项目概览
whqwjb
/
go-ethereum
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
go-ethereum
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
3a9a252f
编写于
4月 23, 2014
作者:
O
obscuren
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fixed minor issue with gas and added state object init
上级
61cd1594
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
135 addition
and
56 deletion
+135
-56
ethchain/state_manager.go
ethchain/state_manager.go
+46
-7
ethchain/transaction.go
ethchain/transaction.go
+7
-7
ethchain/transaction_pool.go
ethchain/transaction_pool.go
+1
-3
ethchain/types.go
ethchain/types.go
+3
-3
ethchain/vm.go
ethchain/vm.go
+11
-13
ethutil/parsing.go
ethutil/parsing.go
+47
-2
ethutil/parsing_test.go
ethutil/parsing_test.go
+20
-21
未找到文件。
ethchain/state_manager.go
浏览文件 @
3a9a252f
...
...
@@ -91,23 +91,60 @@ func (sm *StateManager) BlockChain() *BlockChain {
return
sm
.
bc
}
func
(
sm
*
StateManager
)
MakeContract
(
tx
*
Transaction
)
{
func
(
sm
*
StateManager
)
MakeContract
(
tx
*
Transaction
)
*
StateObject
{
contract
:=
MakeContract
(
tx
,
sm
.
procState
)
if
contract
!=
nil
{
sm
.
procState
.
states
[
string
(
tx
.
Hash
()[
12
:
])]
=
contract
.
state
return
contract
}
return
nil
}
// Apply transactions uses the transaction passed to it and applies them onto
// the current processing state.
func
(
sm
*
StateManager
)
ApplyTransactions
(
block
*
Block
,
txs
[]
*
Transaction
)
{
// Process each transaction/contract
for
_
,
tx
:=
range
txs
{
fmt
.
Printf
(
"Processing Tx: %x
\n
"
,
tx
.
Hash
())
// If there's no recipient, it's a contract
// Check if this is a contract creation traction and if so
// create a contract of this tx.
if
tx
.
IsContract
()
{
err
:=
sm
.
Ethereum
.
TxPool
()
.
ProcessTransaction
(
tx
,
block
,
false
)
if
err
==
nil
{
contract
:=
sm
.
MakeContract
(
tx
)
if
contract
!=
nil
{
sm
.
EvalScript
(
contract
.
Init
(),
contract
,
tx
,
block
)
}
else
{
ethutil
.
Config
.
Log
.
Infoln
(
"[STATE] Unable to create contract"
)
}
}
else
{
ethutil
.
Config
.
Log
.
Infoln
(
"[STATE] contract create:"
,
err
)
}
}
else
{
err
:=
sm
.
Ethereum
.
TxPool
()
.
ProcessTransaction
(
tx
,
block
,
false
)
contract
:=
sm
.
procState
.
GetContract
(
tx
.
Recipient
)
if
err
==
nil
&&
len
(
contract
.
Script
())
>
0
{
sm
.
EvalScript
(
contract
.
Script
(),
contract
,
tx
,
block
)
}
else
if
err
!=
nil
{
ethutil
.
Config
.
Log
.
Infoln
(
"[STATE] process:"
,
err
)
}
}
}
// Process each transaction/contract
for
_
,
tx
:=
range
txs
{
// If there's no recipient, it's a contract
// Check if this is a contract creation traction and if so
// create a contract of this tx.
if
tx
.
IsContract
()
{
sm
.
MakeContract
(
tx
)
contract
:=
sm
.
MakeContract
(
tx
)
if
contract
!=
nil
{
sm
.
EvalScript
(
contract
.
Init
(),
contract
,
tx
,
block
)
}
else
{
ethutil
.
Config
.
Log
.
Infoln
(
"[STATE] Unable to create contract"
)
}
}
else
{
// Figure out if the address this transaction was sent to is a
// contract or an actual account. In case of a contract, we process that
...
...
@@ -303,11 +340,13 @@ func (sm *StateManager) Stop() {
func
(
sm
*
StateManager
)
EvalScript
(
script
[]
byte
,
object
*
StateObject
,
tx
*
Transaction
,
block
*
Block
)
{
// Recovering function in case the VM had any errors
defer
func
()
{
if
r
:=
recover
();
r
!=
nil
{
fmt
.
Println
(
"Recovered from VM execution with err ="
,
r
)
}
}()
/*
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from VM execution with err =", r)
}
}()
*/
caller
:=
sm
.
procState
.
GetAccount
(
tx
.
Sender
())
closure
:=
NewClosure
(
caller
,
object
,
script
,
sm
.
procState
,
tx
.
Gas
,
tx
.
GasPrice
,
tx
.
Value
)
...
...
ethchain/transaction.go
浏览文件 @
3a9a252f
...
...
@@ -23,12 +23,12 @@ type Transaction struct {
contractCreation
bool
}
func
NewContractCreationTx
(
value
,
gas
p
rice
*
big
.
Int
,
script
[]
byte
,
init
[]
byte
)
*
Transaction
{
return
&
Transaction
{
Value
:
value
,
Gas
Price
:
gasp
rice
,
Data
:
script
,
Init
:
init
,
contractCreation
:
true
}
func
NewContractCreationTx
(
value
,
gas
,
gasP
rice
*
big
.
Int
,
script
[]
byte
,
init
[]
byte
)
*
Transaction
{
return
&
Transaction
{
Value
:
value
,
Gas
:
gas
,
GasPrice
:
gasP
rice
,
Data
:
script
,
Init
:
init
,
contractCreation
:
true
}
}
func
NewTransactionMessage
(
to
[]
byte
,
value
,
gas
price
,
gas
*
big
.
Int
,
data
[]
byte
)
*
Transaction
{
return
&
Transaction
{
Recipient
:
to
,
Value
:
value
,
GasPrice
:
gas
p
rice
,
Gas
:
gas
,
Data
:
data
}
func
NewTransactionMessage
(
to
[]
byte
,
value
,
gas
,
gasPrice
*
big
.
Int
,
data
[]
byte
)
*
Transaction
{
return
&
Transaction
{
Recipient
:
to
,
Value
:
value
,
GasPrice
:
gas
P
rice
,
Gas
:
gas
,
Data
:
data
}
}
func
NewTransactionFromBytes
(
data
[]
byte
)
*
Transaction
{
...
...
@@ -46,9 +46,10 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
}
func
(
tx
*
Transaction
)
Hash
()
[]
byte
{
data
:=
[]
interface
{}{
tx
.
Nonce
,
tx
.
Value
,
tx
.
GasPrice
,
tx
.
Gas
,
tx
.
Recipient
,
string
(
tx
.
Data
)}
data
:=
[]
interface
{}{
tx
.
Nonce
,
tx
.
Value
,
tx
.
GasPrice
,
tx
.
Gas
,
tx
.
Recipient
,
tx
.
Data
}
if
tx
.
contractCreation
{
data
=
append
(
data
,
string
(
tx
.
Init
)
)
data
=
append
(
data
,
tx
.
Init
)
}
return
ethutil
.
Sha3Bin
(
ethutil
.
NewValue
(
data
)
.
Encode
())
...
...
@@ -112,7 +113,6 @@ func (tx *Transaction) RlpData() interface{} {
if
tx
.
contractCreation
{
data
=
append
(
data
,
tx
.
Init
)
}
//d := ethutil.NewSliceValue(tx.Data).Slice()
return
append
(
data
,
tx
.
v
,
tx
.
r
,
tx
.
s
)
}
...
...
ethchain/transaction_pool.go
浏览文件 @
3a9a252f
...
...
@@ -104,7 +104,7 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block, toContract
// funds won't invalidate this transaction but simple ignores it.
totAmount
:=
new
(
big
.
Int
)
.
Add
(
tx
.
Value
,
new
(
big
.
Int
)
.
Mul
(
TxFee
,
TxFeeRat
))
if
sender
.
Amount
.
Cmp
(
totAmount
)
<
0
{
return
errors
.
New
(
"[TXPL] Insufficient amount in sender's account"
)
return
fmt
.
Errorf
(
"[TXPL] Insufficient amount in sender's (%x) account"
,
tx
.
Sender
()
)
}
if
sender
.
Nonce
!=
tx
.
Nonce
{
...
...
@@ -119,8 +119,6 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block, toContract
if
bytes
.
Compare
(
tx
.
Recipient
,
tx
.
Sender
())
==
0
{
// Subtract the fee
sender
.
SubAmount
(
new
(
big
.
Int
)
.
Mul
(
TxFee
,
TxFeeRat
))
}
else
if
toContract
{
sender
.
SubAmount
(
new
(
big
.
Int
)
.
Mul
(
TxFee
,
TxFeeRat
))
}
else
{
// Subtract the amount from the senders account
sender
.
SubAmount
(
totAmount
)
...
...
ethchain/types.go
浏览文件 @
3a9a252f
...
...
@@ -35,7 +35,7 @@ const (
oORIGIN
=
0x32
oCALLER
=
0x33
oCALLVALUE
=
0x34
oCALLDATA
=
0x35
oCALLDATA
LOAD
=
0x35
oCALLDATASIZE
=
0x36
oGASPRICE
=
0x37
...
...
@@ -106,7 +106,7 @@ var opCodeToString = map[OpCode]string{
oORIGIN
:
"ORIGIN"
,
oCALLER
:
"CALLER"
,
oCALLVALUE
:
"CALLVALUE"
,
oCALLDATA
:
"CALLDATA
"
,
oCALLDATA
LOAD
:
"CALLDATALOAD
"
,
oCALLDATASIZE
:
"CALLDATASIZE"
,
oGASPRICE
:
"TXGASPRICE"
,
...
...
@@ -180,7 +180,7 @@ var OpCodes = map[string]byte{
"ORIGIN"
:
0x32
,
"CALLER"
:
0x33
,
"CALLVALUE"
:
0x34
,
"CALLDATA
"
:
0x35
,
"CALLDATA
LOAD"
:
0x35
,
"CALLDATASIZE"
:
0x36
,
"GASPRICE"
:
0x38
,
...
...
ethchain/vm.go
浏览文件 @
3a9a252f
...
...
@@ -84,11 +84,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
// The base for all big integer arithmetic
base
:=
new
(
big
.
Int
)
/*
if ethutil.Config.Debug {
ethutil.Config.Log.Debugf("# op\n")
}
*/
if
ethutil
.
Config
.
Debug
{
ethutil
.
Config
.
Log
.
Debugf
(
"# op
\n
"
)
}
for
{
step
++
...
...
@@ -96,11 +94,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
val
:=
closure
.
Get
(
pc
)
// Get the opcode (it must be an opcode!)
op
:=
OpCode
(
val
.
Uint
())
/*
if ethutil.Config.Debug {
ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
}
*/
if
ethutil
.
Config
.
Debug
{
ethutil
.
Config
.
Log
.
Debugf
(
"%-3d %-4s"
,
pc
,
op
.
String
())
}
gas
:=
new
(
big
.
Int
)
useGas
:=
func
(
amount
*
big
.
Int
)
{
...
...
@@ -316,10 +312,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
case
oCALLVALUE
:
// FIXME: Original value of the call, not the current value
stack
.
Push
(
closure
.
Value
)
case
oCALLDATA
:
case
oCALLDATA
LOAD
:
require
(
1
)
offset
:=
stack
.
Pop
()
mem
.
Set
(
offset
.
Int64
(),
int64
(
len
(
closure
.
Args
)),
closure
.
Args
)
offset
:=
stack
.
Pop
()
.
Int64
()
val
:=
closure
.
Args
[
offset
:
offset
+
31
]
stack
.
Push
(
ethutil
.
BigD
(
val
))
case
oCALLDATASIZE
:
stack
.
Push
(
big
.
NewInt
(
int64
(
len
(
closure
.
Args
))))
case
oGASPRICE
:
...
...
ethutil/parsing.go
浏览文件 @
3a9a252f
...
...
@@ -3,7 +3,7 @@ package ethutil
import
(
_
"fmt"
"math/big"
"regexp"
_
"regexp"
)
// Op codes
...
...
@@ -143,7 +143,6 @@ init() {
main() {
// main something
}
*/
func PreProcess(data string) (mainInput, initInput string) {
reg := "\\(\\)\\s*{([\\d\\w\\W\\n\\s]+?)}"
mainReg := regexp.MustCompile("main" + reg)
...
...
@@ -163,3 +162,49 @@ func PreProcess(data string) (mainInput, initInput string) {
return
}
*/
// Very, very dumb parser. Heed no attention :-)
func
FindFor
(
blockMatcher
,
input
string
)
string
{
curCount
:=
-
1
length
:=
len
(
blockMatcher
)
matchfst
:=
rune
(
blockMatcher
[
0
])
var
currStr
string
for
i
,
run
:=
range
input
{
// Find init
if
curCount
==
-
1
&&
run
==
matchfst
&&
input
[
i
:
i
+
length
]
==
blockMatcher
{
curCount
=
0
}
else
if
curCount
>
-
1
{
if
run
==
'{'
{
curCount
++
if
curCount
==
1
{
continue
}
}
else
if
run
==
'}'
{
curCount
--
if
curCount
==
0
{
// we are done
curCount
=
-
1
break
}
}
if
curCount
>
0
{
currStr
+=
string
(
run
)
}
}
}
return
currStr
}
func
PreProcess
(
data
string
)
(
mainInput
,
initInput
string
)
{
mainInput
=
FindFor
(
"main"
,
data
)
if
mainInput
==
""
{
mainInput
=
data
}
initInput
=
FindFor
(
"init"
,
data
)
return
}
ethutil/parsing_test.go
浏览文件 @
3a9a252f
package
ethutil
/*
import
(
"
math
"
"
fmt
"
"testing"
)
func TestCompile(t *testing.T) {
instr, err := CompileInstr("PUSH")
if err != nil {
t.Error("Failed compiling instruction")
func
TestPreProcess
(
t
*
testing
.
T
)
{
main
,
init
:=
PreProcess
(
`
init {
// init
if a > b {
if {
}
}
}
calc := (48 + 0*256 + 0*int64(math.Pow(256, 2)))
if BigD(instr).Int64() != calc {
t.Error("Expected", calc, ", got:", instr)
main {
// main
if a > b {
if c > d {
}
}
}
}
func TestValidInstr(t *testing.T) {
op, args, err := Instr("68163")
if err != nil {
t.Error("Error decoding instruction")
}
}
`
)
func TestInvalidInstr(t *testing.T) {
fmt
.
Println
(
"main"
)
fmt
.
Println
(
main
)
fmt
.
Println
(
"init"
)
fmt
.
Println
(
init
)
}
*/
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录