Updated RPC
* Added a generic RawMessage deserialiser * Updated ethereum.js * Updated coin test app
This commit is contained in:
parent
bbe8b18660
commit
f22684439a
|
@ -77,7 +77,8 @@
|
||||||
}
|
}
|
||||||
document.querySelector("#contract_addr").innerHTML = address;
|
document.querySelector("#contract_addr").innerHTML = address;
|
||||||
|
|
||||||
var contract = web3.eth.contract(address, desc);
|
var Contract = web3.eth.contract(desc);
|
||||||
|
contract = new Contract(address);
|
||||||
contract.Changed({from: eth.coinbase}).changed(function() {
|
contract.Changed({from: eth.coinbase}).changed(function() {
|
||||||
refresh();
|
refresh();
|
||||||
});
|
});
|
||||||
|
@ -88,7 +89,7 @@
|
||||||
var table = document.querySelector("#table_body");
|
var table = document.querySelector("#table_body");
|
||||||
table.innerHTML = ""; // clear
|
table.innerHTML = ""; // clear
|
||||||
|
|
||||||
var storage = eth.storageAt(address);
|
var storage = eth.getStorage(address);
|
||||||
table.innerHTML = "";
|
table.innerHTML = "";
|
||||||
for( var item in storage ) {
|
for( var item in storage ) {
|
||||||
table.innerHTML += "<tr><td>"+item+"</td><td>"+web3.toDecimal(storage[item])+"</td></tr>";
|
table.innerHTML += "<tr><td>"+item+"</td><td>"+web3.toDecimal(storage[item])+"</td></tr>";
|
||||||
|
|
|
@ -1684,7 +1684,7 @@ var methods = [
|
||||||
inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},
|
inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},
|
||||||
{ name: 'getUncle', call: uncleCall,
|
{ name: 'getUncle', call: uncleCall,
|
||||||
outputFormatter: formatters.outputBlockFormatter,
|
outputFormatter: formatters.outputBlockFormatter,
|
||||||
inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},
|
inputFormatter: [utils.toHex, utils.toHex, function(param){ return (!param) ? false : true; }]},
|
||||||
{ name: 'getCompilers', call: 'eth_getCompilers' },
|
{ name: 'getCompilers', call: 'eth_getCompilers' },
|
||||||
{ name: 'getBlockTransactionCount', call: getBlockTransactionCountCall,
|
{ name: 'getBlockTransactionCount', call: getBlockTransactionCountCall,
|
||||||
outputFormatter: utils.toDecimal,
|
outputFormatter: utils.toDecimal,
|
||||||
|
@ -1703,9 +1703,9 @@ var methods = [
|
||||||
inputFormatter: formatters.inputTransactionFormatter },
|
inputFormatter: formatters.inputTransactionFormatter },
|
||||||
{ name: 'call', call: 'eth_call', addDefaultblock: 2,
|
{ name: 'call', call: 'eth_call', addDefaultblock: 2,
|
||||||
inputFormatter: formatters.inputCallFormatter },
|
inputFormatter: formatters.inputCallFormatter },
|
||||||
{ name: 'compile.solidity', call: 'eth_compileSolidity' },
|
{ name: 'compile.solidity', call: 'eth_compileSolidity', inputFormatter: utils.toHex },
|
||||||
{ name: 'compile.lll', call: 'eth_compileLLL' },
|
{ name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex },
|
||||||
{ name: 'compile.serpent', call: 'eth_compileSerpent' },
|
{ name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex },
|
||||||
{ name: 'flush', call: 'eth_flush' },
|
{ name: 'flush', call: 'eth_flush' },
|
||||||
|
|
||||||
// deprecated methods
|
// deprecated methods
|
||||||
|
@ -1939,12 +1939,34 @@ var getOptions = function (options) {
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (options.topics)
|
if (options.topic) {
|
||||||
console.warn('"topics" is deprecated, is "topic" instead');
|
console.warn('"topic" is deprecated, is "topics" instead');
|
||||||
|
options.topics = options.topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.earliest) {
|
||||||
|
console.warn('"earliest" is deprecated, is "fromBlock" instead');
|
||||||
|
options.fromBlock = options.earliest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.latest) {
|
||||||
|
console.warn('"latest" is deprecated, is "toBlock" instead');
|
||||||
|
options.toBlock = options.latest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.skip) {
|
||||||
|
console.warn('"skip" is deprecated, is "offset" instead');
|
||||||
|
options.offset = options.skip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.max) {
|
||||||
|
console.warn('"max" is deprecated, is "limit" instead');
|
||||||
|
options.limit = options.max;
|
||||||
|
}
|
||||||
|
|
||||||
// make sure topics, get converted to hex
|
// make sure topics, get converted to hex
|
||||||
if(options.topic instanceof Array) {
|
if(options.topics instanceof Array) {
|
||||||
options.topic = options.topic.map(function(topic){
|
options.topics = options.topics.map(function(topic){
|
||||||
return utils.toHex(topic);
|
return utils.toHex(topic);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1952,13 +1974,13 @@ var getOptions = function (options) {
|
||||||
|
|
||||||
// evaluate lazy properties
|
// evaluate lazy properties
|
||||||
return {
|
return {
|
||||||
|
fromBlock: utils.toHex(options.fromBlock),
|
||||||
|
toBlock: utils.toHex(options.toBlock),
|
||||||
|
limit: utils.toHex(options.limit),
|
||||||
|
offset: utils.toHex(options.offset),
|
||||||
to: options.to,
|
to: options.to,
|
||||||
topic: options.topic,
|
address: options.address,
|
||||||
earliest: options.earliest,
|
topics: options.topics
|
||||||
latest: options.latest,
|
|
||||||
max: options.max,
|
|
||||||
skip: options.skip,
|
|
||||||
address: options.address
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2269,6 +2291,7 @@ if ("build" !== 'build') {/*
|
||||||
*/}
|
*/}
|
||||||
|
|
||||||
var HttpProvider = function (host) {
|
var HttpProvider = function (host) {
|
||||||
|
this.name = 'HTTP';
|
||||||
this.handlers = [];
|
this.handlers = [];
|
||||||
this.host = host || 'http://localhost:8080';
|
this.host = host || 'http://localhost:8080';
|
||||||
};
|
};
|
||||||
|
@ -2280,8 +2303,14 @@ HttpProvider.prototype.send = function (payload, callback) {
|
||||||
// ASYNC
|
// ASYNC
|
||||||
if(typeof callback === 'function') {
|
if(typeof callback === 'function') {
|
||||||
request.onreadystatechange = function() {
|
request.onreadystatechange = function() {
|
||||||
if(request.readyState === 4 && request.status === 200) {
|
if(request.readyState === 4) {
|
||||||
callback(JSON.parse(request.responseText));
|
var result = '';
|
||||||
|
try {
|
||||||
|
result = JSON.parse(request.responseText)
|
||||||
|
} catch(error) {
|
||||||
|
result = error;
|
||||||
|
}
|
||||||
|
callback(result, request.status);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2518,19 +2547,26 @@ var requestManager = function() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ASYNC (only when callback is given, and it a HttpProvidor)
|
// HTTP ASYNC (only when callback is given, and it a HttpProvidor)
|
||||||
if(typeof callback === 'function' && provider.host){
|
if(typeof callback === 'function' && provider.name === 'HTTP'){
|
||||||
provider.send(payload, function(result){
|
provider.send(payload, function(result, status){
|
||||||
|
|
||||||
if (!jsonrpc.isValidResponse(result)) {
|
if (!jsonrpc.isValidResponse(result)) {
|
||||||
console.log(result);
|
if(typeof result === 'object' && result.error && result.error.message) {
|
||||||
if(typeof result === 'object' && result.error && result.error.message)
|
|
||||||
console.error(result.error.message);
|
console.error(result.error.message);
|
||||||
|
callback(result.error);
|
||||||
|
} else {
|
||||||
|
callback(new Error({
|
||||||
|
status: status,
|
||||||
|
error: result,
|
||||||
|
message: 'Bad Request'
|
||||||
|
}));
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// format the output
|
// format the output
|
||||||
callback((typeof data.outputFormatter === 'function') ? data.outputFormatter(result.result) : result.result);
|
callback(null, (typeof data.outputFormatter === 'function') ? data.outputFormatter(result.result) : result.result);
|
||||||
});
|
});
|
||||||
|
|
||||||
// SYNC
|
// SYNC
|
||||||
|
|
|
@ -165,7 +165,7 @@ func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) erro
|
||||||
id = self.filterManager.InstallFilter(filter)
|
id = self.filterManager.InstallFilter(filter)
|
||||||
self.logs[id] = &logFilter{timeout: time.Now()}
|
self.logs[id] = &logFilter{timeout: time.Now()}
|
||||||
|
|
||||||
*reply = id
|
*reply = i2hex(id)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,7 @@ func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error {
|
||||||
|
|
||||||
func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
|
func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
|
||||||
// Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC
|
// Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC
|
||||||
rpclogger.DebugDetailf("%T %s", req.Params, req.Params)
|
rpclogger.Infof("%s %s", req.Method, req.Params)
|
||||||
switch req.Method {
|
switch req.Method {
|
||||||
case "web3_sha3":
|
case "web3_sha3":
|
||||||
args := new(Sha3Args)
|
args := new(Sha3Args)
|
||||||
|
@ -446,7 +446,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return p.GetBalance(args, reply)
|
return p.GetBalance(args, reply)
|
||||||
case "eth_getStorage":
|
case "eth_getStorage", "eth_storageAt":
|
||||||
// TODO handle BlockNumber
|
// TODO handle BlockNumber
|
||||||
args := new(GetStorageArgs)
|
args := new(GetStorageArgs)
|
||||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||||
|
|
136
rpc/args.go
136
rpc/args.go
|
@ -3,32 +3,26 @@ package rpc
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Unmarshal state is a helper method which has the ability to decode messsages
|
func blockNumber(raw json.RawMessage, number *int64) (err error) {
|
||||||
// that use the `defaultBlock` (https://github.com/ethereum/wiki/wiki/JSON-RPC#the-default-block-parameter)
|
var str string
|
||||||
// For example a `call`: [{to: "0x....", data:"0x..."}, "latest"]. The first argument is the transaction
|
if err = json.Unmarshal(raw, &str); err != nil {
|
||||||
// message and the second one refers to the block height (or state) to which to apply this `call`.
|
|
||||||
func unmarshalState(b []byte, iface interface{}, str *string) (err error) {
|
|
||||||
var data []json.RawMessage
|
|
||||||
if err = json.Unmarshal(b, &data); err != nil && len(data) == 0 {
|
|
||||||
return errDecodeArgs
|
return errDecodeArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = json.Unmarshal(data[0], iface); err != nil {
|
switch str {
|
||||||
return errDecodeArgs
|
case "latest":
|
||||||
|
*number = -1
|
||||||
|
case "pending":
|
||||||
|
*number = 0
|
||||||
|
default:
|
||||||
|
*number = ethutil.String2Big(str).Int64()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second argument is optional (transact doesn't require it)
|
|
||||||
if len(data) > 1 {
|
|
||||||
if err = json.Unmarshal(data[1], str); err != nil {
|
|
||||||
return errDecodeArgs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,20 +82,12 @@ type NewTxArgs struct {
|
||||||
GasPrice *big.Int
|
GasPrice *big.Int
|
||||||
Data string
|
Data string
|
||||||
|
|
||||||
BlockHeight string
|
BlockNumber int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj struct {
|
var obj struct{ From, To, Value, Gas, GasPrice, Data string }
|
||||||
From string `json:"from"`
|
if err = UnmarshalRawMessages(b, &obj, &args.BlockNumber); err != nil {
|
||||||
To string `json:"to"`
|
|
||||||
Value string `json:"value"`
|
|
||||||
Gas string `json:"gas"`
|
|
||||||
GasPrice string `json:"gasPrice"`
|
|
||||||
Data string `json:"data"`
|
|
||||||
}
|
|
||||||
var height string
|
|
||||||
if err = unmarshalState(b, &obj, &height); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +97,6 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
args.Gas = ethutil.Big(obj.Gas)
|
args.Gas = ethutil.Big(obj.Gas)
|
||||||
args.GasPrice = ethutil.Big(obj.GasPrice)
|
args.GasPrice = ethutil.Big(obj.GasPrice)
|
||||||
args.Data = obj.Data
|
args.Data = obj.Data
|
||||||
args.BlockHeight = height
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -122,24 +107,10 @@ type GetStorageArgs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
|
||||||
r := bytes.NewReader(b)
|
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return errDecodeArgs
|
return errDecodeArgs
|
||||||
}
|
}
|
||||||
|
fmt.Println(args)
|
||||||
if len(obj) < 1 {
|
|
||||||
return errArguments
|
|
||||||
}
|
|
||||||
args.Address = obj[0].(string)
|
|
||||||
|
|
||||||
if len(obj) > 1 {
|
|
||||||
if obj[1].(string) == "latest" {
|
|
||||||
args.BlockNumber = -1
|
|
||||||
} else {
|
|
||||||
args.BlockNumber = ethutil.Big(obj[1].(string)).Int64()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -158,25 +129,18 @@ type GetStorageAtArgs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
var obj []string
|
||||||
r := bytes.NewReader(b)
|
if err = UnmarshalRawMessages(b, &obj, &args.BlockNumber); err != nil {
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
return errDecodeArgs
|
||||||
|
}
|
||||||
|
if len(obj) < 2 {
|
||||||
return errDecodeArgs
|
return errDecodeArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(obj) < 2 {
|
args.Address = obj[0]
|
||||||
return errArguments
|
args.Key = obj[1]
|
||||||
}
|
|
||||||
args.Address = obj[0].(string)
|
|
||||||
args.Key = obj[1].(string)
|
|
||||||
|
|
||||||
if len(obj) > 2 {
|
fmt.Println(args)
|
||||||
if obj[2].(string) == "latest" {
|
|
||||||
args.BlockNumber = -1
|
|
||||||
} else {
|
|
||||||
args.BlockNumber = ethutil.Big(obj[2].(string)).Int64()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -198,26 +162,10 @@ type GetTxCountArgs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
|
||||||
r := bytes.NewReader(b)
|
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return errDecodeArgs
|
return errDecodeArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(obj) < 1 {
|
|
||||||
return errArguments
|
|
||||||
|
|
||||||
}
|
|
||||||
args.Address = obj[0].(string)
|
|
||||||
|
|
||||||
if len(obj) > 1 {
|
|
||||||
if obj[1].(string) == "latest" {
|
|
||||||
args.BlockNumber = -1
|
|
||||||
} else {
|
|
||||||
args.BlockNumber = ethutil.Big(obj[1].(string)).Int64()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,25 +182,10 @@ type GetBalanceArgs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
|
||||||
r := bytes.NewReader(b)
|
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return errDecodeArgs
|
return errDecodeArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(obj) < 1 {
|
|
||||||
return errArguments
|
|
||||||
}
|
|
||||||
args.Address = obj[0].(string)
|
|
||||||
|
|
||||||
if len(obj) > 1 {
|
|
||||||
if obj[1].(string) == "latest" {
|
|
||||||
args.BlockNumber = -1
|
|
||||||
} else {
|
|
||||||
args.BlockNumber = ethutil.Big(obj[1].(string)).Int64()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,25 +202,10 @@ type GetDataArgs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
|
func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
var obj []interface{}
|
if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
|
||||||
r := bytes.NewReader(b)
|
|
||||||
if err := json.NewDecoder(r).Decode(&obj); err != nil {
|
|
||||||
return errDecodeArgs
|
return errDecodeArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(obj) < 1 {
|
|
||||||
return errArguments
|
|
||||||
}
|
|
||||||
args.Address = obj[0].(string)
|
|
||||||
|
|
||||||
if len(obj) > 1 {
|
|
||||||
if obj[1].(string) == "latest" {
|
|
||||||
args.BlockNumber = -1
|
|
||||||
} else {
|
|
||||||
args.BlockNumber = ethutil.Big(obj[1].(string)).Int64()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
61
rpc/util.go
61
rpc/util.go
|
@ -18,8 +18,11 @@ package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
|
@ -32,6 +35,60 @@ var rpclogger = logger.NewLogger("RPC")
|
||||||
|
|
||||||
type JsonWrapper struct{}
|
type JsonWrapper struct{}
|
||||||
|
|
||||||
|
// Unmarshal state is a helper method which has the ability to decode messsages
|
||||||
|
// that use the `defaultBlock` (https://github.com/ethereum/wiki/wiki/JSON-RPC#the-default-block-parameter)
|
||||||
|
// For example a `call`: [{to: "0x....", data:"0x..."}, "latest"]. The first argument is the transaction
|
||||||
|
// message and the second one refers to the block height (or state) to which to apply this `call`.
|
||||||
|
func UnmarshalRawMessages(b []byte, iface interface{}, number *int64) (err error) {
|
||||||
|
var data []json.RawMessage
|
||||||
|
if err = json.Unmarshal(b, &data); err != nil && len(data) == 0 {
|
||||||
|
return errDecodeArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number index determines the index in the array for a possible block number
|
||||||
|
numberIndex := 0
|
||||||
|
|
||||||
|
value := reflect.ValueOf(iface)
|
||||||
|
rvalue := reflect.Indirect(value)
|
||||||
|
|
||||||
|
switch rvalue.Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
// This is a bit of a cheat, but `data` is expected to be larger than 2 if iface is a slice
|
||||||
|
if number != nil {
|
||||||
|
numberIndex = len(data) - 1
|
||||||
|
} else {
|
||||||
|
numberIndex = len(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
slice := reflect.MakeSlice(rvalue.Type(), numberIndex, numberIndex)
|
||||||
|
for i, raw := range data[0:numberIndex] {
|
||||||
|
v := slice.Index(i).Interface()
|
||||||
|
if err = json.Unmarshal(raw, &v); err != nil {
|
||||||
|
fmt.Println(err, v)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
slice.Index(i).Set(reflect.ValueOf(v))
|
||||||
|
}
|
||||||
|
reflect.Indirect(rvalue).Set(slice) //value.Set(slice)
|
||||||
|
case reflect.Struct:
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
if err = json.Unmarshal(data[0], iface); err != nil {
|
||||||
|
return errDecodeArgs
|
||||||
|
}
|
||||||
|
numberIndex = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// <0 index means out of bound for block number
|
||||||
|
if numberIndex >= 0 && len(data) > numberIndex {
|
||||||
|
if err = blockNumber(data[numberIndex], number); err != nil {
|
||||||
|
return errDecodeArgs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (self JsonWrapper) Send(writer io.Writer, v interface{}) (n int, err error) {
|
func (self JsonWrapper) Send(writer io.Writer, v interface{}) (n int, err error) {
|
||||||
var payload []byte
|
var payload []byte
|
||||||
payload, err = json.Marshal(v)
|
payload, err = json.Marshal(v)
|
||||||
|
@ -80,6 +137,10 @@ func fromHex(s string) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func i2hex(n int) string {
|
||||||
|
return toHex(big.NewInt(int64(n)).Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
type RpcServer interface {
|
type RpcServer interface {
|
||||||
Start()
|
Start()
|
||||||
Stop()
|
Stop()
|
||||||
|
|
Loading…
Reference in New Issue