To begin working with Mazze blockchain, which is compatible with the Ethereum Virtual Machine (EVM), you'll first need to install Hardhat in your project directory.
Execute the following command to install Hardhat:
npminstall--save-devhardhat
After installation, initiate Hardhat by running npx hardhat. This action will generate a Hardhat configuration file (hardhat.config.js) in your project directory:
npxhardhat
You'll be greeted by the Hardhat interface:
npx hardhat
Welcome to Hardhat v2.2.1
✔ What do you want to do? · Create an empty hardhat.config.js
Config file created
The next step is to create your first smart contract. In the contracts directory, store your Solidity source files (.sol). Let's start with a basic contract named Box, which allows storing and retrieving a value.
Create the contract in the file contracts/Box.sol:
// contracts/Box.sol// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;contract Box {uint256private _value;// Emitted when the stored value changeseventValueChanged(uint256 value);// Stores a new value in the contractfunctionstore(uint256 value) public { _value = value;emitValueChanged(value); }// Reads the last stored valuefunctionretrieve() publicviewreturns (uint256) {return _value; }}
For compiling Solidity code to EVM bytecode, configure Hardhat to use a suitable Solidity compiler version, matching your contract's requirements. In hardhat.config.js, specify Solidity 0.8 for our Box.sol contract:
Hardhat will compile all contracts in the contracts directory. The compiled artifacts (bytecode and metadata) will be stored in the artifacts directory.
As your project expands, you might create more contracts. For instance, let's add an access control system to our Box contract. We'll create an Auth contract that stores an administrator address. This contract will be placed in a subdirectory, like contracts/access-control/Auth.sol.
// contracts/access-control/Auth.sol// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;contract Auth {addressprivate _administrator;constructor(address deployer) {// Make the deployer of the contract the administrator _administrator = deployer; }functionisAdministrator(address user) publicviewreturns (bool) {return user == _administrator; }}
To integrate Auth with Box, use an import statement in Box.sol:
// contracts/Box.sol// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;// Import Auth from the access-control subdirectoryimport"./access-control/Auth.sol";contract Box {uint256private _value; Auth private _auth;eventValueChanged(uint256 value);constructor() { _auth =newAuth(msg.sender); }functionstore(uint256 value) public {// Require that the caller is registered as an administrator in Authrequire(_auth.isAdministrator(msg.sender),"Unauthorized"); _value = value;emitValueChanged(value); }functionretrieve() publicviewreturns (uint256) {return _value; }}
For advanced modularization, consider using inheritance in Solidity. A great resource for reusable modules and libraries is the OpenZeppelin Contracts library. It's thoroughly audited for security and correctness.
To use OpenZeppelin Contracts, install the library:
npminstall@openzeppelin/contracts
Then, import the necessary contracts from OpenZeppelin. For example, to add access control to Box, replace the Auth contract with Ownable from OpenZeppelin:
// contracts/Box.sol// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;// Import Ownable from the OpenZeppelin Contracts libraryimport"@openzeppelin/contracts/access/Ownable.sol";// Make Box inherit from the Ownable contractcontractBoxisOwnable {uint256private _value;eventValueChanged(uint256 value);constuctor() Ownable(msg.sender) {}// The onlyOwner modifier restricts who can call the store functionfunctionstore(uint256 value) publiconlyOwner { _value = value;emitValueChanged(value); }functionretrieve() publicviewreturns (uint256) {return _value; }}