bitpro가 원문에서 글자만 모은 내용이에요. 표·그림·수식은 빠지거나 깨질 수 있어요. 전체 41쪽 중 15쪽
ert.
Calls the JoinDAO method with your wallet address, updating the state and showing a success alert.
Now, wrap the
initializeAndJoinDAO
function in the "Join DAO" button to trigger both Initialize and JoinDAO when clicked.
Next, we'll write the
Create Proposal
function.
Write Create Proposal Function
Let's write the Create Proposal function.
Go to the
src/CreateProposal.tsx
file. This file is the "Create Proposal" page where users can enter details like the proposal title, description, and vote threshold.
Find the comment
Step D - Configure Proposal Form
.
Replace the form variable with this code snippet:
src/CreateProposal.tsx
//Step D - Configure Proposal Form
const
form
=
useForm
<
z
.
infer
<
typeof
formSchema
>>
(
{
resolver
:
zodResolver
(
formSchema
)
,
defaultValues
:
{
address
:
currentWalletAddress
,
title
:
""
,
description
:
""
,
voteThreshold
:
0
,
}
,
}
)
;
tip
ℹ️ Note: We set
currentWalletAddress
as the default value because the wallet address is passed from the HomeDAO.tsx page when the user clicks "Create Proposal" on the landing page.
Default value:
address: currentWalletAddress
Here's what the function does:
Initializes a new form variable with default values needed to create a proposal.
Fields include:
address
,
title
,
description
, and
vote threshold
.
Now your form is ready for users to fill in the necessary details for their proposal.
Now, let's write the Create Proposal function for the form submission.
Scroll down to find the comment
Step E - Write Create Proposal Logic
.
Replace the onSubmit function with this code snippet:
src/CreateProposal.tsx
// Step E - Write Create Proposal Logic
function
onSubmit
(
values
:
z
.
infer
<
typeof
formSchema
>
)
{
const
proposalInput
:
IProposalInput
=
{
creator
:
currentWalletAddress
,
title
:
values
.
title
,
description
:
values
.
description
,
voteThreshold
:
values
.
voteThreshold
,
}
;
const
createNewProposal
=
async
(
)
=>
{
try
{
await
DAOContract
?.
callSendMethod
(
"CreateProposal"
,
currentWalletAddress
,
proposalInput
)
;
navigate
(
"/"
)
;
alert
(
"Successfully created proposal"
)
;
}
catch
(
error
)
{
console
.
error
(
error
)
;
}
}
;
createNewProposal
(
)
;
}
Here's what the function does:
Creates a new
proposalInput
variable with form fields:
title
,
description
, and
vote threshold
.
Invokes the
CreateProposal
function of the deployed smart contract, using the current wallet address and
proposalInput
.
If successful, navigates the user to the landing page and shows an alert that the proposal was created.
Next, we'll write the
Vote
and
Fetch Proposal
functions to complete the frontend components of our Voting dApp.
Write Vote & Fetch Proposals Function
In this step, we'll write the Vote and Fetch Proposals functions to complete our Voting dApp's frontend components.
Go to the
src/HomeDAO.tsx
file and scroll to the
Step F - Write Vote Yes Logic comment
.
Replace the
voteYes
function with this code snippet:
src/HomeDAO.tsx
const
voteYes
=
async
(
index
:
number
)
=>
{
//Step F - Write Vote Yes Logic
try
{
const
accounts
=
await
provider
?.
request
(
{
method
:
MethodsBase
.
ACCOUNTS
,
}
)
;
if
(
!
accounts
)
throw
new
Error
(
"No accounts"
)
;
const
account
=
accounts
?.
tDVW
?.
[
0
]
;
if
(
!
account
)
throw
new
Error
(
"No account"
)
;
const
createVoteInput
:
IVoteInput
=
{
voter
:
account
,
proposalId
:
index
,
vote
:
true
,
}
;
await
DAOContract
?.
callSendMethod
(
"VoteOnProposal"
,
account
,
createVoteInput
)
;
alert
(
"Voted on Proposal"
)
;
setHasVoted
(
true
)
;
}
catch
(
error
)
{
console
.
error
(
error
,
"=====error"
)
;
}
}
;
Here's what the function does:
Takes an
index
parameter, representing the proposal ID to vote on.
Fetches the wallet address using the Portkey provider.
Creates a
createVoteInput
parameter with the voter's wallet address, proposal ID, and a
true
value for a Yes vote..
Calls the
VoteOnProposal
function from the smart contract.
Updates the state and shows an alert upon a successful vote.
The
voteNo
function works similarly but sets the vote to
false
.
Scroll down to the
Step G - Use Effect to Fetch Proposals
comment and replace the
useEffect
hook with this code snippet:
src/HomeDAO.tsx
useEffect
(
(
)
=>
{
// Step G - Use Effect to Fetch Proposals
const
fetchProposals
=
async
(
)
=>
{
try
{
const
accounts
=
await
provider
?.
request
(
{
method
:
MethodsBase
.
ACCOUNTS
,
}
)
;
if
(
!
accounts
)
throw
new
Error
(
"No accounts"
)
;
const
account
=
accounts
?.
tDVW
?.
[
0
]
;
if
(
!
account
)
throw
new
Error
(
"No account"
)
;
if
(
!
DAOContract
)
return
;
const
proposalResponse
=
await
(
DAOContract
?.
callViewMethod
)
<
IProposals
>
(
"GetAllProposals",
""
);
setProposals(proposalResponse.data);
alert("Fetched Proposals");
} catch (error)
{
console
.
error
(
error
)
;
}
};
fetchProposals();
}, [DAOContract, hasVoted, isConnected, joinedDAO]);
Here's what the function does:
Defines the
fetchProposals
function that fetches the wallet address.
Calls the
GetAllProposals
function from the smart contract, returning a list of proposals.
Updates the state and shows an alert once the proposals are fetched.
Now that we've written all the necessary frontend functions and components, we're ready to run the Voting dApp application in the next step.
Run Application
In this step, we will run the Voting dApp application.
To begin, run the following command on your terminal.
Terminal
npm
run dev
info
ℹ️ Note: Ensure that you are running this command under the
vote/2-dapp
folder.
You should observe the following as shown below.
Upon clicking on the
localhost URL
, you should be directed to the StackUpDAO landing page as shown below.
tip
If you are developing and testing this with GitHub codespace, you can use Port Forward to test the web server that is running in codespace, here is the link on how to use Port forward for codespace
https://docs.github.com/en/codespaces/developing-in-a-codespace/forwarding-ports-in-your-codespace
Usually codespace will automatically forward port, you should see a pop-up message at the bottom right of your codespace browser window as shown in the diagram below:
Click the link to open the Voting dApp in the browser.
Create Portkey Wallet
info
Portkey is the first AA wallet from aelf's ecosystem, migrating users, developers and projects from Web2 to Web3 with DID solution.
Users can swiftly log into Portkey via their Web2 social info with no private keys or mnemonics required. Underpinned by social recovery and decentralized guardian design, Portkey safeguards users' assets from centralized control and theft. Portkey has a unique payment delegation mechanism which enables interested parties to function as delegatees to pay for user activities on users' behalf. This means that users can create accounts for free and fees for other usages may also be covered in Portkey.
Portkey also provides crypto on/off-ramp services, allowing users to exchange fiat with crypto freely. It supports the storage and management of various digital assets such as tokens, NFTs, etc. The compatibility with multi-chains and seamless connection to all kinds of DApps makes Portkey a great way to enter the world of Web3.
With DID solution as its core, Portkey provides both Portkey Wallet and Portkey SDKs.
For more information, you may visit the official documentation for Portkey at
https://doc.portkey.finance/
.
Download the Chrome extension for Portkey from
https://chromewebstore.google.com/detail/portkey-wallet/iglbgmakmggfkoidiagnhknlndljlolb
.
info
The Portkey extension supports Chrome browser only (for now). Please ensure that you are using Chrome browser.
You may download Chrome from
https://www.google.com/intl/en_sg/chrome/
.
Once you have downloaded the extension, you should see the following on your browser as shown below.
Click on
Get Start
and you should see the following interface as shown below.
Sign up
Switch to
aelf Testnet
network by selecting it:
danger
Please make sure you are using
aelf Testnet
in order to be able to receive your testnet tokens from the Faucet.
Proceed to sign up with a Google Account or your preferred login method and complete the necessary accounts creation prompts and you should observe the following interface once you have signed up.
With that, you have successfully created your very first Portkey wallet within seconds. How easy was that?
info
It is highly recommended to pin the Portkey wallet extension for easier access and navigation to your Portkey wallet!
Next, click on ‘Open Portkey’ and you should now observe the following as shown below.
Connect Portkey Wallet
Click on
"Connect Wallet"
to connect your Portkey wallet. The button will change to
"Connected"
when the connection is successful.
Next, click on
"Join DAO"
. You will be prompted to sign the
"Initialize"
and
"Join DAO"
methods, as shown below.
Once you have successfully joined the DAO, you should observe now that the landing page renders the proposal we have defined in our smart contract as shown below.
Proposal #1 as defined in smart contract
danger
⚠️ Reminder: This proposal has been hard coded within our smart contract to test our vote functionality and is meant for educational purposes! In actual production settings, proposals should not be hardcoded within your smart contract!
Let’s test our Vote functionality next.
Proceed to click on
"Vote Yes"
and you should observe the following as shown below prompting you to sign the
"Vote Yes"
transaction.
Proceed to click on
"Sign"
.
Upon a successful vote transaction, you should now observe that the proposal status has been updated to
"PASSED"
as shown below as the Yes vote count has reached the vote threshold.
Proposal status updated to
"PASSED"
Lastly, we will be creating a proposal to wrap up our demonstration of our Voting dApp.
Click on
"Create Proposal"
for Proceed and you should be directed to the Create Proposal page as shown below.
Proceed to fill in the following fields under the Create Proposal form:
Title
- Proposal #2
Description
- Proposal to onboard Developer DAO
Vote Threshold
- 10
click on
"Submit"
and you should observe the following as shown below.
Click on
"Sign"
to Proceed.
Upon a successful proposal creation, you should be directed back to the landing page with the newly created proposal rendered on the landing page as shown below.
success
🎉 Congratulations Learners! You have successfully built your Voting dApp and this is no mean feat!
🎯 Conclusion
🎊 Congratulations on completing the Voting Contract tutorial! 🎊 You've reached an important milestone in your journey through aelf blockchain development. 🌟
📚 What You've Learned
Throughout this tutorial, you've gained expertise in:
🛠️ Setting up your development environment for aelf blockchain development.
💻 Implementing complex smart contract logic for secure and transparent voting mechanisms.
🚀 Deploying and interacting with your Voting Smart Contract on the aelf testnet, and integrating it into a frontend application. You've learned how to connect user interfaces with blockchain smart contracts, enabling users to participate in DAOs, create proposals, vote, and track outcomes in real-time.
🔍 Final Output
By now, you should have:
📜 Successfully deployed your Voting Smart Contract on the aelf blockchain.
🎉 Interacted with the contract to join the DAO, create proposals, and participate in voting processes. Seeing your proposals progress based on votes is a testament to your understanding of decentralized decision-making! 🏆
➡️ What's Next?
Now that you've mastered the intricacies of voting contracts, it's time to explore more advanced topics or consider enhancing your knowledge in specialized areas of blockchain development. Dive into topics like:
📊 Implementing governance mechanisms for DAOs.
🔒 Enhancing security protocols for smart contracts.
🌐 Exploring cross-chain interoperability with aelf.
Keep pushing the boundaries of blockchain technology with aelf. Your journey doesn't end here – it's just the beginning of even more exciting possibilities in decentralized applications and smart contracts. 🚀
Happy coding and innovating with aelf! 😊
Step 1 - Setting up your development environment
Step 2 - Develop Smart Contract
Project Setup
Adding Your Smart Contract Code
Defining Methods and Messages
Defining Contract State
Implement Voting Smart Contract Logic
Complete Implementation
Building Smart Contract
Step 3 - Deploy Smart Contract
Step 4 - Interact with Your Deployed Smart Contract
Project Setup
Configure Portkey Provider & Write Connect Wallet Function
Write Initialize Smart Contract & Join DAO Functions
Write Create Proposal Function
Write Vote & Fetch Proposals Function
Run Application
🎯 Conclusion
## /quick-start/developers/nft-dapp
On this page
Description
: This tutorial provides a comprehensive guide to building an NFT dApp using aelf's multi-token contract. It covers the entire process from creating NFT collections to generating non-fungible tokens and enabling seamless transfers between token holders on the aelf blockchain.
Purpose
: The tutorial aims to introduce users to the world of NFTs on aelf by demonstrating the use of aelf's multi-token contract for creating NFT collections, minting unique tokens, and performing token transfers. This hands-on approach allows developers to explore and harness the power of aelf's decentralized infrastructure for NFT development.
Difficulty Level
: Moderate
Step 1 - Setting up your development environment
Local
Codespaces
Basic knowledge of terminal commands
IDE
- Install
VS Code
Note for Apple Silicon users:
Ensure that Rosetta is installed, if it is not, use the following command:
Terminal
softwareupdate --install-rosetta
Install Required Packages
Install dotnet 8.0.x SDK
Install aelf contract templates
Linux and macOs
Windows
Terminal
dotnet new
--install
AElf.ContractTemplates
Command Prompt
dotnet new
install
AElf.ContractTemplates
AELF.ContractTemplates contains various predefined templates for the ease of developing smart contracts on the aelf blockchain.
Install aelf deploy tool
Terminal
dotnet tool
install
--global
aelf.deploy
aelf.deploy is a utility tool for deploying smart contracts on the aelf blockchain.
Please remember to export PATH after installing aelf.deploy.
info
ℹ️ Note: If you have installed aelf.deploy and your terminal says that there is no such command available, please uninstall and install aelf.deploy.
Install Node.js and Yarn
Install Node.js
Install Yarn
Install aelf-command
Linux and macOs
Windows
Terminal
sudo
npm
i
-g
aelf-command
Command Prompt
npm
i
-g
aelf-command
aelf-command is a CLI tool for interacting with the aelf blockchain, enabling tasks like creating wallets and managing transactions.
Provide required permissions while installing aelf-command globally.
Visit
aelf-devcontainer-template
.
Click the
Use this template
button. Choose
Create a new repository
.
Enter a suitable repository name. Click
Create repository
.
Within the GitHub interface of your new repository, click on
Code
.
Select
Codespaces
.
Click on the
+
sign to create a new Codespace.
After some time, your workspace will load with the contents of the repository.
You can now continue your development using GitHub Codespaces.
Step 2 - Getting NFT Seed
In order to create an NFT collection on the aelf blockchain, the deployer wallet must have an
NFT SEED
.
Visit
NFT Faucet
to get your NFT SEED.
After the request is successfully processed, the requestor wallet will receive the
SEED
.
Please note this
SEED
symbol value, as it will be needed later while creating the NFT collection and NFT generation. This will become our
Token Symbol
.
Step 3 - Interact with aelf's multi-token contract
Project Setup
Let's start by cloning the frontend project repository from GitHub.
Run the following command your Terminal:
Terminal
git
clone https://github.com/AElfProject/aelf-samples.git
Next, navigate to the frontend project directory with this command:
Terminal
cd
aelf-samples/nft/2-dapp
Once you're in the
2-dapp
directory, open the project with your preferred IDE (e.g., VSCode). You should see the project structure as shown below.
Install necessary packages and libraries
Run teh following command in the terminal:
Linux and macOs
Windows
Terminal
sudo
npm
install
Command Prompt
npm
install
We are now ready to build the frontend components of our NFT dApp.
Configure Portkey Provider & Write Connect Wallet Function
We'll set up our Portkey provider to allow users to connect their Portkey wallets to our app and interact with the aelf smart contracts. We'll be interacting with the already deployed multi-token contract for this tutorial.
Step 1. Locate the File:
Go to the
src/hooks/useNFTSmartContract.ts
file.
Step 2. Fetch the Smart Contract:
Find the comment
//Step A - Function to fetch a smart contract based on the chain symbol and the contract address.
Replace the existing
fetchContract
function with this updated code:
useNFTSmartContract.ts
//Step A - Function to fetch a smart contract based on the chain symbol and the contract address
const
fetchContract
=
async
(
symbol
:
"AELF"
|
"tDVW"
,
contractAddress
:
string
)
=>
{
try
{
// If no provider is available, return null
if
(
!
provider
)
return
null
;
// Fetch the chain information using the provider
const
chain
=
await
provider
.
getChain
(
symbol
)
;
if
(
!
chain
)
throw
new
Error
(
"Chain not found"
)
;
// Get the smart contract instance from the chain
const
contract
=
chain
.
getContract
(
contractAddress
)
;
// Return the smart contract instance
return
contract
;
}
catch
(
error
)
{
console
.
error
(
"Error in fetchContract"
,
{
symbol
,
contractAddress
,
error
}
)
;
}
}
;
Explanation:
fetchContract
Function
: This function fetches a smart contract based on the given chain symbol (e.g., "AELF" or "tDVW") and the contract address.
Check Provider
: If no provider is available, the function returns null.
Fetch Chain
: The function fetches chain information using the provider.
Get Contract
: It retrieves the smart contract instance from the chain.
Error Handling
: If an error occurs, it logs the error to the console.
Step 3. Initialize and Fetch the Smart Contracts:
Find the comment
// Step B - Effect hook to initialize and fetch the smart contracts when the provider changes.
Replace the existing
useEffect
hook with this updated code:
useNFTSmartContract.ts
// Step B - Effect hook to initialize and fetch the smart contracts when the provider changes
useEffect
(
(
)
=>
{
(
async
(
)
=>
{
// Fetch the MainChain Testnet Contract
const
mainChainContract
=
await
fetchContract
(
"AELF"
,
"JRmBduh4nXWi1aXgdUsj5gJrzeZb2LxmrAbf7W99faZSvoAaE"
)
;
setMainChainSmartContract
(
mainChainContract
as
IContract
)
;
// Fetch the dAppChain Testnet Contract
const
sideChainContract
=
await
fetchContract
(
"tDVW"
,
"ASh2Wt7nSEmYqnGxPPzp4pnVDU4uhj1XW9Se5VeZcX2UDdyjx"
)
;
setSideChainSmartContract
(
sideChainContract
as
IContract
)
;
}
)
(
)
;
}
,
[
provider
]
)
;
// Dependency array ensures this runs when the provider changes
Explanation:
useEffect
Hook
: This hook initializes and fetches the smart contracts when the provider changes.
Check Provider
: If no provider is available, the function returns null.
Fetch Contracts
: It fetches and sets the smart contracts for the main chain, side chain, and cross chain.
MainChain Contract
: Fetches the MainChain Testnet Contract and sets it in the state.
dAppChain Contract
: Fetches the dAppChain Test프로젝트로 돌아가기