Skip to content

Serialization with aioeos

antelopy has full integration for the aioeos package.

Simple token transfer

In this example, a simple token transfer is performed. It is assumed that you have used aioeos before, and this guide won't cover the usage of the package.

Initialisation

First, import necessary modules, and then initialize the ABI cache, reading the eosio.token account's ABI from chain.

Python
import asyncio
from decimal import Decimal

from aioeos import EosAccount, EosAction, EosJsonRpc, EosTransaction

from antelopy import AbiCache

CHAIN_ENDPOINT = "https://waxtestnet.greymass.com"

abi_cache = AbiCache(
    chain_endpoint=CHAIN_ENDPOINT,
    chain_package="aioeos",
)
abi_cache.read_abi("eosio.token")
Make sure to include the chain_package parameter when creating the AbiCache.

aioeos configuration

Next is defining an RPC and account to use with aioeos.

Danger

Don't put your keys in your code. Hardcoding your private key into your code is a huge security risk.

For production environments, check out OWASP's cheat sheet on secrets management.

For working locally, check out the Secrets Management article from Microsoft's Code With Engineering Playbook for tips on ways to manage secrets for local development.

The private key in the example below is one that was randomly generated for these docs, and is not the real key.

Python
RPC = EosJsonRpc(CHAIN_ENDPOINT)

# DO NOT put your key directly in your code.
wax_account = EosAccount(
    name="professoroak",
    private_key="5J2yE5oNnEfAmdBQtzLTo979ptHXXidmQXNvDcAFP9AJVMKnmkb",
)

Creating the transaction

First, the transfer action and an aioeos.EosTransaction are created, and then the AbiCache's async_sign_and_push function is used to serialize the transaction, sign it, and asynchronously send it to the chain endpoint.

Python
async def transfer_token():
    transfer_value = Decimal("3.14").quantize(Decimal("1.00000000")) # (1)!
    transfer_action = EosAction(
        account="eosio.token",
        name="transfer",
        authorization=[wax_account.authorization("active")],
        data={
            "from": wax_account.name,
            "to": "officerjenny",
            "quantity": f"{transfer_value} WAX",
            "memo": "This is an example transfer!",
        },
    )

    block = await RPC.get_head_block()
    transaction = EosTransaction(
        ref_block_num=block["block_num"] & 65535,
        ref_block_prefix=block["ref_block_prefix"],
        actions=[transfer_action],
    )
    chain_response = await abi_cache.async_sign_and_push(
        RPC, [wax_account], transaction
    )
    return chain_response
  1. I strongly recommend using python's decimal module to handle numbers, especially when calculating values.
    Decimal.quantize can be used to format the value to the correct precision.
    e.g. Decimal("3.14").quantize(Decimal("1.00000000")) = Decimal("3.14000000")

The async_sign_and_push function

The async_sign_and_push function in line 45 takes the following arguments:

Parameter Description Value in example
rpc an EosJsonRpc instance RPC
signing_accounts list of EosAccount instances [wax_account]
trx an EosTransaction instance transaction

The AbiCache knows from the chain_package="aioeos" declaration back in the initialisation step that it will be receiving instances of aioeos classes, and handles the serialization and signing of the transaction accordingly. It then uses the RPC that was passed in the function to push the transaction to the blockchain.

Finally, we call the async function. The returned response is a dict containing the JSON response from the endpoint.

Python
if __name__ == "__main__":
    response_from_blockchain = asyncio.run(transfer_token())

The whole script

Python
import asyncio
from decimal import Decimal

from aioeos import EosAccount, EosAction, EosJsonRpc, EosTransaction

from antelopy import AbiCache

CHAIN_ENDPOINT = "https://waxtestnet.greymass.com"

abi_cache = AbiCache(
    chain_endpoint=CHAIN_ENDPOINT,
    chain_package="aioeos",
)
abi_cache.read_abi("eosio.token")

RPC = EosJsonRpc(CHAIN_ENDPOINT)

# DO NOT put your key directly in your code.
wax_account = EosAccount(
    name="professoroak",
    private_key="5J2yE5oNnEfAmdBQtzLTo979ptHXXidmQXNvDcAFP9AJVMKnmkb",
)


async def transfer_token():
    transfer_value = Decimal("3.14").quantize(Decimal("1.00000000"))
    transfer_action = EosAction(
        account="eosio.token",
        name="transfer",
        authorization=[wax_account.authorization("active")],
        data={
            "from": wax_account.name,
            "to": "officerjenny",
            "quantity": f"{transfer_value} WAX",
            "memo": "This is an example transfer!",
        },
    )

    block = await RPC.get_head_block()
    transaction = EosTransaction(
        ref_block_num=block["block_num"] & 65535,
        ref_block_prefix=block["ref_block_prefix"],
        actions=[transfer_action],
    )
    chain_response = await abi_cache.async_sign_and_push(
        RPC, [wax_account], transaction
    )
    return chain_response


if __name__ == "__main__":
    response_from_blockchain = asyncio.run(transfer_token())