@alayanetwork/ethjs-ens
Version:
An ENS interface module built on EthJS.
1,862 lines (1,660 loc) • 1.05 MB
JavaScript
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
module.exports=[
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
}
],
"name": "resolver",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
}
],
"name": "owner",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "resolver",
"type": "address"
}
],
"name": "setResolver",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "label",
"type": "bytes32"
},
{
"name": "owner",
"type": "address"
}
],
"name": "setSubnodeOwner",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "owner",
"type": "address"
}
],
"name": "setOwner",
"outputs": [],
"type": "function"
}
]
},{}],2:[function(require,module,exports){
module.exports=[
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
}
],
"name": "addr",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
}
],
"name": "content",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
}
],
"name": "name",
"outputs": [
{
"name": "",
"type": "string"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "kind",
"type": "bytes32"
}
],
"name": "has",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "addr",
"type": "address"
}
],
"name": "setAddr",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "hash",
"type": "bytes32"
}
],
"name": "setContent",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "name",
"type": "string"
}
],
"name": "setName",
"outputs": [],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "contentType",
"type": "uint256"
}
],
"name": "ABI",
"outputs": [
{
"name": "",
"type": "uint256"
},
{
"name": "",
"type": "bytes"
}
],
"payable": false,
"type": "function"
}
]
},{}],3:[function(require,module,exports){
const ENS = require('../')
const HttpProvider = require('ethjs-provider-http')
const networkMap = require('../lib/network-map.json')
let ens
// For MetaMask or Mist compatibility:
window.addEventListener('load', function() {
if (typeof window.web3 !== 'undefined') {
console.log('web3 browser detected, using.')
web3.version.getNetwork(function (err, network) {
if (err) {
return resultField.innerText = 'There was a problem: ' + err.message
}
ens = new ENS({ provider: web3.currentProvider, network: network })
})
} else {
console.log('no web3 browser detected, using infura.')
const provider = new HttpProvider('https://mainnet.infura.io')
ens = new ENS({ provider, network: '1' })
}
})
searchButton.addEventListener('click', function() {
console.log('clicked button.')
var query = lookupField.value
console.log('querying for ' + query)
ens.lookup(query)
.then((address) => {
console.log('ens returned ' + address)
resultField.innerText = address
})
.catch((reason) => {
console.log('ens failed!')
console.error(reason)
resultField.innerText = 'There was a problem: ' + reason.message
})
})
},{"../":4,"../lib/network-map.json":5,"ethjs-provider-http":131}],4:[function(require,module,exports){
// External Deps
const Eth = require('@alayanetwork/ethjs-query')
const EthContract = require('@alayanetwork/ethjs-contract')
const namehash = require('eth-ens-namehash')
// ABIs
const registryAbi = require('./abis/registry.json')
const resolverAbi = require('./abis/resolver.json')
// Map network to known ENS registries
const networkMap = require('ethereum-ens-network-map')
const emptyHash = '0x0000000000000000000000000000000000000000000000000000000000000000'
const emptyAddr = '0x0000000000000000000000000000000000000000'
const NotFoundError = new Error('ENS name not defined.')
const BadCharacterError = new Error('Illegal Character for ENS.')
class Ens {
constructor (opts = {}) {
const { provider, network } = opts
let { registryAddress } = opts
// Validations
if (!provider) {
throw new Error('The EthJsENS Constructor requires a provider.')
}
// Requires EITHER a network or a registryAddress
if (!network && !registryAddress) {
throw new Error('The EthJsENS Constructor requires a network or registry address.')
}
this.provider = provider
this.eth = new Eth(this.provider)
this.contract = new EthContract(this.eth)
this.namehash = namehash
// Link to Registry
this.Registry = this.contract(registryAbi)
if (!registryAddress && network) {
registryAddress = networkMap[network]
}
this.registry = this.Registry.at(registryAddress)
// Create Resolver class
this.Resolver = this.contract(resolverAbi)
}
lookup (name = '') {
return this.getNamehash(name)
.then((node) => {
if (node === emptyHash) {
return Promise.reject(NotFoundError)
}
return this.resolveAddressForNode(node)
})
}
getNamehash (name) {
try {
return Promise.resolve(namehash(name))
} catch (e) {
return Promise.reject(BadCharacterError)
}
}
getOwner (name = '') {
return this.getNamehash(name)
.then(node => this.getOwnerForNode(node))
}
getOwnerForNode (node) {
if (node === emptyHash) {
return Promise.reject(NotFoundError)
}
return this.registry.owner(node)
.then((result) => {
const ownerAddress = result[0]
if (ownerAddress === emptyAddr) {
throw NotFoundError
}
return ownerAddress
})
}
getResolver (name = '') {
return this.getNamehash(name)
.then(node => this.getResolverForNode(node))
}
getResolverAddress (name = '') {
return this.getNamehash(name)
.then(node => this.getResolverAddressForNode(node))
}
getResolverForNode (node) {
if (!node.startsWith('0x')) {
node = `0x${node}`
}
return this.getResolverAddressForNode(node)
.then((resolverAddress) => {
return this.Resolver.at(resolverAddress)
})
}
getResolverAddressForNode (node) {
return this.registry.resolver(node)
.then((result) => {
const resolverAddress = result[0]
if (resolverAddress === emptyAddr) {
throw NotFoundError
}
return resolverAddress
})
}
resolveAddressForNode (node) {
return this.getResolverForNode(node)
.then((resolver) => {
return resolver.addr(node)
})
.then(result => result[0])
}
reverse (address) {
if (!address) {
return Promise.reject(new Error('Must supply an address to reverse lookup.'))
}
if (address.startsWith('0x')) {
address = address.slice(2)
}
const name = `${address.toLowerCase()}.addr.reverse`
const node = namehash(name)
return this.getNamehash(name)
.then(node => this.getResolverForNode(node))
.then(resolver => resolver.name(node))
.then(results => results[0])
}
}
module.exports = Ens
},{"./abis/registry.json":1,"./abis/resolver.json":2,"@alayanetwork/ethjs-contract":14,"@alayanetwork/ethjs-query":19,"eth-ens-namehash":127,"ethereum-ens-network-map":129}],5:[function(require,module,exports){
module.exports={
"1": {
"registry": "314159265dd8dbb310642f98f50c066173c1259b"
},
"3": {
"registry": "112234455c3a32fd11230c42e7bccd4a84e02010",
"resolver": "C68De5B43C3d980B0C110A77a5F78d3c4c4d63B4"
}
}
},{}],6:[function(require,module,exports){
'use strict';
// Copyright (c) 2017 Pieter Wuille
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
var CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
var GENERATOR = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
module.exports = {
decode: decode,
encode: encode
};
function polymod(values) {
var chk = 1;
for (var p = 0; p < values.length; ++p) {
var top = chk >> 25;
chk = (chk & 0x1ffffff) << 5 ^ values[p];
for (var i = 0; i < 5; ++i) {
if (top >> i & 1) {
chk ^= GENERATOR[i];
}
}
}
return chk;
}
function hrpExpand(hrp) {
var ret = [];
var p;
for (p = 0; p < hrp.length; ++p) {
ret.push(hrp.charCodeAt(p) >> 5);
}
ret.push(0);
for (p = 0; p < hrp.length; ++p) {
ret.push(hrp.charCodeAt(p) & 31);
}
return ret;
}
function verifyChecksum(hrp, data) {
return polymod(hrpExpand(hrp).concat(data)) === 1;
}
function createChecksum(hrp, data) {
var values = hrpExpand(hrp).concat(data).concat([0, 0, 0, 0, 0, 0]);
var mod = polymod(values) ^ 1;
var ret = [];
for (var p = 0; p < 6; ++p) {
ret.push(mod >> 5 * (5 - p) & 31);
}
return ret;
}
function encode(hrp, data) {
var combined = data.concat(createChecksum(hrp, data));
var ret = hrp + '1';
for (var p = 0; p < combined.length; ++p) {
ret += CHARSET.charAt(combined[p]);
}
return ret;
}
function decode(bechString) {
var p;
var hasLower = false;
var hasUpper = false;
for (p = 0; p < bechString.length; ++p) {
if (bechString.charCodeAt(p) < 33 || bechString.charCodeAt(p) > 126) {
return null;
}
if (bechString.charCodeAt(p) >= 97 && bechString.charCodeAt(p) <= 122) {
hasLower = true;
}
if (bechString.charCodeAt(p) >= 65 && bechString.charCodeAt(p) <= 90) {
hasUpper = true;
}
}
if (hasLower && hasUpper) {
return null;
}
bechString = bechString.toLowerCase();
var pos = bechString.lastIndexOf('1');
if (pos < 1 || pos + 7 > bechString.length || bechString.length > 90) {
return null;
}
var hrp = bechString.substring(0, pos);
var data = [];
for (p = pos + 1; p < bechString.length; ++p) {
var d = CHARSET.indexOf(bechString.charAt(p));
if (d === -1) {
return null;
}
data.push(d);
}
if (!verifyChecksum(hrp, data)) {
return null;
}
return { hrp: hrp, data: data.slice(0, data.length - 6) };
}
},{}],7:[function(require,module,exports){
'use strict';
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var createKeccakHash = require('keccak');
var secp256k1 = require('secp256k1');
var assert = require('assert');
var rlp = require('rlp');
var BN = require('bn.js');
var segwitAddr = require('./segwit_addr');
var createHash = require('create-hash');
var Buffer = require('safe-buffer').Buffer;
Object.assign(exports, require('ethjs-util'));
/**
* the max integer that this VM can handle (a ```BN```)
* @var {BN} MAX_INTEGER
*/
exports.MAX_INTEGER = new BN('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16);
/**
* 2^256 (a ```BN```)
* @var {BN} TWO_POW256
*/
exports.TWO_POW256 = new BN('10000000000000000000000000000000000000000000000000000000000000000', 16);
/**
* Keccak-256 hash of null (a ```String```)
* @var {String} KECCAK256_NULL_S
*/
exports.KECCAK256_NULL_S = 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470';
exports.SHA3_NULL_S = exports.KECCAK256_NULL_S;
/**
* Keccak-256 hash of null (a ```Buffer```)
* @var {Buffer} KECCAK256_NULL
*/
exports.KECCAK256_NULL = Buffer.from(exports.KECCAK256_NULL_S, 'hex');
exports.SHA3_NULL = exports.KECCAK256_NULL;
/**
* Keccak-256 of an RLP of an empty array (a ```String```)
* @var {String} KECCAK256_RLP_ARRAY_S
*/
exports.KECCAK256_RLP_ARRAY_S = '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347';
exports.SHA3_RLP_ARRAY_S = exports.KECCAK256_RLP_ARRAY_S;
/**
* Keccak-256 of an RLP of an empty array (a ```Buffer```)
* @var {Buffer} KECCAK256_RLP_ARRAY
*/
exports.KECCAK256_RLP_ARRAY = Buffer.from(exports.KECCAK256_RLP_ARRAY_S, 'hex');
exports.SHA3_RLP_ARRAY = exports.KECCAK256_RLP_ARRAY;
/**
* Keccak-256 hash of the RLP of null (a ```String```)
* @var {String} KECCAK256_RLP_S
*/
exports.KECCAK256_RLP_S = '56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421';
exports.SHA3_RLP_S = exports.KECCAK256_RLP_S;
/**
* Keccak-256 hash of the RLP of null (a ```Buffer```)
* @var {Buffer} KECCAK256_RLP
*/
exports.KECCAK256_RLP = Buffer.from(exports.KECCAK256_RLP_S, 'hex');
exports.SHA3_RLP = exports.KECCAK256_RLP;
/**
* [`BN`](https://github.com/indutny/bn.js)
* @var {Function}
*/
exports.BN = BN;
/**
* [`rlp`](https://github.com/ethereumjs/rlp)
* @var {Function}
*/
exports.rlp = rlp;
/**
* [`secp256k1`](https://github.com/cryptocoinjs/secp256k1-node/)
* @var {Object}
*/
exports.secp256k1 = secp256k1;
/**
* Returns a buffer filled with 0s
* @method zeros
* @param {Number} bytes the number of bytes the buffer should be
* @return {Buffer}
*/
exports.zeros = function (bytes) {
return Buffer.allocUnsafe(bytes).fill(0);
};
/**
* Returns a zero address
* @method zeroAddress
* @return {String}
*/
exports.zeroAddress = function () {
var addressLength = 20;
var zeroAddress = exports.zeros(addressLength);
return exports.bufferToHex(zeroAddress);
};
/**
* Left Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes.
* Or it truncates the beginning if it exceeds.
* @method lsetLength
* @param {Buffer|Array} msg the value to pad
* @param {Number} length the number of bytes the output should be
* @param {Boolean} [right=false] whether to start padding form the left or right
* @return {Buffer|Array}
*/
exports.setLengthLeft = exports.setLength = function (msg, length, right) {
var buf = exports.zeros(length);
msg = exports.toBuffer(msg);
if (right) {
if (msg.length < length) {
msg.copy(buf);
return buf;
}
return msg.slice(0, length);
} else {
if (msg.length < length) {
msg.copy(buf, length - msg.length);
return buf;
}
return msg.slice(-length);
}
};
/**
* Right Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes.
* Or it truncates the beginning if it exceeds.
* @param {Buffer|Array} msg the value to pad
* @param {Number} length the number of bytes the output should be
* @return {Buffer|Array}
*/
exports.setLengthRight = function (msg, length) {
return exports.setLength(msg, length, true);
};
/**
* Trims leading zeros from a `Buffer` or an `Array`
* @param {Buffer|Array|String} a
* @return {Buffer|Array|String}
*/
exports.unpad = exports.stripZeros = function (a) {
a = exports.stripHexPrefix(a);
var first = a[0];
while (a.length > 0 && first.toString() === '0') {
a = a.slice(1);
first = a[0];
}
return a;
};
/**
* Attempts to turn a value into a `Buffer`. As input it supports `Buffer`, `String`, `Number`, null/undefined, `BN` and other objects with a `toArray()` method.
* @param {*} v the value
*/
exports.toBuffer = function (v) {
if (!Buffer.isBuffer(v)) {
if (Array.isArray(v)) {
v = Buffer.from(v);
} else if (typeof v === 'string') {
if (exports.isHexString(v)) {
v = Buffer.from(exports.padToEven(exports.stripHexPrefix(v)), 'hex');
} else {
v = Buffer.from(v);
}
} else if (typeof v === 'number') {
v = exports.intToBuffer(v);
} else if (v === null || v === undefined) {
v = Buffer.allocUnsafe(0);
} else if (BN.isBN(v)) {
v = v.toArrayLike(Buffer);
} else if (v.toArray) {
// converts a BN to a Buffer
v = Buffer.from(v.toArray());
} else {
throw new Error('invalid type');
}
}
return v;
};
/**
* Converts a `Buffer` to a `Number`
* @param {Buffer} buf
* @return {Number}
* @throws If the input number exceeds 53 bits.
*/
exports.bufferToInt = function (buf) {
return new BN(exports.toBuffer(buf)).toNumber();
};
/**
* Converts a `Buffer` into a hex `String`
* @param {Buffer} buf
* @return {String}
*/
exports.bufferToHex = function (buf) {
buf = exports.toBuffer(buf);
return '0x' + buf.toString('hex');
};
/**
* Interprets a `Buffer` as a signed integer and returns a `BN`. Assumes 256-bit numbers.
* @param {Buffer} num
* @return {BN}
*/
exports.fromSigned = function (num) {
return new BN(num).fromTwos(256);
};
/**
* Converts a `BN` to an unsigned integer and returns it as a `Buffer`. Assumes 256-bit numbers.
* @param {BN} num
* @return {Buffer}
*/
exports.toUnsigned = function (num) {
return Buffer.from(num.toTwos(256).toArray());
};
/**
* Creates Keccak hash of the input
* @param {Buffer|Array|String|Number} a the input data
* @param {Number} [bits=256] the Keccak width
* @return {Buffer}
*/
exports.keccak = function (a, bits) {
a = exports.toBuffer(a);
if (!bits) bits = 256;
return createKeccakHash('keccak' + bits).update(a).digest();
};
/**
* Creates Keccak-256 hash of the input, alias for keccak(a, 256)
* @param {Buffer|Array|String|Number} a the input data
* @return {Buffer}
*/
exports.keccak256 = function (a) {
return exports.keccak(a);
};
/**
* Creates SHA-3 (Keccak) hash of the input [OBSOLETE]
* @param {Buffer|Array|String|Number} a the input data
* @param {Number} [bits=256] the SHA-3 width
* @return {Buffer}
*/
exports.sha3 = exports.keccak;
/**
* Creates SHA256 hash of the input
* @param {Buffer|Array|String|Number} a the input data
* @return {Buffer}
*/
exports.sha256 = function (a) {
a = exports.toBuffer(a);
return createHash('sha256').update(a).digest();
};
/**
* Creates RIPEMD160 hash of the input
* @param {Buffer|Array|String|Number} a the input data
* @param {Boolean} padded whether it should be padded to 256 bits or not
* @return {Buffer}
*/
exports.ripemd160 = function (a, padded) {
a = exports.toBuffer(a);
var hash = createHash('rmd160').update(a).digest();
if (padded === true) {
return exports.setLength(hash, 32);
} else {
return hash;
}
};
/**
* Creates SHA-3 hash of the RLP encoded version of the input
* @param {Buffer|Array|String|Number} a the input data
* @return {Buffer}
*/
exports.rlphash = function (a) {
return exports.keccak(rlp.encode(a));
};
/**
* Checks if the private key satisfies the rules of the curve secp256k1.
* @param {Buffer} privateKey
* @return {Boolean}
*/
exports.isValidPrivate = function (privateKey) {
return secp256k1.privateKeyVerify(privateKey);
};
/**
* Checks if the public key satisfies the rules of the curve secp256k1
* and the requirements of Ethereum.
* @param {Buffer} publicKey The two points of an uncompressed key, unless sanitize is enabled
* @param {Boolean} [sanitize=false] Accept public keys in other formats
* @return {Boolean}
*/
exports.isValidPublic = function (publicKey, sanitize) {
if (publicKey.length === 64) {
// Convert to SEC1 for secp256k1
return secp256k1.publicKeyVerify(Buffer.concat([Buffer.from([4]), publicKey]));
}
if (!sanitize) {
return false;
}
return secp256k1.publicKeyVerify(publicKey);
};
/**
* Returns the ethereum address of a given public key.
* Accepts "Ethereum public keys" and SEC1 encoded keys.
* @param {Buffer} pubKey The two points of an uncompressed key, unless sanitize is enabled
* @param {Boolean} [sanitize=false] Accept public keys in other formats
* @return {Buffer}
*/
exports.pubToAddress = exports.publicToAddress = function (pubKey, sanitize) {
pubKey = exports.toBuffer(pubKey);
if (sanitize && pubKey.length !== 64) {
pubKey = secp256k1.publicKeyConvert(pubKey, false).slice(1);
}
assert(pubKey.length === 64);
// Only take the lower 160bits of the hash
return exports.keccak(pubKey).slice(-20);
};
/**
* Returns the ethereum public key of a given private key
* @param {Buffer} privateKey A private key must be 256 bits wide
* @return {Buffer}
*/
var privateToPublic = exports.privateToPublic = function (privateKey) {
privateKey = exports.toBuffer(privateKey);
// skip the type flag and use the X, Y points
return secp256k1.publicKeyCreate(privateKey, false).slice(1);
};
/**
* Converts a public key to the Ethereum format.
* @param {Buffer} publicKey
* @return {Buffer}
*/
exports.importPublic = function (publicKey) {
publicKey = exports.toBuffer(publicKey);
if (publicKey.length !== 64) {
publicKey = secp256k1.publicKeyConvert(publicKey, false).slice(1);
}
return publicKey;
};
/**
* ECDSA sign
* @param {Buffer} msgHash
* @param {Buffer} privateKey
* @return {Object}
*/
exports.ecsign = function (msgHash, privateKey) {
var sig = secp256k1.sign(msgHash, privateKey);
var ret = {};
ret.r = sig.signature.slice(0, 32);
ret.s = sig.signature.slice(32, 64);
ret.v = sig.recovery + 27;
return ret;
};
/**
* Returns the keccak-256 hash of `message`, prefixed with the header used by the `eth_sign` RPC call.
* The output of this function can be fed into `ecsign` to produce the same signature as the `eth_sign`
* call for a given `message`, or fed to `ecrecover` along with a signature to recover the public key
* used to produce the signature.
* @param message
* @returns {Buffer} hash
*/
exports.hashPersonalMessage = function (message) {
var prefix = exports.toBuffer('\x19Ethereum Signed Message:\n' + message.length.toString());
return exports.keccak(Buffer.concat([prefix, message]));
};
/**
* ECDSA public key recovery from signature
* @param {Buffer} msgHash
* @param {Number} v
* @param {Buffer} r
* @param {Buffer} s
* @return {Buffer} publicKey
*/
exports.ecrecover = function (msgHash, v, r, s) {
var signature = Buffer.concat([exports.setLength(r, 32), exports.setLength(s, 32)], 64);
var recovery = v - 27;
if (recovery !== 0 && recovery !== 1) {
throw new Error('Invalid signature v value');
}
var senderPubKey = secp256k1.recover(msgHash, signature, recovery);
return secp256k1.publicKeyConvert(senderPubKey, false).slice(1);
};
/**
* Convert signature parameters into the format of `eth_sign` RPC method
* @param {Number} v
* @param {Buffer} r
* @param {Buffer} s
* @return {String} sig
*/
exports.toRpcSig = function (v, r, s) {
// NOTE: with potential introduction of chainId this might need to be updated
if (v !== 27 && v !== 28) {
throw new Error('Invalid recovery id');
}
// geth (and the RPC eth_sign method) uses the 65 byte format used by Bitcoin
// FIXME: this might change in the future - https://github.com/ethereum/go-ethereum/issues/2053
return exports.bufferToHex(Buffer.concat([exports.setLengthLeft(r, 32), exports.setLengthLeft(s, 32), exports.toBuffer(v - 27)]));
};
/**
* Convert signature format of the `eth_sign` RPC method to signature parameters
* NOTE: all because of a bug in geth: https://github.com/ethereum/go-ethereum/issues/2053
* @param {String} sig
* @return {Object}
*/
exports.fromRpcSig = function (sig) {
sig = exports.toBuffer(sig);
// NOTE: with potential introduction of chainId this might need to be updated
if (sig.length !== 65) {
throw new Error('Invalid signature length');
}
var v = sig[64];
// support both versions of `eth_sign` responses
if (v < 27) {
v += 27;
}
return {
v: v,
r: sig.slice(0, 32),
s: sig.slice(32, 64)
};
};
/**
* Returns the ethereum address of a given private key
* @param {Buffer} privateKey A private key must be 256 bits wide
* @return {Buffer}
*/
exports.privateToAddress = function (privateKey) {
return exports.publicToAddress(privateToPublic(privateKey));
};
/**
* Checks if the given string is an bech32 address
*
* @method isBech32Address
* @param {String} address the given bech32 adress
* @return {Boolean}
*/
exports.isBech32Address = function (address) {
if (address.length !== 42) {
return false;
}
var hrp = address.substr(0, 3);
var ret = segwitAddr.decode(hrp, address);
if (ret === null) {
return false;
}
return true;
};
/**
* Transforms given string to bech32 address
*
* @method toBech32Address
* @param {String} hrp
* @param {String} address
* @return {String} formatted bech32 address
*/
exports.toBech32Address = function (hrp, address) {
if (exports.isValidAddress(address)) {
return segwitAddr.EncodeAddress(hrp, address);
}
return '';
};
/**
* Resolve the bech32 address
*
* @method decodeBech32Address
* @param {String} bech32Address
* @return {String} formatted address
*/
exports.decodeBech32Address = function (bech32Address) {
if (exports.isBech32Address(bech32Address)) {
var hrp = bech32Address.substr(0, 3);
var address = segwitAddr.DecodeAddress(hrp, bech32Address);
if (address !== null) {
return '0x' + address;
}
}
return '';
};
/**
* Checks if the address is a valid. Accepts checksummed addresses too
* @param {String} address
* @return {Boolean}
*/
exports.isValidAddress = function (address) {
return (/^0x[0-9a-fA-F]{40}$/.test(address)
);
};
/**
* Checks if a given address is a zero address
* @method isZeroAddress
* @param {String} address
* @return {Boolean}
*/
exports.isZeroAddress = function (address) {
var zeroAddress = exports.zeroAddress();
return zeroAddress === exports.addHexPrefix(address);
};
/**
* Returns a checksummed address
* @param {String} address
* @return {String}
*/
exports.toChecksumAddress = function (address) {
address = exports.stripHexPrefix(address).toLowerCase();
var hash = exports.keccak(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;
};
/**
* Checks if the address is a valid checksummed address
* @param {Buffer} address
* @return {Boolean}
*/
exports.isValidChecksumAddress = function (address) {
return exports.isValidAddress(address) && exports.toChecksumAddress(address) === address;
};
/**
* Generates an address of a newly created contract
* @param {Buffer} from the address which is creating this new address
* @param {Buffer} nonce the nonce of the from account
* @return {Buffer}
*/
exports.generateAddress = function (from, nonce) {
from = exports.toBuffer(from);
nonce = new BN(nonce);
if (nonce.isZero()) {
// in RLP we want to encode null in the case of zero nonce
// read the RLP documentation for an answer if you dare
nonce = null;
} else {
nonce = Buffer.from(nonce.toArray());
}
// Only take the lower 160bits of the hash
return exports.rlphash([from, nonce]).slice(-20);
};
/**
* Returns true if the supplied address belongs to a precompiled account (Byzantium)
* @param {Buffer|String} address
* @return {Boolean}
*/
exports.isPrecompiled = function (address) {
var a = exports.unpad(address);
return a.length === 1 && a[0] >= 1 && a[0] <= 8;
};
/**
* Adds "0x" to a given `String` if it does not already start with "0x"
* @param {String} str
* @return {String}
*/
exports.addHexPrefix = function (str) {
if (typeof str !== 'string') {
return str;
}
if (str.startsWith('atx') || str.startsWith('atp')) {
return str;
}
return exports.isHexPrefixed(str) ? str : '0x' + str;
};
/**
* Validate ECDSA signature
* @method isValidSignature
* @param {Buffer} v
* @param {Buffer} r
* @param {Buffer} s
* @param {Boolean} [homestead=true]
* @return {Boolean}
*/
exports.isValidSignature = function (v, r, s, homestead) {
var SECP256K1_N_DIV_2 = new BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16);
var SECP256K1_N = new BN('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16);
if (r.length !== 32 || s.length !== 32) {
return false;
}
if (v !== 27 && v !== 28) {
return false;
}
r = new BN(r);
s = new BN(s);
if (r.isZero() || r.gt(SECP256K1_N) || s.isZero() || s.gt(SECP256K1_N)) {
return false;
}
if (homestead === false && new BN(s).cmp(SECP256K1_N_DIV_2) === 1) {
return false;
}
return true;
};
/**
* Converts a `Buffer` or `Array` to JSON
* @param {Buffer|Array} ba
* @return {Array|String|null}
*/
exports.baToJSON = function (ba) {
if (Buffer.isBuffer(ba)) {
return '0x' + ba.toString('hex');
} else if (ba instanceof Array) {
var array = [];
for (var i = 0; i < ba.length; i++) {
array.push(exports.baToJSON(ba[i]));
}
return array;
}
};
/**
* Defines properties on a `Object`. It make the assumption that underlying data is binary.
* @param {Object} self the `Object` to define properties on
* @param {Array} fields an array fields to define. Fields can contain:
* * `name` - the name of the properties
* * `length` - the number of bytes the field can have
* * `allowLess` - if the field can be less than the length
* * `allowEmpty`
* @param {*} data data to be validated against the definitions
*/
exports.defineProperties = function (self, fields, data) {
self.raw = [];
self._fields = [];
// attach the `toJSON`
self.toJSON = function (label) {
if (label) {
var obj = {};
self._fields.forEach(function (field) {
obj[field] = '0x' + self[field].toString('hex');
});
return obj;
}
return exports.baToJSON(this.raw);
};
self.serialize = function serialize() {
return rlp.encode(self.raw);
};
fields.forEach(function (field, i) {
self._fields.push(field.name);
function getter() {
return self.raw[i];
}
function setter(v) {
v = exports.toBuffer(v);
if (v.toString('hex') === '00' && !field.allowZero) {
v = Buffer.allocUnsafe(0);
}
if (field.allowLess && field.length) {
v = exports.stripZeros(v);
assert(field.length >= v.length, 'The field ' + field.name + ' must not have more ' + field.length + ' bytes');
} else if (!(field.allowZero && v.length === 0) && field.length) {
assert(field.length === v.length, 'The field ' + field.name + ' must have byte length of ' + field.length);
}
self.raw[i] = v;
}
Object.defineProperty(self, field.name, {
enumerable: true,
configurable: true,
get: getter,
set: setter
});
if (field.default) {
self[field.name] = field.default;
}
// attach alias
if (field.alias) {
Object.defineProperty(self, field.alias, {
enumerable: false,
configurable: true,
set: setter,
get: getter
});
}
});
// if the constuctor is passed data
if (data) {
if (typeof data === 'string') {
data = Buffer.from(exports.stripHexPrefix(data), 'hex');
}
if (Buffer.isBuffer(data)) {
data = rlp.decode(data);
}
if (Array.isArray(data)) {
if (data.length > self._fields.length) {
throw new Error('wrong number of fields in data');
}
// make sure all the items are buffers
data.forEach(function (d, i) {
self[self._fields[i]] = exports.toBuffer(d);
});
} else if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') {
var keys = Object.keys(data);
fields.forEach(function (field) {
if (keys.indexOf(field.name) !== -1) self[field.name] = data[field.name];
if (keys.indexOf(field.alias) !== -1) self[field.alias] = data[field.alias];
});
} else {
throw new Error('invalid data');
}
}
};
},{"./segwit_addr":8,"assert":205,"bn.js":28,"create-hash":110,"ethjs-util":133,"keccak":154,"rlp":184,"safe-buffer":185,"secp256k1":186}],8:[function(require,module,exports){
'use strict';
// Copyright (c) 2017 Pieter Wuille
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
var bech32 = require('./bech32');
module.exports = {
encode: encode,
decode: decode,
DecodeAddress: DecodeAddress,
EncodeAddress: EncodeAddress
};
function convertbits(data, frombits, tobits, pad) {
var acc = 0;
var bits = 0;
var ret = [];
var maxv = (1 << tobits) - 1;
for (var p = 0; p < data.length; ++p) {
var value = data[p];
if (value < 0 || value >> frombits !== 0) {
return null;
}
acc = acc << frombits | value;
bits += frombits;
while (bits >= tobits) {
bits -= tobits;
ret.push(acc >> bits & maxv);
}
}
if (pad) {
if (bits > 0) {
ret.push(acc << tobits - bits & maxv);
}
} else if (bits >= frombits || acc << tobits - bits & maxv) {
return null;
}
return ret;
}
function decode(hrp, addr) {
var dec = bech32.decode(addr);
if (dec === null || dec.hrp !== hrp || dec.data.length < 1 /* || dec.data[0] > 16 */) {
return null;
}
var res = convertbits(dec.data.slice(0), 5, 8, false);
if (res === null || res.length < 2 || res.length > 40) {
return null;
}
if (dec.data[0] === 0 && res.length !== 20 && res.length !== 32) {
return null;
}
return { hrp: dec.hrp, program: res };
}
function encode(hrp, program) {
var ret = bech32.encode(hrp, convertbits(program, 8, 5, true));
if (decode(hrp, ret) === null) {
return null;
}
return ret;
}
// 十六进制字符串转字节数组
function Str2Bytes(str) {
var pos = 0;
var len = str.length;
if (len % 2 !== 0) {
return null;
}
len /= 2;
var hexA = [];
for (var i = 0; i < len; i++) {
var s = str.substr(pos, 2);
if (s === '0x' || s === '0X') {
pos += 2;
continue;
}
var v = parseInt(s, 16);
hexA.push(v);
pos += 2;
}
return hexA;
}
// 字节数组转十六进制字符串
function Bytes2Str(arr) {
var str = '';
for (var i = 0; i < arr.length; i++) {
var tmp = arr[i].toString(16);
if (tmp.length === 1) {
tmp = '0' + tmp;
}
str += tmp;
}
return str;
}
// 解析
function DecodeAddress(hrp, address) {
var ret = decode(hrp, address);
if (ret === null) {
return null;
}
return Bytes2Str(ret.program);
// console.log("decode result ==> " + Bytes2Str(ret.program));
}
//
function EncodeAddress(hrp, strAddress) {
var program = Str2Bytes(strAddress);
var ret = encode(hrp, program);
// console.log("encode result ==> " + ret);
return ret;
}
},{"./bech32":6}],9:[function(require,module,exports){
(function (Buffer){(function (){
'use strict';
/* eslint-disable */
/*
Primary Attribution
Richard Moore <ricmoo@me.com>
https://github.com/ethers-io
Note, Richard is a god of ether gods. Follow and respect him, and use Ethers.io!
*/
var utils = require('./utils/index.js');
var uint256Coder = utils.uint256Coder;
var ethUtil = require('@alayanetwork/ethereumjs-util');
var coderBoolean = utils.coderBoolean;
var coderFixedBytes = utils.coderFixedBytes;
var coderAddress = utils.coderAddress;
var coderDynamicBytes = utils.coderDynamicBytes;
var coderString = utils.coderString;
var coderArray = utils.coderArray;
var paramTypePart = utils.paramTypePart;
var getParamCoder = utils.getParamCoder;
function Result() {}
function encodeParams(types, values) {
if (types.length !== values.length) {
throw new Error('[ethjs-abi] while encoding params, types/values mismatch, Your contract requires ' + types.length + ' types (arguments), and you passed in ' + values.length);
}
var parts = [];
types.forEach(function (type, index) {
var coder = getParamCoder(type);
if (type === 'address') {
values[index] = ethUtil.decodeBech32Address(values[index]);
}
parts.push({ dynamic: coder.dynamic, value: coder.encode(values[index]) });
});
function alignSize(size) {
return parseInt(32 * Math.ceil(size / 32));
}
var staticSize = 0,
dynamicSize = 0;
parts.forEach(function (part) {
if (part.dynamic) {
staticSize += 32;
dynamicSize += alignSize(part.value.length);
} else {
staticSize += alignSize(part.value.length);
}
});
var offset = 0,
dynamicOffset = staticSize;
var data = new Buffer(staticSize + dynamicSize);
parts.forEach(function (part, index) {
if (part.dynamic) {
uint256Coder.encode(dynamicOffset).copy(data, offset);
offset += 32;
part.value.copy(data, dynamicOffset);
dynamicOffset += alignSize(part.value.length);
} else {
part.value.copy(data, offset);
offset += alignSize(part.value.length);
}
});
return '0x' + data.toString('hex');
}
// decode bytecode data from output names and types
function decodeParams(names, types, data) {
var useNumberedParams = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
// Names is optional, so shift over all the parameters if not provided
if (arguments.length < 3) {
data = types;
types = names;
names = [];
}
data = utils.hexOrBuffer(data);
var values = new Result();
var offset = 0;
types.forEach(function (type, index) {
var coder = getParamCoder(type);
if (coder.dynamic) {
var dynamicOffset = uint256Coder.decode(data, offset);
var result = coder.decode(data, dynamicOffset.value.toNumber());
offset += dynamicOffset.consumed;
} else {
var result = coder.decode(data, offset);
offset += result.consumed;
}
if (useNumberedParams) {
values[index] = result.value;
}
if (names[index]) {
values[names[index]] = result.value;
}
});
return values;
}
// create an encoded method signature from an ABI object
function encodeSignature(method) {
var signature = method.name + '(' + utils.getKeys(method.inputs, 'type').join(',') + ')';
var signatureEncoded = '0x' + new Buffer(utils.keccak256(signature), 'hex').slice(0, 4).toString('hex');
return signatureEncoded;
}
// encode method ABI object with values in an array, output bytecode
function encodeMethod(method, values) {
var paramsEncoded = encodeParams(utils.getKeys(method.inputs, 'type'), values).substring(2);
return '' + encodeSignature(method) + paramsEncoded;
}
// decode method data bytecode, from method ABI object
function decodeMethod(method, data) {
var outputNames = utils.getKeys(method.outputs, 'name', true);
var outputTypes = utils.getKeys(method.outputs, 'type');
return decodeParams(outputNames, outputTypes, utils.hexOrBuffer(data));
}
// decode method data bytecode, from method ABI object
function encodeEvent(eventObject, values) {
return encodeMethod(eventObject, values);
}
function eventSignature(eventObject) {
var signature = eventObject.name + '(' + utils.getKeys(eventObject.inputs, 'type').join(',') + ')';
return '0x' + utils.keccak256(signature);
}
// decode method data bytecode, from method ABI object
function decodeEvent(eventObject, data, topics) {
var useNumberedParams = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
var nonIndexed = eventObject.inputs.filter(function (input) {
return !input.indexed;
});
var nonIndexedNames = utils.getKeys(nonIndexed, 'name', true);
var nonIndexedTypes = utils.getKeys(nonIndexed, 'type');
var event = decodeParams(nonIndexedNames, nonIndexedTypes, utils.hexOrBuffer(data), useNumberedParams);
var topicOffset = eventObject.anonymous ? 0 : 1;
eventObject.inputs.filter(function (input) {
return input.indexed;
}).map(function (input, i) {
var topic = new Buffer(topics[i + topicOffset].slice(2), 'hex');
var coder = getParamCoder(input.type);
event[input.name] = coder.decode(topic, 0).value;
});
event._eventName = eventObject.name;
return event;
}
// Decode a specific log item with a specific event abi
function decodeLogItem(eventObject, log) {
var useNumberedParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
if (eventObject && log.topics[0] === eventSignature(eventObject)) {
return decodeEvent(eventObject, log.data, log.topics, useNumberedParams);
}
}
// Create a decoder for all events defined in an abi. It returns a function which is called
// on an array of log entries such as received from getLogs or getTransactionReceipt and parses
// any matching log entries
function logDecoder(abi) {
var useNumberedParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var eventMap = {};
abi.filter(function (item) {
return item.type === 'event';
}).map(function (item) {
eventMap[eventSignature(item)] = item;
});
return function (logItems) {
return logItems.map(function (log) {
return decodeLogItem(eventMap[log.topics[0]], log, useNumberedParams);
}).filter(function (i) {
return i;
});
};
}
module.exports = {
encodeParams: encodeParams,
decodeParams: decodeParams,
encodeMethod: encodeMethod,
decodeMethod: decodeMethod,
encodeEvent: encodeEvent,
decodeEvent: decodeEvent,
decodeLogItem: decodeLogItem,
logDecoder: logDecoder,
eventSignature: eventSignature,
encodeSignature: encodeSignature
};
}).call(this)}).call(this,require("buffer").Buffer)
},{"./utils/index.js":10,"@alayanetwork/ethereumjs-util":7,"buffer":211}],10:[function(require,module,exports){
(function (Buffer){(function (){
'use strict';
/*
Primary Attribution
Richard Moore <ricmoo@me.com>
https://github.com/ethers-io
Note, Richard is a god of ether gods. Follow and respect him, and use Ethers.io!
*/
var BN = require('bn.js');
var numberToBN = require('number-to-bn');
var keccak256 = require('js-sha3').keccak_256;
// from ethereumjs-util
function stripZeros(aInput) {
var a = aInput; // eslint-disable-line
var first = a[0]; // eslint-disable-line
while (a.length > 0 && first.toString() === '0') {
a = a.slice(1);
first = a[0];
}
return a;
}
function bnToBuffer(bnInput) {
var bn = bnInput; // eslint-disable-line
var hex = bn.toString(16); // eslint-disable-line
if (hex.length % 2) {
hex = '0' + hex;
}
return stripZeros(new Buffer(hex, 'hex'));
}
function isHexString(value, length) {
if (typeof value !== 'string' || !value.match(/^0x[0-9A-Fa-f]*$/)) {
return false;
}
if (length && value.length !== 2 + 2 * length) {
return false;
}
return true;
}
function hexOrBuffer(valueInput, name) {
var value = valueInput; // eslint-disable-line
if (!Buffer.isBuffer(value)) {
if (!isHexString(value)) {
var error = new Error(name ? '[ethjs-abi] invalid ' + name : '[ethjs-abi] invalid hex or buffer, must be a prefixed alphanumeric even length hex string');
error.reason = '[ethjs-abi] invalid hex string, hex must be prefixed and alphanumeric (e.g. 0x023..)';
error.value = value;
throw error;
}
value = value.substring(2);
if (value.length % 2) {
value = '0' + value;
}
value = new Buffer(value, 'hex');
}
return value;
}
function hexlify(value) {
if (typeof value === 'number') {
return '0x' + bnToBuffer(new BN(value)).toString('hex');
} else if (value.mod || value.modulo) {
return '0x' + bnToBuffer(value).toString('hex');
} else {
// eslint-disable-line
return '0x' + hexOrBuffer(value).toString('hex');
}
}
// getKeys([{a: 1, b: 2}, {a: 3, b: 4}], 'a') => [1, 3]
function getKeys(params, key, allowEmpty) {
var result = []; // eslint-disable-line
if (!Array.isArray(params)) {
throw new Error('[ethjs-abi] while getting keys, invalid params value ' + JSON.stringify(params));
}
for (var i = 0; i < params.length; i++) {
// eslint-disable-line
var value = params[i][key]; // eslint-disable-line
if (allowEmpty && !value) {
value = '';
} else if (typeof value !== 'string') {
throw new Error('[ethjs-abi] while getKeys found invalid ABI data structure, type value not string');
}
result.push(value);
}
return result;
}
function coderNumber(size, signed) {
return {
encode: function encodeNumber(valueInput) {
var value = valueInput; // eslint-disable-line
if (typeof value === 'object' && value.toString && (value.toTwos || value.dividedToIntegerBy)) {
value = value.toString(10).split('.')[0];
}
if (typeof value === 'string' || typeof value === 'number') {
value = String(value).split('.')[0];
}
value = numberToBN(value);
value = value.toTwos(size * 8).maskn(size * 8);
if (signed) {
value = value.fromTwos(size * 8).toTwos(256);
}
return value.toArrayLike(Buffer, 'be', 32);
},
decode: function decodeNumber(data, offset) {
var junkLength = 32 - size; // eslint-disable-line
var value = new BN(data.slice(offset + junkLength, offset + 32)); // eslint-disable-line
if (signed) {
value = value.fromTwos(size * 8);
} else {
value = value.maskn(size * 8);
}
return {
consumed: 32,
value: new BN(value.toString(10))
};
}
};
}
var uint256Coder = coderNumber(32, false);
var coderBoolean = {
encode: function encodeBoolean(value) {
return uint256Coder.encode(value ? 1 : 0);
},
decode: function decodeBoolean(data, offset) {
var result = uint256Coder.decode(data, offset); // eslint-disable-line
return {
consumed: result.consumed,
value: !result.value.isZero()
};
}
};
function coderFixedBytes(length) {
return {
encode: function encodeFixedBytes(valueInput) {
var value = valueInput; // eslint-disable-line
value = hexOrBuffer(value);
if (value.length === 32) {
return value;
}
var result = new Buffer(32); // eslint-disable-line
result.fill(0);
value.copy(result);
return result;
},
decode: function decodeFixedBytes(data, offset) {
if (data.length !== 0 && data.length < offset + 32) {
throw new Error('[ethjs-abi] while decoding fixed bytes, invalid bytes data length: ' + length);
}
return {
consumed: 32,
value: '0x' + data.slice(offset, offset + length).toString('hex')
};
}
};
}
var coderAddress = {
encode: function encodeAddress(valueInput) {
var value =