Developer Fundamentals
-- IV. States and Views
Learn how to retrieve data from smart contracts on VeChainThor, use ABIs, simulate transactions, and simplify function calls using the contract loader.
Interacting with Smart Contracts
Smart contracts can expose variables and functions for sharing their stored data publicly. To communicate with a contract, it is essential to have the interface definition, which can be retrieved from either a JSON file or the function definition in the source code.
Example Data
The example used below will utilize the VTHO contract, which manages VeChain's VTHO Token.
Smart Contract Address:
0x0000000000000000000000000000456e65726779
The contract's source code can be found on GitHub.
Its Application Binary Interface (ABI) is available on b32, a repository that gathers publicly available interfaces for VeChain projects. You can either:
a. Hardcode the ABI into the script
b. Import the ABI from a local energyAbi.json file (get the JSON file from the public repository)
c. Fetch the public ABI from the repository
Retrieving information from a smart contract involves calling a function, which can access variables, view functions, and even functions that alter the state for simulation purposes.
In this example, we'll fetch the ABI from the public repository.
To call a function within a contract, use contracts.executeCall, which requires the following parameters:
The contract's address as the first argument
The function ABI as the second argument
The function data as the third argument
A fourth parameter is optional and allows the user to provide the options for executing a contract call within a blockchain environment.
For example, if you want to access a basic variable name, such as the name of the VTHO contract, you can utilize the code snippet below:
With Parameters
When calling a function with parameters, the parameters should be passed as a list in the third argument. For instance, to check the balance of a specific address:
To retrieve data from a previous block, you can specify the block number or id by passing in a revision option:
Simulate Transaction
If a function could change the state, it would require a transaction. To check the success of a transaction, you can invoke the function first and examine the output or handle any potential errors.
For example, simulating a transfer that returns true if the caller has at least 1 VTHO:
If the transaction encounters an error, the method call will also throw an error, which needs to be handled appropriately.
Test It Yourself
The snippet below shows how you can make a request to the blockchain and the name of a specific contract:
Challenge Your Skills
Try the snippet above on your own to read historical data, simulate a transaction using the examples given earlier in this lesson.
contracts.load(address, abi)
To simplify interaction, a dynamic object can be created that can interact with passing less of the repeating arguments.
For example, contracts.read.name() can load the name without the need to pass the function signature, address, and thorClient every time.
Create Contract Object
To create a contract object, it needs to be created from the ThorClient:
The Contract-Loader always requires a JSON ABI Definition. Fragments are not supported.
'Read' Functions
Function calls are encapsulated within a sub-object named 'read'. This enables calling the contract for variable content, viewing functions, or performing simple transaction simulations.
Test It Yourself
The snippet below puts this lesson together and illustrates how you can make an elaborate request to the blockchain and receive data directly from a contract.
This is a full request that includes:
Read the name of the contract
Read the balance of a specific address
Read the past balance of that address
Simulate a transfer
Simulate the failure of a transfer
Join our Telegram