During the development process of blockchain, in addition to developing one's own blockchain and developing based on a public chain or framework, there are also some third-party platforms that provide tools to quickly generate digital encrypted assets and conduct transactions, such as Opensea (website http://opensea.io) and RareBits (website https://rarebits.io/) abroad, and BIGE (website http://bige.game/) domestically.
Three development examples, including one Ethereum query analysis system development example, one ERC20 token development example, and one digital encrypted asset development example based on the OpenSea platform.
● Understand the Ethereum test network Ropsten.
● Master the functions of the web3.py library.
● Master the basic query and analysis methods of Ethereum data.
● Understand the development of ERC20 tokens.
● Learn the development process of encrypted assets.
● Understand the OpenSea trading platform.
In the practical development of Ethereum DApp, a local testing environment for Ethereum was built, but the data in the local testing environment is relatively sparse and cannot reflect the real data situation of the Ethereum network. Therefore, the public test network Ropsten was chosen as the testing environment.
Ropsten is an Ethereum test network launched in November 2016, named after a subway station in Stockholm (the capital of Sweden). Ropsten uses a proof-of-work consensus mechanism, which is the best simulation of the existing production environment of Ethereum, closely resembling the system and network status of the Ethereum mainnet. Moreover, Ether on the Ropsten test network is free, and connecting to the Ropsten test network for various tests and development incurs very low costs, making Ropsten a cost-effective choice. Below, the MetaMask plugin introduced in Chapter 5 is used to connect to the Ropsten test network.
(1) Connect to the Ropsten test network
Click the MetaMask plugin to open the options interface, then click the network option to change the connection network to the Ropsten test network, as shown in Figure 8-1.
(2) Create a test account
After successfully switching the network, click the user avatar and select to create a user to generate a new account in the Ropsten test network.
In the pop-up interface, enter the username and click the "CREATE" button to create, as shown in Figure 8-3.
(3) Check account balance
After creation, enter the account details page, where the new account balance is 0 Ether, as shown in Figure 8-4.
(4) Obtain Ether
To conduct integration tests, it is best to obtain a certain amount of Ether on the Ropsten test network (updating operations on the Ethereum network require Ether). The main methods to obtain Ether on the Ropsten test network are as follows:
● Apply at http://faucet.ropsten.be:3001/, where you need to enter your account address on the Ropsten network, and the transfer operation is very quick; currently, you can apply for 3 ETH at a time.
● Ask a friend to transfer Ether to you.
● Mine it yourself.
Undoubtedly, the first method is the most convenient and quick; below is the application operation.
- Apply for Ether
To apply for Ether, you need to enter your account address.
(1) Copy the account address
Click the menu in the upper left corner of the account to view the account details; there is a copy button to the right of the address; click to copy the address information.
(2) Apply on Ropsten
After obtaining the account address, visit http://faucet.ropsten.be:3001/ in the browser, and enter the copied account address on the opened page, as shown in the image.
(3) Application successful
Click the "Send me test Ether" button to apply for test Ether. After a successful application, a success message and the hash value of the transfer transaction will appear at the bottom of the page, as shown in the image.
Note that the Ether obtained needs to be confirmed by other nodes in the Ropsten network, so after a successful application, it generally takes about half a day to see the Ether information in MetaMask.
Having created a test account on the Ropsten test network using the MetaMask plugin, to integrate the interface of this test network for data querying and obtaining, the web3.py library will be used to connect with the Ropsten test network.
- Introduction to web3.py
web3.py is a Python wrapper for the Ethereum interface, allowing interaction with the Ethereum network through JSON-RPC. Similar to web3.js, where web3.js is mainly suitable for DApp development on the browser side, web3.py is developed based on Python and is more suitable for server use.
- Installation and use of web3.py
web3.py can be installed using Python's package management tool pip. First, create a virtual environment.
(1) Create a virtual environment
Here, a Python virtual environment named ch8 is created (web3.py supports Python 3.5 and above), with the command as follows:
virtualenv venv-p python3
(2) Install web3.py
After creation, activate this virtual environment, and then use the pip install web3 command to install web3.py. This command will automatically download and install the dependency libraries and print the installation information, as shown in the image.
web3.py provides several main functional interfaces, including data filtering interfaces, service providers, Ethereum naming services, network information, account information, block information, etc. For details, you can visit the official website of web3.py at https://web3py.readthedocs.io/en/stable/index.html for inquiries.
(3) Apply for a test node
After installing web3.py, you need to apply for a test node to connect to the Ropsten test network. Here, Infura is used. Infura is a service provider for Ethereum nodes, providing public Ethereum mainnet and test network nodes, and developers can apply on the Infura official website. Open https://infura.io/ in the browser to see the Infura page, as shown in the image.
Click the "GET STARTED FOR FREE" button on the page to start the free application. The free application requires filling in basic information such as name, email, and password. After filling in the information, click the "SIGN UP" button to register. After registration, a confirmation email will be sent to the provided email address. If not received, you can click the "RE-SEND VERIFICATION EMAIL" button to resend the confirmation email.
Clicking the confirmation link in the email will automatically log you into the registered account. After successfully logging in, the user will be prompted to add a new project, with the project name being arbitrary; here, the project name is "Self-Learning Blockchain." Click the "CREATE PROJECT" button to create the project, as shown in the image.
After creation, you will enter the project details page. The details page displays the API KEY, API SECRET, and the endpoint address for connecting to the Ethereum network, as well as the whitelist of smart contracts on this node. Here, select the node of the Ropsten test network, as shown in the image.
- Use web3.py to connect to the network
After obtaining the connection node for the Ropsten test network, you can use web3.py to connect. First, import Web3 and HTTPProvider from web3.py, then connect to the Ropsten test node in the project. After connecting, use the isConnected method to check the connection status; returning True indicates a successful connection, as shown in the image.
Once connected successfully, you can use methods such as getTransaction provided by web3.py to query data from the Ropsten network.
(3) Create an application
After initializing the project, you can start implementing functional code. First, create a Flask application and initialize Web3 for connection in app.py.
After completion, execute the python app.py command to start this application. The started application listens on port 5000 by default, processing requests and returning results.
(4) Implement the basic template
After creating the application, start writing the page. Flask uses Jinja2 template language by default to implement template functionality (Jinja2 has a powerful feature called template inheritance. Template inheritance allows developers to create a basic skeleton template that contains common elements of the website. In child templates, these common elements can be inherited by inheriting this basic template, and different page elements can be implemented through overriding, just as simple as inheritance and overriding in Python classes). Therefore, you can first write a basic template, placing the common parts of the page into this basic template. Other pages inheriting this template will have these common parts, and then add the required custom content and use Bootstrap to beautify the page style to quickly implement a page. The benefit of doing this is to avoid writing repetitive content and improve development efficiency. The specific operation is to create a layout.html file in the templates folder of the current directory, introducing the relevant CSS and JS of Bootstrap in this file.
The content similar to “{% block ×××%}{% endblock %}” is the area for overriding in the child template, where the child template can add custom content through overriding. Next, start implementing the first function, which is to query and display the latest block in the Ropsten test network.
To query the latest block information in the Ropsten test network, you can use the getBlock function of web3.py, which returns a Json string. The front-end HTML page is responsible for displaying this Json string. In app.py, implement a function named get_last_block, which calls getBlock("latest") in the function, then extracts the main content from the returned block information and passes it to the template for display.
The above code extracts the main block information from the obtained block information and encapsulates this information into a dictionary to pass to the block.html template. The block.html template first inherits the layout.html template, then uses the jQuery.json-browse jQuery plugin for display. The purpose of jQuery.json-browse is to beautify the display of Json data and allows for expanding and collapsing Json data.
After completing the code for querying the latest block, start the application to view the effect. Open the browser and visit http://127.0.0.1:5000 to see the latest block information, as shown in the image, displaying the latest block information, including miner address (miner), hash value (hash), etc.
- Querying transaction data of blocks
A block often stores many transaction records. In the block information shown in Figure 8-16, there is a transactions field that contains a series of hash values, each corresponding to a transaction record. In this section, the function implemented is to use the getTransaction function in web3.py to query the transaction information corresponding to the hash value and display the transaction information in HTML. In app.py, implement a handle_transaction function that accepts both GET and POST request methods. The GET request returns an HTML page containing an input box and button, while the POST will pass a transaction information hash value. The function calls the getTransaction function of web3.py to query the corresponding transaction and return the result.
After updating app.py, create a new transaction.html template file, which still inherits from layout.html. The template displays an input box and button. After entering the transaction hash value in the input box, clicking the "Search Transaction" button will send the request data of the transaction hash value to the application. After obtaining the transaction data from the application, the jQuery.json-browse command is used to display the Json data.
After completing the application, restart it and check the page effect. You can see a page for searching transactions. In the browser, enter http://127.0.0.1:5000/transaction to open this page, then enter a transaction ID in the input box and click the "Search Transaction" button to see the transaction details.
Having completed the querying function for block and transaction data, the next step is to implement the function for querying account balances. The logic for querying account balances is similar to that of querying transaction data. In app.py, implement a get_balance function that accepts both GET and POST request methods. The GET request returns an HTML page containing an input box and button, while the POST request receives account address information and retrieves the account balance through the getBalance function of web3.py. The code can be slightly modified based on the "2. Querying transaction data of blocks" section. After completion, open http://127.0.0.1:5000/balance in the browser, and enter the account address to query the corresponding account balance.
Block Information Analysis#
A simple analysis of the block information in the Ropsten test network. First, write a Python script to download the first 10,000 blocks in the Ropsten test network and save this data using the pickle module. Pickle is a module in Python used to save Python objects as files, making it convenient to store and read Python objects.
(1) Download block data
Create a new eth_helper.py file, and in this file, create a download_blocks function to loop through and download block data. After downloading, use pickle to save this block data to a file named block.pkl.
Run the python eth_helper.py command to execute the script. The script will take some time to download block data, and once completed, a block.pkl file containing 10,000 block data will be automatically generated locally.
(2) Load block data
In app.py, create a function named visualization to load the already downloaded block data and extract the block difficulty into a list to pass to the HTML page (visualization.html) for display.
(3) Visualize the data
The final step is to visualize the data. Here, ECharts is used for visualization. ECharts is a data visualization chart library developed by Baidu's front-end technology department based on JavaScript, providing intuitive, vivid, interactive, and customizable data visualization charts. The method for visualizing data using ECharts is also very simple; just include the ECharts js library file in the HTML page, create a div element of a certain size, and then write a piece of js code to load the data for data visualization display.
Create a new visualization.html file, and here choose to visualize the block difficulty data in the form of a line chart.
After completing the code, restart the Flask application and visit http://127.0.0.1:5000/visualization to see the visualization effect.
From the chart, it can be seen that the value of block difficulty in the Ropsten test network is rising sharply, indicating that as the blockchain continues to extend, the difficulty of generating blocks is increasing.
This is a simple Ethereum query analysis system. Interested readers can further analyze other data of Ethereum, such as block generation speed, the number of blocks generated daily, and the number of blocks pending confirmation. To analyze Ethereum in an actual environment, simply replace the Ropsten test node address (http://ropsten.infura.io/v3/×××) with the official node address.
ERC20 can be simply understood as a token protocol on Ethereum, and all token contracts developed based on Ethereum comply with this protocol. Tokens that comply with this protocol are called ERC20 tokens. This case will develop an ERC20 token named Mini Token.
The types of digital currencies are diverse and complex, with many established currencies such as Bitcoin, Ripple, and NEO, each having its own chain and running its own encrypted digital currency on its chain. In addition to these, there are also platform tokens that are created based on Ethereum, which do not have their own chain but run on Ethereum. Currently, 80-90% of the digital currencies on the market belong to platform tokens. These tokens all comply with the ERC20 token protocol and are standardized tokens that can be supported by various Ethereum wallets. Tokens supported by Ethereum wallets can be used for various project developments and can also be submitted to various exchanges for trading.
The reason it is called an ERC20 token is that ERC20 is a standard proposed by the Ethereum community in November 2015, with the code name 20. All tokens that meet this standard are ERC20 tokens. Before the ERC20 standard appeared, the standards for tokens were not unified, and issuing tokens was a very troublesome task. For developers, it required developing smart contracts separately and could not achieve compatibility with multiple wallets. After the ERC20 standard appeared, issuing tokens based on the ERC20 standard became very simple, and developing an ERC20 token takes no more than 10 minutes, with 50 lines of code being sufficient.
ERC20 is the standard interface for various tokens, and developers need to integrate these standard interfaces into their smart contracts to perform the following operations:
● Get the total supply of tokens.
● Get the account balance.
● Transfer tokens.
● Approve spending tokens.
ERC20 enables seamless interaction between other smart contracts and decentralized applications on the Ethereum blockchain. The interface file for the ERC20 standard is as follows.
The meanings are as follows:
● name is the name to be specified, for example, it can be called MyToken.
● symbol is the symbol of the token, similar to common ones like BTC, ETH, etc.
● decimal is the minimum trading unit of the token, representing the number of decimal places. If set to 1, then the minimum tradeable amount is 0.1 tokens.
● totalSupply refers to the total issuance.
● balanceOf returns the account balance of a certain address (account).
● transfer implements the transfer of a certain amount (_value) of tokens to the target address (_to), providing a return value to indicate whether the transfer was successful, and triggering the Transfer event.
● transferFrom transfers a certain amount (_value) of tokens from one address (_from) to the target address (_to), also providing a return value to indicate whether the transfer was successful, and similarly triggering the Transfer event.
● approve authorizes a third party (_spender) to transfer a certain amount (up to _value) of tokens from the sender's account. The third party is usually a smart contract that can execute the specific transfer operation through the transferFrom() function.
● allowance returns the amount that _spender is still allowed to withdraw from _owner.
● Transfer and Approval events are for logging purposes. The former is triggered when tokens are transferred, while the latter is triggered when the approve method is called.
ERC20 tokens are not a DApp; they are one of the important applications of smart contracts. ERC20 tokens are also developed using the Solidity language, and the development environment is generally chosen as Remix (Remix is an online IDE for developing Ethereum smart contracts, located at http://remix.ethereum.org).
Here, we will implement a token named "Mini Token," symbol "MT," with a total issuance of 1,000 tokens. The implementation method is to modify the relevant function contents in the ERC20 standard interface, such as changing name to "Mini Token," symbol to "MT," etc. The complete code is as follows.
After copying and pasting the above code into the Remix editor, compile and deploy it to the local test environment, thus successfully publishing Mini Token. From the contract details, you can see information such as the name, symbol, and total issuance of Mini Token.
Click the copy button on the right side of the contract to copy the address of Mini Token to the clipboard. Then open the account options in MetaMask and select "ADD TOKEN."
In the Add Tokens dialog, select "Custom Token," fill in the "Token Address" text box with the Mini Token address just copied, and then the symbol and precision fields below will be automatically filled in. Click the "Next" button to continue.
Finally, click the "ADD TOKENS" button to add Mini Token to the account.
After completion, you can see the newly created token in the account interface and can trade or transfer these tokens.
At the end of 2017, a popular mini-game called CryptoKitties was released on Ethereum. It is a breeding and nurturing game for CryptoKitties, using Ether as the only currency for the game. The offspring produced by two CryptoKitties will inherit new genes from their parents' genomes through genetic algorithms, determining their appearance, personality, and characteristics. Each cat is unique and 100% owned by the owner; CryptoKitties cannot be copied, taken away, or destroyed, but can be bought or sold. CryptoKitties can be collected and securely recorded on the blockchain. The author of CryptoKitties, Axion Zen, later defined a token standard called ERC721, allowing developers to publish digital assets based on this standard. In ERC20, all tokens that comply with ERC20 are identical, and there is no distinction between any two ERC20 tokens; whereas in ERC721, each digital asset has its unique identifier, and no two digital assets that comply with the ERC721 standard are exactly the same, which is a significant difference from ERC20.
The official brief explanation of ERC721 is "Non-Fungible Tokens," abbreviated as "NFT," which can be simply understood as each token being unique. To explain with CryptoKitties, each CryptoKitty is an independent token, and each CryptoKitty has its unique characteristics, making them irreplaceable. ERC721 defines a standard to realize this type of encrypted asset.
The example in this section is to implement a digital asset similar to CryptoKitties—CryptoPigs. To develop this type of digital asset, it is necessary to implement a smart contract that complies with the ERC721 standard and then create a user interface to display the developed digital asset.
With the increase of digital assets like CryptoKitties, someone began to create a platform specifically for trading such encrypted assets, among which OpenSea is the world's largest encrypted asset trading platform. Developers no longer need to develop from scratch; they can quickly develop an ERC721 digital asset on the OpenSea platform by following the process. This case will first introduce OpenSea and then explain how to develop and trade digital assets on OpenSea. Through this case, you will learn how to develop a digital asset that complies with the ERC721 standard and how to trade such assets.
OpenSea is a blockchain-based encrypted asset trading platform that provides users with services such as buying and selling encrypted assets. The OpenSea homepage is shown in the image.
OpenSea provides a development document that allows developers to complete their own store in just a few minutes. You can visit https://docs.opensea.io/docs for reference. The example provided by OpenSea is trading various marine life encrypted assets.
Here, we will refer to the development process of marine life encrypted assets to develop our own encrypted asset—CryptoPigs. CryptoPigs comply with the Ethereum ERC721 standard and include permission control features. The development steps include creating and implementing the smart contract for CryptoPigs, the display page and user interface for CryptoPigs, and the trading function for CryptoPigs.
This example is developed based on the Truffle framework, and during the development process, the NodeJS package manager npm is used to install the dependency libraries. Before development, ensure that the npm tool in the system is available, and then choose a commonly used text editor (such as VScode, Sublime) to develop this CryptoPig.
The development of the smart contract here is based on the OpenZeppelin library. OpenZeppelin is an open-source library implemented in Solidity that contains best practices for known smart contracts. OpenZeppelin provides various important functions needed for developing smart contracts, allowing us to create safer smart contracts in less time based on it. Now, let's officially start developing the smart contract.
(1) Initialize the smart contract
First, create a folder named LittlePig in any local directory. After creation, enter the folder and use the truffle init command to initialize a Truffle project.
After initialization, install the OpenZeppelin library with the following command:
npm install openzeppelin-solidity
After installation, start implementing the functions of the smart contract.
(2) Implement the LittlePig smart contract
The implementation of the LittlePig smart contract is relatively simple, requiring secondary development based on the openzeppelin-solidity library. In the contracts folder of the current directory, create a file named LittlePig.sol. In this file, write a class named LittlePig that inherits from the two base classes ERC721Token and Ownable. The ERC721Token is the base class of the ERC721 standard, and Ownable provides permission control functionality. After inheritance, it is also necessary to implement functions such as tokenURI, baseTokenURI, and isApprovedForAll in the main part of the class. Notably, there are two points: one is the tokenURI function, which returns a URI address. Here it is https://little-pig-api.herokuapp.com/api/pig/, and requesting this URI will return the attributes of each ERC721 asset, such as name, description, and image, which will be displayed on the OpenSea platform; the second is the isApprovedForAll function, which controls the whitelist for obtaining OpenSea data. The specific code is as follows.
After implementing the smart contract code, you can start publishing the smart contract.
(3) Publish the smart contract
Here, use the previously registered Infura account (as described in section 8.1.2 for connecting to the Ethereum interface to apply for a test node) to publish it to the Ropsten test network. The publishing method is also relatively simple, using HDWalletProvider to connect to the Ropsten test network and perform the publishing operation. During the connection process, it is necessary to configure the mnemonic phrase of the wallet (a set of English words used to derive wallet information) and the Infura interface address, configured in the truffle.js file as follows.
After configuration, use the truffle deploy --network ropsten command to deploy the smart contract to the Ropsten test network. After successful deployment, you can see the transaction hash (transaction hash) and contract address (contract address) information.
(4) Generate encrypted assets
After successfully publishing the smart contract, you can call the smart contract to generate your own encrypted assets. The method for generation is to use HDWalletProvider to connect to the Ropsten test network, then load the smart contract and call the mintTo function to generate encrypted digital assets. Here, create a mint.js file and write the following code in it.
After completing mint.js, you can generate encrypted assets by executing node mint.js in the terminal. The above code sets the generation of 12 CryptoPigs. You can see the 12 hash values generated in the terminal, which correspond to 12 CryptoPigs.
The generated CryptoPigs are your own encrypted assets, which can be traded and transferred. To make these CryptoPigs look more intuitive and attractive, you can add some attribute data to each CryptoPig, so that each CryptoPig will display different images on OpenSea.
In the previous smart contract, a tokenURI() method was implemented, which returns a unique URI for each Token. Requesting this URI will return the attribute data corresponding to this Token. For example, for the Token with Id 1, the returned URI is https://little-pig-api.herokuapp.com/api/creature/1. Requesting this URI will return the following Json data:
The description field is the description of the CryptoPig, the external_url field is the external link of the CryptoPig, the image is the image address of the CryptoPig, the name is the name of the CryptoPig, and the attributes are the custom attribute list of the CryptoPig.
After adding the attribute data, you can view the information of this encrypted asset on the OpenSea platform. The link for viewing is https://ropsten.opensea.io/assets/contract_address/tokenId, for example, the link address for viewing CryptoPig token Id 1 is https://ropsten.opensea.io/assets/0x×××/1.
There are two ways to trade CryptoPigs: one is fixed price sales (Fixed Price), and the other is auctions within a certain price range (Auction).
This concludes the trading function of CryptoPigs.#
The end.