Giter Club home page Giter Club logo

ethereum-address-generator-js's Introduction

Generating Ethereum accounts in Javascript

Public pey cryptography and digital signatures are a foundational technology that enable blockchains to work. In this project you are going to get your hands dirty and understand how they work at the code level. You will be using Javascript and a simple web interface to see what is going on.

First, we are going to generate a private key, derive public keys from the private key and determine the associated accounts.

To get started clone the project and

$ npm install
$ npm run watch         # this will watch for updates in main.js and update bundle.js
$ npm run reload        # this will serve the app @ localhost:8081 and refresh the page when there are updates 

If you run into any problems while implementing this demo application, try opening the developer tools in the browser (Ctrl + Shift + I or F12) and checking the 'Console' tab.

Generating randomness

In the main.js file include the bip39 package. We will use this to generate random input to generate a private key.

const BIP39 = require("bip39")

and directly below that include

// Generate a random mnemonic (uses crypto.randomBytes under the hood), defaults to 128-bits of entropy
function generateMnemonic(){
    return BIP39.generateMnemonic()
}

Not all strings of characters are valid mneomics for generating keys. You can check if a mnemonic is valid using

var isValid = BIP39.validateMnemonic("Enter your mnemonic here")
// This will return false

With this mnemonic, you can generate a seed from which to generate a private key. Add the following line to main.js

function generateHexSeed(mnemonic){
    return BIP39.mnemonicToSeedHex(mnemonic)
}

Generate a Public / Private Keypair

Using this mnemonic as a source of randomness, you can now create signing keypair.

To generate a private key from the hex seed, we will to use the ethereumjs-wallet library. Add the following line to the top of main.js to import the hdkey function.

const hdkey = require('ethereumjs-wallet/hdkey')

Note that the method by which randomness is passed to the private key generator in this demonstration application is different than other common tools such as myetherwallet.com or the Metamask chrome extension. Explore a much more robust address derivation application at iancoleman.io

To generate a private key, create a private key seed from the random mnemonic and feed it to the hdkey.fromMasterSeed() function. Add the following code to main.js.

function generatePrivKey(mnemonic){
    const seed = generateHexSeed(mnemonic)
    return hdkey.fromMasterSeed(seed).derivePath(`m/44'/60'/0'/0`).getWallet().getPrivateKey()
}

With the private key, we can generate the public key. Import the ethereumjs wallet and derive the public key with the following code

// Import the wallet
const Wallet = require('ethereumjs-wallet')

...

// Derive the public key from the private key
function derivePubKey(privKey){
    const wallet = Wallet.fromPrivateKey(privKey)    
    return wallet.getPublicKey()
}

Generating the private key and public key is the same for both Bitcoin and Ethereum, the both use secp256k1 elliptic curve cryptography. Deriving an account address from the public differs slightly. We will see how to generate an Ethereum address.

Derive the Address

Deriving an Ethereum address from a public key requires an additional hashing algorithm. Import it like so

const keccak256 = require('js-sha3').keccak256;

Taking the keccak-256 hash of the public key will return 32 bytes which you need to trim down to the last 20 bytes (40 characters in hex) to get the address the following function should do the trick.

function deriveEthAddress(pubKey){
    const address = keccak256(pubKey) // keccak256 hash of  publicKey
    // Get the last 20 bytes of the public key
    return "0x" + address.substring(address.length - 40, address.length)    
}

You can check this private key and address against myetherwallet. Select restore from private key and verify that the derived address matches the one in this app.

Using your key

Using this private key we can sign transactions from this address and broadcast them to the network.

Nodes that are verifying transactions in the network will use the signature to determine the address of the signatory, cryptographically verifying that every transaction from this account is coming from someone who has access to the corresponding private key.

You can sign transactions in the browser with the ethereumjs-tx library.

// Import the ethereumjs transaction library
const EthereumTx = require('ethereumjs-tx')

...

// Add the following function to enable transaction signing
function signTx(privKey, txData){
    const tx = new EthereumTx(txData)
    tx.sign(privKey)
    return tx
}

You can recover the sender address from the signed transaction with the following function. Add this function to main.js as well.

function getSignerAddress(signedTx){
    return "0x" + signedTx.getSenderAddress().toString('hex')
}

Unsigned Ethereum transactions looks something like this

{
    nonce: '0x00',
    gasPrice: '0x09184e72a000', 
    gasLimit: '0x2710',
    to: '0x31c1c0fec59ceb9cbe6ec474c31c1dc5b66555b6', 
    value: '0x10', 
    data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057',
    chainId: 3
}

And a signed transaction looks something like this

{ 
    nonce: '0x00', 
    gasPrice: '0x09184e72a000', 
    gasLimit: '0x2710', 
    to: '0x31c1c0fec59ceb9cbe6ec474c31c1dc5b66555b6', 
    value: '0x00', 
    data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057', 
    v: '0x29', 
    r: '0xb934fbdb16fda944ddc0cb33e64344b90fbd25564444832f7f8d697512069402',
    s: '0x29' 
}

Notice the main difference is the inclusion of the variables v, r and s. These variables are used to recover the address corresponding to the key that signed the transaction. This signed transaction is broadcast to the network to be included in a block.

Resources

Understanding the concept of private keys, public keys and addresses in Ethereum

Bitcoin wiki on Secp256k1

Ethereum yellow paper

ethereum-address-generator-js's People

Contributors

critesjosh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ethereum-address-generator-js's Issues

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

test issue

This issue has been created to test zenhub

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.