Commit e1571472 authored by Fefe's avatar Fefe

Now using github.com/obscuren/otto, no need for an Ethereum object

(got rid of some messy code in test)
parent b67ded9f
package natspec package natspec
import ( import (
// "encoding/json" "github.com/obscuren/otto"
// "fmt"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/javascript"
"io/ioutil" "io/ioutil"
) )
type NatSpec struct { type NatSpec struct {
jsre *javascript.JSRE jsvm *otto.Otto
} }
func NewNATSpec(ethereum *eth.Ethereum, transaction string) (self *NatSpec, err error) { func NewNATSpec(transaction string) (self *NatSpec, err error) {
self = new(NatSpec) self = new(NatSpec)
self.jsre = javascript.NewJSRE(ethereum) self.jsvm = otto.New()
//self.jsre.LoadExtFile("/home/fefe/go-ethereum/ethutil/natspec/natspec.js")
code, err := ioutil.ReadFile("natspec.js") code, err := ioutil.ReadFile("natspec.js")
if err != nil { if err != nil {
return return
} }
_, err = self.jsre.Run(string(code)) _, err = self.jsvm.Run(string(code))
if err != nil { if err != nil {
return return
} }
_, err = self.jsre.Run("var natspec = require('natspec');") _, err = self.jsvm.Run("var natspec = require('natspec');")
if err != nil { if err != nil {
return return
} }
self.jsre.Run("var transaction = " + transaction + ";") self.jsvm.Run("var transaction = " + transaction + ";")
return return
} }
func (self *NatSpec) SetDescription(desc string) (err error) { func (self *NatSpec) SetDescription(desc string) (err error) {
_, err = self.jsre.Run("var expression = \"" + desc + "\";") _, err = self.jsvm.Run("var expression = \"" + desc + "\";")
return return
} }
func (self *NatSpec) SetABI(abi string) (err error) { func (self *NatSpec) SetABI(abi string) (err error) {
_, err = self.jsre.Run("var abi = " + abi + ";") _, err = self.jsvm.Run("var abi = " + abi + ";")
return return
} }
func (self *NatSpec) SetMethod(method string) (err error) { func (self *NatSpec) SetMethod(method string) (err error) {
_, err = self.jsre.Run("var method = '" + method + "';") _, err = self.jsvm.Run("var method = '" + method + "';")
return return
} }
func (self *NatSpec) Parse() string { func (self *NatSpec) Parse() string {
self.jsre.Run("var call = {method: method,abi: abi,transaction: transaction};") self.jsvm.Run("var call = {method: method,abi: abi,transaction: transaction};")
value, err := self.jsre.Run("natspec.evaluateExpression(expression, call);") value, err := self.jsvm.Run("natspec.evaluateExpression(expression, call);")
if err != nil { if err != nil {
return err.Error() return err.Error()
} }
......
...@@ -1824,10 +1824,6 @@ module.exports = { ...@@ -1824,10 +1824,6 @@ module.exports = {
// Handle values that fail the validity test in BigNumber. // Handle values that fail the validity test in BigNumber.
// Zsolt Felfoldi 15/03/06
// modified regexps in order to compile with go JSRE
parseNumeric = (function () { parseNumeric = (function () {
// var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i, // var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i,
var basePrefix = /^(-?)0([xbo])/i, var basePrefix = /^(-?)0([xbo])/i,
...@@ -1838,7 +1834,6 @@ module.exports = { ...@@ -1838,7 +1834,6 @@ module.exports = {
whitespaceOrPlus = /^\s*\+[\w.]|^\s+|\s+$/g; whitespaceOrPlus = /^\s*\+[\w.]|^\s+|\s+$/g;
return function ( x, str, num, b ) { return function ( x, str, num, b ) {
var base, var base,
s = num ? str : str.replace( whitespaceOrPlus, '' ); s = num ? str : str.replace( whitespaceOrPlus, '' );
...@@ -3387,7 +3382,6 @@ module.exports = { ...@@ -3387,7 +3382,6 @@ module.exports = {
})(this); })(this);
},{"crypto":1}],"natspec":[function(require,module,exports){ },{"crypto":1}],"natspec":[function(require,module,exports){
(function (global){
/* /*
This file is part of natspec.js. This file is part of natspec.js.
...@@ -3418,31 +3412,18 @@ var abi = require('./node_modules/ethereum.js/lib/abi.js'); ...@@ -3418,31 +3412,18 @@ var abi = require('./node_modules/ethereum.js/lib/abi.js');
*/ */
var natspec = (function () { var natspec = (function () {
/// Helper method /// Helper method
/// Modifications by Zsolt Felfoldi, 15/03/06 /// Should be called to copy values from object to global context
/// eval() under go JSRE is unable to reach variables that
/// are added to the global context runtime, so now we
/// create a variable assignment code for each param
/// and run in an isolated function(context)
/// variable assignment code is returned by copyToContext
var copyToContext = function (obj, context) { var copyToContext = function (obj, context) {
var code = ""; Object.keys(obj).forEach(function (key) {
var keys = Object.keys(obj);
keys.forEach(function (key) {
context[key] = obj[key]; context[key] = obj[key];
code = code + "var "+key+" = context['"+key+"'];\n";
}); });
return code;
} }
/// this function will not be used in 'production' natspec evaluation /// generate codes, which will be evaluated
/// it's only used to enable tests in node environment var generateCode = function (obj) {
/// it copies all functions from current context to nodejs global context return Object.keys(obj).reduce(function (acc, key) {
var copyToNodeGlobal = function (obj) { return acc + "var " + key + " = context['" + key + "'];\n";
if (typeof global === 'undefined') { }, "");
return;
}
copyToContext(obj, global);
}; };
/// Helper method /// Helper method
...@@ -3455,25 +3436,38 @@ var natspec = (function () { ...@@ -3455,25 +3436,38 @@ var natspec = (function () {
})[0]; })[0];
}; };
/// Function called to get all contract's storage values
/// @returns hashmap with contract properties which are used
/// TODO: check if this function will be used
var getContractProperties = function (address, abi) {
return {};
};
/// Function called to get all contract method input variables /// Function called to get all contract method input variables
/// @returns hashmap with all contract's method input variables /// @returns hashmap with all contract's method input variables
var getMethodInputParams = function (method, transaction) { var getMethodInputParams = function (method, transaction) {
// do it with output formatter (cause we have to decode) // do it with output formatter (cause we have to decode)
var params = abi.formatOutput(method.inputs, '0x' + transaction.params[0].data.slice(10)); var params = abi.formatOutput(method.inputs, '0x' + transaction.params[0].data.slice(10));
return method.inputs.reduce(function (acc, current, index) { return method.inputs.reduce(function (acc, current, index) {
acc[current.name] = params[index]; acc[current.name] = params[index];
return acc; return acc;
}, {}); }, {});
};
/// Should be called to evaluate expression
var mapExpressionsToEvaluate = function (expression, cb) {
var evaluatedExpression = "";
// match everything in `` quotes
var pattern = /\`(?:\\.|[^`\\])*\`/gim
var match;
var lastIndex = 0;
while ((match = pattern.exec(expression)) !== null) {
var startIndex = pattern.lastIndex - match[0].length;
var toEval = match[0].slice(1, match[0].length - 1);
evaluatedExpression += expression.slice(lastIndex, startIndex);
var evaluatedPart = cb(toEval);
evaluatedExpression += evaluatedPart;
lastIndex = pattern.lastIndex;
}
evaluatedExpression += expression.slice(lastIndex);
return evaluatedExpression;
}; };
/// Should be called to evaluate single expression /// Should be called to evaluate single expression
...@@ -3482,53 +3476,31 @@ var natspec = (function () { ...@@ -3482,53 +3476,31 @@ var natspec = (function () {
/// @param [call] object containing contract abi, transaction, called method /// @param [call] object containing contract abi, transaction, called method
/// TODO: separate evaluation from getting input params, so as not to spoil 'evaluateExpression' function /// TODO: separate evaluation from getting input params, so as not to spoil 'evaluateExpression' function
var evaluateExpression = function (expression, call) { var evaluateExpression = function (expression, call) {
//var self = this;
var self = this; var context = {};
var code = "";
var context = [];
if (!!call) { if (!!call) {
try { try {
var method = getMethodWithName(call.abi, call.method); var method = getMethodWithName(call.abi, call.method);
var params = getMethodInputParams(method, call.transaction); var params = getMethodInputParams(method, call.transaction);
code = copyToContext(params, context); // see copyToContext comments copyToContext(params, context);
} }
catch (err) { catch (err) {
return "Natspec evaluation failed, wrong input params"; return "Natspec evaluation failed, wrong input params";
} }
} }
// used only for tests var code = generateCode(context);
copyToNodeGlobal(context);
var evaluatedExpression = "";
// match everything in `` quotes
var pattern = /\`(?:\\.|[^`\\])*\`/gim
var match;
var lastIndex = 0;
while ((match = pattern.exec(expression)) !== null) {
var startIndex = pattern.lastIndex - match[0].length;
var toEval = match[0].slice(1, match[0].length - 1);
evaluatedExpression += expression.slice(lastIndex, startIndex);
var evaluatedPart; var evaluatedExpression = mapExpressionsToEvaluate(expression, function (toEval) {
try { try {
var fn = new Function("context", code + "return "+toEval+";"); var fn = new Function("context", code + "return " + toEval + ";");
evaluatedPart = fn(context).toString(); // see copyToContext comments return fn(context).toString();
// evaluatedPart = eval(toEval).toString();
} }
catch (err) { catch (err) {
evaluatedPart = 'undefined'; return 'undefined';
}
evaluatedExpression += evaluatedPart;
lastIndex = pattern.lastIndex;
} }
});
evaluatedExpression += expression.slice(lastIndex);
return evaluatedExpression; return evaluatedExpression;
}; };
...@@ -3542,5 +3514,4 @@ var natspec = (function () { ...@@ -3542,5 +3514,4 @@ var natspec = (function () {
module.exports = natspec; module.exports = natspec;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./node_modules/ethereum.js/lib/abi.js":3}]},{},[]); },{"./node_modules/ethereum.js/lib/abi.js":3}]},{},[]);
package natspec package natspec
import ( import (
"flag"
// "crypto/rand"
// "io/ioutil"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/eth"
"testing" "testing"
) )
const (
ClientIdentifier = "Ethereum(G)"
Version = "0.8.1"
)
var (
Identifier string
KeyRing string
DiffTool bool
DiffType string
KeyStore string
StartRpc bool
StartWebSockets bool
RpcPort int
NatType string
PMPGateway string
OutboundPort string
ShowGenesis bool
AddPeer string
MaxPeer int
GenAddr bool
UseSeed bool
SecretFile string
ExportDir string
NonInteractive bool
Datadir string
LogFile string
ConfigFile string
DebugFile string
LogLevel int
Dump bool
DumpHash string
DumpNumber int
VmType int
ImportChain string
SHH bool
Dial bool
PrintVersion bool
)
func Init() {
/* flag.Usage = func() {
fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line\n", os.Args[0])
flag.PrintDefaults()
}*/
flag.IntVar(&VmType, "vm", 0, "Virtual Machine type: 0-1: standard, debug")
flag.StringVar(&Identifier, "id", "", "Custom client identifier")
flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use")
flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)")
flag.StringVar(&OutboundPort, "port", "30303", "listening port")
flag.StringVar(&NatType, "nat", "", "NAT support (UPNP|PMP) (none)")
flag.StringVar(&PMPGateway, "pmp", "", "Gateway IP for PMP")
flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers")
flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server")
flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
flag.BoolVar(&UseSeed, "seed", true, "seed peers")
flag.BoolVar(&SHH, "shh", true, "whisper protocol (on)")
flag.BoolVar(&Dial, "dial", true, "dial out connections (on)")
flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key")
flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)")
flag.StringVar(&ExportDir, "export", "", "exports the session keyring to files in the directory given")
flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)")
flag.StringVar(&Datadir, "datadir", "", "specifies the datadir to use")
flag.StringVar(&ConfigFile, "conf", "", "config file")
flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)")
flag.IntVar(&LogLevel, "loglevel", 0, "loglevel: 0-5: silent,error,warn,info,debug,debug detail)")
flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0")
flag.StringVar(&DiffType, "diff", "all", "sets the level of diff output [vm, all]. Has no effect if difftool=false")
flag.BoolVar(&ShowGenesis, "genesis", false, "Dump the genesis block")
flag.StringVar(&ImportChain, "chain", "", "Imports given chain")
flag.BoolVar(&Dump, "dump", false, "output the ethereum state in JSON format. Sub args [number, hash]")
flag.StringVar(&DumpHash, "hash", "", "specify arg in hex")
flag.IntVar(&DumpNumber, "number", -1, "specify arg in number")
/* flag.BoolVar(&StartMining, "mine", false, "start dagger mining")
flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console")
flag.BoolVar(&PrintVersion, "version", false, "prints version number")*/
flag.Parse()
}
func TestNotice(t *testing.T) { func TestNotice(t *testing.T) {
Init() ns, err := NewNATSpec(`
utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
ethereum, _ := eth.New(&eth.Config{
Name: ClientIdentifier,
Version: Version,
KeyStore: KeyStore,
DataDir: Datadir,
LogFile: LogFile,
LogLevel: LogLevel,
Identifier: Identifier,
MaxPeers: MaxPeer,
Port: OutboundPort,
NATType: PMPGateway,
PMPGateway: PMPGateway,
KeyRing: KeyRing,
Shh: SHH,
Dial: Dial,
})
ns, err := NewNATSpec(ethereum, `
{ {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "eth_call", "method": "eth_call",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment