diff --git a/neo/api/JSONRPC/JsonRpcApi.py b/neo/api/JSONRPC/JsonRpcApi.py index ad3a2dbad..8da69ac94 100644 --- a/neo/api/JSONRPC/JsonRpcApi.py +++ b/neo/api/JSONRPC/JsonRpcApi.py @@ -7,6 +7,7 @@ * http://www.jsonrpc.org/specification """ import json +import base58 import random from json.decoder import JSONDecodeError @@ -118,6 +119,26 @@ def home(self, request): error = JsonRpcError.internalError(str(e)) return self.get_custom_error_payload(request_id, error.code, error.message) + def parse_uint_str(self, param): + if param[0:2] == '0x': + return param[2:] + return param + + def validateaddress(self, params): + # check for [] parameter or [""] + if not params or params[0] == '': + raise JsonRpcError(-100, "Missing argument") + + isValid = False + try: + data = base58.b58decode_check(params[0]) + if len(data) == 21 and data[0] == settings.ADDRESS_VERSION: + isValid = True + except Exception as e: + pass + + return {"address": params[0], "isvalid": isValid} + def json_rpc_method_handler(self, method, params): if method == "getaccountstate": @@ -229,7 +250,7 @@ def json_rpc_method_handler(self, method, params): raise NotImplementedError() elif method == "validateaddress": - raise NotImplementedError() + return self.validateaddress(params) elif method == "getpeers": raise NotImplementedError() diff --git a/neo/api/JSONRPC/neo-cli-json-rpc-docs.md b/neo/api/JSONRPC/neo-cli-json-rpc-docs.md index 030ecc533..559470a83 100644 --- a/neo/api/JSONRPC/neo-cli-json-rpc-docs.md +++ b/neo/api/JSONRPC/neo-cli-json-rpc-docs.md @@ -38,3 +38,15 @@ On MainNet there are actually entries, each of which has this format: `0xde3bc1d curl -X POST http://seed2.neo.org:20332 -H 'Content-Type: application/json' -d '{ "jsonrpc": "2.0", "id": 5, "method": "getversion", "params": [] }' { "jsonrpc": "2.0", "id": 5, "result": { "port": 20333, "nonce": 771199013, "useragent": "/NEO:2.6.0/" } } + +## `validateaddress` + curl -X POST http://seed2.neo.org:20332 -H 'Content-Type: application/json' -d '{ "jsonrpc": "2.0", "id": 5, "method": "validateaddress", "params": ["AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i"] }' + {"jsonrpc":"2.0","id":5,"result":{"address":"AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i","isvalid":true}} + +### with invalid address + curl -X POST http://seed2.neo.org:20332 -H 'Cication/json' -d '{ "jsonrpc": "2.0", "id": 5, "method": "validateaddress", "params": ["152f1muMCNa7goXYhYAQC61hxEgGacmncB"] }' + {"jsonrpc":"2.0","id":5,"result":{"address":"152f1muMCNa7goXYhYAQC61hxEgGacmncB","isvalid":false}} + +### with completely invalid argument + curl -X POST http://seed2.neo.org:20332 -H 'Content-Type: application/json' -d '{ "jsonrpc": "2.0", "id": 5, "method": "validateaddress", "params": [] }' + {"jsonrpc":"2.0","id":5,"error":{"code":-2146233086,"message":"Index was out of range. Must be non-negative and less than the size of the collection.\r\nParameter name: index"}} \ No newline at end of file diff --git a/neo/api/JSONRPC/test_json_rpc_api.py b/neo/api/JSONRPC/test_json_rpc_api.py index 908c01f4a..72093a470 100644 --- a/neo/api/JSONRPC/test_json_rpc_api.py +++ b/neo/api/JSONRPC/test_json_rpc_api.py @@ -274,6 +274,33 @@ def test_get_version(self): self.assertEqual(res["result"]["port"], 20332) self.assertEqual(res["result"]["useragent"], "/NEO-PYTHON:%s/" % __version__) + def test_validate_address(self): + # example from docs.neo.org + req = self._gen_rpc_req("validateaddress", params=["AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i"]) + mock_req = mock_request(json.dumps(req).encode("utf-8")) + res = json.loads(self.app.home(mock_req)) + self.assertTrue(res["result"]["isvalid"]) + + # example from docs.neo.org + req = self._gen_rpc_req("validateaddress", params=["152f1muMCNa7goXYhYAQC61hxEgGacmncB"]) + mock_req = mock_request(json.dumps(req).encode("utf-8")) + res = json.loads(self.app.home(mock_req)) + self.assertFalse(res["result"]["isvalid"]) + + # catch completely invalid argument + req = self._gen_rpc_req("validateaddress", params=[]) + mock_req = mock_request(json.dumps(req).encode("utf-8")) + res = json.loads(self.app.home(mock_req)) + self.assertTrue('error' in res) + self.assertEqual('Missing argument', res['error']['message']) + + # catch completely invalid argument + req = self._gen_rpc_req("validateaddress", params=[""]) + mock_req = mock_request(json.dumps(req).encode("utf-8")) + res = json.loads(self.app.home(mock_req)) + self.assertTrue('error' in res) + self.assertEqual('Missing argument', res['error']['message']) + def test_getrawtx_1(self): txid = 'cedb5c4e24b1f6fc5b239f2d1049c3229ad5ed05293c696b3740dc236c3f41b4' req = self._gen_rpc_req("getrawtransaction", params=[txid, 1])