<p>I believe the error stems from the <code>chain_context.submit_tx(signed_tx)</code> because the API expects CBOR encoded transaction (couple lines above).</p>
<p>You might want to try</p>
<p><code>chain_context.submit_tx(signed_tx.to_cbor())</code></p>

CC BY-SA 4.0
2023-03-30T09:44:46.717Z
2023-03-30T09:44:46.717Z
sorki
<p>I am trying to use the <a href="https://github.com/Python-Cardano/pycardano/blob/main/examples/native_token.py" rel="nofollow noreferrer">https://github.com/Python-Cardano/pycardano/blob/main/examples/native_token.py</a> with minor changes, like pointing to mainnet (have tried preview as well). I have updated the address to point to my actual wallet and trying to create an nft. I am getting the below error</p>
<p>File &quot;\Desktop\CDrive\work\Python3.7\lib\site-packages\pycardano\backend\blockfrost.py&quot;, line 230, in submit_tx
self.api.transaction_submit(f.name)
File &quot;\Desktop\CDrive\work\Python3.7\lib\site-packages\blockfrost\utils.py&quot;, line 63, in error_wrapper
raise ApiError(request_response)
blockfrost.utils.ApiError: {'error': 'Bad Request', 'message': '&quot;transaction read error RawCborDecodeError [DecoderErrorDeserialiseFailure \&quot;Byron Tx\&quot; (DeserialiseFailure 1 \&quot;Size mismatch when decoding TxAux.\\nExpected 2, but found 4.\&quot;),DecoderErrorDeserialiseFailure \&quot;Shelley Tx\&quot; (DeserialiseFailure 1 \&quot;Size mismatch when decoding \\nRecord RecD.\\nExpected 4, but found 3.\&quot;),DecoderErrorDeserialiseFailure \&quot;Shelley Tx\&quot; (DeserialiseFailure 1 \&quot;Size mismatch when decoding \\nRecord RecD.\\nExpected 4, but found 3.\&quot;),DecoderErrorDeserialiseFailure \&quot;Shelley Tx\&quot; (DeserialiseFailure 1 \&quot;Size mismatch when decoding \\nRecord RecD.\\nExpected 4, but found 3.\&quot;),DecoderErrorDeserialiseFailure \&quot;Shelley Tx\&quot; (DeserialiseFailure 79 \&quot;expected string\&quot;),DecoderErrorDeserialiseFailure \&quot;Shelley Tx\&quot; (DeserialiseFailure 79 \&quot;expected string\&quot;)]&quot;', 'status_code': 400}</p>
<p>I am not sure what is wrong, would be of great help if anyone can guide me to get it working. The same code minor change has given have also faced &quot;  File &quot;\Desktop\CDrive\work\Python3.7\lib\tempfile.py&quot;, line 481, in func_wrapper
return func(*args, **kwargs)
TypeError: a bytes-like object is required, not 'Transaction'&quot;</p>
<p>Below is the full python file</p>
<p>&quot;&quot;&quot;
This is a complete walk through of minting a NFT on Cardano blockchain in pure Python code.</p>
<p>This example is inspired by <a href="https://developers.cardano.org/docs/native-tokens/minting-nfts#crafting-the-transaction" rel="nofollow noreferrer">https://developers.cardano.org/docs/native-tokens/minting-nfts#crafting-the-transaction</a></p>
<p>import pathlib</p>
<p>from blockfrost import ApiUrls</p>
<p>from pycardano import *</p>
<h1>Copy your BlockFrost project ID below. Go to <a href="https://blockfrost.io/" rel="nofollow noreferrer">https://blockfrost.io/</a> for more information.</h1>
<p>BLOCK_FROST_PROJECT_ID = &quot;&quot;
NETWORK = Network.MAINNET</p>
<p>chain_context = BlockFrostChainContext(
project_id=BLOCK_FROST_PROJECT_ID,
base_url=ApiUrls.mainnet.value, #ApiUrls.preprod.value,
)</p>
<p>&quot;&quot;&quot;Preparation&quot;&quot;&quot;</p>
<h1>Define the root directory where images and keys will be stored.</h1>
<p>PROJECT_ROOT = &quot;blockfrost&quot;
root = pathlib.Path(PROJECT_ROOT)
print(PROJECT_ROOT)</p>
<h1>Create the directory if it doesn't exist</h1>
<p>root.mkdir(parents=True, exist_ok=True)</p>
<p>&quot;&quot;&quot;Generate keys&quot;&quot;&quot;
key_dir = root / &quot;keys&quot;
key_dir.mkdir(exist_ok=True)</p>
<h1>Load payment keys or create them if they don't exist</h1>
<p>def load_or_create_key_pair(base_dir, base_name):
skey_path = base_dir / f&quot;{base_name}.skey&quot;
vkey_path = base_dir / f&quot;{base_name}.vkey&quot;</p>
<pre><code>if skey_path.exists():
    skey = PaymentSigningKey.load(str(skey_path))
    vkey = PaymentVerificationKey.from_signing_key(skey)
