Develop an Aspect
This section guides you in building a dApp on Artela with a sample Aspect. This Aspect functions as a native extension, co-process with smart contract, and can be injected throughout the transaction lifecycle. In this example, we'll show how Aspect can identify and revert a specific transaction.
Pre-requisites:
1. Setting up a new projectβ
Make sure you have a recent version of Node.js and npm installed,
Start by installing the aspect-tool
:
npm install -g @artela/aspect-tool
Project Initialization, to kick off your project with aspect-tool
, follow these steps:
# Create a new directory and navigate into it
mkdir my-first-aspect && cd my-first-aspect
# Set up the npm project with aspect-tool
aspect-tool init
# Install the necessary dependencies
npm install
This will create a project directory with the following structure:
.
βββ README.md
βββ asconfig.json
βββ aspect <-- Your aspect code resides here
βΒ Β βββ index.ts <-- Entry functions for the aspect
βββ contracts <-- Place your smart contracts here
βββ package.json
βββ project.config.json
βββ scripts <-- Utility scripts, including deploying, binding and etc.
βΒ Β βββ aspect-deploy.cjs
βΒ Β βββ bind.cjs
βΒ Β βββ contract-call.cjs
βΒ Β βββ contract-deploy.cjs
βΒ Β βββ contract-send.cjs
βΒ Β βββ create-account.cjs
βββ tests
βββ tsconfig.json
2. Deploy a smart contractβ
2.1. Add a Smart Contractβ
Within the contracts
directory of your project, create your smart contract source files with a .sol
extension.
For example, create a HelloWorld.sol
file:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
contract HelloWorld {
address private owner;
constructor() {
owner = msg.sender;
}
function isOwner(address user) external view returns (bool result) {
return user == owner;
}
// print hello message
function hello() public pure returns (string memory) {
return "hello world";
}
}
2.2. Compile the Smart Contractβ
This step relies on solc
, first check if solc is
installed correctly
solc --version
Compile your contract using:
npm run contract:build
β Successful compilation will generate
HelloWorld.abi
andHelloWorld.bin
files in thebuild/contract
directory.
2.3. Deploy the Smart Contractβ
2.3.1 Update project.config.jsonβ
Update the project.config.json
in the root directory with the appropriate network configuration:
{
"node": "https://betanet-rpc1.artela.network"
}
For more details regarding testnet environment setup, please refer to artela testnet.
If you are using a local node, please use http://localhost:8545
instead.
2.3.2 Create a blockchain account (optional).β
If you already have an account, you can skip this step. You can just create a file named privateKey.txt
in the root directory and paste the hex format (with 0x prefix) private key to the file.
Execute the following command under the my-first-aspect
folder to create an account if you haven't already done so:
npm run account:create
β If an account gets created successfully, its private key will be dumped as
privateKey.txt
in the current directory.
For more detailed usage information about this command, please refer to the create-account command documentation.
If your account lacks test tokens, join DiscordοΌand request some
in testnet-faucet
channel.
2.3.4 Deploy your contractβ
Execute the following command within the my-first-aspect
folder, using the provided script:
npm run contract:deploy -- --abi ./build/contract/HelloWorld.abi \
--bytecode ./build/contract/HelloWorld.bin
β Upon successful deployment, the terminal will display the contract address.
For more detailed usage information about this command, please refer to the deploy-contract command documentation.
2.4 Call Contractβ
Execute the following command within the my-first-aspect
folder, call the Contract
2.4.1 call world
methodβ
Replace {smart-contract-address}
with the contract address you obtained from the previous step.
npm run contract:call -- --contract {smart-contract-address} \
--abi ./build/contract/HelloWorld.abi \
--method hello
β If the
hello
string is returned, it means that we have successfully deployed theHelloWorld
contract.
β Upon successful, the terminal will display call result.
For more detailed usage information about this command, please refer to the contract-call command documentation.
3. Create your Aspectβ
3.1. Implements an Aspectβ
The Aspect source files can be found in aspect/index.ts
.
For example, to add logic after a smart contract call execution, open index.ts
, locate the postContractCall
function, and insert your logic:
postContractCall(input: PostContractCallInput): void {
// Implement me...
}
For detailed instructions, refer to the Aspect Doc.
3.2. Access State Changes of Smart Contractβ
To integrate the state of the HelloWorld
contract with your Aspect, please follow the following steps:
- In
aspect/index.ts
, copy over the code in thepostContractCall
method. Ifhello
function is called, the Aspect revert the call
// 1. implement IPostContractCallJP
class Aspect implements IPostContractCallJP {
...
/**
* postContractCall is a join-point which will be invoked after a contract call has finished.
*
* @param input input to the current join point
*/
postContractCall(input: PostContractCallInput): void {
let txData = uint8ArrayToHex(input.call!.data);
// if call `hello` function then revert, 19ff1d21 is method signature of `hello`
if (txData.startsWith("19ff1d21")) {
sys.revert("the function `hello` not available");
}
}
...
}
3.3. Compile the Aspectβ
Build your Aspect:
npm run aspect:build
β The resulting
release.wasm
in thebuild
folder contains the necessary WASM bytecode.
3.4. Deploy the Aspectβ
Deploy your compiled Aspect:
npm run aspect:deploy -- --wasm ./build/release.wasm --joinPoints PostContractCall
β Upon successful execution, the terminal will display the
Aspect address
. It is essential to make a note of this address as it will be useful later on.
For more detailed usage information about this command, please refer to the deploy-aspect command documentation.
4. Bind the Smart Contract and Aspectβ
Deploying the Aspect doesn't automatically activate it. To make it functional, bind it to a smart contract:
npm run contract:bind -- --contract {smart-contract-address} \
--abi ./build/contract/HelloWorld.abi \
--aspectId {aspect-Id}
- replace the placeholder {smart-contract-address} with the information obtained from step
2 3 deploy the smart contract
. - replace the placeholder {aspect-Id} with the information obtained from step
3.4. Deploy the Aspect
.
β The binding process has been successful, and the transaction receipt has been printed.
For more detailed usage information about this command, please refer to the bind-aspect command documentation.
5. Test the Smart Contract and Aspect Integrationβ
Now that the HelloWorld
contract and Aspect are bound, call hello
to test.
npm run contract:call -- --contract {smart-contract-address} \
--abi ./build/contract/HelloWorld.abi \
--method hello
- replace the placeholder {smart-contract-address} with the information obtained from step
2 3 deploy the smart contract
.
β Due to Aspect interception, the transaction is reverted.
Congratulations! You've learned the basics of Aspect development. For a deeper dive, refer to our comprehensive Aspect Doc.