# WebAssembly Smart Contract Verification - Ecosystem Status

**URL:** <https://forum.astar.network/t/webassembly-smart-contract-verification-ecosystem-status/4797>\
**Category:** General\
**Created:** [July 6, 2023, 4:04am UTC](https://forum.astar.network/t/webassembly-smart-contract-verification-ecosystem-status/4797 "2023-07-06T04:04:04Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![ashutoshvarma](https://avatars.discourse-cdn.com/v4/letter/a/85f322/32.png) [@ashutoshvarma](https://forum.astar.network/u/ashutoshvarma)\
**Post date:** [July 6, 2023, 4:04am UTC](https://forum.astar.network/t/webassembly-smart-contract-verification-ecosystem-status/4797/1 "2023-07-06T04:04:04Z")

</div>

# Introduction

Smart contract verification plays a crucial role in ensuring the security and integrity of blockchain-based applications. By matching the source code with the deployed byte-code, developers and users can gain better visibility into the functionality and behaviour of smart contracts. This article explores the typical workflow for contract verification and discusses the challenges and solutions associated with Wasm Smart contracts

## 1 The Workflow for Smart Contract Verification

The process of smart contract verification involves two main components: the verification service (backend) and the block explorer (frontend). The following steps outline the general workflow:

### 1.1 Smart Contract Developer’s Role

- The smart contract developer uploads the complete contract source code, along with the required build metadata (e.g., compiler version, optimization flags), to the verification service.
- For multi-file projects, the developer may choose to flatten the source code into a single file or upload multiple files/zip archives, depending on the verification service’s capabilities.

### 1.2 Verification Service’s Role

- The verification service receives the source code and metadata and compiles the code to generate the bytecode.
- The compiled output is compared with the bytecode deployed on the blockchain to ensure consistency and correctness.
- The verification service maintains a catalog in a database, storing the verification status and the associated source code.

### 1.3 Block Explorer’s Role

- The block explorer acts as the frontend interface, providing users with access to the verification status and source code.
- It retrieves the verification status from the verification service and displays it to users.
- If the contract is not verified, the block explorer may provide a user-friendly UI/UX to upload the source code to the verification service.

Since there is not a tight coupling between the above two components any entity can opt to implement either of one and provide a service on top of it OR build both of them in-house.

## 2. Handling Multi-File Projects with External Dependencies

Managing multi-file projects with external dependencies can be challenging during the verification process. Here are some common solutions:

### 2.1 Flattening the Source Code

One approach is to flatten all the source code into a single file. This process involves replacing import statements in each source file with the actual code from the imported module. By flattening the code, the verification service can compile it more easily.

### 2.2 Uploading Multiple Files or Zip Archives

Alternatively, some verification services support uploading multiple files or a zip archive containing all the necessary source code files. In this case, the verification service handles the dependencies while compiling the code.

## 3. Challenges in Wasm Smart Contract Verification

Verifying Wasm-based smart contracts, compared to Solidity contracts, presents additional challenges due to the nature of the Rust compiler. Here’s why:

### 3.1 Non-Deterministic Bytecode Generation

The Rust compiler may produce different bytecode outputs for the same source code across different build environments or dependencies. That means if you compile your smart contract in two different machines, let’s say linux and other macOS, the output bytecode will be different from each other even tough source code and their functionality remains same.  
This non-deterministic behaviour complicates the verification process, as for a verification service in order to match the bytecode deployed on blockchain it needs to compile your given source code on it’s servers which will produce different bytecode for the exact same code.

### 3.2 Dockerized Build Environments

To address the non-determinism issue, a recommended solution is to utilize a Dockerfile that provides a consistent build environment for producing deterministic bytecode. The same Dockerfile used to build the production/release artifacts locally should be employed by the verification service for the verification process.

## 4. Overview of Ecosystem

- There are many verification platform available for wasm contract verification, such as [Subscan](https://astar.subscan.io/wasm_contract_dashboard), [Sirato](https://substrate.sirato.xyz/contracts), [Patron](https://github.com/Brushfam/patron-frontend) (still under development), etc.
- In the absence of a commonly agreed build environment, each verification service was forced to come up with their own in order to provide verifiable builds to enable Wasm smart contract verification service.
- That led to **fragmentation of the ecosystem as a contract verified on one service cannot be verified on other** since they all uses different build environments that are not compatible with each other which is clearly not good for the ecosystem which is at it’s infancy stage.

## Solution - Standardised Build Environment (`cargo contract verify`)

There was a clear need to define a standard build environment for Wasm contracts to make the bytecode deterministic and it make sense to add this functionality in the CLI tool that is use to build wasm contracts, i.e `cargo contract`.

> <https://github.com/use-ink/cargo-contract/pull/1148>
>
> Refers to #1065
> 
> This PR aims to bring the workflow to produce verifiable and …reproducible builds using \`cargo contract --verifiable\` and docker container with the pre-defined based on Debian distro.
> 
> In detail, the command spawns the container with the binding volume to the contact folder (See image documentation for more details), then executes \`cargo contract build --release --output-json \<some additional flags\> \> target/build\_result.json\` to build the contract in the release mode and save the serialized \`BuildResult\` output to a file. We need that in order to allow the host machine to access the results and print them in the STDOUT in the requested format.
> 
> After the execution, the container and \`build\_result.json\` files are deleted. The host then accesses metadata files, deserializes them back into the rust object, add the \`image\` name, and writes them back.
> 
> It was noted that building an image on different architectures (AMD64 vs ARM64) results in the production of different WASM binaries. Therefore, it was decided to stick with the single AMD64 image for the builds. While it may have an impact on the build times on ARM machines, this is the only way we can guarantee consistency in the reproducible builds. 
> 
> The image has been published to: https://hub.docker.com/r/paritytech/contracts-verifiable
> 
> Since the docker image is supposed to track the \`cargo-contract\` use \`paritytech/contracts-verifiable:test\` tag which can be manually specified with the \`--image\` flag.
> 
> Once the PR is merged, \`master\` tag tracking master branch will be published.
> 
> The follow up PR will be focused on the CI to automate the image release process.
> 
> \## Tasks
> 
> \- \[x\] Successfully spawn and remove containers upon execution
> \- \[x\] Persist image digest id in the metadata
> \- \[x\] Save output to the host folder
> \- \[x\] Respect cargo flags passed to the host
> \- \[x\] Allowing to specify docker image to use
> 
> \## Some extra goals I think worth considering
> 
> 1. \<del\>Allowing to specify docker image to use\</del\>
> 2. Specify the docker command to be used for the build
> 3. Recognise path dependant multi-contract projects and mount directories automatically ( by @deuszx )
> 
> Points 2 and 3 can be considered as a follow-up issues

The above PR adds a new subcommand `cargo contract verify` and provides a standard build environment for producing verifiable wasm contract

> In detail, the command spawns the container with the binding volume to the contact folder (See image documentation for more details), then executes `cargo contract build --release --output-json <some additional flags> > target/build_result.json` to build the contract in the release mode and save the serialized `BuildResult` output to a file. We need that in order to allow the host machine to access the results and print them in the STDOUT in the requested format.  
> After the execution, the container and `build_result.json` files are deleted. The host then accesses metadata files, deserializes them back into the rust object, add the `image` name, and writes them back.

## Summary

Once `cargo contract verify` is released it will become very seamless for contract developers to compile their contracts that are verifiable. Unfortunately all of the verification services uses their own build environments that is not compatible with each other that’s results in fragmentation, but that can be changed if all of the verification services start using `cargo contract verify`.

If you are a developer of one of the verification service, take a look at the above PR and give your valuable inputs and look into possibility of integrating this into your service.
