Skip to content

Instantly share code, notes, and snippets.

@normandmickey
Last active April 7, 2023 19:07
Show Gist options
  • Save normandmickey/7462cf56892e38bcdd48e47a68245af3 to your computer and use it in GitHub Desktop.
Save normandmickey/7462cf56892e38bcdd48e47a68245af3 to your computer and use it in GitHub Desktop.
Ethereum Paywall
To create an Ethereum paywall in a React app using Hardhat, you can follow the steps below. This guide assumes you have Node.js, npm, and the MetaMask browser extension installed and set up.
Step 1: Set up the React app
First, create a new React app using the command:
```
npx create-react-app ethereum-paywall
```
Step 2: Install dependencies
To build the paywall, you will need some additional dependencies, such as ethers, hardhat, and @nomiclabs/hardhat-waffle. Install these packages by running:
```
cd ethereum-paywall
npm install --save ethers
npm install --save-dev hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai
```
Step 3: Create Hardhat project
Initialize a Hardhat project with the following command:
```
npx hardhat
```
Select "Create an empty hardhat.config.js" when prompted.
Step 4: Create and compile the smart contract
Create a new directory called 'contracts' at the root of your project and create a file named 'Paywall.sol' inside it.
Paste the following code into 'Paywall.sol':
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Paywall {
address payable public owner;
event AccessGranted(address _user);
constructor() {
owner = payable(msg.sender);
}
function grantAccess() public payable {
require(msg.value >= 0.01 ether, "Not enough Ether sent.");
owner.transfer(msg.value);
emit AccessGranted(msg.sender);
}
}
```
Step 5: Deploy the smart contract
Create a new directory called 'scripts' at the root of your project and create a file named 'deploy.js' inside it.
Paste the following code into 'deploy.js':
```javascript
async function main() {
const [deployer] = await ethers.getSigners();
console.log("Deploying contracts with the account:", deployer.address);
console.log("Account balance:", (await deployer.getBalance()).toString());
const Paywall = await ethers.getContractFactory("Paywall");
const paywall = await Paywall.deploy();
console.log("Paywall contract deployed at:", paywall.address);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
```
Now deploy the contract using the following command:
```
npx hardhat run scripts/deploy.js --network localhost
```
Take note of the contract's address as it will be used in the React app.
Step 6: Integrate the paywall with the React app
Open 'src/App.js' and paste the following code:
```javascript
import React, { useState, useEffect } from "react";
import "./App.css";
import { ethers } from "ethers";
import paywallArtifact from "../contracts/Paywall.json";
const App = () => {
const [account, setAccount] = useState("");
const [accessible, setAccessible] = useState(false);
const [paywall, setPaywall] = useState(null);
useEffect(() => {
loadAccounts();
loadPaywall();
}, []);
const loadAccounts = async () => {
if (typeof window.ethereum !== "undefined") {
const accounts = await window.ethereum.request({ method: "eth_requestAccounts" });
setAccount(accounts[0]);
}
};
const loadPaywall = async () => {
if (typeof window.ethereum !== "undefined") {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const contractAddress = "your-contract-address"; // Replace with your contract's address
const paywallContract = new ethers.Contract(contractAddress, paywallArtifact.abi, provider);
try {
const signer = provider.getSigner();
const signedPaywallContract = paywallContract.connect(signer);
setPaywall(signedPaywallContract);
} catch (err) {
console.log("Error: ", err);
}
}
};
const handleAccess = async () => {
if (paywall) {
try {
const valueToSend = ethers.utils.parseUnits("0.01", "ether");
const tx = await paywall.grantAccess({ value: valueToSend });
const receipt = await tx.wait();
if (receipt.status === 1) {
setAccessible(true);
}
} catch (err) {
console.log("Error: ", err);
}
}
};
return (
<div className="App">
<h1>Ethereum Paywall</h1>
{!accessible ? (
<button onClick={handleAccess}>Pay 0.01 ETH to access content</button>
) : (
<div>
<h2>Exclusive Content</h2>
<p>You have successfully unlocked the exclusive content!</p>
</div>
)}
</div>
);
};
export default App;
```
Make sure to replace "your-contract-address" with the contract's address that you noted earlier.
Now run the React app:
```
npm start
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment