UNPKG

witnet-solidity-bridge

Version:

Witnet Solidity Bridge contracts for EVM-compatible chains

816 lines (815 loc) 917 kB
{ "contractName": "WitnetCBOR", "abi": [ { "inputs": [], "name": "EmptyArray", "type": "error" }, { "inputs": [ { "internalType": "uint256", "name": "length", "type": "uint256" } ], "name": "InvalidLengthEncoding", "type": "error" }, { "inputs": [ { "internalType": "uint256", "name": "read", "type": "uint256" }, { "internalType": "uint256", "name": "expected", "type": "uint256" } ], "name": "UnexpectedMajorType", "type": "error" }, { "inputs": [ { "internalType": "uint256", "name": "unexpected", "type": "uint256" } ], "name": "UnsupportedMajorType", "type": "error" }, { "inputs": [ { "internalType": "uint256", "name": "primitive", "type": "uint256" } ], "name": "UnsupportedPrimitive", "type": "error" } ], "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EmptyArray\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidLengthEncoding\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"read\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"}],\"name\":\"UnexpectedMajorType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"unexpected\",\"type\":\"uint256\"}],\"name\":\"UnsupportedMajorType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"primitive\",\"type\":\"uint256\"}],\"name\":\"UnsupportedPrimitive\",\"type\":\"error\"}],\"devdoc\":{\"author\":\"The Witnet Foundation.\",\"details\":\"Most of the logic has been borrowed from Patrick Gansterer\\u2019s cbor.js library: https://github.com/paroga/cbor-js\",\"kind\":\"dev\",\"methods\":{},\"title\":\"A minimalistic implementation of \\u201cRFC 7049 Concise Binary Object Representation\\u201d\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"This library leverages a buffer-like structure for step-by-step decoding of bytes so as to minimize the gas cost of decoding them into a useful native type.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"project:/contracts/libs/WitnetCBOR.sol\":\"WitnetCBOR\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"project:/contracts/libs/WitnetBuffer.sol\":{\"keccak256\":\"0xa14570492eb5a313ddbacae0185c850ec99c67211eb33989a5e21d31bf06a150\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e83c11edb49cab6a767c0b685825bc22ece0d3d2897e0d54fe1923df5cc76ba5\",\"dweb:/ipfs/QmdLDgCc3tnKbgRrXwfNzsg6uUDirNmjvBB8V3iMmnD69a\"]},\"project:/contracts/libs/WitnetCBOR.sol\":{\"keccak256\":\"0xb346547ff731163beea2c657c52675cdf7936691d566a76a045577cf9c34ade0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6d4b5b6424a033584b41f1204d635db98fda9ca9bd2a614c9d82539a3e4e6529\",\"dweb:/ipfs/QmW6Qy3wWpzHSECYaCPaf9LWGfPqWDKVoP2kPSNNQu7LMQ\"]}},\"version\":1}", "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a5bfe42e8bf3fec6aa4642967f703d5bc2a70cb662ef6d7ee4a5d8d2d41927dd64736f6c63430008190033", "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a5bfe42e8bf3fec6aa4642967f703d5bc2a70cb662ef6d7ee4a5d8d2d41927dd64736f6c63430008190033", "immutableReferences": {}, "generatedSources": [], "deployedGeneratedSources": [], "sourceMap": "536:19008:66:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;536:19008:66;;;;;;;;;;;;;;;;;", "deployedSourceMap": "536:19008:66:-:0;;;;;;;;", "source": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity >=0.8.0 <0.9.0;\r\n\r\nimport \"./WitnetBuffer.sol\";\r\n\r\n/// @title A minimalistic implementation of “RFC 7049 Concise Binary Object Representation”\r\n/// @notice This library leverages a buffer-like structure for step-by-step decoding of bytes so as to minimize\r\n/// the gas cost of decoding them into a useful native type.\r\n/// @dev Most of the logic has been borrowed from Patrick Gansterer’s cbor.js library: https://github.com/paroga/cbor-js\r\n/// @author The Witnet Foundation.\r\n\r\nlibrary WitnetCBOR {\r\n\r\n using WitnetBuffer for WitnetBuffer.Buffer;\r\n using WitnetCBOR for WitnetCBOR.CBOR;\r\n\r\n /// Data struct following the RFC-7049 standard: Concise Binary Object Representation.\r\n struct CBOR {\r\n WitnetBuffer.Buffer buffer;\r\n uint8 initialByte;\r\n uint8 majorType;\r\n uint8 additionalInformation;\r\n uint64 len;\r\n uint64 tag;\r\n }\r\n\r\n uint8 internal constant MAJOR_TYPE_INT = 0;\r\n uint8 internal constant MAJOR_TYPE_NEGATIVE_INT = 1;\r\n uint8 internal constant MAJOR_TYPE_BYTES = 2;\r\n uint8 internal constant MAJOR_TYPE_STRING = 3;\r\n uint8 internal constant MAJOR_TYPE_ARRAY = 4;\r\n uint8 internal constant MAJOR_TYPE_MAP = 5;\r\n uint8 internal constant MAJOR_TYPE_TAG = 6;\r\n uint8 internal constant MAJOR_TYPE_CONTENT_FREE = 7;\r\n\r\n uint32 internal constant UINT32_MAX = type(uint32).max;\r\n uint64 internal constant UINT64_MAX = type(uint64).max;\r\n \r\n error EmptyArray();\r\n error InvalidLengthEncoding(uint length);\r\n error UnexpectedMajorType(uint read, uint expected);\r\n error UnsupportedPrimitive(uint primitive);\r\n error UnsupportedMajorType(uint unexpected); \r\n\r\n modifier isMajorType(\r\n WitnetCBOR.CBOR memory cbor,\r\n uint8 expected\r\n ) {\r\n if (cbor.majorType != expected) {\r\n revert UnexpectedMajorType(cbor.majorType, expected);\r\n }\r\n _;\r\n }\r\n\r\n modifier notEmpty(WitnetBuffer.Buffer memory buffer) {\r\n if (buffer.data.length == 0) {\r\n revert WitnetBuffer.EmptyBuffer();\r\n }\r\n _;\r\n }\r\n\r\n function eof(CBOR memory cbor)\r\n internal pure\r\n returns (bool)\r\n {\r\n return cbor.buffer.cursor >= cbor.buffer.data.length;\r\n }\r\n\r\n /// @notice Decode a CBOR structure from raw bytes.\r\n /// @dev This is the main factory for CBOR instances, which can be later decoded into native EVM types.\r\n /// @param bytecode Raw bytes representing a CBOR-encoded value.\r\n /// @return A `CBOR` instance containing a partially decoded value.\r\n function fromBytes(bytes memory bytecode)\r\n internal pure\r\n returns (CBOR memory)\r\n {\r\n WitnetBuffer.Buffer memory buffer = WitnetBuffer.Buffer(bytecode, 0);\r\n return fromBuffer(buffer);\r\n }\r\n\r\n /// @notice Decode a CBOR structure from raw bytes.\r\n /// @dev This is an alternate factory for CBOR instances, which can be later decoded into native EVM types.\r\n /// @param buffer A Buffer structure representing a CBOR-encoded value.\r\n /// @return A `CBOR` instance containing a partially decoded value.\r\n function fromBuffer(WitnetBuffer.Buffer memory buffer)\r\n internal pure\r\n notEmpty(buffer)\r\n returns (CBOR memory)\r\n {\r\n uint8 initialByte;\r\n uint8 majorType = 255;\r\n uint8 additionalInformation;\r\n uint64 tag = UINT64_MAX;\r\n uint256 len;\r\n bool isTagged = true;\r\n while (isTagged) {\r\n // Extract basic CBOR properties from input bytes\r\n initialByte = buffer.readUint8();\r\n len ++;\r\n majorType = initialByte >> 5;\r\n additionalInformation = initialByte & 0x1f;\r\n // Early CBOR tag parsing.\r\n if (majorType == MAJOR_TYPE_TAG) {\r\n uint _cursor = buffer.cursor;\r\n tag = readLength(buffer, additionalInformation);\r\n len += buffer.cursor - _cursor;\r\n } else {\r\n isTagged = false;\r\n }\r\n }\r\n if (majorType > MAJOR_TYPE_CONTENT_FREE) {\r\n revert UnsupportedMajorType(majorType);\r\n }\r\n return CBOR(\r\n buffer,\r\n initialByte,\r\n majorType,\r\n additionalInformation,\r\n uint64(len),\r\n tag\r\n );\r\n }\r\n\r\n function fork(WitnetCBOR.CBOR memory self)\r\n internal pure\r\n returns (WitnetCBOR.CBOR memory)\r\n {\r\n return CBOR({\r\n buffer: self.buffer.fork(),\r\n initialByte: self.initialByte,\r\n majorType: self.majorType,\r\n additionalInformation: self.additionalInformation,\r\n len: self.len,\r\n tag: self.tag\r\n });\r\n }\r\n\r\n function settle(CBOR memory self)\r\n internal pure\r\n returns (WitnetCBOR.CBOR memory)\r\n {\r\n if (!self.eof()) {\r\n return fromBuffer(self.buffer);\r\n } else {\r\n return self;\r\n }\r\n }\r\n\r\n function skip(CBOR memory self)\r\n internal pure\r\n returns (WitnetCBOR.CBOR memory)\r\n {\r\n if (\r\n self.majorType == MAJOR_TYPE_INT\r\n || self.majorType == MAJOR_TYPE_NEGATIVE_INT\r\n || (\r\n self.majorType == MAJOR_TYPE_CONTENT_FREE \r\n && self.additionalInformation >= 25\r\n && self.additionalInformation <= 27\r\n )\r\n ) {\r\n self.buffer.cursor += self.peekLength();\r\n } else if (\r\n self.majorType == MAJOR_TYPE_STRING\r\n || self.majorType == MAJOR_TYPE_BYTES\r\n ) {\r\n uint64 len = readLength(self.buffer, self.additionalInformation);\r\n self.buffer.cursor += len;\r\n } else if (\r\n self.majorType == MAJOR_TYPE_ARRAY\r\n || self.majorType == MAJOR_TYPE_MAP\r\n ) { \r\n self.len = readLength(self.buffer, self.additionalInformation); \r\n } else if (\r\n self.majorType != MAJOR_TYPE_CONTENT_FREE\r\n || (\r\n self.additionalInformation != 20\r\n && self.additionalInformation != 21\r\n )\r\n ) {\r\n revert(\"WitnetCBOR.skip: unsupported major type\");\r\n }\r\n return self;\r\n }\r\n\r\n function peekLength(CBOR memory self)\r\n internal pure\r\n returns (uint64)\r\n {\r\n if (self.additionalInformation < 24) {\r\n return 0;\r\n } else if (self.additionalInformation < 28) {\r\n return uint64(1 << (self.additionalInformation - 24));\r\n } else {\r\n revert InvalidLengthEncoding(self.additionalInformation);\r\n }\r\n }\r\n\r\n function readArray(CBOR memory self)\r\n internal pure\r\n isMajorType(self, MAJOR_TYPE_ARRAY)\r\n returns (CBOR[] memory items)\r\n {\r\n // read array's length and move self cursor forward to the first array element:\r\n uint64 len = readLength(self.buffer, self.additionalInformation);\r\n items = new CBOR[](len + 1);\r\n for (uint ix = 0; ix < len; ix ++) {\r\n // settle next element in the array:\r\n self = self.settle();\r\n // fork it and added to the list of items to be returned:\r\n items[ix] = self.fork();\r\n if (self.majorType == MAJOR_TYPE_ARRAY) {\r\n CBOR[] memory _subitems = self.readArray();\r\n // move forward to the first element after inner array:\r\n self = _subitems[_subitems.length - 1];\r\n } else if (self.majorType == MAJOR_TYPE_MAP) {\r\n CBOR[] memory _subitems = self.readMap();\r\n // move forward to the first element after inner map:\r\n self = _subitems[_subitems.length - 1];\r\n } else {\r\n // move forward to the next element:\r\n self.skip();\r\n }\r\n }\r\n // return self cursor as extra item at the end of the list,\r\n // as to optimize recursion when jumping over nested arrays:\r\n items[len] = self;\r\n }\r\n\r\n function readMap(CBOR memory self)\r\n internal pure\r\n isMajorType(self, MAJOR_TYPE_MAP)\r\n returns (CBOR[] memory items)\r\n {\r\n // read number of items within the map and move self cursor forward to the first inner element:\r\n uint64 len = readLength(self.buffer, self.additionalInformation) * 2;\r\n items = new CBOR[](len + 1);\r\n for (uint ix = 0; ix < len; ix ++) {\r\n // settle next element in the array:\r\n self = self.settle();\r\n // fork it and added to the list of items to be returned:\r\n items[ix] = self.fork();\r\n if (ix % 2 == 0 && self.majorType != MAJOR_TYPE_STRING) {\r\n revert UnexpectedMajorType(self.majorType, MAJOR_TYPE_STRING);\r\n } else if (self.majorType == MAJOR_TYPE_ARRAY || self.majorType == MAJOR_TYPE_MAP) {\r\n CBOR[] memory _subitems = (self.majorType == MAJOR_TYPE_ARRAY\r\n ? self.readArray()\r\n : self.readMap()\r\n );\r\n // move forward to the first element after inner array or map:\r\n self = _subitems[_subitems.length - 1];\r\n } else {\r\n // move forward to the next element:\r\n self.skip();\r\n }\r\n }\r\n // return self cursor as extra item at the end of the list,\r\n // as to optimize recursion when jumping over nested arrays:\r\n items[len] = self;\r\n }\r\n\r\n /// Reads the length of the settle CBOR item from a buffer, consuming a different number of bytes depending on the\r\n /// value of the `additionalInformation` argument.\r\n function readLength(\r\n WitnetBuffer.Buffer memory buffer,\r\n uint8 additionalInformation\r\n ) \r\n internal pure\r\n returns (uint64)\r\n {\r\n if (additionalInformation < 24) {\r\n return additionalInformation;\r\n }\r\n if (additionalInformation == 24) {\r\n return buffer.readUint8();\r\n }\r\n if (additionalInformation == 25) {\r\n return buffer.readUint16();\r\n }\r\n if (additionalInformation == 26) {\r\n return buffer.readUint32();\r\n }\r\n if (additionalInformation == 27) {\r\n return buffer.readUint64();\r\n }\r\n if (additionalInformation == 31) {\r\n return UINT64_MAX;\r\n }\r\n revert InvalidLengthEncoding(additionalInformation);\r\n }\r\n\r\n /// @notice Read a `CBOR` structure into a native `bool` value.\r\n /// @param cbor An instance of `CBOR`.\r\n /// @return The value represented by the input, as a `bool` value.\r\n function readBool(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_CONTENT_FREE)\r\n returns (bool)\r\n {\r\n if (cbor.additionalInformation == 20) {\r\n return false;\r\n } else if (cbor.additionalInformation == 21) {\r\n return true;\r\n } else {\r\n revert UnsupportedPrimitive(cbor.additionalInformation);\r\n }\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a native `bytes` value.\r\n /// @param cbor An instance of `CBOR`.\r\n /// @return output The value represented by the input, as a `bytes` value. \r\n function readBytes(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_BYTES)\r\n returns (bytes memory output)\r\n {\r\n cbor.len = readLength(\r\n cbor.buffer,\r\n cbor.additionalInformation\r\n );\r\n if (cbor.len == UINT32_MAX) {\r\n // These checks look repetitive but the equivalent loop would be more expensive.\r\n uint32 length = uint32(_readIndefiniteStringLength(\r\n cbor.buffer,\r\n cbor.majorType\r\n ));\r\n if (length < UINT32_MAX) {\r\n output = abi.encodePacked(cbor.buffer.read(length));\r\n length = uint32(_readIndefiniteStringLength(\r\n cbor.buffer,\r\n cbor.majorType\r\n ));\r\n if (length < UINT32_MAX) {\r\n output = abi.encodePacked(\r\n output,\r\n cbor.buffer.read(length)\r\n );\r\n }\r\n }\r\n } else {\r\n return cbor.buffer.read(uint32(cbor.len));\r\n }\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a `fixed16` value.\r\n /// @dev Due to the lack of support for floating or fixed point arithmetic in the EVM, this method offsets all values\r\n /// by 5 decimal orders so as to get a fixed precision of 5 decimal positions, which should be OK for most `fixed16`\r\n /// use cases. In other words, the output of this method is 10,000 times the actual value, encoded into an `int32`.\r\n /// @param cbor An instance of `CBOR`.\r\n /// @return The value represented by the input, as an `int128` value.\r\n function readFloat16(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_CONTENT_FREE)\r\n returns (int32)\r\n {\r\n if (cbor.additionalInformation == 25) {\r\n return cbor.buffer.readFloat16();\r\n } else {\r\n revert UnsupportedPrimitive(cbor.additionalInformation);\r\n }\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a `fixed32` value.\r\n /// @dev Due to the lack of support for floating or fixed point arithmetic in the EVM, this method offsets all values\r\n /// by 9 decimal orders so as to get a fixed precision of 9 decimal positions, which should be OK for most `fixed64`\r\n /// use cases. In other words, the output of this method is 10^9 times the actual value, encoded into an `int`.\r\n /// @param cbor An instance of `CBOR`.\r\n /// @return The value represented by the input, as an `int` value.\r\n function readFloat32(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_CONTENT_FREE)\r\n returns (int)\r\n {\r\n if (cbor.additionalInformation == 26) {\r\n return cbor.buffer.readFloat32();\r\n } else {\r\n revert UnsupportedPrimitive(cbor.additionalInformation);\r\n }\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a `fixed64` value.\r\n /// @dev Due to the lack of support for floating or fixed point arithmetic in the EVM, this method offsets all values\r\n /// by 15 decimal orders so as to get a fixed precision of 15 decimal positions, which should be OK for most `fixed64`\r\n /// use cases. In other words, the output of this method is 10^15 times the actual value, encoded into an `int`.\r\n /// @param cbor An instance of `CBOR`.\r\n /// @return The value represented by the input, as an `int` value.\r\n function readFloat64(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_CONTENT_FREE)\r\n returns (int)\r\n {\r\n if (cbor.additionalInformation == 27) {\r\n return cbor.buffer.readFloat64();\r\n } else {\r\n revert UnsupportedPrimitive(cbor.additionalInformation);\r\n }\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a native `int128[]` value whose inner values follow the same convention \r\n /// @notice as explained in `decodeFixed16`.\r\n /// @param cbor An instance of `CBOR`.\r\n function readFloat16Array(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_ARRAY)\r\n returns (int32[] memory values)\r\n {\r\n uint64 length = readLength(cbor.buffer, cbor.additionalInformation);\r\n if (length < UINT64_MAX) {\r\n values = new int32[](length);\r\n for (uint64 i = 0; i < length; ) {\r\n CBOR memory item = fromBuffer(cbor.buffer);\r\n values[i] = readFloat16(item);\r\n unchecked {\r\n i ++;\r\n }\r\n }\r\n } else {\r\n revert InvalidLengthEncoding(length);\r\n }\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a native `int128` value.\r\n /// @param cbor An instance of `CBOR`.\r\n /// @return The value represented by the input, as an `int128` value.\r\n function readInt(CBOR memory cbor)\r\n internal pure\r\n returns (int)\r\n {\r\n if (cbor.majorType == 1) {\r\n uint64 _value = readLength(\r\n cbor.buffer,\r\n cbor.additionalInformation\r\n );\r\n return int(-1) - int(uint(_value));\r\n } else if (cbor.majorType == 0) {\r\n // Any `uint64` can be safely casted to `int128`, so this method supports majorType 1 as well so as to have offer\r\n // a uniform API for positive and negative numbers\r\n return int(readUint(cbor));\r\n }\r\n else {\r\n revert UnexpectedMajorType(cbor.majorType, 1);\r\n }\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a native `int[]` value.\r\n /// @param cbor instance of `CBOR`.\r\n /// @return array The value represented by the input, as an `int[]` value.\r\n function readIntArray(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_ARRAY)\r\n returns (int[] memory array)\r\n {\r\n uint64 length = readLength(cbor.buffer, cbor.additionalInformation);\r\n if (length < UINT64_MAX) {\r\n array = new int[](length);\r\n for (uint i = 0; i < length; ) {\r\n CBOR memory item = fromBuffer(cbor.buffer);\r\n array[i] = readInt(item);\r\n unchecked {\r\n i ++;\r\n }\r\n }\r\n } else {\r\n revert InvalidLengthEncoding(length);\r\n }\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a native `string` value.\r\n /// @param cbor An instance of `CBOR`.\r\n /// @return text The value represented by the input, as a `string` value.\r\n function readString(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_STRING)\r\n returns (string memory text)\r\n {\r\n cbor.len = readLength(cbor.buffer, cbor.additionalInformation);\r\n if (cbor.len == UINT64_MAX) {\r\n bool _done;\r\n while (!_done) {\r\n uint64 length = _readIndefiniteStringLength(\r\n cbor.buffer,\r\n cbor.majorType\r\n );\r\n if (length < UINT64_MAX) {\r\n text = string(abi.encodePacked(\r\n text,\r\n cbor.buffer.readText(length / 4)\r\n ));\r\n } else {\r\n _done = true;\r\n }\r\n }\r\n } else {\r\n return string(cbor.buffer.readText(cbor.len));\r\n }\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a native `string[]` value.\r\n /// @param cbor An instance of `CBOR`.\r\n /// @return strings The value represented by the input, as an `string[]` value.\r\n function readStringArray(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_ARRAY)\r\n returns (string[] memory strings)\r\n {\r\n uint length = readLength(cbor.buffer, cbor.additionalInformation);\r\n if (length < UINT64_MAX) {\r\n strings = new string[](length);\r\n for (uint i = 0; i < length; ) {\r\n CBOR memory item = fromBuffer(cbor.buffer);\r\n strings[i] = readString(item);\r\n unchecked {\r\n i ++;\r\n }\r\n }\r\n } else {\r\n revert InvalidLengthEncoding(length);\r\n }\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a native `uint64` value.\r\n /// @param cbor An instance of `CBOR`.\r\n /// @return The value represented by the input, as an `uint64` value.\r\n function readUint(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_INT)\r\n returns (uint)\r\n {\r\n return readLength(\r\n cbor.buffer,\r\n cbor.additionalInformation\r\n );\r\n }\r\n\r\n /// @notice Decode a `CBOR` structure into a native `uint64[]` value.\r\n /// @param cbor An instance of `CBOR`.\r\n /// @return values The value represented by the input, as an `uint64[]` value.\r\n function readUintArray(CBOR memory cbor)\r\n internal pure\r\n isMajorType(cbor, MAJOR_TYPE_ARRAY)\r\n returns (uint[] memory values)\r\n {\r\n uint64 length = readLength(cbor.buffer, cbor.additionalInformation);\r\n if (length < UINT64_MAX) {\r\n values = new uint[](length);\r\n for (uint ix = 0; ix < length; ) {\r\n CBOR memory item = fromBuffer(cbor.buffer);\r\n values[ix] = readUint(item);\r\n unchecked {\r\n ix ++;\r\n }\r\n }\r\n } else {\r\n revert InvalidLengthEncoding(length);\r\n }\r\n } \r\n\r\n /// Read the length of a CBOR indifinite-length item (arrays, maps, byte strings and text) from a buffer, consuming\r\n /// as many bytes as specified by the first byte.\r\n function _readIndefiniteStringLength(\r\n WitnetBuffer.Buffer memory buffer,\r\n uint8 majorType\r\n )\r\n private pure\r\n returns (uint64 len)\r\n {\r\n uint8 initialByte = buffer.readUint8();\r\n if (initialByte == 0xff) {\r\n return UINT64_MAX;\r\n }\r\n len = readLength(\r\n buffer,\r\n initialByte & 0x1f\r\n );\r\n if (len >= UINT64_MAX) {\r\n revert InvalidLengthEncoding(len);\r\n } else if (majorType != (initialByte >> 5)) {\r\n revert UnexpectedMajorType((initialByte >> 5), majorType);\r\n }\r\n }\r\n \r\n}", "sourcePath": "C:\\Users\\guill\\github\\witnet\\witnet-solidity-bridge\\contracts\\libs\\WitnetCBOR.sol", "ast": { "absolutePath": "project:/contracts/libs/WitnetCBOR.sol", "exportedSymbols": { "WitnetBuffer": [ 19191 ], "WitnetCBOR": [ 20734 ] }, "id": 20735, "license": "MIT", "nodeType": "SourceUnit", "nodes": [ { "id": 19193, "literals": [ "solidity", ">=", "0.8", ".0", "<", "0.9", ".0" ], "nodeType": "PragmaDirective", "src": "35:31:66" }, { "absolutePath": "project:/contracts/libs/WitnetBuffer.sol", "file": "./WitnetBuffer.sol", "id": 19194, "nameLocation": "-1:-1:-1", "nodeType": "ImportDirective", "scope": 20735, "sourceUnit": 19192, "src": "70:28:66", "symbolAliases": [], "unitAlias": "" }, { "abstract": false, "baseContracts": [], "canonicalName": "WitnetCBOR", "contractDependencies": [], "contractKind": "library", "documentation": { "id": 19195, "nodeType": "StructuredDocumentation", "src": "102:432:66", "text": "@title A minimalistic implementation of “RFC 7049 Concise Binary Object Representation”\n @notice This library leverages a buffer-like structure for step-by-step decoding of bytes so as to minimize\n the gas cost of decoding them into a useful native type.\n @dev Most of the logic has been borrowed from Patrick Gansterer’s cbor.js library: https://github.com/paroga/cbor-js\n @author The Witnet Foundation." }, "fullyImplemented": true, "id": 20734, "linearizedBaseContracts": [ 20734 ], "name": "WitnetCBOR", "nameLocation": "544:10:66", "nodeType": "ContractDefinition", "nodes": [ { "global": false, "id": 19199, "libraryName": { "id": 19196, "name": "WitnetBuffer", "nameLocations": [ "568:12:66" ], "nodeType": "IdentifierPath", "referencedDeclaration": 19191, "src": "568:12:66" }, "nodeType": "UsingForDirective", "src": "562:43:66", "typeName": { "id": 19198, "nodeType": "UserDefinedTypeName", "pathNode": { "id": 19197, "name": "WitnetBuffer.Buffer", "nameLocations": [ "585:12:66", "598:6:66" ], "nodeType": "IdentifierPath", "referencedDeclaration": 17580, "src": "585:19:66" }, "referencedDeclaration": 17580, "src": "585:19:66", "typeDescriptions": { "typeIdentifier": "t_struct$_Buffer_$17580_storage_ptr", "typeString": "struct WitnetBuffer.Buffer" } } }, { "global": false, "id": 19203, "libraryName": { "id": 19200, "name": "WitnetCBOR", "nameLocations": [ "615:10:66" ], "nodeType": "IdentifierPath", "referencedDeclaration": 20734, "src": "615:10:66" }, "nodeType": "UsingForDirective", "src": "609:37:66", "typeName": { "id": 19202, "nodeType": "UserDefinedTypeName", "pathNode": { "id": 19201, "name": "WitnetCBOR.CBOR", "nameLocations": [ "630:10:66", "641:4:66" ], "nodeType": "IdentifierPath", "referencedDeclaration": 19218, "src": "630:15:66" }, "referencedDeclaration": 19218, "src": "630:15:66", "typeDescriptions": { "typeIdentifier": "t_struct$_CBOR_$19218_storage_ptr", "typeString": "struct WitnetCBOR.CBOR" } } }, { "canonicalName": "WitnetCBOR.CBOR", "documentation": { "id": 19204, "nodeType": "StructuredDocumentation", "src": "652:86:66", "text": "Data struct following the RFC-7049 standard: Concise Binary Object Representation." }, "id": 19218, "members": [ { "constant": false, "id": 19207, "mutability": "mutable", "name": "buffer", "nameLocation": "783:6:66", "nodeType": "VariableDeclaration", "scope": 19218, "src": "763:26:66", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_struct$_Buffer_$17580_storage_ptr", "typeString": "struct WitnetBuffer.Buffer" }, "typeName": { "id": 19206, "nodeType": "UserDefinedTypeName", "pathNode": { "id": 19205, "name": "WitnetBuffer.Buffer", "nameLocations": [ "763:12:66", "776:6:66" ], "nodeType": "IdentifierPath", "referencedDeclaration": 17580, "src": "763:19:66" }, "referencedDeclaration": 17580, "src": "763:19:66", "typeDescriptions": { "typeIdentifier": "t_struct$_Buffer_$17580_storage_ptr", "typeString": "struct WitnetBuffer.Buffer" } }, "visibility": "internal" }, { "constant": false, "id": 19209, "mutability": "mutable", "name": "initialByte", "nameLocation": "804:11:66", "nodeType": "VariableDeclaration", "scope": 19218, "src": "798:17:66", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19208, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "798:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "visibility": "internal" }, { "constant": false, "id": 19211, "mutability": "mutable", "name": "majorType", "nameLocation": "830:9:66", "nodeType": "VariableDeclaration", "scope": 19218, "src": "824:15:66", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19210, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "824:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "visibility": "internal" }, { "constant": false, "id": 19213, "mutability": "mutable", "name": "additionalInformation", "nameLocation": "854:21:66", "nodeType": "VariableDeclaration", "scope": 19218, "src": "848:27:66", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19212, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "848:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "visibility": "internal" }, { "constant": false, "id": 19215, "mutability": "mutable", "name": "len", "nameLocation": "891:3:66", "nodeType": "VariableDeclaration", "scope": 19218, "src": "884:10:66", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint64", "typeString": "uint64" }, "typeName": { "id": 19214, "name": "uint64", "nodeType": "ElementaryTypeName", "src": "884:6:66", "typeDescriptions": { "typeIdentifier": "t_uint64", "typeString": "uint64" } }, "visibility": "internal" }, { "constant": false, "id": 19217, "mutability": "mutable", "name": "tag", "nameLocation": "910:3:66", "nodeType": "VariableDeclaration", "scope": 19218, "src": "903:10:66", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint64", "typeString": "uint64" }, "typeName": { "id": 19216, "name": "uint64", "nodeType": "ElementaryTypeName", "src": "903:6:66", "typeDescriptions": { "typeIdentifier": "t_uint64", "typeString": "uint64" } }, "visibility": "internal" } ], "name": "CBOR", "nameLocation": "749:4:66", "nodeType": "StructDefinition", "scope": 20734, "src": "742:177:66", "visibility": "public" }, { "constant": true, "id": 19221, "mutability": "constant", "name": "MAJOR_TYPE_INT", "nameLocation": "949:14:66", "nodeType": "VariableDeclaration", "scope": 20734, "src": "925:42:66", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19219, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "925:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "value": { "hexValue": "30", "id": 19220, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "966:1:66", "typeDescriptions": { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" }, "value": "0" }, "visibility": "internal" }, { "constant": true, "id": 19224, "mutability": "constant", "name": "MAJOR_TYPE_NEGATIVE_INT", "nameLocation": "996:23:66", "nodeType": "VariableDeclaration", "scope": 20734, "src": "972:51:66", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19222, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "972:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "value": { "hexValue": "31", "id": 19223, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "1022:1:66", "typeDescriptions": { "typeIdentifier": "t_rational_1_by_1", "typeString": "int_const 1" }, "value": "1" }, "visibility": "internal" }, { "constant": true, "id": 19227, "mutability": "constant", "name": "MAJOR_TYPE_BYTES", "nameLocation": "1052:16:66", "nodeType": "VariableDeclaration", "scope": 20734, "src": "1028:44:66", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19225, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "1028:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "value": { "hexValue": "32", "id": 19226, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "1071:1:66", "typeDescriptions": { "typeIdentifier": "t_rational_2_by_1", "typeString": "int_const 2" }, "value": "2" }, "visibility": "internal" }, { "constant": true, "id": 19230, "mutability": "constant", "name": "MAJOR_TYPE_STRING", "nameLocation": "1101:17:66", "nodeType": "VariableDeclaration", "scope": 20734, "src": "1077:45:66", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19228, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "1077:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "value": { "hexValue": "33", "id": 19229, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "1121:1:66", "typeDescriptions": { "typeIdentifier": "t_rational_3_by_1", "typeString": "int_const 3" }, "value": "3" }, "visibility": "internal" }, { "constant": true, "id": 19233, "mutability": "constant", "name": "MAJOR_TYPE_ARRAY", "nameLocation": "1151:16:66", "nodeType": "VariableDeclaration", "scope": 20734, "src": "1127:44:66", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19231, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "1127:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "value": { "hexValue": "34", "id": 19232, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "1170:1:66", "typeDescriptions": { "typeIdentifier": "t_rational_4_by_1", "typeString": "int_const 4" }, "value": "4" }, "visibility": "internal" }, { "constant": true, "id": 19236, "mutability": "constant", "name": "MAJOR_TYPE_MAP", "nameLocation": "1200:14:66", "nodeType": "VariableDeclaration", "scope": 20734, "src": "1176:42:66", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19234, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "1176:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "value": { "hexValue": "35", "id": 19235, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "1217:1:66", "typeDescriptions": { "typeIdentifier": "t_rational_5_by_1", "typeString": "int_const 5" }, "value": "5" }, "visibility": "internal" }, { "constant": true, "id": 19239, "mutability": "constant", "name": "MAJOR_TYPE_TAG", "nameLocation": "1247:14:66", "nodeType": "VariableDeclaration", "scope": 20734, "src": "1223:42:66", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19237, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "1223:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "value": { "hexValue": "36", "id": 19238, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "1264:1:66", "typeDescriptions": { "typeIdentifier": "t_rational_6_by_1", "typeString": "int_const 6" }, "value": "6" }, "visibility": "internal" }, { "constant": true, "id": 19242, "mutability": "constant", "name": "MAJOR_TYPE_CONTENT_FREE", "nameLocation": "1294:23:66", "nodeType": "VariableDeclaration", "scope": 20734, "src": "1270:51:66", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, "typeName": { "id": 19240, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "1270:5:66", "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } }, "value": { "hexValue": "37", "id": 19241, "isConstant": false, "isLValue": false, "isPure": true, "kind": "number", "lValueRequested": false, "nodeType": "Literal", "src": "1320:1:66", "typeDescriptions": { "typeIdentifier": "t_rational_7_by_1", "typeString": "int_const 7" }, "value": "7" }, "visibility": "internal" }, { "constant": true, "id": 19249, "mutability": "constant", "name": "UINT32_MAX", "nameLocation": "1353:10:66", "nodeType": "VariableDeclaration", "scope": 20734, "src": "1328:54:66", "stateVariable": true, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_uint32", "typeString": "uint32" }, "typeName": { "id": 19243, "name": "uint32", "nodeType": "ElementaryTypeName", "src": "1328:6:66", "typeDescriptions": { "typeIdentifier": "t_uint32", "typeString": "uint32" } }, "value": { "expression": { "arguments": [ { "id": 19246, "isConstant": false, "isLValue": false, "isPure": true, "lValueRequested": false, "nodeType": "ElementaryTypeNameExpression", "src": "1371:6:66", "typeDescriptions": { "typeIdentifier": "t_type$_t_uint32_$", "typeString": "type(uint32)" }, "typeName": { "id": 19245, "name": "uint32", "nodeType": "ElementaryTypeName", "src": "1371:6:66", "typeDescriptions": {} } } ], "expression": { "argumentTypes": [ { "typeIdentifier": "t_type$_t_uint32_$", "typeString": "type(uint32)" } ], "id": 19244, "name": "type", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 4294967269, "src": "1366:4:66", "typeDescriptions": { "typeIdentifier": "t_function_metatype_pure$__$returns$__$", "typeString": "function () pure" } }, "id": 19247, "isConstant": false, "isLValue": false, "isPure": true, "kind": "functionCall", "lValueRequested": false, "nameLocations": [], "names": [], "nodeType": "FunctionCall", "src": "1366:12:66",