Deploying Ethereum smart contracts using Ledger Wallet + Truffle

The official Truffle Suite currently does not contain any easy way of deploying smart contracts signed with Ledger Wallet. The standard way of deploying smart contracts usually involved BIP39 mnemonics, MetaMask or copy-pasting compiled smart contracts to MyEtherWallet. Hence, I have created a simple Ledger Wallet-enabled Web3 provider, that allows a safe & easy way of deploying smart contracts (for example through Infura gateway) without storing your private keys in a hot storage. This package is available as a NPM package truffle-ledger-provider.

In this article, I will demonstrate this approach by deploying a ERC20 smart contract in 10 minutes, without storing the private key on your computer, without using MetaMask or without downloading the whole Ethereum blockchain.

Configure Ledger Nano S

The first step is to connect your Ledger Wallet to the computer, install Ethereum App (if you haven’t already did so) and configure it as follows:

  • Contract data: YES
  • Browser support: NO

Initializing Truffle environment

First of all, we need to install the Truffle Suite:

npm install -g truffle

The parameter -g is there to install the Truffle Suite globally, so that we can use the truffle command.

Now, we create and initialize our Truffle environment with Open Zeppelin and Ledger Wallet support:

mkdir my-token && cd my-token
truffle init
npm install
zeppelin-solidity
npm install truffle-ledger-provider

Creating ERC20 token smart contract

To demonstrate capabilities of truffle-ledger-provider, we create and deploy ERC20 token smart contract signed by the private key stored in our Ledger Wallet.

We store our sample ERC20 token in file contracts/MyToken.sol:

pragma solidity ^0.4.18;
import 'zeppelin-solidity/contracts/token/ERC20/StandardToken.sol';
contract MyToken is StandardToken {
string public name = "MY-TOKEN";
string public symbol = "MYT";
uint public decimals = 18;
uint public INITIAL_SUPPLY = 100000000 * (10 ** decimals);
    function MyToken() public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
Transfer(0x0, msg.sender, INITIAL_SUPPLY);
}
}

Before deploying this smart contract, we must create a Truffle migration script migrations/2_deploy_token.js:

var MyToken = artifacts.require("MyToken");
module.exports = function(deployer) {
deployer.deploy(MyToken);
};

Deployment with Ledger Wallet

Finally, in order to deploy the smart contract using the Ledger Nano S or Ledger Blue wallet, we update our Truffle Suite configuration file truffle.js. To avoid downloading the whole Ethereum blockchain locally, you can register your Infura API key and use the following configuration:

var LedgerWalletProvider = require("truffle-ledger-provider");
var infura_apikey = "..."; // set your Infura API key
var ledgerOptions = {
networkId: 3, // ropsten testnet
accountsOffset: 0 // we use the first address
};
module.exports = {
networks: {
ropsten: {
provider: new LedgerWalletProvider(
ledgerOptions,
"https://ropsten.infura.io/" + infura_apikey
),
network_id: 3,
gas: 4600000
}
}
};

The compilation and deployment of the smart contract is done by executing:

truffle compile
truffle migration --network ropsten

In case you correctly followed all steps in this article, you should see the following confirmation on your Ledger Wallet before deployment of each smart contract:

Deployment of each smart contract must be confirmed with Ledger Wallet