UNPKG

11.9 kBJavaScriptView Raw
1"use strict";
2var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 if (k2 === undefined) k2 = k;
4 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5}) : (function(o, m, k, k2) {
6 if (k2 === undefined) k2 = k;
7 o[k2] = m[k];
8}));
9var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10 Object.defineProperty(o, "default", { enumerable: true, value: v });
11}) : function(o, v) {
12 o["default"] = v;
13});
14var __importStar = (this && this.__importStar) || function (mod) {
15 if (mod && mod.__esModule) return mod;
16 var result = {};
17 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18 __setModuleDefault(result, mod);
19 return result;
20};
21var __importDefault = (this && this.__importDefault) || function (mod) {
22 return (mod && mod.__esModule) ? mod : { "default": mod };
23};
24Object.defineProperty(exports, "__esModule", { value: true });
25exports.isZeroAddress = exports.zeroAddress = exports.importPublic = exports.privateToAddress = exports.privateToPublic = exports.publicToAddress = exports.pubToAddress = exports.isValidPublic = exports.isValidPrivate = exports.generateAddress2 = exports.generateAddress = exports.isValidChecksumAddress = exports.toChecksumAddress = exports.isValidAddress = exports.Account = void 0;
26const assert_1 = __importDefault(require("assert"));
27const bn_js_1 = __importDefault(require("bn.js"));
28const rlp = __importStar(require("rlp"));
29const secp256k1_1 = require("ethereum-cryptography/secp256k1");
30const internal_1 = require("./internal");
31const constants_1 = require("./constants");
32const bytes_1 = require("./bytes");
33const hash_1 = require("./hash");
34const helpers_1 = require("./helpers");
35const types_1 = require("./types");
36class Account {
37 /**
38 * This constructor assigns and validates the values.
39 * Use the static factory methods to assist in creating an Account from varying data types.
40 */
41 constructor(nonce = new bn_js_1.default(0), balance = new bn_js_1.default(0), stateRoot = constants_1.KECCAK256_RLP, codeHash = constants_1.KECCAK256_NULL) {
42 this.nonce = nonce;
43 this.balance = balance;
44 this.stateRoot = stateRoot;
45 this.codeHash = codeHash;
46 this._validate();
47 }
48 static fromAccountData(accountData) {
49 const { nonce, balance, stateRoot, codeHash } = accountData;
50 return new Account(nonce ? new bn_js_1.default((0, bytes_1.toBuffer)(nonce)) : undefined, balance ? new bn_js_1.default((0, bytes_1.toBuffer)(balance)) : undefined, stateRoot ? (0, bytes_1.toBuffer)(stateRoot) : undefined, codeHash ? (0, bytes_1.toBuffer)(codeHash) : undefined);
51 }
52 static fromRlpSerializedAccount(serialized) {
53 const values = rlp.decode(serialized);
54 if (!Array.isArray(values)) {
55 throw new Error('Invalid serialized account input. Must be array');
56 }
57 return this.fromValuesArray(values);
58 }
59 static fromValuesArray(values) {
60 const [nonce, balance, stateRoot, codeHash] = values;
61 return new Account(new bn_js_1.default(nonce), new bn_js_1.default(balance), stateRoot, codeHash);
62 }
63 _validate() {
64 if (this.nonce.lt(new bn_js_1.default(0))) {
65 throw new Error('nonce must be greater than zero');
66 }
67 if (this.balance.lt(new bn_js_1.default(0))) {
68 throw new Error('balance must be greater than zero');
69 }
70 if (this.stateRoot.length !== 32) {
71 throw new Error('stateRoot must have a length of 32');
72 }
73 if (this.codeHash.length !== 32) {
74 throw new Error('codeHash must have a length of 32');
75 }
76 }
77 /**
78 * Returns a Buffer Array of the raw Buffers for the account, in order.
79 */
80 raw() {
81 return [
82 (0, types_1.bnToUnpaddedBuffer)(this.nonce),
83 (0, types_1.bnToUnpaddedBuffer)(this.balance),
84 this.stateRoot,
85 this.codeHash,
86 ];
87 }
88 /**
89 * Returns the RLP serialization of the account as a `Buffer`.
90 */
91 serialize() {
92 return rlp.encode(this.raw());
93 }
94 /**
95 * Returns a `Boolean` determining if the account is a contract.
96 */
97 isContract() {
98 return !this.codeHash.equals(constants_1.KECCAK256_NULL);
99 }
100 /**
101 * Returns a `Boolean` determining if the account is empty complying to the definition of
102 * account emptiness in [EIP-161](https://eips.ethereum.org/EIPS/eip-161):
103 * "An account is considered empty when it has no code and zero nonce and zero balance."
104 */
105 isEmpty() {
106 return this.balance.isZero() && this.nonce.isZero() && this.codeHash.equals(constants_1.KECCAK256_NULL);
107 }
108}
109exports.Account = Account;
110/**
111 * Checks if the address is a valid. Accepts checksummed addresses too.
112 */
113const isValidAddress = function (hexAddress) {
114 try {
115 (0, helpers_1.assertIsString)(hexAddress);
116 }
117 catch (e) {
118 return false;
119 }
120 return /^0x[0-9a-fA-F]{40}$/.test(hexAddress);
121};
122exports.isValidAddress = isValidAddress;
123/**
124 * Returns a checksummed address.
125 *
126 * If an eip1191ChainId is provided, the chainId will be included in the checksum calculation. This
127 * has the effect of checksummed addresses for one chain having invalid checksums for others.
128 * For more details see [EIP-1191](https://eips.ethereum.org/EIPS/eip-1191).
129 *
130 * WARNING: Checksums with and without the chainId will differ and the EIP-1191 checksum is not
131 * backwards compatible to the original widely adopted checksum format standard introduced in
132 * [EIP-55](https://eips.ethereum.org/EIPS/eip-55), so this will break in existing applications.
133 * Usage of this EIP is therefore discouraged unless you have a very targeted use case.
134 */
135const toChecksumAddress = function (hexAddress, eip1191ChainId) {
136 (0, helpers_1.assertIsHexString)(hexAddress);
137 const address = (0, internal_1.stripHexPrefix)(hexAddress).toLowerCase();
138 let prefix = '';
139 if (eip1191ChainId) {
140 const chainId = (0, types_1.toType)(eip1191ChainId, types_1.TypeOutput.BN);
141 prefix = chainId.toString() + '0x';
142 }
143 const hash = (0, hash_1.keccakFromString)(prefix + address).toString('hex');
144 let ret = '0x';
145 for (let i = 0; i < address.length; i++) {
146 if (parseInt(hash[i], 16) >= 8) {
147 ret += address[i].toUpperCase();
148 }
149 else {
150 ret += address[i];
151 }
152 }
153 return ret;
154};
155exports.toChecksumAddress = toChecksumAddress;
156/**
157 * Checks if the address is a valid checksummed address.
158 *
159 * See toChecksumAddress' documentation for details about the eip1191ChainId parameter.
160 */
161const isValidChecksumAddress = function (hexAddress, eip1191ChainId) {
162 return (0, exports.isValidAddress)(hexAddress) && (0, exports.toChecksumAddress)(hexAddress, eip1191ChainId) === hexAddress;
163};
164exports.isValidChecksumAddress = isValidChecksumAddress;
165/**
166 * Generates an address of a newly created contract.
167 * @param from The address which is creating this new address
168 * @param nonce The nonce of the from account
169 */
170const generateAddress = function (from, nonce) {
171 (0, helpers_1.assertIsBuffer)(from);
172 (0, helpers_1.assertIsBuffer)(nonce);
173 const nonceBN = new bn_js_1.default(nonce);
174 if (nonceBN.isZero()) {
175 // in RLP we want to encode null in the case of zero nonce
176 // read the RLP documentation for an answer if you dare
177 return (0, hash_1.rlphash)([from, null]).slice(-20);
178 }
179 // Only take the lower 160bits of the hash
180 return (0, hash_1.rlphash)([from, Buffer.from(nonceBN.toArray())]).slice(-20);
181};
182exports.generateAddress = generateAddress;
183/**
184 * Generates an address for a contract created using CREATE2.
185 * @param from The address which is creating this new address
186 * @param salt A salt
187 * @param initCode The init code of the contract being created
188 */
189const generateAddress2 = function (from, salt, initCode) {
190 (0, helpers_1.assertIsBuffer)(from);
191 (0, helpers_1.assertIsBuffer)(salt);
192 (0, helpers_1.assertIsBuffer)(initCode);
193 (0, assert_1.default)(from.length === 20);
194 (0, assert_1.default)(salt.length === 32);
195 const address = (0, hash_1.keccak256)(Buffer.concat([Buffer.from('ff', 'hex'), from, salt, (0, hash_1.keccak256)(initCode)]));
196 return address.slice(-20);
197};
198exports.generateAddress2 = generateAddress2;
199/**
200 * Checks if the private key satisfies the rules of the curve secp256k1.
201 */
202const isValidPrivate = function (privateKey) {
203 return (0, secp256k1_1.privateKeyVerify)(privateKey);
204};
205exports.isValidPrivate = isValidPrivate;
206/**
207 * Checks if the public key satisfies the rules of the curve secp256k1
208 * and the requirements of Ethereum.
209 * @param publicKey The two points of an uncompressed key, unless sanitize is enabled
210 * @param sanitize Accept public keys in other formats
211 */
212const isValidPublic = function (publicKey, sanitize = false) {
213 (0, helpers_1.assertIsBuffer)(publicKey);
214 if (publicKey.length === 64) {
215 // Convert to SEC1 for secp256k1
216 return (0, secp256k1_1.publicKeyVerify)(Buffer.concat([Buffer.from([4]), publicKey]));
217 }
218 if (!sanitize) {
219 return false;
220 }
221 return (0, secp256k1_1.publicKeyVerify)(publicKey);
222};
223exports.isValidPublic = isValidPublic;
224/**
225 * Returns the ethereum address of a given public key.
226 * Accepts "Ethereum public keys" and SEC1 encoded keys.
227 * @param pubKey The two points of an uncompressed key, unless sanitize is enabled
228 * @param sanitize Accept public keys in other formats
229 */
230const pubToAddress = function (pubKey, sanitize = false) {
231 (0, helpers_1.assertIsBuffer)(pubKey);
232 if (sanitize && pubKey.length !== 64) {
233 pubKey = Buffer.from((0, secp256k1_1.publicKeyConvert)(pubKey, false).slice(1));
234 }
235 (0, assert_1.default)(pubKey.length === 64);
236 // Only take the lower 160bits of the hash
237 return (0, hash_1.keccak)(pubKey).slice(-20);
238};
239exports.pubToAddress = pubToAddress;
240exports.publicToAddress = exports.pubToAddress;
241/**
242 * Returns the ethereum public key of a given private key.
243 * @param privateKey A private key must be 256 bits wide
244 */
245const privateToPublic = function (privateKey) {
246 (0, helpers_1.assertIsBuffer)(privateKey);
247 // skip the type flag and use the X, Y points
248 return Buffer.from((0, secp256k1_1.publicKeyCreate)(privateKey, false)).slice(1);
249};
250exports.privateToPublic = privateToPublic;
251/**
252 * Returns the ethereum address of a given private key.
253 * @param privateKey A private key must be 256 bits wide
254 */
255const privateToAddress = function (privateKey) {
256 return (0, exports.publicToAddress)((0, exports.privateToPublic)(privateKey));
257};
258exports.privateToAddress = privateToAddress;
259/**
260 * Converts a public key to the Ethereum format.
261 */
262const importPublic = function (publicKey) {
263 (0, helpers_1.assertIsBuffer)(publicKey);
264 if (publicKey.length !== 64) {
265 publicKey = Buffer.from((0, secp256k1_1.publicKeyConvert)(publicKey, false).slice(1));
266 }
267 return publicKey;
268};
269exports.importPublic = importPublic;
270/**
271 * Returns the zero address.
272 */
273const zeroAddress = function () {
274 const addressLength = 20;
275 const addr = (0, bytes_1.zeros)(addressLength);
276 return (0, bytes_1.bufferToHex)(addr);
277};
278exports.zeroAddress = zeroAddress;
279/**
280 * Checks if a given address is the zero address.
281 */
282const isZeroAddress = function (hexAddress) {
283 try {
284 (0, helpers_1.assertIsString)(hexAddress);
285 }
286 catch (e) {
287 return false;
288 }
289 const zeroAddr = (0, exports.zeroAddress)();
290 return zeroAddr === hexAddress;
291};
292exports.isZeroAddress = isZeroAddress;
293//# sourceMappingURL=account.js.map
\No newline at end of file