Skip to content

Commit

Permalink
Merge pull request iotaledger#76 from iotaledger/release/2.0.0
Browse files Browse the repository at this point in the history
Release/2.0.0
  • Loading branch information
todofixthis authored Oct 3, 2017
2 parents 220c1e0 + 2400d21 commit d69b5c9
Show file tree
Hide file tree
Showing 13 changed files with 346 additions and 203 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ deploy:
python: '3.6'
tags: true
provider: pypi
distribution: 'bdist_wheel sdist'
distributions: 'bdist_wheel sdist'
skip_upload_docs: true
user: phx
password:
Expand Down
14 changes: 3 additions & 11 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
=====
PyOTA
=====
.. warning::
⚠️ This is pre-release software; it may have performance or stability issues.
Please do not use this software on mainnet until v2.0.0 stable is released. ⚠️

This is the official Python library for the IOTA Core.

It implements both the `official API`_, as well as newly-proposed functionality
Expand All @@ -32,13 +28,9 @@ PyOTA is compatible with Python 3.6, 3.5 and 2.7.
============
Installation
============
.. warning::
⚠️ This is pre-release software; it may have performance or stability issues.
Please do not use this software on mainnet until v2.0.0 stable is released. ⚠️

To install the latest version::

pip install --pre pyota
pip install pyota

Optional C Extension
====================
Expand All @@ -47,7 +39,7 @@ cryptography features significantly (speedups of **60x** are common!).

To install this extension, use the following command::

pip install --pre pyota[ccurl]
pip install pyota[ccurl]


Installing from Source
Expand Down Expand Up @@ -75,7 +67,7 @@ For the full documentation of this library, please refer to the
`official API`_


.. _Create virtualenv: https://virtualenvwrapper.readthedocs.io/
.. _Create virtualenv: https://realpython.com/blog/python/python-virtual-environments-a-primer/
.. _PyOTA Bug Tracker: https://github.com/iotaledger/iota.lib.py/issues
.. _Slack: https://slack.iota.org/
.. _dedicated forum: https://forum.iota.org/
Expand Down
2 changes: 1 addition & 1 deletion iota/commands/extended/replay_bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def _execute(self, request):
minWeightMagnitude = min_weight_magnitude,


trytes = bundle.as_tryte_strings(head_to_tail=True),
trytes = bundle.as_tryte_strings(),
)


Expand Down
2 changes: 1 addition & 1 deletion iota/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from abc import ABCMeta, abstractmethod as abstract_method
from json.encoder import JSONEncoder as BaseJsonEncoder
from typing import Mapping, Iterable
from typing import Iterable, Mapping, Text

from six import with_metaclass

Expand Down
110 changes: 88 additions & 22 deletions iota/transaction/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from iota.crypto import Curl, HASH_LENGTH
from iota.json import JsonSerializable
from iota.transaction.types import BundleHash, Fragment, TransactionHash, \
TransactionTrytes
TransactionTrytes, Nonce
from iota.types import Address, Hash, Tag, TryteString, TrytesCompatible, \
int_from_trits, trits_from_int

Expand Down Expand Up @@ -53,14 +53,18 @@ def from_tryte_string(cls, trytes, hash_=None):
signature_message_fragment = Fragment(tryte_string[0:2187]),
address = Address(tryte_string[2187:2268]),
value = int_from_trits(tryte_string[2268:2295].as_trits()),
tag = Tag(tryte_string[2295:2322]),
legacy_tag = Tag(tryte_string[2295:2322]),
timestamp = int_from_trits(tryte_string[2322:2331].as_trits()),
current_index = int_from_trits(tryte_string[2331:2340].as_trits()),
last_index = int_from_trits(tryte_string[2340:2349].as_trits()),
bundle_hash = BundleHash(tryte_string[2349:2430]),
trunk_transaction_hash = TransactionHash(tryte_string[2430:2511]),
branch_transaction_hash = TransactionHash(tryte_string[2511:2592]),
nonce = Hash(tryte_string[2592:2673]),
tag = Tag(tryte_string[2592:2619]),
attachment_timestamp = int_from_trits(tryte_string[2619:2628].as_trits()),
attachment_timestamp_lower_bound = int_from_trits(tryte_string[2628:2637].as_trits()),
attachment_timestamp_upper_bound = int_from_trits(tryte_string[2637:2646].as_trits()),
nonce = Nonce(tryte_string[2646:2673]),
)

def __init__(
Expand All @@ -69,16 +73,20 @@ def __init__(
signature_message_fragment,
address,
value,
tag,
timestamp,
current_index,
last_index,
bundle_hash,
trunk_transaction_hash,
branch_transaction_hash,
tag,
attachment_timestamp,
attachment_timestamp_lower_bound,
attachment_timestamp_upper_bound,
nonce,
legacy_tag = None
):
# type: (Optional[TransactionHash], Optional[Fragment], Address, int, Optional[Tag], int, Optional[int], Optional[int], Optional[BundleHash], Optional[TransactionHash], Optional[TransactionHash], Optional[Hash]) -> None
# type: (Optional[TransactionHash], Optional[Fragment], Address, int, int, Optional[int], Optional[int], Optional[BundleHash], Optional[TransactionHash], Optional[TransactionHash], Optional[Tag], Optional[int], Optional[int], Optional[int] Optional[Hash]) -> None
self.hash = hash_ # type: Optional[TransactionHash]
"""
Transaction ID, generated by taking a hash of the transaction
Expand All @@ -104,12 +112,12 @@ def __init__(
Can be negative (i.e., for spending inputs).
"""

self.tag = tag # type: Optional[Tag]
self._legacy_tag = legacy_tag # type: Optional[Tag]
"""
Optional classification tag applied to this transaction.
Optional classification legacy_tag applied to this transaction.
"""

self.nonce = nonce # type: Optional[Hash]
self.nonce = nonce # type: Optional[Nonce]
"""
Unique value used to increase security of the transaction hash.
"""
Expand Down Expand Up @@ -154,6 +162,17 @@ def __init__(
The branch transaction generally has no significance.
"""

self.tag = tag # type: Optional[Tag]
"""
Optional classification tag applied to this transaction.
"""

self.attachment_timestamp = attachment_timestamp # type: int

self.attachment_timestamp_lower_bound = attachment_timestamp_lower_bound # type: int

self.attachment_timestamp_upper_bound = attachment_timestamp_upper_bound # type: int

self.signature_message_fragment = signature_message_fragment # type: Optional[Fragment]
"""
Expand Down Expand Up @@ -227,6 +246,36 @@ def last_index_as_trytes(self):
"""
# Note that we are padding to 27 _trits_.
return TryteString.from_trits(trits_from_int(self.last_index, pad=27))

@property
def attachment_timestamp_as_trytes(self):
# type: () -> TryteString
"""
Returns a TryteString representation of the transaction's
attachment timestamp.
"""
#Note that we are padding to 27 _trits_.
return TryteString.from_trits(trits_from_int(self.attachment_timestamp, pad=27))

@property
def attachment_timestamp_lower_bound_as_trytes(self):
# type: () -> TryteString
"""
Returns a TryteString representation of the transaction's
attachment timestamp lower bound.
"""
#Note that we are padding to 27 _trits_.
return TryteString.from_trits(trits_from_int(self.attachment_timestamp_lower_bound, pad=27))

@property
def attachment_timestamp_upper_bound_as_trytes(self):
# type: () -> TryteString
"""
Returns a TryteString representation of the transaction's
attachment timestamp upper bound.
"""
#Note that we are padding to 27 _trits_.
return TryteString.from_trits(trits_from_int(self.attachment_timestamp_upper_bound, pad=27))

def as_json_compatible(self):
# type: () -> dict
Expand All @@ -237,18 +286,22 @@ def as_json_compatible(self):
- :py:class:`iota.json.JsonEncoder`.
"""
return {
'hash_': self.hash,
'signature_message_fragment': self.signature_message_fragment,
'address': self.address,
'value': self.value,
'tag': self.tag,
'timestamp': self.timestamp,
'current_index': self.current_index,
'last_index': self.last_index,
'bundle_hash': self.bundle_hash,
'trunk_transaction_hash': self.trunk_transaction_hash,
'branch_transaction_hash': self.branch_transaction_hash,
'nonce': self.nonce,
'hash_': self.hash,
'signature_message_fragment': self.signature_message_fragment,
'address': self.address,
'value': self.value,
'legacy_tag': self.legacy_tag,
'timestamp': self.timestamp,
'current_index': self.current_index,
'last_index': self.last_index,
'bundle_hash': self.bundle_hash,
'trunk_transaction_hash': self.trunk_transaction_hash,
'branch_transaction_hash': self.branch_transaction_hash,
'tag': self.tag,
'attachment_timestamp': self.attachment_timestamp,
'attachment_timestamp_lower_bound': self.attachment_timestamp_lower_bound,
'attachment_timestamp_upper_bound': self.attachment_timestamp_upper_bound,
'nonce': self.nonce,
}

def as_tryte_string(self):
Expand All @@ -260,13 +313,17 @@ def as_tryte_string(self):
self.signature_message_fragment
+ self.address.address
+ self.value_as_trytes
+ self.tag
+ self.legacy_tag
+ self.timestamp_as_trytes
+ self.current_index_as_trytes
+ self.last_index_as_trytes
+ self.bundle_hash
+ self.trunk_transaction_hash
+ self.branch_transaction_hash
+ self.tag
+ self.attachment_timestamp_as_trytes
+ self.attachment_timestamp_lower_bound_as_trytes
+ self.attachment_timestamp_upper_bound_as_trytes
+ self.nonce
)

Expand All @@ -279,11 +336,20 @@ def get_signature_validation_trytes(self):
return (
self.address.address
+ self.value_as_trytes
+ self.tag
+ self.legacy_tag
+ self.timestamp_as_trytes
+ self.current_index_as_trytes
+ self.last_index_as_trytes
)

@property
def legacy_tag(self):
# type: () -> Tag
"""
Return the legacy tag of the transaction.
If no legacy tag was set, returns the tag instead.
"""
return self._legacy_tag or self.tag


class Bundle(JsonSerializable, Sequence[Transaction]):
Expand Down
29 changes: 16 additions & 13 deletions iota/transaction/creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from iota.crypto.types import PrivateKey
from iota.exceptions import with_context
from iota.transaction.base import Bundle, Transaction
from iota.transaction.types import BundleHash, Fragment, TransactionHash
from iota.transaction.types import BundleHash, Fragment, TransactionHash, Nonce
from iota.transaction.utils import get_current_timestamp
from iota.types import Address, Hash, Tag, TryteString

Expand All @@ -36,23 +36,26 @@ def __init__(self, address, value, tag=None, message=None, timestamp=None):
timestamp = get_current_timestamp()

super(ProposedTransaction, self).__init__(
address = address,
tag = Tag(b'') if tag is None else tag,
timestamp = timestamp,
value = value,
address = address,
tag = Tag(b'') if tag is None else tag,
timestamp = timestamp,
value = value,

# These values will be populated when the bundle is finalized.
bundle_hash = None,
current_index = None,
hash_ = None,
last_index = None,
signature_message_fragment = None,
bundle_hash = None,
current_index = None,
hash_ = None,
last_index = None,
signature_message_fragment = None,
attachment_timestamp = 0,
attachment_timestamp_lower_bound = 0,
attachment_timestamp_upper_bound = 0,

# These values start out empty; they will be populated when the
# node does PoW.
branch_transaction_hash = TransactionHash(b''),
nonce = Hash(b''),
trunk_transaction_hash = TransactionHash(b''),
branch_transaction_hash = TransactionHash(b''),
nonce = Nonce(b''),
trunk_transaction_hash = TransactionHash(b''),
)

self.message = TryteString(b'') if message is None else message
Expand Down
23 changes: 23 additions & 0 deletions iota/transaction/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
'Fragment',
'TransactionHash',
'TransactionTrytes',
'Nonce'
]


Expand Down Expand Up @@ -72,3 +73,25 @@ def __init__(self, trytes):
'trytes': trytes,
},
)

class Nonce(TryteString):
"""
A TryteString that acts as a transaction nonce.
"""
LEN = 27

def __init__(self, trytes):
# type: (TrytesCompatible) -> None
super(Nonce, self).__init__(trytes, pad=self.LEN)

if len(self._trytes) > self.LEN:
raise with_context(
exc = ValueError('{cls} values must be {len} trytes long.'.format(
cls = type(self).__name__,
len = self.LEN
)),

context = {
'trytes': trytes,
},
)
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
name = 'PyOTA',
description = 'IOTA API library for Python',
url = 'https://github.com/iotaledger/iota.lib.py',
version = '2.0.0b2',
version = '2.0.0',

long_description = long_description,

Expand Down Expand Up @@ -66,7 +66,7 @@
license = 'MIT',

classifiers = [
'Development Status :: 4 - Beta',
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2',
Expand Down
Loading

0 comments on commit d69b5c9

Please sign in to comment.