Skip to content

Instantly share code, notes, and snippets.

@danfinlay
Last active April 6, 2024 04:32
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save danfinlay/aea93752fb90322bbe11 to your computer and use it in GitHub Desktop.
Save danfinlay/aea93752fb90322bbe11 to your computer and use it in GitHub Desktop.
Developing Ethereum Dapps with Truffle and Metamask

Truffle and Metamask If you're interested in building web apps with the Ethereum blockchain, you may have found the Truffle web framework to be a nice fit for your needs.

For many types of Dapps (Distributed Apps), Truffle does everything you could want: It compiles your blockchain contracts, injects them into your web app, and can even run a test suite against them!

This is all great for you, but what about your users? Truffle has some great defaults for users who are willing to run a local Ethereum JSON RPC server on their computer, but what about your users who just want to sign on and get started?

With Metamask, all your users need to do is install our Chrome plugin, and they will have their own secure blockchain accounts right there in the convenience of their browsers.

metamask accounts

Metamask is just a Developer Preview right now, and has not been released to the general public. We don't recommend putting serious funds in it, but instead encourage you to use it to help prepare your dapps for Ethereum browsers.

It's possible your Truffle Dapp is already compatible with Metamask, but if you're like me, you want to go through your project and see what it's like from your user's perspective.

Just in case you haven't used Truffle before, I'm going to start by describing how to scaffold a minimal Truffle dapp. If you already have one set up, feel free to scroll ahead!

Installing Truffle Dependencies

You're going to need to have installed node.js.

From there, you need to install truffle (npm install -g truffle).

Also, you're going to need to run a local blockchain RPC server to test and develop against. I recommend using testrpc, which you install by running npm install -g ethereumjs-testrpc.

Next let's make sure we have our testrpc running in the background. Open your terminal and run the command testrpc. That's all! It runs on port 8545 by default, just like most Ethereum RPCs, and so does Truffle.

A quick note on RPCs

Ethereum RPCs can run in a pre-authenticated mode, that allows you to perform transactions without providing any additional credentials. Obviously this would be a dangerous thing to do on the open web, but for local development, it's the default method that testrpc provides.

When you first start testrpc, You get a list of initial accounts. These accounts start funded with a whole lot of Ether, so you can practice exchanging funds between accounts.

When you open a normal Truffle Dapp, it takes advantage of your local authenticated rpc, and has access to its account list. The default Truffle dapp just uses the first account in the list.

Setting up a simple Truffle Dapp

Next, let's generate a basic Truffle dapp. The default result of truffle init is a simple example currency.

To get it up and running, run these commands:

mkdir my-money  # Create a folder for your new dapp
cd my-money     # Move into that folder
truffle init    # Initialize a default truffle project in that folder
truffle build   # Compile the dapp
truffle deploy  # Publish the dapp on the blockchain
truffle serve   # Host your web interface on port 8080

We just deployed a simple alt-coin called MetaCoin to our local blockchain, and it's available to our browser on http://localhost:8080!

MetaCoin default

If you visit it, you'll see that by default this new Dapp template signs you in with the first account on your testrpc account list, which happens to be the same account that got pre-populated with 10k shiny new Metacoins! That's because when you ran truffle deploy, Truffle used your first account as the contract publisher, and the contract says to fund the creator's account with 10k coins.

If you don't see any Metacoin in this account, it may be because you have Metamask already installed. Jump down to "Switching between testrpc and Metamask accounts" below.

You can now send those coins to any account you want, so let's now set up some Metamask accounts, and then we can fund them!

Setting up Metamask

Now you'll want to install Metamask from the Chrome store.

Metamask is currently not listed on the Chrome store, but you get that link because you're an early adopter who we want to support.

When first setting up Metamask, you'll need to provide a password (used to encrypt your wallet). It is then going to generate a unique twelve-word phrase that you'll eventually be able to use to recover all your accounts.We haven't done that yet because this is just a developer preview! Please don't use Metamask for important things yet!

