Skip to content

Commit a5abfe1

Browse files
authored
Update docs (#469)
1 parent 0f412ac commit a5abfe1

File tree

3 files changed

+119
-1
lines changed

3 files changed

+119
-1
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ could be beneficial for faster R&D iterations.
4848
- [x] Pool certificate
4949
- [x] Protocol proposal update
5050
- [x] Governance actions
51-
- [ ] Byron Address
51+
- [x] Byron Address
5252

5353

5454
### Installation
@@ -71,6 +71,10 @@ ensure_pure_cbor2.sh
7171

7272
https://pycardano.readthedocs.io/en/latest/
7373

74+
#### Frequently asked questions
75+
76+
https://pycardano.readthedocs.io/en/latest/frequently_asked_questions.html
77+
7478
### Examples
7579

7680
#### Transaction creation and signing
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
===
2+
FAQ
3+
===
4+
5+
What is PyCardano?
6+
------------------
7+
8+
PyCardano is a standalone Cardano client written in Python. The library is able to create and sign transactions
9+
without depending on third-party Cardano serialization tools, making it a light-weight library that is easy and fast to set up in all kinds of environments.
10+
11+
Where can I find some examples?
12+
-------------------------------
13+
You can find some examples in the `examples <https://github.com/Python-Cardano/pycardano/tree/main/examples>`_ directory. There is also a collection of examples under `awesome-pycardano <https://github.com/B3nac/awesome-pycardano>`_.
14+
15+
16+
What is a transaction builder?
17+
-------------------------------
18+
19+
A transaction builder is a class that helps you build and sign transactions. It provides a user-friendly interface that automatically handles transaction inputs, outputs, fees, and other details based on the context you provide.
20+
21+
Here is an example::
22+
23+
>>> # Create a transaction builder with a chain context
24+
>>> builder = TransactionBuilder(context)
25+
>>>
26+
>>> # Add inputs from an address
27+
>>> builder.add_input_address(address)
28+
>>>
29+
>>> # Add an output - sending 100 ADA to a recipient
30+
>>> recipient = Address.from_primitive("addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x")
31+
>>> builder.add_output(TransactionOutput(recipient, Value.from_primitive([100_000_000])))
32+
>>>
33+
>>> # Build, sign, and submit
34+
>>> signed_tx = builder.build_and_sign([payment_signing_key], change_address=address)
35+
>>> context.submit_tx(signed_tx)
36+
37+
38+
.. note::
39+
40+
The transaction builder in PyCardano is **stateful**. It maintains an internal state for the transaction under construction. Once you use it to build a transaction, that instance cannot be reused to build another transaction. If you need to create multiple transactions, instantiate a new transaction builder for each transaction or create a copy of the builder.
41+
42+
43+
44+
45+
How do I burn a token?
46+
----------------------
47+
48+
To burn a token, create a transaction that mints a negative amount of the token.
49+
50+
Here is an example::
51+
52+
>>> # Set up the transaction builder with the address containing the tokens
53+
>>> builder = TransactionBuilder(context)
54+
>>> builder.add_input_address(address)
55+
>>>
56+
>>> # Add the native script (policy) that governs the token
57+
>>> native_script = ScriptAll([pub_key_policy, must_before_slot])
58+
>>> builder.native_scripts = [native_script]
59+
>>>
60+
>>> # Mint negative amount to burn tokens
61+
>>> policy_id = bytes.fromhex("57fca08abbaddee36da742a839f7d83a7e1d2419f1507fcbf3916522")
62+
>>> builder.mint = MultiAsset.from_primitive({policy_id: {b"Token1": -100}})
63+
>>>
64+
>>> # Build, sign, and submit
65+
>>> signed_tx = builder.build_and_sign([payment_signing_key], change_address=address)
66+
>>> context.submit_tx(signed_tx)
67+
68+
.. note::
69+
70+
The negative amount in the ``mint`` field indicates burning. To burn 100 tokens, use ``-100``.
71+
72+
73+
Why does a decoded transaction have a different hash than the original transaction?
74+
------------------------------------------------------------------------------------
75+
76+
When you decode a transaction from CBOR using ``Transaction.from_cbor()`` and then re-encode it with ``to_cbor()``, you may notice that the resulting CBOR bytes (and therefore the transaction hash) are different from the original. This is due to non-deterministic CBOR encoding behavior in the C implementation of the ``cbor2`` library.
77+
78+
**Root Cause**
79+
80+
PyCardano uses `cbor2 <https://github.com/agronholm/cbor2/tree/master>`_ for CBOR encoding and decoding. The library has two implementations:
81+
82+
- **C implementation** (default): Faster but less deterministic
83+
- **Pure Python implementation**: Slightly slower but produces consistent, deterministic encodings
84+
85+
The C implementation does not guarantee that the order and structure of certain CBOR elements (such as map keys, array elements, or encoding choices for indefinite vs definite length arrays) will be preserved during deserialization and re-serialization. This can cause:
86+
87+
- **Transaction input order changes** - resulting in a different transaction hash and invalidating signatures (see `issue #311 <https://github.com/Python-Cardano/pycardano/issues/311>`_)
88+
- **Plutus data encoding changes** - altering datum hashes and breaking script validation (see `issue #466 <https://github.com/Python-Cardano/pycardano/issues/466>`_)
89+
90+
**Solution**
91+
92+
Use the **pure Python implementation** of cbor2, which provides deterministic encoding. PyCardano provides a convenience script to ensure the pure Python implementation is installed:
93+
94+
.. code-block:: bash
95+
96+
./ensure_pure_cbor2.sh
97+
98+
Or manually install it with:
99+
100+
.. code-block:: bash
101+
102+
pip uninstall -y cbor2
103+
pip install --no-binary cbor2 cbor2
104+
105+
**Best Practices**
106+
107+
- Always use the pure Python cbor2 implementation when working with pre-signed transactions or Plutus scripts
108+
- Avoid decoding and re-encoding signed transactions unless absolutely necessary
109+
- Test serialization round-trips if working with complex transactions
110+
- Keep the original CBOR bytes when you need to preserve the exact transaction structure
111+
112+
113+

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ making it a light-weight library that is easy and fast to set up in all kinds of
1515
:caption: Get Started
1616

1717
tutorial
18+
frequently_asked_questions
1819

1920
.. toctree::
2021
:maxdepth: 1

0 commit comments

Comments
 (0)