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.