kleros-interaction-2
Version:
Smart contracts interacting with Kleros.
796 lines (795 loc) • 225 kB
JSON
{
"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,