diff --git a/crypto/constants.py b/crypto/constants.py index e5cf084..6a4d6af 100644 --- a/crypto/constants.py +++ b/crypto/constants.py @@ -1,43 +1,28 @@ from enum import Enum TRANSACTION_TRANSFER = 0 -TRANSACTION_SECOND_SIGNATURE_REGISTRATION = 1 TRANSACTION_DELEGATE_REGISTRATION = 2 TRANSACTION_VOTE = 3 TRANSACTION_MULTI_SIGNATURE_REGISTRATION = 4 -TRANSACTION_IPFS = 5 TRANSACTION_MULTI_PAYMENT = 6 TRANSACTION_DELEGATE_RESIGNATION = 7 -TRANSACTION_HTLC_LOCK = 8 -TRANSACTION_HTLC_CLAIM = 9 -TRANSACTION_HTLC_REFUND = 10 TRANSACTION_TYPES = { TRANSACTION_TRANSFER: 'transfer', - TRANSACTION_SECOND_SIGNATURE_REGISTRATION: 'second_signature_registration', TRANSACTION_DELEGATE_REGISTRATION: 'delegate_registration', TRANSACTION_VOTE: 'vote', TRANSACTION_MULTI_SIGNATURE_REGISTRATION: 'multi_signature_registration', - TRANSACTION_IPFS: 'ipfs', TRANSACTION_MULTI_PAYMENT: 'multi_payment', TRANSACTION_DELEGATE_RESIGNATION: 'delegate_resignation', - TRANSACTION_HTLC_LOCK: 'htlc_lock', - TRANSACTION_HTLC_CLAIM: 'htlc_claim', - TRANSACTION_HTLC_REFUND: 'htlc_refund', } TRANSACTION_FEES = { TRANSACTION_TRANSFER: 10000000, - TRANSACTION_SECOND_SIGNATURE_REGISTRATION: 500000000, TRANSACTION_DELEGATE_REGISTRATION: 2500000000, TRANSACTION_VOTE: 100000000, TRANSACTION_MULTI_SIGNATURE_REGISTRATION: 500000000, - TRANSACTION_IPFS: 500000000, TRANSACTION_MULTI_PAYMENT: 10000000, TRANSACTION_DELEGATE_RESIGNATION: 2500000000, - TRANSACTION_HTLC_LOCK: 10000000, - TRANSACTION_HTLC_CLAIM: 0, - TRANSACTION_HTLC_REFUND: 0, } @@ -48,11 +33,3 @@ def __int__(self): TEST = 0 CORE = 1 RESERVED = 1000 # Everything above is available to anyone - - -class HTLC_LOCK_EXPIRATION_TYPE(Enum): - def __str__(self): - return int(self.value) - - EPOCH_TIMESTAMP = 1 - BLOCK_HEIGHT = 2 diff --git a/crypto/transactions/builder/base.py b/crypto/transactions/builder/base.py index efa68ce..25592cf 100644 --- a/crypto/transactions/builder/base.py +++ b/crypto/transactions/builder/base.py @@ -1,7 +1,7 @@ from binascii import hexlify, unhexlify from crypto.configuration.fee import get_fee -from crypto.constants import HTLC_LOCK_EXPIRATION_TYPE, TRANSACTION_TYPE_GROUP +from crypto.constants import TRANSACTION_TYPE_GROUP from crypto.identity.private_key import PrivateKey from crypto.identity.public_key import PublicKey from crypto.transactions.signature import Signature @@ -82,12 +82,8 @@ def set_amount(self, amount): def set_sender_public_key(self, public_key): self.transaction.senderPublicKey = public_key - def set_expiration(self, expiration): - if type(expiration) == int: - self.transaction.expiration = expiration - else: - types = {HTLC_LOCK_EXPIRATION_TYPE.EPOCH_TIMESTAMP: 1, HTLC_LOCK_EXPIRATION_TYPE.BLOCK_HEIGHT: 2} - self.transaction.expiration = types[expiration] + def set_expiration(self, expiration: int): + self.transaction.expiration = expiration def set_type_group(self, type_group): if type(type_group) == int: diff --git a/crypto/transactions/builder/htlc_claim.py b/crypto/transactions/builder/htlc_claim.py deleted file mode 100644 index 9f15398..0000000 --- a/crypto/transactions/builder/htlc_claim.py +++ /dev/null @@ -1,31 +0,0 @@ -from crypto.constants import TRANSACTION_HTLC_CLAIM, TRANSACTION_TYPE_GROUP -from crypto.exceptions import ArkInvalidTransaction -from crypto.transactions.builder.base import BaseTransactionBuilder - - -class HtlcClaim(BaseTransactionBuilder): - - transaction_type = TRANSACTION_HTLC_CLAIM - - def __init__(self, lock_transaction_id, unlock_secret, fee=None): - """Create a timelock transaction - - Args: - lock_transaction_id (str): HTLC lock transaction ID we wish to claim - unlock_secret (str): unlock secret required to claim the transaction, must be 64 chars long - fee (int, optional): fee used for the transaction (default is already set) - """ - super().__init__() - - self.transaction.typeGroup = self.get_type_group() - - self.transaction.asset['claim'] = { - 'lockTransactionId': lock_transaction_id, - 'unlockSecret': unlock_secret - } - - if fee: - self.transaction.fee = fee - - def get_type_group(self): - return TRANSACTION_TYPE_GROUP.CORE.value diff --git a/crypto/transactions/builder/htlc_lock.py b/crypto/transactions/builder/htlc_lock.py deleted file mode 100644 index 0ee2c7a..0000000 --- a/crypto/transactions/builder/htlc_lock.py +++ /dev/null @@ -1,46 +0,0 @@ -from crypto.constants import TRANSACTION_HTLC_LOCK, TRANSACTION_TYPE_GROUP -from crypto.transactions.builder.base import BaseTransactionBuilder - - -class HtlcLock(BaseTransactionBuilder): - - transaction_type = TRANSACTION_HTLC_LOCK - - def __init__(self, recipient_id, amount, secret_hash, expiration_type, expiration_value, vendorField=None, fee=None): - """Create a timelock transaction - - Args: - recipient_id (str): recipient identifier - amount (int): amount of coins you want to transfer - secret_hash (str): a hash of the secret. The SAME hash must be used in the corresponding “claim” transaction - expiration_type (int): type of the expiration. Either block height or network epoch timestamp based - expiration_value (int): Expiration of transaction in seconds or height depending on expiration_type - vendorField (str): value for the vendor field aka smartbridge - fee (int, optional): fee used for the transaction (default is already set) - """ - super().__init__() - - self.transaction.recipientId = recipient_id - - if type(amount) == int and amount > 0: - self.transaction.amount = amount - else: - raise ValueError('Amount is not valid') - - self.transaction.typeGroup = self.get_type_group() - - self.transaction.asset['lock'] = { - 'secretHash': secret_hash, - 'expiration': { - 'type': expiration_type, - 'value': expiration_value - } - } - - self.transaction.vendorField = vendorField.encode() if vendorField else None - - if fee: - self.transaction.fee = fee - - def get_type_group(self): - return TRANSACTION_TYPE_GROUP.CORE.value diff --git a/crypto/transactions/builder/htlc_refund.py b/crypto/transactions/builder/htlc_refund.py deleted file mode 100644 index c18e1b5..0000000 --- a/crypto/transactions/builder/htlc_refund.py +++ /dev/null @@ -1,28 +0,0 @@ -from crypto.constants import TRANSACTION_HTLC_REFUND, TRANSACTION_TYPE_GROUP -from crypto.transactions.builder.base import BaseTransactionBuilder - - -class HtlcRefund(BaseTransactionBuilder): - - transaction_type = TRANSACTION_HTLC_REFUND - - def __init__(self, lock_transaction_id, fee=None): - """Create a timelock transaction - - Args: - lock_transaction_id (str) : HTLC lock transaction ID we wish to claim - fee (int, optional): fee used for the transaction (default is already set) - """ - super().__init__() - - self.transaction.typeGroup = self.get_type_group() - - self.transaction.asset['refund'] = { - 'lockTransactionId': lock_transaction_id, - } - - if fee: - self.transaction.fee = fee - - def get_type_group(self): - return TRANSACTION_TYPE_GROUP.CORE.value diff --git a/crypto/transactions/builder/ipfs.py b/crypto/transactions/builder/ipfs.py deleted file mode 100644 index e1adf2c..0000000 --- a/crypto/transactions/builder/ipfs.py +++ /dev/null @@ -1,25 +0,0 @@ -from crypto.constants import TRANSACTION_IPFS, TRANSACTION_TYPE_GROUP -from crypto.transactions.builder.base import BaseTransactionBuilder - - -class IPFS(BaseTransactionBuilder): - - transaction_type = TRANSACTION_IPFS - - def __init__(self, ipfs_id, fee=None): - """Create an ipfs transaction - - Args: - ipfs_id (str): ipfs transaction identifier - fee (int, optional): fee used for the transaction (default is already set) - """ - super().__init__() - - self.transaction.asset['ipfs'] = ipfs_id - self.transaction.typeGroup = self.get_type_group() - - if fee: - self.transaction.fee = fee - - def get_type_group(self): - return TRANSACTION_TYPE_GROUP.CORE.value diff --git a/crypto/transactions/builder/second_signature_registration.py b/crypto/transactions/builder/second_signature_registration.py deleted file mode 100644 index d35c6f6..0000000 --- a/crypto/transactions/builder/second_signature_registration.py +++ /dev/null @@ -1,23 +0,0 @@ -from crypto.constants import TRANSACTION_SECOND_SIGNATURE_REGISTRATION -from crypto.identity.public_key import PublicKey -from crypto.transactions.builder.base import BaseTransactionBuilder - - -class SecondSignatureRegistration(BaseTransactionBuilder): - - transaction_type = TRANSACTION_SECOND_SIGNATURE_REGISTRATION - - def __init__(self, second_passphrase, fee=None): - """Create a second signature registration transaction - - Args: - second_passphrase (str): used for signing a transaction the 2nd time - fee (int, optional): fee used for the transaction (default is already set) - """ - super().__init__() - - public_key = PublicKey.from_passphrase(second_passphrase) - self.transaction.asset['signature'] = {'publicKey': public_key} - - if fee: - self.transaction.fee = fee diff --git a/crypto/transactions/deserializers/htlc_claim.py b/crypto/transactions/deserializers/htlc_claim.py deleted file mode 100644 index 1324352..0000000 --- a/crypto/transactions/deserializers/htlc_claim.py +++ /dev/null @@ -1,24 +0,0 @@ -from binascii import hexlify - -from crypto.transactions.deserializers.base import BaseDeserializer - - -class HtlcClaimDeserializer(BaseDeserializer): - - def deserialize(self): - starting_position = int(self.asset_offset / 2) - lock_transaction_id = hexlify(self.serialized[starting_position:starting_position + 32]) - - unlock_secret = hexlify(self.serialized[starting_position + 32:starting_position + 64]) - - self.transaction.asset['claim'] = { - 'lockTransactionId': lock_transaction_id.decode(), - 'unlockSecret': unlock_secret.decode() - } - - self.transaction.parse_signatures( - hexlify(self.serialized).decode(), - self.asset_offset + (64 * 2) - ) - - return self.transaction diff --git a/crypto/transactions/deserializers/htlc_lock.py b/crypto/transactions/deserializers/htlc_lock.py deleted file mode 100644 index dfbd52b..0000000 --- a/crypto/transactions/deserializers/htlc_lock.py +++ /dev/null @@ -1,41 +0,0 @@ -from binascii import hexlify, unhexlify - -from base58 import b58encode_check - -from binary.unsigned_integer.reader import read_bit8, read_bit32, read_bit64 - -from crypto.transactions.deserializers.base import BaseDeserializer - - -class HtlcLockDeserializer(BaseDeserializer): - - def deserialize(self): - starting_position = int(self.asset_offset / 2) - - self.transaction.amount = read_bit64(self.serialized, offset=starting_position) - - secret_hash = hexlify(self.serialized)[(starting_position + 8) * 2:(starting_position + 8 + 32) * 2] - - expiration_type = read_bit8(self.serialized, offset=99) - - expiration_value = read_bit32(self.serialized, offset=100) - - recipient_start_index = (starting_position + 45) * 2 - recipientId = hexlify(self.serialized)[recipient_start_index:recipient_start_index + 42] - self.transaction.recipientId = b58encode_check(unhexlify(recipientId)).decode() - - self.transaction.asset['lock'] = { - 'secretHash': secret_hash.decode() - } - - self.transaction.asset['lock']['expiration'] = { - 'type': expiration_type, - 'value': expiration_value - } - - self.transaction.parse_signatures( - hexlify(self.serialized).decode(), - self.asset_offset + (8 + 32 + 1 + 4 + 21) * 2 - ) - - return self.transaction diff --git a/crypto/transactions/deserializers/htlc_refund.py b/crypto/transactions/deserializers/htlc_refund.py deleted file mode 100644 index 9260c1e..0000000 --- a/crypto/transactions/deserializers/htlc_refund.py +++ /dev/null @@ -1,22 +0,0 @@ -from binascii import hexlify - -from crypto.transactions.deserializers.base import BaseDeserializer - - -class HtlcRefundDeserializer(BaseDeserializer): - - def deserialize(self): - starting_position = int(self.asset_offset) - - lock_transaction_id = hexlify(self.serialized)[starting_position:starting_position + 64] - - self.transaction.asset['refund'] = { - 'lockTransactionId': lock_transaction_id.decode() - } - - self.transaction.parse_signatures( - hexlify(self.serialized).decode(), - self.asset_offset + 64 - ) - - return self.transaction diff --git a/crypto/transactions/deserializers/ipfs.py b/crypto/transactions/deserializers/ipfs.py deleted file mode 100644 index 1cf91a3..0000000 --- a/crypto/transactions/deserializers/ipfs.py +++ /dev/null @@ -1,38 +0,0 @@ -from binascii import hexlify, unhexlify - -from base58 import b58encode - -from binary.unsigned_integer.reader import read_bit8 -from binary.unsigned_integer.writer import write_bit8 - -from crypto.transactions.deserializers.base import BaseDeserializer - - -class IPFSDeserializer(BaseDeserializer): - - def deserialize(self): - starting_position = int(self.asset_offset / 2) - - hash_function = read_bit8(self.serialized, starting_position) & 0xff - ipfs_hash_length = read_bit8(self.serialized, starting_position + 1) & 0xff - - start_index = (starting_position + 2) * 2 - end_index = start_index + (ipfs_hash_length * 2) - ipfs_hash = hexlify(self.serialized)[start_index:end_index] - - temp_buffer = bytes() - - temp_buffer += write_bit8(hash_function) - temp_buffer += write_bit8(ipfs_hash_length) - temp_buffer += unhexlify(ipfs_hash) - - self.transaction.asset = { - 'ipfs': b58encode(temp_buffer).decode() - } - - self.transaction.parse_signatures( - hexlify(self.serialized).decode(), - self.asset_offset + (ipfs_hash_length + 2) * 2 - ) - - return self.transaction diff --git a/crypto/transactions/deserializers/second_signature_registration.py b/crypto/transactions/deserializers/second_signature_registration.py deleted file mode 100644 index 0b69081..0000000 --- a/crypto/transactions/deserializers/second_signature_registration.py +++ /dev/null @@ -1,21 +0,0 @@ -from binascii import hexlify - -from crypto.transactions.deserializers.base import BaseDeserializer - - -class SecondSignatureRegistrationDeserializer(BaseDeserializer): - - def deserialize(self): - starting_position = int(self.asset_offset) - - public_key = hexlify(self.serialized)[starting_position:starting_position + 66] - - self.transaction.asset = { - 'signature': { - 'publicKey': public_key.decode() - } - } - - self.transaction.parse_signatures(hexlify(self.serialized).decode(), self.asset_offset + 66) - - return self.transaction diff --git a/crypto/transactions/serializers/htlc_claim.py b/crypto/transactions/serializers/htlc_claim.py deleted file mode 100644 index 68ed633..0000000 --- a/crypto/transactions/serializers/htlc_claim.py +++ /dev/null @@ -1,18 +0,0 @@ -from binascii import unhexlify - -from crypto.transactions.serializers.base import BaseSerializer -from crypto.exceptions import ArkSerializerException - - -class HtlcClaimSerializer(BaseSerializer): - """Serializer handling timelock claim data - """ - - def serialize(self): - self.bytes_data += unhexlify(self.transaction['asset']['claim']['lockTransactionId']) - unlock_secret_bytes = unhexlify(self.transaction['asset']['claim']['unlockSecret'].encode()) - if len(unlock_secret_bytes) != 32: - raise ArkSerializerException("Unlock secret must be 32 bytes long") - - self.bytes_data += unlock_secret_bytes - return self.bytes_data diff --git a/crypto/transactions/serializers/htlc_lock.py b/crypto/transactions/serializers/htlc_lock.py deleted file mode 100644 index 30fb2ec..0000000 --- a/crypto/transactions/serializers/htlc_lock.py +++ /dev/null @@ -1,24 +0,0 @@ -from binascii import hexlify, unhexlify - -from base58 import b58decode_check - -from binary.hex.writer import write_high -from binary.unsigned_integer.writer import write_bit8, write_bit32, write_bit64 - -from crypto.transactions.serializers.base import BaseSerializer - - -class HtlcLockSerializer(BaseSerializer): - """Serializer handling timelock transfer data - """ - - def serialize(self): - self.bytes_data += write_bit64(self.transaction['amount']) - self.bytes_data += unhexlify(self.transaction['asset']['lock']['secretHash'].encode()) - self.bytes_data += write_bit8(self.transaction['asset']['lock']['expiration']['type']) - self.bytes_data += write_bit32(self.transaction['asset']['lock']['expiration']['value']) - - recipientId = hexlify(b58decode_check(self.transaction['recipientId'])) - self.bytes_data += write_high(recipientId) - - return self.bytes_data diff --git a/crypto/transactions/serializers/htlc_refund.py b/crypto/transactions/serializers/htlc_refund.py deleted file mode 100644 index 1ef2ce5..0000000 --- a/crypto/transactions/serializers/htlc_refund.py +++ /dev/null @@ -1,12 +0,0 @@ -from binascii import unhexlify - -from crypto.transactions.serializers.base import BaseSerializer - - -class HtlcRefundSerializer(BaseSerializer): - """Serializer handling timelock refund data - """ - - def serialize(self): - self.bytes_data += unhexlify(self.transaction['asset']['refund']['lockTransactionId'].encode()) - return self.bytes_data diff --git a/crypto/transactions/serializers/ipfs.py b/crypto/transactions/serializers/ipfs.py deleted file mode 100644 index 88dd629..0000000 --- a/crypto/transactions/serializers/ipfs.py +++ /dev/null @@ -1,19 +0,0 @@ -from binascii import hexlify - -from base58 import b58decode - -from binary.hex.writer import write_high - -from crypto.transactions.serializers.base import BaseSerializer - - -class IPFSSerializer(BaseSerializer): - """Serializer handling ipfs data - """ - - def serialize(self): - ipfs = hexlify(b58decode(self.transaction['asset']['ipfs'])) - - self.bytes_data += write_high(ipfs) - - return self.bytes_data diff --git a/crypto/transactions/serializers/second_signature_registration.py b/crypto/transactions/serializers/second_signature_registration.py deleted file mode 100644 index dc8f398..0000000 --- a/crypto/transactions/serializers/second_signature_registration.py +++ /dev/null @@ -1,12 +0,0 @@ -from binascii import unhexlify - -from crypto.transactions.serializers.base import BaseSerializer - - -class SecondSignatureRegistrationSerializer(BaseSerializer): - """Serializer handling registration of the seconds signature - """ - - def serialize(self): - self.bytes_data += unhexlify(self.transaction['asset']['signature']['publicKey'].encode()) - return self.bytes_data diff --git a/crypto/transactions/transaction.py b/crypto/transactions/transaction.py index 81b10a7..3f8fcc3 100644 --- a/crypto/transactions/transaction.py +++ b/crypto/transactions/transaction.py @@ -5,10 +5,7 @@ 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_SECOND_SIGNATURE_REGISTRATION, TRANSACTION_VOTE -) +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 diff --git a/tests/transactions/builder/test_multi_signature_registration.py b/tests/transactions/builder/test_multi_signature_registration.py index 0724fc2..f720742 100644 --- a/tests/transactions/builder/test_multi_signature_registration.py +++ b/tests/transactions/builder/test_multi_signature_registration.py @@ -7,7 +7,7 @@ def test_multi_signature_registration_transaction(passphrase): - """Test if a second signature registration transaction gets built + """Test if a multi signature registration transaction gets built """ publicKeys = [ '0205d9bbe71c343ac9a6a83a4344fd404c3534fc7349827097d0835d160bc2b896', diff --git a/tests/transactions/builder/test_transfer.py b/tests/transactions/builder/test_transfer.py index 4436e60..9ce829e 100644 --- a/tests/transactions/builder/test_transfer.py +++ b/tests/transactions/builder/test_transfer.py @@ -90,7 +90,7 @@ def test_transfer_transaction_custom_fee(passphrase): transaction.schnorr_verify() # if no exception is raised, it means the transaction is valid -def test_transfer_secondsig_transaction(passphrase): +def test_transfer_secondsign_transaction(passphrase): """Test if a transfer transaction with second signature gets built """ transaction = Transfer( diff --git a/tests/transactions/deserializers/test_transfer.py b/tests/transactions/deserializers/test_transfer.py index dc60f11..413923d 100644 --- a/tests/transactions/deserializers/test_transfer.py +++ b/tests/transactions/deserializers/test_transfer.py @@ -22,27 +22,3 @@ def test_transfer_deserializer(): assert actual.id == '8d0584d1bbc8fa7a6e4e7904b884f69399df56dcfe6458c2bedc283c55604def' actual.verify_schnorr() - - -@pytest.mark.skip() -def test_transfer_second_signature_deserializer(): - serialized = 'ff02170100000000000100000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000000c2eb0b0000000000000000170995750207ecaf0ccf251c1265b92ad84f553662136c29d921b58ae3194020b82e9808f9cd54f7178cb34678f570f28226b8e56ba0ad318297a3bacbb37ab22ddaa5dbf1901cda3ec2d2bca5ce98d6407839ab9b02dd94f611e300ad77147d808a34e942b379c5468760d8605adc0304400a2578a2039468b844f30ad1f0515f9cce33855791296117bfe8ef3caa664152644fd6' - - deserializer = Deserializer(serialized) - actual = deserializer.deserialize() - - assert actual.version == 2 - assert actual.network == 23 - assert actual.typeGroup == 1 - assert actual.expiration == 0 - assert actual.type == 0 - assert actual.amount == 200000000 - assert actual.fee == 10000000 - assert actual.nonce == 1 - assert actual.recipientId == 'AGeYmgbg2LgGxRW2vNNJvQ88PknEJsYizC' - assert actual.senderPublicKey == '034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192' # noqa - assert actual.id == 'be148ab83b75c199f9778f8963814a641a6ee937b6dd5b294082fbf7def94a45' - assert actual.signature == '136c29d921b58ae3194020b82e9808f9cd54f7178cb34678f570f28226b8e56ba0ad318297a3bacbb37ab22ddaa5dbf1901cda3ec2d2bca5ce98d6407839ab9b' - assert actual.signSignature == '02dd94f611e300ad77147d808a34e942b379c5468760d8605adc0304400a2578a2039468b844f30ad1f0515f9cce33855791296117bfe8ef3caa664152644fd6' - - actual.verify_schnorr()