Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions crypto/configuration/fee.py

This file was deleted.

41 changes: 0 additions & 41 deletions crypto/constants.py

This file was deleted.

7 changes: 7 additions & 0 deletions crypto/enums/abi_function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from enum import Enum

class AbiFunction(Enum):
VOTE = 'vote'
UNVOTE = 'unvote'
VALIDATOR_REGISTRATION = 'registerValidator'
VALIDATOR_RESIGNATION = 'resignValidator'
11 changes: 3 additions & 8 deletions crypto/identity/private_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,9 @@ def sign(self, message: bytes) -> bytes:
Returns:
bytes: signature of the signed message
"""
from crypto.transactions.signature import Signature

signature = Signature.sign(
hexlify(message),
self
)

return signature.encode()
signature = self.private_key.sign(message)

return hexlify(signature).decode()

def to_hex(self):
"""Returns a private key in hex format
Expand Down
167 changes: 56 additions & 111 deletions crypto/transactions/builder/base.py
Original file line number Diff line number Diff line change
@@ -1,120 +1,65 @@
from binascii import hexlify, unhexlify
from typing import Optional

from crypto.configuration.fee import get_fee
from crypto.constants import TRANSACTION_TYPE_GROUP
from crypto.configuration.network import get_network
from crypto.identity.private_key import PrivateKey
from crypto.identity.public_key import PublicKey
from crypto.transactions.serializer import Serializer
from crypto.transactions.signature import Signature
from crypto.transactions.transaction import Transaction

class BaseTransactionBuilder(object):
transaction: Transaction

def __init__(self):
self.transaction = Transaction()

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.version = getattr(self, 'version', 1)
self.transaction.expiration = getattr(self, 'expiration', 0)
if self.transaction.type != 0:
self.transaction.amount = getattr(self, 'amount', 0)
from crypto.transactions.types.abstract_transaction import AbstractTransaction


class AbstractTransactionBuilder:
def __init__(self, data: Optional[dict] = None):
default_data = {
'value': '0',
'senderPublicKey': '',
'gasPrice': '5',
'nonce': '1',
'network': get_network()['version'],
'gasLimit': 1_000_000,
'data': '',
}
self.transaction = self.get_transaction_instance(data or default_data)

def __str__(self):
return self.to_json()

@classmethod
def new(cls, data: Optional[dict] = None):
return cls(data)

def gas_limit(self, gas_limit: int):
self.transaction.data['gasLimit'] = gas_limit
return self

def recipient_address(self, recipient_address: str):
self.transaction.data['recipientAddress'] = recipient_address
return self

def gas_price(self, gas_price: int):
self.transaction.data['gasPrice'] = gas_price
return self

def nonce(self, nonce: str):
self.transaction.data['nonce'] = nonce
return self

def network(self, network: int):
self.transaction.data['network'] = network
return self

def sign(self, passphrase: str):
keys = PrivateKey.from_passphrase(passphrase)
self.transaction.data['senderPublicKey'] = keys.public_key
self.transaction = self.transaction.sign(keys)
self.transaction.data['id'] = self.transaction.get_id()
return self

def verify(self):
return self.transaction.verify()

def to_dict(self):
return self.transaction.to_dict()

def to_json(self):
return self.transaction.to_json()

def sign(self, passphrase):
"""Sign the transaction using the given passphrase

Args:
passphrase (str): passphrase associated with the account sending this transaction
"""
self.transaction.senderPublicKey = PublicKey.from_passphrase(passphrase)

msg = self.transaction.to_bytes(False, True, False)
secret = unhexlify(PrivateKey.from_passphrase(passphrase).to_hex())
self.transaction.signature = Signature.sign(msg, secret)
self.transaction.id = self.transaction.get_id()

def second_sign(self, passphrase):
"""Sign the transaction using the given second passphrase

Args:
passphrase (str): 2nd passphrase associated with the account sending this transaction
"""
msg = self.transaction.to_bytes(False, True, False)
secret = unhexlify(PrivateKey.from_passphrase(passphrase).to_hex())
self.transaction.signSignature = Signature.sign(msg, secret)
self.transaction.id = self.transaction.get_id()

def multi_sign(self, passphrase, index):
if not self.transaction.signatures:
self.transaction.signatures = []

if self.transaction.senderPublicKey is None:
raise Exception('Sender Public Key is required for multi signature')

index = len(self.transaction.signatures) if index == -1 else index

msg = self.transaction.to_bytes()
secret = unhexlify(PrivateKey.from_passphrase(passphrase).to_hex())
signature = Signature.sign(msg, secret)

index_formatted = hex(index).replace('x', '')
self.transaction.signatures.append(index_formatted + signature)

def serialize(self, skip_signature=False, skip_second_signature=False, skip_multi_signature=False):
"""Perform AIP11 compliant serialization.

Args:
skip_signature (bool, optional): do you want to skip the signature
skip_second_signature (bool, optional): do you want to skip the 2nd signature
skip_multi_signature (bool, optional): do you want to skip multi signature

Returns:
str: Serialized string
"""
return Serializer(self.to_dict()).serialize(skip_signature, skip_second_signature, skip_multi_signature)

def schnorr_verify(self):
return self.transaction.verify_schnorr()

def verify_secondsig_schnorr(self, secondPublicKey):
return self.transaction.verify_secondsig_schnorr(secondPublicKey)

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: int):
self.transaction.amount = amount

def set_sender_public_key(self, public_key: str):
self.transaction.senderPublicKey = public_key

def set_expiration(self, expiration: int):
self.transaction.expiration = expiration

def set_type_group(self, type_group):
if type(type_group) == int:
self.transaction.typeGroup = type_group
else:
types = {TRANSACTION_TYPE_GROUP.TEST: 0, TRANSACTION_TYPE_GROUP.CORE: 1, TRANSACTION_TYPE_GROUP.RESERVED: 1000}
self.transaction.typeGroup = types[type_group]
def get_transaction_instance(self, data: dict) -> AbstractTransaction:
raise NotImplementedError("Subclasses must implement get_transaction_instance()")
11 changes: 11 additions & 0 deletions crypto/transactions/builder/evm_call_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from crypto.transactions.builder.base import AbstractTransactionBuilder
from crypto.transactions.types.evm_call import EvmCall

class EvmCallBuilder(AbstractTransactionBuilder):
def payload(self, payload: str):
payload = payload.lstrip('0x') # Remove '0x' prefix if present
self.transaction.data['data'] = payload
return self

def get_transaction_instance(self, data: dict):
return EvmCall(data)
31 changes: 0 additions & 31 deletions crypto/transactions/builder/multi_payment.py

This file was deleted.

38 changes: 0 additions & 38 deletions crypto/transactions/builder/multi_signature_registration.py

This file was deleted.

31 changes: 0 additions & 31 deletions crypto/transactions/builder/transfer.py

This file was deleted.

12 changes: 12 additions & 0 deletions crypto/transactions/builder/transfer_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from crypto.transactions.builder.base import AbstractTransactionBuilder
from crypto.transactions.types.transfer import Transfer


class TransferBuilder(AbstractTransactionBuilder):
def value(self, value: str):
self.transaction.data['value'] = value
self.transaction.refresh_payload_data()
return self

def get_transaction_instance(self, data: dict):
return Transfer(data)
Loading
Loading