From f2552e2cc0949b56e4c1e6e59666428708e34a48 Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:23:00 +0100 Subject: [PATCH 1/3] remove changelog --- CHANGELOG.md | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 384c278..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,30 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - -## Unreleased - -## 2.0.0 - 2021-09-21 - -## Fixed - -- Add amount option to HTLC transactions - -## 1.0.0 - 2020-02-11 - -### Added - -- Implement AIP11 -- Implement AIP18 - -## 0.1.1 - 2018-08-29 - -### Fixed - -- created network objects instead of loading network settings from an ini file which is not included in the built package - -## 0.1.0 - 2018-08-27 -- Initial Release From 471517ea632e8c9aa875d303dce01b35ea096188 Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:23:06 +0100 Subject: [PATCH 2/3] remove codecov --- .github/workflows/test.yml | 2 -- README.md | 1 - 2 files changed, 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0e601c4..899afb2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,5 +32,3 @@ jobs: . venv/bin/activate mkdir test-results pytest -v -s --junitxml=test-reports/junit.xml --cov=crypto --cov-config=.coveragerc --cov-report xml - - name: Codecov - run: bash <(curl -s https://codecov.io/bash) -t ${{ secrets.CODECOV_TOKEN }} diff --git a/README.md b/README.md index dca05c1..87bbdb7 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ > A simple Cryptography Implementation in Python for the Ark Blockchain. [![Build Status](https://badgen.now.sh/circleci/github/ArkEcosystem/python-crypto)](https://circleci.com/gh/ArkEcosystem/python-crypto) -[![Codecov](https://badgen.now.sh/codecov/c/github/arkecosystem/python-crypto)](https://codecov.io/gh/arkecosystem/python-crypto) [![Latest Version](https://badgen.now.sh/github/release/ArkEcosystem/python-crypto)](https://github.com/ArkEcosystem/python-crypto/releases/latest) [![License: MIT](https://badgen.now.sh/badge/license/MIT/green)](https://opensource.org/licenses/MIT) From f6c198e5faa6726c5436df8cde2d323dcbb416dc Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:43:18 +0100 Subject: [PATCH 3/3] type hints --- crypto/configuration/fee.py | 11 +- crypto/configuration/network.py | 28 +- crypto/identity/address.py | 35 ++- crypto/identity/private_key.py | 14 +- crypto/identity/public_key.py | 10 +- crypto/identity/wif.py | 7 +- crypto/networks/devnet.py | 1 - crypto/networks/mainnet.py | 1 - crypto/networks/testnet.py | 1 - crypto/schnorr/__init__.py | 1 - crypto/schnorr/schnorr.py | 262 ------------------ crypto/transactions/builder/base.py | 30 +- .../builder/delegate_registration.py | 12 +- .../builder/delegate_resignation.py | 8 +- crypto/transactions/builder/multi_payment.py | 10 +- .../builder/multi_signature_registration.py | 17 +- crypto/transactions/builder/transfer.py | 5 +- crypto/transactions/builder/vote.py | 5 +- crypto/transactions/deserializer.py | 24 +- crypto/transactions/deserializers/base.py | 11 +- .../deserializers/delegate_registration.py | 2 - .../deserializers/delegate_resignation.py | 2 - .../deserializers/multi_payment.py | 3 - .../multi_signature_registration.py | 3 - crypto/transactions/deserializers/transfer.py | 1 - crypto/transactions/deserializers/vote.py | 1 - crypto/transactions/serializer.py | 30 +- crypto/transactions/serializers/base.py | 7 +- .../serializers/delegate_registration.py | 7 +- .../serializers/delegate_resignation.py | 3 +- .../transactions/serializers/multi_payment.py | 3 +- .../multi_signature_registration.py | 4 +- crypto/transactions/serializers/transfer.py | 3 +- crypto/transactions/serializers/vote.py | 4 +- crypto/transactions/signature.py | 2 +- crypto/transactions/transaction.py | 64 +++-- .../test_multi_signature_registration.py | 2 +- tests/transactions/builder/test_transfer.py | 2 +- .../test_multi_signature_registration.py | 2 +- 39 files changed, 193 insertions(+), 445 deletions(-) delete mode 100644 crypto/schnorr/__init__.py delete mode 100644 crypto/schnorr/schnorr.py diff --git a/crypto/configuration/fee.py b/crypto/configuration/fee.py index e1b876c..d6c3e52 100644 --- a/crypto/configuration/fee.py +++ b/crypto/configuration/fee.py @@ -2,20 +2,18 @@ fees = TRANSACTION_FEES.copy() - -def get_fee(transaction_type): +def get_fee(transaction_type: int, *, default: int = 0) -> int: """Get a fee for a given transaction type Args: transaction_type (int): transaction type for which we wish to get a fee Returns: - int: transaction fee + int | None: transaction fee, or None if the transaction type is not found """ - return fees.get(transaction_type) - + return fees.get(transaction_type, default) -def set_fee(transaction_type, value): +def set_fee(transaction_type: int, value: int) -> None: """Set a fee Args: @@ -23,4 +21,5 @@ def set_fee(transaction_type, value): value (int): fee for a given transaction type """ global fees + fees[transaction_type] = value diff --git a/crypto/configuration/network.py b/crypto/configuration/network.py index 97a4bba..3440123 100644 --- a/crypto/configuration/network.py +++ b/crypto/configuration/network.py @@ -1,34 +1,43 @@ +from datetime import datetime +from typing import Type, TypedDict, Union from crypto.networks.devnet import Devnet +from crypto.networks.mainnet import Mainnet +from crypto.networks.testnet import Testnet -network = {} +class NetworkType(TypedDict): + epoch: datetime + version: int + wif: int +network: NetworkType = { + 'epoch': Devnet.epoch, + 'version': Devnet.version, + 'wif': Devnet.wif, +} -def set_network(network_object): +def set_network(network_object: Union[Type[Mainnet], Type[Devnet], Type[Testnet]]) -> None: """Set what network you want to use in the crypto library Args: - network_object (Network object): Testnet, Devnet, Mainnet + network_object: Testnet, Devnet, Mainnet """ global network + network = { 'epoch': network_object.epoch, 'version': network_object.version, 'wif': network_object.wif, } - -def get_network(): +def get_network() -> NetworkType: """Get settings for a selected network, default network is devnet Returns: dict: network settings (default network is devnet) """ - if not network: - set_network(Devnet) return network - -def set_custom_network(epoch, version, wif): +def set_custom_network(epoch: datetime, version: int, wif: int) -> None: """Set custom network Args: @@ -37,6 +46,7 @@ def set_custom_network(epoch, version, wif): wif (int): chains wif """ global network + network = { 'epoch': epoch, 'version': version, diff --git a/crypto/identity/address.py b/crypto/identity/address.py index 514eb7d..477ec9e 100644 --- a/crypto/identity/address.py +++ b/crypto/identity/address.py @@ -3,10 +3,10 @@ from crypto.identity.private_key import PrivateKey -from Cryptodome.Hash import RIPEMD160, keccak +from Cryptodome.Hash import keccak from coincurve import PrivateKey, PublicKey -def get_checksum_address(address: bytes) -> str: +def get_checksum_address(address: str) -> str: """Get checksum address Args: @@ -33,50 +33,47 @@ def get_checksum_address(address: bytes) -> str: return "0x" + ''.join(chars) -def address_from_public_key(public_key): +def address_from_public_key(public_key: str) -> str: """Get an address from a public key Args: - public_key (str): + public_key (str): public key to get address Returns: str: address """ - public_key = PublicKey(bytes.fromhex(public_key)).format(compressed=False)[1:] + public_key_bytes = PublicKey(bytes.fromhex(public_key)).format(compressed=False)[1:] keccak_hash = keccak.new( - data=bytearray.fromhex(public_key.hex()), + data=bytearray.fromhex(public_key_bytes.hex()), digest_bits=256, ) return get_checksum_address(unhexlify(keccak_hash.hexdigest()[22:]).hex()) - -def address_from_private_key(private_key): +def address_from_private_key(private_key: str) -> str: """Get an address from private key Args: - private_key (string): + private_key (string): private key to get address Returns: - TYPE: Description + str: address """ - private_key = PrivateKey.from_hex(private_key) - - return address_from_public_key(private_key.public_key.format(compressed=False).hex()) + private_key_object = PrivateKey.from_hex(private_key) + return address_from_public_key(private_key_object.public_key.format(compressed=False).hex()) -def address_from_passphrase(passphrase): +def address_from_passphrase(passphrase: str) -> str: """Get an address from passphrase Args: - passphrase (str): - network_version (int, optional): + passphrase (str): passphrase to get address Returns: - string: address + str: address """ private_key = hashlib.sha256(passphrase.encode()).hexdigest() - address = address_from_private_key(private_key) - return address + + return address_from_private_key(private_key) diff --git a/crypto/identity/private_key.py b/crypto/identity/private_key.py index 3183e90..5c0781d 100644 --- a/crypto/identity/private_key.py +++ b/crypto/identity/private_key.py @@ -3,26 +3,25 @@ from coincurve import PrivateKey as PvtKey - class PrivateKey(object): - def __init__(self, private_key): + def __init__(self, private_key: str): self.private_key = PvtKey.from_hex(private_key) self.public_key = hexlify(self.private_key.public_key.format()).decode() - def sign(self, message): + def sign(self, message: bytes) -> bytes: """Sign a message with this private key object Args: message (bytes): bytes data you want to sign Returns: - str: signature of the signed message + bytes: signature of the signed message """ from crypto.transactions.signature import Signature signature = Signature.sign( hexlify(message), - self.private_key.to_hex() + self ) return signature.encode() @@ -36,7 +35,7 @@ def to_hex(self): return self.private_key.to_hex() @classmethod - def from_passphrase(cls, passphrase): + def from_passphrase(cls, passphrase: str): """Create PrivateKey object from a given passphrase Args: @@ -46,10 +45,11 @@ def from_passphrase(cls, passphrase): PrivateKey: Private key object """ private_key = sha256(passphrase.encode()).hexdigest() + return cls(private_key) @classmethod - def from_hex(cls, private_key): + def from_hex(cls, private_key: str): """Create PrivateKey object from a given hex private key Args: diff --git a/crypto/identity/public_key.py b/crypto/identity/public_key.py index f231358..d32f2b0 100644 --- a/crypto/identity/public_key.py +++ b/crypto/identity/public_key.py @@ -5,16 +5,16 @@ from crypto.identity.private_key import PrivateKey class PublicKey(object): - def __init__(self, public_key): - public_key = unhexlify(public_key.encode()) - self.public_key = PubKey(public_key) + def __init__(self, public_key: str): + self.public_key = PubKey(unhexlify(public_key.encode())) - def to_hex(self): + def to_hex(self) -> str: return hexlify(self.public_key.format()).decode() @classmethod - def from_passphrase(cls, passphrase): + def from_passphrase(cls, passphrase: str) -> str: private_key = PrivateKey.from_passphrase(passphrase) + return private_key.public_key @classmethod diff --git a/crypto/identity/wif.py b/crypto/identity/wif.py index 1f29631..c541cee 100644 --- a/crypto/identity/wif.py +++ b/crypto/identity/wif.py @@ -1,4 +1,5 @@ import hashlib +from typing import Optional from base58 import b58encode_check @@ -6,12 +7,11 @@ from crypto.configuration.network import get_network - -def wif_from_passphrase(passphrase, network_wif=None): +def wif_from_passphrase(passphrase: str, network_wif: Optional[int] = None): """Get wif from passphrase Args: - passphrase (bytes): + passphrase (str): network_wif (int, optional): Returns: @@ -19,6 +19,7 @@ def wif_from_passphrase(passphrase, network_wif=None): """ if not network_wif: network = get_network() + network_wif = network['wif'] private_key = hashlib.sha256(passphrase.encode()) diff --git a/crypto/networks/devnet.py b/crypto/networks/devnet.py index 6af399f..dc3d249 100644 --- a/crypto/networks/devnet.py +++ b/crypto/networks/devnet.py @@ -1,6 +1,5 @@ from datetime import datetime - class Devnet(object): epoch = datetime(2017, 3, 21, 13, 00, 00) version = 30 diff --git a/crypto/networks/mainnet.py b/crypto/networks/mainnet.py index 7e64890..4b21668 100644 --- a/crypto/networks/mainnet.py +++ b/crypto/networks/mainnet.py @@ -1,6 +1,5 @@ from datetime import datetime - class Mainnet(object): epoch = datetime(2017, 3, 21, 13, 00, 00) version = 23 diff --git a/crypto/networks/testnet.py b/crypto/networks/testnet.py index 7644cec..cb4f73b 100644 --- a/crypto/networks/testnet.py +++ b/crypto/networks/testnet.py @@ -1,6 +1,5 @@ from datetime import datetime - class Testnet(object): epoch = datetime(2017, 3, 21, 13, 00, 00) version = 23 diff --git a/crypto/schnorr/__init__.py b/crypto/schnorr/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/crypto/schnorr/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crypto/schnorr/schnorr.py b/crypto/schnorr/schnorr.py deleted file mode 100644 index 8b76a9c..0000000 --- a/crypto/schnorr/schnorr.py +++ /dev/null @@ -1,262 +0,0 @@ -# From Toons implementation -# see here https://github.com/Moustikitos/dpos/blob/master/dposlib/ark/secp256k1/schnorr.py - -import hashlib -from binascii import unhexlify -from builtins import int - -p = int(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) -n = int(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141) - - -def point_from_encoded(pubkey): - """ - Decode and decompress a ``secp256k1`` point. - Args: - pubkey (:class:`bytes`): compressed and encoded point - Returns: - :class:`list`: ``secp256k1`` point - """ - pubkey = bytearray(pubkey) - x = int_from_bytes(pubkey[1:]) - y = y_from_x(x) - if y is None: - raise ValueError('Point not on ``secp256k1`` curve') - elif y % 2 != pubkey[0] - 2: - y = -y % p - return [x, y] - - -def y_from_x(x): - """ - Compute :class:`P.y` from :class:`P.x` according to ``y²=x³+7``. - """ - y_sq = (pow(x, 3, p) + 7) % p - y = pow(y_sq, (p + 1) // 4, p) - if pow(y, 2, p) != y_sq: - return None - return y - - -class Point(list): - """ - ``secp256k1`` point . Initialization can be done with sole ``x`` value. - :class:`Point` overrides ``*`` and ``+`` operators which accepts - :class:`list` as argument and returns :class:`Point`. It extends - :class:`list` and allows item access using ``__getattr__``/``__setattr__`` - operators. - """ - - x = property( - lambda cls: list.__getitem__(cls, 0), - lambda cls, v: [ - list.__setitem__(cls, 0, int(v)), - list.__setitem__(cls, 1, y_from_x(int(v))) - ], - None, '' - ) - y = property( - lambda cls: list.__getitem__(cls, 1), - None, None, '' - ) - - def __init__(self, *xy): - if len(xy) == 0: - xy = (0, None) - elif len(xy) == 1: - xy += (y_from_x(int(xy[0])), ) - list.__init__(self, [int(e) if e is not None else e for e in xy[:2]]) - - def __mul__(self, k): - if isinstance(k, int): - return Point(*point_mul(self, k)) - else: - raise TypeError("'%s' should be an int" % k) - __rmul__ = __mul__ - - def __add__(self, P): - if isinstance(P, list): - return Point(*point_add(self, P)) - else: - raise TypeError("'%s' should be a 2-int-length list" % P) - __radd__ = __add__ - - @staticmethod - def decode(pubkey): - """ - Decode and decompress a ``secp256k1`` point. - """ - return Point(*point_from_encoded(pubkey)) - - def encode(self): - """ - Decode and decompress a ``secp256k1`` point. - """ - return encoded_from_point(self) - - -G = Point(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798) - - -def point_add(P1, P2): - """ - Add ``secp256k1`` points. - Args: - P1 (:class:`list`): first ``secp256k1`` point - P2 (:class:`list`): second ``secp256k1`` point - Returns: - :class:`list`: ``secp256k1`` point - """ - if (P1 is None): - return P2 - if (P2 is None): - return P1 - if (x(P1) == x(P2) and y(P1) != y(P2)): - raise ValueError('One of the point is not on the curve') - if (P1 == P2): - lam = (3 * x(P1) * x(P1) * pow(2 * y(P1), p - 2, p)) % p - else: - lam = ((y(P2) - y(P1)) * pow(x(P2) - x(P1), p - 2, p)) % p - x3 = (lam * lam - x(P1) - x(P2)) % p - return [x3, (lam * (x(P1) - x3) - y(P1)) % p] - - -def bcrypto410_verify(msg, pubkey, sig): - if len(msg) != 32: - raise ValueError('The message must be a 32-byte array.') - if len(sig) != 64: - raise ValueError('The signature must be a 64-byte array.') - - P = Point.decode(pubkey) - r, s = int_from_bytes(sig[:32]), int_from_bytes(sig[32:]) - if r >= p or s >= n: - return False - - e = int_from_bytes(hash_sha256(sig[0:32] + pubkey + msg)) % n - R = Point(*(G*s + point_mul(P, n-e))) # P*(n-e) does not work... - if R is None or not is_quad(R.y) or R.x != r: - return False - return True - - -def b410_schnorr_verify(message, publicKey, signature): - return bcrypto410_verify( - hash_sha256(message), - Point.decode(unhexlify(publicKey)).encode(), - unhexlify(signature) - ) - - -def x(P): - """ - Return :class:`P.x` or :class:`P[0]`. - Args: - P (:class:`list`): ``secp256k1`` point - Returns: - :class:`int`: x - """ - return P[0] - - -def bytes_from_int(x): - return int(x).to_bytes(32, byteorder='big') - - -def int_from_bytes(b): - return int.from_bytes(b, byteorder='big') - - -def jacobi(x): - return pow(x, (p - 1) // 2, p) - - -def is_quad(x): - return jacobi(x) == 1 - - -def hash_sha256(b): - """ - Args: - b (:class:`bytes` or :class:`str`): sequence to be hashed - Returns: - :class:`bytes`: sha256 hash - """ - return hashlib.sha256( - b if isinstance(b, bytes) else b.encode('utf-8') - ).digest() - - -def point_mul(P, n): - """ - Multiply ``secp256k1`` point with scalar. - Args: - P (:class:`list`): ``secp256k1`` point - n (:class:`int`): scalar - Returns: - :class:`list`: ``secp256k1`` point - """ - R = None - for i in range(256): - if ((n >> i) & 1): - R = point_add(R, P) - P = point_add(P, P) - return R - - -def y(P): - """ - Return :class:`P.y` or :class:`P[1]`. - - Args: - P (:class:`list`): ``secp256k1`` point - Returns: - :class:`int`: y - """ - return P[1] - - -def encoded_from_point(P): - """ - Encode and compress a ``secp256k1`` point: - * ``bytes(2) || bytes(x)`` if y is even - * ``bytes(3) || bytes(x)`` if y is odd - - Args: - P (:class:`list`): ``secp256k1`` point - Returns: - :class:`bytes`: compressed and encoded point - """ - return (b'\x03' if y(P) & 1 else b'\x02') + bytes_from_int(x(P)) - - -# https://github.com/bcoin-org/bcrypto/blob/v4.1.0/lib/js/schnorr.js -def bcrypto410_sign(msg, seckey0): - if len(msg) != 32: - raise ValueError('The message must be a 32-byte array.') - - seckey = int_from_bytes(seckey0) - if not (1 <= seckey <= n - 1): - raise ValueError( - 'The secret key must be an integer in the range 1..n-1.' - ) - - k0 = int_from_bytes(hash_sha256(seckey0 + msg)) % n - if k0 == 0: - raise RuntimeError( - 'Failure. This happens only with negligible probability.' - ) - - R = G * k0 - Rraw = bytes_from_int(R.x) - e = int_from_bytes( - hash_sha256(Rraw + encoded_from_point(G*seckey) + msg) - ) % n - - seckey %= n - k0 %= n - k = n - k0 if not is_quad(R.y) else k0 - - s = (k + e * seckey) % n - s %= n - - return Rraw + bytes_from_int(s) diff --git a/crypto/transactions/builder/base.py b/crypto/transactions/builder/base.py index 2a5181e..8683eba 100644 --- a/crypto/transactions/builder/base.py +++ b/crypto/transactions/builder/base.py @@ -9,14 +9,24 @@ from crypto.transactions.transaction import Transaction class BaseTransactionBuilder(object): + transaction: Transaction def __init__(self): self.transaction = Transaction() - self.transaction.type = getattr(self, 'transaction_type', None) - self.transaction.fee = get_fee(getattr(self, 'transaction_type', None)) - self.transaction.nonce = getattr(self, 'nonce', None) + + if hasattr(self, 'transaction_type'): + self.transaction.type = getattr(self, 'transaction_type') + + if hasattr(self, 'transaction_type'): + self.transaction.fee = get_fee(getattr(self, 'transaction_type')) + + if hasattr(self, 'nonce'): + self.transaction.nonce = getattr(self, 'nonce') + + if hasattr(self, 'signatures'): + self.transaction.signatures = getattr(self, 'signatures') + self.transaction.typeGroup = getattr(self, 'typeGroup', int(TRANSACTION_TYPE_GROUP.CORE)) - self.transaction.signatures = getattr(self, 'signatures', None) self.transaction.version = getattr(self, 'version', 1) self.transaction.expiration = getattr(self, 'expiration', 0) if self.transaction.type != 0: @@ -81,19 +91,19 @@ def serialize(self, skip_signature=False, skip_second_signature=False, skip_mult def schnorr_verify(self): return self.transaction.verify_schnorr() - def schnorr_verify_second(self, secondPublicKey): - return self.transaction.verify_schnorr_secondsig(secondPublicKey) + def verify_secondsig_schnorr(self, secondPublicKey): + return self.transaction.verify_secondsig_schnorr(secondPublicKey) - def schnorr_verify_multisig(self): - return self.transaction.verify_schnorr_multisig() + def verify_multisig_schnorr(self): + return self.transaction.verify_multisig_schnorr() def set_nonce(self, nonce): self.transaction.nonce = nonce - def set_amount(self, amount): + def set_amount(self, amount: int): self.transaction.amount = amount - def set_sender_public_key(self, public_key): + def set_sender_public_key(self, public_key: str): self.transaction.senderPublicKey = public_key def set_expiration(self, expiration: int): diff --git a/crypto/transactions/builder/delegate_registration.py b/crypto/transactions/builder/delegate_registration.py index 4dd17db..9010606 100644 --- a/crypto/transactions/builder/delegate_registration.py +++ b/crypto/transactions/builder/delegate_registration.py @@ -1,13 +1,12 @@ +from typing import Optional + from crypto.constants import TRANSACTION_DELEGATE_REGISTRATION -from crypto.identity.public_key import PublicKey from crypto.transactions.builder.base import BaseTransactionBuilder - class DelegateRegistration(BaseTransactionBuilder): - transaction_type = TRANSACTION_DELEGATE_REGISTRATION - def __init__(self, public_key, fee=None): + def __init__(self, public_key: str, fee: Optional[int] = None): """Create a delegate registration transaction Args: @@ -20,8 +19,3 @@ def __init__(self, public_key, fee=None): if fee: self.transaction.fee = fee - - def sign(self, passphrase): - public_key = PublicKey.from_passphrase(passphrase) - #self.transaction.asset['delegate']['publicKey'] = public_key - super().sign(passphrase) diff --git a/crypto/transactions/builder/delegate_resignation.py b/crypto/transactions/builder/delegate_resignation.py index 4075dd8..145d46b 100644 --- a/crypto/transactions/builder/delegate_resignation.py +++ b/crypto/transactions/builder/delegate_resignation.py @@ -1,12 +1,12 @@ +from typing import Optional + from crypto.constants import TRANSACTION_DELEGATE_RESIGNATION, TRANSACTION_TYPE_GROUP from crypto.transactions.builder.base import BaseTransactionBuilder - class DelegateResignation(BaseTransactionBuilder): - transaction_type = TRANSACTION_DELEGATE_RESIGNATION - def __init__(self, fee=None): + def __init__(self, fee: Optional[int] = None): """Create a delegate resignation transaction Args: @@ -19,5 +19,5 @@ def __init__(self, fee=None): if fee: self.transaction.fee = fee - def get_type_group(self): + def get_type_group(self) -> int: return TRANSACTION_TYPE_GROUP.CORE.value diff --git a/crypto/transactions/builder/multi_payment.py b/crypto/transactions/builder/multi_payment.py index 8b76851..131f0e8 100644 --- a/crypto/transactions/builder/multi_payment.py +++ b/crypto/transactions/builder/multi_payment.py @@ -1,12 +1,12 @@ +from typing import Optional + from crypto.constants import TRANSACTION_MULTI_PAYMENT, TRANSACTION_TYPE_GROUP from crypto.transactions.builder.base import BaseTransactionBuilder - class MultiPayment(BaseTransactionBuilder): - transaction_type = TRANSACTION_MULTI_PAYMENT - def __init__(self, vendorField=None, fee=None): + def __init__(self, vendorField: Optional[str] = None, fee: Optional[int] = None): """Create a multi payment transaction Args: @@ -24,8 +24,8 @@ def __init__(self, vendorField=None, fee=None): if fee: self.transaction.fee = fee - def get_type_group(self): + def get_type_group(self) -> int: return TRANSACTION_TYPE_GROUP.CORE.value - def add_payment(self, amount, recipient_id): + def add_payment(self, amount: int, recipient_id: str): self.transaction.asset['payments'].append({'amount': amount, 'recipientId': recipient_id}) diff --git a/crypto/transactions/builder/multi_signature_registration.py b/crypto/transactions/builder/multi_signature_registration.py index 56b664d..b267158 100644 --- a/crypto/transactions/builder/multi_signature_registration.py +++ b/crypto/transactions/builder/multi_signature_registration.py @@ -1,12 +1,14 @@ -from crypto.constants import TRANSACTION_FEES, TRANSACTION_MULTI_SIGNATURE_REGISTRATION -from crypto.transactions.builder.base import BaseTransactionBuilder +from typing import Optional +from crypto.configuration.fee import get_fee +from crypto.constants import TRANSACTION_MULTI_SIGNATURE_REGISTRATION +from crypto.transactions.builder.base import BaseTransactionBuilder class MultiSignatureRegistration(BaseTransactionBuilder): transaction_type = TRANSACTION_MULTI_SIGNATURE_REGISTRATION - def __init__(self, fee=None): + def __init__(self, fee: Optional[int] = None): """Create a new multi signature transaction Args: @@ -31,7 +33,10 @@ def set_public_keys(self, public_keys): self.transaction.asset['multiSignature']['publicKeys'] = public_keys self.transaction.fee = (len(public_keys) + 1) * self.transaction.fee - def add_participant(self, public_key): + def add_participant(self, public_key: str): self.transaction.asset['multiSignature']['publicKeys'].append(public_key) - self.transaction.fee = (len(self.transaction.asset['multiSignature']['publicKeys']) + 1) * \ - TRANSACTION_FEES.get(TRANSACTION_MULTI_SIGNATURE_REGISTRATION) + + public_key_count = (len(self.transaction.asset['multiSignature']['publicKeys']) + 1) + transaction_fee = get_fee(TRANSACTION_MULTI_SIGNATURE_REGISTRATION) + + self.transaction.fee = public_key_count * transaction_fee diff --git a/crypto/transactions/builder/transfer.py b/crypto/transactions/builder/transfer.py index 5d2f15c..37d245a 100644 --- a/crypto/transactions/builder/transfer.py +++ b/crypto/transactions/builder/transfer.py @@ -1,12 +1,13 @@ +from typing import Optional + from crypto.constants import TRANSACTION_TRANSFER from crypto.transactions.builder.base import BaseTransactionBuilder - class Transfer(BaseTransactionBuilder): transaction_type = TRANSACTION_TRANSFER - def __init__(self, recipientId, amount, vendorField=None, fee=None): + def __init__(self, recipientId: str, amount: int, vendorField: Optional[str] = None, fee: Optional[int] = None): """Create a transfer transaction Args: diff --git a/crypto/transactions/builder/vote.py b/crypto/transactions/builder/vote.py index 8086d3e..28cceff 100644 --- a/crypto/transactions/builder/vote.py +++ b/crypto/transactions/builder/vote.py @@ -1,8 +1,8 @@ +from typing import Optional + from crypto.constants import TRANSACTION_VOTE from crypto.identity.address import address_from_passphrase from crypto.transactions.builder.base import BaseTransactionBuilder -from typing import Optional - class Vote(BaseTransactionBuilder): transaction_type = TRANSACTION_VOTE @@ -25,4 +25,5 @@ def __init__(self, votes: Optional[list[str]] = None, unvotes: Optional[list[str def sign(self, passphrase): self.transaction.recipientId = address_from_passphrase(passphrase) + super().sign(passphrase) diff --git a/crypto/transactions/deserializer.py b/crypto/transactions/deserializer.py index fa28aae..01395f1 100644 --- a/crypto/transactions/deserializer.py +++ b/crypto/transactions/deserializer.py @@ -1,31 +1,26 @@ import inspect from binascii import hexlify, unhexlify -from hashlib import sha256 from importlib import import_module +from typing import Union from binary.unsigned_integer.reader import read_bit8, read_bit16, read_bit32, read_bit64 from crypto.constants import TRANSACTION_TYPES from crypto.transactions.deserializers.base import BaseDeserializer - +from crypto.transactions.transaction import Transaction class Deserializer(object): + serialized: bytes - serialized = None - - def __init__(self, serialized): + def __init__(self, serialized: Union[bytes, str]): self.serialized = unhexlify(serialized) - def deserialize(self): + def deserialize(self) -> Transaction: """Deserialize transaction Returns: - object: returns Transaction resource object + Transaction: returns transaction object """ - # circular import with transaction.py :( - I'm thinking of just returning a dict here - # which then needs to be passed to a Transaction object, instead of returning a Transaction - # object - from crypto.transactions.transaction import Transaction transaction = Transaction() transaction.version = read_bit8(self.serialized, offset=1) @@ -53,16 +48,17 @@ def deserialize(self): return transaction - def _handle_transaction_type(self, asset_offset, transaction): + def _handle_transaction_type(self, asset_offset: int, transaction): """Handle deserialization for a given transaction type Args: asset_offset (int): - transaction (object): Transaction resource object + transaction (Transaction): Transaction resource object Returns: - object: Transaction resource object of currently deserialized data + Transaction: Transaction object of currently deserialized data """ + deserializer_name = TRANSACTION_TYPES[transaction.type] module = import_module('crypto.transactions.deserializers.{}'.format(deserializer_name)) for attr in dir(module): diff --git a/crypto/transactions/deserializers/base.py b/crypto/transactions/deserializers/base.py index 6f712e5..6cbfbed 100644 --- a/crypto/transactions/deserializers/base.py +++ b/crypto/transactions/deserializers/base.py @@ -1,10 +1,11 @@ -class BaseDeserializer(object): +from crypto.transactions.transaction import Transaction - serialized = None - asset_offset = None - transaction = None +class BaseDeserializer(object): + serialized: bytes + asset_offset: int + transaction: Transaction - def __init__(self, serialized, asset_offset, transaction): + def __init__(self, serialized: bytes, asset_offset: int, transaction: Transaction): self.serialized = serialized self.asset_offset = asset_offset self.transaction = transaction diff --git a/crypto/transactions/deserializers/delegate_registration.py b/crypto/transactions/deserializers/delegate_registration.py index d359471..ce6d860 100644 --- a/crypto/transactions/deserializers/delegate_registration.py +++ b/crypto/transactions/deserializers/delegate_registration.py @@ -2,9 +2,7 @@ from crypto.transactions.deserializers.base import BaseDeserializer - class DelegateRegistrationDeserializer(BaseDeserializer): - def deserialize(self): starting_position = int(self.asset_offset / 2) diff --git a/crypto/transactions/deserializers/delegate_resignation.py b/crypto/transactions/deserializers/delegate_resignation.py index eaf4bf8..06757b1 100644 --- a/crypto/transactions/deserializers/delegate_resignation.py +++ b/crypto/transactions/deserializers/delegate_resignation.py @@ -2,9 +2,7 @@ from crypto.transactions.deserializers.base import BaseDeserializer - class DelegateResignationDeserializer(BaseDeserializer): - def deserialize(self): self.transaction.parse_signatures( hexlify(self.serialized).decode(), diff --git a/crypto/transactions/deserializers/multi_payment.py b/crypto/transactions/deserializers/multi_payment.py index e1c63f1..23f9ada 100644 --- a/crypto/transactions/deserializers/multi_payment.py +++ b/crypto/transactions/deserializers/multi_payment.py @@ -1,13 +1,10 @@ from binascii import hexlify, unhexlify - from binary.unsigned_integer.reader import read_bit16, read_bit64 from crypto.identity.address import get_checksum_address from crypto.transactions.deserializers.base import BaseDeserializer - class MultiPaymentDeserializer(BaseDeserializer): - def deserialize(self): starting_position = int(self.asset_offset / 2) diff --git a/crypto/transactions/deserializers/multi_signature_registration.py b/crypto/transactions/deserializers/multi_signature_registration.py index f8cc46d..c6381fc 100644 --- a/crypto/transactions/deserializers/multi_signature_registration.py +++ b/crypto/transactions/deserializers/multi_signature_registration.py @@ -1,12 +1,9 @@ from binascii import hexlify - from binary.unsigned_integer.reader import read_bit8 from crypto.transactions.deserializers.base import BaseDeserializer - class MultiSignatureRegistrationDeserializer(BaseDeserializer): - def deserialize(self): starting_position = int(self.asset_offset / 2) diff --git a/crypto/transactions/deserializers/transfer.py b/crypto/transactions/deserializers/transfer.py index cfe98d9..eb78c87 100644 --- a/crypto/transactions/deserializers/transfer.py +++ b/crypto/transactions/deserializers/transfer.py @@ -1,5 +1,4 @@ from binascii import hexlify, unhexlify - from binary.unsigned_integer.reader import read_bit32, read_bit64 from crypto.identity.address import get_checksum_address diff --git a/crypto/transactions/deserializers/vote.py b/crypto/transactions/deserializers/vote.py index 2c087b6..a04c189 100644 --- a/crypto/transactions/deserializers/vote.py +++ b/crypto/transactions/deserializers/vote.py @@ -1,5 +1,4 @@ from binascii import hexlify - from binary.unsigned_integer.reader import read_bit8 from crypto.transactions.deserializers.base import BaseDeserializer diff --git a/crypto/transactions/serializer.py b/crypto/transactions/serializer.py index 20b6e4c..f9bdf50 100644 --- a/crypto/transactions/serializer.py +++ b/crypto/transactions/serializer.py @@ -10,21 +10,19 @@ from crypto.exceptions import ArkSerializerException from crypto.transactions.serializers.base import BaseSerializer - class Serializer(object): - - transaction = None + transaction: dict = {} def __init__(self, transaction): if not transaction: raise ArkSerializerException('No transaction data provided') self.transaction = transaction - def serialize(self, skip_signature=True, skip_second_signature=True, skip_multi_signature=True, raw=False): + def serialize_bytes(self, skip_signature: bool = True, skip_second_signature: bool = True, skip_multi_signature: bool = True) -> bytes: """Perform AIP11 compliant serialization Returns: - bytes: bytes string + bytes: Serialized bytes """ network_config = get_network() bytes_data = bytes() @@ -41,21 +39,34 @@ def serialize(self, skip_signature=True, skip_second_signature=True, skip_multi_ bytes_data += write_bit64(self.transaction.get('fee')) if self.transaction.get('vendorField'): - vendorFieldLength = len(self.transaction.get('vendorField')) + vendorFieldLength = len(self.transaction.get('vendorField') or '') + bytes_data += write_bit8(vendorFieldLength) bytes_data += self.transaction['vendorField'].encode() elif self.transaction.get('vendorFieldHex'): vendorField_hex_length = len(self.transaction['vendorFieldHex']) + bytes_data += write_bit8(vendorField_hex_length / 2) bytes_data += self.transaction['vendorFieldHex'] else: bytes_data += write_bit8(0x00) + bytes_data = self._handle_transaction_type(bytes_data) bytes_data = self._handle_signature(bytes_data, skip_signature, skip_second_signature, skip_multi_signature) - return bytes_data if raw else hexlify(bytes_data).decode() + return bytes_data + + def serialize(self, skip_signature: bool = True, skip_second_signature: bool = True, skip_multi_signature: bool = True) -> str: + """Perform AIP11 compliant serialization - def _handle_transaction_type(self, bytes_data): + Returns: + str: Serialized string + """ + bytes_data = self.serialize_bytes(skip_signature, skip_second_signature, skip_multi_signature) + + return hexlify(bytes_data).decode() + + def _handle_transaction_type(self, bytes_data) -> bytes: """Serialize transaction specific data (eg. delegate registration) Args: @@ -78,9 +89,10 @@ def _handle_transaction_type(self, bytes_data): # this attribute is actually a specific serializer that we want to use serializer = attribute break + return serializer(self.transaction, bytes_data).serialize() - def _handle_signature(self, bytes_data, skip_signature, skip_second_signature, skip_multi_signature): + def _handle_signature(self, bytes_data, skip_signature, skip_second_signature, skip_multi_signature) -> bytes: """Serialize signature data of the transaction Args: diff --git a/crypto/transactions/serializers/base.py b/crypto/transactions/serializers/base.py index 7fca2c1..84cbb95 100644 --- a/crypto/transactions/serializers/base.py +++ b/crypto/transactions/serializers/base.py @@ -1,9 +1,8 @@ class BaseSerializer(object): + transaction: dict + bytes_data: bytes - transaction = None - bytes_data = None - - def __init__(self, transaction, bytes_data=bytes()): + def __init__(self, transaction: dict, bytes_data: bytes = bytes()): self.transaction = transaction self.bytes_data = bytes_data diff --git a/crypto/transactions/serializers/delegate_registration.py b/crypto/transactions/serializers/delegate_registration.py index 7db5c32..c6925ec 100644 --- a/crypto/transactions/serializers/delegate_registration.py +++ b/crypto/transactions/serializers/delegate_registration.py @@ -1,15 +1,12 @@ -from binascii import hexlify, unhexlify - -from binary.unsigned_integer.writer import write_bit8 +from binary.hex.writer import write_high from crypto.transactions.serializers.base import BaseSerializer -from binary.hex.writer import write_high class DelegateRegistrationSerializer(BaseSerializer): """Serializer handling delegate registration data """ - def serialize(self): + def serialize(self) -> bytes: delegate_bytes = self.transaction['asset']['validatorPublicKey'].encode() self.bytes_data += write_high(delegate_bytes) diff --git a/crypto/transactions/serializers/delegate_resignation.py b/crypto/transactions/serializers/delegate_resignation.py index fb6c7a2..07abb14 100644 --- a/crypto/transactions/serializers/delegate_resignation.py +++ b/crypto/transactions/serializers/delegate_resignation.py @@ -1,9 +1,8 @@ from crypto.transactions.serializers.base import BaseSerializer - class DelegateResignationSerializer(BaseSerializer): """Serializer handling delegate resignation data """ - def serialize(self): + def serialize(self) -> bytes: return self.bytes_data diff --git a/crypto/transactions/serializers/multi_payment.py b/crypto/transactions/serializers/multi_payment.py index a328b7c..5081768 100644 --- a/crypto/transactions/serializers/multi_payment.py +++ b/crypto/transactions/serializers/multi_payment.py @@ -3,12 +3,11 @@ from crypto.transactions.serializers.base import BaseSerializer - class MultiPaymentSerializer(BaseSerializer): """Serializer handling multi payment data """ - def serialize(self): + def serialize(self) -> bytes: self.bytes_data += write_bit16(len(self.transaction['asset']['payments'])) for payment in self.transaction['asset']['payments']: diff --git a/crypto/transactions/serializers/multi_signature_registration.py b/crypto/transactions/serializers/multi_signature_registration.py index b87fe0b..3a59466 100644 --- a/crypto/transactions/serializers/multi_signature_registration.py +++ b/crypto/transactions/serializers/multi_signature_registration.py @@ -1,15 +1,13 @@ from binascii import unhexlify - from binary.unsigned_integer.writer import write_bit8 from crypto.transactions.serializers.base import BaseSerializer - class MultiSignatureSerializer(BaseSerializer): """Serializer handling delegate registration data """ - def serialize(self): + def serialize(self) -> bytes: public_keys_length = len(self.transaction['asset']['multiSignature']['publicKeys']) self.bytes_data += write_bit8(self.transaction['asset']['multiSignature']['min']) self.bytes_data += write_bit8(public_keys_length) diff --git a/crypto/transactions/serializers/transfer.py b/crypto/transactions/serializers/transfer.py index cbc6912..5a2edbb 100644 --- a/crypto/transactions/serializers/transfer.py +++ b/crypto/transactions/serializers/transfer.py @@ -3,12 +3,11 @@ from crypto.transactions.serializers.base import BaseSerializer - class TransferSerializer(BaseSerializer): """Serializer handling transfer data """ - def serialize(self): + def serialize(self) -> bytes: self.bytes_data += write_bit64(self.transaction['amount']) self.bytes_data += write_bit32(self.transaction.get('expiration', 0)) diff --git a/crypto/transactions/serializers/vote.py b/crypto/transactions/serializers/vote.py index 4adbe07..30c6d69 100644 --- a/crypto/transactions/serializers/vote.py +++ b/crypto/transactions/serializers/vote.py @@ -1,15 +1,13 @@ from binascii import unhexlify - from binary.unsigned_integer.writer import write_bit8 from crypto.transactions.serializers.base import BaseSerializer - class VoteSerializer(BaseSerializer): """Serializer handling vote data """ - def serialize(self): + def serialize(self) -> bytes: vote_bytes = [] unvote_bytes = [] diff --git a/crypto/transactions/signature.py b/crypto/transactions/signature.py index 03ac4ac..106d060 100644 --- a/crypto/transactions/signature.py +++ b/crypto/transactions/signature.py @@ -4,7 +4,7 @@ class Signature: @staticmethod - def verify(signature, message, publicKey: bytes): + def verify(signature, message, publicKey: Union[bytes, str]): # Remove leading byte ('02' / '03') from ECDSA key if (len(publicKey) == 33): publicKey = publicKey[1:] diff --git a/crypto/transactions/transaction.py b/crypto/transactions/transaction.py index 3f8fcc3..966dafa 100644 --- a/crypto/transactions/transaction.py +++ b/crypto/transactions/transaction.py @@ -1,14 +1,12 @@ import json -from binascii import unhexlify from hashlib import sha256 +from typing import Optional from binary.hex.writer import write_high from binary.unsigned_integer.writer import write_bit8 from crypto.constants import TRANSACTION_DELEGATE_REGISTRATION, TRANSACTION_MULTI_SIGNATURE_REGISTRATION, TRANSACTION_VOTE from crypto.exceptions import ArkInvalidTransaction -from crypto.schnorr import schnorr -from crypto.transactions.deserializer import Deserializer from crypto.transactions.serializer import Serializer from crypto.transactions.signature import Signature @@ -35,10 +33,25 @@ 'expiration': None } - class Transaction(object): - - def __init__(self, *args, **kwargs): + id: str + type: int + fee: int + nonce: int + typeGroup: int + signatures: list + version: int + expiration: int + type: int + amount: int + recipientId: str + senderPublicKey: str + asset: dict + vendorField: Optional[bytes] + vendorFieldHex: bytes + network: int + + def __init__(self, **kwargs): for attribute, attribute_value in TRANSACTION_ATTRIBUTES.items(): if callable(attribute_value): attribute_value = attribute_value() @@ -73,7 +86,7 @@ def to_json(self): data = self.to_dict() return json.dumps(data) - def to_bytes(self, skip_signature=True, skip_second_signature=True, skip_multi_signature=True): + def to_bytes(self, skip_signature=True, skip_second_signature=True, skip_multi_signature=True) -> bytes: """Convert the transaction to its byte representation Args: @@ -84,20 +97,16 @@ def to_bytes(self, skip_signature=True, skip_second_signature=True, skip_multi_s Returns: bytes: bytes representation of the transaction """ - return Serializer(self.to_dict()).serialize(skip_signature=skip_signature, + return Serializer(self.to_dict()).serialize_bytes(skip_signature=skip_signature, skip_second_signature=skip_second_signature, - skip_multi_signature=skip_multi_signature, - raw=True) + skip_multi_signature=skip_multi_signature) - def parse_signatures(self, serialized, start_offset): + def parse_signatures(self, serialized: str, start_offset: int): """Parse the signature, second signature and multi signatures Args: serialized (str): parses a given serialized string start_offset (int): - - Returns: - None: methods returns nothing """ signature_end_offset = start_offset + (64 * 2) @@ -122,9 +131,7 @@ def parse_signatures(self, serialized, start_offset): signature_formatted = signature_index + signature self.signatures.append(signature_formatted) - return - - def serialize(self, skip_signature=True, skip_second_signature=True, skip_multi_signature=True): + def serialize(self, skip_signature=True, skip_second_signature=True, skip_multi_signature=True) -> str: """Perform AIP11 compliant serialization. Args: @@ -136,17 +143,21 @@ def serialize(self, skip_signature=True, skip_second_signature=True, skip_multi_ str: Serialized string """ data = self.to_dict() + return Serializer(data).serialize(skip_signature, skip_second_signature, skip_multi_signature) - def deserialize(self, serialized): + @staticmethod + def deserialize(serialized: bytes): """Perform AIP11 compliant deserialization. Args: - serialized (str): parses a given serialized string + serialized (bytes): parses a given serialized string Returns: crypto.transactions.transaction.Transaction: Transaction """ + from crypto.transactions.deserializer import Deserializer + return Deserializer(serialized).deserialize() def verify_schnorr(self): @@ -160,7 +171,7 @@ def verify_schnorr(self): return is_valid - def verify_schnorr_secondsig(self, secondPublicKey): + def verify_secondsig_schnorr(self, secondPublicKey: bytes): """Verify the transaction. Method will raise an exception if invalid, if it's valid it will returns True """ @@ -169,7 +180,9 @@ def verify_schnorr_secondsig(self, secondPublicKey): if not is_valid: raise ArkInvalidTransaction('Transaction could not be verified') - def verify_schnorr_multisig(self): + return is_valid + + def verify_multisig_schnorr(self): """Verify the multisignatures transaction. Method will raise an exception if invalid, it will returns True """ @@ -180,7 +193,7 @@ def verify_schnorr_multisig(self): return is_valid - def _handle_transaction_type(self, bytes_data): + def _handle_transaction_type(self, bytes_data) -> bytes: """Handled each transaction type differently Args: @@ -190,10 +203,7 @@ def _handle_transaction_type(self, bytes_data): NotImplementedError: raised only if the child transaction doesn't implement this required method """ - if self.type == TRANSACTION_SECOND_SIGNATURE_REGISTRATION: - public_key = self.asset['signature']['publicKey'] - bytes_data += unhexlify(public_key) - elif self.type == TRANSACTION_DELEGATE_REGISTRATION: + if self.type == TRANSACTION_DELEGATE_REGISTRATION: bytes_data += self.asset['delegate']['username'].encode() elif self.type == TRANSACTION_VOTE: bytes_data += ''.join(self.asset['votes']).encode() @@ -203,7 +213,7 @@ def _handle_transaction_type(self, bytes_data): return bytes_data - def _handle_signature(self, bytes_data, skip_signature, skip_second_signature, skip_multi_signature): + def _handle_signature(self, bytes_data, skip_signature, skip_second_signature, skip_multi_signature) -> bytes: """Internal method, used to handle the signature Args: diff --git a/tests/transactions/builder/test_multi_signature_registration.py b/tests/transactions/builder/test_multi_signature_registration.py index f720742..025de87 100644 --- a/tests/transactions/builder/test_multi_signature_registration.py +++ b/tests/transactions/builder/test_multi_signature_registration.py @@ -44,4 +44,4 @@ def test_multi_signature_registration_transaction(passphrase): assert transaction_dict['asset']['multiSignature']['publicKeys'][1] == publicKeys[1] assert transaction_dict['asset']['multiSignature']['publicKeys'][2] == '03860d76b1df09659ac282cea3da5bd84fc45729f348a4a8e5f802186be72dc17f' - transaction.schnorr_verify_multisig() # if no exception is raised, it means the transaction is valid + transaction.verify_multisig_schnorr() # if no exception is raised, it means the transaction is valid diff --git a/tests/transactions/builder/test_transfer.py b/tests/transactions/builder/test_transfer.py index 700a63a..75aa73d 100644 --- a/tests/transactions/builder/test_transfer.py +++ b/tests/transactions/builder/test_transfer.py @@ -111,7 +111,7 @@ def test_transfer_secondsign_transaction(passphrase): assert transaction_dict['senderPublicKey'] == '023efc1da7f315f3c533a4080e491f32cd4219731cef008976c3876539e1f192d3' transaction.schnorr_verify() # if no exception is raised, it means the transaction is valid - transaction.schnorr_verify_second(PublicKey.from_passphrase('second top secret passphrase')) # if no exception is raised, it means the transaction is valid + transaction.verify_secondsig_schnorr(PublicKey.from_passphrase('second top secret passphrase')) # if no exception is raised, it means the transaction is valid def test_parse_signatures(transaction_type_0): diff --git a/tests/transactions/deserializers/test_multi_signature_registration.py b/tests/transactions/deserializers/test_multi_signature_registration.py index 5488ed2..db1dea0 100644 --- a/tests/transactions/deserializers/test_multi_signature_registration.py +++ b/tests/transactions/deserializers/test_multi_signature_registration.py @@ -29,4 +29,4 @@ def test_multi_signature_registration_deserializer(): '021d03e19f1e39ac9b985b867e8362002df387fd778a682218bc3e6ce4b5c7f59eaa6f893ffb8deec2e4c9b28287417e2ab7b427356ca74d790f7fb63b6f8dcbd5' # noqa ] - actual.verify_schnorr_multisig() + actual.verify_multisig_schnorr()