natspec for poc-9
- put natspec.js in a heredoc string (to help binary) - constructor takes no args, just sets up js vm - API: only exports Notice(transaction, abi, method, expression string) (string, error) - effort to turn natspec.js error strings to proper go errors - test errors
This commit is contained in:
		
							parent
							
								
									07955b3041
								
							
						
					
					
						commit
						97dc4edb45
					
				| @ -1,24 +1,21 @@ | ||||
| package natspec | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/obscuren/otto" | ||||
| 	"io/ioutil" | ||||
| ) | ||||
| 
 | ||||
| type NatSpec struct { | ||||
| 	jsvm *otto.Otto | ||||
| } | ||||
| 
 | ||||
| func NewNATSpec(transaction string) (self *NatSpec, err error) { | ||||
| // TODO: should initialise with abi and userdoc jsons
 | ||||
| func NewNATSpec() (self *NatSpec, err error) { | ||||
| 
 | ||||
| 	self = new(NatSpec) | ||||
| 	self.jsvm = otto.New() | ||||
| 	code, err := ioutil.ReadFile("natspec.js") | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	_, err = self.jsvm.Run(string(code)) | ||||
| 	_, err = self.jsvm.Run(natspecJS) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| @ -27,39 +24,40 @@ func NewNATSpec(transaction string) (self *NatSpec, err error) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	self.jsvm.Run("var transaction = " + transaction + ";") | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (self *NatSpec) SetDescription(desc string) (err error) { | ||||
| func (self *NatSpec) Notice(transaction, abi, method, expression string) (string, error) { | ||||
| 	var err error | ||||
| 	if _, err = self.jsvm.Run("var transaction = " + transaction + ";"); err != nil { | ||||
| 		return "", fmt.Errorf("natspec.js error setting transaction: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	_, err = self.jsvm.Run("var expression = \"" + desc + "\";") | ||||
| 	return | ||||
| 	if _, err = self.jsvm.Run("var abi = " + abi + ";"); err != nil { | ||||
| 		return "", fmt.Errorf("natspec.js error setting abi: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 	if _, err = self.jsvm.Run("var method = '" + method + "';"); err != nil { | ||||
| 		return "", fmt.Errorf("natspec.js error setting method: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| func (self *NatSpec) SetABI(abi string) (err error) { | ||||
| 
 | ||||
| 	_, err = self.jsvm.Run("var abi = " + abi + ";") | ||||
| 	return | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func (self *NatSpec) SetMethod(method string) (err error) { | ||||
| 
 | ||||
| 	_, err = self.jsvm.Run("var method = '" + method + "';") | ||||
| 	return | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func (self *NatSpec) Parse() string { | ||||
| 	if _, err = self.jsvm.Run("var expression = \"" + expression + "\";"); err != nil { | ||||
| 		return "", fmt.Errorf("natspec.js error setting expression: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	self.jsvm.Run("var call = {method: method,abi: abi,transaction: transaction};") | ||||
| 	value, err := self.jsvm.Run("natspec.evaluateExpression(expression, call);") | ||||
| 	if err != nil { | ||||
| 		return err.Error() | ||||
| 		return "", fmt.Errorf("natspec.js error evaluating expression: %v", err) | ||||
| 	} | ||||
| 	return value.String() | ||||
| 	evalError := "Natspec evaluation failed, wrong input params" | ||||
| 	if value.String() == evalError { | ||||
| 		return "", fmt.Errorf("natspec.js error evaluating expression: wrong input params in expression '%s'", expression) | ||||
| 	} | ||||
| 	if len(value.String()) == 0 { | ||||
| 		return "", fmt.Errorf("natspec.js error evaluating expression") | ||||
| 	} | ||||
| 
 | ||||
| 	return value.String(), nil | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,6 @@ | ||||
| require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||||
| package natspec | ||||
| 
 | ||||
| const natspecJS = `require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||||
| 
 | ||||
| },{}],2:[function(require,module,exports){ | ||||
| // shim for using process in browser
 | ||||
| @ -3452,8 +3454,8 @@ var natspec = (function () { | ||||
|     var mapExpressionsToEvaluate = function (expression, cb) { | ||||
|         var evaluatedExpression = ""; | ||||
| 
 | ||||
|         // match everything in `` quotes
 | ||||
|         var pattern = /\`(?:\\.|[^`\\])*\`/gim | ||||
|         // match everything in backtick
 | ||||
|         var pattern = /\` + "`" + `(?:\\.|[^` + "`" + `\\])*\` + "`" + `/gim | ||||
|         var match; | ||||
|         var lastIndex = 0; | ||||
|         while ((match = pattern.exec(expression)) !== null) { | ||||
| @ -3515,3 +3517,4 @@ module.exports = natspec; | ||||
| 
 | ||||
| 
 | ||||
| },{"./node_modules/ethereum.js/lib/abi.js":3}]},{},[]); | ||||
| ` | ||||
| @ -6,41 +6,48 @@ import ( | ||||
| 
 | ||||
| func TestNotice(t *testing.T) { | ||||
| 
 | ||||
| 	ns, err := NewNATSpec(` | ||||
| 	tx := ` | ||||
| 	{ | ||||
|             "jsonrpc": "2.0", | ||||
|             "method": "eth_call", | ||||
|             "params": [{ | ||||
|                 "to": "0x8521742d3f456bd237e312d6e30724960f72517a", | ||||
|                 "data": "0xc6888fa1000000000000000000000000000000000000000000000000000000000000007a" | ||||
|             }], | ||||
|             "id": 6 | ||||
|         } | ||||
| 	`) | ||||
|     "jsonrpc": "2.0", | ||||
|     "method": "eth_call", | ||||
|     "params": [{ | ||||
|         "to": "0x8521742d3f456bd237e312d6e30724960f72517a", | ||||
|         "data": "0xc6888fa1000000000000000000000000000000000000000000000000000000000000007a" | ||||
|     }], | ||||
|     "id": 6 | ||||
|   } | ||||
| 	` | ||||
| 
 | ||||
| 	abi := ` | ||||
| 	[{ | ||||
|     "name": "multiply", | ||||
|     "constant": false, | ||||
|     "type": "function", | ||||
|     "inputs": [{ | ||||
|       "name": "a", | ||||
|       "type": "uint256" | ||||
|     }], | ||||
|     "outputs": [{ | ||||
|       "name": "d", | ||||
|       "type": "uint256" | ||||
|     }] | ||||
|   }] | ||||
| 	` | ||||
| 
 | ||||
| 	desc := "Will multiply `a` by 7 and return `a * 7`." | ||||
| 
 | ||||
| 	method := "multiply" | ||||
| 
 | ||||
| 	ns, err := NewNATSpec() | ||||
| 	if err != nil { | ||||
| 		t.Errorf("NewNATSpec error %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	ns.SetABI(` | ||||
| 	[{ | ||||
|             "name": "multiply", | ||||
|             "constant": false, | ||||
|             "type": "function", | ||||
|             "inputs": [{ | ||||
|                 "name": "a", | ||||
|                 "type": "uint256" | ||||
|             }], | ||||
|             "outputs": [{ | ||||
|                 "name": "d", | ||||
|                 "type": "uint256" | ||||
|             }] | ||||
|         }] | ||||
| 	`) | ||||
| 	ns.SetDescription("Will multiply `a` by 7 and return `a * 7`.") | ||||
| 	ns.SetMethod("multiply") | ||||
| 	notice, err := ns.Notice(tx, abi, method, desc) | ||||
| 
 | ||||
| 	notice := ns.Parse() | ||||
| 	if err != nil { | ||||
| 		t.Errorf("expected no error got %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	expected := "Will multiply 122 by 7 and return 854." | ||||
| 	if notice != expected { | ||||
| @ -48,4 +55,42 @@ func TestNotice(t *testing.T) { | ||||
| 	} else { | ||||
| 		t.Logf("returned notice \"%v\"", notice) | ||||
| 	} | ||||
| 
 | ||||
| 	notice, err = ns.Notice(tx, abi, method, "Will multiply 122 by \"7\" and return 854.") | ||||
| 
 | ||||
| 	expected = "natspec.js error setting expression: (anonymous): Line 1:41 Unexpected number" | ||||
| 
 | ||||
| 	if err == nil { | ||||
| 		t.Errorf("expected error, got nothing (notice: '%v')", err, notice) | ||||
| 	} else { | ||||
| 		if err.Error() != expected { | ||||
| 			t.Errorf("expected error '%s' got '%v' (notice: '%v')", expected, err, notice) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// badDesc := "Will multiply `e` by 7 and return `a * 7`."
 | ||||
| 	// notice, err = ns.Notice(tx, abi, method, badDesc)
 | ||||
| 
 | ||||
| 	// expected = "natspec.js error evaluating expression: wrong input param in expression ''"
 | ||||
| 
 | ||||
| 	// if err == nil {
 | ||||
| 	// 	t.Errorf("expected error, got nothing (notice: '%v')", notice)
 | ||||
| 	// } else {
 | ||||
| 	// 	if err.Error() != expected {
 | ||||
| 	// 		t.Errorf("expected error '%s' got '%v' (notice: '%v')", expected, err, notice)
 | ||||
| 	// 	}
 | ||||
| 	// }
 | ||||
| 
 | ||||
| 	notice, err = ns.Notice(tx, abi, "missing_method", desc) | ||||
| 
 | ||||
| 	expected = "natspec.js error evaluating expression: wrong input params in expression 'Will multiply `a` by 7 and return `a * 7`.'" | ||||
| 
 | ||||
| 	if err == nil { | ||||
| 		t.Errorf("expected error, got nothing (notice: '%v')", notice) | ||||
| 	} else { | ||||
| 		if err.Error() != expected { | ||||
| 			t.Errorf("expected error '%s' got '%v' (notice: '%v')", expected, err, notice) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user