The purpose of this tutorial is to demonstrate how EOSFactory and its Python CLI can be used to make interacting with EOS easy & intuitive.
- This tutorial assumes that you have successfully installed EOSFactory. If it's not the case, please refer to Installing EOSFactory.
- We also assume that you are familiar with the official EOS tutorials, as they will give you a broader context and explain the rationale behind EOS smart-contracts.
Open a bash terminal (or if you are on Windows, open an Ubuntu bash terminal supplied by Windows Subsystem for Linux) and run Python CLI:
python3Once in the Python shell, import the EOSFactory library:
from eosfactory.eosf import *To start your own single-node local testnet:
reset()Besides starting a reset nodeos executable, the command reset() cleans EOSFactory: deletes account objects, wallets, etc.
On MacOS the EOSIO process is run in the background with no visible interface. However in Ubuntu & Windows it's launched in a separate window.
To verify the EOSIO node is running or to get information about the current state of the testnet:
info()To stop the current testnet:
stop()To continue running the same testnet:
resume()To stop the current testnet and start a new one:
reset()First, make sure a local testnet is running:
reset()Next, create a master account from which other accounts can be created:
create_master_account("master")As a result, a global (in the current script) variable called master (or whatever name you pass as the parameter) is created and from now on you can use it anywhere in the code, for example:
master.info()NOTE: The name
masteris just a name of a variable, not the actual name of the account created on the blockchain. The actual (physical) name of the account isstr(master).
You don't need to worry about locking or unlocking the wallet, managing its password or importing private keys into it. All of this is being taken care of by EOS Factory behind the scenes.
Test accounts can be created using such command:
create_account("charlie", master)Such actions happen while creating an account:
- the given account name is checked for uniqueness, if positive, break;
- a random physical name of the new account is determined;
- two pairs of cryptographic keys are produced;
- a wallet is opened and unlocked;
- two private keys are imported to the wallet;
- a new account is send to the blockchain;
- confirmation from the blockchain is received.
Again, a global (in the current script) variable, this time called charlie, is created and from now on can be used anywhere in the code, for example:
charlie.info()NOTE: If you don't specify the
account_nameparameter increate_account()which is the third parameter, a random name is applied, which is useful on a public testnet where extra restrictions apply. You can see it:str(charlie)
However, if you want to assign a specific name to an account, you can still do it, for example:
create_account("charlie2", master, account_name="charlie4eos")NOTE: You cannot create the same account variable twice (EOSFactory protects yourself against non-uniqueness), that's why we use a different name for the variable to be created, i.e.
charlie2.
And then run the info() command to verify that the charlie4eos name is actually assigned to the account referenced by the charlie2 variable:
charlie2.info()We assume that a local testnet is running and initialized:
reset()
create_master_account("master")To create a reference to an already existing contract, first create an account which will host the contract:
create_account("host", master)And then create a reference to the contract by supplying the host account and the path to the folder where the contract is located, for example:
smart = Contract(host, "/mnt/c/Workspaces/EOS/eosfactory/contracts/eosio_token")Alternatively, supply just the name of the folder, if it can be found in the standard location, i.e. eosfactory/contracts, for example:
smart = Contract(host, "eosio_token")Before deploying, the contract needs to be built from the source code. To build the contract invoke its build() method:
smart.build()At this stage the contract has no code deployed. You can check it by running its code() method:
smart.code()To deploy the contract use its deploy() method:
smart.deploy()And now you can verify that the hash of the deployed code is non-zero:
smart.code()To create a new token we call the create action on the eosio.token contract:
host.push_action(
"create",
{
"issuer": master,
"maximum_supply": "1000000000.0000 EOS",
"can_freeze": "0",
"can_recall": "0",
"can_whitelist": "0"
}, [master, host])NOTE: The
push_actionmethod takes three arguments: the action's name, the action's arguments in JSON format and the accounts whose permission is needed, in this casemaster&host.
NOTE: If you want to see the actual transaction without broadcasting it, use the
show_actionmethod instead ofpush_action, for example:
host.show_action(
"create",
{
"issuer": master,
"maximum_supply": "1000000000.0000 EOS",
"can_freeze": "0",
"can_recall": "0",
"can_whitelist": "0"
}, [master, host])We'll need two accounts. To create them just run:
create_account("alice", master)
create_account("carol", master)Now that we have created the token, the issuer can issue new tokens to alice:
host.push_action(
"issue",
{
"to": alice, "quantity": "100.0000 EOS", "memo": ""
},
master)NOTE: In this case the permission is assigned to the default
masteraccount.
Now that alice has tokens, we will transfer some of them to carol:
host.push_action(
"transfer",
{
"from": alice, "to": carol,
"quantity": "25.0000 EOS", "memo":""
},
alice)NOTE: As the third argument we pass the reference to the
aliceaccount to indicate that she is the one who authorized this action.
From the contract's ABI we know that the table keeping track of the token balances is called accounts.
Let's check the state of both accounts involved in the previous transaction:
host.table("accounts", alice)host.table("accounts", carol)NOTE: The
table()method takes two arguments: the name of the table as specified by the contract ABI and the scope within the contract in which the table is found.
This is the result you should get for alice:
{
"rows": [{
"balance": "75.0000 EOS"
}
],
"more": False
}And this is for carol:
{
"rows": [{
"balance": "25.0000 EOS"
}
],
"more": False
}To stop the local testnet:
stop()To exit Python CLI:
exit()Alternatively, use the ctrl-D shortcut.
The python blocks in the current Markdown document can be executed with a provided bash tool. While the working directory is the root of the EOSFactory installation, do:
eosfactory/pythonmd.sh docs/tutorials/02.InteractingWithEOSContractsInEOSFactory.md