diff options
author | Greg Hysen <greg.hysen@gmail.com> | 2018-11-26 09:04:50 +0800 |
---|---|---|
committer | Greg Hysen <greg.hysen@gmail.com> | 2018-11-29 08:38:11 +0800 |
commit | 58a2dfbc4d191ea21e6a749371e586dcff3b3239 (patch) | |
tree | 848b6be9277a10144d8e2c1fe5350abfb48b3e5a /packages/utils/src/abi_encoder/evm_data_types/string.ts | |
parent | 173fc1dcefa266704dd80de6335c03b73b7d8702 (diff) | |
download | dexon-sol-tools-58a2dfbc4d191ea21e6a749371e586dcff3b3239.tar dexon-sol-tools-58a2dfbc4d191ea21e6a749371e586dcff3b3239.tar.gz dexon-sol-tools-58a2dfbc4d191ea21e6a749371e586dcff3b3239.tar.bz2 dexon-sol-tools-58a2dfbc4d191ea21e6a749371e586dcff3b3239.tar.lz dexon-sol-tools-58a2dfbc4d191ea21e6a749371e586dcff3b3239.tar.xz dexon-sol-tools-58a2dfbc4d191ea21e6a749371e586dcff3b3239.tar.zst dexon-sol-tools-58a2dfbc4d191ea21e6a749371e586dcff3b3239.zip |
Final rounds on evm data types
Diffstat (limited to 'packages/utils/src/abi_encoder/evm_data_types/string.ts')
-rw-r--r-- | packages/utils/src/abi_encoder/evm_data_types/string.ts | 33 |
1 files changed, 21 insertions, 12 deletions
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 47ad7cb97..15b93e447 100644 --- a/packages/utils/src/abi_encoder/evm_data_types/string.ts +++ b/packages/utils/src/abi_encoder/evm_data_types/string.ts @@ -13,7 +13,7 @@ export class String extends PayloadDataType { public static matchType(type: string): boolean { return type === 'string'; } - + public constructor(dataItem: DataItem, dataTypeFactory: DataTypeFactory) { super(dataItem, dataTypeFactory, String._SIZE_KNOWN_AT_COMPILE_TIME); if (!String.matchType(dataItem.type)) { @@ -22,21 +22,30 @@ export class String extends PayloadDataType { } public encodeValue(value: string): Buffer { - const wordsForValue = Math.ceil(value.length / Constants.EVM_WORD_WIDTH_IN_BYTES); - const paddedDynamicBytesForValue = wordsForValue * Constants.EVM_WORD_WIDTH_IN_BYTES; - const valueBuf = ethUtil.setLengthRight(new Buffer(value), paddedDynamicBytesForValue); - const lengthBuf = ethUtil.setLengthLeft(ethUtil.toBuffer(value.length), Constants.EVM_WORD_WIDTH_IN_BYTES); - const encodedValueBuf = Buffer.concat([lengthBuf, valueBuf]); + // Encoded value is of the form: <length><value>, with each field padded to be word-aligned. + // 1/3 Construct the length + const wordsToStoreValuePadded = Math.ceil(value.length / Constants.EVM_WORD_WIDTH_IN_BYTES); + const bytesToStoreValuePadded = wordsToStoreValuePadded * Constants.EVM_WORD_WIDTH_IN_BYTES; + const lengthBuf = ethUtil.toBuffer(value.length); + const lengthBufPadded = ethUtil.setLengthLeft(lengthBuf, Constants.EVM_WORD_WIDTH_IN_BYTES); + // 2/3 Construct the value + 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; } public decodeValue(calldata: RawCalldata): string { - 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); + // Encoded value is of the form: <length><value>, with each field padded to be word-aligned. + // 1/2 Decode length + const lengthBufPadded = calldata.popWord(); + const lengthHexPadded = ethUtil.bufferToHex(lengthBufPadded); + const length = parseInt(lengthHexPadded, Constants.HEX_BASE); + // 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 = valueBuf.toString('ascii'); return value; } |