The goal of this project is to provide a light-weight minimal library to sign (and verify) raw Ethereum transactions.
npm install --save '@warren-bank/ethereumjs-tx-sign'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 MB24.9 MBon disk (ext4)
Clean installation of this module results in a node_modules directory that is:
333.5 KB640.0 KBon disk (ext4)
{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
rawDatain the field corresponding to "v"
(ie: thesignature recoveryshares its field with thechainId); consequently,
value is stored inrawTx
- type: native
- "chainId":
- privateKey
- type: String
- format: hex-encoded (with or without '0x' prefix)
- txData
- 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
- 7th: Buffer containing
- if
- note:
- type: String
- format: hex-encoded (without '0x' prefix)
- description: sha3 hash of RLP encoded Array containing the first 6 elements of rawData
- 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)
- rawData
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')
- type:
- publicKey
- type: String
- format: hex-encoded (with or without '0x' prefix)
- msgHash
- returns:
- Boolean
- indicates whether the
signaturecan be verified for themsgHashusing thepublicKeytrueindicates that thesignaturewas originally created using the (unavailable)privateKeythat is paired to the (available)publicKeyfalseindicates that it was not
- indicates whether the
- Boolean
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
- type:
- rawTx
- 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
- type: native
- "chainId":
- 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)
- txData
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
txDataand (optionally)signaturefromrawTx - it doesn't include any external dependencies and (consequently) lacks the ability to calculate
publicKeyandaddressfromsignature
- exports a variation of the function:
{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)
- privateKey
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
- type:
- compressed
- description
- type: Boolean
- default: false
- privateKey
- returns:
- publicKey
- type: String
- format: hex-encoded (without '0x' prefix)
- publicKey
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
- type:
- publicKey
- returns:
- address
- type: String
- format: hex-encoded (without '0x' prefix)
- address
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
- any value that can be converted to a Buffer:
rlp.toBuffer(value)
- any value that can be converted to a Buffer:
- bits
- type: Number
- supported values include:
224, 256, 384, 512 - default: 256
- value
- returns:
- hash
- type: String
- format: hex-encoded (without '0x' prefix)
- hash
Example:
const {sha3} = require('@warren-bank/ethereumjs-tx-sign/lib/keccak')
{
let hash = sha3('hello world')
}<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>
- elliptic
- is a dependency of this module
- is the work-horse that makes all of this possible