aelf 백서

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

kahRzq5XS" 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 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 - Interact with Your Deployed Smart Contract ​ Lets try to call methods on your newly-deployed smart contract using aelf-command . Firstly, we will set a message using the Update method. Run the following command, and enter the message argument as test . This will set test into the Message contract state. Remember to export CONTRACT_ADDRESS equals to your deployed contract address. Terminal aelf-command send $CONTRACT_ADDRESS -a $WALLET_ADDRESS -p $WALLET_PASSWORD -e https://tdvw-test-node.aelf.io Update After that, we can use Read method to retrieve the value previously set for the Message contract state. Running the following command should yield test . Terminal aelf-command call $CONTRACT_ADDRESS -a $WALLET_ADDRESS -p $WALLET_PASSWORD -e https://tdvw-test-node.aelf.io Read 🎯 Conclusion ​ 🎊 Congratulations! ​ You've successfully completed the Hello World Contract tutorial! Awesome job sticking with it until the end. 🌟 📚 What You've Learned ​ In this tutorial, you've discovered: 🛠️ How to set up your development environment for aelf. 💻 The basics of writing a smart contract in C# for the aelf blockchain. 🚀 How to deploy and interact with your Hello World Contract on the aelf network. 🔍 Final Output ​ By now, you should have: 📜 A deployed Hello World Contract on the aelf blockchain. 🎉 Successfully invoked the contract to set and read a message. To verify, you should have seen the test message returned when you called the Read method after setting it using the Update method. If you see this message, you've nailed it! 🏆 ➡️ What's Next? ​ Now that you've got the basics down, why not dive into more advanced topics or other tutorials like the Lottery Game Contract or Voting Contract? Keep experimenting and building to level up your aelf blockchain development skills. 🚀 Happy coding! 😊 Step 1 - Setting up your development environment Step 2 - Develop Smart Contract Start Your Smart Contract Project Adding Your Smart Contract Code Building Smart Contract Step 3 - Deploy Smart Contract Step 4 - Interact with Your Deployed Smart Contract 🎯 Conclusion ## /quick-start/developers/lottery-game-smart-contract On this page Description : This contract is moderately complex. It demonstrates the use of state variables, user interactions, and random number generation to create a basic lottery game. Purpose : To introduce you to more advanced concepts such as state management, event handling, and randomization in smart contracts. 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 - Develop Smart Contract ​ Start Your Smart Contract Project ​ Open your Terminal . Enter the following command to generate a new project: Terminal mkdir lottery-game cd lottery-game dotnet new aelf -n LotteryGame Adding Your Smart Contract Code ​ Now that we have a template lottery game project, we can customise the template to incorporate our own contract logic. Lets start by implementing methods to provide basic functionality for updating and reading a message stored persistently in the contract state. Enter this command in your Terminal . Terminal cd src Defining Methods and Messages ​ Rename the file name from Protobuf/contract/hello_world_contract.proto to lottery_game_contract.proto : Terminal mv Protobuf/contract/hello_world_contract.proto Protobuf/contract/lottery_game_contract.proto open the project with your IDE. The implementation of file src/Protobuf/contract/lottery_game_contract.proto is as follows: lottery_game_contract.proto syntax = "proto3" ; import "aelf/core.proto" ; import "aelf/options.proto" ; import "google/protobuf/empty.proto" ; import "google/protobuf/wrappers.proto" ; import "Protobuf/reference/acs12.proto" ; // The namespace of this class option csharp_namespace = "AElf.Contracts.LotteryGame" ; service LotteryGame { // The name of the state class the smart contract is going to use to access blockchain state option ( aelf . csharp_state ) = "AElf.Contracts.LotteryGame.LotteryGameState" ; option ( aelf . base ) = "Protobuf/reference/acs12.proto" ; rpc Initialize ( google . protobuf . Empty ) returns ( google . protobuf . Empty ) { } rpc Play ( google . protobuf . Int64Value ) returns ( google . protobuf . Empty ) { } rpc Withdraw ( google . protobuf . Int64Value ) returns ( google . protobuf . Empty ) { } rpc Deposit ( google . protobuf . Int64Value ) returns ( google . protobuf . Empty ) { } rpc TransferOwnership ( aelf . Address ) returns ( google . protobuf . Empty ) { } rpc GetPlayAmountLimit ( google . protobuf . Empty ) returns ( PlayAmountLimitMessage ) { option ( aelf . is_view ) = true ; } rpc GetContractBalance ( google . protobuf . Empty ) returns ( google . protobuf . Int64Value ) { option ( aelf . is_view ) = true ; } rpc GetOwner ( google . protobuf . Empty ) returns ( google . protobuf . StringValue ) { option ( aelf . is_view ) = true ; } } // An event that will be emitted from contract method call when Play is called. message PlayOutcomeEvent { option ( aelf . is_event ) = true ; int64 amount = 1 ; int64 won = 2 ; } // An event that will be emitted from contract method call when Withdraw is called. message WithdrawEvent { option ( aelf . is_event ) = true ; int64 amount = 1 ; aelf . Address from = 2 ; aelf . Address to = 3 ; } // An event that will be emitted from contract method call when Deposit is called. message DepositEvent { option ( aelf . is_event ) = true ; int64 amount = 1 ; aelf . Address from = 2 ; aelf . Address to = 3 ; } // The message containing the play amount limits message PlayAmountLimitMessage { int64 minimumAmount = 1 ; int64 maximumAmount = 2 ; } Define Contract States ​ The implementation of file src/LotteryGameState.cs is as follows: src/LotteryGameState.cs using AElf . Sdk . CSharp . State ; using AElf . Types ; namespace AElf . Contracts . LotteryGame { // The state class is access the blockchain state public partial class LotteryGameState : ContractState { // A state to check if contract is initialized public BoolState Initialized { get ; set ; } // A state to store the owner address public SingletonState < Address > Owner { get ; set ; } } } Contract Reference State ​ Create a new file token_contract.proto under src/Protobuf/reference/ . Replace this code of implementation file of token_contract.proto : token_contract.proto /** * MultiToken contract. */ syntax = "proto3" ; package token ; import "aelf/core.proto" ; import "aelf/options.proto" ; import "google/protobuf/empty.proto" ; import "google/protobuf/wrappers.proto" ; option csharp_namespace = "AElf.Contracts.MultiToken" ; service TokenContract { // Create a new token. rpc Create ( CreateInput ) returns ( google . protobuf . Empty ) { } // Issuing some amount of tokens to an address is the action of increasing that addresses balance // for the given token. The total amount of issued tokens must not exceed the total supply of the token // and only the issuer (creator) of the token can issue tokens. // Issuing tokens effectively increases the circulating supply. rpc Issue ( IssueInput ) returns ( google . protobuf . Empty ) { } // Transferring tokens simply is the action of transferring a given amount of tokens from one address to another. // The origin or source address is the signer of the transaction. // The balance of the sender must be higher than the amount that is transferred. rpc Transfer ( TransferInput ) returns ( google . protobuf . Empty ) { } // The TransferFrom action will transfer a specified amount of tokens from one address to another. // For this operation to succeed the from address needs to have approved (see allowances) enough tokens // to Sender of this transaction. If successful the amount will be removed from the allowance. rpc TransferFrom ( TransferFromInput ) returns ( google . protobuf . Empty ) { } // The approve action increases the allowance from the Sender to the Spender address, // enabling the Spender to call TransferFrom. rpc Approve ( ApproveInput ) returns ( google . protobuf . Empty ) { } rpc BatchApprove ( BatchApproveInput ) returns ( google . protobuf . Empty ) { } // This is the reverse operation for Approve, it will decrease the allowance. rpc UnApprove ( UnApproveInput ) returns ( google . protobuf . Empty ) { } // This method can be used to lock tokens. rpc Lock ( LockInput ) returns ( google . protobuf . Empty ) { } // This is the reverse operation of locking, it un-locks some previously locked tokens. rpc Unlock ( UnlockInput ) returns ( google . protobuf . Empty ) { } // This action will burn the specified amount of tokens, removing them from the token’s Supply. rpc Burn ( BurnInput ) returns ( google . protobuf . Empty ) { } // Set the primary token of side chain. rpc SetPrimaryTokenSymbol ( SetPrimaryTokenSymbolInput ) returns ( google . protobuf . Empty ) { } // This interface is used for cross-chain transfer. rpc CrossChainTransfer ( CrossChainTransferInput ) returns ( google . protobuf . Empty ) { } // This method is used to receive cross-chain transfers. rpc CrossChainReceiveToken ( CrossChainReceiveTokenInput ) returns ( google . protobuf . Empty ) { } // The side chain creates tokens. rpc CrossChainCreateToken ( CrossChainCreateTokenInput ) returns ( google . protobuf . Empty ) { } // When the side chain is started, the side chain is initialized with the parent chain information. rpc InitializeFromParentChain ( InitializeFromParentChainInput ) returns ( google . protobuf . Empty ) { } // Handle the transaction fees charged by ChargeTransactionFees. rpc ClaimTransactionFees ( TotalTransactionFeesMap ) returns ( google . protobuf . Empty ) { } // Used to collect transaction fees. rpc ChargeTransactionFees ( ChargeTransactionFeesInput ) returns ( ChargeTransactionFeesOutput ) { } rpc ChargeUserContractTransactionFees ( ChargeTransactionFeesInput ) returns ( ChargeTransactionFeesOutput ) { } // Check the token threshold. rpc CheckThreshold ( CheckThresholdInput ) returns ( google . protobuf . Empty ) { } // Initialize coefficients of every type of tokens supporting charging fee. rpc InitialCoefficients ( google . protobuf . Empty ) returns ( google . protobuf . Empty ) { } // Processing resource token received. rpc DonateResourceToken ( TotalResourceTokensMaps ) returns ( google . protobuf . Empty ) { } // A transaction resource fee is charged to implement the ACS8 standards. rpc ChargeResourceToken ( ChargeResourceTokenInput ) returns ( google . protobuf . Empty ) { } // Verify that the resource token are sufficient. rpc CheckResourceToken ( google . protobuf . Empty ) returns ( google . protobuf . Empty ) { } // Set the list of tokens to pay transaction fees. rpc SetSymbolsToPayTxSizeFee ( SymbolListToPayTxSizeFee ) returns ( google . protobuf . Empty ) { } // Update the coefficient of the transaction fee calculation formula. rpc UpdateCoefficientsForSender ( UpdateCoefficientsInput ) returns ( google . protobuf . Empty ) { } // Update the coefficient of the transaction fee calculation formula. rpc UpdateCoefficientsForContract ( UpdateCoefficientsInput ) returns ( google . protobuf . Empty ) { } // This method is used to initialize the governance organization for some functions, // including: the coefficient of the user transaction fee calculation formula, // the coefficient of the contract developer resource fee calculation formula, and the side chain rental fee. rpc InitializeAuthorizedController ( google . protobuf . Empty ) returns ( google . protobuf . Empty ) { } rpc AddAddressToCreateTokenWhiteList ( aelf . Address ) returns ( google . protobuf . Empty ) { } rpc RemoveAddressFromCreateTokenWhiteList ( aelf . Address ) returns ( google . protobuf . Empty ) { } rpc SetTransactionFeeDelegations ( SetTransactionFeeDelegationsInput ) returns ( SetTransactionFeeDelegationsOutput ) { } rpc RemoveTransactionFeeDelegator ( RemoveTransactionFeeDelegatorInput ) returns ( google . protobuf . Empty ) { } rpc RemoveTransactionFeeDelegatee ( RemoveTransactionFeeDelegateeInput ) returns ( google . protobuf . Empty ) { } rpc SetSymbolAlias ( SetSymbolAliasInput ) returns ( google . protobuf . Empty ) { } // Get all delegatees' address of delegator from input rpc GetTransactionFeeDelegatees ( GetTransactionFeeDelegateesInput ) returns ( GetTransactionFeeDelegateesOutput ) { option ( aelf . is_view ) = true ; } // Query token information. rpc GetTokenInfo ( GetTokenInfoInput ) returns ( TokenInfo ) { option ( aelf . is_view ) = true ; } // Query native token information. rpc GetNativeTokenInfo ( google . protobuf . Empty ) returns ( TokenInfo ) { option ( aelf . is_view ) = true ; } // Query resource token information. rpc GetResourceTokenInfo ( google . protobuf . Empty ) returns ( TokenInfoList ) { option ( aelf . is_view ) = true ; } // Query the balance at the specified address. rpc GetBalance ( GetBalanceInput ) returns ( GetBalanceOutput ) { option ( aelf . is_view ) = true ; } // Query the account's allowance for other addresses rpc GetAllowance ( GetAllowanceInput ) returns ( GetAllowanceOutput ) { option ( aelf . is_view ) = true ; } // Query the account's available allowance for other addresses rpc GetAvailableAllowance ( GetAllowanceInput ) returns ( GetAllowanceOutput ) { option ( aelf . is_view ) = true ; } // Check whether the token is in the whitelist of an address, // which can be called TransferFrom to transfer the token under the condition of not being credited. rpc IsInWhiteList ( IsInWhiteListInput ) returns ( google . protobuf . BoolValue ) { option ( aelf . is_view ) = true ; } // Query the information for a lock. rpc GetLockedAmount ( GetLockedAmountInput ) returns ( GetLockedAmountOutput ) { option ( aelf . is_view ) = true ; } // Query the address of receiving token in cross-chain transfer. rpc GetCrossChainTransferTokenContractAddress ( GetCrossChainTransferTokenContractAddressInput ) returns ( aelf . Address ) { option ( aelf . is_view ) = true ; } // Query the name of the primary Token. rpc GetPrimaryTokenSymbol ( google . protobuf . Empty ) returns ( google . protobuf . StringValue ) { option ( aelf . is_view ) = true ; } // Query the coefficient of the transaction fee calculation formula. rpc GetCalculateFeeCoefficientsForContract ( google . protobuf . Int32Value ) returns ( CalculateFeeCoefficients ) { option ( aelf . is_view ) = true ; } // Query the coefficient of the transaction fee calculation formula. rpc GetCalculateFeeCoefficientsForSender ( google . protobuf . Empty ) returns ( CalculateFeeCoefficients ) { option ( aelf . is_view ) = true ; } // Query tokens that can pay transaction fees. rpc GetSymbolsToPayTxSizeFee ( google . protobuf . Empty ) returns ( SymbolListToPayTxSizeFee ) { option ( aelf . is_view ) = true ; } // Query the hash of the last input of ClaimTransactionFees. rpc GetLatestTotalTransactionFeesMapHash ( google . protobuf . Empty ) returns ( aelf . Hash ) { option ( aelf . is_view ) = true ; } // Query the hash of the last input of DonateResourceToken. rpc GetLatestTotalResourceTokensMapsHash ( google . protobuf . Empty ) returns ( aelf . Hash ) { option ( aelf . is_view ) = true ; } rpc IsTokenAvailableForMethodFee ( google . protobuf . StringValue ) returns ( google . protobuf . BoolValue ) { option ( aelf . is_view ) = true ; } rpc GetReservedExternalInfoKeyList ( google . protobuf . Empty ) returns ( StringList ) { option ( aelf . is_view ) = true ; } rpc GetTransactionFeeDelegationsOfADelegatee ( GetTransactionFeeDelegationsOfADelegateeInput ) returns ( TransactionFeeDelegations ) { option ( aelf . is_view ) = true ; } rpc GetTokenAlias ( google . protobuf . StringValue ) returns ( google . protobuf . StringValue ) { option ( aelf . is_view ) = true ; } rpc GetSymbolByAlias ( google . protobuf . StringValue ) returns ( google . protobuf . StringValue ) { option ( aelf . is_view ) = true ; } } message TokenInfo { // The symbol of the token.f string symbol = 1 ; // The full name of the token. string token_name = 2 ; // The current supply of the token. int64 supply = 3 ; // The total supply of the token. int64 total_supply = 4 ; // The precision of the token. int32 decimals = 5 ; // The address that has permission to issue the token. aelf . Address issuer = 6 ; // A flag indicating if this token is burnable. bool is_burnable = 7 ; // The chain id of the token. int32 issue_chain_id = 8 ; // The amount of issued tokens. int64 issued = 9 ; // The external information of the token. ExternalInfo external_info = 10 ; // The address that owns the token. aelf . Address owner = 11 ; } message ExternalInfo { map < string , string > value = 1 ; } message CreateInput { // 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 . Add
프로젝트로 돌아가기