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
64a6c2c1
Commit
64a6c2c1
authored
May 12, 2016
by
Bas van Kervel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eth: add new RPC method (personal.) SignAndSendTransaction
parent
e798e4fd
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
165 additions
and
71 deletions
+165
-71
account_manager.go
accounts/account_manager.go
+14
-2
accounts_test.go
accounts/accounts_test.go
+28
-0
js.go
cmd/geth/js.go
+1
-1
api.go
eth/api.go
+113
-67
backend.go
eth/backend.go
+3
-1
web3ext.go
internal/web3ext/web3ext.go
+6
-0
No files found.
accounts/account_manager.go
View file @
64a6c2c1
...
...
@@ -147,9 +147,21 @@ func (am *Manager) Sign(addr common.Address, hash []byte) (signature []byte, err
return
crypto
.
Sign
(
hash
,
unlockedKey
.
PrivateKey
)
}
// SignWithPassphrase signs hash if the private key matching the given address can be
// decrypted with the given passphrase.
func
(
am
*
Manager
)
SignWithPassphrase
(
addr
common
.
Address
,
passphrase
string
,
hash
[]
byte
)
(
signature
[]
byte
,
err
error
)
{
_
,
key
,
err
:=
am
.
getDecryptedKey
(
Account
{
Address
:
addr
},
passphrase
)
if
err
!=
nil
{
return
nil
,
err
}
defer
zeroKey
(
key
.
PrivateKey
)
return
crypto
.
Sign
(
hash
,
key
.
PrivateKey
)
}
// Unlock unlocks the given account indefinitely.
func
(
am
*
Manager
)
Unlock
(
a
Account
,
keyAuth
string
)
error
{
return
am
.
TimedUnlock
(
a
,
keyAuth
,
0
)
func
(
am
*
Manager
)
Unlock
(
a
Account
,
passphrase
string
)
error
{
return
am
.
TimedUnlock
(
a
,
passphrase
,
0
)
}
// Lock removes the private key with the given address from memory.
...
...
accounts/accounts_test.go
View file @
64a6c2c1
...
...
@@ -81,6 +81,34 @@ func TestSign(t *testing.T) {
}
}
func
TestSignWithPassphrase
(
t
*
testing
.
T
)
{
dir
,
am
:=
tmpManager
(
t
,
true
)
defer
os
.
RemoveAll
(
dir
)
pass
:=
"passwd"
acc
,
err
:=
am
.
NewAccount
(
pass
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
_
,
unlocked
:=
am
.
unlocked
[
acc
.
Address
];
unlocked
{
t
.
Fatal
(
"expected account to be locked"
)
}
_
,
err
=
am
.
SignWithPassphrase
(
acc
.
Address
,
pass
,
testSigData
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
_
,
unlocked
:=
am
.
unlocked
[
acc
.
Address
];
unlocked
{
t
.
Fatal
(
"expected account to be locked"
)
}
if
_
,
err
=
am
.
SignWithPassphrase
(
acc
.
Address
,
"invalid passwd"
,
testSigData
);
err
==
nil
{
t
.
Fatal
(
"expected SignHash to fail with invalid password"
)
}
}
func
TestTimedUnlock
(
t
*
testing
.
T
)
{
dir
,
am
:=
tmpManager
(
t
,
true
)
defer
os
.
RemoveAll
(
dir
)
...
...
cmd/geth/js.go
View file @
64a6c2c1
...
...
@@ -41,7 +41,7 @@ import (
)
var
(
passwordRegexp
=
regexp
.
MustCompile
(
"personal.[nu]"
)
passwordRegexp
=
regexp
.
MustCompile
(
"personal.[nu
s
]"
)
onlyws
=
regexp
.
MustCompile
(
"^
\\
s*$"
)
exit
=
regexp
.
MustCompile
(
"^
\\
s*exit
\\
s*;*
\\
s*$"
)
)
...
...
eth/api.go
View file @
64a6c2c1
...
...
@@ -148,7 +148,7 @@ func (s *PublicEthereumAPI) Etherbase() (common.Address, error) {
return
s
.
e
.
Etherbase
()
}
//
see Etherbase
//
Coinbase is the address that mining rewards will be send to (alias for Etherbase)
func
(
s
*
PublicEthereumAPI
)
Coinbase
()
(
common
.
Address
,
error
)
{
return
s
.
Etherbase
()
}
...
...
@@ -217,18 +217,17 @@ func (s *PublicMinerAPI) SubmitWork(nonce rpc.HexNumber, solution, digest common
// result[0], 32 bytes hex encoded current block header pow-hash
// result[1], 32 bytes hex encoded seed hash used for DAG
// result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty
func
(
s
*
PublicMinerAPI
)
GetWork
()
(
[]
string
,
error
)
{
func
(
s
*
PublicMinerAPI
)
GetWork
()
(
work
[
3
]
string
,
err
error
)
{
if
!
s
.
e
.
IsMining
()
{
if
err
:=
s
.
e
.
StartMining
(
0
,
""
);
err
!=
nil
{
return
nil
,
err
return
work
,
err
}
}
if
work
,
err
:=
s
.
agent
.
GetWork
();
err
==
nil
{
return
work
[
:
],
nil
}
else
{
glog
.
Infof
(
"%v
\n
"
,
err
)
if
work
,
err
=
s
.
agent
.
GetWork
();
err
==
nil
{
return
}
return
nil
,
fmt
.
Errorf
(
"mining not ready"
)
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"%v"
,
err
)
return
work
,
fmt
.
Errorf
(
"mining not ready"
)
}
// SubmitHashrate can be used for remote miners to submit their hash rate. This enables the node to report the combined
...
...
@@ -423,14 +422,23 @@ func (s *PublicAccountAPI) Accounts() []accounts.Account {
}
// PrivateAccountAPI provides an API to access accounts managed by this node.
// It offers methods to create, (un)lock en list accounts.
// It offers methods to create, (un)lock en list accounts. Some methods accept
// passwords and are therefore considered private by default.
type
PrivateAccountAPI
struct
{
am
*
accounts
.
Manager
am
*
accounts
.
Manager
txPool
*
core
.
TxPool
txMu
*
sync
.
Mutex
gpo
*
GasPriceOracle
}
// NewPrivateAccountAPI create a new PrivateAccountAPI.
func
NewPrivateAccountAPI
(
am
*
accounts
.
Manager
)
*
PrivateAccountAPI
{
return
&
PrivateAccountAPI
{
am
}
func
NewPrivateAccountAPI
(
e
*
Ethereum
)
*
PrivateAccountAPI
{
return
&
PrivateAccountAPI
{
am
:
e
.
accountManager
,
txPool
:
e
.
txPool
,
txMu
:
&
e
.
txMu
,
gpo
:
e
.
gpo
,
}
}
// ListAccounts will return a list of addresses for accounts this node manages.
...
...
@@ -452,6 +460,8 @@ func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error)
return
common
.
Address
{},
err
}
// ImportRawKey stores the given hex encoded ECDSA key into the key directory,
// encrypting it with the passphrase.
func
(
s
*
PrivateAccountAPI
)
ImportRawKey
(
privkey
string
,
password
string
)
(
common
.
Address
,
error
)
{
hexkey
,
err
:=
hex
.
DecodeString
(
privkey
)
if
err
!=
nil
{
...
...
@@ -482,6 +492,34 @@ func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool {
return
s
.
am
.
Lock
(
addr
)
==
nil
}
// SignAndSendTransaction will create a transaction from the given arguments and
// tries to sign it with the key associated with args.To. If the given passwd isn't
// able to decrypt the key it fails.
func
(
s
*
PrivateAccountAPI
)
SignAndSendTransaction
(
args
SendTxArgs
,
passwd
string
)
(
common
.
Hash
,
error
)
{
args
=
prepareSendTxArgs
(
args
,
s
.
gpo
)
s
.
txMu
.
Lock
()
defer
s
.
txMu
.
Unlock
()
if
args
.
Nonce
==
nil
{
args
.
Nonce
=
rpc
.
NewHexNumber
(
s
.
txPool
.
State
()
.
GetNonce
(
args
.
From
))
}
var
tx
*
types
.
Transaction
if
args
.
To
==
nil
{
tx
=
types
.
NewContractCreation
(
args
.
Nonce
.
Uint64
(),
args
.
Value
.
BigInt
(),
args
.
Gas
.
BigInt
(),
args
.
GasPrice
.
BigInt
(),
common
.
FromHex
(
args
.
Data
))
}
else
{
tx
=
types
.
NewTransaction
(
args
.
Nonce
.
Uint64
(),
*
args
.
To
,
args
.
Value
.
BigInt
(),
args
.
Gas
.
BigInt
(),
args
.
GasPrice
.
BigInt
(),
common
.
FromHex
(
args
.
Data
))
}
signature
,
err
:=
s
.
am
.
SignWithPassphrase
(
args
.
From
,
passwd
,
tx
.
SigHash
()
.
Bytes
())
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
return
submitTransaction
(
s
.
txPool
,
tx
,
signature
)
}
// PublicBlockChainAPI provides an API to access the Ethereum blockchain.
// It offers only methods that operate on public data that is freely available to anyone.
type
PublicBlockChainAPI
struct
{
...
...
@@ -645,15 +683,14 @@ func (s *PublicBlockChainAPI) NewBlocks(ctx context.Context, args NewBlocksArgs)
// add a callback that is called on chain events which will format the block and notify the client
s
.
muNewBlockSubscriptions
.
Lock
()
s
.
newBlockSubscriptions
[
subscription
.
ID
()]
=
func
(
e
core
.
ChainEvent
)
error
{
if
notification
,
err
:=
s
.
rpcOutputBlock
(
e
.
Block
,
args
.
IncludeTransactions
,
args
.
TransactionDetails
);
err
==
nil
{
notification
,
err
:=
s
.
rpcOutputBlock
(
e
.
Block
,
args
.
IncludeTransactions
,
args
.
TransactionDetails
)
if
err
==
nil
{
return
subscription
.
Notify
(
notification
)
}
else
{
glog
.
V
(
logger
.
Warn
)
.
Info
(
"unable to format block %v
\n
"
,
err
)
}
glog
.
V
(
logger
.
Warn
)
.
Info
(
"unable to format block %v
\n
"
,
err
)
return
nil
}
s
.
muNewBlockSubscriptions
.
Unlock
()
return
subscription
,
nil
}
...
...
@@ -700,6 +737,7 @@ func (m callmsg) Gas() *big.Int { return m.gas }
func
(
m
callmsg
)
Value
()
*
big
.
Int
{
return
m
.
value
}
func
(
m
callmsg
)
Data
()
[]
byte
{
return
m
.
data
}
// CallArgs represents the arguments for a call.
type
CallArgs
struct
{
From
common
.
Address
`json:"from"`
To
*
common
.
Address
`json:"to"`
...
...
@@ -911,7 +949,7 @@ type PublicTransactionPoolAPI struct {
miner
*
miner
.
Miner
am
*
accounts
.
Manager
txPool
*
core
.
TxPool
txMu
sync
.
Mutex
txMu
*
sync
.
Mutex
muPendingTxSubs
sync
.
Mutex
pendingTxSubs
map
[
string
]
rpc
.
Subscription
}
...
...
@@ -925,6 +963,7 @@ func NewPublicTransactionPoolAPI(e *Ethereum) *PublicTransactionPoolAPI {
bc
:
e
.
blockchain
,
am
:
e
.
accountManager
,
txPool
:
e
.
txPool
,
txMu
:
&
e
.
txMu
,
miner
:
e
.
miner
,
pendingTxSubs
:
make
(
map
[
string
]
rpc
.
Subscription
),
}
...
...
@@ -1124,6 +1163,7 @@ func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transacti
return
tx
.
WithSignature
(
signature
)
}
// SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool.
type
SendTxArgs
struct
{
From
common
.
Address
`json:"from"`
To
*
common
.
Address
`json:"to"`
...
...
@@ -1134,18 +1174,47 @@ type SendTxArgs struct {
Nonce
*
rpc
.
HexNumber
`json:"nonce"`
}
// SendTransaction will create a transaction for the given transaction argument, sign it and submit it to the
// transaction pool.
func
(
s
*
PublicTransactionPoolAPI
)
SendTransaction
(
args
SendTxArgs
)
(
common
.
Hash
,
error
)
{
// prepareSendTxArgs is a helper function that fills in default values for unspecified tx fields.
func
prepareSendTxArgs
(
args
SendTxArgs
,
gpo
*
GasPriceOracle
)
SendTxArgs
{
if
args
.
Gas
==
nil
{
args
.
Gas
=
rpc
.
NewHexNumber
(
defaultGas
)
}
if
args
.
GasPrice
==
nil
{
args
.
GasPrice
=
rpc
.
NewHexNumber
(
s
.
gpo
.
SuggestPrice
())
args
.
GasPrice
=
rpc
.
NewHexNumber
(
gpo
.
SuggestPrice
())
}
if
args
.
Value
==
nil
{
args
.
Value
=
rpc
.
NewHexNumber
(
0
)
}
return
args
}
// submitTransaction is a helper function that submits tx to txPool and creates a log entry.
func
submitTransaction
(
txPool
*
core
.
TxPool
,
tx
*
types
.
Transaction
,
signature
[]
byte
)
(
common
.
Hash
,
error
)
{
signedTx
,
err
:=
tx
.
WithSignature
(
signature
)
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
txPool
.
SetLocal
(
signedTx
)
if
err
:=
txPool
.
Add
(
signedTx
);
err
!=
nil
{
return
common
.
Hash
{},
err
}
if
signedTx
.
To
()
==
nil
{
from
,
_
:=
signedTx
.
From
()
addr
:=
crypto
.
CreateAddress
(
from
,
signedTx
.
Nonce
())
glog
.
V
(
logger
.
Info
)
.
Infof
(
"Tx(%s) created: %s
\n
"
,
signedTx
.
Hash
()
.
Hex
(),
addr
.
Hex
())
}
else
{
glog
.
V
(
logger
.
Info
)
.
Infof
(
"Tx(%s) to: %s
\n
"
,
signedTx
.
Hash
()
.
Hex
(),
tx
.
To
()
.
Hex
())
}
return
signedTx
.
Hash
(),
nil
}
// SendTransaction creates a transaction for the given argument, sign it and submit it to the
// transaction pool.
func
(
s
*
PublicTransactionPoolAPI
)
SendTransaction
(
args
SendTxArgs
)
(
common
.
Hash
,
error
)
{
args
=
prepareSendTxArgs
(
args
,
s
.
gpo
)
s
.
txMu
.
Lock
()
defer
s
.
txMu
.
Unlock
()
...
...
@@ -1155,32 +1224,18 @@ func (s *PublicTransactionPoolAPI) SendTransaction(args SendTxArgs) (common.Hash
}
var
tx
*
types
.
Transaction
contractCreation
:=
(
args
.
To
==
nil
)
if
contractCreation
{
if
args
.
To
==
nil
{
tx
=
types
.
NewContractCreation
(
args
.
Nonce
.
Uint64
(),
args
.
Value
.
BigInt
(),
args
.
Gas
.
BigInt
(),
args
.
GasPrice
.
BigInt
(),
common
.
FromHex
(
args
.
Data
))
}
else
{
tx
=
types
.
NewTransaction
(
args
.
Nonce
.
Uint64
(),
*
args
.
To
,
args
.
Value
.
BigInt
(),
args
.
Gas
.
BigInt
(),
args
.
GasPrice
.
BigInt
(),
common
.
FromHex
(
args
.
Data
))
}
sign
edTx
,
err
:=
s
.
sign
(
args
.
From
,
tx
)
sign
ature
,
err
:=
s
.
am
.
Sign
(
args
.
From
,
tx
.
SigHash
()
.
Bytes
()
)
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
s
.
txPool
.
SetLocal
(
signedTx
)
if
err
:=
s
.
txPool
.
Add
(
signedTx
);
err
!=
nil
{
return
common
.
Hash
{},
err
}
if
contractCreation
{
addr
:=
crypto
.
CreateAddress
(
args
.
From
,
args
.
Nonce
.
Uint64
())
glog
.
V
(
logger
.
Info
)
.
Infof
(
"Tx(%s) created: %s
\n
"
,
signedTx
.
Hash
()
.
Hex
(),
addr
.
Hex
())
}
else
{
glog
.
V
(
logger
.
Info
)
.
Infof
(
"Tx(%s) to: %s
\n
"
,
signedTx
.
Hash
()
.
Hex
(),
tx
.
To
()
.
Hex
())
}
return
signedTx
.
Hash
(),
nil
return
submitTransaction
(
s
.
txPool
,
tx
,
signature
)
}
// SendRawTransaction will add the signed transaction to the transaction pool.
...
...
@@ -1217,6 +1272,7 @@ func (s *PublicTransactionPoolAPI) Sign(addr common.Address, hash common.Hash) (
return
common
.
ToHex
(
signature
),
error
}
// SignTransactionArgs represents the arguments to sign a transaction.
type
SignTransactionArgs
struct
{
From
common
.
Address
To
*
common
.
Address
...
...
@@ -1243,6 +1299,7 @@ type Tx struct {
Hash
common
.
Hash
`json:"hash"`
}
// UnmarshalJSON parses JSON data into tx.
func
(
tx
*
Tx
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
req
:=
struct
{
To
*
common
.
Address
`json:"to"`
...
...
@@ -1283,8 +1340,7 @@ func (tx *Tx) UnmarshalJSON(b []byte) (err error) {
tx
.
GasPrice
=
rpc
.
NewHexNumber
(
int64
(
50000000000
))
}
contractCreation
:=
(
req
.
To
==
nil
)
if
contractCreation
{
if
req
.
To
==
nil
{
tx
.
tx
=
types
.
NewContractCreation
(
tx
.
Nonce
.
Uint64
(),
tx
.
Value
.
BigInt
(),
tx
.
GasLimit
.
BigInt
(),
tx
.
GasPrice
.
BigInt
(),
data
)
}
else
{
tx
.
tx
=
types
.
NewTransaction
(
tx
.
Nonce
.
Uint64
(),
*
tx
.
To
,
tx
.
Value
.
BigInt
(),
tx
.
GasLimit
.
BigInt
(),
tx
.
GasPrice
.
BigInt
(),
data
)
...
...
@@ -1293,6 +1349,7 @@ func (tx *Tx) UnmarshalJSON(b []byte) (err error) {
return
nil
}
// SignTransactionResult represents a RLP encoded signed transaction.
type
SignTransactionResult
struct
{
Raw
string
`json:"raw"`
Tx
*
Tx
`json:"tx"`
...
...
@@ -1335,9 +1392,7 @@ func (s *PublicTransactionPoolAPI) SignTransaction(args SignTransactionArgs) (*S
}
var
tx
*
types
.
Transaction
contractCreation
:=
(
args
.
To
==
nil
)
if
contractCreation
{
if
args
.
To
==
nil
{
tx
=
types
.
NewContractCreation
(
args
.
Nonce
.
Uint64
(),
args
.
Value
.
BigInt
(),
args
.
Gas
.
BigInt
(),
args
.
GasPrice
.
BigInt
(),
common
.
FromHex
(
args
.
Data
))
}
else
{
tx
=
types
.
NewTransaction
(
args
.
Nonce
.
Uint64
(),
*
args
.
To
,
args
.
Value
.
BigInt
(),
args
.
Gas
.
BigInt
(),
args
.
GasPrice
.
BigInt
(),
common
.
FromHex
(
args
.
Data
))
...
...
@@ -1360,7 +1415,7 @@ func (s *PublicTransactionPoolAPI) SignTransaction(args SignTransactionArgs) (*S
// the accounts this node manages.
func
(
s
*
PublicTransactionPoolAPI
)
PendingTransactions
()
[]
*
RPCTransaction
{
pending
:=
s
.
txPool
.
GetTransactions
()
transactions
:=
make
([]
*
RPCTransaction
,
0
)
transactions
:=
make
([]
*
RPCTransaction
,
0
,
len
(
pending
)
)
for
_
,
tx
:=
range
pending
{
from
,
_
:=
tx
.
FromFrontier
()
if
s
.
am
.
HasAddress
(
from
)
{
...
...
@@ -1370,7 +1425,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() []*RPCTransaction {
return
transactions
}
// NewPendingTransaction creates a subscription that is triggered each time a transaction enters the transaction pool
// NewPendingTransaction
s
creates a subscription that is triggered each time a transaction enters the transaction pool
// and is send from one of the transactions this nodes manages.
func
(
s
*
PublicTransactionPoolAPI
)
NewPendingTransactions
(
ctx
context
.
Context
)
(
rpc
.
Subscription
,
error
)
{
notifier
,
supported
:=
rpc
.
NotifierFromContext
(
ctx
)
...
...
@@ -1410,8 +1465,7 @@ func (s *PublicTransactionPoolAPI) Resend(tx Tx, gasPrice, gasLimit *rpc.HexNumb
}
var
newTx
*
types
.
Transaction
contractCreation
:=
(
tx
.
tx
.
To
()
==
nil
)
if
contractCreation
{
if
tx
.
tx
.
To
()
==
nil
{
newTx
=
types
.
NewContractCreation
(
tx
.
tx
.
Nonce
(),
tx
.
tx
.
Value
(),
gasPrice
.
BigInt
(),
gasLimit
.
BigInt
(),
tx
.
tx
.
Data
())
}
else
{
newTx
=
types
.
NewTransaction
(
tx
.
tx
.
Nonce
(),
*
tx
.
tx
.
To
(),
tx
.
tx
.
Value
(),
gasPrice
.
BigInt
(),
gasLimit
.
BigInt
(),
tx
.
tx
.
Data
())
...
...
@@ -1612,7 +1666,7 @@ func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) {
return
ldb
.
LDB
()
.
GetProperty
(
property
)
}
// BlockTraceResult
s
is the returned value when replaying a block to check for
// BlockTraceResult is the returned value when replaying a block to check for
// consensus results and full VM trace logs for all included transactions.
type
BlockTraceResult
struct
{
Validated
bool
`json:"validated"`
...
...
@@ -1647,7 +1701,7 @@ func (api *PrivateDebugAPI) TraceBlockFromFile(file string, config *vm.Config) B
return
api
.
TraceBlock
(
blockRlp
,
config
)
}
// Trace
ProcessBlock
processes the block by canonical block number.
// Trace
BlockByNumber
processes the block by canonical block number.
func
(
api
*
PrivateDebugAPI
)
TraceBlockByNumber
(
number
uint64
,
config
*
vm
.
Config
)
BlockTraceResult
{
// Fetch the block that we aim to reprocess
block
:=
api
.
eth
.
BlockChain
()
.
GetBlockByNumber
(
number
)
...
...
@@ -1752,15 +1806,6 @@ type structLogRes struct {
Storage
map
[
string
]
string
`json:"storage"`
}
// VmLoggerOptions are the options used for debugging transactions and capturing
// specific data.
type
VmLoggerOptions
struct
{
DisableMemory
bool
// disable memory capture
DisableStack
bool
// disable stack capture
DisableStorage
bool
// disable storage capture
FullStorage
bool
// show full storage (slow)
}
// formatLogs formats EVM returned structured logs for json output
func
formatLogs
(
structLogs
[]
vm
.
StructLog
)
[]
structLogRes
{
formattedStructLogs
:=
make
([]
structLogRes
,
len
(
structLogs
))
...
...
@@ -1802,25 +1847,25 @@ func formatError(err error) string {
// TraceTransaction returns the structured logs created during the execution of EVM
// and returns them as a JSON object.
func
(
s
*
PrivateDebugAPI
)
TraceTransaction
(
txHash
common
.
Hash
,
logger
*
vm
.
LogConfig
)
(
*
ExecutionResult
,
error
)
{
func
(
api
*
PrivateDebugAPI
)
TraceTransaction
(
txHash
common
.
Hash
,
logger
*
vm
.
LogConfig
)
(
*
ExecutionResult
,
error
)
{
if
logger
==
nil
{
logger
=
new
(
vm
.
LogConfig
)
}
// Retrieve the tx from the chain and the containing block
tx
,
blockHash
,
_
,
txIndex
:=
core
.
GetTransaction
(
s
.
eth
.
ChainDb
(),
txHash
)
tx
,
blockHash
,
_
,
txIndex
:=
core
.
GetTransaction
(
api
.
eth
.
ChainDb
(),
txHash
)
if
tx
==
nil
{
return
nil
,
fmt
.
Errorf
(
"transaction %x not found"
,
txHash
)
}
block
:=
s
.
eth
.
BlockChain
()
.
GetBlock
(
blockHash
)
block
:=
api
.
eth
.
BlockChain
()
.
GetBlock
(
blockHash
)
if
block
==
nil
{
return
nil
,
fmt
.
Errorf
(
"block %x not found"
,
blockHash
)
}
// Create the state database to mutate and eventually trace
parent
:=
s
.
eth
.
BlockChain
()
.
GetBlock
(
block
.
ParentHash
())
parent
:=
api
.
eth
.
BlockChain
()
.
GetBlock
(
block
.
ParentHash
())
if
parent
==
nil
{
return
nil
,
fmt
.
Errorf
(
"block parent %x not found"
,
block
.
ParentHash
())
}
stateDb
,
err
:=
state
.
New
(
parent
.
Root
(),
s
.
eth
.
ChainDb
())
stateDb
,
err
:=
state
.
New
(
parent
.
Root
(),
api
.
eth
.
ChainDb
())
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -1841,7 +1886,7 @@ func (s *PrivateDebugAPI) TraceTransaction(txHash common.Hash, logger *vm.LogCon
}
// Mutate the state if we haven't reached the tracing transaction yet
if
uint64
(
idx
)
<
txIndex
{
vmenv
:=
core
.
NewEnv
(
stateDb
,
s
.
config
,
s
.
eth
.
BlockChain
(),
msg
,
block
.
Header
(),
vm
.
Config
{})
vmenv
:=
core
.
NewEnv
(
stateDb
,
api
.
config
,
api
.
eth
.
BlockChain
(),
msg
,
block
.
Header
(),
vm
.
Config
{})
_
,
_
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
new
(
core
.
GasPool
)
.
AddGas
(
tx
.
Gas
()))
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"mutation failed: %v"
,
err
)
...
...
@@ -1849,7 +1894,7 @@ func (s *PrivateDebugAPI) TraceTransaction(txHash common.Hash, logger *vm.LogCon
continue
}
// Otherwise trace the transaction and return
vmenv
:=
core
.
NewEnv
(
stateDb
,
s
.
config
,
s
.
eth
.
BlockChain
(),
msg
,
block
.
Header
(),
vm
.
Config
{
Debug
:
true
,
Logger
:
*
logger
})
vmenv
:=
core
.
NewEnv
(
stateDb
,
api
.
config
,
api
.
eth
.
BlockChain
(),
msg
,
block
.
Header
(),
vm
.
Config
{
Debug
:
true
,
Logger
:
*
logger
})
ret
,
gas
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
new
(
core
.
GasPool
)
.
AddGas
(
tx
.
Gas
()))
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"tracing failed: %v"
,
err
)
...
...
@@ -1863,6 +1908,7 @@ func (s *PrivateDebugAPI) TraceTransaction(txHash common.Hash, logger *vm.LogCon
return
nil
,
errors
.
New
(
"database inconsistency"
)
}
// TraceCall executes a call and returns the amount of gas, created logs and optionally returned values.
func
(
s
*
PublicBlockChainAPI
)
TraceCall
(
args
CallArgs
,
blockNr
rpc
.
BlockNumber
)
(
*
ExecutionResult
,
error
)
{
// Fetch the state associated with the block number
stateDb
,
block
,
err
:=
stateAndBlockByNumber
(
s
.
miner
,
s
.
bc
,
blockNr
,
s
.
chainDb
)
...
...
@@ -1931,12 +1977,12 @@ func (s *PublicNetAPI) Listening() bool {
return
true
// always listening
}
// Peer
c
ount returns the number of connected peers
// Peer
C
ount returns the number of connected peers
func
(
s
*
PublicNetAPI
)
PeerCount
()
*
rpc
.
HexNumber
{
return
rpc
.
NewHexNumber
(
s
.
net
.
PeerCount
())
}
//
Protocol
Version returns the current ethereum protocol version.
// Version returns the current ethereum protocol version.
func
(
s
*
PublicNetAPI
)
Version
()
string
{
return
fmt
.
Sprintf
(
"%d"
,
s
.
networkVersion
)
}
eth/backend.go
View file @
64a6c2c1
...
...
@@ -26,6 +26,7 @@ import (
"path/filepath"
"regexp"
"strings"
"sync"
"time"
"github.com/ethereum/ethash"
...
...
@@ -113,6 +114,7 @@ type Ethereum struct {
// Handlers
txPool
*
core
.
TxPool
txMu
sync
.
Mutex
blockchain
*
core
.
BlockChain
accountManager
*
accounts
.
Manager
pow
*
ethash
.
Ethash
...
...
@@ -293,7 +295,7 @@ func (s *Ethereum) APIs() []rpc.API {
},
{
Namespace
:
"personal"
,
Version
:
"1.0"
,
Service
:
NewPrivateAccountAPI
(
s
.
accountManager
),
Service
:
NewPrivateAccountAPI
(
s
),
Public
:
false
,
},
{
Namespace
:
"eth"
,
...
...
internal/web3ext/web3ext.go
View file @
64a6c2c1
...
...
@@ -431,6 +431,12 @@ web3._extend({
name: 'importRawKey',
call: 'personal_importRawKey',
params: 2
}),
new web3._extend.Method({
name: 'signAndSendTransaction',
call: 'personal_signAndSendTransaction',
params: 2,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter, null]
})
]
});
...
...
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