Skip to content

Commit

Permalink
Namecoin: serialize name_op to JSON
Browse files Browse the repository at this point in the history
Also support hex name/value encoding in name_list.
  • Loading branch information
JeremyRand committed Feb 17, 2020
1 parent 8a4d8aa commit 1141bf4
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
26 changes: 20 additions & 6 deletions electrum_nmc/electrum/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ async def listunspent(self, wallet: Abstract_Wallet = None):
return coins

@command('wn')
async def name_list(self, identifier=None, wallet: Abstract_Wallet = None):
async def name_list(self, identifier=None, name_encoding='ascii', value_encoding='ascii', wallet: Abstract_Wallet = None):
"""List unspent name outputs. Returns the list of unspent name_anyupdate
outputs in your wallet."""

Expand All @@ -343,9 +343,21 @@ async def name_list(self, identifier=None, wallet: Abstract_Wallet = None):
if "name" not in name_op:
continue

# TODO: handle non-ASCII name/value encoding
name = name_op["name"].decode("ascii")
value = name_op["value"].decode("ascii")
if name_encoding == "hex":
name = name_op["name"]
elif name_encoding == "ascii":
name_bytes = bfh(name_op["name"])
name = name_bytes.decode("ascii")
else:
raise Exception("Unsupported name_encoding")

if value_encoding == "hex":
value = name_op["value"]
elif value_encoding == "ascii":
value_bytes = bfh(name_op["value"])
value = value_bytes.decode("ascii")
else:
raise Exception("Unsupported value_encoding")

# Skip this item if it doesn't match the requested identifier
if identifier is not None:
Expand All @@ -367,9 +379,9 @@ async def name_list(self, identifier=None, wallet: Abstract_Wallet = None):

result_item = {
"name": name,
"name_encoding": "ascii",
"name_encoding": name_encoding,
"value": value,
"value_encoding": "ascii",
"value_encoding": value_encoding,
"txid": txid,
"vout": vout,
"address": address,
Expand Down Expand Up @@ -1553,6 +1565,8 @@ def eval_bool(x: str) -> bool:
'allow_early': (None, "Allow submitting a name registration while its pre-registration is still pending. This increases the risk of an attacker stealing your name registration."),
'identifier': (None, "The requested name identifier"),
'value': (None, "The value to assign to the name"),
'name_encoding': (None, "Encoding for the name identifier ('ascii' or 'hex')"),
'value_encoding': (None, "Encoding for the name value ('ascii' or 'hex')"),
'trigger_txid':(None, "Broadcast the transaction when this txid reaches the specified number of confirmations"),
'trigger_name':(None, "Broadcast the transaction when this name reaches the specified number of confirmations"),
}
Expand Down
26 changes: 26 additions & 0 deletions electrum_nmc/electrum/names.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from typing import Dict

def split_name_script(decoded):
# This case happens if a script was malformed and couldn't be decoded by
# transaction.get_address_from_output_script.
Expand Down Expand Up @@ -273,6 +275,29 @@ def format_name_op(name_op):
if name_op["op"] == OP_NAME_UPDATE:
return "\tUpdate\n\t\t" + formatted_name + "\n\t\t" + formatted_value

def name_op_to_json(name_op: Dict) -> Dict[str, str]:
result = deepcopy(name_op)

op_str = {
OP_NAME_NEW: "name_new",
OP_NAME_FIRSTUPDATE: "name_firstupdate",
OP_NAME_UPDATE: "name_update",
}

result["op"] = op_str[result["op"]]

if "hash" in result:
result["hash"] = result["hash"].hex()
if "rand" in result:
result["rand"] = result["rand"].hex()
if "name" in result:
result["name"] = result["name"].hex()
result["name_encoding"] = "hex"
if "value" in result:
result["value"] = result["value"].hex()
result["value_encoding"] = "hex"

return result

def get_default_name_tx_label(wallet, tx):
for idx, o in enumerate(tx.outputs()):
Expand Down Expand Up @@ -1279,6 +1304,7 @@ def add_domain_record_import(value, data):


import binascii
from copy import deepcopy
from datetime import datetime, timedelta
import json
import os
Expand Down
8 changes: 3 additions & 5 deletions electrum_nmc/electrum/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,9 @@ def __ne__(self, other):

def to_json(self):
d = {
# TODO: Namecoin: Convert all name_op fields to JSON
'scriptpubkey': self.scriptpubkey.hex(),
'address': self.address,
'name_op': self.name_op,
'name_op': name_op_to_json(self.name_op) if self.name_op else None,
'value_sats': self.value,
}
return d
Expand Down Expand Up @@ -1131,11 +1130,10 @@ def __init__(self, *args, **kwargs):
def to_json(self):
d = super().to_json()
d.update({
# TODO: Namecoin: Convert all name_op fields to JSON
'height': self.block_height,
'value_sats': self.value_sats(),
'address': self.address,
'name_op': self.name_op,
'name_op': name_op_to_json(self.name_op) if self.name_op else None,
'utxo': str(self.utxo) if self.utxo else None,
'witness_utxo': self.witness_utxo.serialize_to_network().hex() if self.witness_utxo else None,
'sighash': self.sighash,
Expand Down Expand Up @@ -1990,4 +1988,4 @@ def unpack_bip32_root_fingerprint_and_int_path(path: bytes) -> Tuple[bytes, Sequ
int_path = [int.from_bytes(b, byteorder='little', signed=False) for b in chunks(path[4:], 4)]
return xfp, int_path

from .names import get_name_op_from_output_script, name_op_to_script, OP_NAME_NEW, split_name_script
from .names import get_name_op_from_output_script, name_op_to_json, name_op_to_script, OP_NAME_NEW, split_name_script

0 comments on commit 1141bf4

Please sign in to comment.