By default you get three accounts, all named Wallie. Again, our developer preview is showing. Eventually we're planning to integrate rich persona management via uPort!).

To use Metamask with your local development blockchain, you need to point it at your testrpc.

setting metamask testrpc

  1. Open Metamask
  2. Click the gear icon in the bottom left
  3. Enter your testrpc address into the RPC field. It's probably http://localhost:8545/.

Metamask will close at this point to restart itself.

You can now sign into the dapp with Metamask.

  1. Open Metamask
  2. Enter your password
  3. Select an account
  4. Reload the Dapp page (some dapps will notice when you change accounts, but this basic one doesn't)

You might notice you don't have any Metacoin in this account. That's a good thing! It means your new currency isn't going out to random accounts on the internet!

To send some Metacoin to one of your Metamask accounts, you're going to need that account's address.

To copy a Metamask account's address:

  1. Open Metamask
  2. Click the details arrow next to the account whose address you want.
  3. Click the "Copy Address" button.

You now you have a copy of your address to send to!

Switching between testrpc and Metamask accounts

When Metamask is installed, it intercepts calls and transactions to the Ethereum blockchain, and forwards them to its own RPC (which is currently on the test-network by default).

Since Metamask is managing ethereum connections when it's installed, our Chrome browser right now can't access our testrpc accounts, because those accounts are managed by the testrpc node itself, so we need to open a browser without metamask.

The easiest way to do this is to open an incognito window. You can also open another browser.

Funding your Metamask account

Once you're connected to your testrpc accounts again, you can send your Metacoin to whoever you please, including your new Metamask accounts.

You might also notice that your new Metamask accounts don't have any ether in them. The testrpc initializes the blockchain with just its starting accounts having any balance, so to fund a Metamask account, you need to send some Ether to those accounts from one of your testrpc accounts. (In a future version of testrpc there will probably be better ways to do this).

Here's a simple shell command to tell your testrpc to send 1 ether to your Metamask account. Let's assume 0x0f91747e3a5df28d81ab30b2d8216c93263c0cf3 is the first account in your testrpc list, and 0xbbd220f66e989a493c4d48531ea1e283abc385de is one of your Metamask accounts.

1e18 is equal to 1 ether, which will be more than enough for our purposes.

curl -d '{"jsonrpc":"2.0","method":"eth_sendTransaction","params": [{"from":"0x0f91747e3a5df28d81ab30b2d8216c93263c0cf3", "to":"0xbbd220f66e989a493c4d48531ea1e283abc385de", "value": 1e18}], "id":1}' -X POST http://localhost:8545/

Sending Metacoin from Metamask: So Meta!

Now if we connect to our Dapp via Metamask, we should see we have some MetaCoin, and if we look in our Metamask plugin, we should have 1 ether too!

It's important that we have ether, because it's not only a currency for trade, it's also the currency for processing transactions on the Ethereum blockchain. This processing fee is referred to as "gas".

Let's try sending some Metacoin from one of our Metamask accounts to another.

First select the account that has the Metacoin and Ether. Now click the details arrow for another account, and copy its address (COPY ADDR).

Metamask account detail view

Paste the address into the Dapp window, along with how much Metacoin you'd like to send, and hit send!

You should see a notification pop-up, notifying you that you have a transaction to approve in Metamask.

Approval notification

You can either click "Approve" on the notification, or open the Metamask pop-up and review the transaction there.

This is one way that Metamask is a safer Ethereum browsing experience than running your own RPC. While a pre-authenticated RPC automatically approves all requests sent to it, Metamask gives the user an opportunity to review and approve or reject each transaction that's requested by the dapp. Long term, making transactions easy to intelligently review is an important priority for Ethereum developers.

Wrapping Up

This has been a simple example, but hopefully shows how Truffle and Metamask work together. They are able to pretty much work out of the box! That's because Truffle helps you write web3-compliant dapps. Web3 is a Javascript API declared by the core Ethereum team, and since it was standardized early, tools that take advantage of its common methods work well together.

This makes connecting to a Truffle Dapp with Metamask not much harder than connecting via your own RPC, but it's a lot easier for your users.

That's because Metamask is a hyper-light client that doesn't replicate the entire blockchain locally, but it does let users manage their own accounts, so they can casually benefit from the security of private key management, while placing trust for block validation on Metamask's configured RPC provider.

We hope this has been a useful introduction to developing with Truffle and Metamask!

Please, leave a comment or question, start a discussion on github, or Tweet at us on Twitter. We're trying to make Metamask the easiest tool to let anyone benefit from using Distributed Apps on the Ethereum Blockchain.

@paulpreibisch
Copy link

"Now if we connect to our Dapp via Metamask, we should see we have some MetaCoin, and if we look in our Metamask plugin, we should have 1 ether too!" So.... how do we connect our Dapp via MetaMask?

@stuffyvater
Copy link

It seems truffle never found the addresses testrpc created.. when i open local host i get the exact same address as the webpage and no meta coins :(

@haiqu
Copy link

haiqu commented Oct 2, 2016

This is out of date already. 'truffle migrate' replaces 'truffle deploy'.

See http://truffle.readthedocs.io/en/latest/getting_started/migrations/

Here's the actual procedure:

Run testrpc in a terminal window

In a new window:

mkdir metacoin # Create a folder for your new dapp
cd metacoin # Move into that folder
truffle init # Initialize a default truffle project in that folder
truffle migrate # Publish the dapp on the blockchain
truffle build # Compile the dapp
truffle serve # Host your web interface on port 8080

To view: http://localhost:8080 (in a new Incognito window if using Chrome)

@s-xu
Copy link

s-xu commented Jan 9, 2017

Great client (for user), dapp (MetaCoin) and nice demo. Thank you!

(in addition to the updating of using "truffle migrate", a newer or later version of nvm/npm is needed, at least on Ubuntu 16.04. Everything else works smoothly "pretty much out of box".)

@rstormsf
Copy link

@FlySwatter this won't work anymore since truffle init won't provide any build config

@rstormsf
Copy link

it should be:

truffle init webpack
  Compile:        truffle compile
  Migrate:        truffle migrate
  Test:           truffle test
  Build Frontend: npm run build
  Run Linter:     npm run lint
  Run Dev Server: npm run dev

then use those commands

@jw122
Copy link

jw122 commented Jun 12, 2017

Resolved: Metamask allows importing of private keys so I don't need to use the shell cmd to transfer funds (https://ethereum.stackexchange.com/questions/3447/how-can-i-get-my-accounts-into-metamask-or-vise-versa)

When I try to run the shell command to fund my Metamask account with my testrpc account, I get the error "could not unlock signer account"

How do I unlock the signer account when running this command?

@dzarezenko
Copy link

I wanted to fund my Metamask account but received this response:

curl -d '{"jsonrpc":"2.0","method":"eth_sendTransaction","params": [{"from":"0x90ff78591d2f0c8fce1da09a384074384133acaa", "to":"0x39d5d93A1AbAbDBb7F8b5A45a02E6bc5a33EDfE7", "value": 1e18}], "id":1}' -X POST http://localhost:8545/
curl: (3) [globbing] bad range specification in column 2
curl: (6) Could not resolve host: to
curl: (6) Could not resolve host: value
curl: (3) [globbing] unmatched close brace/bracket in column 5
curl: (3) [globbing] unmatched close brace/bracket in column 5
400 Bad Request

What is wrong with my command?

@drpenny
Copy link

drpenny commented Jun 29, 2017

dzarezenko, see jw122's post, you can copy one of the private keys from the window you started testrpc in....

Resolved: Metamask allows importing of private keys so I don't need to use the shell cmd to transfer funds (https://ethereum.stackexchange.com/questions/3447/how-can-i-get-my-accounts-into-metamask-or-vise-versa)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment