
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
hardhat-scilla-plugin
Advanced tools
Hardhat plugin to test Scilla contracts.
This plugin is used to test scilla contracts in hardhat. It tries to be like ethers.js:
pnpm install hardhat-scilla-plugin
Import the plugin in your hardhat.config.js
:
require("hardhat-scilla-plugin");
Or if you are using TypeScript, in your hardhat.config.ts
:
import "hardhat-scilla-plugin";
In order to check, and extract data from, Scilla contracts, we use binaries from the Scilla distribution itself.
By default, we pull these from the zilliqa/scilla
container in docker hub, using Scilla v0.13.3, but if you want to run them from your local machine, you can set the USE_NATIVE_SCILLA
environment variable to run them from your PATH
. If want to run scilla-checker
with USE_NATIVE_SCILLA
set, you will need to give the -libDir
argument to tell it where to find the Scilla standard library.
If you want to set USE_NATIVE_SCILLA
, you need to have scilla-fmt
and scilla-checker
binaries from the Scilla project on your PATH
. You can build them by following the instructions in the scilla project repository.
This plugin adds the scilla-check task to Hardhat:
Hardhat version 2.16.0
Usage: hardhat [GLOBAL OPTIONS] scilla-check --libdir <STRING> [...contracts]
OPTIONS:
--libdir Path to Scilla stdlib
POSITIONAL ARGUMENTS:
contracts An optional list of files to check (default: [])
scilla-check: Parsing scilla contracts and performing a number of static checks including typechecking.
For global options help run: hardhat help
This plugin extends the Hardhat Runtime Environment by adding an scillaContracts
field
whose type is ScillaContracts
.
Scilla testing can be done in the same way ethers.js is used for solidity. It's possible to deploy a scilla contract by its name and call its transitions just like a normal function call. It's also possible to get a field value through a function call. In the below sections, all of these topics are covered in detail.
To deploy a contract all you need to know is its name:
import {ScillaContract, initZilliqa} from "hardhat-scilla-plugin";
const privateKeys = ["254d9924fc1dcdca44ce92d80255c6a0bb690f867abde80e626fbfef4d357004"];
const network_url = "http://localhost:5555";
const chain_id = 1;
initZilliqa(network_url, chain_id, privateKeys);
let contract: ScillaContract = await hre.deployScillaContract("SetGet");
let contract: ScillaContract = await hre.deployScillaContract("HelloWorld", "Hello World"); // Contract with initial parameters.
You can override the following parameters while deploying a contract:
TxParams {
version: number;
toAddr: string;
amount: BN;
gasPrice: BN;
gasLimit: Long;
code?: string;
data?: string;
receipt?: TxReceipt;
nonce?: number;
pubKey?: string;
signature?: string;
}
let contract: ScillaContract = await hre.deployScillaContract("HelloWorld", "Hello World", {gasLimit: 8000}); // Override a parameter
Alternatively, you can deploy them using the contractDeployer
object injected to hre
:
const contract = await hre.contractDeployer
.withName("Codehash")
.deploy();
const contract = await this.hre.contractDeployer
.withName("HelloWorld")
.withContractParams("Hello world!")
.deploy();
const contract = await this.hre.contractDeployer
.withName("HelloWorld")
.withContractParams("sss")
.withContractCompression() // To enable contract compression.
.deploy();
In the same way, you can deploy your libraries with their names:
let library: ScillaContract = await hre.deployScillaLibrary("MyLibrary", false);
Pass true
as the second parameter if you want your library's contract gets compressed before deployment.
and finally, here is how you can deploy a contract importing a user-defined library:
contract2 = await hre.deployScillaWithLib("TestContract2",
[{name: "MutualLib", address: mutualLibAddress}]
Or:
const contract = await this.hre.contractDeployer
.withName("TestContract2")
.withUserDefinedLibraries(
[{name: "MutualLib", address: mutualLibAddress}]
)
.deploy();
To change the deployer of the contract, you can send an instance of Account
class to hre.setActiveAccount
.
You can call
hre.setScillaDefaults( obj )
to set the defaults used when deploying a Scilla contract. Parameters supported are:
gasPrice
- a string denoting the gas price in Li
(to match the initZilliqa
use).gasLimit
- a string denoting the gas limit (in Qa
, to match initZilliqa
use)attempts
- a number denoting the number of attempts to make to check whether a transaction has been acceptedtimeout
- the space between attempts, in milliseconds.Call
hre.interactWithScillaContract(address)
To:
undefined
if we failed.address
should be a string, and the function returns ScillaContract | undefined
.
It's not harder than calling a normal function in typescript.
Let's assume we have a transition named Set
which accepts a number
as its parameter. Here is how to call it:
await contract.Set(12);
await contract.Set(12, {nonce: 12});
It's possible to override the following properties:
export interface TxParams {
version: number;
toAddr: string;
amount: BN;
gasPrice: BN;
gasLimit: Long;
code?: string;
data?: string;
receipt?: TxReceipt;
nonce?: number;
pubKey?: string;
signature?: string;
}
await contract.Set(12, {nonce: 12, amount: new BN(1000)});
You can call connect
on a contract to change its default account which is used to execute transitions.
await contract.connect(newAccount).Set(123);
If a given contract has a filed named msg
is possible to get its current value using a function call to msg()
const msg = await contract.msg();
Chai matchers can be used to expect a value:
it("Should set state correctly", async function () {
const VALUE = 12;
await contract.Set(VALUE);
expect(await contract.value()).to.be.eq(VALUE);
});
There are two custom chai matchers specially developed to expect
scilla events. eventLog
and eventLogWithParams
.
Use eventLog
if you just need to expect event name:
import chai from "chai";
import {scillaChaiEventMatcher} from "hardhat-scilla-plugin";
chai.use(scillaChaiEventMatcher);
it("Should contain event data if emit function is called", async function () {
const tx = await contract.emit();
expect(tx).to.have.eventLog("Emit");
});
Otherwise, if you need to deeply expect an event, you should use eventLogWithParams
. The first parameter is again the event name. The rest are parameters of the expected event. If you expect to have an event like getHello
sending a parameter named msg
with a "hello world"
value:
import chai from "chai";
import {scillaChaiEventMatcher} from "hardhat-scilla-plugin";
chai.use(scillaChaiEventMatcher);
it("Should send getHello() event when getHello() transition is called", async function () {
const tx = await contract.getHello();
expect(tx).to.have.eventLogWithParams("getHello()", {value: "hello world", vname: "msg"});
});
You can even expect data type of the parameter(s):
expect(tx).to.have.eventLogWithParams("getHello()", {value: "hello world", vname: "msg", type: "String"});
Type should be a valid Scilla type.
But if you just want to expect on the value of a event parameter do this:
expect(tx).to.have.eventLogWithParams("getHello()", {value: "hello world"});
For easier value matching, some value conversions are done under the hood.
Number
BigNumber
Option
is converted to its inner value if exists any, or null
otherwise.Bool
is converted to underlying boolean value.for more tests please take look at scilla tests.
Map
and List
To run scilla-checker
on all of the scilla contracts in the contracts directory run:
npx hardhat scilla-check --libdir path_to_stdlib
alternatively, you can check a specific file(s):
npx hardhat scilla-check --libdir path_to_stdlib contracts/scilla/helloWorld.scilla
scilla-fmt
taskIf you want to monitor your requests:
mitmweb --mode reverse:https://dev-api.zilliqa.com --modify-headers /~q/Host/dev-api.zilliqa.com --no-web-open-browser --listen-port 5600 --web-port 8600
export ZILLIQA_API_URL=http://localhost:5600/
Set ZILLIQA_API_URL
to the URL of a network to test - or to eg. http://localhost:5600
if you're proxying as above.
Set ZILLIQA_NETWORK
to the name of the network to test against - see test/fixture-projects/hardhat-proxy/hardhat.config.ts
for details.
pnpm test
Will run all tests that don't require an external network (so that test passes will be deterministic).
pnpm test-live
Will run just the tests that do require an external network.
pnpm test-all
Will run both sets of tests.
In order to publish the plugin to npmjs.com, follow these steps:
npm login
and enter your credentials.pnpm install
pnpm publish
. This command will run pnpm build
&& pnpm test
beforehand.FAQs
Hardhat TypeScript plugin for scilla testing
The npm package hardhat-scilla-plugin receives a total of 102 weekly downloads. As such, hardhat-scilla-plugin popularity was classified as not popular.
We found that hardhat-scilla-plugin demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.