Skip to content

blitslabs/ethereumjs-tx-sign

 
 

Repository files navigation

Description:

The goal of this project is to provide a light-weight minimal library to sign (and verify) raw Ethereum transactions.

Installation:

npm install --save '@warren-bank/ethereumjs-tx-sign'

Background:

ethereumjs-tx is the de-facto library used to sign raw transactions.

Clean installation of the ethereumjs-tx module results in a node_modules directory that is:

  • 10.4 MB
  • 24.9 MB on disk (ext4)

Clean installation of this module results in a node_modules directory that is:

  • 333.5 KB
  • 640.0 KB on disk (ext4)

API:

{rawData, msgHash, DER, signature, rawTx} = sign(txData, privateKey)

  • params:
    • txData
      • type: Object
      • keys can include: "nonce","gasPrice","gasLimit","to","value","data","chainId"
      • values:
        • type: String
        • format: hex-encoded (with '0x' prefix)
        • more generally: any value that can be converted to a Buffer: rlp.toBuffer(value)
        • exceptions:
          • "chainId":
            • type: native Number
            • notes:
              • EIP 155
              • value is used to modify msgHash
              • value is stored in rawData in the field corresponding to "v"
                (ie: the signature recovery shares its field with the chainId); consequently,
                value is stored in rawTx
    • privateKey
      • type: String
      • format: hex-encoded (with or without '0x' prefix)
  • returns:
    • rawData
      • type: Array of Buffers
      • length: 9
      • values (and order) correspond to the data fields: "nonce","gasPrice","gasLimit","to","value","data","v","r","s"
    • msgHash
      • description: sha3 hash of RLP encoded Array containing the first 6 elements of rawData
        • note:
          • if chainId > 0: Array is extended to 9 elements
            • 7th: Buffer containing chainId
            • 8th and 9th: zero-length Buffers
      • type: String
      • format: hex-encoded (without '0x' prefix)
    • DER
      • description: DER encoded signature
      • type: Array of Number
      • format: each Number is an Integer in the range [0..255] and represents a single Byte
    • signature
      • Buffer
      • length: 64 Bytes
      • contents: rawData.r (32 Bytes) + rawData.s (32 Bytes)
    • rawTx
      • description: RLP encoded rawData
      • type: String
      • format: hex-encoded (without '0x' prefix)

Example:

const {sign} = require('@warren-bank/ethereumjs-tx-sign')

const txData = {
  nonce:    '0x00',
  gasPrice: '0x6fc23ac00',
  gasLimit: '0x2710',
//to:       '0x00',
  value:    '0x00',
  data:     '0x7f7465737432000000000000000000000000000000000000000000000000000000600057',
  chainId:  1
}

const privateKey = 'e922354a3e5902b5ac474f3ff08a79cff43533826b8f451ae2190b65a9d26158'

const {rawTx} = sign(txData, privateKey)

const Web3 = require('web3')
const web3 = new Web3()
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'))

web3.eth.sendRawTransaction(rawTx, function(err, hash) {
  if (err)
    console.log('error:', err.message)
  if ((!err) && hash)
    console.log('transaction hash:', hash)
})

More Complete Example:


verify(msgHash, signature, publicKey)

  • params:
    • msgHash
      • type: String
      • format: hex-encoded (without '0x' prefix)
    • signature
      • type:
        • Buffer: length of 64 Bytes
        • Object: {r, s}
          • r: Buffer w/ length of 32 Bytes
          • s: Buffer w/ length of 32 Bytes
        • (DER encoded) Array of Number
        • (DER encoded) String: hex-encoded (without '0x' prefix):
          let DER_string = require('elliptic').utils.encode(DER, 'hex')
    • publicKey
      • type: String
      • format: hex-encoded (with or without '0x' prefix)
  • returns:
    • Boolean
      • indicates whether the signature can be verified for the msgHash using the publicKey
        • true indicates that the signature was originally created using the (unavailable) privateKey that is paired to the (available) publicKey
        • false indicates that it was not

Example:

// continuation of the previous example:

const {verify} = require('@warren-bank/ethereumjs-tx-sign')

{
  let {msgHash, signature} = sign(txData, privateKey)

  let publicKey = '0493ff3bd23838a02f24adcb23aa90bf2de8becbd1abe688e0f6a3202bee2cc4c2ecf7cd2608cda0817d6223f81bed074f166b8b55de54d603817699b4c70feaac'

  let result = verify(msgHash, signature, publicKey)
}

More Complete Example:


