Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
6f31d2a
chore: 0.1.0 changelog (#45)
faustbrian Aug 27, 2018
e13b01c
chore: add visual studio support (#48)
ciband Aug 28, 2018
ded2dc2
misc: remove "contributions closed" from PR template (#46)
roks0n Aug 28, 2018
f74bc62
misc: link to docs (#49)
dated Aug 28, 2018
d56fdb2
refactor: create network objects instead of reading from config.ini (…
roks0n Aug 30, 2018
3a0260c
chore: update pytest syntax (#54)
ciband Aug 30, 2018
ace580d
fix: skip recipient_id in to_bytes for tx type 1 and 4 (#56)
spkjp Sep 30, 2018
0163d94
chore: setup CircleCI
faustbrian Oct 16, 2018
4941618
chore: delete .travis.yml
faustbrian Oct 16, 2018
fe58284
chore: replace travis badge with circleci (#57)
dated Oct 17, 2018
6bbb2aa
chore: add codecov to circleci config (#58)
dated Oct 18, 2018
7414a37
chore: store test results (#60)
dated Oct 19, 2018
0a2ca4b
fix: contributing link in pr template (#59)
dated Oct 19, 2018
c0bf737
chore: adhere to naming convention (#61)
dated Oct 23, 2018
48d6dc3
fix: pass network_version to the underlying call in address_from_priv…
roks0n Nov 11, 2018
6203494
fix: 64 length vendorfield not 63 (#64)
whitehat Nov 30, 2018
deea082
fix: messages now can work with both publickey and publicKey (#66)
Highjhacker Dec 18, 2018
8c33e4d
docs: fix documentation sdk url (#68)
vmunich Dec 25, 2018
52a26f3
refactor: ensure that the transaction amount is an unsigned integer (…
Pedro-Souza Dec 25, 2018
367224f
chore: setup code owners (#71)
faustbrian Feb 12, 2019
5850bc1
chore: update contribution link (#79)
vulet May 23, 2019
7be9cb4
feat: support new vendorfield length (#80)
dated May 24, 2019
236f577
chore: use organization-wide GitHub Configuration (#82)
faustbrian May 27, 2019
f365fbc
chore: add itsanametoo to code owners (#83)
ItsANameToo May 27, 2019
e0b7952
Merge branch 'master' into develop
May 27, 2019
aed332f
chore: setup probot/stale configuration (#86)
faustbrian Jul 22, 2019
bbde5da
chore(readme): add lead maintainer information (#87)
faustbrian Jul 22, 2019
92b7259
ci: setup github action workflow for testing (#92)
faustbrian Sep 21, 2019
e9cde8d
ci: remove old CircleCI configuration
Sep 21, 2019
0e0c4dc
Merge branch 'master' of github.com:ArkEcosystem/python-crypto
Sep 21, 2019
f1e9170
ci: adjust job triggers (#94)
faustbrian Sep 23, 2019
f1f70ab
ci: report coverage to codecov (#95)
faustbrian Sep 23, 2019
6058091
chore(deps): add renovate.json (#96)
renovate[bot] Sep 27, 2019
e17c2a2
chore: update workflow config (#98)
dated Oct 19, 2019
6bea614
Merge branch 'master' into develop
ItsANameToo Dec 16, 2019
e80fdf8
feat: AIP 11 & 18 implementation (#100)
Highjhacker Dec 23, 2019
738c3b8
fix: enable vendorfield for multipayment (#103)
dated Jan 30, 2020
7f45b7f
fix: enable vendorfield for htlc lock (#104)
dated Jan 30, 2020
69233f9
fix: update second_sign method to use schnorr (#106)
galperins4 Feb 5, 2020
4cfc576
release: 1.0.0 (#111)
faustbrian Feb 10, 2020
6b23b77
chore: fix wrong release year (#112)
faustbrian Feb 10, 2020
0e38682
ci: test against python 3.8 and 3.9 (#117)
ciband Feb 16, 2021
5d84769
feat: add amount to HTLC lock constructor (#116)
ciband Feb 16, 2021
c2dd3d2
chore: Increase test coverage for transactions (#119)
ciband Feb 17, 2021
818a349
chore: update README links (#121)
Highjhacker Sep 8, 2021
928771c
release: 2.0.0
ItsANameToo Sep 21, 2021
676c942
test: improve HTLC tests, add docs, raise exception on invalid unlock…
c0nsol3 Apr 20, 2022
f5eb570
chore: initial requirements.txt (#125)
alexbarnsley Jul 10, 2024
dd22fcb
chore: update minor dependencies (#126)
alexbarnsley Jul 10, 2024
d642809
chore: update major dependencies (#127)
alexbarnsley Jul 10, 2024
969df99
fix: ripemd160 usage (#128)
alexbarnsley Jul 17, 2024
fb8e8d5
feat: keccak addresses (#130)
alexbarnsley Jul 19, 2024
5ffb58e
refactor: update schnorr implementation (#129)
alexbarnsley Jul 29, 2024
5bbbbde
refactor: remove old transaction types (#131)
alexbarnsley Jul 29, 2024
3df8946
refactor: tidy base58 (#132)
alexbarnsley Jul 29, 2024
9aa6664
chore: update editorconfig (#134)
alexbarnsley Jul 29, 2024
602c6ae
refactor: serialize transaction method (#133)
alexbarnsley Jul 29, 2024
184b1d2
refactor: add type hints & general tidy up (#135)
alexbarnsley Jul 30, 2024
bac823a
refactor: move serialized test data to fixtures (#136)
alexbarnsley Jul 30, 2024
527cbd6
chore: rename delegate to validator (#137)
alexbarnsley Jul 31, 2024
e55335f
refactor: validate bls public key (#138)
alexbarnsley Jul 31, 2024
cb1da79
feat: implement username transaction types (#139)
alexbarnsley Aug 12, 2024
ae4c2e0
feat: bls key generation (#141)
alexbarnsley Aug 20, 2024
5c84bc5
fix: include submodule in packages (#142)
alexbarnsley Aug 21, 2024
474a49a
fix: multi sign signatures & fees (#143)
alexbarnsley Aug 22, 2024
9e014e6
add fixtures
alfonsobries Nov 28, 2024
36b09bb
wip
alfonsobries Nov 29, 2024
056399b
create transaction types and builder as per other languages
alfonsobries Nov 29, 2024
73322a4
wip
alfonsobries Nov 29, 2024
15592d5
wip
alfonsobries Nov 29, 2024
f1efd5f
debug results
alfonsobries Nov 29, 2024
97bbee7
Merge branch 'feat/mainsail' into refactor/evm-adjustments
alfonsobries Nov 29, 2024
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
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()")
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