UNPKG

kleros-interaction-2

Version:
796 lines (795 loc) 225 kB
{ "contractName": "BytesLib", "abi": [], "bytecode": "0x604c602c600b82828239805160001a60731460008114601c57601e565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600080fd00a165627a7a72305820c56bc2c56eb23f565dbdb65da5dccbd72fc855f5112d4da72147433b3307ff540029", "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fd00a165627a7a72305820c56bc2c56eb23f565dbdb65da5dccbd72fc855f5112d4da72147433b3307ff540029", "sourceMap": "326:16501:68:-;;132:2:-1;166:7;155:9;146:7;137:37;252:7;246:14;243:1;238:23;232:4;229:33;270:1;265:20;;;;222:63;;265:20;274:9;222:63;;298:9;295:1;288:20;328:4;319:7;311:22;352:7;343;336:24", "deployedSourceMap": "326:16501:68:-;;;;;;;;", "source": "/*\n * @title Solidity Bytes Arrays Utils\n * @author Gonçalo Sá <goncalo.sa@consensys.net>\n *\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n */\n\npragma solidity ^0.4.19;\n\n\nlibrary BytesLib {\n function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes) {\n bytes memory tempBytes;\n\n assembly {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // Store the length of the first bytes array at the beginning of\n // the memory for tempBytes.\n let length := mload(_preBytes)\n mstore(tempBytes, length)\n\n // Maintain a memory counter for the current write location in the\n // temp bytes array by adding the 32 bytes for the array length to\n // the starting location.\n let mc := add(tempBytes, 0x20)\n // Stop copying when the memory counter reaches the length of the\n // first bytes array.\n let end := add(mc, length)\n\n for {\n // Initialize a copy counter to the start of the _preBytes data,\n // 32 bytes into its memory.\n let cc := add(_preBytes, 0x20)\n } lt(mc, end) {\n // Increase both counters by 32 bytes each iteration.\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // Write the _preBytes data into the tempBytes memory 32 bytes\n // at a time.\n mstore(mc, mload(cc))\n }\n\n // Add the length of _postBytes to the current length of tempBytes\n // and store it as the new length in the first 32 bytes of the\n // tempBytes memory.\n length := mload(_postBytes)\n mstore(tempBytes, add(length, mload(tempBytes)))\n\n // Move the memory counter back from a multiple of 0x20 to the\n // actual end of the _preBytes data.\n mc := end\n // Stop copying when the memory counter reaches the new combined\n // length of the arrays.\n end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n // Update the free-memory pointer by padding our last write location\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n // next 32 byte block, then round down to the nearest multiple of\n // 32. If the sum of the length of the two arrays is zero then add \n // one before rounding down to leave a blank 32 bytes (the length block with 0).\n mstore(0x40, and(\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n not(31) // Round down to the nearest 32 bytes.\n ))\n }\n\n return tempBytes;\n }\n\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\n assembly {\n // Read the first 32 bytes of _preBytes storage, which is the length\n // of the array. (We don't need to use the offset into the slot\n // because arrays use the entire slot.)\n let fslot := sload(_preBytes_slot)\n // Arrays of 31 bytes or less have an even value in their slot,\n // while longer arrays have an odd value. The actual length is\n // the slot divided by two for odd values, and the lowest order\n // byte divided by two for even values.\n // If the slot is even, bitwise and the slot with 255 and divide by\n // two to get the length. If the slot is odd, bitwise and the slot\n // with -1 and divide by two.\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n let newlength := add(slength, mlength)\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n switch add(lt(slength, 32), lt(newlength, 32))\n case 2 {\n // Since the new array still fits in the slot, we just need to\n // update the contents of the slot.\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\n sstore(\n _preBytes_slot,\n // all the modifications to the slot are inside this\n // next block\n add(\n // we can just add to the slot contents because the\n // bytes we want to change are the LSBs\n fslot,\n add(\n mul(\n div(\n // load the bytes from memory\n mload(add(_postBytes, 0x20)),\n // zero all bytes to the right\n exp(0x100, sub(32, mlength))\n ),\n // and now shift left the number of bytes to\n // leave space for the length in the slot\n exp(0x100, sub(32, newlength))\n ),\n // increase length by the double of the memory\n // bytes length\n mul(mlength, 2)\n )\n )\n )\n }\n case 1 {\n // The stored value fits in the slot, but the combined value\n // will exceed it.\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes_slot)\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes_slot, add(mul(newlength, 2), 1))\n\n // The contents of the _postBytes array start 32 bytes into\n // the structure. Our first read should obtain the `submod`\n // bytes that can fit into the unused space in the last word\n // of the stored array. To get this, we read 32 bytes starting\n // from `submod`, so the data we read overlaps with the array\n // contents by `submod` bytes. Masking the lowest-order\n // `submod` bytes allows us to add that value directly to the\n // stored value.\n\n let submod := sub(32, slength)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(\n sc,\n add(\n and(\n fslot,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\n ),\n and(mload(mc), mask)\n )\n )\n\n for {\n mc := add(mc, 0x20)\n sc := add(sc, 1)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n default {\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes_slot)\n // Start copying to the last used word of the stored array.\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes_slot, add(mul(newlength, 2), 1))\n\n // Copy over the first `submod` bytes of the new data as in\n // case 1 above.\n let slengthmod := mod(slength, 32)\n let mlengthmod := mod(mlength, 32)\n let submod := sub(32, slengthmod)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\n \n for { \n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n }\n }\n\n function slice(bytes _bytes, uint _start, uint _length) internal pure returns (bytes) {\n require(_bytes.length >= (_start + _length));\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n function toAddress(bytes _bytes, uint _start) internal pure returns (address) {\n require(_bytes.length >= (_start + 20));\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint(bytes _bytes, uint _start) internal pure returns (uint256) {\n require(_bytes.length >= (_start + 32));\n uint256 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempUint;\n }\n\n function toBytes32(bytes _bytes, uint _start) internal pure returns (bytes32) {\n require(_bytes.length >= (_start + 32));\n bytes32 tempBytes32;\n\n assembly {\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempBytes32;\n }\n\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n bool success = true;\n\n assembly {\n let length := mload(_preBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(length, mload(_postBytes))\n case 1 {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n let mc := add(_preBytes, 0x20)\n let end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n // the next line is the loop condition:\n // while(uint(mc < end) + cb == 2)\n } eq(add(lt(mc, end), cb), 2) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // if any of these checks fails then arrays are not equal\n if iszero(eq(mload(mc), mload(cc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n\n function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {\n bool success = true;\n\n assembly {\n // we know _preBytes_offset is 0\n let fslot := sload(_preBytes_slot)\n // Decode the length of the stored array like in concatStorage().\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(slength, mlength)\n case 1 {\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n if iszero(iszero(slength)) {\n switch lt(slength, 32)\n case 1 {\n // blank the last byte which is the length\n fslot := mul(div(fslot, 0x100), 0x100)\n\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\n // unsuccess:\n success := 0\n }\n }\n default {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes_slot)\n let sc := keccak256(0x0, 0x20)\n\n let mc := add(_postBytes, 0x20)\n let end := add(mc, mlength)\n\n // the next line is the loop condition:\n // while(uint(mc < end) + cb == 2)\n for {} eq(add(lt(mc, end), cb), 2) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n if iszero(eq(sload(sc), mload(mc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n}\n", "sourcePath": "solidity-bytes-utils/contracts/BytesLib.sol", "ast": { "absolutePath": "solidity-bytes-utils/contracts/BytesLib.sol", "exportedSymbols": { "BytesLib": [ 20624 ] }, "id": 20625, "nodeType": "SourceUnit", "nodes": [ { "id": 20458, "literals": [ "solidity", "^", "0.4", ".19" ], "nodeType": "PragmaDirective", "src": "299:24:68" }, { "baseContracts": [], "contractDependencies": [], "contractKind": "library", "documentation": null, "fullyImplemented": true, "id": 20624, "linearizedBaseContracts": [ 20624 ], "name": "BytesLib", "nodeType": "ContractDefinition", "nodes": [ { "body": { "id": 20473, "nodeType": "Block", "src": "444:2804:68", "statements": [ { "assignments": [], "declarations": [ { "constant": false, "id": 20468, "name": "tempBytes", "nodeType": "VariableDeclaration", "scope": 20474, "src": "454:22:68", "stateVariable": false, "storageLocation": "memory", "typeDescriptions": { "typeIdentifier": "t_bytes_memory_ptr", "typeString": "bytes" }, "typeName": { "id": 20467, "name": "bytes", "nodeType": "ElementaryTypeName", "src": "454:5:68", "typeDescriptions": { "typeIdentifier": "t_bytes_storage_ptr", "typeString": "bytes" } }, "value": null, "visibility": "internal" } ], "id": 20469, "initialValue": null, "nodeType": "VariableDeclarationStatement", "src": "454:22:68" }, { "externalReferences": [ { "tempBytes": { "declaration": 20468, "isOffset": false, "isSlot": false, "src": "640:9:68", "valueSize": 1 } }, { "_preBytes": { "declaration": 20460, "isOffset": false, "isSlot": false, "src": "816:9:68", "valueSize": 1 } }, { "tempBytes": { "declaration": 20468, "isOffset": false, "isSlot": false, "src": "846:9:68", "valueSize": 1 } }, { "_preBytes": { "declaration": 20460, "isOffset": false, "isSlot": false, "src": "1431:9:68", "valueSize": 1 } }, { "tempBytes": { "declaration": 20468, "isOffset": false, "isSlot": false, "src": "1088:9:68", "valueSize": 1 } }, { "_postBytes": { "declaration": 20462, "isOffset": false, "isSlot": false, "src": "2429:10:68", "valueSize": 1 } }, { "_postBytes": { "declaration": 20462, "isOffset": false, "isSlot": false, "src": "2011:10:68", "valueSize": 1 } }, { "tempBytes": { "declaration": 20468, "isOffset": false, "isSlot": false, "src": "2042:9:68", "valueSize": 1 } }, { "tempBytes": { "declaration": 20468, "isOffset": false, "isSlot": false, "src": "2071:9:68", "valueSize": 1 } }, { "_preBytes": { "declaration": 20460, "isOffset": false, "isSlot": false, "src": "3110:9:68", "valueSize": 1 } } ], "id": 20470, "nodeType": "InlineAssembly", "operations": "{\n tempBytes := mload(0x40)\n let length := mload(_preBytes)\n mstore(tempBytes, length)\n let mc := add(tempBytes, 0x20)\n let end := add(mc, length)\n for {\n let cc := add(_preBytes, 0x20)\n }\n lt(mc, end)\n {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n }\n {\n mstore(mc, mload(cc))\n }\n length := mload(_postBytes)\n mstore(tempBytes, add(length, mload(tempBytes)))\n mc := end\n end := add(mc, length)\n for {\n let cc := add(_postBytes, 0x20)\n }\n lt(mc, end)\n {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n }\n {\n mstore(mc, mload(cc))\n }\n mstore(0x40, and(add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31)))\n}", "src": "487:2744:68" }, { "expression": { "argumentTypes": null, "id": 20471, "name": "tempBytes", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 20468, "src": "3232:9:68", "typeDescriptions": { "typeIdentifier": "t_bytes_memory_ptr", "typeString": "bytes memory" } }, "functionReturnParameters": 20466, "id": 20472, "nodeType": "Return", "src": "3225:16:68" } ] }, "documentation": null, "id": 20474, "implemented": true, "isConstructor": false, "isDeclaredConst": true, "modifiers": [], "name": "concat", "nodeType": "FunctionDefinition", "parameters": { "id": 20463, "nodeType": "ParameterList", "parameters": [ { "constant": false, "id": 20460, "name": "_preBytes", "nodeType": "VariableDeclaration", "scope": 20474, "src": "365:22:68", "stateVariable": false, "storageLocation": "memory", "typeDescriptions": { "typeIdentifier": "t_bytes_memory_ptr", "typeString": "bytes" }, "typeName": { "id": 20459, "name": "bytes", "nodeType": "ElementaryTypeName", "src": "365:5:68", "typeDescriptions": { "typeIdentifier": "t_bytes_storage_ptr", "typeString": "bytes" } }, "value": null, "visibility": "internal" }, { "constant": false, "id": 20462, "name": "_postBytes", "nodeType": "VariableDeclaration", "scope": 20474, "src": "389:23:68", "stateVariable": false, "storageLocation": "memory", "typeDescriptions": { "typeIdentifier": "t_bytes_memory_ptr", "typeString": "bytes" }, "typeName": { "id": 20461, "name": "bytes", "nodeType": "ElementaryTypeName", "src": "389:5:68", "typeDescriptions": { "typeIdentifier": "t_bytes_storage_ptr", "typeString": "bytes" } }, "value": null, "visibility": "internal" } ], "src": "364:49:68" }, "payable": false, "returnParameters": { "id": 20466, "nodeType": "ParameterList", "parameters": [ { "constant": false, "id": 20465, "name": "", "nodeType": "VariableDeclaration", "scope": 20474, "src": "437:5:68", "stateVariable": false, "storageLocation": "default", "typeDescriptions": { "typeIdentifier": "t_bytes_memory_ptr", "typeString": "bytes" }, "typeName": { "id": 20464, "name": "bytes", "nodeType": "ElementaryTypeName", "src": "437:5:68", "typeDescriptions": { "typeIdentifier": "t_bytes_storage_ptr", "typeString": "bytes" } }, "value": null, "visibility": "internal" } ], "src": "436:7:68" }, "scope": 20624, "src": "349:2899:68", "stateMutability": "pure", "superFunction": null, "visibility": "internal" }, { "body": { "id": 20482, "nodeType": "Block", "src": "3336:6032:68", "statements": [ { "externalReferences": [ { "_preBytes_slot": { "declaration": 20476, "isOffset": false, "isSlot": true, "src": "3597:14:68", "valueSize": 1 } }, { "_postBytes": { "declaration": 20478, "isOffset": false, "isSlot": false, "src": "4215:10:68", "valueSize": 1 } }, { "_postBytes": { "declaration": 20478, "isOffset": false, "isSlot": false, "src": "7216:10:68", "valueSize": 1 } }, { "_postBytes": { "declaration": 20478, "isOffset": false, "isSlot": false, "src": "7165:10:68", "valueSize": 1 } }, { "_postBytes": { "declaration": 20478, "isOffset": false, "isSlot": false, "src": "8729:10:68", "valueSize": 1 } }, { "_postBytes": { "declaration": 20478, "isOffset": false, "isSlot": false, "src": "8780:10:68", "valueSize": 1 } }, { "_preBytes_slot": { "declaration": 20476, "isOffset": false, "isSlot": true, "src": "4891:14:68", "valueSize": 1 } }, { "_postBytes": { "declaration": 20478, "isOffset": false, "isSlot": false, "src": "5421:10:68", "valueSize": 1 } }, { "_preBytes_slot": { "declaration": 20476, "isOffset": false, "isSlot": true, "src": "6329:14:68", "valueSize": 1 } }, { "_preBytes_slot": { "declaration": 20476, "isOffset": false, "isSlot": true, "src": "6474:14:68", "valueSize": 1 } }, { "_preBytes_slot": { "declaration": 20476, "isOffset": false, "isSlot": true, "src": "8173:14:68", "valueSize": 1 } }, { "_preBytes_slot": { "declaration": 20476, "isOffset": false, "isSlot": true, "src": "8394:14:68", "valueSize": 1 } } ], "id": 20481, "nodeType": "InlineAssembly", "operations": "{\n let fslot := sload(_preBytes_slot)\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n let newlength := add(slength, mlength)\n switch add(lt(slength, 32), lt(newlength, 32))\n case 2 {\n sstore(_preBytes_slot, add(fslot, add(mul(div(mload(add(_postBytes, 0x20)), exp(0x100, sub(32, mlength))), exp(0x100, sub(32, newlength))), mul(mlength, 2))))\n }\n case 1 {\n mstore(0x0, _preBytes_slot)\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n sstore(_preBytes_slot, add(mul(newlength, 2), 1))\n let submod := sub(32, slength)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n sstore(sc, add(and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00), and(mload(mc), mask)))\n for {\n mc := add(mc, 0x20)\n sc := add(sc, 1)\n }\n lt(mc, end)\n {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n }\n {\n sstore(sc, mload(mc))\n }\n mask := exp(0x100, sub(mc, end))\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n default {\n mstore(0x0, _preBytes_slot)\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n sstore(_preBytes_slot, add(mul(newlength, 2), 1))\n let slengthmod := mod(slength, 32)\n let mlengthmod := mod(mlength, 32)\n let submod := sub(32, slengthmod)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\n for {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n }\n lt(mc, end)\n {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n }\n {\n sstore(sc, mload(mc))\n }\n mask := exp(0x100, sub(mc, end))\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n}", "src": "3346:6022:68" } ] }, "documentation": null, "id": 20483, "implemented": true, "isConstructor": false, "isDeclaredConst": false, "modifiers": [], "name": "concatStorage", "nodeType": "FunctionDefinition", "parameters": { "id": 20479, "nodeType": "ParameterList", "parameters": [ { "constant": false, "id": 20476, "name": "_preBytes", "nodeType": "VariableDeclaration", "scope": 20483, "src": "3277:23:68", "stateVariable": false, "storageLocation": "storage", "typeDescriptions": { "typeIdentifier": "t_bytes_storage_ptr", "typeString": "bytes" }, "typeName": { "id": 20475, "name": "bytes", "nodeType": "ElementaryTypeName", "src": "3277:5:68", "typeDescriptions": { "typeIdentifier": "t_bytes_storage_ptr", "typeString": "bytes" } }, "value": null, "visibility": "internal" }, { "constant": false, "id": 20478, "name": "_postBytes", "nodeType": "VariableDeclaration", "scope": 20483, "src": "3302:23:68", "stateVariable": false, "storageLocation": "memory", "typeDescriptions": { "typeIdentifier": "t_bytes_memory_ptr", "typeString": "bytes" }, "typeName": { "id": 20477, "name": "bytes", "nodeType": "ElementaryTypeName", "src": "3302:5:68", "typeDescriptions": { "typeIdentifier": "t_bytes_storage_ptr", "typeString": "bytes" } }, "value": null, "visibility": "internal" } ], "src": "3276:50:68" }, "payable": false, "returnParameters": { "id": 20480, "nodeType": "ParameterList", "parameters": [], "src": "3336:0:68" }, "scope": 20624, "src": "3254:6114:68", "stateMutability": "nonpayable", "superFunction": null, "visibility": "internal" }, { "body": { "id": 20510, "nodeType": "Block", "src": "9461:2378:68", "statements": [ { "expression": { "argumentTypes": null, "arguments": [ { "argumentTypes": null, "commonType": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, "id": 20501, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, "leftExpression": { "argumentTypes": null, "expression": { "argumentTypes": null, "id": 20495, "name": "_bytes", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 20485, "src": "9479:6:68", "typeDescriptions": { "typeIdentifier": "t_bytes_memory_ptr", "typeString": "bytes memory" } }, "id": 20496, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, "memberName": "length", "nodeType": "MemberAccess", "referencedDeclaration": null, "src": "9479:13:68", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "nodeType": "BinaryOperation", "operator": ">=", "rightExpression": { "argumentTypes": null, "components": [ { "argumentTypes": null, "commonType": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, "id": 20499, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, "leftExpression": { "argumentTypes": null, "id": 20497, "name": "_start", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 20487, "src": "9497:6:68", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "nodeType": "BinaryOperation", "operator": "+", "rightExpression": { "argumentTypes": null, "id": 20498, "name": "_length", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 20489, "src": "9506:7:68", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "src": "9497:16:68", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } } ], "id": 20500, "isConstant": false, "isInlineArray": false, "isLValue": false, "isPure": false, "lValueRequested": false, "nodeType": "TupleExpression", "src": "9496:18:68", "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "src": "9479:35:68", "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" } } ], "expression": { "argumentTypes": [ { "typeIdentifier": "t_bool", "typeString": "bool" } ], "id": 20494, "name": "require", "nodeType": "Identifier", "overloadedDeclarations": [ 20642, 20643 ], "referencedDeclaration": 20642, "src": "9471:7:68", "typeDescriptions": { "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", "typeString": "function (bool) pure" } }, "id": 20502, "isConstant": false, "isLValue": false, "isPure": false, "kind": "functionCall", "lValueRequested": false, "names": [], "nodeType": "FunctionCall", "src": "9471:44:68", "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } }, "id": 20503, "nodeType": "ExpressionStatement", "src": "9471:44:68" }, { "assignments": [], "declarations": [ { "constant": false, "id": 20505, "name": "tempBytes", "nodeType": "VariableDeclaration", "scope": 20511, "src": "9526:22:68", "stateVariable": false, "storageLocation": "memory", "typeDescriptions": { "typeIdentifier": "t_bytes_memory_ptr", "typeString": "bytes" }, "typeName": { "id": 20504, "name": "bytes", "nodeType": "ElementaryTypeName", "src": "9526:5:68", "typeDescriptions": { "typeIdentifier": "t_bytes_storage_ptr", "typeString": "bytes" } }, "value": null, "visibility": "internal" } ], "id": 20506, "initialValue": null, "nodeType": "VariableDeclarationStatement", "src": "9526:22:68" }, { "externalReferences": [ { "tempBytes": { "declaration": 20505, "isOffset": false, "isSlot": false, "src": "11706:9:68", "valueSize": 1 } }, { "tempBytes": { "declaration": 20505, "isOffset": false, "isSlot": false, "src": "10800:9:68", "valueSize": 1 } }, { "_length": { "declaration": 20489, "isOffset": false, "isSlot": false, "src": "10888:7:68", "valueSize": 1 } }, { "tempBytes": { "declaration": 20505, "isOffset": false, "isSlot": false, "src": "9780:9:68", "valueSize": 1 } }, { "_length": { "declaration": 20489, "isOffset": false, "isSlot": false, "src": "10449:7:68", "valueSize": 1 } }, { "_length": { "declaration": 20489, "isOffset": false, "isSlot": false, "src": "9596:7:68", "valueSize": 1 } }, { "tempBytes": { "declaration": 20505, "isOffset": false, "isSlot": false, "src": "11364:9:68", "valueSize": 1 } }, { "_length": { "declaration": 20489, "isOffset": false, "isSlot": false, "src": "11375:7:68", "valueSize": 1 } }, { "_start": { "declaration": 20487, "isOffset": false, "isSlot": false, "src": "11140:6:68", "valueSize": 1 } }, { "_bytes": { "declaration": 20485,