UNPKG

3.25 kBJavaScriptView Raw
1const { sha3, ecdsaSign, ecdsaRecover, publicKeyToAddress, rlpEncode } = require('./util/sign');
2const format = require('./util/format');
3
4class Transaction {
5 /**
6 * Create a transaction.
7 *
8 * @param options {object}
9 * @param options.nonce {string|number} - This allows to overwrite your own pending transactions that use the same nonce.
10 * @param options.gasPrice {string|number|BigNumber} - The price of gas for this transaction in drip.
11 * @param options.gas {string|number} - The amount of gas to use for the transaction (unused gas is refunded).
12 * @param [options.to=null] {string} - The destination address of the message, left undefined for a contract-creation transaction.
13 * @param [options.value=0] {string|number|BigNumber} - The value transferred for the transaction in drip, also the endowment if it’s a contract-creation transaction.
14 * @param [options.data='0x'] {string|Buffer} - Either a ABI byte string containing the data of the function call on a contract, or in the case of a contract-creation transaction the initialisation code.
15 * @param [options.r] {string|Buffer} - ECDSA signature r
16 * @param [options.s] {string|Buffer} - ECDSA signature s
17 * @param [options.v] {number} - ECDSA recovery id
18 * @return {Transaction}
19 */
20 constructor({ nonce, gasPrice, gas, to, value, data, v, r, s }) {
21 Object.assign(this, { nonce, gasPrice, gas, to, value, data, v, r, s });
22 }
23
24 /**
25 * Getter of transaction hash include signature.
26 *
27 * > Note: calculate every time.
28 *
29 * @return {string|undefined} If transaction has r,s,v return hex string, else return undefined.
30 */
31 get hash() {
32 try {
33 return format.hex(sha3(this.encode(true)));
34 } catch (e) {
35 return undefined;
36 }
37 }
38
39 /**
40 * Getter of sender address.
41 *
42 * > Note: calculate every time.
43 *
44 * @return {string|undefined} If ECDSA recover success return address, else return undefined.
45 */
46 get from() {
47 try {
48 const publicKey = ecdsaRecover(sha3(this.encode(false)), {
49 r: format.buffer(this.r),
50 s: format.buffer(this.s),
51 v: format.uint(this.v),
52 });
53 return format.hex(publicKeyToAddress(publicKey));
54 } catch (e) {
55 return undefined;
56 }
57 }
58
59 /**
60 * Sign transaction and set 'r','s','v'.
61 *
62 * @param privateKey {string} - Private key hex string.
63 */
64 sign(privateKey) {
65 const { r, s, v } = ecdsaSign(sha3(this.encode(false)), format.buffer(privateKey));
66 Object.assign(this, { r, s, v });
67 }
68
69 /**
70 * Encode rlp.
71 *
72 * @param [includeSignature=false] {boolean} - Whether or not to include the signature.
73 * @return {Buffer}
74 */
75 encode(includeSignature = false) {
76 const { nonce, gasPrice, gas, to, value, data, v, r, s } = format.signTx(this);
77
78 const raw = includeSignature
79 ? [nonce, gasPrice, gas, to, value, data, v, r, s]
80 : [nonce, gasPrice, gas, to, value, data];
81
82 return rlpEncode(raw.map(format.buffer));
83 }
84
85 /**
86 * Get the raw tx hex string.
87 *
88 * @return {Buffer}
89 */
90 serialize() {
91 return format.hex(this.encode(true));
92 }
93}
94
95module.exports = Transaction;