đCounter
This tutorial guides you through creating a smart contract with a Counter.
the This tutorial guides you through creating a smart contract using the Concordium default contract template. The contract maintains a counter value in its state.
Prerequisites
To follow along with this tutorial, ensure you have the following:
Follow these steps to create the contract:
Step 1: Initialize Project
Create a working directory called "counter" and navigate to it in your terminal with these commands:
Install "cargo-generate" (a helper tool for Rust project initialization) within your working directory with this command:
When you run the command, you will get the following result:
Run the following command to set up the initial project:
Select the "Default" option from the menu and provide a name and description for your project when prompted:
Afterward, your project will be created with the default smart contract template:
Run the following commands to see what the project folder contains:
You will see the following:
Here's a short description of the project folder's contents:
Cargo.toml: Manifest file containing project details like name, dependencies, build instructions, and configurations.
deploy-scripts: Directory for scripts deploying smart contracts to the Concordium network, including code building, deployment, and interaction management.
src: Core directory for smart contract code, typically containing Rust source files defining logic and functions.
tests: Directory for Rust unit tests ensuring smart contract functionality, aiding error detection and code consistency.
Step 2: Define the Contract Structure
Open the project folder in your code editor. Go to the "src > lib.rs" directory:
This is a basic skeleton of a smart contract containing the following:
State
struct: Holds the data your smart contract stores.init
function: Creates a new instance of your smart contract.Error
enum: Defines custom errors your contract can throw.view
function: Allows reading the contract's state without modifying it.receive
function: Handles incoming transactions and interacts with the contract's state.
In the
State
struct, modify the code to include a field named "counter" of type "i8" for the integer. This field will hold the counter value:
In the
init
function, return aState
object and initialize the counter field to "0". This will set the starting value of the counter when the smart contract is created:
Add the values
OwnerError
,IncrementError
, andDecrementError
to theError
enum to enhance error handling for ownership and counter-manipulation scenarios:
Here's a short description of the purpose of these error values:
OwnerError
: Stops unauthorized users from changing the counter value.IncrementError
: Catches attempts to decrease the counter disguised as increments (negative increment values).DecrementError
(potential): Would prevent attempts to increase the counter disguised as decrements (negative decrement values).
Step 3: Implement Increment Function
Add a function to increment the counter value. Ensure that the function can only be called by the contract owner and that the input parameter is positive:
Note the following:
The value must be positive, otherwise, you will get an
Error::IncrementError
.The owner of the contract instance must trigger the transaction, or it will throw
Error::OwnerError
.The function itself has to be mutable because you will change the state of the contract.
Step 4: Implement Decrement Function
Add a function to decrement the counter value. Similar to the increment function, ensure it can only be called by the contract owner and that the input parameter is negative:
If the input parameter is not negative, you will get a
Error::DecrementError
. Like the Increment counter, this function can be triggered by only the owner of the contract, otherwise it will throw anError::OwnerError
.
Step 5: Implement View Function
Create a function to retrieve the current counter value. This function should return the counter value as an i8 type, updating its return value within the host.state()
:
Step 6: Build and Deploy the Contract
Create a folder named "dist" in your project directory.
Run the following command. This command will generate the schema output file and the Wasm compiled contract and place them in the "dist" folder for you:
You will see the following in your terminal:
3. Deploy it with the command below:
When you run the command, you will see the following in your terminal:
Run the following command to initialize it and create your contract instance so you'll be ready to invoke the functions in the next section:
When you run the command, you'll see the following:
Step 7: Interact with the Contract
After deploying the contract, you can interact with it using various functions. View Function
Check the initial state of the contract with the following command:
When you run the command, you will see the following:
Since you just initialized the contract, the counter value is 0.
Increment Function
Create a JSON file that holds your operator, which will be given as input to the function.
Run the following command to increment the counter:
Start by testing with conditions. Try using another account other than the contract's owner, confirming that only the owner can call this function.
You will receive the error code -2, indicating that you call the second error code from your Error enum, OwnerError.
Update the state with a number, for example, 2:
Check the state once more. It should be 2:
To test the requirement that you cannot increment with a negative number, change the value in the JSON file to a negative number like -2:
You cannot do it because of error code -3, which corresponds to the third element in the enum:
IncrementError
.
Test the decrement function in the same way as the increment function.
Congratulations! You've successfully created and tested a smart contract with a counter using the Concordium platform.
Last updated