Skip to content

Commit

Permalink
docs: jenesis v6 updates (#182)
Browse files Browse the repository at this point in the history
* docs: jenesis v6 updates

* docs: minor fix

* docs: updates on contract and deployments

* docs: add contract updates

* docs: update add contract

Co-authored-by: James Riehl <33920192+jrriehl@users.noreply.github.com>
Co-authored-by: James Riehl <james.riehl@fetch.ai>
  • Loading branch information
3 people authored Jan 6, 2023
1 parent 06d4673 commit cb332fd
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 87 deletions.
105 changes: 55 additions & 50 deletions docs/add-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,65 @@
Once you have successfully created your project, you can add contract templates. You first need to navigate to your project's directory and run the following command:

```
jenesis add contract <TEMPLATE> <NAME>
jenesis add contract <TEMPLATE> <CONTRACT NAME>
```
You can find all the contract templates available in [Jenesis Templates](https://github.com/fetchai/jenesis-templates).
An example of how to add the template **starter** with the name `my_first_contract` is given below:
An example of how to add the template **cw20-base** with the name `my_token` is given below:

```
jenesis add contract starter my_first_contract
jenesis add contract cw20-base my_token
```

This ```add contract``` command will add a contract template to your jenesis project inside `contracts/my_first_contract/` folder. It will also update the `jenesis.toml` configuration file with the contract information under all existing profiles.

If you need multiple deployments of the same contract, you can use the `-d` flag to specify multiple deployments and name them.
```
jenesis add contract <TEMPLATE> <CONTRACT NAME> -d <DEPLOYMENTS>
```
Jenesis will add the deployments to all profiles for the specified contract.
In the example below, `token_1` and `token_2` deployments have been added. This will allow you to deploy `my_token` contract with two different configurations. You can add as many deployments as you wish.
```
jenesis add contract cw20-base my_token -d token_1 token_2
```
[profile.my_profile.contracts.my_first_contract]
contract = "my_first_contract"

If no deployments are selected when adding a contract, the default deployment name will be equal to the contract name.

This ```add contract``` command will add a contract template to your jenesis project inside `contracts/my_token/` folder. It will also update the `jenesis.toml` configuration file with the contract information.

```toml
[profile.testing.contracts.token_1]
name = "token_1"
contract = "my_token"
network = "fetchai-testnet"
deployer_key = ""
init_funds = ""

[profile.testing.contracts.token_2]
name = "token_2"
contract = "my_token"
network = "fetchai-testnet"
deployer_key = ""
init_funds = ""

[profile.my_profile.contracts.my_first_contract.init]
count = ""
[profile.testing.contracts.token_1.init]

[profile.testing.contracts.token_2.init]
```

The `deployer_key` field can be manually specified, you can choose any private key locally available to deploy any specific contract. You can also leave this field empty since the ```deploy``` command has an optional argument to deploy all contracts inside a specified profile with the same key, overriding this `deployer_key` argument in the `jenesis.toml` file. See [deploy contracts](deploy-contracts.md) for more information.

Finally, the `init` section contains the parameters needed in the instantiation message for this contract to be deployed. The required parameters are taken from the `instantiate_msg.json` file inside the `contracts` directory. You will need to manually add the values for these parameters in their correct variable type, which are listed in `contracts/my_first_contract/schema/instantiate_msg.json`. For this contract **my_first_contract** we need to add an integer value to the `count` field.
Finally, the `init` section contains the parameters needed in the instantiation message for this contract to be deployed. The required parameters are taken from the schema file inside the `contracts` directory. Since this contract template doesn't include a schema, it will be generated when [compiling](compile-contracts.md) the `my_token` contract loading the init fields to the `jenesis.toml` file. You will need to manually add the values for these parameters in their correct variable type, which are listed on the schema file. For this **my_token** contract, we need to fill the following init fields for each deployment after [compiling](compile-contracts.md). Here is an example:

```
[profile.my_profile.contracts.my_first_contract.init]
count = 10
[profile.testing.contracts.token_1.init]
decimals = 6
name = "my_token_name"
symbol = "SYMBOL"
initial_balances = [{ address = "fetch1d25ap9danl4726uk2nt307y630v87h3h2vq6pl", amount = "5000"}]
[profile.testing.contracts.token_2.init]
decimals = 6
name = "my_token_name_2"
symbol = "SYMBOL"
initial_balances = [{ address = "fetch1d25ap9danl4726uk2nt307y630v87h3h2vq6pl", amount = "2000"}]
```

If your contract requires nested instantiation messages you may add fields following this structure:
Expand All @@ -38,7 +70,7 @@ If your contract requires nested instantiation messages you may add fields follo
price = {amount = 1000, denom = DLS}
info = {performance = {max_speed = 200, unit = kph}, fuel = {consumption = 7, unit = kmpl}}
```
> *NOTE: Before editing the `jenesis.toml` configuration file with the desired `deployer_key` and `init` parameters, make sure to first [compile](compile-contracts.md) your contract. All configuration parameters will restart every time a contract is compiled to make sure everything is up to date.*
> *NOTE: Before editing the `jenesis.toml` configuration file with the desired `deployer_key` and `init` parameters, make sure to first [compile](compile-contracts.md) your contract. All configuration parameters will restart every time a contract is compiled if the schema has changed.*
You can also add contracts manually by copying and pasting the contract directory from another project you may have, however, they need to follow the same directory structure as the **starter** template mentioned above.

Expand All @@ -49,50 +81,23 @@ jenesis update
```
The `update` command will automatically detect which contract is missing in the `jenesis.toml` configuration file by revising the contracts directory.

# Add contract deployments
You can add multiple deployments for any given contract in your project by running:

```
jenesis add deployment my_first_contract deployment_name
```
This will automatically create another my_first_contract entry called deployment_name without the need of adding a duplicated contract template to your project. This command will update your jenesis.toml file to:
# Add contract deployments
You can also add further deployments for a given contract by specifying the contract name and the deployment name. If we want to add a third token called `token_3` using `my_token` contract, we can run:

```
[profile.testing.contracts.my_first_contract]
name = "my_first_contract"
contract = "my_first_contract"
network = "fetchai-testnet"
deployer_key = "alice"
init_funds = ""
[profile.testing.contracts.my_first_contract.init]
count = 1
[profile.testing.contracts.deployment_name]
name = "deployment_name"
contract = "my_first_contract"
network = "fetchai-testnet"
deployer_key = "alice"
init_funds = ""
[profile.testing.contracts.deployment_name.init]
count = 1
jenesis add deployment my_token token_3
```
This will automatically create another deployment entry called `token_3`.

# Attach deployed contracts

If you add a contract into the project's contract folder that has already been deployed in the network, you can attach it to your project for future interaction using the ```attach``` command.
If you add a contract into the project's contract folder that has already been deployed in the network, you can attach the deployment to your project for future interaction using the ```attach``` command.

To add a contract to yout project you can run:
To add a deployment to yout project you can run:

```
jenesis add contract starter my_first_contract
```

If you add the contract just by copying and pasting it, you will need to run:

```
jenesis update
jenesis add contract cw20-base my_token -d token_1
```

Then compile the contract:
Expand All @@ -101,10 +106,10 @@ Then compile the contract:
jenesis compile
```

To attach the contract, you will need to specify the contract's name and deployment address. You can optionally specify the profile where you wish to insert the contract into. If this is not specified, the deployment will be attached to the default profile, which is the first profile created in your project, unless the `default` settings are manually changed.
To attach the contract, you will need to specify the deployment's name and address. You can optionally specify the profile where you wish to insert the contract into. If this is not specified, the deployment will be attached to the default profile, which is the first profile created in your project, unless the `default` settings are manually changed.

```
jenesis attach my_first_contract fetch18xs97q6h9zgh4sz730a42pp0dqa9sh4eef7eutfkv69q3v2y3x8s72pkua
jenesis attach token_1 fetch18xs97q6h9zgh4sz730a42pp0dqa9sh4eef7eutfkv69q3v2y3x8s72pkua
```

This will add the relevant deployment information into a `jenesis.lock` file and you will now be able to interact with `my_first_contract` using [contract interactions](use-contracts.md)
This will add the relevant deployment information into a `jenesis.lock` file and you will now be able to interact with `token_1` using [contract interactions](use-contracts.md)
1 change: 0 additions & 1 deletion docs/add-profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,5 @@ is_local = false

[profile.my_second_profile.contracts]
```
If there are existing contracts in your project, all of them will be added to the new profile.

Currently available network configurations are `fetchai-testnet`, `fetchai-mainnet`, and `fetchai-localnode`, but Jenesis is easily configurable for other networks by directly editing the `jenesis.toml` file.
9 changes: 7 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ There are multiple commands integrated into jenesis that allow you to perform a
- `deploy`
- `run`
- `shell`
- `network`

## Create a new project
Create a project using the ```new``` command
Expand All @@ -33,7 +34,11 @@ This will create a new directory called `my_project`. You can use `--profile` an
```toml
[project]
name = "my_project"
authors = [ "Alice Tyler <alice@mail.com>",]
authors = [ "Alice Tyler <alice@mail.com>"]
keyring_backend = "os"

[profile.my_profile]
default = true

[profile.my_profile.network]
name = "fetchai-testnet"
Expand All @@ -48,7 +53,7 @@ is_local = false
[profile.my_profile.contracts]
```

The project name is the argument passed to the ```new``` command while the authors field is populated by querying the user's GitHub username and email address. The profile's network will be filled with the relevant configuration variables. The contracts field will remain empty until new contracts are added.
The project name is the argument passed to the ```new``` command while the authors field is populated by querying the user's GitHub username and email address. The profile's network will be filled with the relevant configuration variables. The contracts field will remain empty until new contracts are added. This `my_profile` profile will be set as the default profile, this means that every time you use a jenesis command without specifying a profile, `my_profile` will be used.

An empty `contracts` folder will also be created inside `my_project` directory that will eventually contain all the information needed to compile and deploy the desired contracts.

Expand Down
79 changes: 45 additions & 34 deletions docs/use-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ You can interact with your project's contracts by using the ```shell``` or ```ru
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:

```bash
jenesis add contract starter my_first_contract
jenesis add contract token my_token
jenesis add contract starter my_first_contract -d deployment_1
jenesis add contract cw20-base my_token -d token_1
jenesis compile
```

Expand All @@ -31,16 +31,17 @@ You will observe the following text indicating the available contracts in your p
```
Network: fetchai-testnet
Detecting contracts...
C my_first_contract
C my_token
C deployment_1
C token_1
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.*
> *NOTE: `jenesis shell` currently requires that contract names use accepted python variable names. For example, using `token-1` instead of `token_1` 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:
In this case, we can see that `deployment_1` and `token_1` deployments are available for this project. If these contracts have been already deployed you can directly interact with them by performing contract querys and executions such as:

```python
>>> my_first_contract.execute(args = {'msg_name': {...}}
>>> deployment_1.query(args = {'msg_name': {...}}
>>> deployment_1.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:
Expand All @@ -54,7 +55,30 @@ If the ledger is a testnet with a faucet url, you can get funds using the `fauce
>>> 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.
## Dynamic Methods

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

For example, the following query

```python
>>> token_1.query({"balance": {"address": str(wallet.address())}}))
```
can also be run with:
```python
>>> token_1.balance(address=str(wallet.address()))
{'balance': '4000'}
```

Similarly, instead of using `token_1.execute...` , a transfer can be executed with:
```python
>>> token_1.transfer(amount='1000', recipient=str(wallet2.address()), sender=wallet)
```

Jensesis also has an autocompletion helper for query, execution and deployment arguments. It will show automatically when typing in the shell.


We will now show an example assuming that the `token_1` deployment contract has only been compiled and not yet deployed, going through deployment, execution, and querying using dynamic methods.

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.

Expand All @@ -64,49 +88,35 @@ For this example, we will first generate two wallets. We provide wealth to the s
>>> 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.
We now proceed to deploy `my_token` contract using `token_1` deployment configuration, we define the arguments for the cw20 token: name, symbol, decimal, and the addresses that will be funded with these cw20 tokens. In this case we will fund wallet's address with 5000 tokens.

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

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

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

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

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

Finally, we query both wallet's balance

```python
>>> my_token.query({"balance": {"address": str(wallet.address())}})
>>> token_1.balance(address=str(wallet.address()))
{'balance': '4000'}
>>> my_token.query({"balance": {"address": str(wallet2.address())}})
>>> token_1.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:
```python
>>> my_token.balance(address=str(wallet.address()))
{'balance': '4000'}
```

Similarly, the transfer can be executed with:
```python
>>> 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:
Expand All @@ -117,15 +127,16 @@ 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())}}))
token_1.deploy(name="Crab Coin", symbol="CRAB", decimals=6, initial_balances=[{ "address": str(wallet.address()), "amount" : "5000"}], sender=wallet)

print("wallet initial cw20 MT balance: ", token_1.balance(address=str(wallet.address())))

tx = my_token.execute({'transfer': {'amount': '1000', 'recipient': str(wallet2.address())}}, sender=wallet)
tx = token_1.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())}}))
print("wallet final cw20 MT balance: ", token_1.balance(address=str(wallet.address())))
print("wallet2 final cw20 MT balance: ", token_1.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:
Expand Down

0 comments on commit cb332fd

Please sign in to comment.