UNPKG

ethereumjs-util

Version:
296 lines 12 kB
"use strict"; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.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; var assert_1 = __importDefault(require("assert")); var externals_1 = require("./externals"); var secp256k1_1 = require("ethereum-cryptography/secp256k1"); var internal_1 = require("./internal"); var constants_1 = require("./constants"); var bytes_1 = require("./bytes"); var hash_1 = require("./hash"); var helpers_1 = require("./helpers"); var types_1 = require("./types"); var Account = /** @class */ (function () { /** * This constructor assigns and validates the values. * Use the static factory methods to assist in creating an Account from varying data types. */ function Account(nonce, balance, stateRoot, codeHash) { if (nonce === void 0) { nonce = new externals_1.BN(0); } if (balance === void 0) { balance = new externals_1.BN(0); } if (stateRoot === void 0) { stateRoot = constants_1.KECCAK256_RLP; } if (codeHash === void 0) { codeHash = constants_1.KECCAK256_NULL; } this.nonce = nonce; this.balance = balance; this.stateRoot = stateRoot; this.codeHash = codeHash; this._validate(); } Account.fromAccountData = function (accountData) { var nonce = accountData.nonce, balance = accountData.balance, stateRoot = accountData.stateRoot, codeHash = accountData.codeHash; return new Account(nonce ? new externals_1.BN((0, bytes_1.toBuffer)(nonce)) : undefined, balance ? new externals_1.BN((0, bytes_1.toBuffer)(balance)) : undefined, stateRoot ? (0, bytes_1.toBuffer)(stateRoot) : undefined, codeHash ? (0, bytes_1.toBuffer)(codeHash) : undefined); }; Account.fromRlpSerializedAccount = function (serialized) { var values = externals_1.rlp.decode(serialized); if (!Array.isArray(values)) { throw new Error('Invalid serialized account input. Must be array'); } return this.fromValuesArray(values); }; Account.fromValuesArray = function (values) { var _a = __read(values, 4), nonce = _a[0], balance = _a[1], stateRoot = _a[2], codeHash = _a[3]; return new Account(new externals_1.BN(nonce), new externals_1.BN(balance), stateRoot, codeHash); }; Account.prototype._validate = function () { if (this.nonce.lt(new externals_1.BN(0))) { throw new Error('nonce must be greater than zero'); } if (this.balance.lt(new externals_1.BN(0))) { throw new Error('balance must be greater than zero'); } if (this.stateRoot.length !== 32) { throw new Error('stateRoot must have a length of 32'); } if (this.codeHash.length !== 32) { throw new Error('codeHash must have a length of 32'); } }; /** * Returns a Buffer Array of the raw Buffers for the account, in order. */ Account.prototype.raw = function () { return [ (0, types_1.bnToUnpaddedBuffer)(this.nonce), (0, types_1.bnToUnpaddedBuffer)(this.balance), this.stateRoot, this.codeHash, ]; }; /** * Returns the RLP serialization of the account as a `Buffer`. */ Account.prototype.serialize = function () { return externals_1.rlp.encode(this.raw()); }; /** * Returns a `Boolean` determining if the account is a contract. */ Account.prototype.isContract = function () { return !this.codeHash.equals(constants_1.KECCAK256_NULL); }; /** * Returns a `Boolean` determining if the account is empty complying to the definition of * account emptiness in [EIP-161](https://eips.ethereum.org/EIPS/eip-161): * "An account is considered empty when it has no code and zero nonce and zero balance." */ Account.prototype.isEmpty = function () { return this.balance.isZero() && this.nonce.isZero() && this.codeHash.equals(constants_1.KECCAK256_NULL); }; return Account; }()); exports.Account = Account; /** * Checks if the address is a valid. Accepts checksummed addresses too. */ var isValidAddress = function (hexAddress) { try { (0, helpers_1.assertIsString)(hexAddress); } catch (e) { return false; } return /^0x[0-9a-fA-F]{40}$/.test(hexAddress); }; exports.isValidAddress = isValidAddress; /** * Returns a checksummed address. * * If an eip1191ChainId is provided, the chainId will be included in the checksum calculation. This * has the effect of checksummed addresses for one chain having invalid checksums for others. * For more details see [EIP-1191](https://eips.ethereum.org/EIPS/eip-1191). * * WARNING: Checksums with and without the chainId will differ and the EIP-1191 checksum is not * backwards compatible to the original widely adopted checksum format standard introduced in * [EIP-55](https://eips.ethereum.org/EIPS/eip-55), so this will break in existing applications. * Usage of this EIP is therefore discouraged unless you have a very targeted use case. */ var toChecksumAddress = function (hexAddress, eip1191ChainId) { (0, helpers_1.assertIsHexString)(hexAddress); var address = (0, internal_1.stripHexPrefix)(hexAddress).toLowerCase(); var prefix = ''; if (eip1191ChainId) { var chainId = (0, types_1.toType)(eip1191ChainId, types_1.TypeOutput.BN); prefix = chainId.toString() + '0x'; } var hash = (0, hash_1.keccakFromString)(prefix + address).toString('hex'); var ret = '0x'; for (var i = 0; i < address.length; i++) { if (parseInt(hash[i], 16) >= 8) { ret += address[i].toUpperCase(); } else { ret += address[i]; } } return ret; }; exports.toChecksumAddress = toChecksumAddress; /** * Checks if the address is a valid checksummed address. * * See toChecksumAddress' documentation for details about the eip1191ChainId parameter. */ var isValidChecksumAddress = function (hexAddress, eip1191ChainId) { return (0, exports.isValidAddress)(hexAddress) && (0, exports.toChecksumAddress)(hexAddress, eip1191ChainId) === hexAddress; }; exports.isValidChecksumAddress = isValidChecksumAddress; /** * Generates an address of a newly created contract. * @param from The address which is creating this new address * @param nonce The nonce of the from account */ var generateAddress = function (from, nonce) { (0, helpers_1.assertIsBuffer)(from); (0, helpers_1.assertIsBuffer)(nonce); var nonceBN = new externals_1.BN(nonce); if (nonceBN.isZero()) { // in RLP we want to encode null in the case of zero nonce // read the RLP documentation for an answer if you dare return (0, hash_1.rlphash)([from, null]).slice(-20); } // Only take the lower 160bits of the hash return (0, hash_1.rlphash)([from, Buffer.from(nonceBN.toArray())]).slice(-20); }; exports.generateAddress = generateAddress; /** * Generates an address for a contract created using CREATE2. * @param from The address which is creating this new address * @param salt A salt * @param initCode The init code of the contract being created */ var generateAddress2 = function (from, salt, initCode) { (0, helpers_1.assertIsBuffer)(from); (0, helpers_1.assertIsBuffer)(salt); (0, helpers_1.assertIsBuffer)(initCode); (0, assert_1.default)(from.length === 20); (0, assert_1.default)(salt.length === 32); var address = (0, hash_1.keccak256)(Buffer.concat([Buffer.from('ff', 'hex'), from, salt, (0, hash_1.keccak256)(initCode)])); return address.slice(-20); }; exports.generateAddress2 = generateAddress2; /** * Checks if the private key satisfies the rules of the curve secp256k1. */ var isValidPrivate = function (privateKey) { return (0, secp256k1_1.privateKeyVerify)(privateKey); }; exports.isValidPrivate = isValidPrivate; /** * Checks if the public key satisfies the rules of the curve secp256k1 * and the requirements of Ethereum. * @param publicKey The two points of an uncompressed key, unless sanitize is enabled * @param sanitize Accept public keys in other formats */ var isValidPublic = function (publicKey, sanitize) { if (sanitize === void 0) { sanitize = false; } (0, helpers_1.assertIsBuffer)(publicKey); if (publicKey.length === 64) { // Convert to SEC1 for secp256k1 return (0, secp256k1_1.publicKeyVerify)(Buffer.concat([Buffer.from([4]), publicKey])); } if (!sanitize) { return false; } return (0, secp256k1_1.publicKeyVerify)(publicKey); }; exports.isValidPublic = isValidPublic; /** * Returns the ethereum address of a given public key. * Accepts "Ethereum public keys" and SEC1 encoded keys. * @param pubKey The two points of an uncompressed key, unless sanitize is enabled * @param sanitize Accept public keys in other formats */ var pubToAddress = function (pubKey, sanitize) { if (sanitize === void 0) { sanitize = false; } (0, helpers_1.assertIsBuffer)(pubKey); if (sanitize && pubKey.length !== 64) { pubKey = Buffer.from((0, secp256k1_1.publicKeyConvert)(pubKey, false).slice(1)); } (0, assert_1.default)(pubKey.length === 64); // Only take the lower 160bits of the hash return (0, hash_1.keccak)(pubKey).slice(-20); }; exports.pubToAddress = pubToAddress; exports.publicToAddress = exports.pubToAddress; /** * Returns the ethereum public key of a given private key. * @param privateKey A private key must be 256 bits wide */ var privateToPublic = function (privateKey) { (0, helpers_1.assertIsBuffer)(privateKey); // skip the type flag and use the X, Y points return Buffer.from((0, secp256k1_1.publicKeyCreate)(privateKey, false)).slice(1); }; exports.privateToPublic = privateToPublic; /** * Returns the ethereum address of a given private key. * @param privateKey A private key must be 256 bits wide */ var privateToAddress = function (privateKey) { return (0, exports.publicToAddress)((0, exports.privateToPublic)(privateKey)); }; exports.privateToAddress = privateToAddress; /** * Converts a public key to the Ethereum format. */ var importPublic = function (publicKey) { (0, helpers_1.assertIsBuffer)(publicKey); if (publicKey.length !== 64) { publicKey = Buffer.from((0, secp256k1_1.publicKeyConvert)(publicKey, false).slice(1)); } return publicKey; }; exports.importPublic = importPublic; /** * Returns the zero address. */ var zeroAddress = function () { var addressLength = 20; var addr = (0, bytes_1.zeros)(addressLength); return (0, bytes_1.bufferToHex)(addr); }; exports.zeroAddress = zeroAddress; /** * Checks if a given address is the zero address. */ var isZeroAddress = function (hexAddress) { try { (0, helpers_1.assertIsString)(hexAddress); } catch (e) { return false; } var zeroAddr = (0, exports.zeroAddress)(); return zeroAddr === hexAddress; }; exports.isZeroAddress = isZeroAddress; //# sourceMappingURL=account.js.map