This article was created thanks to @vitiv (Yavhen Vitiv)!
In contrast to traditional applications that have their back-end parts running on centralized servers, dApp’s backend code runs autonomously in a decentralized network, like the OnFlow network.
Smart contracts are programs used for agreement execution running when predetermined conditions are met. They allow involved parties to safely release funds, register vehicles, issue tickets, and even send notifications without intermediaries.
Smart contracts provide for high-level security and transparency, speed, accuracy, and notable cost efficiency. These can be used in various different industries, including healthcare, distribution, retail, and more.
dApps allow to interact with smart contracts deployed on the blockchain.
How to build a client-side application that interacts with smart contract in the blockchain network
The application we're about to build will have the following functionality:
- Log-in and log-out buttons
- User profiles
- The opportunity to update user profiles
- Account address directly connected to the blockchain network
Step 1. Installing dependencies
- Install the Node Package Manager (NPM)
- Install the Flow CLI to run local emulator
- Clone the fcl-dev-wallet repository in a separate folder to run dev wallet and the npm install
Step 2. Setting up ReactJS dApp and the npm packages
Create a ReactJS dApp:
npx create-react-app my-first-dapp
Install the OnFlow packages from the my-first-dapp directory:
npm i @onflow/fcl @onflow/types
Step 3. Setting up Tailwind CSS
This step is optional, but if you like, you can read how to set up Tailwind CSS.
Step 4. Running the local emulator with the dev wallet
In the fcl-dev-wallet repository, you will have to run these two commands:
flow emulator
npm run dev
Step 5. Creating the AppJS component with built-in log-in and log-out buttons
In the src/AppJS file, you can create the AppJS component with the log-in and log-out logic:
mport * as fcl from "@onflow/fcl";
import './App.css';
import { useEffect, useState } from "react";
fcl
.config()
// Point App at Emulator REST API
.put("accessNode.api", "http://localhost:8888")
// Point FCL at dev-wallet (default port)
.put("discovery.wallet", "http://localhost:8701/fcl/authn")
function App() {
const [isLogged, setIsLogged] = useState(false);
const [user, setUser] = useState();
useEffect(() => {
fcl.currentUser.subscribe((account) => {
setUser(account);
setIsLogged(account.addr)
});
}, [])
const logIn = () => {
fcl.authenticate();
}
const logOut = () => {
fcl.unauthenticate();
}
return (
<div className="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
{isLogged ? (
<div className="p-3">
<h3 className="text-2xl">{user.addr}</h3>
<button onClick={logOut}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Logout
</button>
</div>
) : (
<button onClick={logIn}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Login
</button>
)}
</div>
);
}
export default App;
Step 6. Running the ReactJS dApp
Run the npm-start command and open the page in http://localhost:3000/
Step 7. Creating first smart contract
Create the Profile.cdc file in the fcl-dev-wallet/cadence/contract directory:
Add the smart contract to the configuration file of the fcl-dev-wallet/flow.json directory:
{
…
"contracts": {
"Profile": {
"source": "./cadence/contracts/Profile.cdc"
"aliases": {
"emulator": "0xee82856bf20e2aa6"
}
},
…
},
…
"deployments": {
"emulator": {
"emulator-account": ["FUSD", "Profile"]
}
}
}
Deploy the Profile.cdc file to the local emulator:
flow project deploy --update
Step 8. Creating first cadence script
Extract data from the blockchain network:
const getProfile = async () => {
const [firstName, lastName, email] = await fcl.send([
fcl.script`
import Profile from 0xf8d6e0586b0a20c7
pub fun main(): [String] {
return [Profile.firstName, Profile.lastName, Profile.email]
}
`
]).then(fcl.decode)
setProfile({ firstName, lastName, email })
}
view raw
Step 9. Creating first blockchain transaction
Create the blockchain transaction to modify the data in the blockchain network:
const updateProfile = async () => {
const txId = await fcl.send(
[
fcl.transaction`
import Profile from 0xProfile
transaction(newFirstName: String, newLastName: String, newEmail: String) {
prepare(signer: AuthAccount) {
}
execute {
Profile.updateProfile(newFirstName: newFirstName, newLastName: newLastName, newEmail: newEmail)
}
}
`,// update profile transaction
fcl.args([
fcl.arg(profile.firstName, t.String),
fcl.arg(profile.lastName, t.String),
fcl.arg(profile.email, t.String)
]), // parameters of the transaction
fcl.proposer(fcl.authz), // The account that initiate this transaction
fcl.payer(fcl.authz), // The account that pays the fee for this transaction (free on local emulator)
fcl.authorizations([fcl.authz]), // A list of the accounts that are authorizing this transaction to mutate to their on-chain account state.
fcl.limit(9999), // The maximum number of computational units that can be used to execute this transaction.
]
).then(fcl.decode);
alert(`The transaction executed successfully`);
}
Step 10. Updating content
Add the cadence script and the blockchain transaction to the AppJS component and create a from to update the content (user profile):
import * as fcl from "@onflow/fcl";
import * as t from "@onflow/types"
import './App.css';
import { useEffect, useState } from "react";
fcl
.config()
// Point App at Emulator REST API
.put("accessNode.api", "http://localhost:8888")
// Point FCL at dev-wallet (default port)
.put("discovery.wallet", "http://localhost:8701/fcl/authn")
.put("0xProfile", "0xf8d6e0586b0a20c7");
function App() {
const [isLogged, setIsLogged] = useState(false);
const [user, setUser] = useState();
const [profile, setProfile] = useState();
useEffect(() => {
fcl.currentUser.subscribe((account) => {
setUser(account);
setIsLogged(account.addr)
getProfile();
});
}, [])
const getProfile = async () => {
const [firstName, lastName, email] = await fcl.send([
fcl.script`
import Profile from 0xProfile
pub fun main(): [String] {
return [Profile.firstName, Profile.lastName, Profile.email]
}
`
]).then(fcl.decode)
setProfile({ firstName, lastName, email })
}
const updateProfile = async (e) => {
e.preventDefault();
const txId = await fcl.send(
[
fcl.transaction`
import Profile from 0xProfile
transaction(newFirstName: String, newLastName: String, newEmail: String) {
prepare(signer: AuthAccount) {
}
execute {
Profile.updateProfile(newFirstName: newFirstName, newLastName: newLastName, newEmail: newEmail)
}
}
`,// update profile transaction
fcl.args([
fcl.arg(profile.firstName, t.String),
fcl.arg(profile.lastName, t.String),
fcl.arg(profile.email, t.String)
]), // parameters of the transaction
fcl.proposer(fcl.authz), // The account that initiate this transaction
fcl.payer(fcl.authz), // The account that pays the fee for this transaction (free on local emulator)
fcl.authorizations([fcl.authz]), // A list of the accounts that are authorizing this transaction to mutate to their on-chain account state.
fcl.limit(9999), // The maximum number of computational units that can be used to execute this transaction.
]
).then(fcl.decode);
console.log(txId);
alert(`The transaction executed successfully`);
}
const logIn = () => {
fcl.authenticate();
}
const logOut = () => {
fcl.unauthenticate();
}
const handleInputChange = (e) => {
setProfile({ ...profile, [e.target.id]: e.target.value });
}
const profileBlock = profile ? (<div className="border-b-2 block md:flex">
<div className="w-full p-8 bg-white shadow-md">
<form onSubmit={updateProfile} autoComplete="off">
<div className="pb-6">
<label htmlFor="firstName"
className="font-semibold text-gray-700 block pb-1">First Name</label>
<div className="flex">
<input id="firstName" required className="border-1 bg-gray-200 rounded-r px-4 py-2 w-full"
type="text" value={profile.firstName} onChange={handleInputChange}/>
</div>
</div>
<div className="pb-6">
<label htmlFor="lastName"
className="font-semibold text-gray-700 block pb-1">Last Name</label>
<div className="flex">
<input id="lastName" required className="border-1 bg-gray-200 rounded-r px-4 py-2 w-full"
type="text" value={profile.lastName} onChange={handleInputChange}/>
</div>
</div>
<div className="pb-6">
<label htmlFor="email"
className="font-semibold text-gray-700 block pb-1">Email</label>
<div className="flex">
<input id="email" autocomplete="nope" required
className="border-1 bg-gray-200 rounded-r px-4 py-2 w-full"
type="email" value={profile.email} onChange={handleInputChange}/>
</div>
</div>
<div>
<button type="submit"
className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
Update Profile
</button>
</div>
</form>
</div>
</div>) : '';
return (
<div className="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
{isLogged ? (
<div className="p-3">
<span className="inline-block text-2xl mr-2">Account address: {user.addr}</span>
<button onClick={logOut}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Logout
</button>
{profileBlock}
</div>
) : (
<button onClick={logIn}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Login
</button>
)}
</div>
);
}
export default App;
Now you can test you first decentralized application.
__
There are around 4,000 decentralized applications being utilized in government, healthcare and even gambling. And the positive dynamics undoubtedly attest the feasibility and profitability of adopting blockchain solutions. When speaking about their market dominance, decentralized apps are unlikely to replace traditional apps. However, they are expected to get more momentum in the business environment.
Here are some statistics to consider:
- Over 199000 Bitcoin transactions are carried out in a single day
- 10 percent of the global population own cryptocurrencies
- 16 percent of Americans have invested in cryptocurrency
- The global Blockchain market is expected to reach $34 billion by 2026 In dApps, personal and business data is stored in separate immutable blocks on the blockchain environment. This means, sensitive data is protected from exploitation, one of the most serious issues, which might be faced by both young startups and mature international corporations.
Top comments (3)
Wow Rally Nice Information I Like It sarkariprep.in
This is h amazing post work it (indjobalert.in)
Thanks for this amazing article. You can visit our proggapon website.