{"id":18437839,"url":"https://github.com/zilliqa/hardhat-scilla-plugin","last_synced_at":"2025-04-07T20:34:35.250Z","repository":{"id":65221217,"uuid":"582552389","full_name":"Zilliqa/hardhat-scilla-plugin","owner":"Zilliqa","description":null,"archived":false,"fork":false,"pushed_at":"2024-09-09T15:04:24.000Z","size":579,"stargazers_count":3,"open_issues_count":6,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-09-09T18:27:07.443Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Zilliqa.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-27T07:25:28.000Z","updated_at":"2024-09-09T15:04:26.000Z","dependencies_parsed_at":"2024-09-09T18:05:20.693Z","dependency_job_id":"8c5535a2-186a-412d-a7e6-c01db06ff98d","html_url":"https://github.com/Zilliqa/hardhat-scilla-plugin","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":"NomicFoundation/hardhat-ts-plugin-boilerplate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zilliqa%2Fhardhat-scilla-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zilliqa%2Fhardhat-scilla-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zilliqa%2Fhardhat-scilla-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zilliqa%2Fhardhat-scilla-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Zilliqa","download_url":"https://codeload.github.com/Zilliqa/hardhat-scilla-plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223291499,"owners_count":17120965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T06:16:23.214Z","updated_at":"2024-11-06T06:16:24.017Z","avatar_url":"https://github.com/Zilliqa.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hardhat-scilla-plugin\n\n[Hardhat](https://hardhat.org) plugin to test Scilla contracts.\n\n## What\n\nThis plugin is used to test scilla contracts in hardhat. It tries to be like ethers.js:\n* You can deploy contracts using their names.\n* You can call transitions like a normal function call.\n* You can get field easily.\n* You can use custom chai matchers to expect scilla events.\n\n## Installation\n\n```bash\npnpm install hardhat-scilla-plugin\n```\n\nImport the plugin in your `hardhat.config.js`:\n\n```js\nrequire(\"hardhat-scilla-plugin\");\n```\n\nOr if you are using TypeScript, in your `hardhat.config.ts`:\n\n```ts\nimport \"hardhat-scilla-plugin\";\n```\n\n## Running Scilla\n\nIn order to check, and extract data from, Scilla contracts, we use binaries from the Scilla distribution itself.\n\nBy 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.\n\nIf you want to set `USE_NATIVE_SCILLA`, you need to have `scilla-fmt` and `scilla-checker` binaries from the [Scilla project](https://github.com/Zilliqa/scilla/) on your `PATH`. You can build them by following the instructions in the scilla project repository.\n\n## Tasks\n\nThis plugin adds the _scilla-check_ task to Hardhat:\n```\nHardhat version 2.16.0\n\nUsage: hardhat [GLOBAL OPTIONS] scilla-check --libdir \u003cSTRING\u003e [...contracts]\n\nOPTIONS:\n\n  --libdir      Path to Scilla stdlib \n\nPOSITIONAL ARGUMENTS:\n\n  contracts     An optional list of files to check (default: [])\n\nscilla-check: Parsing scilla contracts and performing a number of static checks including typechecking.\n\nFor global options help run: hardhat help\n```\n\n## Environment extensions\n\nThis plugin extends the Hardhat Runtime Environment by adding an `scillaContracts` field\nwhose type is `ScillaContracts`.\n\n## Usage\n\nScilla 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.\n\n### Deploy a contract\n\nTo deploy a contract all you need to know is its name:\n\n```typescript\nimport {ScillaContract, initZilliqa} from \"hardhat-scilla-plugin\";\n\nconst privateKeys = [\"254d9924fc1dcdca44ce92d80255c6a0bb690f867abde80e626fbfef4d357004\"];\nconst network_url = \"http://localhost:5555\";\nconst chain_id = 1;\ninitZilliqa(network_url, chain_id, privateKeys);\n\nlet contract: ScillaContract = await hre.deployScillaContract(\"SetGet\");\nlet contract: ScillaContract = await hre.deployScillaContract(\"HelloWorld\", \"Hello World\"); // Contract with initial parameters.\n```\n\nYou can override the following parameters while deploying a contract:\n```typescript\nTxParams {\n    version: number;\n    toAddr: string;\n    amount: BN;\n    gasPrice: BN;\n    gasLimit: Long;\n    code?: string;\n    data?: string;\n    receipt?: TxReceipt;\n    nonce?: number;\n    pubKey?: string;\n    signature?: string;\n}\n```\n```typescript\nlet contract: ScillaContract = await hre.deployScillaContract(\"HelloWorld\", \"Hello World\", {gasLimit: 8000}); // Override a parameter\n```\n\nAlternatively, you can deploy them using the `contractDeployer` object injected to `hre`:\n```typescript\n  const contract = await hre.contractDeployer\n    .withName(\"Codehash\")\n    .deploy();\n\n  const contract = await this.hre.contractDeployer\n    .withName(\"HelloWorld\")\n    .withContractParams(\"Hello world!\")\n    .deploy();\n \n  const contract = await this.hre.contractDeployer\n    .withName(\"HelloWorld\")\n    .withContractParams(\"sss\")\n    .withContractCompression()  // To enable contract compression.\n    .deploy();\n```\n\nIn the same way, you can deploy your libraries with their names:\n```typescript\nlet library: ScillaContract = await hre.deployScillaLibrary(\"MyLibrary\", false);\n```\nPass `true` as the second parameter if you want your library's contract gets compressed before deployment.\n\nand finally, here is how you can deploy a contract importing a user-defined library:\n```typescript\ncontract2 = await hre.deployScillaWithLib(\"TestContract2\",\n      [{name: \"MutualLib\", address: mutualLibAddress}]\n```\nOr:\n```typescript\n  const contract = await this.hre.contractDeployer\n    .withName(\"TestContract2\")\n    .withUserDefinedLibraries(\n      [{name: \"MutualLib\", address: mutualLibAddress}]\n    )\n    .deploy();\n```\n\nTo change the deployer of the contract, you can send an instance of `Account` class to `hre.setActiveAccount`.\n\n### Change the default parameters when deploying a contract\n\nYou can call\n\n```\nhre.setScillaDefaults( obj )\n```\n\nto set the defaults used when deploying a Scilla contract. Parameters supported are:\n\n * `gasPrice` - a string denoting the gas price in `Li` (to match the `initZilliqa` use).\n * `gasLimit` - a string denoting the gas limit (in `Qa`, to match `initZilliqa` use)\n * `attempts` - a number denoting the number of attempts to make to check whether a transaction has been accepted\n * `timeout` - the space between attempts, in milliseconds.\n\n### Connect to an existing Scilla contract\n\nCall\n\n```\nhre.interactWithScillaContract(address)\n```\n\nTo:\n\n * Retrieve the code for a contract from the configured chain.\n * Parse it.\n * Construct a proxy contract object for it.\n * Return that object, or `undefined` if we failed.\n\n`address` should be a string, and the function returns `ScillaContract | undefined`.\n\n### Call a transition\n\nIt's not harder than calling a normal function in typescript.\nLet's assume we have a transition named `Set` which accepts a `number` as its parameter. Here is how to call it:\n\n```typescript\nawait contract.Set(12);\n```\n\n### Call a transition with a custom nonce\n```typescript\nawait contract.Set(12, {nonce: 12});\n```\nIt's possible to override the following properties:\n\n```typescript\nexport interface TxParams {\n    version: number;\n    toAddr: string;\n    amount: BN;\n    gasPrice: BN;\n    gasLimit: Long;\n    code?: string;\n    data?: string;\n    receipt?: TxReceipt;\n    nonce?: number;\n    pubKey?: string;\n    signature?: string;\n}\n```\n\n```typescript\nawait contract.Set(12, {nonce: 12, amount: new BN(1000)});\n```\n\n### call a transition with a new account\n\nYou can call `connect` on a contract to change its default account which is used to execute transitions.\n\n```typescript\nawait contract.connect(newAccount).Set(123);\n```\n\n### Get field value\n\nIf a given contract has a filed named `msg` is possible to get its current value using a function call to `msg()`\n\n```typescript\nconst msg = await contract.msg();\n```\n\n### Expect a result\n\nChai matchers can be used to expect a value:\n\n```typescript\nit(\"Should set state correctly\", async function () {\n  const VALUE = 12;\n  await contract.Set(VALUE);\n  expect(await contract.value()).to.be.eq(VALUE);\n});\n```\n\nThere are two custom chai matchers specially developed to `expect` scilla events. `eventLog` and `eventLogWithParams`.\nUse `eventLog` if you just need to expect event name:\n\n```typescript\nimport chai from \"chai\";\nimport {scillaChaiEventMatcher} from \"hardhat-scilla-plugin\";\n\nchai.use(scillaChaiEventMatcher);\n\nit(\"Should contain event data if emit function is called\", async function () {\n  const tx = await contract.emit();\n  expect(tx).to.have.eventLog(\"Emit\");\n});\n```\n\nOtherwise, 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:\n\n```typescript\nimport chai from \"chai\";\nimport {scillaChaiEventMatcher} from \"hardhat-scilla-plugin\";\n\nchai.use(scillaChaiEventMatcher);\n\nit(\"Should send getHello() event when getHello() transition is called\", async function () {\n  const tx = await contract.getHello();\n  expect(tx).to.have.eventLogWithParams(\"getHello()\", {value: \"hello world\", vname: \"msg\"});\n});\n```\n\nYou can even expect data type of the parameter(s):\n\n```typescript\nexpect(tx).to.have.eventLogWithParams(\"getHello()\", {value: \"hello world\", vname: \"msg\", type: \"String\"});\n```\n\nType should be a valid Scilla type.\n\nBut if you just want to expect on the value of a event parameter do this:\n\n```typescript\nexpect(tx).to.have.eventLogWithParams(\"getHello()\", {value: \"hello world\"});\n```\n\nFor easier value matching, some value conversions are done under the hood.\n* 32/64 bit integer values are converted to `Number`\n* 128/256 bit integer values are converted to `BigNumber`\n* `Option` is converted to its inner value if exists any, or `null` otherwise.\n* `Bool` is converted to underlying boolean value.\n\nfor more tests please take look at [scilla tests](https://github.com/Zilliqa/Zilliqa/tree/master/tests/EvmAcceptanceTests/test/scilla).\n\n### TODO\n\n- Support formatting complex data types such as `Map` and `List`\n\n### Scilla checker task\n\nTo run `scilla-checker` on all of the scilla contracts in the [contracts directory](./contracts/) run:\n\n```bash\nnpx hardhat scilla-check --libdir path_to_stdlib\n```\n\nalternatively, you can check a specific file(s):\n\n```bash\nnpx hardhat scilla-check --libdir path_to_stdlib contracts/scilla/helloWorld.scilla\n```\n\n### TODO\n\n- Add `scilla-fmt` task\n\n# Plugin development\n\n## Running internal tests\n\nIf you want to monitor your requests:\n\n```\nmitmweb --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\nexport ZILLIQA_API_URL=http://localhost:5600/\n```\n\nSet `ZILLIQA_API_URL` to the URL of a network to test - or to eg. `http://localhost:5600` if you're proxying as above.\nSet `ZILLIQA_NETWORK` to the name of the network to test against - see `test/fixture-projects/hardhat-proxy/hardhat.config.ts` for details.\n\n```sh\npnpm test\n```\n\nWill run all tests that don't require an external network (so that test passes will be deterministic).\n\n```sh\npnpm test-live\n```\n\nWill run just the tests that do require an external network.\n\n```sh\npnpm test-all\n```\n\nWill run both sets of tests.\n\n## Publishing the plugin\n\nIn order to publish the plugin to [npmjs.com](https://www.npmjs.com/package/hardhat-scilla-plugin), follow these steps:\n1. Increase the plugin version in [package.json](./package.json)\n2. Run `npm login` and enter your credentials.\n3. Run `pnpm install`\n3. Run `pnpm publish`. This command will run `pnpm build` \u0026\u0026 `pnpm test` beforehand. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzilliqa%2Fhardhat-scilla-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzilliqa%2Fhardhat-scilla-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzilliqa%2Fhardhat-scilla-plugin/lists"}