else:
    key_pair = PaymentKeyPair.generate()
    key_pair.signing_key.save(str(skey_path))
    key_pair.verification_key.save(str(vkey_path))
    skey = key_pair.signing_key
    vkey = key_pair.verification_key
return skey, vkey
</code></pre>
<h1>Payment address. Send some ADA (~5 ADA is enough) to this address, so we can pay the minting fee later.</h1>
<p>payment_skey, payment_vkey = load_or_create_key_pair(key_dir, &quot;payment&quot;)
address = &quot;&lt;myWalletAddress&quot;</p>
<h1>address = Address(payment_vkey.hash(), network=NETWORK)</h1>
<pre><code>#&quot;addr_test1qqxypmc96e3pska6ch2ucq4uv5d7uz6nhpgcne4ea4hgmemv40lpm3wmc3wqk5arjpgzrccm0m9k72puaqzwsgrj47asmp86u7&quot; #Address(payment_vkey.hash(), network=NETWORK)
</code></pre>
<p>print(address)</p>
<h1>Generate policy keys, which will be used when minting NFT</h1>
<p>policy_skey, policy_vkey = load_or_create_key_pair(key_dir, &quot;policy&quot;)</p>
<p>&quot;&quot;&quot;Create policy&quot;&quot;&quot;</p>
<h1>A policy that requires a signature from the policy key we generated above</h1>
<p>pub_key_policy = ScriptPubkey(policy_vkey.hash())</p>
<h1>A time policy that disallows token minting after 10000 seconds from last block</h1>
<p>must_before_slot = InvalidHereAfter(chain_context.last_block_slot + 10000)</p>
<h1>Combine two policies using ScriptAll policy</h1>
<p>policy = ScriptAll([pub_key_policy, must_before_slot])</p>
<h1>Calculate policy ID, which is the hash of the policy</h1>
<p>policy_id = policy.hash()
print(f&quot;Policy ID: {policy_id}&quot;)
with open(root / &quot;policy.id&quot;, &quot;a+&quot;) as f:
f.truncate(0)
f.write(str(policy_id))
#******************************************************************************************************************************************
&quot;&quot;&quot;Define NFT&quot;&quot;&quot;</p>
<h1>Create an asset container</h1>
<p>my_asset = Asset()</p>
<h1>Create names for our assets</h1>
<p>nft1 = AssetName(b&quot;MY_NFT_1&quot;)
nft2 = AssetName(b&quot;MY_NFT_2&quot;)</p>
<h1>Put assets into the asset container with a quantity of 1</h1>
<p>my_asset[nft1] = 1
my_asset[nft2] = 1</p>
<h1>Create a MultiAsset container</h1>
<p>my_nft = MultiAsset()</p>
<h1>Put assets into MultiAsset container. In this example, we only have one policy.</h1>
<h1>However, MultiAsset container can hold multiple different policies.</h1>
<p>my_nft[policy_id] = my_asset</p>
<h1>Create the final native script that will be attached to the transaction</h1>
<p>native_scripts = [policy]
#******************************************************************************************************************************************
&quot;&quot;&quot;Define NFT (Alternative)&quot;&quot;&quot;</p>
<h1>The nft definition above is somewhat verbose.</h1>
<h1>We can also directly create native assets from python primitives.</h1>
<p>my_nft_alternative = MultiAsset.from_primitive(
{
policy_id.payload: {  # Use policy ID created from above. We can't use policy_id here because policy_id's type  # is ScriptHash, which is not a primitive type. Instead, we use policy_id.payload (bytes)
b&quot;MY_NFT_1&quot;: 1,  # Name of our NFT1  # Quantity of this NFT
b&quot;MY_NFT_2&quot;: 1,  # Name of our NFT2  # Quantity of this NFT
}
}
)</p>
<h1>my_nft and my_nft_alternative are equivalent</h1>
<p>assert my_nft == my_nft_alternative
#******************************************************************************************************************************************
&quot;&quot;&quot;Create metadata&quot;&quot;&quot;</p>
<h1>We need to create a metadata for our NFTs, so they could be displayed correctly by blockchain explorer</h1>
<p>metadata = {
721: {  # 721 refers to the metadata label registered for NFT standard here:
# <a href="https://github.com/cardano-foundation/CIPs/blob/master/CIP-0010/registry.json#L14-L17" rel="nofollow noreferrer">https://github.com/cardano-foundation/CIPs/blob/master/CIP-0010/registry.json#L14-L17</a>
policy_id.payload.hex(): {
&quot;MY_NFT_1&quot;: {
&quot;description&quot;: &quot;This is my first NFT thanks to PyCardano&quot;,
&quot;name&quot;: &quot;PyCardano NFT example token 1&quot;,
&quot;id&quot;: 1,
&quot;image&quot;: &quot;ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw&quot;,
},
&quot;MY_NFT_2&quot;: {
&quot;description&quot;: &quot;This is my second NFT thanks to PyCardano&quot;,
&quot;name&quot;: &quot;PyCardano NFT example token 2&quot;,
&quot;id&quot;: 2,
&quot;image&quot;: &quot;ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw&quot;,
},
}
}
}</p>
<h1>Place metadata in AuxiliaryData, the format acceptable by a transaction.</h1>
<p>auxiliary_data = AuxiliaryData(AlonzoMetadata(metadata=Metadata(metadata)))</p>
<p>&quot;&quot;&quot;Build transaction&quot;&quot;&quot;</p>
<h1>Create a transaction builder</h1>
<p>builder = TransactionBuilder(chain_context)</p>
<h1>Add our own address as the input address</h1>
<p>builder.add_input_address(address)</p>
<h1>Since an InvalidHereAfter rule is included in the policy, we must specify time to live (ttl) for this transaction</h1>
<p>builder.ttl = must_before_slot.after</p>
<h1>Set nft we want to mint</h1>
<p>builder.mint = my_nft</p>
<h1>Set native script</h1>
<p>builder.native_scripts = native_scripts</p>
<h1>Set transaction metadata</h1>
<p>builder.auxiliary_data = auxiliary_data</p>
<h1>Calculate the minimum amount of lovelace that need to hold the NFT we are going to mint</h1>
<p>min_val = min_lovelace(
chain_context, output=TransactionOutput(address, Value(0, my_nft))
)</p>
<h1>Send the NFT to our own address</h1>
<p>builder.add_output(TransactionOutput(address, Value(min_val, my_nft)))</p>
<h1>Create final signed transaction</h1>
<p>signed_tx = builder.build_and_sign([payment_skey], change_address=address)</p>
<h1>signed_tx = builder.build_and_sign([payment_skey, policy_skey], change_address=address)</h1>
<p>print(&quot;############### Transaction created ###############&quot;)
print(&quot;------------------------------Signed transaction------------------------------&quot;)
print(signed_tx)
print(&quot;-------------------------------------Signed to CBOR------------------------------&quot;)
print(signed_tx.to_cbor())</p>
<h1>Submit signed transaction to the network</h1>
<p>print(&quot;############### Submitting transaction ###############&quot;)</p>
<p>chain_context.submit_tx(signed_tx)</p>

<transaction><nft><native-assets><blockfrost><native>
TypeError: a bytes-like object is required, not 'Transaction'
# TypeError: a bytes-like object is required, not 'Transaction'

(Asked by: username_0 on 2023-03-02)

I am trying to use the https://github.com/Python-Cardano/pycardano/blob/main/examples/native_token.py with minor changes, like pointing to mainnet (have tried preview as well). I have updated the address to point to my actual wallet and trying to create an nft. I am getting the below error
File "\Desktop\CDrive\work\Python3.7\lib\site-packages\pycardano\backend\blockfrost.py", line 230, in submit_tx
self.api.transaction_submit(f.name)
File "\Desktop\CDrive\work\Python3.7\lib\site-packages\blockfrost\utils.py", line 63, in error_wrapper
raise ApiError(request_response)
blockfrost.utils.ApiError: {'error': 'Bad Request', 'message': '"transaction read error RawCborDecodeError [DecoderErrorDeserialiseFailure \"Byron Tx\" (DeserialiseFailure 1 \"Size mismatch when decoding TxAux.\\nExpected 2, but found 4.\"),DecoderErrorDeserialiseFailure \"Shelley Tx\" (DeserialiseFailure 1 \"Size mismatch when decoding \\nRecord RecD.\\nExpected 4, but found 3.\"),DecoderErrorDeserialiseFailure \"Shelley Tx\" (DeserialiseFailure 1 \"Size mismatch when decoding \\nRecord RecD.\\nExpected 4, but found 3.\"),DecoderErrorDeserialiseFailure \"Shelley Tx\" (DeserialiseFailure 1 \"Size mismatch when decoding \\nRecord RecD.\\nExpected 4, but found 3.\"),DecoderErrorDeserialiseFailure \"Shelley Tx\" (DeserialiseFailure 79 \"expected string\"),DecoderErrorDeserialiseFailure \"Shelley Tx\" (DeserialiseFailure 79 \"expected string\")]"', 'status_code': 400}
I am not sure what is wrong, would be of great help if anyone can guide me to get it working. The same code minor change has given have also faced "  File "\Desktop\CDrive\work\Python3.7\lib\tempfile.py", line 481, in func_wrapper
return func(*args, **kwargs)
TypeError: a bytes-like object is required, not 'Transaction'"
Below is the full python file
"""
This is a complete walk through of minting a NFT on Cardano blockchain in pure Python code.
This example is inspired by https://developers.cardano.org/docs/native-tokens/minting-nfts#crafting-the-transaction
import pathlib
from blockfrost import ApiUrls
from pycardano import *
Copy your BlockFrost project ID below. Go to https://blockfrost.io/ for more information.
BLOCK_FROST_PROJECT_ID = ""
NETWORK = Network.MAINNET
chain_context = BlockFrostChainContext(
project_id=BLOCK_FROST_PROJECT_ID,
base_url=ApiUrls.mainnet.value, #ApiUrls.preprod.value,
)
"""Preparation"""
Define the root directory where images and keys will be stored.
PROJECT_ROOT = "blockfrost"
root = pathlib.Path(PROJECT_ROOT)
print(PROJECT_ROOT)
Create the directory if it doesn't exist
root.mkdir(parents=True, exist_ok=True)
"""Generate keys"""
key_dir = root / "keys"
key_dir.mkdir(exist_ok=True)
Load payment keys or create them if they don't exist
def load_or_create_key_pair(base_dir, base_name):
skey_path = base_dir / f"{base_name}.skey"
vkey_path = base_dir / f"{base_name}.vkey"
if skey_path.exists():
    skey = PaymentSigningKey.load(str(skey_path))
    vkey = PaymentVerificationKey.from_signing_key(skey)
else:
    key_pair = PaymentKeyPair.generate()
    key_pair.signing_key.save(str(skey_path))
    key_pair.verification_key.save(str(vkey_path))
    skey = key_pair.signing_key
    vkey = key_pair.verification_key
return skey, vkey

Payment address. Send some ADA (~5 ADA is enough) to this address, so we can pay the minting fee later.
payment_skey, payment_vkey = load_or_create_key_pair(key_dir, "payment")
address = "
address = Address(payment_vkey.hash(), network=NETWORK)
#"addr_test1qqxypmc96e3pska6ch2ucq4uv5d7uz6nhpgcne4ea4hgmemv40lpm3wmc3wqk5arjpgzrccm0m9k72puaqzwsgrj47asmp86u7" #Address(payment_vkey.hash(), network=NETWORK)

print(address)
Generate policy keys, which will be used when minting NFT
policy_skey, policy_vkey = load_or_create_key_pair(key_dir, "policy")
"""Create policy"""
A policy that requires a signature from the policy key we generated above
pub_key_policy = ScriptPubkey(policy_vkey.hash())
A time policy that disallows token minting after 10000 seconds from last block
must_before_slot = InvalidHereAfter(chain_context.last_block_slot + 10000)
Combine two policies using ScriptAll policy
policy = ScriptAll([pub_key_policy, must_before_slot])
Calculate policy ID, which is the hash of the policy
policy_id = policy.hash()
print(f"Policy ID: {policy_id}")
with open(root / "policy.id", "a+") as f:
f.truncate(0)
f.write(str(policy_id))
#******************************************************************************************************************************************
"""Define NFT"""
Create an asset container
my_asset = Asset()
Create names for our assets
nft1 = AssetName(b"MY_NFT_1")
nft2 = AssetName(b"MY_NFT_2")
Put assets into the asset container with a quantity of 1
my_asset[nft1] = 1
my_asset[nft2] = 1
Create a MultiAsset container
my_nft = MultiAsset()
Put assets into MultiAsset container. In this example, we only have one policy.
However, MultiAsset container can hold multiple different policies.
my_nft[policy_id] = my_asset
Create the final native script that will be attached to the transaction
native_scripts = [policy]
#******************************************************************************************************************************************
"""Define NFT (Alternative)"""
The nft definition above is somewhat verbose.
We can also directly create native assets from python primitives.
my_nft_alternative = MultiAsset.from_primitive(
{
policy_id.payload: {  # Use policy ID created from above. We can't use policy_id here because policy_id's type  # is ScriptHash, which is not a primitive type. Instead, we use policy_id.payload (bytes)
b"MY_NFT_1": 1,  # Name of our NFT1  # Quantity of this NFT
b"MY_NFT_2": 1,  # Name of our NFT2  # Quantity of this NFT
}
}
)
my_nft and my_nft_alternative are equivalent
assert my_nft == my_nft_alternative
#******************************************************************************************************************************************
"""Create metadata"""
We need to create a metadata for our NFTs, so they could be displayed correctly by blockchain explorer
metadata = {
721: {  # 721 refers to the metadata label registered for NFT standard here:
# https://github.com/cardano-foundation/CIPs/blob/master/CIP-0010/registry.json#L14-L17
policy_id.payload.hex(): {
"MY_NFT_1": {
"description": "This is my first NFT thanks to PyCardano",
"name": "PyCardano NFT example token 1",
"id": 1,
"image": "ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw",
},
"MY_NFT_2": {
"description": "This is my second NFT thanks to PyCardano",
"name": "PyCardano NFT example token 2",
"id": 2,
"image": "ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw",
},
}
}
}
Place metadata in AuxiliaryData, the format acceptable by a transaction.
auxiliary_data = AuxiliaryData(AlonzoMetadata(metadata=Metadata(metadata)))
"""Build transaction"""
Create a transaction builder
builder = TransactionBuilder(chain_context)
Add our own address as the input address
builder.add_input_address(address)
Since an InvalidHereAfter rule is included in the policy, we must specify time to live (ttl) for this transaction
builder.ttl = must_before_slot.after
Set nft we want to mint
builder.mint = my_nft
Set native script
builder.native_scripts = native_scripts
Set transaction metadata
builder.auxiliary_data = auxiliary_data
Calculate the minimum amount of lovelace that need to hold the NFT we are going to mint
min_val = min_lovelace(
chain_context, output=TransactionOutput(address, Value(0, my_nft))
)
Send the NFT to our own address
builder.add_output(TransactionOutput(address, Value(min_val, my_nft)))
Create final signed transaction
signed_tx = builder.build_and_sign([payment_skey], change_address=address)
signed_tx = builder.build_and_sign([payment_skey, policy_skey], change_address=address)
print("############### Transaction created ###############")
print("------------------------------Signed transaction------------------------------")
print(signed_tx)
print("-------------------------------------Signed to CBOR------------------------------")
print(signed_tx.to_cbor())
Submit signed transaction to the network
print("############### Submitting transaction ###############")
chain_context.submit_tx(signed_tx)

**Tags:** transaction, nft, native-assets, blockfrost, native

---

## 1 answers

### Answer by username_1 on 2023-03-30. Score: 0

I believe the error stems from the `chain_context.submit_tx(signed_tx)` because the API expects CBOR encoded transaction (couple lines above).

You might want to try

`chain_context.submit_tx(signed_tx.to_cbor())`


---

