|
|
@ -3,6 +3,7 @@ package main |
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"errors" |
|
|
|
"errors" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
|
|
|
|
"strconv" |
|
|
|
"time" |
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/cmd/utils" |
|
|
|
"github.com/ethereum/go-ethereum/cmd/utils" |
|
|
@ -15,6 +16,7 @@ import ( |
|
|
|
"github.com/ethereum/go-ethereum/rpc" |
|
|
|
"github.com/ethereum/go-ethereum/rpc" |
|
|
|
"github.com/ethereum/go-ethereum/xeth" |
|
|
|
"github.com/ethereum/go-ethereum/xeth" |
|
|
|
"github.com/robertkrimen/otto" |
|
|
|
"github.com/robertkrimen/otto" |
|
|
|
|
|
|
|
"gopkg.in/fatih/set.v0" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
/* |
|
|
@ -22,6 +24,11 @@ node admin bindings |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
func (js *jsre) adminBindings() { |
|
|
|
func (js *jsre) adminBindings() { |
|
|
|
|
|
|
|
ethO, _ := js.re.Get("eth") |
|
|
|
|
|
|
|
eth := ethO.Object() |
|
|
|
|
|
|
|
eth.Set("pendingTransactions", js.pendingTransactions) |
|
|
|
|
|
|
|
eth.Set("resend", js.resend) |
|
|
|
|
|
|
|
|
|
|
|
js.re.Set("admin", struct{}{}) |
|
|
|
js.re.Set("admin", struct{}{}) |
|
|
|
t, _ := js.re.Get("admin") |
|
|
|
t, _ := js.re.Get("admin") |
|
|
|
admin := t.Object() |
|
|
|
admin := t.Object() |
|
|
@ -74,6 +81,70 @@ func (js *jsre) getBlock(call otto.FunctionCall) (*types.Block, error) { |
|
|
|
return nil, errors.New("requires block number or block hash as argument") |
|
|
|
return nil, errors.New("requires block number or block hash as argument") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (js *jsre) pendingTransactions(call otto.FunctionCall) otto.Value { |
|
|
|
|
|
|
|
txs := js.ethereum.TxPool().GetTransactions() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// grab the accounts from the account manager. This will help with determening which
|
|
|
|
|
|
|
|
// transactions should be returned.
|
|
|
|
|
|
|
|
accounts, err := js.ethereum.AccountManager().Accounts() |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
fmt.Println(err) |
|
|
|
|
|
|
|
return otto.UndefinedValue() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add the accouns to a new set
|
|
|
|
|
|
|
|
accountSet := set.New() |
|
|
|
|
|
|
|
for _, account := range accounts { |
|
|
|
|
|
|
|
accountSet.Add(common.BytesToAddress(account.Address)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//ltxs := make([]*tx, len(txs))
|
|
|
|
|
|
|
|
var ltxs []*tx |
|
|
|
|
|
|
|
for _, tx := range txs { |
|
|
|
|
|
|
|
// no need to check err
|
|
|
|
|
|
|
|
if from, _ := tx.From(); accountSet.Has(from) { |
|
|
|
|
|
|
|
ltxs = append(ltxs, newTx(tx)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return js.re.ToVal(ltxs) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (js *jsre) resend(call otto.FunctionCall) otto.Value { |
|
|
|
|
|
|
|
if len(call.ArgumentList) == 0 { |
|
|
|
|
|
|
|
fmt.Println("first argument must be a transaction") |
|
|
|
|
|
|
|
return otto.FalseValue() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
v, err := call.Argument(0).Export() |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
fmt.Println(err) |
|
|
|
|
|
|
|
return otto.FalseValue() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if tx, ok := v.(*tx); ok { |
|
|
|
|
|
|
|
gl, gp := tx.GasLimit, tx.GasPrice |
|
|
|
|
|
|
|
if len(call.ArgumentList) > 1 { |
|
|
|
|
|
|
|
gp = call.Argument(1).String() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if len(call.ArgumentList) > 2 { |
|
|
|
|
|
|
|
gl = call.Argument(2).String() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ret, err := js.xeth.Transact(tx.From, tx.To, tx.Nonce, tx.Value, gl, gp, tx.Data) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
fmt.Println(err) |
|
|
|
|
|
|
|
return otto.FalseValue() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
js.ethereum.TxPool().RemoveTransactions(types.Transactions{tx.tx}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return js.re.ToVal(ret) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fmt.Println("first argument must be a transaction") |
|
|
|
|
|
|
|
return otto.FalseValue() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (js *jsre) debugBlock(call otto.FunctionCall) otto.Value { |
|
|
|
func (js *jsre) debugBlock(call otto.FunctionCall) otto.Value { |
|
|
|
block, err := js.getBlock(call) |
|
|
|
block, err := js.getBlock(call) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
@ -421,3 +492,35 @@ func (js *jsre) dumpBlock(call otto.FunctionCall) otto.Value { |
|
|
|
return js.re.ToVal(dump) |
|
|
|
return js.re.ToVal(dump) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// internal transaction type which will allow us to resend transactions using `eth.resend`
|
|
|
|
|
|
|
|
type tx struct { |
|
|
|
|
|
|
|
tx *types.Transaction |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
To string |
|
|
|
|
|
|
|
From string |
|
|
|
|
|
|
|
Nonce string |
|
|
|
|
|
|
|
Value string |
|
|
|
|
|
|
|
Data string |
|
|
|
|
|
|
|
GasLimit string |
|
|
|
|
|
|
|
GasPrice string |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func newTx(t *types.Transaction) *tx { |
|
|
|
|
|
|
|
from, _ := t.From() |
|
|
|
|
|
|
|
var to string |
|
|
|
|
|
|
|
if t := t.To(); t != nil { |
|
|
|
|
|
|
|
to = t.Hex() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return &tx{ |
|
|
|
|
|
|
|
tx: t, |
|
|
|
|
|
|
|
To: to, |
|
|
|
|
|
|
|
From: from.Hex(), |
|
|
|
|
|
|
|
Value: t.Amount.String(), |
|
|
|
|
|
|
|
Nonce: strconv.Itoa(int(t.Nonce())), |
|
|
|
|
|
|
|
Data: "0x" + common.Bytes2Hex(t.Data()), |
|
|
|
|
|
|
|
GasLimit: t.GasLimit.String(), |
|
|
|
|
|
|
|
GasPrice: t.GasPrice().String(), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|