mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
fixed request argument parsing issue
This commit is contained in:
parent
8c736d1319
commit
483041eaa5
8 changed files with 1268 additions and 44 deletions
843
cmd/console/admin.go
Normal file
843
cmd/console/admin.go
Normal file
|
|
@ -0,0 +1,843 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
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.downloadProgress)
|
||||||
|
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("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)
|
||||||
|
// undocumented temporary
|
||||||
|
debug.Set("waitForBlocks", js.waitForBlocks)
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// 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) 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 {
|
||||||
|
// no need to check err
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
old := vm.Debug
|
||||||
|
vm.Debug = true
|
||||||
|
_, err = js.ethereum.BlockProcessor().RetryProcess(block)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
vm.Debug = old
|
||||||
|
|
||||||
|
fmt.Println("ok")
|
||||||
|
return otto.UndefinedValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
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) downloadProgress(call otto.FunctionCall) otto.Value {
|
||||||
|
pending, cached := js.ethereum.Downloader().Stats()
|
||||||
|
v, _ := call.Otto.ToValue(map[string]interface{}{"pending": pending, "cached": cached})
|
||||||
|
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) 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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
@ -74,7 +74,7 @@ func newJSRE(datadir, libPath, ipcpath string) *jsre {
|
||||||
// update state in separare forever blocks
|
// update state in separare forever blocks
|
||||||
js.re = re.New(libPath)
|
js.re = re.New(libPath)
|
||||||
js.apiBindings(ipcpath)
|
js.apiBindings(ipcpath)
|
||||||
// TODO js.adminBindings()
|
js.adminBindings()
|
||||||
|
|
||||||
if !liner.TerminalSupported() {
|
if !liner.TerminalSupported() {
|
||||||
js.prompter = dumbterm{bufio.NewReader(os.Stdin)}
|
js.prompter = dumbterm{bufio.NewReader(os.Stdin)}
|
||||||
|
|
@ -173,6 +173,13 @@ func (self *jsre) exec(filename string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// show summary of current geth instance
|
||||||
|
func (self *jsre) welcome() {
|
||||||
|
self.re.Eval(`
|
||||||
|
console.log('Connected to ' + web3.version.client);
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
func (self *jsre) interactive() {
|
func (self *jsre) interactive() {
|
||||||
// Read input lines.
|
// Read input lines.
|
||||||
prompt := make(chan string)
|
prompt := make(chan string)
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,6 @@ func run(ctx *cli.Context) {
|
||||||
ipcpath := ctx.GlobalString(utils.IPCPathFlag.Name)
|
ipcpath := ctx.GlobalString(utils.IPCPathFlag.Name)
|
||||||
|
|
||||||
repl := newJSRE(datadir, jspath, ipcpath)
|
repl := newJSRE(datadir, jspath, ipcpath)
|
||||||
|
repl.welcome()
|
||||||
repl.interactive()
|
repl.interactive()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) {
|
||||||
t.Errorf("Error creating DocServer: %v", err)
|
t.Errorf("Error creating DocServer: %v", err)
|
||||||
}
|
}
|
||||||
tf := &testjethre{ds: ds, stateDb: ethereum.ChainManager().State().Copy()}
|
tf := &testjethre{ds: ds, stateDb: ethereum.ChainManager().State().Copy()}
|
||||||
repl := newJSRE(ethereum, assetPath, "", false, tf)
|
repl := newJSRE(ethereum, assetPath, "", "", false, tf)
|
||||||
tf.jsre = repl
|
tf.jsre = repl
|
||||||
return tmp, tf, ethereum
|
return tmp, tf, ethereum
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@ func console(ctx *cli.Context) {
|
||||||
repl := newJSRE(
|
repl := newJSRE(
|
||||||
ethereum,
|
ethereum,
|
||||||
ctx.String(utils.JSpathFlag.Name),
|
ctx.String(utils.JSpathFlag.Name),
|
||||||
ctx.String(utils.IPCPathFlag.Name),
|
ctx.GlobalString(utils.IPCPathFlag.Name),
|
||||||
ctx.GlobalString(utils.RPCCORSDomainFlag.Name),
|
ctx.GlobalString(utils.RPCCORSDomainFlag.Name),
|
||||||
true,
|
true,
|
||||||
nil,
|
nil,
|
||||||
|
|
|
||||||
413
rpc/api/eth.go
413
rpc/api/eth.go
|
|
@ -546,40 +546,252 @@ type GetBalanceArgs struct {
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
addstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
|
}
|
||||||
|
args.Address = addstr
|
||||||
|
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type GetStorageArgs struct {
|
type GetStorageArgs struct {
|
||||||
Address string
|
Address string
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
addstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
|
}
|
||||||
|
args.Address = addstr
|
||||||
|
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type GetStorageAtArgs struct {
|
type GetStorageAtArgs struct {
|
||||||
Address string
|
Address string
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
Key string
|
Key string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 2 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
addstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
|
}
|
||||||
|
args.Address = addstr
|
||||||
|
|
||||||
|
keystr, ok := obj[1].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("key", "not a string")
|
||||||
|
}
|
||||||
|
args.Key = keystr
|
||||||
|
|
||||||
|
if len(obj) > 2 {
|
||||||
|
if err := blockHeight(obj[2], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type GetTxCountArgs struct {
|
type GetTxCountArgs struct {
|
||||||
Address string
|
Address string
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
addstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
|
}
|
||||||
|
args.Address = addstr
|
||||||
|
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type HashArgs struct {
|
type HashArgs struct {
|
||||||
Hash string
|
Hash string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *HashArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
arg0, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("hash", "not a string")
|
||||||
|
}
|
||||||
|
args.Hash = arg0
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type BlockNumArg struct {
|
type BlockNumArg struct {
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *BlockNumArg) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type GetDataArgs struct {
|
type GetDataArgs struct {
|
||||||
Address string
|
Address string
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
addstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
|
}
|
||||||
|
args.Address = addstr
|
||||||
|
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type NewSignArgs struct {
|
type NewSignArgs struct {
|
||||||
From string
|
From string
|
||||||
Data string
|
Data string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *NewSignArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []json.RawMessage
|
||||||
|
var ext struct {
|
||||||
|
From string
|
||||||
|
Data string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode byte slice to array of RawMessages
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for sufficient params
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode 0th RawMessage to temporary struct
|
||||||
|
if err := json.Unmarshal(obj[0], &ext); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ext.From) == 0 {
|
||||||
|
return shared.NewValidationError("from", "is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ext.Data) == 0 {
|
||||||
|
return shared.NewValidationError("data", "is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
args.From = ext.From
|
||||||
|
args.Data = ext.Data
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type NewTxArgs struct {
|
type NewTxArgs struct {
|
||||||
From string
|
From string
|
||||||
To string
|
To string
|
||||||
|
|
@ -592,36 +804,12 @@ type NewTxArgs struct {
|
||||||
BlockNumber int64
|
BlockNumber int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type SourceArgs struct {
|
|
||||||
Source string
|
|
||||||
}
|
|
||||||
|
|
||||||
type CallArgs struct {
|
|
||||||
From string
|
|
||||||
To string
|
|
||||||
Value *big.Int
|
|
||||||
Gas *big.Int
|
|
||||||
GasPrice *big.Int
|
|
||||||
Data string
|
|
||||||
|
|
||||||
BlockNumber int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type HashIndexArgs struct {
|
|
||||||
Hash string
|
|
||||||
Index int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type BlockNumIndexArgs struct {
|
|
||||||
BlockNumber int64
|
|
||||||
Index int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []json.RawMessage
|
var obj []json.RawMessage
|
||||||
var ext struct {
|
var ext struct {
|
||||||
From string
|
From string
|
||||||
To string
|
To string
|
||||||
|
Nonce interface{}
|
||||||
Value interface{}
|
Value interface{}
|
||||||
Gas interface{}
|
Gas interface{}
|
||||||
GasPrice interface{}
|
GasPrice interface{}
|
||||||
|
|
@ -652,6 +840,14 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
args.Data = ext.Data
|
args.Data = ext.Data
|
||||||
|
|
||||||
var num *big.Int
|
var num *big.Int
|
||||||
|
if ext.Nonce != nil {
|
||||||
|
num, err = numString(ext.Nonce)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Nonce = num
|
||||||
|
|
||||||
if ext.Value == nil {
|
if ext.Value == nil {
|
||||||
num = big.NewInt(0)
|
num = big.NewInt(0)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -694,6 +890,173 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SourceArgs struct {
|
||||||
|
Source string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *SourceArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
arg0, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("source code", "not a string")
|
||||||
|
}
|
||||||
|
args.Source = arg0
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CallArgs struct {
|
||||||
|
From string
|
||||||
|
To string
|
||||||
|
Value *big.Int
|
||||||
|
Gas *big.Int
|
||||||
|
GasPrice *big.Int
|
||||||
|
Data string
|
||||||
|
|
||||||
|
BlockNumber int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *CallArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []json.RawMessage
|
||||||
|
var ext struct {
|
||||||
|
From string
|
||||||
|
To string
|
||||||
|
Value interface{}
|
||||||
|
Gas interface{}
|
||||||
|
GasPrice interface{}
|
||||||
|
Data string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode byte slice to array of RawMessages
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for sufficient params
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode 0th RawMessage to temporary struct
|
||||||
|
if err := json.Unmarshal(obj[0], &ext); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
args.From = ext.From
|
||||||
|
|
||||||
|
if len(ext.To) == 0 {
|
||||||
|
return shared.NewValidationError("to", "is required")
|
||||||
|
}
|
||||||
|
args.To = ext.To
|
||||||
|
|
||||||
|
var num *big.Int
|
||||||
|
if ext.Value == nil {
|
||||||
|
num = big.NewInt(0)
|
||||||
|
} else {
|
||||||
|
if num, err = numString(ext.Value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Value = num
|
||||||
|
|
||||||
|
if ext.Gas == nil {
|
||||||
|
num = big.NewInt(0)
|
||||||
|
} else {
|
||||||
|
if num, err = numString(ext.Gas); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Gas = num
|
||||||
|
|
||||||
|
if ext.GasPrice == nil {
|
||||||
|
num = big.NewInt(0)
|
||||||
|
} else {
|
||||||
|
if num, err = numString(ext.GasPrice); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.GasPrice = num
|
||||||
|
|
||||||
|
args.Data = ext.Data
|
||||||
|
|
||||||
|
// Check for optional BlockNumber param
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type HashIndexArgs struct {
|
||||||
|
Hash string
|
||||||
|
Index int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 2 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
arg0, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("hash", "not a string")
|
||||||
|
}
|
||||||
|
args.Hash = arg0
|
||||||
|
|
||||||
|
arg1, ok := obj[1].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("index", "not a string")
|
||||||
|
}
|
||||||
|
args.Index = common.Big(arg1).Int64()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type BlockNumIndexArgs struct {
|
||||||
|
BlockNumber int64
|
||||||
|
Index int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 2 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var arg1 *big.Int
|
||||||
|
if arg1, err = numString(obj[1]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
args.Index = arg1.Int64()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type GetBlockByHashArgs struct {
|
type GetBlockByHashArgs struct {
|
||||||
BlockHash string
|
BlockHash string
|
||||||
IncludeTxs bool
|
IncludeTxs bool
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/rpc/shared"
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MAX_RESPONSE_SIZE = 64 * 1024
|
||||||
|
)
|
||||||
|
|
||||||
// Json serialization support
|
// Json serialization support
|
||||||
type JsonCodec struct {
|
type JsonCodec struct {
|
||||||
c net.Conn
|
c net.Conn
|
||||||
|
|
@ -35,16 +39,19 @@ func (self *JsonCodec) ReadRequest() (*shared.Request, error) {
|
||||||
|
|
||||||
func (self *JsonCodec) ReadResponse() (interface{}, error) {
|
func (self *JsonCodec) ReadResponse() (interface{}, error) {
|
||||||
var err error
|
var err error
|
||||||
var success shared.SuccessResponse
|
buf := make([]byte, MAX_RESPONSE_SIZE)
|
||||||
if err = self.d.Decode(&success); err == nil {
|
n, _ := self.c.Read(buf)
|
||||||
return success, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var failure shared.ErrorResponse
|
var failure shared.ErrorResponse
|
||||||
if err = self.d.Decode(&failure); err == nil {
|
if err = json.Unmarshal(buf[:n], &failure); err == nil && failure.Error != nil {
|
||||||
return failure, nil
|
return failure, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var success shared.SuccessResponse
|
||||||
|
if err = json.Unmarshal(buf[:n], &success); err == nil {
|
||||||
|
return success, nil
|
||||||
|
}
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
24
rpc/jeth.go
24
rpc/jeth.go
|
|
@ -43,7 +43,7 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
|
||||||
|
|
||||||
client, err := comms.NewIpcClient(comms.IpcConfig{self.ipcpath}, codec.JSON)
|
client, err := comms.NewIpcClient(comms.IpcConfig{self.ipcpath}, codec.JSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error response:", err)
|
fmt.Println("Unable to connect to geth.")
|
||||||
return self.err(call, -32603, err.Error(), -1)
|
return self.err(call, -32603, err.Error(), -1)
|
||||||
}
|
}
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
|
|
@ -80,19 +80,23 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
|
||||||
resObj, _ := json.Marshal(res.Result)
|
resObj, _ := json.Marshal(res.Result)
|
||||||
call.Otto.Set("ret_result", string(resObj))
|
call.Otto.Set("ret_result", string(resObj))
|
||||||
call.Otto.Set("response_idx", i)
|
call.Otto.Set("response_idx", i)
|
||||||
} else if res, ok := respif.(shared.ErrorResponse); ok {
|
|
||||||
call.Otto.Set("ret_id", res.Id)
|
|
||||||
call.Otto.Set("ret_jsonrpc", res.Jsonrpc)
|
|
||||||
errorObj, _ := json.Marshal(res.Error)
|
|
||||||
call.Otto.Set("ret_result", string(errorObj))
|
|
||||||
call.Otto.Set("response_idx", i)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("different type\n", reflect.TypeOf(respif))
|
|
||||||
}
|
|
||||||
|
|
||||||
response, err = call.Otto.Run(`
|
response, err = call.Otto.Run(`
|
||||||
ret_response[response_idx] = { jsonrpc: ret_jsonrpc, id: ret_id, result: JSON.parse(ret_result) };
|
ret_response[response_idx] = { jsonrpc: ret_jsonrpc, id: ret_id, result: JSON.parse(ret_result) };
|
||||||
`)
|
`)
|
||||||
|
} else if res, ok := respif.(shared.ErrorResponse); ok {
|
||||||
|
call.Otto.Set("ret_id", res.Id)
|
||||||
|
call.Otto.Set("ret_jsonrpc", res.Jsonrpc)
|
||||||
|
call.Otto.Set("ret_error", res.Error)
|
||||||
|
call.Otto.Set("response_idx", i)
|
||||||
|
|
||||||
|
response, _ = call.Otto.Run(`
|
||||||
|
ret_response = { jsonrpc: ret_jsonrpc, id: ret_id, error: ret_error };
|
||||||
|
`)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
fmt.Printf("unexpected response\n", reflect.TypeOf(respif))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !batch {
|
if !batch {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue