This tutorial explains how to execute a Smart Contract on your private Kaleido Ethereum Blockchain with the Truffle Framework.
Prerequisites
Do read "Deploy a Private Ethereum Blockchain in 10 minutes" to have your private Blockchain instance running before continuing with this tutorial.
Setting Up
If you haven't setup the Truffle Framework, here are the steps to do so.
If you are running Truffle on Windows, you first need to install the window build tool. Run this in your command prompt.
npm install -g -production windows-build-tools
Then install the Truffle Framework.
npm install -g truffle
The truffle-hdwallet-provider-privkey library lets you sign and execute transactions by providing a private key that belongs to an existing Ethereum wallet. This is helpful because I could have an existing Wallet address that was generated earlier in MetaMask and now wish to use it to test my Smart Contract in Truffle.
npm install truffle-hdwallet-provider-privkey
Create a folder in a location of your choice.
md trufflekaleido
And then enter the folder.
cd trufflekaleido
Truffle Framework provides several boilerplates for building Ethereum-based DApps. Here are several boilerplates. Webpack is the most basic boilerplate to start with. We will setup webpack in our /trufflekaleido folder.
truffle unbox webpack
Getting a Wallet Address
I use Ian Coleman's website to generate my wallet address and private key. Ian's mnemonic code key generator allows you to base on a 3 to 24 words mnemonic to generate your wallet's address and private keys.
To do so, select the total number of words to use as mnemonic. Then select Ethereum, and click [Generate].
Now scroll down to the Derived Address section and copy any one of the Address/Private Key pair. The "Address" field is what you can feel free to send to anyone you wish to receive ETH from. The private key is what you will use to sign transactions.
Go to your Kaleido console and click "Ether Pool".
Then paste the public key here to receive some ETH.
If you are wondering how is it possible to generate a wallet address without first connecting to the Blockchain to check if there's a existing duplicate wallet address on the Blockchain, here's an article to read. (TLDR) The probability that a randomly generated private key and wallet address has been used is essentially 0.
Creating the Contract
We will now write a simple greeting contract. Navigate to /trufflekaleido/contracts folder. Webpack would have added several contracts here by default. Create a new file. You can call it hello.sol.
Add the follow codes to hello.sol.
pragma solidity >=0.4.22 <0.6.0;
contract Mortal {
/* Define variable owner of the type address */
address owner;
/* This constructor is executed at initialization and sets the owner of the contract */
constructor() public { owner = msg.sender; }
/* Function to recover the funds on the contract */
function kill() public { if (msg.sender == owner) selfdestruct(msg.sender); }
}
contract Greeter is Mortal {
/* Define variable greeting of the type string */
string greeting;
/* This runs when the contract is executed */
constructor(string memory _greeting) public {
greeting = _greeting;
}
/* Main function */
function greet() public view returns (string memory) {
return greeting;
}
}
This greeter smart contract code comes from https://www.ethereum.org/greeter and does nothing but lets you set and read a "greeting" variable in the contract.
Deploy the Greeter Contract
Navigate to the /trufflekaleido/migrations folder and edit 2_deploy_contracts.js
var mortal = artifacts.require("./Mortal");
var greeter = artifacts.require("./Greeter");
module.exports = function(deployer) {
deployer.deploy(greeter, 'Jack');
};
Here, we declare mortal and greeter. This corresponds to the contracts of the same name in hello.sol. The contract that we will run is greeter and we instantiate the contract by providing the string 'Jack' to the greeting
variable in the greeter contract.
Navigate back to /trufflekaleido and edit truffle-config.js. Here's a sample of how it may look.
var HDWalletProvider = require("truffle-hdwallet-provider-privkey");
const privKeys = ["<replace with your wallet's private key"];
module.exports = {
networks: {
ganache: {
host: '127.0.0.1',
port: 7545,
network_id: '*' // Match any network id
},
development: {
provider: function() {
return new HDWalletProvider(privKeys, "<replace with your kaleido node address");
},
network_id: '*',
gas: 4700000
}
},
// Set default mocha options here, use special reporters etc.
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
}
}
}
We then tell Truffle that truffle-hdwallet-provider-privkey is our Wallet Provider.
var HDWalletProvider = require("truffle-hdwallet-provider-privkey");
And here, we provide our wallet's private key.
const privKeys = ["65c2d64f53211d8328c6db8e8bc22341c0f0b8d22989f40f4efd0ed55e3e3d8b"];
Replace the part in "<" and ">" with the private key generated in the previous step. Remember to remove the leading "0x". So this:
0x65c2d64f53211d8328c6db8e8bc22341c0f0b8d22989f40f4efd0ed55e3e3d8b
Should look like:
const privKeys = ["65c2d64f53211d8328c6db8e8bc22341c0f0b8d22989f40f4efd0ed55e3e3d8b"];
Truffle Framework allows you to run your Smart Contracts on a local private instance of an Ethereum Blockchain network with Ganache but we want to run our contract in our Kaleido Ethereum instance. So add a new network "development" right below ganache:
ganache: {
host: '127.0.0.1',
port: 7545,
network_id: '*' // Match any network id
},
development: {
provider: function() {
return new HDWalletProvider(privKeys, "<replace with your kaleido node address>");
},
network_id: '*',
gas: 4700000
}
To find out what's your Kaleido node's address, select the node in the Kaleido interface and click on [Connect Node].
Select [VIEW DETAILS] under Native JSON/RPC.
Provide your SECRET KEY. Hit [Submit].
Copy the CONNECTION URL under the "Auth Type -INURL" section.
Paste it in the section that says "<replace with your kaleido node address>".
return new HDWalletProvider(privKeys, "<replace with your kaleido node address>");
We are ready to compile and run.
truffle compile
And migrate. Migration will create your Smart Contract in the Kaleido private Ethereum Blockchain network.
truffle migrate
This is what you should see:
Running migration: 1_initial_migration.js
Deploying Migrations...
... 0xbb56569292a0a5f47700f450dc8e166545308835b5fd8db7d09c00a306d83852
Migrations: 0xcdd5665ec87da674dc58549f2fc0bb8c514661bb
Saving artifacts...
Running migration: 2_deploy_contracts.js
Replacing Greeter...
... 0xa3447e50d0de2a86c0325e975478399d8abe931efa6458a9deb78b0b24a89d82
Greeter: 0x96b9b7d5330021ed3e1ab2191482479def16c036
Saving artifacts...
Take a look at the Block Explorer in Kaleido and you should see that new transactions have just been executed.
Testing the Contract
You may now test the contract in the Truffle Console. Start the console using the "development" settings that we have provided.
truffle console --network development
The truffle console starts up.
truffle(development)>
And run the following command to execute the greet()
method to find out the value of greeting
in your Smart Contract.
Greeter.deployed().then(function(contractInstance) {contractInstance.greet().then(function(v) {console.log(v)})})
Greeter responds with "Jack" like this:
truffle(development)> Greeter.deployed().then(function(contractInstance) {contractInstance.greet().then(function(v) {console.log(v)})})
undefined
truffle(development)> Jack
Photo by Lance Anderson on Unsplash