Builder 06 of 06
Share Your Project
Put your own dApp on a public URL, then register it on chain so it appears in the showcase under your address for good.
20 min read, then one transaction
Everything so far has been an exercise with a known answer. This one is not. You decide what to build, and the only requirement is that it works and that somebody other than you can use it.
Then you share it: a public URL and your contract's address, written into an ownerless contract by your own wallet, which puts your project in the showcase beside everybody else's. It is the last thing you do on this track and the first thing here that is permanent, public, and yours.
What counts
A finished project has four parts. Nothing about scale — a small thing that works beats an ambitious thing that half-works.
- 01
A contract you wrote
Deployed on LiteForge by your own wallet. It can be simple. It must be yours, not a copy of the lesson contract with a new name.
- 02
At least one write
A function that changes state and emits an event, so the change is visible to anything reading the chain.
- 03
A frontend anyone can open
A public URL. A single HTML file on GitHub Pages is a perfectly good answer; nobody is grading your build tooling.
- 04
Honest states and errors
Pending, confirmed, reverted, rejected, wrong network. The difference between a demo and a product is almost entirely this.
Four projects that work
Pick one, or bring your own. These are sized for a weekend, not a quarter.
On-chain guestbook
- Anyone leaves a message, stored on chain
- Frontend lists them from events
- Teaches: indexed logs, pagination
- The most direct extension of module two
Token dashboard
- Reads balances for any address you paste
- Shows transfers from event logs
- Teaches: multicall, formatting decimals
- Almost all reads, very few writes
Tip jar
- Accepts zkLTC with a message attached
- Owner withdraws the balance
- Teaches: payable, withdrawal patterns
- Small contract, real money movement
Something you actually want
- A tracker, a poll, a game, a registry
- Any of it is fine
- Teaches: the parts nobody warned you about
- The version you are most likely to finish
Putting the frontend on a public URL
You need a public URL, not a build pipeline. If your project is one HTML file — and the starter from the previous module is — GitHub Pages hosts it for free with no tooling at all:
- 01
Create a repository
On github.com press New, give it a name, tick Public, and create it. An account is free and no card is asked for.
- 02
Put your file in it
Add file, then Upload files. Drag your HTML file in and rename it index.html — that exact name is what a web server serves when somebody opens the bare URL. Commit changes.
- 03
Turn Pages on
Settings tab, Pages in the left sidebar. Under Build and deployment set Source to Deploy from a branch, Branch to main and the folder to / (root). Save.
- 04
Wait a minute, then copy the URL
The same Pages screen shows it once the first build finishes: https://<your-username>.github.io/<your-repository>/. That string is what you register on chain.
Vercel and Netlify are the same job with a different button: connect the repository, accept every default, take the URL they give you. IPFS is the purist's answer — pin the files, share the gateway URL — and fits if your project's point is that it depends on no server at all.
Share it in the showcase
Sharing here is two values written to a contract with no owner and no admin, living at
0x11de4c281680bEA18Cd9177A16f573A7E0480aa1
and the only function you need on it is
function register(string calldata url, address contractAddress) external;
You give it two things — where your project lives and which contract it talks
to — and it emits ProjectRegistered. The gallery is built by reading those
events back, so your entry is published by the chain rather than by us. There is
no database anywhere in this Academy, and this is the last place one could have
crept in.
Doing it in Remix
You are calling a contract somebody else deployed, so there is nothing to deploy and nothing to compile except a description of the one function you want. That description is the file below — paste it into Remix exactly as it is.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IAcademyShowcase {
function register(string calldata url, address contractAddress) external;
}
- 01
Make the file
In Remix, create a new file called Showcase.sol and paste the four lines above into it. Compile it with 0.8.20 or newer, the same as every other lesson.
- 02
Open the Deploy tab
Set Environment to Injected Provider so Remix uses your wallet, and check the wallet says LitVM LiteForge, chain 4441.
- 03
Pick the interface in the CONTRACT dropdown
It reads IAcademyShowcase. Do not press the blue Deploy button — the showcase already exists, and deploying would create a second, empty one that nothing reads.
- 04
Point Remix at the existing contract
Scroll to Deployed Contracts at the bottom of the panel. Press + Add Contract there, paste 0x11de4c281680bEA18Cd9177A16f573A7E0480aa1 into the address field, and choose IAcademyShowcase if it asks which contract it is. Older Remix versions call this At Address, with the field beside the button — same thing.
- 05
Fill the two fields and send
The showcase now sits in Deployed Contracts with an orange register button and two fields. Fill them as in the table below, press register (Transact in newer Remix), confirm in your wallet, and copy the transaction hash for the check below.
What goes in the two fields:
| Field | Type this | Rules the contract enforces |
|---|---|---|
url (string) | https://your-name.github.io/your-repo/ | The full public address of the working page, https:// included and no quotes around it. Empty is rejected with EmptyUrl, and over 256 characters with UrlTooLong — nothing else is checked, on chain or off. |
contractAddress (address) | 0x... | Your project's contract, the one your frontend calls. Pasting your wallet address here reverts with NotAContract, because the showcase checks that the address has code. |
Both fields are plain text: Remix is already expecting a string and an address, so quotes typed by hand become part of the value.
The chain will accept any string at all in url, which makes it worth saying
what belongs there: the page somebody can use, not the repository it was built
from. https://your-name.github.io/your-repo/ opens your project;
https://github.com/your-name/your-repo opens its source, and a visitor who
clicks it from the gallery has to go looking for the thing you built.
If you would rather not touch Remix, cast does the same thing in one line:
cast send 0x11de4c281680bEA18Cd9177A16f573A7E0480aa1 \
"register(string,address)" "https://your-page-url" 0xYourContract \
--private-key $PRIVATE_KEY \
--rpc-url https://liteforge.rpc.caldera.xyz/http
The most fitting option of all is your own frontend: add a button that calls
register, and the project's last transaction is the project registering
itself.
What the check verifies
The badge is signed for when the chain shows a register() call from your
wallet that emitted ProjectRegistered naming your address. The contract
already refuses an empty URL, a URL over 256 characters, and an address with no
code — that last one catches the common mistake of registering a wallet instead
of a contract.
What it does not check is whether your project is any good. Nothing automated can, and pretending otherwise would make the badge mean less, not more. The gallery is public and the code is on chain: that is the review.
Seeing what you earned
Your badges are ERC-1155 tokens on chain 4441, at
0x01982622D0960b4f8F63A86Ce4608767997FEE2b
- In this Academy. Your own page lives at
/collection/<your address>, built by reading your balances off the chain at request time. It is public and shareable, and there is no database behind it — delete this site and the badges are still yours. - In a wallet. Import NFT, that contract address, and the badge's token id: 11, 13, 15, 16, 18 and 20 for the Builder modules, 21 for the certificate. ERC-1155 support varies by wallet, so a badge that refuses to import is a limitation of the wallet rather than a problem with the token.
- In the explorer. The token page lists every holder of every id, so you can check what you hold without trusting any interface, including this one.
Your project itself appears in the showcase as soon as the
register transaction confirms, because that gallery is nothing but the
ProjectRegistered events read back in order.
Then the certificate
With all six Builder badges in your wallet, mintCertificate becomes callable.
Its requirements are checked on chain against your own balances, so nobody can
grant it to you — not the Academy, not the contract owner, not anyone.
That is worth more than it sounds. Most certificates are a claim by whoever issued them, and you have to trust the issuer. This one is a fact anybody can verify against a public ledger without trusting us at all.
What to remember
- 01A finished project is a contract you wrote, one write that emits an event, a public URL, and honest transaction states.
- 02Let people withdraw what they are owed rather than pushing funds to them: one reverting recipient can otherwise stop the whole payout.
- 03Registering writes to an ownerless contract, so the gallery needs no database and nobody can edit your entry — including us.
- 04The check proves the registration happened, not that the work is good. Nothing automated could, and claiming otherwise would cheapen the badge.
- 05The certificate is gated on chain by your own balances, so it is verifiable by anyone without trusting the issuer.
Primary sources
Share your project
Paste the hash of your register() transaction on the showcase contract. The check reads the transaction straight from LiteForge, so it has to be one your own wallet sent.