Rsk react-express box
In this tutorial, I will show you step-by-step how to use the Truffle box rsk-react-express-box, which comes with everything you need to start using express JS to provide API endpoints to smart contracts and a react app to interact with them on RSK Blockchain. It includes network configurations for Mainnet, Testnet and the SimpleStorage contract as an example to deploy.
This tutorial is helpful to review the steps with more explanatory details and images.
Overview
What we will do in this tutorial:
- Pre-requisites
- Install RSK Truffle box;
- Truffle development console;
- Compile a smart contract;
- Deploy a smart contract;
- Test a smart contract;
- Interact with a smart contract in development console;
- Client-server application;
- Using RSK networks;
- Deploy the smart contract on RSK network;
- Client-server application on RSK network;
Setup prerequisites
Check out this tutorial to be shure that you have all prerequisites configured.
Install RSK Truffle Box
The truffle unbox command sets up a project based on a known template. In this tutorial, we will be using the “RSK react-express” Truffle box, which provides API endpoints to smart contracts and app to interact with them, including RSK network configurations and the SimpleStorage contract as an example to deploy.
Create a new folder
For example, create the folder rsk-react-express
.
Navigate to the folder in the terminal.
mkdir rsk-react-express
cd rsk-react-express
This is the result using Windows OS:
C:\>cd C:\RSK
C:\RSK>mkdir rsk-react-express
C:\RSK>cd rsk-react-express
C:\RSK\rsk-react-express>
Run the unbox command
The truffle unbox command will install all necessary dependencies in the project, so it can take some time.
truffle unbox rsksmart/rsk-react-express-box
The truffle unbox output
should be similar to:
C:\RSK\rsk-react-express>truffle unbox rsksmart/rsk-react-express-box
Starting unbox...
=================
√ Preparing to download box
√ Downloading
√ cleaning up temporary files
√ Setting up box
Unbox successful, sweet!
Commands:
Compile contracts: truffle compile
Migrate contracts: truffle migrate
Test contracts: truffle test
Run dev server: cd app && npm run dev
Run production server: cd app && npm start
Build for production: cd app && npm run build
C:\RSK\rsk-react-express>
A client-server
application is generated in the app
directory.
SimpleStorage.sol
Take a look at the smart contract SimpleStorage.sol
. You can check it out in folder contracts
.
pragma solidity >=0.4.0 <0.7.0;
contract SimpleStorage {
uint storedData;
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint) {
return storedData;
}
}
This smart contract has:
- A variable
storedData
to store a number - A function
get()
to return the number stored at variablestoredData
- A function
set()
to change the number stored at variablestoredData
Truffle development console
Truffle has an interactive console that also spawns a development blockchain. This is very useful for compiling, deploying and testing locally.
Run the development console by typing the following command below into the terminal:
truffle develop
This command is successful if you see a list of 10 accounts and their associated private keys,
a mnemonic and the command prompt is now truffle(develop)>
C:\RSK\rsk-next>truffle develop
Truffle Develop started at http://127.0.0.1:8545/
Accounts:
(0) 0x1056f747cf4bc7710e178b2aeed4eb8c8506c728
(1) 0x45a71c00382c2898b5d6fae69a6f7bfe6edab80c
(2) 0x1596384706dc9ac4cca7f50279a4abe591d6c3fe
(3) 0x9576d0a496b645baa64f22aceb2328e7468d4113
(4) 0xd431572eef7d77584d944c1809398a155e89f830
(5) 0x92c111839718fe0800fadccc67068b40b8524a0f
(6) 0x6da22b5a027146619bfe6704957f7f36ff029c48
(7) 0x2c3a82d8c3993f8c80dcaf91025437bd057df867
(8) 0xc43ae7a44f7deb759177b7093f06512a0a9ff5d7
(9) 0xe61bf00cd7dce248449cfe58f23a4ef7d542bc0b
Private Keys:
(0) f32f32839fe27ad906b63eafb326f26fed95c231e3c5e33c7cdd08f62db63167
(1) ebef990088f27f6ef13b5e52a77d5dcc5a76862a701908c586d01b6fe93562b3
(2) 598ccae5e4436fedeb0e798c0d254789c55a63401ebfc3ae8ddde29634ddfcde
(3) 09934b80f391e0024b8cb00cd73790fdf64c4d0509e144766414fee317cd3f4e
(4) ac745b84b6574b5738d364b43e0d471c9d5107504acc709c90f6f091b78c751b
(5) 449654cde095f2349113ef12a93e139b4302bc95adb3619d08adf53dde9b8847
(6) c217f12a89c352fc70b5f1bd5742314b4fb1bb1e35cb779fdb3c2390106355db
(7) 1d4c74dfa4e99e161130c18cc63938bb120a128cefbf1b9188efc678bf5722cb
(8) 0f44e0becf2e090db498a1b747d2a758fcc81fb0241f350d61117a9c6b1fa82e
(9) 85218c5eec657470dafeb09e6f7101f91d21bfe822fbeeecfc9275f798662a63
Mnemonic: virtual valve razor retreat either turn possible student grief engage attract fiber
⚠️ Important ⚠️ : This mnemonic was created for you by Truffle. It is not secure.
Ensure you do not use it on production blockchains, or else you risk losing funds.
truffle(develop)>
Inside the development console we don't preface commands with
truffle
.
Compile a smart contract
In the Truffle console, run this command:
compile
The compile output
should be similar to:
truffle(develop)> compile
Compiling your contracts...
===========================
> Compiling .\contracts\Migrations.sol
> Compiling .\contracts\SimpleStorage.sol
> Artifacts written to C:\RSK\rsk-react-express\app\src\contracts
> Compiled successfully using:
- solc: 0.5.16+commit.9c3226ce.Emscripten.clang
truffle(develop)>
About contracts_build_directory in Truffle config
Did you notice above that the artifacts
was written in a different locale?
In truffle-config.js
file, located in the project folder, we change the localization where files for contracts artifacts are saved, like abi and deployed addresses.
Take a look at the changes:
- Line 1: library
path
was added. - Line 37: we add a new parameter
contracts_build_directory
that defines the locale for the contracts artifacts.
It is located in a different folder: app/src/contracts
.
Deploy a smart contract
To deploy a smart contract using Truffle, we need a new migrations file where Truffle will find it. This file contains instructions to deploy the smart contract.
The migrations
folder has JavaScript files that help you deploy contracts to the network.
These files are responsible for staging your deployment tasks, and they're written under the assumption that your deployment needs will change over time.
A history of previously run migrations is recorded on-chain through a special Migrations contract.
(source: truffle: running-migrations)
Take a look in the file 2_deploy_contracts.js
located in the migrations folder.
Migrate
In the Truffle console, run this command:
migrate
The migrate output
should be similar to:
truffle(develop)> migrate
Compiling your contracts...
===========================
> Compiling .\contracts\Migrations.sol
> Compiling .\contracts\SimpleStorage.sol
> Artifacts written to C:\RSK\rsk-react-express\app\src\contracts
> Compiled successfully using:
- solc: 0.5.16+commit.9c3226ce.Emscripten.clang
Starting migrations...
======================
> Network name: 'develop'
> Network id: 5777
> Block gas limit: 6721975 (0x6691b7)
1_initial_migration.js
======================
Deploying 'Migrations'
----------------------
> transaction hash: 0x1e14b5f2230f5cf09057c636885713d9d44de1fe88436797bf6af0931d77d76f
> Blocks: 0 Seconds: 0
> contract address: 0xf5c8B230b5281A8813b5153B4bCd815626d098cb
> block number: 1
> block timestamp: 1597619265
> account: 0x1056F747cf4bC7710E178B2aeED4Eb8c8506c728
> balance: 99.9967165
> gas used: 164175 (0x2814f)
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.0032835 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.0032835 ETH
2_deploy_contracts.js
=====================
Deploying 'SimpleStorage'
-------------------------
> transaction hash: 0x59fe05c934f09bb4ca610d46ceed7a0a3712eec8de96981420a3535bf63ccf94
> Blocks: 0 Seconds: 0
> contract address: 0x73f2aa5D251DbdEd6C950257124eA93bb00c0Ec0
> block number: 3
> block timestamp: 1597619265
> account: 0x1056F747cf4bC7710E178B2aeED4Eb8c8506c728
> balance: 99.9939459
> gas used: 96189 (0x177bd)
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.00192378 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.00192378 ETH
Summary
=======
> Total deployments: 2
> Final cost: 0.00520728 ETH
truffle(develop)>
Test a smart contract
Truffle has an automated testing framework to facilitate the testing of contracts.
All test files should be located in the test
directory.
To learn more, go to the Truffle documentation, in the section testing your contracts.
This Truffle box also comes with the file TestSimpleStorage.js
for testing the smart contract.
You can check it out in the test
folder.
Run this command in the development console:
test
This test output
should be similar to:
Note the command varies slightly if you're in or outside of the development console.
// inside the development console.
test
// outside the development console.
truffle test
Interact with a smart contract in development console
Make sure you deploy the smart contract before executing this part.
The next commands will run inside the development console.
Connect with our published contract
const simpleStorage = await SimpleStorage.deployed()
Now simpleStorage variable contains an instance of the previously deployed contract.
truffle(develop)> const simpleStorage = await SimpleStorage.deployed()
undefined
truffle(develop)>
Remember that the published contract information is stored in the app/src/contracts
folder.
You will find a JSON file with the same name of our smart contract.
The section networks
has the networks in which the smart contract was published, including its address and hash of the transaction.
The ABI - Application Binary Interface
is also very important because to connect with one smart contract, we must know the ABI and the address of the smart contract.
Get value
Get the value stored in the contract.
simpleStorage.get().then(bn => bn.toNumber())
We do not have any value stored, because we do not define anything at the moment when we deployed.
truffle(develop)> simpleStorage.get().then(bn => bn.toNumber())
0
truffle(develop)>
Set value
Store some value in the contract.
simpleStorage.set(2020)
Have a look at the response. The transaction receipt, generated by the blockchain nodes, is the response for the transaction request.
Get value (again)
Verify if the value stored in the smart contract was changed.
simpleStorage.get().then(bn => bn.toNumber())
The value now should be 2020
!
truffle(develop)> simpleStorage.get().then(bn => bn.toNumber())
2020
truffle(develop)>
Client-server application
This Truffle box is a client-server:
- Server uses
express JS
to interact with the smart contract. - Client uses
react
app.
Running the application in development mode
In another terminal (i.e. not in the truffle develop prompt), go to the app
directory to run the application in development mode.
Do not close the other terminal, which is running the Truffle development console, because it is our Blockchain simulator.
If you close it and then open it again, you need to deploy / migrate the smart contract again too!
cd app
npm run dev
The npm run dev output
should be similar to:
This command executes both server and client applications and you can access it in your browser:
- Server: http://localhost:8080/
- Client: http://localhost:3000/
Smart contract changes must be manually recompiled and migrated!
Running the production server
You can choose to run only the production server. In another terminal (i.e. not in the truffle develop prompt), go to the app
directory and run the app in production mode.
cd app
npm start
It can take some time. The npm start output
should be similar to:
If you have
yarn
installed, you can useyarn start
.
Then go to your browser at http://localhost:8080/
When you are running only the production server, for any change you need to stop and run the server again for the updates to take effect!
Building the application for production
To build the application for production, use the build script in the app
folder.
A production build will be in the app/dist
folder.
npm run build
The npm run build output
should be similar to:
The result will be in the app/dist
folder. Take a look:
Using RSK networks
This Truffle box is already configured to connect to both RSK networks: testnet and mainnet. We need only to update few items:
- RSK network gas price
- Your wallet mnemonic
- Choose the network in the app
Setup the gas price
Gas is the internal pricing for running a transaction or contract. When you send tokens, interact with a contract, send RBTC, or do anything else on the blockchain, you must pay for that computation. That payment is calculated as gas. In RSK, this is paid in RBTC. The minimumGasPrice is written in the block header by miners and establishes the minimum gas price that a transaction should have in order to be included in that block.
To update the minimumGasPrice, go to your project folder and run this query using cURL:
Testnet
curl https://public-node.testnet.rsk.co/ \
-X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false],"id":1}' \
> .minimum-gas-price-testnet.json
Mainnet
curl https://public-node.rsk.co/ \
-X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false],"id":1}' \
> .minimum-gas-price-mainnet.json
This query saved the details of latest block to file .minimum-gas-price-testnet.json or .minimum-gas-price-mainnet.json, respectively.
This is the result of Testnet query in the terminal in Windows OS:
In the truffle-config.js
, we are reading the parameter minimumGasPrice
in each json file.
For more information about the Gas and minimumGasPrice please go to gas page.
Create a wallet mnemonic
If you don't have a wallet mnemonic, check it out in in the tutorial prerequisites.
Update mnemonic in Truffle config
In truffle-config.js
, locate this line:
const mnemonic = 'A_MNEMONIC';
Substitute A_MNEMONIC
with the mnemonic of your wallet.
Im my example, it will be:
const mnemonic = 'virtual valve razor retreat either turn possible student grief engage attract fiber';
HD wallet provider
To connect to the RSK network, we are going to use a provider that allows us to connect to any network by unlocking an account locally.
We are using @truffle/hdwallet-provider
. It was installed with the box.
Please be aware that we are using HDWalletProvider
with RSK Networks derivations path:
- RSK Mainnet dpath:
m/44’/137’/0’/0
- RSK Testnet dpath:
m/44’/37310’/0’/0
For more information, check the account based RSK addresses.
Using Truffle Console to connect to the RSK network
Run the development console for any RSK network.
Testnet
truffle console --network testnet
Mainnet
truffle console --network mainnet
This action instructs Truffle to connect to an RSK public node and grants it permission to control the accounts created with your mnemonic through the HD wallet provider
.
I will connect to the Testnet network:
C:\RSK\rsk-react-express>truffle console --network testnet
truffle(testnet)>
Get your addresses / accounts
We will use a special instruction in Truffle console to get the first 10 addresses in our hierarchical deterministic wallet for the RSK Testnet network, that are generated from our mnemonic.
Inside the Truffle console, run this command to save the addresses at variable accounts
:
const accounts = await web3.eth.getAccounts()
truffle(testnet)> const accounts = await web3.eth.getAccounts()
undefined
truffle(testnet)>
Don't worry about the undefined
return, it is ok.
See the addresses after it by entering the command below:
accounts
truffle(testnet)> accounts
[ '0x4417CdC73f53573999F3A0397eE9df560a2f0507',
'0x390BeD29A3F28772eDdcB02750c5A58FE7793647',
'0x723dB256f61be581a6cA404d71D1d1951dD83F5e',
'0x546A13cFe418BCd8E149C78C234a953Ba79FC427',
'0xa88b72640758861f8ED4106241d743B948f7D55a',
'0xC48141Ca379f27eEABcEaBc26e5E2c2f6130b2A1',
'0xE7254aa2147549dbDA01559B449A61f993bA9b16',
'0xa52DB3045a6A880149d87014FbCAeb33a2FDbE51',
'0x7f3255db0514e0b78175e3f72DEC006B713AA166',
'0x4eD69220224f9aC13e867961027C4599fFa74409' ]
truffle(testnet)>
To view each account:
accounts[0]
accounts[1]
Take a look in the result:
In my example, the account[0]
is 0x4417CdC73f53573999F3A0397eE9df560a2f0507
.
Check balance
To check the balance of account[0]
, for example, run this command in Truffle console:
(await web3.eth.getBalance(accounts[0])).toString()
truffle(testnet)> (await web3.eth.getBalance(accounts[0])).toString()
'0'
truffle(testnet)>
The balance is 0 and we need some tRBTC to pay gas fees, which will be used to publish smart contracts and interact with them. We shall obtain some tRBTC in the next step.
Exit Truffle console
In the Truffle console, enter this command to exit the terminal:
.exit
truffle(testnet)> .exit
C:\RSK\rsk-starter>
Get RBTC
The Smart Bitcoin (RBTC) is the token used to pay for the execution of transactions in RSK.
Mainnet
For the RSK Mainnet, get RBTC from an exchange.
Testnet
For the RSK Testnet, get tRBTC from our faucet.
Enter your wallet address and pass the CAPTCHA.
Wait a few seconds…
This is an example of a transaction hash received from faucet:
0x0661f313cb387b6f09549a7f81ca7c0e7cc476cfe6069a9c755b1ceb8b531874
Deploy the smart contract on RSK network
Migrate the smart contracts. We will do it by running the below commands directly in the terminal, without using the truffle console now to show to you this alternative. Run the migrate command for the RSK network of your choice.
Testnet
truffle migrate --network testnet
Mainnet
truffle migrate --network mainnet
I will do it on RSK testnet.
C:\RSK\rsk-react-express>truffle migrate --network testnet
Minimum gas price Testnet: 59240000
Minimum gas price Mainnet: 59240000
Compiling your contracts...
===========================
> Compiling .\contracts\Migrations.sol
> Compiling .\contracts\SimpleStorage.sol
> Artifacts written to C:\RSK\rsk-react-express\app\src\contracts
> Compiled successfully using:
- solc: 0.5.16+commit.9c3226ce.Emscripten.clang
Starting migrations...
======================
> Network name: 'testnet'
> Network id: 31
> Block gas limit: 6800000 (0x67c280)
1_initial_migration.js
======================
Deploying 'Migrations'
----------------------
> transaction hash: 0xd6cc1be060799ba290b586d9c79faeac168f6acf9c7ac9bb37c5a861e0a42c8e
> Blocks: 2 Seconds: 45
> contract address: 0xE74cB414FaB072D2cF1b33D85CC76de47e83F6ef
> block number: 1100032
> block timestamp: 1597621554
> account: 0x4417CdC73f53573999F3A0397eE9df560a2f0507
> balance: 0.0998586922394028
> gas used: 188483 (0x2e043)
> gas price: 0.065164 gwei
> value sent: 0 ETH
> total cost: 0.000012282306212 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.000012282306212 ETH
2_deploy_contracts.js
=====================
Deploying 'SimpleStorage'
-------------------------
> transaction hash: 0xee1c7f901fa94baf05ef7f5909399ee838a14aa71f75fa9a19b7fa1170fa6d35
> Blocks: 1 Seconds: 49
> contract address: 0xA1F4B62F9643B405763552915400cc7dA361b7C5
> block number: 1100036
> block timestamp: 1597621663
> account: 0x4417CdC73f53573999F3A0397eE9df560a2f0507
> balance: 0.0998489586927228
> gas used: 107369 (0x1a369)
> gas price: 0.065164 gwei
> value sent: 0 ETH
> total cost: 0.000006996593516 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.000006996593516 ETH
Summary
=======
> Total deployments: 2
> Final cost: 0.000019278899728 ETH
C:\RSK\rsk-react-express>
Congratulations!
Simple storage
is now published on the RSK network.
Make sure you have enough RBTC to deploy it.
Client-server application on RSK network
The express JS server uses the web3.js library to interact with the blockchain - writing code that reads and writes data from the blockchain with smart contracts.
To connect the client-server application to an RSK network, we just have to update a single line in the express JS component.
Update connection
Open the file app/src/server/index.js
Choose which network you would like to connect the server to RSK Network and update line 11:
Testnet
const provider = new Web3.providers.HttpProvider("https://public-node.testnet.rsk.co");
Mainnet
const provider = new Web3.providers.HttpProvider("https://public-node.rsk.co");
Running the app
In a terminal, go to the app
directory and run the app.
For example, this command will run the production server:
cd app
npm start
Then go to your browser at http://localhost:8080/
Note that when you are connected to an RSK network, you do not need to leave open the Truffle console, because the app is connected via a public node, directly to the network.
Final considerations
In this tutorial you learned how to use the Truffle box rsk-react-express-box, which comes with everything you need to start using Truffle on RSK networks.
Check out RSK Blockchain for more details about us.
I hope this tutorial has been helpful and I'd appreciate your feedback. Share it if you like it :)
Do you have questions?
Ask in the the RSK community Slack.