Reproducible buildsalpha
Why the same source always produces the same wasm with moxzi, and how to use that to check a build.
Given the same source files, the same options and the same compiler, moxzi build produces exactly the same bytes, on any machine, in a browser, or in a canister. That lets anyone check that a deployed module came from a given source: build it and compare hashes.
What determines the output#
| Input | How it's identified |
|---|---|
| The compiler | The SHA-256 of compiler.wasm, printed by every build and by moxzi info |
| The linker | The SHA-256 of linker.wasm, printed by moxzi info |
| Source files | Their contents and their paths as the compiler sees them (/src/…, /pkg/NAME/…) |
| Options | The build flags |
Paths are independent of where the project is on disk, so two people building the same project from different directories get the same bytes. moxzi deps --paths-only lists the paths.
cp -R project /tmp/copy-a
cp -R project ./copy-b
moxzi build /tmp/copy-a/src/Main.mo -o a.wasm > /dev/null
moxzi build copy-b/src/Main.mo -o b.wasm > /dev/null
shasum -a 256 a.wasm b.wasm
962c7764d537812391dbcfef2288f958b3ba8986409cffd4ab34c2bc26022d54 a.wasm
962c7764d537812391dbcfef2288f958b3ba8986409cffd4ab34c2bc26022d54 b.wasm
Nothing else affects the output: not the time, the machine, the operating system, or where the compiler runs.
Checking a deployed canister#
To check that a canister runs the module your source produces:
moxzi build src/main.mo -o main.wasm
shasum -a 256 main.wasm
dfx canister info CANISTER_ID # shows the module hash
Use the same moxzi release, and the same options, as the original build. If the module was built on-chain, moxzi verify shows the source hashes, options and compiler that built it; see Verifying a build.
The compiler builds itself#
The compiler is a Motoko program, and moxzi can compile it. Compiling the compiler's source with moxzi produces the same compiler.wasm byte for byte, and the production compiler canister has done the same on the Internet Computer. So the compiler you run, locally or on-chain, is the one its source describes.
Compared with moc#
moxzi compiles programs the way moc 2.0.0 does, but it links its own build of the Motoko runtime system, so a module built by moxzi isn't byte-identical to one built by moc. They behave the same. To check a build, compare it with another moxzi build.
What changes the output#
| Change | Effect |
|---|---|
| A different moxzi release | Usually a different compiler hash, and different bytes |
--compact-rts, --ephemeral, --actor-max-pages, --top-max-pages | Different bytes, by design |
--stack-budget, --force-gc, --progress, --timings | None. They change how the compile runs, not what it produces |
| Moving the project directory | None, as long as files keep the same paths relative to the project |