UNPKG

cipher-ethereum

Version:

An Ethereum library used by Cipher Browser, a mobile Ethereum client

106 lines (91 loc) 2.56 kB
import * as rlp from 'rlp' import BN from 'bn.js' import { bnToBuffer, hexToBuffer, keccak256, numberToBuffer } from './util' import { ec as EC } from 'elliptic' const secp256k1 = new EC('secp256k1') export interface TransactionParams { nonce: number gasPriceWei: BN gasLimit: BN toAddress?: string | null valueWei: BN data?: string | null chainId?: number v?: number r?: string s?: string } export class Transaction { private nonce: Buffer private gasPriceWei: Buffer private gasLimit: Buffer private toAddress: Buffer private valueWei: Buffer // in wei private data: Buffer private chainId?: number private v: number private r: Buffer private s: Buffer constructor (params: TransactionParams) { this.nonce = numberToBuffer(params.nonce) this.gasPriceWei = bnToBuffer(params.gasPriceWei) this.gasLimit = bnToBuffer(params.gasLimit) this.toAddress = params.toAddress ? hexToBuffer(params.toAddress) : Buffer.alloc(0) this.valueWei = bnToBuffer(params.valueWei) this.data = params.data ? hexToBuffer(params.data) : Buffer.alloc(0) this.chainId = params.chainId ? params.chainId : undefined // disallow 0 this.v = params.v || 28 this.r = params.r ? hexToBuffer(params.r) : Buffer.alloc(0) this.s = params.s ? hexToBuffer(params.s) : Buffer.alloc(0) } get fields (): Buffer[] { return [ this.nonce, // 0: nonce this.gasPriceWei, // 1: gas price this.gasLimit, // 2: gas limit this.toAddress, // 3: to this.valueWei, // 4: value this.data, // 5: data numberToBuffer(this.v), // 6: v this.r, // 7: r this.s // 8: s ] } get rlp (): Buffer { return rlp.encode(this.fields) } get hash (): Buffer { return keccak256(this.rlp) } get fieldsForSigning (): Buffer[] { const fields = this.fields.slice(0, 6) return this.chainId ? fields.concat([ // EIP155 numberToBuffer(this.chainId), // 6: v = chainID numberToBuffer(0), // 7: r = 0 numberToBuffer(0) // 8: s = 0 ]) : fields } get hashForSigning (): Buffer { return keccak256(rlp.encode(this.fieldsForSigning)) } sign (privateKey: Buffer): Buffer { const sig = secp256k1 .keyFromPrivate(privateKey) .sign(this.hashForSigning, { canonical: true }) this.v = (sig.recoveryParam || 0) + 27 + (this.chainId ? this.chainId * 2 + 8 : 0) this.r = bnToBuffer(sig.r) this.s = bnToBuffer(sig.s) return this.rlp } }