diff options
author | Steve Klebanoff <steve.klebanoff@gmail.com> | 2018-11-30 07:45:35 +0800 |
---|---|---|
committer | Steve Klebanoff <steve.klebanoff@gmail.com> | 2018-11-30 07:45:35 +0800 |
commit | 702dbbae54ae2fba3330c7dcda68ad6ffe64abc0 (patch) | |
tree | e5f6da99570de8d0f49695f944e92b2423de0b85 /packages/utils/src/abi_encoder/calldata/raw_calldata.ts | |
parent | 856f4b473b54ecb3dc707ea334890397c98606bf (diff) | |
parent | fc3641b49938ea9dc5e77e633e798ca19aa812ff (diff) | |
download | dexon-sol-tools-702dbbae54ae2fba3330c7dcda68ad6ffe64abc0.tar dexon-sol-tools-702dbbae54ae2fba3330c7dcda68ad6ffe64abc0.tar.gz dexon-sol-tools-702dbbae54ae2fba3330c7dcda68ad6ffe64abc0.tar.bz2 dexon-sol-tools-702dbbae54ae2fba3330c7dcda68ad6ffe64abc0.tar.lz dexon-sol-tools-702dbbae54ae2fba3330c7dcda68ad6ffe64abc0.tar.xz dexon-sol-tools-702dbbae54ae2fba3330c7dcda68ad6ffe64abc0.tar.zst dexon-sol-tools-702dbbae54ae2fba3330c7dcda68ad6ffe64abc0.zip |
Merge branch 'development' into feature/instant/misc-close-analytics
Diffstat (limited to 'packages/utils/src/abi_encoder/calldata/raw_calldata.ts')
-rw-r--r-- | packages/utils/src/abi_encoder/calldata/raw_calldata.ts | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/packages/utils/src/abi_encoder/calldata/raw_calldata.ts b/packages/utils/src/abi_encoder/calldata/raw_calldata.ts new file mode 100644 index 000000000..189841989 --- /dev/null +++ b/packages/utils/src/abi_encoder/calldata/raw_calldata.ts @@ -0,0 +1,82 @@ +import * as ethUtil from 'ethereumjs-util'; +import * as _ from 'lodash'; + +import { constants } from '../utils/constants'; +import { Queue } from '../utils/queue'; + +export class RawCalldata { + private static readonly _INITIAL_OFFSET = 0; + private readonly _value: Buffer; + private readonly _selector: string; + private readonly _scopes: Queue<number>; + private _offset: number; + + public constructor(value: string | Buffer, hasSelector: boolean = true) { + // Sanity check + if (typeof value === 'string' && !_.startsWith(value, '0x')) { + throw new Error(`Expected raw calldata to start with '0x'`); + } + // Construct initial values + this._value = ethUtil.toBuffer(value); + this._selector = '0x'; + this._scopes = new Queue<number>(); + this._scopes.pushBack(RawCalldata._INITIAL_OFFSET); + this._offset = RawCalldata._INITIAL_OFFSET; + // If there's a selector then slice it + if (hasSelector) { + const selectorBuf = this._value.slice(constants.HEX_SELECTOR_LENGTH_IN_BYTES); + this._value = this._value.slice(constants.HEX_SELECTOR_LENGTH_IN_BYTES); + this._selector = ethUtil.bufferToHex(selectorBuf); + } + } + + public popBytes(lengthInBytes: number): Buffer { + const value = this._value.slice(this._offset, this._offset + lengthInBytes); + this.setOffset(this._offset + lengthInBytes); + return value; + } + + public popWord(): Buffer { + const wordInBytes = 32; + return this.popBytes(wordInBytes); + } + + public popWords(length: number): Buffer { + const wordInBytes = 32; + return this.popBytes(length * wordInBytes); + } + + public readBytes(from: number, to: number): Buffer { + const value = this._value.slice(from, to); + return value; + } + + public setOffset(offsetInBytes: number): void { + this._offset = offsetInBytes; + } + + public startScope(): void { + this._scopes.pushFront(this._offset); + } + + public endScope(): void { + this._scopes.popFront(); + } + + public getOffset(): number { + return this._offset; + } + + public toAbsoluteOffset(relativeOffset: number): number { + const scopeOffset = this._scopes.peekFront(); + if (_.isUndefined(scopeOffset)) { + throw new Error(`Tried to access undefined scope.`); + } + const absoluteOffset = relativeOffset + scopeOffset; + return absoluteOffset; + } + + public getSelector(): string { + return this._selector; + } +} |