aelf 백서

bitpro가 원문에서 글자만 모은 내용이에요. 표·그림·수식은 빠지거나 깨질 수 있어요. 전체 41쪽 중 26쪽

// The contract address. aelf . Address contract_address = 1 ; // Resource tokens to charge. TotalResourceTokensMap tokens_map = 2 ; } message TotalResourceTokensMap { // Resource token dictionary, Symbol->Amount. map < string , int64 > value = 1 ; } message StringList { repeated string value = 1 ; } message TransactionFeeDelegations { // delegation, symbols and its' amount map < string , int64 > delegations = 1 ; // height when added int64 block_height = 2 ; //Whether to pay transaction fee continuously bool isUnlimitedDelegate = 3 ; } message TransactionFeeDelegatees { map < string , TransactionFeeDelegations > delegatees = 1 ; } message SetTransactionFeeDelegationsInput { // the delegator address aelf . Address delegator_address = 1 ; // delegation, symbols and its' amount map < string , int64 > delegations = 2 ; } message SetTransactionFeeDelegationsOutput { bool success = 1 ; } message RemoveTransactionFeeDelegatorInput { // the delegator address aelf . Address delegator_address = 1 ; } message RemoveTransactionFeeDelegateeInput { // the delegatee address aelf . Address delegatee_address = 1 ; } message GetTransactionFeeDelegationsOfADelegateeInput { aelf . Address delegatee_address = 1 ; aelf . Address delegator_address = 2 ; } message GetTransactionFeeDelegateesInput { aelf . Address delegator_address = 1 ; } message GetTransactionFeeDelegateesOutput { repeated aelf . Address delegatee_addresses = 1 ; } message SetSymbolAliasInput { string symbol = 1 ; string alias = 2 ; } // Events message Transferred { option ( aelf . is_event ) = true ; // The source address of the transferred token. aelf . Address from = 1 [ ( aelf . is_indexed ) = true ] ; // The destination address of the transferred token. aelf . Address to = 2 [ ( aelf . is_indexed ) = true ] ; // The symbol of the transferred token. string symbol = 3 [ ( aelf . is_indexed ) = true ] ; // The amount of the transferred token. int64 amount = 4 ; // The memo. string memo = 5 ; } message Approved { option ( aelf . is_event ) = true ; // The address of the token owner. aelf . Address owner = 1 [ ( aelf . is_indexed ) = true ] ; // The address that allowance be increased. aelf . Address spender = 2 [ ( aelf . is_indexed ) = true ] ; // The symbol of approved token. string symbol = 3 [ ( aelf . is_indexed ) = true ] ; // The amount of approved token. int64 amount = 4 ; } message UnApproved { option ( aelf . is_event ) = true ; // The address of the token owner. aelf . Address owner = 1 [ ( aelf . is_indexed ) = true ] ; // The address that allowance be decreased. aelf . Address spender = 2 [ ( aelf . is_indexed ) = true ] ; // The symbol of un-approved token. string symbol = 3 [ ( aelf . is_indexed ) = true ] ; // The amount of un-approved token. int64 amount = 4 ; } message Burned { option ( aelf . is_event ) = true ; // The address who wants to burn token. aelf . Address burner = 1 [ ( aelf . is_indexed ) = true ] ; // The symbol of burned token. string symbol = 2 [ ( aelf . is_indexed ) = true ] ; // The amount of burned token. int64 amount = 3 ; } message ChainPrimaryTokenSymbolSet { option ( aelf . is_event ) = true ; // The symbol of token. string token_symbol = 1 ; } message CalculateFeeAlgorithmUpdated { option ( aelf . is_event ) = true ; // All calculate fee coefficients after modification. AllCalculateFeeCoefficients all_type_fee_coefficients = 1 ; } message RentalCharged { option ( aelf . is_event ) = true ; // The symbol of rental fee charged. string symbol = 1 ; // The amount of rental fee charged. int64 amount = 2 ; // The payer of rental fee. aelf . Address payer = 3 ; // The receiver of rental fee. aelf . Address receiver = 4 ; } message RentalAccountBalanceInsufficient { option ( aelf . is_event ) = true ; // The symbol of insufficient rental account balance. string symbol = 1 ; // The balance of the account. int64 amount = 2 ; } message TokenCreated { option ( aelf . is_event ) = true ; // The symbol of the token. string symbol = 1 ; // The full name of the token. string token_name = 2 ; // The total supply of the token. int64 total_supply = 3 ; // The precision of the token. int32 decimals = 4 ; // The address that has permission to issue the token. aelf . Address issuer = 5 ; // A flag indicating if this token is burnable. bool is_burnable = 6 ; // The chain id of the token. int32 issue_chain_id = 7 ; // The external information of the token. ExternalInfo external_info = 8 ; // The address that owns the token. aelf . Address owner = 9 ; } message Issued { option ( aelf . is_event ) = true ; // The symbol of issued token. string symbol = 1 ; // The amount of issued token. int64 amount = 2 ; // The memo. string memo = 3 ; // The issued target address. aelf . Address to = 4 ; } message CrossChainTransferred { option ( aelf . is_event ) = true ; // The source address of the transferred token. aelf . Address from = 1 ; // The destination address of the transferred token. aelf . Address to = 2 ; // The symbol of the transferred token. string symbol = 3 ; // The amount of the transferred token. int64 amount = 4 ; // The memo. string memo = 5 ; // The destination chain id. int32 to_chain_id = 6 ; // The chain id of the token. int32 issue_chain_id = 7 ; } message CrossChainReceived { option ( aelf . is_event ) = true ; // The source address of the transferred token. aelf . Address from = 1 ; // The destination address of the transferred token. aelf . Address to = 2 ; // The symbol of the received token. string symbol = 3 ; // The amount of the received token. int64 amount = 4 ; // The memo. string memo = 5 ; // The destination chain id. int32 from_chain_id = 6 ; // The chain id of the token. int32 issue_chain_id = 7 ; // The parent chain height of the transfer transaction. int64 parent_chain_height = 8 ; // The id of transfer transaction. aelf . Hash transfer_transaction_id = 9 ; } message TransactionFeeDelegationAdded { option ( aelf . is_event ) = true ; aelf . Address delegator = 1 [ ( aelf . is_indexed ) = true ] ; aelf . Address delegatee = 2 [ ( aelf . is_indexed ) = true ] ; aelf . Address caller = 3 [ ( aelf . is_indexed ) = true ] ; } message TransactionFeeDelegationCancelled { option ( aelf . is_event ) = true ; aelf . Address delegator = 1 [ ( aelf . is_indexed ) = true ] ; aelf . Address delegatee = 2 [ ( aelf . is_indexed ) = true ] ; aelf . Address caller = 3 [ ( aelf . is_indexed ) = true ] ; } message SymbolAliasAdded { option ( aelf . is_event ) = true ; string symbol = 1 [ ( aelf . is_indexed ) = true ] ; string alias = 2 [ ( aelf . is_indexed ) = true ] ; } message SymbolAliasDeleted { option ( aelf . is_event ) = true ; string symbol = 1 [ ( aelf . is_indexed ) = true ] ; string alias = 2 [ ( aelf . is_indexed ) = true ] ; } Building Smart Contract ​ Build the smart contract code with the following command inside src folder: Terminal dotnet build You should see SinglePoolStaking.dll.patched in the directory SinglePoolStaking/src/bin/Debug/net.8.0 Step 3 - Deploy Smart Contract ​ Create A Wallet ​ To send transactions on the aelf blockchain, you must have a wallet. Run this command to create aelf wallet. Terminal aelf-command create You will be prompted to save your account, please do save your account as shown below: Terminal ? Save account info into a file? ( Y/n ) Y Make sure to choose Y to save your account information. tip ℹ️ Note: If you do not save your account information (by selecting n or N), do not export the wallet password. Only proceed to the next step if you have saved your account information. Next, enter and confirm your password. Then export your wallet password as shown below: Linux and macOs Windows Terminal export WALLET_PASSWORD = "YOUR_WALLET_PASSWORD" Command Prompt $env :WALLET_PASSWORD = "YOUR_WALLET_PASSWORD" Acquire Testnet Tokens (Faucet) for Development ​ To deploy smart contracts or execute on-chain transactions on aelf, you'll require testnet ELF tokens. Get ELF Tokens Go to https://faucet-ui.aelf.dev Enter your address and click Get Tokens . Deploy Smart Contract: The smart contract needs to be deployed on the chain before users can interact with it. Run the following command to deploy a contract. Remember to export the path of SinglePoolStaking.dll.patched to CONTRACT_PATH. Linux and macOs Windows Terminal export CONTRACT_PATH = $( find ~+ . -path "*patched*" | head -n 1 ) Terminal aelf-deploy -a $WALLET_ADDRESS -p $WALLET_PASSWORD -c $CONTRACT_PATH -e https://tdvw-test-node.aelf.io/ Command Prompt $CONTRACT_PATH = Get-ChildItem -Recurse -Filter "*patched*" | Select-Object -First 1 -ExpandProperty FullName $env :CONTRACT_PATH = $CONTRACT_PATH Command Prompt aelf-deploy -a $env :WALLET_ADDRESS -p $env :WALLET_PASSWORD -c $env :CONTRACT_PATH -e https://tdvw-test-node.aelf.io/ Please wait for approximately 1 to 2 minutes. If the deployment is successful, it will provide you with the contract address. Copy the smart contract address from the address field Export your smart contract address: Linux and macOs Windows Terminal export CONTRACT_ADDRESS = "YOUR_SMART_CONTRACT_ADDRESS e.g. 2LUmicHyH4RXrMjG4beDwuDsiWJESyLkgkwPdGTR8kahRzq5XS" Command Prompt $env :CONTRACT_ADDRESS = "YOUR_SMART_CONTRACT_ADDRESS e.g. 2LUmicHyH4RXrMjG4beDwuDsiWJESyLkgkwPdGTR8kahRzq5XS" tip ℹ️ Note: You are to copy the smart contract address as we will be referencing it in the next steps! info 🎉 You have successfully deployed your Single Pool Staking dApp smart contract on the aelf testnet! In the next steps, we will be building the frontend components that allow us to interact with our deployed smart contract! Step 4 - Getting TOKEN Seed ​ In order to create a fungible token on the aelf blockchain, the deployer wallet must have a TOKEN SEED . Visit TOKEN Faucet to get your TOKEN SEED. After the request is successfully processed, the requestor wallet will receive the SEED . Please note this SEED symbol value separately as it will be needed while creating the fungible token and staking integration. This will become our Token Symbol . Step 5 - Interact with Your Deployed Smart Contracts ​ Project Setup ​ Let's start by cloning the frontend project repository from github. Run the following command in your Terminal: Terminal git clone https://github.com/AElfProject/aelf-samples.git Next, navigate to the staking frontend project directory with this command: Terminal cd aelf-samples/staking/2-dapp Once you're inside 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 this command in the terminal to install all necessary packages and libraries. Linux and macOs Windows Terminal sudo npm install Command Prompt npm install We are now ready to build the frontend components of our Staking dApp. Configure Portkey Provider & Write Contract Hooks Function ​ We'll set up our Portkey provider to allow users to connect their Portkey wallets to the dApp and interact with the aelf smart contracts. We'll be interacting with the Stakinng contract and the Multi-token contract. Write Functions for MainChain and dAppChain Contracts ​ Step 1. Locate the File: Go to the src/hooks/useSmartContract.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 the below code: useSmartContract.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 : This function fetches chain information using the provider. Get Contract : It retrieves the smart contract instance from the chain. 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: useStakingContract.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. MainChain Contract : Fetches the mainchain testnet contract and sets it in the state. dAppChain Contract : Fetches the dAppChain testnet contract and sets it in the state. Write Functions for Staking Contract ​ Step 4. Locate the File: Go to the src/hooks/useStakingContract.ts file. Step 5. Fetch the Smart Contract: Find the comment //Step C - Function to fetch a smart contract based on the chain symbol and the contract address Replace the existing fetchContract function with this updated code: useStakingContract.ts //Step C - 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. Step 6. Initialize and Fetch the Smart Contracts: Find the comment // Step D - Effect hook to initialize and fetch the smart contracts when the provider changes Replace the existing useEffect hook with this updated code: useStakingContract.ts // Step D - Effect hook to initialize and fetch the smart contracts when the provider changes useEffect ( ( ) => { ( async ( ) => { // Fetch the Staking Testnet Contract const stakingContract = await fetchContract ( "tDVW" , stakingContractAddress ) ; setStakingSmartContract ( stakingContract as IContract ) ; } ) ( ) ; } , [ provider ] ) ; // Dependency array ensures this runs when the provider changes Explanation: useEffect Hook : This hook initializes and fetches the staking smart contract when the provider changes. Check Provider : If no provider is available, the function returns null. Fetch Contracts : It fetches and sets the smart contract for the staking. By following these steps, we'll configure the Portkey provider to connect users' wallets to the dApp and interact with the multi-token and staking smart contract including interaction with the fungible token and the staking functionalities. This setup will enable our frontend components to perform actions like create tokens , transfer tokens , and stake tokens , withdraw tokens , emergency withdraw tokens , etc. Configure Connect Wallet Function ​ Step 1: Locate the File Go to the src/components/layout/header/index.tsx file. Step 2: Write the Connect Wallet Function The header/index.tsx file is the header of our Staking dApp. It allows users to connect their Portkey wallet with the staking dApp. Before users can interact with the smart contract, we need to write the Connect Wallet function. Find the comment // Step E - Connect Portkey Wallet . Replace the existing connect function with this code snippet: header/index.tsx // Step E - Connect Portkey Wallet const connect = async ( walletProvider ? : IPortkeyProvider ) => { const accounts = await ( walletProvider ? walletProvider : provider ) ?. request ( { method : MethodsBase . REQUEST_ACCOUNTS , } ) ; const account = accounts ?. AELF && accounts ?. AELF [ 0 ] ; if ( account ) { setCurrentWalletAddress ( account . replace ( / ^ ELF_ / , "" ) . replace ( / _AELF $ / , "" ) ) ; setIsConnected ( true ) ; } ! walletProvider && toast . success ( "Successfully connected" ) ; } ; Explanation: connect Function : This function connects the user's Portkey wallet with the dApp. Fetch Accounts : It fetches the wallet accounts using the provider. Log Accounts : Logs the accounts to the console for debugging. Set Wallet Address : Sets the current wallet address state variable with the fetched account. Update Connection Status : Updates the state to indicate that the wallet is connected. In this code, we fetch the Portkey wallet account using the provider and update the wallet address state variable. An alert notifies the user that their wallet is successfully connected. With the ConnectWallet function defined, we're ready to write the remaining functions in the next steps. Configure Create TOKEN Form ​ Step 1: Locate the File Go to the src/components/create-token-modal/index.tsx file. This file is the Create Fungible TOKEN popup modal where users can create a new TOKEN by submitting the details like tokenName , symbol and totalSupply . Step 2: Prepare Form to Create TOKEN Find the comment // Step F - Configure TOKEN Create Form . Replace the form variable with this code snippet: create-token-modal/index.tsx // Step F - Configure TOKEN Create Form const form = useForm < z . infer < typeof formSchema >> ( { resolver : zodResolver ( formSchema ) , defaultValues : { tokenName : "$T
프로젝트로 돌아가기