aboutsummaryrefslogtreecommitdiffstats
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
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
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/bool.ts8
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/dynamic_bytes.ts55
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/string.ts4
-rw-r--r--packages/utils/test/abi_encoder/evm_data_types_test.ts2
4 files changed, 40 insertions, 29 deletions
diff --git a/packages/utils/src/abi_encoder/evm_data_types/bool.ts b/packages/utils/src/abi_encoder/evm_data_types/bool.ts
index 6bc299544..82a519aae 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/bool.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/bool.ts
@@ -22,10 +22,6 @@ export class Bool extends PayloadDataType {
}
}
- public getSignature(): string {
- return 'bool';
- }
-
public encodeValue(value: boolean): Buffer {
const encodedValue = value ? '0x1' : '0x0';
const encodedValueBuf = ethUtil.setLengthLeft(
@@ -47,4 +43,8 @@ export class Bool extends PayloadDataType {
/* tslint:enable boolean-naming */
return value;
}
+
+ public getSignature(): string {
+ return 'bool';
+ }
}
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.`);
+ }
+ }
}
diff --git a/packages/utils/src/abi_encoder/evm_data_types/string.ts b/packages/utils/src/abi_encoder/evm_data_types/string.ts
index 428ea21db..2bb6541a3 100644
--- a/packages/utils/src/abi_encoder/evm_data_types/string.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types/string.ts
@@ -32,8 +32,8 @@ export class String extends PayloadDataType {
const valueBuf = new Buffer(value);
const valueBufPadded = ethUtil.setLengthRight(valueBuf, bytesToStoreValuePadded);
// 3/3 Combine length and value
- const encodedValueBuf = Buffer.concat([lengthBufPadded, valueBufPadded]);
- return encodedValueBuf;
+ const encodedValue = Buffer.concat([lengthBufPadded, valueBufPadded]);
+ return encodedValue;
}
public decodeValue(calldata: RawCalldata): string {
diff --git a/packages/utils/test/abi_encoder/evm_data_types_test.ts b/packages/utils/test/abi_encoder/evm_data_types_test.ts
index 9c3e3c0f9..7cea86529 100644
--- a/packages/utils/test/abi_encoder/evm_data_types_test.ts
+++ b/packages/utils/test/abi_encoder/evm_data_types_test.ts
@@ -1018,7 +1018,7 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => {
// Encode Args and validate result
expect(() => {
dataType.encode(args);
- }).to.throw("Tried to encode non-hex value. Value must inlcude '0x' prefix. Got '01'");
+ }).to.throw("Tried to encode non-hex value. Value must inlcude '0x' prefix.");
});
it('Should throw when pass in bad hex (include a half-byte)', async () => {
// Create DataType object