Skip to content
This repository has been archived by the owner on Jan 13, 2023. It is now read-only.

Commit

Permalink
Merge pull request #287 from lzpap/tutorials_init
Browse files Browse the repository at this point in the history
Add first tutorials to documentation
  • Loading branch information
lzpap committed Jan 15, 2020
2 parents 6e0b5c2 + b3e3172 commit 5a3aecd
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
addresses
multisig
commands
tutorials

.. include:: README.rst
173 changes: 173 additions & 0 deletions docs/tutorials.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
Tutorials
=========
Are you new to IOTA in Python? Don't worry, we got you covered! With the
walkthrough examples of this section, you will be a master of PyOTA.

In each section below, a code snippet will be shown and discussed in detail
to help you understand how to carry out specific tasks with PyOTA.

If you feel that something is missing or not clear, please post your questions
and suggestions in the `PyOTA Bug Tracker`_.

Let's get to it then!

.. py:currentmodule:: iota
Hello Node
----------
In this example, you will learn how to:

- **Import the** ``iota`` **package into your application.**
- **Instantiate an API object for communication with the IOTA network.**
- **Request information about the IOTA node you are connected to.**


Code
~~~~
.. literalinclude:: ../examples/tutorials/01_hello_node.py
:linenos:

Discussion
~~~~~~~~~~
.. literalinclude:: ../examples/tutorials/01_hello_node.py
:lines: 1-3
:lineno-start: 1

First things first, we need to import in our application the modules we intend
to use. PyOTA provide the ``iota`` package, therefore, whenever you need
something from the library, you need to import it from there.

Notice, how we import the :py:class:`Iota` object, that defines a
so-called extended API object. We will use this to send and receive data from
the network. Read more about API objects at :ref:`PyOTA API Classes`.

We also import the ``pprint`` method that prettifies the output before printing
it to the console.

.. literalinclude:: ../examples/tutorials/01_hello_node.py
:lines: 5-6
:lineno-start: 5

Next, we declare an API object. Since this object handles the communication,
we need to specify an IOTA node to connect to in the form of an URI. Note, that
the library will parse this string and will throw an exception if it is not
a valid one.

.. literalinclude:: ../examples/tutorials/01_hello_node.py
:lines: 8-9
:lineno-start: 8

Then we can call the :py:meth:`Iota.get_node_info` method of the API
object to get some basic info about the node.

.. code-block::
:lineno-start: 11
# Using pprint instead of print for a nicer looking result in the console
pprint(response)
Finally, we print out the response. It is important to note, that all API
methods return a python dictionary. Refer to the method's documentation to
determine what exactly is in the response ``dict``. Here for example,
we could list the ``features`` of the node::

pprint(response['features'])

Send Data
---------
In this example, you will learn how to:

- **Encode data to be stored on the Tangle.**
- **Generate a random IOTA address that doesn't belong to anyone.**
- **Create a zero-value transaction with custom payload.**
- **Send a transaction to the network.**

Code
~~~~
.. literalinclude:: ../examples/tutorials/02_send_data.py
:linenos:

Discussion
~~~~~~~~~~
.. literalinclude:: ../examples/tutorials/02_send_data.py
:lines: 1-5
:lineno-start: 1

We have seen this part before. Note, that now we import more objects which we
will use to construct our transaction.

Notice ``testnet=True`` in the argument list of the API instantiation. We
tell the API directly that we will use the devnet/testnet. By default, the API
is configured for the mainnet.

.. literalinclude:: ../examples/tutorials/02_send_data.py
:lines: 7-8
:lineno-start: 7

If you read :ref:`Basic Concepts` and :ref:`PyOTA Types`, it shouldn't be a
surprise to you that most things in IOTA are represented as trytes, that are
:py:class:`TryteString` in PyOTA.

Here, we encode our message with :py:meth:`TryteString.from_unicode` into
trytes.

.. literalinclude:: ../examples/tutorials/02_send_data.py
:lines: 10-11
:lineno-start: 10

To put anything (transactions) on the Tangle, it needs to be associated with
an address. **Since we will be posting a zero-value transaction, nobody has to
own this address**; therefore we can use the :py:meth:`TryteString.random` (an
:py:class:`Address` is just a :py:class:`TryteString` with some additional
attributes and fixed length) method to generate one.

.. literalinclude:: ../examples/tutorials/02_send_data.py
:lines: 13-14
:lineno-start: 13

To tag our transaction, we might define a custom :py:class:`Tag` object.
Notice, that the ``b`` means we are passing a `bytestring`_ value instead of a
unicode string. This is so that PyOTA interprets our input as literal trytes,
rather than a unicode string that needs to be encoded into trytes.

When passing a bytestring to a PyOTA class, each byte is interpreted as a tryte;
therefore we are restricted to the `tryte alphabet`_.

.. literalinclude:: ../examples/tutorials/02_send_data.py
:lines: 16-22
:lineno-start: 16

It's time to construct the transaction. According to :ref:`Transaction Types`,
PyOTA uses :py:class:`ProposedTransaction` to build transactions that are not
yet broadcast to the network. Oberve, that the ``value=0`` means this is
a zero-value transaction.

.. literalinclude:: ../examples/tutorials/02_send_data.py
:lines: 24-25
:lineno-start: 24

Next, we send the transfer to the node for tip selection,
proof-of-work calculation, broadcasting and storing. The API takes care of
all these tasks, and returns the resulting ``Bundle`` object.

.. note::

:py:meth:`~Iota.send_transfer` takes a list of :py:class:`ProposedTransaction`
objects as its ``transfers`` argument. An IOTA transfer (bundle) usually
consists of multiple transactions linked together, however, in this simple
example, there is only one transaction in the bundle. Regardless, you need
to pass this sole transaction as a list of one transaction.

.. literalinclude:: ../examples/tutorials/02_send_data.py
:lines: 27-28
:lineno-start: 27

Finally, we print out the transaction's link on the Tangle Explorer.
Observe how we extract the transaction hash from the response ``dict``. We take
the first element of the bundle, as it is just a sequence of transactions, and
access its ``hash`` attribute.

.. _PyOTA Bug Tracker: https://github.com/iotaledger/iota.py/issues
.. _bytestring: https://docs.python.org/3/library/stdtypes.html#bytes
.. _tryte alphabet: https://docs.iota.org/docs/getting-started/0.1/introduction/ternary#tryte-encoding
.. _Tangle Explorer: https://utils.iota.org
7 changes: 7 additions & 0 deletions docs/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ converted; garbage in, garbage out!
^^^^^^^^^^^^
.. automethod:: TryteString.as_trits

Generation
~~~~~~~~~~

**random**
^^^^^^^^^^
.. automethod:: TryteString.random

Seed
----
.. autoclass:: Seed
Expand Down
12 changes: 12 additions & 0 deletions examples/tutorials/01_hello_node.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Import neccessary modules
from iota import Iota
from pprint import pprint

# Declare an API object
api = Iota('https://nodes.devnet.iota.org:443')

# Request information about the node
response = api.get_node_info()

# Using pprint instead of print for a nicer looking result in the console
pprint(response)
28 changes: 28 additions & 0 deletions examples/tutorials/02_send_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from iota import Iota, TryteString, Address, Tag, ProposedTransaction
from pprint import pprint

# Declare an API object
api = Iota('https://nodes.devnet.iota.org:443', testnet=True)

# Prepare custom data
my_data = TryteString.from_unicode('Hello from the Tangle!')

# Generate a random address that doesn't have to belong to anyone
my_address = Address.random()

# Tag is optional here
my_tag = Tag(b'MY9FIRST9TAG')

# Prepare a transaction object
tx = ProposedTransaction(
address=my_address,
value=0,
tag=my_tag,
message=my_data
)

# Send the transaction to the network
response = api.send_transfer([tx])

pprint('Check your transaction on the Tangle!')
pprint('https://utils.iota.org/transaction/%s/devnet' % response['bundle'][0].hash)
4 changes: 4 additions & 0 deletions iota/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ def random(cls, length=None):
:return:
:py:class:`TryteString` object.
:raises TypeError:
- if ``length`` is negative,
- if ``length`` is not defined, and the class doesn't have ``LEN`` attribute.
"""
alphabet = list(itervalues(AsciiTrytesCodec.alphabet))
generator = SystemRandom()
Expand Down

0 comments on commit 5a3aecd

Please sign in to comment.