This is the final project for the Blockchain & Smart Contracts exam at the University of Cagliari (UniCa).
The Decentraland scene features a public area open to anyone and a reserved area separated by a door. Access to the reserved area requires a valid NFT ticket (unused and not expired), issued by an ERC-721 smart contract on the Sepolia testnet. Walking through the door consumes the ticket with the nearest expiration.
License: GPL-3.0-or-later (see LICENSE).
- Node.js 18+ and npm.
- MetaMask (browser extension), with a connected account.
- Sepolia test ETH in the account (from a Sepolia faucet).
- Decentraland SDK7: installed locally with
npm installinsidescene/(see the guide below).
- From the root folder:
cd contract
npm install
cp .env.example .env- In the
.envfile, set:
SEPOLIA_RPC_URL— Sepolia RPC endpointPRIVATE_KEY— private key of an account holding Sepolia ETH- (optional)
TICKET_PRICE_ETH,TICKET_VALIDITY_SECONDS
- Compile and run the tests (in-memory local network):
npm run compile
npm test- Deploy to Sepolia:
npm run deploy:sepoliaThe script prints the contract address and saves the address + ABI to
contract/deployments/sepolia.json. Note down the address.
- (Optional) Estimate gas and execution costs (Ethereum vs Polygon):
npx hardhat run scripts/gas-costs.jsThe script measures gas live on the in-memory local network and computes the costs for the
various scenarios. The reference prices (gas price and token value) can be edited at the top of
scripts/gas-costs.js.
-
Connect the contract and the scene. In
scene/src/contract/config.ts, paste the deployment address:export const CONTRACT_ADDRESS = "<copied_address>"
If the contract interface was changed, also update
scene/src/contract/abi.ts(copy theabiarray fromcontract/deployments/sepolia.json). -
Install and start the preview:
cd scene npm install npm startThe
startscript runssdk-commands start --dclenv zone --web3:--dclenv zoneselects the test environment (Sepolia) instead of production;--web3connects the browser wallet to sign transactions.
Required condition:
- MetaMask set to the Sepolia network before interacting.
The scene still performs a check (
assertSepolia) and blocks any transaction if the wallet is not on Sepolia, so it never spends real ETH. To deliberately start in the production environment:npm run start:mainnet. -
Usage flow in the scene:
- Go to the statue (in the public area) and click → MetaMask asks you to sign the ticket purchase.
- Approach the door and click "Enter" → If you hold a valid ticket, MetaMask asks you to
sign
useTicket(); on success, the door opens and you can access the reserved area.
Project distributed under the GNU General Public License v3.0 or later. Every source
file carries the SPDX header GPL-3.0-or-later. The OpenZeppelin dependencies are MIT (compatible
with the GPL). See LICENSE for the full text.