Skip to content

Contract Interaction

You can interact with your project's contracts by using the shell or run commands.

Previous steps

To reproduce the examples in this document, add and compile a basic starter contract and a cw20 token contract to your project with the following commands:

jenesis add contract starter my_first_contract
jenesis add contract token my_token
jenesis compile

For more contract template examples visit Jenesis Templates

Interactive Shell

To open a shell where you can easily interact with your contracts, run:

jenesis shell
If a profile is not selected, the default profile will be selected automatically. You can specify any profile using the --profile optional argument:

jenesis shell --profile my_profile

You will observe the following text indicating the available contracts in your project.

Network: fetchai-testnet
Detecting contracts...
C my_first_contract
C my_token
Detecting contracts...complete

NOTE: jenesis shell currently requires that contract names use accepted python variable names. For example, using my-first-contract instead of my_first_contract will generate an error when trying to interact with it.

In this case, we can see that my_first_contract and my_token contracts are available for this project. If these contracts have been already deployed you can directly interact with them by performing contract executions such as:

>>> my_first_contract.execute(args = {'msg_name': {...}}

A ledger client (ledger) and your locally stored wallet keys will also be available in the shell. For example, if you have a local key named alice, you will find this under wallets['alice'] and you can query the balance as follows:

>>> ledger.query_bank_balance(wallets['alice'])
10000000000000000000

If the ledger is a testnet with a faucet url, you can get funds using the faucet:

>>> faucet.get_wealth(wallets['alice'])

We will show an example assuming that the my_token contract has only been compiled and not yet deployed, going through deployment, execution, and querying.

For this example, we will first generate two wallets. We provide wealth to the sender wallet in atestfet so it can pay for transaction fees.

>>> wallet = LocalWallet.generate()
>>> wallet2 = LocalWallet.generate()
>>> faucet.get_wealth(wallet)

We now proceed to deploy my_token contract, we define the arguments for the cw20 token: name, symbol, decimal, and the addresses that will be funded with these my_token tokens. In this case we will fund wallet's address with 5000 tokens.

>>> my_token.deploy({"name": "Crab Coin", "symbol": "CRAB", "decimals": 6, "initial_balances": [{"address": str(wallet.address()), "amount": "5000"}]}, wallet)

We can query wallet balance to make sure it has been funded with cw20 tokens

>>> my_token.query({"balance": {"address": str(wallet.address())}})
{'balance': '5000'}

We now execute a cw20 token transfer of 1000 tokens from wallet to wallet2

>>> my_token.execute({'transfer': {'amount': '1000','recipient': str(wallet2.address())}}, sender=wallet)

Finally, we query both wallet's balance

>>> my_token.query({"balance": {"address": str(wallet.address())}})
{'balance': '4000'}
>>> my_token.query({"balance": {"address": str(wallet2.address())}})
{'balance': '1000'}
We can observe that wallet has sent 1000 tokens to wallet2.

Queries and Executions as Dynamic Methods

Jenesis also attaches the contract query and execution messages as dynamic methods.

For example, the above queries can also be run with:

>>> my_token.balance(address=str(wallet.address()))
{'balance': '4000'}

Similarly, the transfer can be executed with:

>>> my_tokentransfer(wallet, amount='1000', recipient=str(wallet2.address()))

Executing Scripts

You can also assemble the above commands into a script that is executable by the run command:

from cosmpy.aerial.wallet import LocalWallet

wallet = LocalWallet.generate()
faucet.get_wealth(wallet.address())
wallet2 = LocalWallet.generate()

my_token.deploy({"name": "My Token","symbol": "MT", "decimals": 6, "initial_balances": [{"address": str(wallet.address()), "amount": "5000"}]}, wallet)
print("wallet initial cw20 MT balance: ", my_token.query({"balance": {"address": str(wallet.address())}}))

tx = my_token.execute({'transfer': {'amount': '1000', 'recipient': str(wallet2.address())}}, sender=wallet)
print("transfering 1000 cw20 MT tokens from wallet to wallet2")
tx.wait_to_complete()

print("wallet final cw20 MT balance: ", my_token.query({"balance": {"address": str(wallet.address())}}))
print("wallet2 final cw20 MT balance: ", my_token.query({"balance": {"address": str(wallet2.address())}}))

If we paste the above code into the file script.py inside the project's directory, we can run it with:

jenesis run script.py

And you will observe the same output as before. You can also specify the profile as an optional argument using --profile.

You can visit CosmPy for more contract interaction examples.