Initial new UI source code import (#2607)
* address -> name mappings * expanding, loading all coin details * send use only actual BasicCoin tokens registered (any reg) * sending token & accounts * form styling updates * send form layout in place * coin send working as expected * api subscriptions on multiple addresses * bring in events * simplify * basic events display in-place, functionally complete * basic functionality in-place * fix horrible event address issue * rwork display of events slightly * test TLA availability * table for owner -> tokens * fix signature lookup address * fix signature lookup address * basic overview styling * txhash links * page layout adjustments * background import * adjust colors * no global registration, simplify color selection * updated styling * connection dialog for "busy connecting" * initial token connection - WIP * init token updates take place * basic test for manual token * rework connection display * allow updates of the secure token * first stab at making the build build * update runner tags * fix linting issues * skip tests requiring network (should be e2e, TODO) * re-enable javascript tag/runner * release push does the trick * push to any branch, CI name * javscript-test runner as well * swap dependencies build requires test * revert stages swap * retrieve images associated with tokens * remove js build deps order * null image when hash = 0x0 * 6x64 images (hashes for registries) * don't pass tokens as prop to IdentityIcon * check images against content hash pictures * cleanup signer after connection changes * fix naming typo * display unknownImages for balances (not available as content hash) * unknownImage for transfer dialog * basic githubhint layout * single input for commit/filename * ethcore_hashContent call * lookup hash * registration in place * fixes * events is using a proper table * pass value through as-is * stop wrongly using main app IdentityIcon * NEVER export class instance functions * alignment back to normal * typo in definition * set & get images working (mostly) * show content retrieval info * set exitcode via || * use javascript:latest images * disable npm progress bar * rename phase I * rename phase II * only send build output to GitHub on major branches * also run the build step as part of the test (until comprehensive) * ci-specific build (no webpack progress) * allow for account creation via recovery phrase * display account uuid (where available), closes #2546 * connection dialog now shows up in dapps as well, closes #2538 * token images show up as expected * IdentityName component added and deployed * fix padding tests * adjust tests to map to stricter 0x-prefixed hex * render names via common component for the address -> name * split lint into seperate script (early exit) * test phases changed to lint, test & pack * pack part of test phase * remove files marked for deletion (cleanup) * Signer cleanups, start moving in the direction of the rest * add personal signer methods * basic signer request subscription * don't poll blockNumber when not connected * missing return, creating massive ws queue backlogs * ΞTH -> ETH * fix failing tests * registry uses setAddress to actually set addresses now * bytes mapping operates on lowerCase hex strings * sha3 ids for each application * add dappreg to list of contracts * adjust alignment of queries * show gas estimation log * abi with payable for register function * add key as required * image retrieval from dappreg * use proper Image urls * embed and link apps from Parity, retrieved via /api/apps * filter apps that has been replaced * proxy entry for parity-utils * add basiccoin abi * add support for fallback abi type * capture constructor paramaters * merge master into js * move images to assets/images/ * add font assets * import fonts as part of build * don't inline woff files * Revert "merge master into js" This reverts commit cfcfa81bd26f1b3cbc748d3afa1eb5c670b363fe. * remove unused npm packages * information on gas estimates (like almost everywhere else) * don't pass gas & gasPrice to estimation * display account passwordhint when available * signer subscriptions based on polling & function trapping * pending requests retrieved via jsapi * update signer middleware * remove all web3 instances * remove web3 package * last web3 dependencies removed * no need to toChecksumAddress - api takes care of it * expand description for personal_confirmRequest * Signer conversion from web3 -> parity.js completed * explicit in no return * green circle background * remove generated background * convert /api/* paths to localhost:8080/api/* paths (hard-coded, temporary) * change dapps to load from localhost:8080/ui/* * remove dangling web3 files * update manager test for signer * /api/ping -> / * additional token images * additional token images * add missing styles.css for 8180 error pages * cater for txhash returning null/empty object * adjust output directories * Release merge with origin with ours strategy * additional token images * cater for development server * s/localhost/127.0.0.1/ (cater for origin) * Fix address selection for contract deployment * Adjust z-index for error overlay * better text on unique background pattern * fix signer rejections * Don't allow gavcoin transfer with no balance * fix txhash rendering in signer * remove unnecessary ParityBackground * script to update js-precompiled * Redirect from :8080 to :8180 * Remove extra return * Dapp logo images
This commit is contained in:
30
js/src/abi/decoder/bytesTaken.js
Normal file
30
js/src/abi/decoder/bytesTaken.js
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default class BytesTaken {
|
||||
constructor (bytes, newOffset) {
|
||||
this._bytes = bytes;
|
||||
this._newOffset = newOffset;
|
||||
}
|
||||
|
||||
get bytes () {
|
||||
return this._bytes;
|
||||
}
|
||||
|
||||
get newOffset () {
|
||||
return this._newOffset;
|
||||
}
|
||||
}
|
||||
29
js/src/abi/decoder/bytesTaken.spec.js
Normal file
29
js/src/abi/decoder/bytesTaken.spec.js
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BytesTaken from './bytesTaken';
|
||||
|
||||
describe('abi/decoder/BytesTaken', () => {
|
||||
describe('constructor', () => {
|
||||
it('sets the bytes of the object', () => {
|
||||
expect((new BytesTaken(1, 2)).bytes).to.equal(1);
|
||||
});
|
||||
|
||||
it('sets the newOffset of the object', () => {
|
||||
expect((new BytesTaken(3, 4)).newOffset).to.equal(4);
|
||||
});
|
||||
});
|
||||
});
|
||||
30
js/src/abi/decoder/decodeResult.js
Normal file
30
js/src/abi/decoder/decodeResult.js
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default class DecodeResult {
|
||||
constructor (token, newOffset) {
|
||||
this._token = token;
|
||||
this._newOffset = newOffset;
|
||||
}
|
||||
|
||||
get token () {
|
||||
return this._token;
|
||||
}
|
||||
|
||||
get newOffset () {
|
||||
return this._newOffset;
|
||||
}
|
||||
}
|
||||
29
js/src/abi/decoder/decodeResult.spec.js
Normal file
29
js/src/abi/decoder/decodeResult.spec.js
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import DecodeResult from './decodeResult';
|
||||
|
||||
describe('abi/decoder/DecodeResult', () => {
|
||||
describe('constructor', () => {
|
||||
it('sets the token of the object', () => {
|
||||
expect((new DecodeResult('token', 2)).token).to.equal('token');
|
||||
});
|
||||
|
||||
it('sets the newOffset of the object', () => {
|
||||
expect((new DecodeResult('baz', 4)).newOffset).to.equal(4);
|
||||
});
|
||||
});
|
||||
});
|
||||
145
js/src/abi/decoder/decoder.js
Normal file
145
js/src/abi/decoder/decoder.js
Normal file
@@ -0,0 +1,145 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import utf8 from 'utf8';
|
||||
|
||||
import Token from '../token/token';
|
||||
import BytesTaken from './bytesTaken';
|
||||
import DecodeResult from './decodeResult';
|
||||
import ParamType from '../spec/paramType/paramType';
|
||||
import { sliceData } from '../util/slice';
|
||||
import { asAddress, asBool, asI32, asU32 } from '../util/sliceAs';
|
||||
import { isArray, isInstanceOf } from '../util/types';
|
||||
|
||||
const NULL = '0000000000000000000000000000000000000000000000000000000000000000';
|
||||
|
||||
export default class Decoder {
|
||||
static decode (params, data) {
|
||||
if (!isArray(params)) {
|
||||
throw new Error('Parameters should be array of ParamType');
|
||||
}
|
||||
|
||||
const slices = sliceData(data);
|
||||
let offset = 0;
|
||||
|
||||
return params.map((param) => {
|
||||
const result = Decoder.decodeParam(param, slices, offset);
|
||||
offset = result.newOffset;
|
||||
return result.token;
|
||||
});
|
||||
}
|
||||
|
||||
static peek (slices, position) {
|
||||
if (!slices || !slices[position]) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return slices[position];
|
||||
}
|
||||
|
||||
static takeBytes (slices, position, length) {
|
||||
const slicesLength = Math.floor((length + 31) / 32);
|
||||
let bytesStr = '';
|
||||
|
||||
for (let idx = 0; idx < slicesLength; idx++) {
|
||||
bytesStr = `${bytesStr}${Decoder.peek(slices, position + idx)}`;
|
||||
}
|
||||
|
||||
const bytes = (bytesStr.substr(0, length * 2).match(/.{1,2}/g) || []).map((code) => parseInt(code, 16));
|
||||
|
||||
return new BytesTaken(bytes, position + slicesLength);
|
||||
}
|
||||
|
||||
static decodeParam (param, slices, offset) {
|
||||
if (!isInstanceOf(param, ParamType)) {
|
||||
throw new Error('param should be instanceof ParamType');
|
||||
}
|
||||
|
||||
const tokens = [];
|
||||
let taken;
|
||||
let lengthOffset;
|
||||
let length;
|
||||
let newOffset;
|
||||
|
||||
switch (param.type) {
|
||||
case 'address':
|
||||
return new DecodeResult(new Token(param.type, asAddress(Decoder.peek(slices, offset))), offset + 1);
|
||||
|
||||
case 'bool':
|
||||
return new DecodeResult(new Token(param.type, asBool(Decoder.peek(slices, offset))), offset + 1);
|
||||
|
||||
case 'int':
|
||||
return new DecodeResult(new Token(param.type, asI32(Decoder.peek(slices, offset))), offset + 1);
|
||||
|
||||
case 'uint':
|
||||
return new DecodeResult(new Token(param.type, asU32(Decoder.peek(slices, offset))), offset + 1);
|
||||
|
||||
case 'fixedBytes':
|
||||
taken = Decoder.takeBytes(slices, offset, param.length);
|
||||
|
||||
return new DecodeResult(new Token(param.type, taken.bytes), taken.newOffset);
|
||||
|
||||
case 'bytes':
|
||||
lengthOffset = asU32(Decoder.peek(slices, offset)).div(32).toNumber();
|
||||
length = asU32(Decoder.peek(slices, lengthOffset)).toNumber();
|
||||
taken = Decoder.takeBytes(slices, lengthOffset + 1, length);
|
||||
|
||||
return new DecodeResult(new Token(param.type, taken.bytes), offset + 1);
|
||||
|
||||
case 'string':
|
||||
if (param.indexed) {
|
||||
taken = Decoder.takeBytes(slices, offset, 32);
|
||||
|
||||
return new DecodeResult(new Token('fixedBytes', taken.bytes), offset + 1);
|
||||
}
|
||||
|
||||
lengthOffset = asU32(Decoder.peek(slices, offset)).div(32).toNumber();
|
||||
length = asU32(Decoder.peek(slices, lengthOffset)).toNumber();
|
||||
taken = Decoder.takeBytes(slices, lengthOffset + 1, length);
|
||||
|
||||
const str = taken.bytes.map((code) => String.fromCharCode(code)).join('');
|
||||
|
||||
return new DecodeResult(new Token(param.type, utf8.decode(str)), offset + 1);
|
||||
|
||||
case 'array':
|
||||
lengthOffset = asU32(Decoder.peek(slices, offset)).div(32).toNumber();
|
||||
length = asU32(Decoder.peek(slices, lengthOffset)).toNumber();
|
||||
newOffset = lengthOffset + 1;
|
||||
|
||||
for (let idx = 0; idx < length; idx++) {
|
||||
const result = Decoder.decodeParam(param.subtype, slices, newOffset);
|
||||
newOffset = result.newOffset;
|
||||
tokens.push(result.token);
|
||||
}
|
||||
|
||||
return new DecodeResult(new Token(param.type, tokens), offset + 1);
|
||||
|
||||
case 'fixedArray':
|
||||
newOffset = offset;
|
||||
|
||||
for (let idx = 0; idx < param.length; idx++) {
|
||||
const result = Decoder.decodeParam(param.subtype, slices, newOffset);
|
||||
newOffset = result.newOffset;
|
||||
tokens.push(result.token);
|
||||
}
|
||||
|
||||
return new DecodeResult(new Token(param.type, tokens), newOffset);
|
||||
|
||||
default:
|
||||
throw new Error(`Invalid param type ${param.type} in decodeParam`);
|
||||
}
|
||||
}
|
||||
}
|
||||
310
js/src/abi/decoder/decoder.spec.js
Normal file
310
js/src/abi/decoder/decoder.spec.js
Normal file
@@ -0,0 +1,310 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import Decoder from './decoder';
|
||||
import ParamType from '../spec/paramType';
|
||||
import Token from '../token';
|
||||
import { padU32 } from '../util/pad';
|
||||
|
||||
describe('abi/decoder/Decoder', () => {
|
||||
const stringToBytes = function (str) {
|
||||
return str.match(/.{1,2}/g).map((code) => parseInt(code, 16));
|
||||
};
|
||||
|
||||
const address1 = '0000000000000000000000001111111111111111111111111111111111111111';
|
||||
const address2 = '0000000000000000000000002222222222222222222222222222222222222222';
|
||||
const address3 = '0000000000000000000000003333333333333333333333333333333333333333';
|
||||
const address4 = '0000000000000000000000004444444444444444444444444444444444444444';
|
||||
const bool1 = '0000000000000000000000000000000000000000000000000000000000000001';
|
||||
const bytes1 = '1234000000000000000000000000000000000000000000000000000000000000';
|
||||
const bytes2 = '1000000000000000000000000000000000000000000000000000000000000000';
|
||||
const bytes3 = '10000000000000000000000000000000000000000000000000000000000002';
|
||||
const bytes4 = '0010000000000000000000000000000000000000000000000000000000000002';
|
||||
const int1 = '0111111111111111111111111111111111111111111111111111111111111111';
|
||||
const intn = 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85';
|
||||
const string1 = '6761766f66796f726b0000000000000000000000000000000000000000000000';
|
||||
const tokenAddress1 = new Token('address', `0x${address1.slice(-40)}`);
|
||||
const tokenAddress2 = new Token('address', `0x${address2.slice(-40)}`);
|
||||
const tokenAddress3 = new Token('address', `0x${address3.slice(-40)}`);
|
||||
const tokenAddress4 = new Token('address', `0x${address4.slice(-40)}`);
|
||||
const tokenBool1 = new Token('bool', true);
|
||||
const tokenFixedBytes1 = new Token('fixedBytes', [0x12, 0x34]);
|
||||
const tokenBytes1 = new Token('bytes', [0x12, 0x34]);
|
||||
const tokenBytes2 = new Token('bytes', stringToBytes(bytes2).concat(stringToBytes(bytes2)));
|
||||
const tokenBytes3 = new Token('bytes', stringToBytes(bytes3));
|
||||
const tokenBytes4 = new Token('bytes', stringToBytes(bytes4));
|
||||
const tokenInt1 = new Token('int', new BigNumber(int1, 16));
|
||||
const tokenIntn = new Token('int', new BigNumber(-123));
|
||||
const tokenUint1 = new Token('uint', new BigNumber(int1, 16));
|
||||
const tokenUintn = new Token('uint', new BigNumber(intn, 16));
|
||||
const tokenString1 = new Token('string', 'gavofyork');
|
||||
const slices = [ address1, address2, address3, address4 ];
|
||||
|
||||
describe('peek', () => {
|
||||
it('returns the slice at the correct position', () => {
|
||||
expect(Decoder.peek(slices, 1)).to.equal(slices[1]);
|
||||
});
|
||||
|
||||
it('returns empty on invalid slices', () => {
|
||||
expect(Decoder.peek(null, 4)).to.equal('0000000000000000000000000000000000000000000000000000000000000000');
|
||||
});
|
||||
});
|
||||
|
||||
describe('takeBytes', () => {
|
||||
it('returns a single slice', () => {
|
||||
expect(Decoder.takeBytes(slices, 0, 32).bytes).to.deep.equal(stringToBytes(slices[0]));
|
||||
});
|
||||
|
||||
it('returns a single partial slice', () => {
|
||||
expect(Decoder.takeBytes(slices, 0, 20).bytes).to.deep.equal(stringToBytes(slices[0].substr(0, 40)));
|
||||
});
|
||||
|
||||
it('returns multiple slices', () => {
|
||||
expect(Decoder.takeBytes(slices, 0, 64).bytes).to.deep.equal(stringToBytes(`${slices[0]}${slices[1]}`));
|
||||
});
|
||||
|
||||
it('returns a single offset slice', () => {
|
||||
expect(Decoder.takeBytes(slices, 1, 32).bytes).to.deep.equal(stringToBytes(slices[1]));
|
||||
});
|
||||
|
||||
it('returns multiple offset slices', () => {
|
||||
expect(Decoder.takeBytes(slices, 1, 64).bytes).to.deep.equal(stringToBytes(`${slices[1]}${slices[2]}`));
|
||||
});
|
||||
|
||||
it('returns the requires length from slices', () => {
|
||||
expect(
|
||||
Decoder.takeBytes(slices, 1, 75).bytes
|
||||
).to.deep.equal(stringToBytes(`${slices[1]}${slices[2]}${slices[3]}`.substr(0, 150)));
|
||||
});
|
||||
});
|
||||
|
||||
describe('decodeParam', () => {
|
||||
it('throws an error on non ParamType param', () => {
|
||||
expect(() => Decoder.decodeParam({})).to.throw(/ParamType/);
|
||||
});
|
||||
|
||||
it('throws an error on invalid param type', () => {
|
||||
const pt = new ParamType('address');
|
||||
pt._type = 'noMatch';
|
||||
|
||||
expect(() => Decoder.decodeParam(pt)).to.throw(/noMatch/);
|
||||
});
|
||||
|
||||
it('decodes an address', () => {
|
||||
expect(
|
||||
Decoder.decodeParam(new ParamType('address'), [address1], 0).token
|
||||
).to.deep.equal(tokenAddress1);
|
||||
});
|
||||
|
||||
it('decodes a bool', () => {
|
||||
expect(
|
||||
Decoder.decodeParam(new ParamType('bool'), [bool1], 0).token
|
||||
).to.deep.equal(tokenBool1);
|
||||
});
|
||||
|
||||
it('decodes an int', () => {
|
||||
expect(
|
||||
Decoder.decodeParam(new ParamType('int'), [int1], 0).token
|
||||
).to.deep.equal(tokenInt1);
|
||||
});
|
||||
|
||||
it('decodes a negative int', () => {
|
||||
expect(
|
||||
Decoder.decodeParam(new ParamType('int'), [intn], 0).token
|
||||
).to.deep.equal(tokenIntn);
|
||||
});
|
||||
|
||||
it('decodes an uint', () => {
|
||||
expect(
|
||||
Decoder.decodeParam(new ParamType('uint'), [int1], 0).token
|
||||
).to.deep.equal(tokenUint1);
|
||||
});
|
||||
|
||||
it('decodes an uint (negative as int)', () => {
|
||||
expect(
|
||||
Decoder.decodeParam(new ParamType('uint'), [intn], 0).token
|
||||
).to.deep.equal(tokenUintn);
|
||||
});
|
||||
|
||||
it('decodes fixedBytes', () => {
|
||||
expect(
|
||||
Decoder.decodeParam(new ParamType('fixedBytes', null, 2), [bytes1], 0).token
|
||||
).to.deep.equal(tokenFixedBytes1);
|
||||
});
|
||||
|
||||
it('decodes bytes', () => {
|
||||
expect(
|
||||
Decoder.decodeParam(new ParamType('bytes'), [padU32(0x20), padU32(2), bytes1], 0).token
|
||||
).to.deep.equal(tokenBytes1);
|
||||
});
|
||||
|
||||
it('decodes string', () => {
|
||||
expect(
|
||||
Decoder.decodeParam(new ParamType('string'), [padU32(0x20), padU32(9), string1], 0).token
|
||||
).to.deep.equal(tokenString1);
|
||||
});
|
||||
|
||||
it('decodes string (indexed)', () => {
|
||||
expect(
|
||||
Decoder.decodeParam(new ParamType('string', null, 0, true), [bytes1], 0)
|
||||
).to.deep.equal(Decoder.decodeParam(new ParamType('fixedBytes', null, 32, true), [bytes1], 0));
|
||||
});
|
||||
});
|
||||
|
||||
describe('decode', () => {
|
||||
it('throws an error on invalid params', () => {
|
||||
expect(() => Decoder.decode(null, '123')).to.throw(/array/);
|
||||
});
|
||||
|
||||
describe('address', () => {
|
||||
it('decodes an address', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('address')],
|
||||
`${address1}`
|
||||
)
|
||||
).to.deep.equal([tokenAddress1]);
|
||||
});
|
||||
|
||||
it('decodes 2 addresses', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('address'), new ParamType('address')],
|
||||
`${address1}${address2}`
|
||||
)
|
||||
).to.deep.equal([tokenAddress1, tokenAddress2]);
|
||||
});
|
||||
|
||||
it('decodes a fixedArray of addresses', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('fixedArray', new ParamType('address'), 2)],
|
||||
`${address1}${address2}`
|
||||
)
|
||||
).to.deep.equal([new Token('fixedArray', [tokenAddress1, tokenAddress2])]);
|
||||
});
|
||||
|
||||
it('decodes a dynamic array of addresses', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('array', new ParamType('address'))],
|
||||
`${padU32(0x20)}${padU32(2)}${address1}${address2}`
|
||||
)
|
||||
).to.deep.equal([new Token('array', [tokenAddress1, tokenAddress2])]);
|
||||
});
|
||||
|
||||
it('decodes a dynamic array of fixed arrays', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('array', new ParamType('fixedArray', new ParamType('address'), 2))],
|
||||
`${padU32(0x20)}${padU32(2)}${address1}${address2}${address3}${address4}`
|
||||
)
|
||||
).to.deep.equal([
|
||||
new Token('array', [
|
||||
new Token('fixedArray', [tokenAddress1, tokenAddress2]),
|
||||
new Token('fixedArray', [tokenAddress3, tokenAddress4])
|
||||
])
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('int', () => {
|
||||
it('decodes an int', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('int')],
|
||||
`${int1}`
|
||||
)
|
||||
).to.deep.equal([tokenInt1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('uint', () => {
|
||||
it('decodes an uint', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('uint')],
|
||||
`${int1}`
|
||||
)
|
||||
).to.deep.equal([tokenUint1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fixedBytes', () => {
|
||||
it('decodes fixedBytes', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('fixedBytes', null, 2)],
|
||||
`${bytes1}`
|
||||
)
|
||||
).to.deep.equal([tokenFixedBytes1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('bytes', () => {
|
||||
it('decodes bytes', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('bytes')],
|
||||
`${padU32(0x20)}${padU32(2)}${bytes1}`
|
||||
)
|
||||
).to.deep.equal([tokenBytes1]);
|
||||
});
|
||||
|
||||
it('decodes bytes sequence', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('bytes')],
|
||||
`${padU32(0x20)}${padU32(0x40)}${bytes2}${bytes2}`
|
||||
)
|
||||
).to.deep.equal([tokenBytes2]);
|
||||
});
|
||||
|
||||
it('decodes bytes seuence (2)', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('bytes'), new ParamType('bytes')],
|
||||
`${padU32(0x40)}${padU32(0x80)}${padU32(0x1f)}${bytes3}00${padU32(0x20)}${bytes4}`
|
||||
)
|
||||
).to.deep.equal([tokenBytes3, tokenBytes4]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('bool', () => {
|
||||
it('decodes a single bool', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('bool')],
|
||||
bool1
|
||||
)
|
||||
).to.deep.equal([tokenBool1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('string', () => {
|
||||
it('decodes a string', () => {
|
||||
expect(
|
||||
Decoder.decode(
|
||||
[new ParamType('string')],
|
||||
`${padU32(0x20)}${padU32(9)}${string1}`
|
||||
)
|
||||
).to.deep.equal([tokenString1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
17
js/src/abi/decoder/index.js
Normal file
17
js/src/abi/decoder/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './decoder';
|
||||
Reference in New Issue
Block a user