From 54c416de13c859a48266adcc6721a1d36f44aa8e Mon Sep 17 00:00:00 2001 From: Pino' Surace Date: Thu, 1 Aug 2024 14:10:17 +0200 Subject: [PATCH 1/3] Improve wasmd instantiate2, execute and migrate sections --- src/pages/wasmd/getting-started/cli.mdx | 355 +++++++++++++++++++++--- 1 file changed, 319 insertions(+), 36 deletions(-) diff --git a/src/pages/wasmd/getting-started/cli.mdx b/src/pages/wasmd/getting-started/cli.mdx index bdd56a39..ccf9cde5 100644 --- a/src/pages/wasmd/getting-started/cli.mdx +++ b/src/pages/wasmd/getting-started/cli.mdx @@ -56,7 +56,7 @@ ID. wasmd q tx 2C19314D369E7EF3C77CBD1B33E02DB0401619B5C8E1B1E5BD15AB46C3704E96 -o json ``` -Output: +The command will return a JSON object similar to the following: ```json { @@ -128,7 +128,7 @@ To query the metadata of a specific code ID, use the following command: wasmd q wasm code-info $CODE_ID -o json ``` -Output: +The command will return a JSON object similar to the following: ```json { @@ -268,7 +268,7 @@ To query the metadata of a specific contract, use the following command: wasmd q wasm contract $CONTRACT -o json ``` -Output: +The command will return a JSON object similar to the following: ```json { @@ -309,116 +309,379 @@ Output: ## Instantiation with Predictable Address +Instantiation with a predictable address refers to the process of deploying a smart contract on a +blockchain such that the resulting contract address can be determined in advance. This is +particularly useful in scenarios where you need to know the contract address before its actual +deployment for purposes like pre-configuring other contracts or systems to interact with it. + ### Create a new contract instance with predictable address +First, we need to define a salt value. The salt is a unique value that, when combined with the +contract's code ID and initialization parameters, helps derive a unique and predictable contract +address. This ensures that even if the same contract code and initialization parameters are used, +different salt values will result in different contract addresses. + ```sh -RESP=$(wasmd tx wasm instantiate2 "$CODE_ID" "$INIT" 10 \ +SALT=10 +``` + +Run the following command to instantiate the contract with predicatable address: + +```sh +wasmd tx wasm instantiate2 "$CODE_ID" "$INIT" "$SALT" \ --admin="$ALICE_ADDR" \ --from alice \ --amount="100stake" \ --label "local0.1.0" \ - --fix-msg \ --gas 1000000 \ -y \ --chain-id=docs-chain-1 \ - -b sync \ -o json \ - --keyring-backend=test) - -sleep 6 - -CONTRACT_PREDICTABLE=$(wasmd query wasm list-contract-by-code "$CODE_ID" -o json | jq -r '.contracts[-1]') - -# Print contract address -echo "* Predictable contract address: $CONTRACT_PREDICTABLE" + --keyring-backend=test ``` +- `wasmd tx wasm instantiate2 "$CODE_ID" "$INIT" "$SALT"` instantiates a new contract instance with + the specified code ID, initialization parameters, and the salt value +- `--admin="$ALICE_ADDR"` specifies Alice as the admin who can later update the contract +- `--from alice` specifies Alice as the sender of the transaction +- `--amount="100stake"`: Sends `100 stake` to the contract upon instantiation +- `--label "local0.1.0"` assigns a label to this contract instance for easy identification +- `--gas 1000000` sets the gas limit for the transaction +- `-y` automatically accepts the transaction without prompting for confirmation +- `--chain-id=docs-chain-1` specifies the chain ID of the blockchain +- `-o json` outputs the result in JSON format +- `--keyring-backend=test` specifies the keyring backend to use + ### Query contracts by code id -You can get a list of contracts instantiated from a specific Code ID, by running the following -command: +To get a list of contracts instantiated from a specific Code ID, you can use the following command. +This will query the blockchain and return a JSON object containing the addresses of the contracts +associated with the given Code ID. ```sh -wasmd q wasm list-contract-by-code $CODE_ID +wasmd q wasm list-contract-by-code $CODE_ID -o json ``` +The command will return a JSON object similar to the following: + +```json +{ + "contracts": [ + "wasm1wug8sewp6cedgkmrmvhl3lf3tulagm9hnvy8p0rppz9yjw0g4wtqhs9hr8", + "wasm19ph090ka8tzrd2wrp8gnn7lachwt7r2npvf6rdnd3ha3jv5n5gqquzcpd0" + ], + "pagination": { + "next_key": null, + "total": "0" + } +} +``` + +- "contracts": This array contains the addresses of the contracts instantiated from the specified + Code ID. In this example, there are two contracts associated with the Code ID. + ### Query contracts by creator -You can get a list of contracts instantiated from a specific creator, by running the following -command: +To get a list of contracts instantiated by a specific creator, you can use the following command. +This will query the blockchain and return a JSON object containing the addresses of the contracts +associated with the given creator's address. ```sh -wasmd q wasm list-contracts-by-creator $ALICE_ADDR +wasmd q wasm list-contracts-by-creator $BOB_ADDR -o json +``` + +The command will return a JSON object similar to the following: + +```json +{ + "contract_addresses": [], + "pagination": { + "next_key": null, + "total": "0" + } +} ``` +- "contract_addresses": This array contains the addresses of the contracts instantiated by the + specified creator. In this example, there are two contracts associated with Bob's address + ## Execution +Executing a command on a WASM contract involves sending a transaction that includes specific +instructions (or messages) to the contract. This process allows you to interact with the contract, +triggering predefined functions and operations defined within its code. + ### Execute a command on a wasm contract -To execute a command on a wasm contract you can run the following commands: +First, you define the message you want to send to the contract. In this example we want to call the +release function of the contract: + +```sh +MSG='{"release":{}}' +``` + +Run the following command to execute the message on the contract: ```sh -echo "## Execute contract $CONTRACT" +wasmd tx wasm execute "$CONTRACT" "$MSG" \ + --from alice \ + --gas 1000000 \ + -y \ + --chain-id=docs-chain-1 \ + -o json \ + --keyring-backend=test +``` + +- `"$CONTRACT"` specifies the address of the contract +- `"$MSG"` specifies the message to execute +- `--from alice` specifies Alice as the sender of the transaction +- `--gas 1000000` sets the gas limit for the transaction +- `-y` automatically accepts the transaction without prompting for confirmation +- `--chain-id=docs-chain-1` specifies the chain ID of the blockchain +- `-o json` outputs the result in JSON format +- `--keyring-backend=test` specifies the keyring backend to use + +By querying the transaction using the `txhash`, we can check the events emited by the contract. The +output will look similar to the following: + +```json +{ + ... + "events": [ + ... + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmwasm.wasm.v1.MsgExecuteContract", + "index": true + }, + { + "key": "sender", + "value": "wasm1hvgm6p76gccgg4dl4caa8a7v03dsqww6r9sk4g", + "index": true + }, + { + "key": "module", + "value": "wasm", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "execute", + "attributes": [ + { + "key": "_contract_address", + "value": "wasm1wug8sewp6cedgkmrmvhl3lf3tulagm9hnvy8p0rppz9yjw0g4wtqhs9hr8", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + ] +} +``` + +Events are logs emitted by the contract during its execution, providing detailed information about +the actions performed and the resulting state changes. + +Below is the full script that combines all the steps for executing a command on a WASM contract and +querying the events: +```sh +# Define the message to send to the contract, in this case a "release" command MSG='{"release":{}}' +# Execute the contract with the specified message RESP=$(wasmd tx wasm execute "$CONTRACT" "$MSG" \ --from alice \ --gas 1000000 \ -y \ --chain-id=docs-chain-1 \ - -b sync \ -o json \ --keyring-backend=test) +# Wait for the transaction to be processed sleep 6 -wasmd q tx $(echo "$RESP"| jq -r '.txhash') -o json | jq +# Query the transaction using its hash to check the events emitted by the contract +wasmd q tx $(echo "$RESP" | jq -r '.txhash') -o json | jq ``` ### Query contract state +To query the state of a WASM contract, you can use the following command. + ```sh wasmd query wasm contract-state all "$CONTRACT" -o json | jq -r '.models[0].value' | base64 -d | jq ``` +The output will look similar to this: + +```json +{ + "models": [ + { + "key": "636F6E666967", + "value": "eyJ2ZXJpZmllciI6Indhc20xaHZnbTZwNzZnY2NnZzRkbDRjYWE4YTd2MDNkc3F3dzZyOXNrNGciLCJiZW5lZmljaWFyeSI6Indhc20xcGEyOWxhYzVzODVrZ2o3cG45ejZnYzB0NHNxZ3psbGNndWhmMjQiLCJmdW5kZXIiOiJ3YXNtMWh2Z202cDc2Z2NjZ2c0ZGw0Y2FhOGE3djAzZHNxd3c2cjlzazRnIn0=" + } + ], + "pagination": { + "next_key": null, + "total": "0" + } +} +``` + +- `"models"` contains key-value pairs representing the state data of the contract base64-encoded. + +We can decode the contract state using the following command: + +```sh +wasmd query wasm contract-state all "$CONTRACT" -o json | jq -r '.models[0].value' | base64 -d +``` + +The output will be similar to the following: + +```json +{ + "verifier": "wasm1hvgm6p76gccgg4dl4caa8a7v03dsqww6r9sk4g", + "beneficiary": "wasm1pa29lac5s85kgj7pn9z6gc0t4sqgzllcguhf24", + "funder": "wasm1hvgm6p76gccgg4dl4caa8a7v03dsqww6r9sk4g" +} +``` + ## Migration +Migration is the process of upgrading an existing contract to a new version without changing its +address or losing its state. This ensures that the contract can evolve over time while preserving +the data of the original contract. + ### Migrate a wasm contract to a new code version +First, upload the new contract code to the blockchain: + +```sh +RESP=$(wasmd tx wasm store "./x/wasm/keeper/testdata/burner.wasm" \ + --from alice \ + --gas 1100000 \ + -y \ + --chain-id=docs-chain-1 \ + -o json \ + --keyring-backend=test) +``` + +Query the transaction to get the code ID of the newly uploaded code: + ```sh -echo "## Migrate contract" -echo "### Upload new code" +RESP=$(wasmd q tx $(echo "$RESP" | jq -r '.txhash') -o json) +BURNER_CODE_ID=$(echo "$RESP" | jq -r '.events[] | select(.type=="store_code").attributes[] | select(.key=="code_id").value') +``` + +Set up the migration message that will be used during the migration process. + +```sh +DEST_ACCOUNT=$(wasmd keys show bob -a --keyring-backend=test) +MIGRATION_MSG="{\"payout\": \"$DEST_ACCOUNT\"}" +``` +Next, migrate the existing contract to use the new code ID. + +```sh +RESP=$(wasmd tx wasm migrate "$CONTRACT" "$BURNER_CODE_ID" "$MIGRATION_MSG" \ + --from alice \ + --chain-id=docs-chain-1 \ + -y \ + -o json \ + --keyring-backend=test) +``` + +Finally, query the transaction to check its status and view the results + +```sh +wasmd q tx $(echo "$RESP" | jq -r '.txhash') -o json +``` + +The output will be similar to the following: + +```json +{ + ... + "events": [ + ... + { + "type": "migrate", + "attributes": [ + { + "key": "code_id", + "value": "3", + "index": true + }, + { + "key": "_contract_address", + "value": "wasm1wug8sewp6cedgkmrmvhl3lf3tulagm9hnvy8p0rppz9yjw0g4wtqhs9hr8", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + ] +} +``` + +In this case, the contract was migrated to use code ID 3. + +Below is the full script that combines all the steps for a wasm contract to a new code version + +```sh +# Upload the new contract code RESP=$(wasmd tx wasm store "./x/wasm/keeper/testdata/burner.wasm" \ --from alice \ --gas 1100000 \ -y \ --chain-id=docs-chain-1 \ - --node=http://localhost:26657 \ - -b sync \ -o json \ --keyring-backend=test) +# Wait for the transaction to be processed sleep 6 +# Query the transaction to get the code ID RESP=$(wasmd q tx $(echo "$RESP" | jq -r '.txhash') -o json) BURNER_CODE_ID=$(echo "$RESP" | jq -r '.events[] | select(.type=="store_code").attributes[] | select(.key=="code_id").value') -echo "### Migrate to code id: $BURNER_CODE_ID" - +# Get the destination account address DEST_ACCOUNT=$(wasmd keys show bob -a --keyring-backend=test) +# Define the migration message +MIGRATION_MSG="{\"payout\": \"$DEST_ACCOUNT\"}" -RESP=$(wasmd tx wasm migrate "$CONTRACT" "$BURNER_CODE_ID" "{\"payout\": \"$DEST_ACCOUNT\"}" \ +# Migrate the contract to the new code ID +RESP=$(wasmd tx wasm migrate "$CONTRACT" "$BURNER_CODE_ID" "$MIGRATION_MSG" \ --from alice \ --chain-id=docs-chain-1 \ - -b sync \ -y \ -o json \ --keyring-backend=test) +# Wait for the transaction to be processed sleep 6 +# Query the migration transaction wasmd q tx $(echo "$RESP" | jq -r '.txhash') -o json | jq ``` @@ -427,10 +690,12 @@ wasmd q tx $(echo "$RESP" | jq -r '.txhash') -o json | jq You can query the history entries for a contract by running the following command: ```sh -wasmd q wasm contract-history $CONTRACT -o json | jq +wasmd q wasm contract-history $CONTRACT -o json ``` -Output: +This command retrieves the history of changes made to the specified contract, including initial +instantiation and subsequent migrations. The command will return a JSON object similar to the +following: ```json { @@ -466,12 +731,21 @@ Output: } ``` +Each entry provides details about a specific operation performed on the contract. Entry Fields: + +- `"operation"` is the type of operation performed, such as initialization or migration. +- `"code_id"` is the code ID associated with the operation. +- `"updated"` contains information about when the operation was performed. +- `"msg"` is the message payload associated with the operation. + ### Set contract admin The admin is the only address that can migrate a contract. The admin can be updated by the current admin with the following command. In this case, the admin is updated from Alice's address to Bob's address. +Run the following command to update the contract admin: + ```sh wasmd tx wasm set-contract-admin \ "$CONTRACT" \ @@ -482,15 +756,24 @@ wasmd tx wasm set-contract-admin \ -y ``` +After running this command, Bob will be the new admin of the contract, and only he will have the +authority to migrate the contract to a new code version or further update the admin role. + ### Clear contract admin -You can clear the admin address from a contract. This action prevents any further migration. +Clearing the admin address from a WASM contract removes the ability to migrate the contract to a new +code version. This action effectively locks the contract, preventing any further migrations. + +Run the following command to clear the contract admin: ```sh wasmd tx wasm clear-contract-admin \ "$CONTRACT" \ - --from alice \ + --from bob \ --keyring-backend=test \ --chain-id=docs-chain-1 \ -y ``` + +After running this command, the contract will no longer have an admin, and no one will be able to +migrate the contract to a new code version. From 54d44a6dcc13c5e269fe42bdc2df171d29976d03 Mon Sep 17 00:00:00 2001 From: Pino' Surace Date: Thu, 1 Aug 2024 14:29:38 +0200 Subject: [PATCH 2/3] Fix errors and typos --- src/pages/wasmd/getting-started/cli.mdx | 27 +++++++++---------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/pages/wasmd/getting-started/cli.mdx b/src/pages/wasmd/getting-started/cli.mdx index ccf9cde5..d09d6dd3 100644 --- a/src/pages/wasmd/getting-started/cli.mdx +++ b/src/pages/wasmd/getting-started/cli.mdx @@ -377,8 +377,7 @@ The command will return a JSON object similar to the following: } ``` -- "contracts": This array contains the addresses of the contracts instantiated from the specified - Code ID. In this example, there are two contracts associated with the Code ID. +In this example, there are two contracts associated with the Code ID. ### Query contracts by creator @@ -402,18 +401,15 @@ The command will return a JSON object similar to the following: } ``` -- "contract_addresses": This array contains the addresses of the contracts instantiated by the - specified creator. In this example, there are two contracts associated with Bob's address +In this example, there are no contract addresses associated with Bob's address. ## Execution -Executing a command on a WASM contract involves sending a transaction that includes specific -instructions (or messages) to the contract. This process allows you to interact with the contract, -triggering predefined functions and operations defined within its code. +Executing a command on a WASM contract involves sending a message to the contract. ### Execute a command on a wasm contract -First, you define the message you want to send to the contract. In this example we want to call the +First, we have to define the message to send to the contract. In this example we want to call the release function of the contract: ```sh @@ -441,7 +437,7 @@ wasmd tx wasm execute "$CONTRACT" "$MSG" \ - `-o json` outputs the result in JSON format - `--keyring-backend=test` specifies the keyring backend to use -By querying the transaction using the `txhash`, we can check the events emited by the contract. The +By querying the transaction using the `txhash`, we can check the events emitted by the contract. The output will look similar to the following: ```json @@ -493,7 +489,7 @@ output will look similar to the following: } ``` -Events are logs emitted by the contract during its execution, providing detailed information about +`Events` are logs emitted by the contract during its execution, providing detailed information about the actions performed and the resulting state changes. Below is the full script that combines all the steps for executing a command on a WASM contract and @@ -524,7 +520,7 @@ wasmd q tx $(echo "$RESP" | jq -r '.txhash') -o json | jq To query the state of a WASM contract, you can use the following command. ```sh -wasmd query wasm contract-state all "$CONTRACT" -o json | jq -r '.models[0].value' | base64 -d | jq +wasmd query wasm contract-state all "$CONTRACT" -o json ``` The output will look similar to this: @@ -544,7 +540,7 @@ The output will look similar to this: } ``` -- `"models"` contains key-value pairs representing the state data of the contract base64-encoded. +`Models` are key-value pairs representing the state data of the contract base64-encoded. We can decode the contract state using the following command: @@ -731,7 +727,7 @@ following: } ``` -Each entry provides details about a specific operation performed on the contract. Entry Fields: +Each `entry` provides details about a specific operation performed on the contract. Entry Fields: - `"operation"` is the type of operation performed, such as initialization or migration. - `"code_id"` is the code ID associated with the operation. @@ -741,10 +737,7 @@ Each entry provides details about a specific operation performed on the contract ### Set contract admin The admin is the only address that can migrate a contract. The admin can be updated by the current -admin with the following command. In this case, the admin is updated from Alice's address to Bob's -address. - -Run the following command to update the contract admin: +admin with the following command: ```sh wasmd tx wasm set-contract-admin \ From ce6ff31047b9f4f7b37eef5e5144223c2ac617fe Mon Sep 17 00:00:00 2001 From: Pino' Surace Date: Thu, 15 Aug 2024 12:14:58 +0200 Subject: [PATCH 3/3] Fix comments --- src/pages/wasmd/getting-started/cli.mdx | 39 ++++++++++++------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/pages/wasmd/getting-started/cli.mdx b/src/pages/wasmd/getting-started/cli.mdx index d09d6dd3..8c422ede 100644 --- a/src/pages/wasmd/getting-started/cli.mdx +++ b/src/pages/wasmd/getting-started/cli.mdx @@ -142,10 +142,10 @@ The command will return a JSON object similar to the following: } ``` -- Code ID: This is the reference to the stored WASM code -- Creator: This is the address of the account that uploaded the code -- Data Hash: This is the checksum of the stored WASM code -- Instantiate Permission: This is the instantiate permission configuration. It is optional, and the +- `"code_id"` is the reference to the stored WASM code +- `"creator"` is the address of the account that uploaded the code +- `"data_hash"` is the checksum of the stored WASM code +- `"instantiate_permission"` is the instantiate permission configuration. It is optional, and the default value is `Everybody`, which means everybody can create an instance of the uploaded WASM code @@ -288,24 +288,23 @@ The command will return a JSON object similar to the following: } ``` -- Address: This is the address of the contract on the blockchain. It uniquely identifies the - contract and is used for interacting with it. -- Code ID: This is the reference to the stored WASM code from which the contract was instantiated. -- Creator: This is the blockchain address of the account that initially instantiated the contract. - It indicates who created the contract instance. -- Admin: This is the address of the account that has administrative privileges over the contract, - such as the ability to execute migrations. This field is optional and can be set during - instantiation. -- Label: This is an optional field used to give a human-readable label to the contract. It helps in +- `"address"` is the address of the contract on the blockchain. It uniquely identifies the contract + and is used for interacting with it. +- `"code_id"` is the reference to the stored WASM code from which the contract was instantiated. +- `"creator"` is the blockchain address of the account that initially instantiated the contract. It + indicates who created the contract instance. +- `"admin"` is the address of the account that has administrative privileges over the contract, such + as the ability to execute migrations. This field is optional and can be set during instantiation. +- `"label"` is an optional field used to give a human-readable label to the contract. It helps in identifying the contract instance, especially when multiple instances of the same code are deployed. -- Created: This section provides details about the transaction in which the contract was - instantiated, including the block height at which the contract was created and the index of the - transaction within the block. -- IBC Port ID: This is the Port ID for Inter-Blockchain Communication [IBC](../../ibc.mdx). If the +- `"created"` section provides details about the transaction in which the contract was instantiated, + including the block height at which the contract was created and the index of the transaction + within the block. +- `"ibc_port_id"` is the Port ID for Inter-Blockchain Communication [IBC](../../ibc.mdx). If the contract is set up to interact with other blockchains via IBC, this field will contain the relevant port ID. -- Extention: This is is an extension point to store custom metadata within the persistence model +- `"extension"` is is an extension point to store custom metadata within the persistence model ## Instantiation with Predictable Address @@ -489,8 +488,8 @@ output will look similar to the following: } ``` -`Events` are logs emitted by the contract during its execution, providing detailed information about -the actions performed and the resulting state changes. +`"events"` are logs emitted by the contract during its execution, providing detailed information +about the actions performed and the resulting state changes. Below is the full script that combines all the steps for executing a command on a WASM contract and querying the events: