UNPKG

7.35 kBJavaScriptView Raw
1const { assert } = require('../util');
2const format = require('../util/format');
3const sign = require('../util/sign');
4const Account = require('./Account');
5
6class PrivateKeyAccount extends Account {
7 /**
8 * Create a new PrivateKeyAccount with random privateKey.
9 *
10 * @param [entropy] {string|Buffer} - Entropy of random account
11 * @return {PrivateKeyAccount}
12 *
13 * @example
14 * > PrivateKeyAccount.random()
15 PrivateKeyAccount {
16 privateKey: '0xd28edbdb7bbe75787b84c5f525f47666a3274bb06561581f00839645f3c26f66',
17 publicKey: '0xc42b53ae2ef95fee489948d33df391c4a9da31b7a3e29cf772c24eb42f74e94ab3bfe00bf29a239c17786a5b921853b7c5344d36694db43aa849e401f91566a5',
18 address: '0x1cecb4a2922b7007e236daf0c797de6e55496e84'
19 }
20 * > PrivateKeyAccount.random() // gen a different account from above
21 PrivateKeyAccount {
22 privateKey: '0x1b67150f56f49556ef7e3899024d83c125d84990d311ec08fa98aa1433bc0f53',
23 publicKey: '0xd442207828ffd4dad918fea0d75d42dbea1fe5e3789c00a82e18ce8229714eae3f70b12f2f1abd795ad3e5c52a5a597289eb5096548438c233431f498b47b9a6',
24 address: '0x16c25691aadc3363f5862d264072584f3ebf4613'
25 }
26 * > PrivateKeyAccount.random('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
27 PrivateKeyAccount {
28 privateKey: '0x1d41e006afd28ea339922d8ab4be93154a14d4f1b6d0ad4e7aabf807e7536a5f',
29 publicKey: '0x4c07c75d3fdc5b1d6afef6ec374b0eaac86bcaa771a1d536bc4ce6f111b1c60e414b370e4cf31bf7770ae6818a3518c485398a43857d9053153f6eb4f5644a90',
30 address: '0x113d49784c80d6f8fdbc0bef5a5ab0d9c9fee520'
31 }
32 * > PrivateKeyAccount.random('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
33 * // gen a different account from above, even use same entropy
34 PrivateKeyAccount {
35 privateKey: '0x5a34ff3318674c33209ce856218890e9a6ee3811e8a51e3094ed1e6a94bf58ef',
36 publicKey: '0xe530d77c3ed6115cb46ba79821085bf67d2a7a8c808c1d52dec03fd7a82e569c2136dba84b21d40f46d90484722b21a9d5a8038495adf93f2eed564ababa2422',
37 address: '0x1f63fcef4aaa88c03cbb5c9fb34be69dee65d0a8'
38 }
39 */
40 static random(entropy) {
41 const privateKeyBuffer = sign.randomPrivateKey(entropy === undefined ? undefined : format.hexBuffer(entropy));
42 return new this(privateKeyBuffer);
43 }
44
45 /**
46 * Decrypt account encrypt info.
47 *
48 * @param keystore {object} - Keystore version 3 object.
49 * @param password {string|Buffer} - Password for keystore to decrypt with.
50 * @return {PrivateKeyAccount}
51 *
52 * @example
53 * > PrivateKeyAccount.decrypt({
54 version: 3,
55 id: '0bb47ee0-aac3-a006-2717-03877afa15f0',
56 address: '1cad0b19bb29d4674531d6f115237e16afce377c',
57 crypto: {
58 ciphertext: 'a8ec41d2440311ce897bacb6f7942f3235113fa17c4ae6732e032336038a8f73',
59 cipherparams: { iv: '85b5e092c1c32129e3d27df8c581514d' },
60 cipher: 'aes-128-ctr',
61 kdf: 'scrypt',
62 kdfparams: {
63 dklen: 32,
64 salt: 'b662f09bdf6751ac599219732609dceac430bc0629a7906eaa1451555f051ebc',
65 n: 8192,
66 r: 8,
67 p: 1
68 },
69 mac: 'cc89df7ef6c27d284526a65cabf8e5042cdf1ec1aa4ee36dcf65b965fa34843d'
70 }
71 }, 'password');
72 PrivateKeyAccount {
73 address: '0x1cad0b19bb29d4674531d6f115237e16afce377c',
74 publicKey: '0x4646ae5047316b4230d0086c8acec687f00b1cd9d1dc634f6cb358ac0a9a8ffffe77b4dd0a4bfb95851f3b7355c781dd60f8418fc8a65d14907aff47c903a559',
75 privateKey: '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
76 }
77 */
78 static decrypt(keystore, password) {
79 const privateKeyBuffer = sign.decrypt(keystore, password);
80 return new this(privateKeyBuffer);
81 }
82
83 /**
84 * Create a account by privateKey.
85 *
86 * @param privateKey {string|Buffer} - Private key of account
87 * @return {PrivateKeyAccount}
88 *
89 * @example
90 * > new PrivateKeyAccount('0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef')
91 PrivateKeyAccount {
92 address: '0x1cad0b19bb29d4674531d6f115237e16afce377c',
93 publicKey: '0x4646ae5047316b4230d0086c8acec687f00b1cd9d1dc634f6cb358ac0a9a8ffffe77b4dd0a4bfb95851f3b7355c781dd60f8418fc8a65d14907aff47c903a559',
94 privateKey: '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
95 }
96 */
97 constructor(privateKey) {
98 const privateKeyBuffer = format.hexBuffer(privateKey);
99 const publicKeyBuffer = sign.privateKeyToPublicKey(privateKeyBuffer);
100 const addressBuffer = sign.publicKeyToAddress(publicKeyBuffer);
101
102 super(format.address(addressBuffer));
103 this.publicKey = format.publicKey(publicKeyBuffer);
104 this.privateKey = format.privateKey(privateKeyBuffer);
105 }
106
107 /**
108 * Encrypt account privateKey to object.
109 *
110 * @param password {string}
111 * @return {object} - keystoreV3 object
112 *
113 * @example
114 * > account = new PrivateKeyAccount('0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef')
115 * > account.encrypt('password')
116 {version:3, id:..., address:..., crypto:...}
117 */
118 encrypt(password) {
119 return sign.encrypt(format.hexBuffer(this.privateKey), password);
120 }
121
122 /**
123 * Sign a transaction.
124 *
125 * @param options {object} - See [Transaction](Transaction.js/constructor)
126 * @return {Promise<Transaction>}
127 *
128 * @example
129 * > account = new PrivateKeyAccount('0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef')
130 * > transaction = account.signTransaction({
131 nonce: 0,
132 gasPrice: 100,
133 gas: 10000,
134 storageLimit: 10000,
135 epochHeight: 100,
136 chainId: 0,
137 })
138
139 Transaction {
140 from: '0x1cad0b19bb29d4674531d6f115237e16afce377c',
141 nonce: 0,
142 gasPrice: 100,
143 gas: 10000,
144 to: undefined,
145 value: undefined,
146 storageLimit: 10000,
147 epochHeight: 100,
148 chainId: 0,
149 data: undefined,
150 v: 0,
151 r: '0x096f4e00ac15f6bd6e09937e99f0e54aaa2dd0f4c6bd8421e1e81b0e8bd30723',
152 s: '0x41e63a41ede0cbb8ccfaa827423c654dcdc09fb1aa1c3a7233566544aff4cd9a'
153 }
154 */
155 async signTransaction(options) {
156 const transaction = await super.signTransaction(options);
157 transaction.sign(this.privateKey); // sign will cover r,s,v fields
158
159 assert(transaction.from === this.address, {
160 message: 'Invalid sign transaction.from',
161 expected: this.address,
162 got: transaction.from,
163 });
164
165 return transaction;
166 }
167
168 /**
169 * Sign a string.
170 *
171 * @param options {string}
172 * @return {Promise<Message>}
173 *
174 * @example
175 * > account = new PrivateKeyAccount('0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef')
176 * > message = account.signMessage('Hello World')
177 Message {
178 message: 'Hello World',
179 signature: '0x6e913e2b76459f19ebd269b82b51a70e912e909b2f5c002312efc27bcc280f3c29134d382aad0dbd3f0ccc9f0eb8f1dbe3f90141d81574ebb6504156b0d7b95f01'
180 }
181 */
182 async signMessage(options) {
183 const message = await super.signMessage(options);
184 message.sign(this.privateKey); // sign will cover r,s,v fields
185
186 assert(message.from === this.address, {
187 message: 'Invalid sign message.from',
188 expected: this.address,
189 got: message.from,
190 });
191
192 return message;
193 }
194}
195
196module.exports = PrivateKeyAccount;