ethereum-web-token
Version:
EWT bundles Ethereum function-calls into [JWT](https://jwt.io/)-like tokens. It simplifies the use of ECDSA signatures for webapps and the development of [Smart Oracles](https://github.com/codius/codius/wiki/Smart-Oracles:-A-Simple,-Powerful-Approach-to-S
129 lines (108 loc) • 5.52 kB
JavaScript
;Object.defineProperty(exports, "__esModule", { value: true });var _keys = require('babel-runtime/core-js/object/keys');var _keys2 = _interopRequireDefault(_keys);var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);var _createClass2 = require('babel-runtime/helpers/createClass');var _createClass3 = _interopRequireDefault(_createClass2);var _ethAbi = require('./ethAbi');var _ethAbi2 = _interopRequireDefault(_ethAbi);
var _signer = require('./signer');var _signer2 = _interopRequireDefault(_signer);
var _ethereumjsUtil = require('ethereumjs-util');var _ethereumjsUtil2 = _interopRequireDefault(_ethereumjsUtil);
var _base64url = require('base64url');var _base64url2 = _interopRequireDefault(_base64url);
var _ecdsaSigFormatter = require('ecdsa-sig-formatter');var _ecdsaSigFormatter2 = _interopRequireDefault(_ecdsaSigFormatter);
var _signature = require('./util/signature');var _signature2 = _interopRequireDefault(_signature);
var _bn = require('bn.js');var _bn2 = _interopRequireDefault(_bn);
var _types = require('./util/types');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}var
Token = function () {
function Token(abi) {var _this = this;(0, _classCallCheck3.default)(this, Token);
if (!abi) {
throw new Error('Object ABI needs to be provided to Token instance');
}
this._abi = new _ethAbi2.default(abi);
this._abiObj = abi;
this._abi.functions.forEach(function (func) {
var functionAbi;
_this._abiObj.forEach(function (elem) {
if (elem.name == func.name)
functionAbi = elem;
});
_this[func.name] = function () {
return new _signer2.default(arguments, functionAbi);
}.bind(_this);
});
}(0, _createClass3.default)(Token, [{ key: 'functions', get: function get()
{
return this._functions;
} }, { key: 'abi', get: function get()
{
return this._abi;
} }], [{ key: 'concat', value: function concat(
address, amount) {
var addr = new Buffer(address.replace('0x', ''), 'hex');
return Buffer.concat([addr, _ethereumjsUtil2.default.setLength(amount, 12)]);
} }, { key: 'separate', value: function separate(
bytes32String) {
var val = new Buffer(bytes32String.replace('0x', ''), 'hex');
return {
address: '0x' + val.slice(0, 20).toString('hex'),
amount: new _bn2.default(val.slice(21, 32)).toNumber() };
} }, { key: 'parseToHex', value: function parseToHex(
token) {
//parse payload
var tokenParts = token.split('.'),
payload = JSON.parse(_base64url2.default.decode(tokenParts[1])),
byteValues = [],values = [],
abiObj = {
type: 'function',
name: (0, _keys2.default)(payload)[0],
inputs: [] };
//rebuild abi and values
payload[abiObj.name].forEach(function (entry) {
var input = {};
input.type = (0, _keys2.default)(entry)[0];
abiObj.inputs.push(input);
values.push(entry[(0, _keys2.default)(entry)[0]]);
byteValues.push((0, _types.checkConversion)(entry[(0, _keys2.default)(entry)[0]], input.type));
});
//rebuild signed data
var abi = new _ethAbi2.default([abiObj]),
tokens = abi.encodeTokens(abi.functions[0].inputParamTypes(), byteValues),
encoded = new Buffer(abi.functions[0].encodeCall(tokens), 'hex');
//parse signature
var derSignature = _ecdsaSigFormatter2.default.joseToDer(tokenParts[2], 'ES256'),
sig = new _signature2.default(derSignature, 'ES256'),
r = sig.r.toBuffer('be', 32),
s = sig.s.toBuffer('be', 32),
v = payload.v + 27;
return {
rec: encoded.toString('hex'),
sig: Buffer.concat([r, s]).toString('hex') + v.toString(16) };
} }, { key: 'parse', value: function parse(
token) {
//parse payload
var tokenParts = token.split('.'),
payload = JSON.parse(_base64url2.default.decode(tokenParts[1])),
byteValues = [],values = [],
abiObj = {
type: 'function',
name: (0, _keys2.default)(payload)[0],
inputs: [] };
//rebuild abi and values
payload[abiObj.name].forEach(function (entry) {
var input = {};
input.type = (0, _keys2.default)(entry)[0];
abiObj.inputs.push(input);
values.push(entry[(0, _keys2.default)(entry)[0]]);
byteValues.push((0, _types.checkConversion)(entry[(0, _keys2.default)(entry)[0]], input.type));
});
//rebuild signed data
var abi = new _ethAbi2.default([abiObj]),
tokens = abi.encodeTokens(abi.functions[0].inputParamTypes(), byteValues),
encoded = new Buffer(abi.functions[0].encodeCall(tokens), 'hex'),
hash = _ethereumjsUtil2.default.sha3(encoded);
//parse signature
var derSignature = _ecdsaSigFormatter2.default.joseToDer(tokenParts[2], 'ES256'),
sig = new _signature2.default(derSignature, 'ES256'),
r = sig.r.toBuffer('be', 32),
s = sig.s.toBuffer('be', 32),
pub = _ethereumjsUtil2.default.ecrecover(hash, payload.v + 27, r, s),
signer = '0x' + _ethereumjsUtil2.default.pubToAddress(pub).toString('hex');
return {
header: JSON.parse(_base64url2.default.decode(tokenParts[0])),
abi: [abiObj],
values: values,
signer: signer };
} }]);return Token;}();exports.default = Token;module.exports = exports['default'];