Last active
April 7, 2023 19:07
-
-
Save normandmickey/7462cf56892e38bcdd48e47a68245af3 to your computer and use it in GitHub Desktop.
Ethereum Paywall
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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