forked from mirror/go-ethereum
parent
22c7ce0162
commit
821e01b013
@ -0,0 +1,960 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"encoding/json" |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"math/big" |
||||||
|
"strconv" |
||||||
|
"time" |
||||||
|
|
||||||
|
"github.com/rcrowley/go-metrics" |
||||||
|
|
||||||
|
"github.com/ethereum/ethash" |
||||||
|
"github.com/ethereum/go-ethereum/accounts" |
||||||
|
"github.com/ethereum/go-ethereum/cmd/utils" |
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
"github.com/ethereum/go-ethereum/common/compiler" |
||||||
|
"github.com/ethereum/go-ethereum/common/natspec" |
||||||
|
"github.com/ethereum/go-ethereum/common/resolver" |
||||||
|
"github.com/ethereum/go-ethereum/core/state" |
||||||
|
"github.com/ethereum/go-ethereum/core/types" |
||||||
|
"github.com/ethereum/go-ethereum/core/vm" |
||||||
|
"github.com/ethereum/go-ethereum/crypto" |
||||||
|
"github.com/ethereum/go-ethereum/logger/glog" |
||||||
|
"github.com/ethereum/go-ethereum/rlp" |
||||||
|
"github.com/ethereum/go-ethereum/rpc" |
||||||
|
"github.com/ethereum/go-ethereum/xeth" |
||||||
|
"github.com/robertkrimen/otto" |
||||||
|
"gopkg.in/fatih/set.v0" |
||||||
|
) |
||||||
|
|
||||||
|
/* |
||||||
|
node admin bindings |
||||||
|
*/ |
||||||
|
|
||||||
|
func (js *jsre) adminBindings() { |
||||||
|
ethO, _ := js.re.Get("eth") |
||||||
|
eth := ethO.Object() |
||||||
|
eth.Set("pendingTransactions", js.pendingTransactions) |
||||||
|
eth.Set("resend", js.resend) |
||||||
|
eth.Set("sign", js.sign) |
||||||
|
|
||||||
|
js.re.Set("admin", struct{}{}) |
||||||
|
t, _ := js.re.Get("admin") |
||||||
|
admin := t.Object() |
||||||
|
admin.Set("addPeer", js.addPeer) |
||||||
|
admin.Set("startRPC", js.startRPC) |
||||||
|
admin.Set("stopRPC", js.stopRPC) |
||||||
|
admin.Set("nodeInfo", js.nodeInfo) |
||||||
|
admin.Set("peers", js.peers) |
||||||
|
admin.Set("newAccount", js.newAccount) |
||||||
|
admin.Set("unlock", js.unlock) |
||||||
|
admin.Set("import", js.importChain) |
||||||
|
admin.Set("export", js.exportChain) |
||||||
|
admin.Set("verbosity", js.verbosity) |
||||||
|
admin.Set("progress", js.syncProgress) |
||||||
|
admin.Set("setSolc", js.setSolc) |
||||||
|
|
||||||
|
admin.Set("contractInfo", struct{}{}) |
||||||
|
t, _ = admin.Get("contractInfo") |
||||||
|
cinfo := t.Object() |
||||||
|
// newRegistry officially not documented temporary option
|
||||||
|
cinfo.Set("start", js.startNatSpec) |
||||||
|
cinfo.Set("stop", js.stopNatSpec) |
||||||
|
cinfo.Set("newRegistry", js.newRegistry) |
||||||
|
cinfo.Set("get", js.getContractInfo) |
||||||
|
cinfo.Set("register", js.register) |
||||||
|
cinfo.Set("registerUrl", js.registerUrl) |
||||||
|
// cinfo.Set("verify", js.verify)
|
||||||
|
|
||||||
|
admin.Set("miner", struct{}{}) |
||||||
|
t, _ = admin.Get("miner") |
||||||
|
miner := t.Object() |
||||||
|
miner.Set("start", js.startMining) |
||||||
|
miner.Set("stop", js.stopMining) |
||||||
|
miner.Set("hashrate", js.hashrate) |
||||||
|
miner.Set("setExtra", js.setExtra) |
||||||
|
miner.Set("setGasPrice", js.setGasPrice) |
||||||
|
miner.Set("startAutoDAG", js.startAutoDAG) |
||||||
|
miner.Set("stopAutoDAG", js.stopAutoDAG) |
||||||
|
miner.Set("makeDAG", js.makeDAG) |
||||||
|
|
||||||
|
admin.Set("txPool", struct{}{}) |
||||||
|
t, _ = admin.Get("txPool") |
||||||
|
txPool := t.Object() |
||||||
|
txPool.Set("pending", js.allPendingTransactions) |
||||||
|
txPool.Set("queued", js.allQueuedTransactions) |
||||||
|
|
||||||
|
admin.Set("debug", struct{}{}) |
||||||
|
t, _ = admin.Get("debug") |
||||||
|
debug := t.Object() |
||||||
|
js.re.Set("sleep", js.sleep) |
||||||
|
debug.Set("backtrace", js.backtrace) |
||||||
|
debug.Set("printBlock", js.printBlock) |
||||||
|
debug.Set("dumpBlock", js.dumpBlock) |
||||||
|
debug.Set("getBlockRlp", js.getBlockRlp) |
||||||
|
debug.Set("setHead", js.setHead) |
||||||
|
debug.Set("processBlock", js.debugBlock) |
||||||
|
debug.Set("seedhash", js.seedHash) |
||||||
|
debug.Set("insertBlock", js.insertBlockRlp) |
||||||
|
// undocumented temporary
|
||||||
|
debug.Set("waitForBlocks", js.waitForBlocks) |
||||||
|
|
||||||
|
admin.Set("metrics", js.metrics) |
||||||
|
} |
||||||
|
|
||||||
|
// generic helper to getBlock by Number/Height or Hex depending on autodetected input
|
||||||
|
// if argument is missing the current block is returned
|
||||||
|
// if block is not found or there is problem with decoding
|
||||||
|
// the appropriate value is returned and block is guaranteed to be nil
|
||||||
|
func (js *jsre) getBlock(call otto.FunctionCall) (*types.Block, error) { |
||||||
|
var block *types.Block |
||||||
|
if len(call.ArgumentList) > 0 { |
||||||
|
if call.Argument(0).IsNumber() { |
||||||
|
num, _ := call.Argument(0).ToInteger() |
||||||
|
block = js.ethereum.ChainManager().GetBlockByNumber(uint64(num)) |
||||||
|
} else if call.Argument(0).IsString() { |
||||||
|
hash, _ := call.Argument(0).ToString() |
||||||
|
block = js.ethereum.ChainManager().GetBlock(common.HexToHash(hash)) |
||||||
|
} else { |
||||||
|
return nil, errors.New("invalid argument for dump. Either hex string or number") |
||||||
|
} |
||||||
|
} else { |
||||||
|
block = js.ethereum.ChainManager().CurrentBlock() |
||||||
|
} |
||||||
|
|
||||||
|
if block == nil { |
||||||
|
return nil, errors.New("block not found") |
||||||
|
} |
||||||
|
return block, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) seedHash(call otto.FunctionCall) otto.Value { |
||||||
|
if len(call.ArgumentList) > 0 { |
||||||
|
if call.Argument(0).IsNumber() { |
||||||
|
num, _ := call.Argument(0).ToInteger() |
||||||
|
hash, err := ethash.GetSeedHash(uint64(num)) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
v, _ := call.Otto.ToValue(fmt.Sprintf("0x%x", hash)) |
||||||
|
return v |
||||||
|
} else { |
||||||
|
fmt.Println("arg not a number") |
||||||
|
} |
||||||
|
} else { |
||||||
|
fmt.Println("requires number argument") |
||||||
|
} |
||||||
|
|
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) allPendingTransactions(call otto.FunctionCall) otto.Value { |
||||||
|
txs := js.ethereum.TxPool().GetTransactions() |
||||||
|
|
||||||
|
ltxs := make([]*tx, len(txs)) |
||||||
|
for i, tx := range txs { |
||||||
|
// no need to check err
|
||||||
|
ltxs[i] = newTx(tx) |
||||||
|
} |
||||||
|
|
||||||
|
v, _ := call.Otto.ToValue(ltxs) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) allQueuedTransactions(call otto.FunctionCall) otto.Value { |
||||||
|
txs := js.ethereum.TxPool().GetQueuedTransactions() |
||||||
|
|
||||||
|
ltxs := make([]*tx, len(txs)) |
||||||
|
for i, tx := range txs { |
||||||
|
// no need to check err
|
||||||
|
ltxs[i] = newTx(tx) |
||||||
|
} |
||||||
|
|
||||||
|
v, _ := call.Otto.ToValue(ltxs) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
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(account.Address) |
||||||
|
} |
||||||
|
|
||||||
|
//ltxs := make([]*tx, len(txs))
|
||||||
|
var ltxs []*tx |
||||||
|
for _, tx := range txs { |
||||||
|
if from, _ := tx.From(); accountSet.Has(from) { |
||||||
|
ltxs = append(ltxs, newTx(tx)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
v, _ := call.Otto.ToValue(ltxs) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
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}) |
||||||
|
|
||||||
|
v, _ := call.Otto.ToValue(ret) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Println("first argument must be a transaction") |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) sign(call otto.FunctionCall) otto.Value { |
||||||
|
if len(call.ArgumentList) != 2 { |
||||||
|
fmt.Println("requires 2 arguments: eth.sign(signer, data)") |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
signer, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
data, err := call.Argument(1).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
signed, err := js.xeth.Sign(signer, data, false) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
v, _ := call.Otto.ToValue(signed) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) debugBlock(call otto.FunctionCall) otto.Value { |
||||||
|
block, err := js.getBlock(call) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
tstart := time.Now() |
||||||
|
old := vm.Debug |
||||||
|
|
||||||
|
if len(call.ArgumentList) > 1 { |
||||||
|
vm.Debug, _ = call.Argument(1).ToBoolean() |
||||||
|
} |
||||||
|
|
||||||
|
_, err = js.ethereum.BlockProcessor().RetryProcess(block) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
r, _ := call.Otto.ToValue(map[string]interface{}{"success": false, "time": time.Since(tstart).Seconds()}) |
||||||
|
return r |
||||||
|
} |
||||||
|
vm.Debug = old |
||||||
|
|
||||||
|
r, _ := call.Otto.ToValue(map[string]interface{}{"success": true, "time": time.Since(tstart).Seconds()}) |
||||||
|
return r |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) insertBlockRlp(call otto.FunctionCall) otto.Value { |
||||||
|
tstart := time.Now() |
||||||
|
|
||||||
|
var block types.Block |
||||||
|
if call.Argument(0).IsString() { |
||||||
|
blockRlp, _ := call.Argument(0).ToString() |
||||||
|
err := rlp.DecodeBytes(common.Hex2Bytes(blockRlp), &block) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
old := vm.Debug |
||||||
|
vm.Debug = true |
||||||
|
_, err := js.ethereum.BlockProcessor().RetryProcess(&block) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
r, _ := call.Otto.ToValue(map[string]interface{}{"success": false, "time": time.Since(tstart).Seconds()}) |
||||||
|
return r |
||||||
|
} |
||||||
|
vm.Debug = old |
||||||
|
|
||||||
|
r, _ := call.Otto.ToValue(map[string]interface{}{"success": true, "time": time.Since(tstart).Seconds()}) |
||||||
|
return r |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) setHead(call otto.FunctionCall) otto.Value { |
||||||
|
block, err := js.getBlock(call) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
js.ethereum.ChainManager().SetHead(block) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) syncProgress(call otto.FunctionCall) otto.Value { |
||||||
|
pending, cached, importing, eta := js.ethereum.Downloader().Stats() |
||||||
|
v, _ := call.Otto.ToValue(map[string]interface{}{ |
||||||
|
"pending": pending, |
||||||
|
"cached": cached, |
||||||
|
"importing": importing, |
||||||
|
"estimate": (eta / time.Second * time.Second).String(), |
||||||
|
}) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) getBlockRlp(call otto.FunctionCall) otto.Value { |
||||||
|
block, err := js.getBlock(call) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
encoded, _ := rlp.EncodeToBytes(block) |
||||||
|
v, _ := call.Otto.ToValue(fmt.Sprintf("%x", encoded)) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) setExtra(call otto.FunctionCall) otto.Value { |
||||||
|
extra, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
if len(extra) > 1024 { |
||||||
|
fmt.Println("error: cannot exceed 1024 bytes") |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
js.ethereum.Miner().SetExtra([]byte(extra)) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) setGasPrice(call otto.FunctionCall) otto.Value { |
||||||
|
gasPrice, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
js.ethereum.Miner().SetGasPrice(common.String2Big(gasPrice)) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) hashrate(call otto.FunctionCall) otto.Value { |
||||||
|
v, _ := call.Otto.ToValue(js.ethereum.Miner().HashRate()) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) makeDAG(call otto.FunctionCall) otto.Value { |
||||||
|
blockNumber, err := call.Argument(1).ToInteger() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
err = ethash.MakeDAG(uint64(blockNumber), "") |
||||||
|
if err != nil { |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) startAutoDAG(otto.FunctionCall) otto.Value { |
||||||
|
js.ethereum.StartAutoDAG() |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) stopAutoDAG(otto.FunctionCall) otto.Value { |
||||||
|
js.ethereum.StopAutoDAG() |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) backtrace(call otto.FunctionCall) otto.Value { |
||||||
|
tracestr, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
glog.GetTraceLocation().Set(tracestr) |
||||||
|
|
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) verbosity(call otto.FunctionCall) otto.Value { |
||||||
|
v, err := call.Argument(0).ToInteger() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
glog.SetV(int(v)) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) startMining(call otto.FunctionCall) otto.Value { |
||||||
|
var ( |
||||||
|
threads int64 |
||||||
|
err error |
||||||
|
) |
||||||
|
|
||||||
|
if len(call.ArgumentList) > 0 { |
||||||
|
threads, err = call.Argument(0).ToInteger() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
} else { |
||||||
|
threads = int64(js.ethereum.MinerThreads) |
||||||
|
} |
||||||
|
|
||||||
|
// switch on DAG autogeneration when miner starts
|
||||||
|
js.ethereum.StartAutoDAG() |
||||||
|
|
||||||
|
err = js.ethereum.StartMining(int(threads)) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) stopMining(call otto.FunctionCall) otto.Value { |
||||||
|
js.ethereum.StopMining() |
||||||
|
js.ethereum.StopAutoDAG() |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) startRPC(call otto.FunctionCall) otto.Value { |
||||||
|
addr, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
port, err := call.Argument(1).ToInteger() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
corsDomain := js.corsDomain |
||||||
|
if len(call.ArgumentList) > 2 { |
||||||
|
corsDomain, err = call.Argument(2).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
config := rpc.RpcConfig{ |
||||||
|
ListenAddress: addr, |
||||||
|
ListenPort: uint(port), |
||||||
|
CorsDomain: corsDomain, |
||||||
|
} |
||||||
|
|
||||||
|
xeth := xeth.New(js.ethereum, nil) |
||||||
|
err = rpc.Start(xeth, config) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) stopRPC(call otto.FunctionCall) otto.Value { |
||||||
|
if rpc.Stop() == nil { |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) addPeer(call otto.FunctionCall) otto.Value { |
||||||
|
nodeURL, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
err = js.ethereum.AddPeer(nodeURL) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) unlock(call otto.FunctionCall) otto.Value { |
||||||
|
addr, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
seconds, err := call.Argument(2).ToInteger() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
if seconds == 0 { |
||||||
|
seconds = accounts.DefaultAccountUnlockDuration |
||||||
|
} |
||||||
|
|
||||||
|
arg := call.Argument(1) |
||||||
|
var passphrase string |
||||||
|
if arg.IsUndefined() { |
||||||
|
fmt.Println("Please enter a passphrase now.") |
||||||
|
passphrase, err = utils.PromptPassword("Passphrase: ", true) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
} else { |
||||||
|
passphrase, err = arg.ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
} |
||||||
|
am := js.ethereum.AccountManager() |
||||||
|
err = am.TimedUnlock(common.HexToAddress(addr), passphrase, time.Duration(seconds)*time.Second) |
||||||
|
if err != nil { |
||||||
|
fmt.Printf("Unlock account failed '%v'\n", err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) newAccount(call otto.FunctionCall) otto.Value { |
||||||
|
arg := call.Argument(0) |
||||||
|
var passphrase string |
||||||
|
if arg.IsUndefined() { |
||||||
|
fmt.Println("The new account will be encrypted with a passphrase.") |
||||||
|
fmt.Println("Please enter a passphrase now.") |
||||||
|
auth, err := utils.PromptPassword("Passphrase: ", true) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
confirm, err := utils.PromptPassword("Repeat Passphrase: ", false) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
if auth != confirm { |
||||||
|
fmt.Println("Passphrases did not match.") |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
passphrase = auth |
||||||
|
} else { |
||||||
|
var err error |
||||||
|
passphrase, err = arg.ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
} |
||||||
|
acct, err := js.ethereum.AccountManager().NewAccount(passphrase) |
||||||
|
if err != nil { |
||||||
|
fmt.Printf("Could not create the account: %v", err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
v, _ := call.Otto.ToValue(acct.Address.Hex()) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) nodeInfo(call otto.FunctionCall) otto.Value { |
||||||
|
v, _ := call.Otto.ToValue(js.ethereum.NodeInfo()) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) peers(call otto.FunctionCall) otto.Value { |
||||||
|
v, _ := call.Otto.ToValue(js.ethereum.PeersInfo()) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) importChain(call otto.FunctionCall) otto.Value { |
||||||
|
if len(call.ArgumentList) == 0 { |
||||||
|
fmt.Println("require file name. admin.importChain(filename)") |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
fn, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
if err := utils.ImportChain(js.ethereum.ChainManager(), fn); err != nil { |
||||||
|
fmt.Println("Import error: ", err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) exportChain(call otto.FunctionCall) otto.Value { |
||||||
|
if len(call.ArgumentList) == 0 { |
||||||
|
fmt.Println("require file name: admin.exportChain(filename)") |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
fn, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
if err := utils.ExportChain(js.ethereum.ChainManager(), fn); err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) printBlock(call otto.FunctionCall) otto.Value { |
||||||
|
block, err := js.getBlock(call) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Println(block) |
||||||
|
|
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) dumpBlock(call otto.FunctionCall) otto.Value { |
||||||
|
block, err := js.getBlock(call) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
statedb := state.New(block.Root(), js.ethereum.StateDb()) |
||||||
|
dump := statedb.RawDump() |
||||||
|
v, _ := call.Otto.ToValue(dump) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) waitForBlocks(call otto.FunctionCall) otto.Value { |
||||||
|
if len(call.ArgumentList) > 2 { |
||||||
|
fmt.Println("requires 0, 1 or 2 arguments: admin.debug.waitForBlock(minHeight, timeout)") |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
var n, timeout int64 |
||||||
|
var timer <-chan time.Time |
||||||
|
var height *big.Int |
||||||
|
var err error |
||||||
|
args := len(call.ArgumentList) |
||||||
|
if args == 2 { |
||||||
|
timeout, err = call.Argument(1).ToInteger() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
timer = time.NewTimer(time.Duration(timeout) * time.Second).C |
||||||
|
} |
||||||
|
if args >= 1 { |
||||||
|
n, err = call.Argument(0).ToInteger() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
height = big.NewInt(n) |
||||||
|
} |
||||||
|
|
||||||
|
if args == 0 { |
||||||
|
height = js.xeth.CurrentBlock().Number() |
||||||
|
height.Add(height, common.Big1) |
||||||
|
} |
||||||
|
|
||||||
|
wait := js.wait |
||||||
|
js.wait <- height |
||||||
|
select { |
||||||
|
case <-timer: |
||||||
|
// if times out make sure the xeth loop does not block
|
||||||
|
go func() { |
||||||
|
select { |
||||||
|
case wait <- nil: |
||||||
|
case <-wait: |
||||||
|
} |
||||||
|
}() |
||||||
|
return otto.UndefinedValue() |
||||||
|
case height = <-wait: |
||||||
|
} |
||||||
|
v, _ := call.Otto.ToValue(height.Uint64()) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) metrics(call otto.FunctionCall) otto.Value { |
||||||
|
// Iterate over all the metrics, and just dump for now
|
||||||
|
counters := make(map[string]interface{}) |
||||||
|
metrics.DefaultRegistry.Each(func(name string, metric interface{}) { |
||||||
|
switch metric := metric.(type) { |
||||||
|
case metrics.Meter: |
||||||
|
counters[name+"( 1 min)"] = int(metric.Rate1() * 60) |
||||||
|
counters[name+"( 5 min)"] = int(metric.Rate5() * 300) |
||||||
|
counters[name+"(15 min)"] = int(metric.Rate15() * 900) |
||||||
|
|
||||||
|
default: |
||||||
|
counters[name] = "Unknown metric type" |
||||||
|
} |
||||||
|
}) |
||||||
|
// Flatten the counters into some metrics and return
|
||||||
|
v, _ := call.Otto.ToValue(counters) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) sleep(call otto.FunctionCall) otto.Value { |
||||||
|
sec, err := call.Argument(0).ToInteger() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
time.Sleep(time.Duration(sec) * time.Second) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) setSolc(call otto.FunctionCall) otto.Value { |
||||||
|
if len(call.ArgumentList) != 1 { |
||||||
|
fmt.Println("needs 1 argument: admin.contractInfo.setSolc(solcPath)") |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
solcPath, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
solc, err := js.xeth.SetSolc(solcPath) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
fmt.Println(solc.Info()) |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) register(call otto.FunctionCall) otto.Value { |
||||||
|
if len(call.ArgumentList) != 4 { |
||||||
|
fmt.Println("requires 4 arguments: admin.contractInfo.register(fromaddress, contractaddress, contract, filename)") |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
sender, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
address, err := call.Argument(1).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
raw, err := call.Argument(2).Export() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
jsonraw, err := json.Marshal(raw) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
var contract compiler.Contract |
||||||
|
err = json.Unmarshal(jsonraw, &contract) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
filename, err := call.Argument(3).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
contenthash, err := compiler.ExtractInfo(&contract, filename) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
// sender and contract address are passed as hex strings
|
||||||
|
codeb := js.xeth.CodeAtBytes(address) |
||||||
|
codehash := common.BytesToHash(crypto.Sha3(codeb)) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
registry := resolver.New(js.xeth) |
||||||
|
|
||||||
|
_, err = registry.RegisterContentHash(common.HexToAddress(sender), codehash, contenthash) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
|
||||||
|
v, _ := call.Otto.ToValue(contenthash.Hex()) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) registerUrl(call otto.FunctionCall) otto.Value { |
||||||
|
if len(call.ArgumentList) != 3 { |
||||||
|
fmt.Println("requires 3 arguments: admin.contractInfo.register(fromaddress, contenthash, filename)") |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
sender, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
contenthash, err := call.Argument(1).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
url, err := call.Argument(2).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
registry := resolver.New(js.xeth) |
||||||
|
|
||||||
|
_, err = registry.RegisterUrl(common.HexToAddress(sender), common.HexToHash(contenthash), url) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) getContractInfo(call otto.FunctionCall) otto.Value { |
||||||
|
if len(call.ArgumentList) != 1 { |
||||||
|
fmt.Println("requires 1 argument: admin.contractInfo.register(contractaddress)") |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
addr, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
infoDoc, err := natspec.FetchDocsForContract(addr, js.xeth, ds) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
var info compiler.ContractInfo |
||||||
|
err = json.Unmarshal(infoDoc, &info) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.UndefinedValue() |
||||||
|
} |
||||||
|
v, _ := call.Otto.ToValue(info) |
||||||
|
return v |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) startNatSpec(call otto.FunctionCall) otto.Value { |
||||||
|
js.ethereum.NatSpec = true |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) stopNatSpec(call otto.FunctionCall) otto.Value { |
||||||
|
js.ethereum.NatSpec = false |
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
func (js *jsre) newRegistry(call otto.FunctionCall) otto.Value { |
||||||
|
|
||||||
|
if len(call.ArgumentList) != 1 { |
||||||
|
fmt.Println("requires 1 argument: admin.contractInfo.newRegistry(adminaddress)") |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
addr, err := call.Argument(0).ToString() |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
registry := resolver.New(js.xeth) |
||||||
|
err = registry.CreateContracts(common.HexToAddress(addr)) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
return otto.FalseValue() |
||||||
|
} |
||||||
|
|
||||||
|
return otto.TrueValue() |
||||||
|
} |
||||||
|
|
||||||
|
// 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(), |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue