It is one of the networks built from the Substrate Framework, and also a formidable contender to be a Parachain for Polkadot in the future. Polkadot Relaychain basically does not support Smart Contracts, and that is also an opportunity for Plasm to fill that void.
And one more point that programmers really like is that PLASM completely opensource: https://github.com/PlasmNetwork
Introduce
Instead of writing smart contracts with the Web, Plasm brings familiarity to Ethereum developers, they can freely write Solidity and deploy contracts to Plasm because Plasm supports EVM, now they can support smart contracts to run. on the Dusty testnet network (the future will be Shiden if a successful auction on Kusama).
Practice
In this section, I will guide the steps to be able to build a complete Dapp on the Dusty network
Config metamask
The first is to interact with Dapps as well as interact with Remix to sign transactions.
We will reconfigure the network with the following parameters:
- Network Name: Dusty
- New RPC URL: https://rpc.dusty.plasmnet.io:8545
- Chain ID: 80
- Current Symbol: PLD
Temporarily, Dusty does not support BlockExplorer, so debugging when transaction errors is quite difficult, but wait for more complete versions on Shiden – hope then the tools for developers have been invested more.
Faucet
To be able to Deploy or create transactions, we must first have a native token on Plasm, as on the config, the native token here has the symbol PLD.
To can faucet a little PLD convenient for testing, you can faucet directly here:
https://plasm-faUC-frontend.vercel.app/
However we are using metamask so the account address will be of the form of ETH address, therefore we need some steps to get the correct address to be able to receive faucet.
The first is to convert from ETH address to prefix 5 through: https://hoonsubin.github.io/evm-substrate-address-converter/index.html
After getting the address converted to prefix 5, it will switch here to get the correct address on the Plasm corresponding to the address on Metamask: https://polkadot.subscan.io/tools/ss58_transform
5 other address prefix is what we need to find, copy and retrieve from this faucet come: https://plasm-faucet-frontend.vercel.app/
And then we have PLD for testing
Note: Since PLD’s decimal is 15 different from Metamask’s default that for native tokens with a decimal is 18 so with 1 PLD displayed in the metamask we will implicitly correspond to 1000 PLD in the Dusty network.
With enough money to pay the transaction fee, next we will build some Dapps
Dapp
Smart Contract
We will use Remix to code as well as deploy the contract to Dusty: https://remix.ethereum.org/
In the article, I will demo a small Dapp demoed in ETH workshop India: Airbnb smart contract
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | pragma solidity <span class="token operator">^</span> <span class="token number">0.5</span> <span class="token number">.7</span> <span class="token punctuation">;</span> contract Airbnb <span class="token punctuation">{</span> <span class="token comment">// Property to be rented out on Airbnb</span> struct Property <span class="token punctuation">{</span> string name <span class="token punctuation">;</span> string description <span class="token punctuation">;</span> bool isActive <span class="token punctuation">;</span> <span class="token comment">// is property active</span> uint256 price <span class="token punctuation">;</span> <span class="token comment">// per day price in wei (1 ether = 10^18 wei)</span> address owner <span class="token punctuation">;</span> <span class="token comment">// Owner of the property</span> <span class="token comment">// Is the property booked on a particular day,</span> <span class="token comment">// For the sake of simplicity, we assign 0 to Jan 1, 1 to Jan 2 and so on</span> <span class="token comment">// so isBooked[31] will denote whether the property is booked for Feb 1</span> bool <span class="token punctuation">[</span> <span class="token punctuation">]</span> isBooked <span class="token punctuation">;</span> <span class="token punctuation">}</span> uint256 <span class="token keyword">public</span> propertyId <span class="token punctuation">;</span> <span class="token comment">// mapping of propertyId to Property object</span> <span class="token function">mapping</span> <span class="token punctuation">(</span> <span class="token parameter">uint256</span> <span class="token operator">=></span> Property <span class="token punctuation">)</span> <span class="token keyword">public</span> properties <span class="token punctuation">;</span> <span class="token comment">// Details of a particular booking</span> struct Booking <span class="token punctuation">{</span> uint256 propertyId <span class="token punctuation">;</span> uint256 checkInDate <span class="token punctuation">;</span> uint256 checkoutDate <span class="token punctuation">;</span> address user <span class="token punctuation">;</span> <span class="token punctuation">}</span> uint256 <span class="token keyword">public</span> bookingId <span class="token punctuation">;</span> <span class="token comment">// mapping of bookingId to Booking object</span> <span class="token function">mapping</span> <span class="token punctuation">(</span> <span class="token parameter">uint256</span> <span class="token operator">=></span> Booking <span class="token punctuation">)</span> <span class="token keyword">public</span> bookings <span class="token punctuation">;</span> <span class="token comment">// This event is emitted when a new property is put up for sale</span> event <span class="token function">NewProperty</span> <span class="token punctuation">(</span> uint256 indexed propertyId <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// This event is emitted when a NewBooking is made</span> event <span class="token function">NewBooking</span> <span class="token punctuation">(</span> uint256 indexed propertyId <span class="token punctuation">,</span> uint256 indexed bookingId <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">/** * @dev Put up an Airbnb property in the market * @param name Name of the property * @param description Short description of your property * @param price Price per day in wei (1 ether = 10^18 wei) */</span> <span class="token keyword">function</span> <span class="token function">rentOutproperty</span> <span class="token punctuation">(</span> <span class="token parameter">string memory name <span class="token punctuation">,</span> string memory description <span class="token punctuation">,</span> uint256 price</span> <span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token punctuation">{</span> Property memory property <span class="token operator">=</span> <span class="token function">Property</span> <span class="token punctuation">(</span> name <span class="token punctuation">,</span> description <span class="token punctuation">,</span> <span class="token boolean">true</span> <span class="token comment">/* isActive */</span> <span class="token punctuation">,</span> price <span class="token punctuation">,</span> msg <span class="token punctuation">.</span> sender <span class="token comment">/* owner */</span> <span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">bool</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token punctuation">(</span> <span class="token number">365</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Persist `property` object to the "permanent" storage</span> properties <span class="token punctuation">[</span> propertyId <span class="token punctuation">]</span> <span class="token operator">=</span> property <span class="token punctuation">;</span> <span class="token comment">// emit an event to notify the clients</span> emit <span class="token function">NewProperty</span> <span class="token punctuation">(</span> propertyId <span class="token operator">++</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @dev Make an Airbnb booking * @param _propertyId id of the property to rent out * @param checkInDate Check-in date * @param checkoutDate Check-out date */</span> <span class="token keyword">function</span> <span class="token function">rentProperty</span> <span class="token punctuation">(</span> <span class="token parameter">uint256 _propertyId <span class="token punctuation">,</span> uint256 checkInDate <span class="token punctuation">,</span> uint256 checkoutDate</span> <span class="token punctuation">)</span> <span class="token keyword">public</span> payable <span class="token punctuation">{</span> <span class="token comment">// Retrieve `property` object from the storage</span> Property storage property <span class="token operator">=</span> properties <span class="token punctuation">[</span> _propertyId <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token comment">// Assert that property is active</span> <span class="token function">require</span> <span class="token punctuation">(</span> property <span class="token punctuation">.</span> isActive <span class="token operator">==</span> <span class="token boolean">true</span> <span class="token punctuation">,</span> <span class="token string">"property with this ID is not active"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Assert that property is available for the dates</span> <span class="token keyword">for</span> <span class="token punctuation">(</span> uint256 i <span class="token operator">=</span> checkInDate <span class="token punctuation">;</span> i <span class="token operator"><</span> checkoutDate <span class="token punctuation">;</span> i <span class="token operator">++</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> property <span class="token punctuation">.</span> isBooked <span class="token punctuation">[</span> i <span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token boolean">true</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// if property is booked on a day, revert the transaction</span> <span class="token function">revert</span> <span class="token punctuation">(</span> <span class="token string">"property is not available for the selected dates"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Check the customer has sent an amount equal to (pricePerDay * numberOfDays)</span> <span class="token function">require</span> <span class="token punctuation">(</span> msg <span class="token punctuation">.</span> value <span class="token operator">==</span> property <span class="token punctuation">.</span> price <span class="token operator">*</span> <span class="token punctuation">(</span> checkoutDate <span class="token operator">-</span> checkInDate <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token string">"Sent insufficient funds"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// send funds to the owner of the property</span> <span class="token function">_sendFunds</span> <span class="token punctuation">(</span> property <span class="token punctuation">.</span> owner <span class="token punctuation">,</span> msg <span class="token punctuation">.</span> value <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// conditions for a booking are satisfied, so make the booking</span> <span class="token function">_createBooking</span> <span class="token punctuation">(</span> _propertyId <span class="token punctuation">,</span> checkInDate <span class="token punctuation">,</span> checkoutDate <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">_createBooking</span> <span class="token punctuation">(</span> <span class="token parameter">uint256 _propertyId <span class="token punctuation">,</span> uint256 checkInDate <span class="token punctuation">,</span> uint256 checkoutDate</span> <span class="token punctuation">)</span> internal <span class="token punctuation">{</span> <span class="token comment">// Create a new booking object</span> bookings <span class="token punctuation">[</span> bookingId <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">Booking</span> <span class="token punctuation">(</span> _propertyId <span class="token punctuation">,</span> checkInDate <span class="token punctuation">,</span> checkoutDate <span class="token punctuation">,</span> msg <span class="token punctuation">.</span> sender <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Retrieve `property` object from the storage</span> Property storage property <span class="token operator">=</span> properties <span class="token punctuation">[</span> _propertyId <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token comment">// Mark the property booked on the requested dates</span> <span class="token keyword">for</span> <span class="token punctuation">(</span> uint256 i <span class="token operator">=</span> checkInDate <span class="token punctuation">;</span> i <span class="token operator"><</span> checkoutDate <span class="token punctuation">;</span> i <span class="token operator">++</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> property <span class="token punctuation">.</span> isBooked <span class="token punctuation">[</span> i <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Emit an event to notify clients</span> emit <span class="token function">NewBooking</span> <span class="token punctuation">(</span> _propertyId <span class="token punctuation">,</span> bookingId <span class="token operator">++</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">_sendFunds</span> <span class="token punctuation">(</span> <span class="token parameter">address beneficiary <span class="token punctuation">,</span> uint256 value</span> <span class="token punctuation">)</span> internal <span class="token punctuation">{</span> <span class="token comment">// address(uint160()) is a weird solidity quirk</span> <span class="token comment">// Read more here: https://solidity.readthedocs.io/en/v0.5.10/050-breaking-changes.html?highlight=address%20payable#explicitness-requirements</span> <span class="token function">address</span> <span class="token punctuation">(</span> <span class="token function">uint160</span> <span class="token punctuation">(</span> beneficiary <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">transfer</span> <span class="token punctuation">(</span> value <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @dev Take down the property from the market * @param _propertyId Property ID */</span> <span class="token keyword">function</span> <span class="token function">markPropertyAsInactive</span> <span class="token punctuation">(</span> <span class="token parameter">uint256 _propertyId</span> <span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token punctuation">{</span> <span class="token function">require</span> <span class="token punctuation">(</span> properties <span class="token punctuation">[</span> _propertyId <span class="token punctuation">]</span> <span class="token punctuation">.</span> owner <span class="token operator">==</span> msg <span class="token punctuation">.</span> sender <span class="token punctuation">,</span> <span class="token string">"THIS IS NOT YOUR PROPERTY"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> properties <span class="token punctuation">[</span> _propertyId <span class="token punctuation">]</span> <span class="token punctuation">.</span> isActive <span class="token operator">=</span> <span class="token boolean">false</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
The rest of us is compile and connect the Dusty network via metamask and deploy, the contract after successful deploying will appear:
UI
After deploying is complete, we will have a contract running on Dusty, the next thing is to build the UI to interact with that contract, I have also prepared a folder for you to test directly on it. You can clone and apply the contract address to be able to test and dabble:
In this repo we should learn a bit about Nuxt and Web3js a bit
https://github.com/tranchien2002/dustyPLM-demo
The first is to change the address of the contract in the file:
Temporarily after replacing it with the new contract deploy address above, we can run it test to test
1 2 3 4 | yarn install cd dapp <span class="token operator">-</span> ui yarn dev |
Run a test and create a transaction, and here are the results after the transaction is successful
Conclude
And finally we were able to run a complete Dapp on Dusty – Plasm’s testnet. For Ethereum devs, it will be quite similar to building on ETH or other EVM-enabled blockchains in general. Hope my article can be of help to you who are starting to learn about Polkadot’s parachains.