What is Loom Network?
Loom Network is a class 2 extension solution for Ethereum. This is a sidechains DPoS network that allows games and DApps on a blockchain-capable platform while still supporting Ethereum security. It allows developers to run large-scale applications and is the first Ethereum extension solution to be applied into practice.
The Loom SDK
Loom’s core product is the SDK that allows users to quickly build their own blockchain without having to understand the details of the blockchain’s consensus infrastructure or algorithms. Think of it as a blockchain creator of your own.
DAppChains
Loom SDK creates a DAppChain – a two-layer blockchain that uses Ethereum as its base class. Running DApp on the sidechain for Ethereum has several benefits, but most importantly: DAppChains can use consensus rules (like DPoS) to optimize for scalability. Using Ethereum as a base class means that DAppChain-based assets (such as tokens ERC20 and ERC721) can be securely secured.
DApps scalability
Loom SDK allows users to select consensus algorithms and rules to customize scalability or security depending on DApps needs. Loom Network supports DPoS (Delegated Proof of Stake), allowing the development of large-scale online games and social networking applications. These are the first two DApp categories that Loom focuses on developing (although users can build any type of DApp on the Loom SDK). Being linked to Ethereum via Plasma above, it is possible to transfer assets from Ethereum to Dappchain, to understand, the tokens ERC20 and ERC721 are used on DAppChain while still being secured by Ethereum. In short, the Loom SDK allows developers to build the same types of applications they will build on EOS, but supported by Ethereum.
To learn more about Plasma, please refer to the article: https://viblo.asia/p/plasma-giai-phap-cho-su-mo-rong-mang-luoi-blockchain-tiep-theo-ByEZkybY5Q0
ring ring ring … the theory lesson here is the next step is to practice
Run and create simple applications on Loom Network
Download Loom
You can use the command below to download Loom in the current directory:
1 | curl https://raw.githubusercontent.com/loomnetwork/loom-sdk-documentation/master/scripts/get_loom.sh | sh |
Installation
Run the following commands in the same directory as the downloaded loom file
1 | ./loom init |
Run
1 | ./loom run |
Only three commands above have created your own blockchain network
Deploy contract on Loom
Let’s start with Solidity + Truffle
You can install Truffle according to the instructions here: https://www.trufflesuite.com/docs/truffle/overview
And learn about Solidity language to write a contract here: https://cryptozombies.io/
Deploying and run from Truffle
1 | # Currently supported version npm install -g <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="087c7a7d6e6e646d483d26382638">[email protected]</a> |
Now let’s create a project
1 | # Create directory and access mkdir simple-store cd simple-store # Initialize a project from zero with truffle truffle init |
Files are created
1 | . ├── contracts │ └── Migrations.sol ├── migrations │ └── 1_initial_migration.js ├── test ├── truffle-config.js └── truffle.js |
Write a contract
On the contracts folder, we create a new file called Simplestore.sol that has a function to set a parameter value also for a change of that value, the get function is read only and an event named NewValueSet will have parameter values, as the following example:
1 | pragma solidity <span class="token operator">^</span> <span class="token number">0.4</span> <span class="token number">.22</span> <span class="token punctuation">;</span> contract SimpleStore <span class="token punctuation">{</span> uint value <span class="token punctuation">;</span> event <span class="token function">NewValueSet</span> <span class="token punctuation">(</span> uint _value <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token keyword">set</span> <span class="token punctuation">(</span> uint _value <span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token punctuation">{</span> value <span class="token operator">=</span> _value <span class="token punctuation">;</span> emit <span class="token function">NewValueSet</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 keyword">function</span> <span class="token keyword">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">public</span> view <span class="token function">returns</span> <span class="token punctuation">(</span> uint <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> value <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Next, add a migration and the file name starts with the number 2 example 2_simple_store.js and the content should be as follows:
1 | <span class="token keyword">var</span> SimpleStore <span class="token operator">=</span> artifacts <span class="token punctuation">.</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">"./SimpleStore.sol"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> module <span class="token punctuation">.</span> <span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> deployer <span class="token punctuation">)</span> <span class="token punctuation">{</span> deployer <span class="token punctuation">.</span> <span class="token function">deploy</span> <span class="token punctuation">(</span> SimpleStore <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> |
Install and configure Loom Truffle Provider
Next step we need to install loom-truffle provider to provide connection between Truffle and Loom DAppChain and configure truffle-config.js
1 | npm install loom-truffle-provider --save #or yarn add loom-truffle-provider |
Before configuring truffle-config.js we need to create a key using the command:
loom genkey -a public_key -k private_key
Configure truffle-config.js
1 | <span class="token keyword">const</span> <span class="token punctuation">{</span> readFileSync <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'fs'</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> LoomTruffleProvider <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'loom-truffle-provider'</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> chainId <span class="token operator">=</span> <span class="token string">'default'</span> <span class="token keyword">const</span> writeUrl <span class="token operator">=</span> <span class="token string">'http://127.0.0.1:46658/rpc'</span> <span class="token keyword">const</span> readUrl <span class="token operator">=</span> <span class="token string">'http://127.0.0.1:46658/query'</span> <span class="token keyword">const</span> privateKey <span class="token operator">=</span> <span class="token function">readFileSync</span> <span class="token punctuation">(</span> <span class="token string">'./private_key'</span> <span class="token punctuation">,</span> <span class="token string">'utf-8'</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> loomTruffleProvider <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LoomTruffleProvider</span> <span class="token punctuation">(</span> chainId <span class="token punctuation">,</span> writeUrl <span class="token punctuation">,</span> readUrl <span class="token punctuation">,</span> privateKey <span class="token punctuation">)</span> module <span class="token punctuation">.</span> exports <span class="token operator">=</span> <span class="token punctuation">{</span> networks <span class="token punctuation">:</span> <span class="token punctuation">{</span> loom_dapp_chain <span class="token punctuation">:</span> <span class="token punctuation">{</span> provider <span class="token punctuation">:</span> loomTruffleProvider <span class="token punctuation">,</span> network_id <span class="token punctuation">:</span> <span class="token string">'*'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Running Truffle deploy command
Now you can deploy contract to Dappchain but remember to run the network using the ./loom command first:
truffle deploy --network loom_dapp_chain
If you have deployed and want to deploy again, use the command
truffle deploy --reset --network loom_dapp_chain
Configure and run Web3.js + LoomProvider
We have deployed the contract to the Dappchain network and then we will interact with that contract via web3.js and LoomProvider.
Install web3.js
1 | npm install <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="87f0e2e5b4c7b6a9b7a9b7">[email protected]</a> --save #or yarn add <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="ddaab8bfee9decf3edf3ed">[email protected]</a> |
Install LoomProvider (it is in loom-js)
1 | npm install loom-js --save #or yarn add loom-js |
After installation is complete, we create a js file named index.js to interact with Dappchain with the following content:
1 | <span class="token keyword">const</span> Web3 <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'web3'</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> SimpleStore <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'./build/contracts/SimpleStore.json'</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> LoomProvider <span class="token punctuation">,</span> Client <span class="token punctuation">,</span> Contract <span class="token punctuation">,</span> Address <span class="token punctuation">,</span> LocalAddress <span class="token punctuation">,</span> CryptoUtils <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'loom-js'</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> privateKey <span class="token operator">=</span> CryptoUtils <span class="token punctuation">.</span> <span class="token function">generatePrivateKey</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> publicKey <span class="token operator">=</span> CryptoUtils <span class="token punctuation">.</span> <span class="token function">publicKeyFromPrivateKey</span> <span class="token punctuation">(</span> privateKey <span class="token punctuation">)</span> <span class="token comment">// Create the client</span> <span class="token keyword">const</span> client <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Client</span> <span class="token punctuation">(</span> <span class="token string">'default'</span> <span class="token punctuation">,</span> <span class="token string">'ws://127.0.0.1:46658/websocket'</span> <span class="token punctuation">,</span> <span class="token string">'ws://127.0.0.1:46658/queryws'</span> <span class="token punctuation">,</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> main <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// The address for the caller of the function</span> <span class="token keyword">const</span> <span class="token keyword">from</span> <span class="token operator">=</span> LocalAddress <span class="token punctuation">.</span> <span class="token function">fromPublicKey</span> <span class="token punctuation">(</span> publicKey <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toString</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"from = "</span> <span class="token operator">+</span> <span class="token keyword">from</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Instantiate web3 client using LoomProvider</span> <span class="token keyword">const</span> web3 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Web3</span> <span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">LoomProvider</span> <span class="token punctuation">(</span> client <span class="token punctuation">,</span> privateKey <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">// const contractAddress = '0x62C436B6f3f028cF1eb14BDBBc0eaF0c63f62B0E'</span> <span class="token keyword">const</span> contractAddress <span class="token operator">=</span> SimpleStore <span class="token punctuation">.</span> networks <span class="token punctuation">[</span> <span class="token string">"13654820909954"</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> address <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> contractAddress <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Instantiate the contract and let it ready to be used</span> <span class="token keyword">const</span> contract <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">web3 <span class="token punctuation">.</span> eth <span class="token punctuation">.</span> Contract</span> <span class="token punctuation">(</span> SimpleStore <span class="token punctuation">.</span> abi <span class="token punctuation">,</span> contractAddress <span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token keyword">from</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token comment">// Set the value 47</span> <span class="token keyword">await</span> contract <span class="token punctuation">.</span> methods <span class="token punctuation">.</span> <span class="token keyword">set</span> <span class="token punctuation">(</span> <span class="token number">47</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">send</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token keyword">from</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token comment">// Get the value 47</span> <span class="token keyword">await</span> contract <span class="token punctuation">.</span> methods <span class="token punctuation">.</span> <span class="token keyword">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">call</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token keyword">from</span> <span class="token punctuation">:</span> <span class="token keyword">from</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> error <span class="token punctuation">,</span> result <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"result = "</span> <span class="token operator">+</span> result <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> contract <span class="token punctuation">.</span> events <span class="token punctuation">.</span> <span class="token function">NewValueSet</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> error <span class="token punctuation">,</span> event <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'New value set = '</span> <span class="token punctuation">,</span> event <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">on</span> <span class="token punctuation">(</span> <span class="token string">'error'</span> <span class="token punctuation">,</span> console <span class="token punctuation">.</span> error <span class="token punctuation">)</span> <span class="token comment">// The address for the caller of the function</span> <span class="token punctuation">}</span> <span class="token function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
To run this file you can run it by:
node index.js
github complete example:
https://github.com/vinhyenvodoi98/Loomnetwork_Dappchain
Reference sources:
https://loomx.io/developers/docs/en/intro-loom-sdk.html
The introduction to Loom Network as well as the construction of a simple example running on Loom Network here is a very nice ending.