{txData, signature, msgHash, publicKey, address} = unsign(rawTx)

  • params:
    • rawTx
      • type:
        • String: hex-encoded (with or without '0x' prefix)
        • Buffer
  • returns:
    • txData
      • type: Object
      • keys: "nonce","gasPrice","gasLimit","to","value","data","chainId"
      • values:
        • type: String
        • format: hex-encoded (with '0x' prefix)
        • exceptions:
          • "chainId":
            • type: native Number
    • signature
      • type: Object
      • keys: "r","s"
      • values:
        • type: String
        • format: hex-encoded (without '0x' prefix)
    • msgHash
      • type: String
      • format: hex-encoded (without '0x' prefix)
    • publicKey
      • type: String
      • format: hex-encoded (without '0x' prefix)
    • address
      • description: "from" address … seen by network as the sender of this signed transaction
      • type: String
      • format: hex-encoded (without '0x' prefix)

Example:

// continuation of the previous example:

const {unsign} = require('@warren-bank/ethereumjs-tx-sign')

{
  let {txData, msgHash, signature, publicKey} = unsign(rawTx)

  let result = verify(msgHash, signature, publicKey)
}

More Complete Example:

Related:

  • ethereumjs-tx-unsign
    • exports a variation of the function: unsign()
    • it is a minimal library to retrieve txData and (optionally) signature from rawTx
    • it doesn't include any external dependencies and (consequently) lacks the ability to calculate publicKey and address from signature

Bonus (Internal Library) APIs:

{privateKey, publicKey, address} = genKeyPair()

  • returns:
    • privateKey
      • type: String
      • format: hex-encoded (without '0x' prefix)
    • publicKey
      • type: String
      • format: hex-encoded (without '0x' prefix)
    • address
      • type: String
      • format: hex-encoded (without '0x' prefix)

Example:

const {genKeyPair} = require('@warren-bank/ethereumjs-tx-sign/lib/keypairs')

const {privateKey, publicKey, address} = genKeyPair()

console.log({privateKey, publicKey, address})

Output:

{
  privateKey: 'e922354a3e5902b5ac474f3ff08a79cff43533826b8f451ae2190b65a9d26158',
  publicKey:  '0493ff3bd23838a02f24adcb23aa90bf2de8becbd1abe688e0f6a3202bee2cc4c2ecf7cd2608cda0817d6223f81bed074f166b8b55de54d603817699b4c70feaac',
  address:    'f95abdf6ede4c3703e0e9453771fbee8592d31e9'
}

More Complete Example:


publicKey = privateToPublic(privateKey, compressed)

  • params:
    • privateKey
      • type:
        • String: hex-encoded (with or without '0x' prefix)
        • Buffer
    • compressed
  • returns:
    • publicKey
      • type: String
      • format: hex-encoded (without '0x' prefix)

Example:

// continuation of the previous example:

const {privateToPublic} = require('@warren-bank/ethereumjs-tx-sign/lib/keypairs')

{
  let pubKey = privateToPublic(privateKey)

  assert(pubKey === publicKey)
}

address = publicToAddress(publicKey)

  • params:
    • publicKey
      • type:
        • String: hex-encoded (with or without '0x' prefix)
        • Buffer
  • returns:
    • address
      • type: String
      • format: hex-encoded (without '0x' prefix)

Example:

// continuation of the previous example:

const {publicToAddress} = require('@warren-bank/ethereumjs-tx-sign/lib/keypairs')

{
  let addr = publicToAddress(publicKey)

  assert(addr === address)
}

hash = sha3(value, bits)

  • params:
    • value
    • bits
      • type: Number
      • supported values include: 224, 256, 384, 512
      • default: 256
  • returns:
    • hash
      • type: String
      • format: hex-encoded (without '0x' prefix)

Example:

const {sha3} = require('@warren-bank/ethereumjs-tx-sign/lib/keccak')

{
  let hash = sha3('hello world')
}

Browser Bundle:

<script src="./browser-build/dist/js/bundle.js"></script>
<script>
{
  let Buffer = window.Buffer

  let BN = window.BN

  let {sign, verify, unsign} = window.ethereumjs_tx_sign

  let {privateToPublic, publicToAddress, genKeyPair} = window.ethereumjs_tx_sign.keypairs

  let {encode, isHexPrefixed, stripHexPrefix, stripZeros, intToHex, padToEven, intToBuffer, toBuffer, bufferToHex, bufferToInt} = window.ethereumjs_tx_sign.rlp

  let {createKeccakHash, sha3} = window.ethereumjs_tx_sign.keccak
}
</script>

Hosted Tests:


Credits (mostly) Belong To:

Special Thanks To:

  • elliptic
    • is a dependency of this module
    • is the work-horse that makes all of this possible

About

minimal library to sign (and verify) raw Ethereum transactions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 96.2%
  • Shell 2.8%
  • HTML 1.0%