aboutsummaryrefslogtreecommitdiffstats
path: root/packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts
diff options
context:
space:
mode:
authorGreg Hysen <greg.hysen@gmail.com>2018-11-26 09:37:14 +0800
committerGreg Hysen <greg.hysen@gmail.com>2018-11-29 08:38:11 +0800
commitacd364b71c8b3ddb6d4d75d8667cc7f50b18694d (patch)
tree1f83daeddba941a8281ba5b5ccbfaf96f9466a45 /packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts
parentebaf9dd275403cdecfb3364876737fcbcd0eab82 (diff)
downloaddexon-0x-contracts-acd364b71c8b3ddb6d4d75d8667cc7f50b18694d.tar
dexon-0x-contracts-acd364b71c8b3ddb6d4d75d8667cc7f50b18694d.tar.gz
dexon-0x-contracts-acd364b71c8b3ddb6d4d75d8667cc7f50b18694d.tar.bz2
dexon-0x-contracts-acd364b71c8b3ddb6d4d75d8667cc7f50b18694d.tar.lz
dexon-0x-contracts-acd364b71c8b3ddb6d4d75d8667cc7f50b18694d.tar.xz
dexon-0x-contracts-acd364b71c8b3ddb6d4d75d8667cc7f50b18694d.tar.zst
dexon-0x-contracts-acd364b71c8b3ddb6d4d75d8667cc7f50b18694d.zip
Comments and inline documentation for dynamic bytes
Diffstat (limited to 'packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts')
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts55
1 files changed, 33 insertions, 22 deletions
diff --git a/packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts b/packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts
index 626e266c9..ce6ace627 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts
@@ -17,42 +17,53 @@ export class DynamicBytes extends PayloadDataType {
public constructor(dataItem: DataItem, dataTypeFactory: DataTypeFactory) {
super(dataItem, dataTypeFactory, DynamicBytes._SIZE_KNOWN_AT_COMPILE_TIME);
if (!DynamicBytes.matchType(dataItem.type)) {
- throw new Error(`Tried to instantiate DynamicBytes with bad input: ${dataItem}`);
+ throw new Error(`Tried to instantiate Dynamic Bytes with bad input: ${dataItem}`);
}
}
public encodeValue(value: string | Buffer): Buffer {
- if (typeof value === 'string' && !value.startsWith('0x')) {
- throw new Error(`Tried to encode non-hex value. Value must inlcude '0x' prefix. Got '${value}'`);
- }
+ // Encoded value is of the form: <length><value>, with each field padded to be word-aligned.
+ // 1/3 Construct the length
const valueBuf = ethUtil.toBuffer(value);
- if (value.length % 2 !== 0) {
- throw new Error(`Tried to assign ${value}, which is contains a half-byte. Use full bytes only.`);
- }
-
- const wordsForValue = Math.ceil(valueBuf.byteLength / Constants.EVM_WORD_WIDTH_IN_BYTES);
- const paddedDynamicBytesForValue = wordsForValue * Constants.EVM_WORD_WIDTH_IN_BYTES;
- const paddedValueBuf = ethUtil.setLengthRight(valueBuf, paddedDynamicBytesForValue);
- const paddedLengthBuf = ethUtil.setLengthLeft(
- ethUtil.toBuffer(valueBuf.byteLength),
- Constants.EVM_WORD_WIDTH_IN_BYTES,
- );
- const encodedValueBuf = Buffer.concat([paddedLengthBuf, paddedValueBuf]);
- return encodedValueBuf;
+ const wordsToStoreValuePadded = Math.ceil(valueBuf.byteLength / Constants.EVM_WORD_WIDTH_IN_BYTES);
+ const bytesToStoreValuePadded = wordsToStoreValuePadded * Constants.EVM_WORD_WIDTH_IN_BYTES;
+ const lengthBuf = ethUtil.toBuffer(valueBuf.byteLength);
+ const lengthBufPadded = ethUtil.setLengthLeft(lengthBuf, Constants.EVM_WORD_WIDTH_IN_BYTES);
+ // 2/3 Construct the value
+ this._sanityCheckValue(value);
+ const valueBufPadded = ethUtil.setLengthRight(valueBuf, bytesToStoreValuePadded);
+ // 3/3 Combine length and value
+ const encodedValue = Buffer.concat([lengthBufPadded, valueBufPadded]);
+ return encodedValue;
}
public decodeValue(calldata: RawCalldata): string {
+ // Encoded value is of the form: <length><value>, with each field padded to be word-aligned.
+ // 1/2 Decode length
const lengthBuf = calldata.popWord();
const lengthHex = ethUtil.bufferToHex(lengthBuf);
const length = parseInt(lengthHex, Constants.HEX_BASE);
- const wordsForValue = Math.ceil(length / Constants.EVM_WORD_WIDTH_IN_BYTES);
- const paddedValueBuf = calldata.popWords(wordsForValue);
- const valueBuf = paddedValueBuf.slice(0, length);
- const decodedValue = ethUtil.bufferToHex(valueBuf);
- return decodedValue;
+ // 2/2 Decode value
+ const wordsToStoreValuePadded = Math.ceil(length / Constants.EVM_WORD_WIDTH_IN_BYTES);
+ const valueBufPadded = calldata.popWords(wordsToStoreValuePadded);
+ const valueBuf = valueBufPadded.slice(0, length);
+ const value = ethUtil.bufferToHex(valueBuf);
+ this._sanityCheckValue(value);
+ return value;
}
public getSignature(): string {
return 'bytes';
}
+
+ private _sanityCheckValue(value: string | Buffer): void {
+ if (typeof value !== 'string') {
+ return;
+ }
+ if (!value.startsWith('0x')) {
+ throw new Error(`Tried to encode non-hex value. Value must inlcude '0x' prefix.`);
+ } else if (value.length % 2 !== 0) {
+ throw new Error(`Tried to assign ${value}, which is contains a half-byte. Use full bytes only.`);
+ }
+ }
}