witnet-solidity-bridge
Version:
Witnet Solidity Bridge contracts for EVM-compatible chains
12 lines • 2.07 MB
JSON
{
"contractName": "Witnet",
"abi": [],
"metadata": "{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"project:/contracts/libs/Witnet.sol\":\"Witnet\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"project:/contracts/libs/Bech32.sol\":{\"keccak256\":\"0x14618323a0efe7586c20906a2e9cee7ad63baa976ff231c57f7f2d7d3707fb8b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a19f05fe84047a7a6d3d6fc39972b432e6e536aa70472386a9d7a6d9aab64a64\",\"dweb:/ipfs/QmcHwUY66yjiotRH4Q3kbRvSzcHyLQ1yHL3KbtQKiMhtZE\"]},\"project:/contracts/libs/Secp256k1.sol\":{\"keccak256\":\"0xbe686002da5004ff39dd70709f3820eba2afe9323ae9cb894009c161e4b1a666\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://18fab91775216de0707cea9ad285b10be09127461a13432fea358bf9cb2a0c2e\",\"dweb:/ipfs/QmeRUGsgstnM4hxM9hpkBf3L6cE5btirEaowcMxmuw3utj\"]},\"project:/contracts/libs/Witnet.sol\":{\"keccak256\":\"0x1d446c3e534e40e676d1763bfb2897fadfac8afed904ab757843d7d6770b0a6c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://338fb1073f17d64e8d31bfe492d9475ce906788ee08e6489ce30413f91dc1328\",\"dweb:/ipfs/QmPe5QX2AGTnQFjse1Xttq4ZYWwYAiXoySb5VUui3PqPhk\"]},\"project:/contracts/libs/WitnetBuffer.sol\":{\"keccak256\":\"0x8e07aebe2954ab3e6f2d8eceedb12db7cf915c1f3e8630f4fa9999cecb1c78ec\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ed6c54cc901183d61546e8fd15bd5ea8ef238ebc915642946071d435dd7481ea\",\"dweb:/ipfs/Qmcaqta7YjUSBbBUGqoh44bsCS6UqqoyHjBuz4qnKBShXM\"]},\"project:/contracts/libs/WitnetCBOR.sol\":{\"keccak256\":\"0xd99308373575cc10fb7f2ceb0f6a8625f3911275c1fa27811fae498d98d03d97\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b4909a999d7b660a2dc54ca957b6eccfa523e2765fc4d6a2574dee7d5cd67b43\",\"dweb:/ipfs/QmWGQT4KDcfSFe1hcHVoWx6E4PhYMaod5iLpJCWBEeShzh\"]}},\"version\":1}",
"bytecode": "0x60556032600b8282823980515f1a607314602657634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f5ffdfea264697066735822122040c412fceb899814e2c0744a20bfd8ee042e4540ee069db2253cf31e9ead548964736f6c634300081e0033",
"deployedBytecode": "0x730000000000000000000000000000000000000000301460806040525f5ffdfea264697066735822122040c412fceb899814e2c0744a20bfd8ee042e4540ee069db2253cf31e9ead548964736f6c634300081e0033",
"immutableReferences": {},
"generatedSources": [],
"deployedGeneratedSources": [],
"sourceMap": "151:52706:116:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;151:52706:116;;;;;;;;;;;;;;;;;",
"deployedSourceMap": "151:52706:116:-:0;;;;;;;;",
"source": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity >=0.8.0 <0.9.0;\r\n\r\nimport \"./Bech32.sol\";\r\nimport \"./Secp256k1.sol\";\r\nimport \"./WitnetCBOR.sol\";\r\n\r\nlibrary Witnet {\r\n\r\n using Bech32 for Witnet.Address;\r\n using WitnetBuffer for WitnetBuffer.Buffer;\r\n using WitnetCBOR for WitnetCBOR.CBOR;\r\n using WitnetCBOR for WitnetCBOR.CBOR[];\r\n\r\n type Address is bytes20;\r\n\r\n type BlockNumber is uint64;\r\n \r\n type QueryEvmReward is uint72;\r\n type QueryUUID is bytes15;\r\n type QueryId is uint64;\r\n\r\n type RadonHash is bytes32;\r\n type ServiceProvider is bytes20;\r\n \r\n type Timestamp is uint64;\r\n type TransactionHash is bytes32;\r\n\r\n uint32 constant internal WIT_1_GENESIS_TIMESTAMP = 0; // TBD \r\n uint32 constant internal WIT_1_SECS_PER_EPOCH = 45;\r\n\r\n uint32 constant internal WIT_2_GENESIS_BEACON_INDEX = 0; // TBD\r\n uint32 constant internal WIT_2_GENESIS_BEACON_PREV_INDEX = 0; // TBD\r\n bytes24 constant internal WIT_2_GENESIS_BEACON_PREV_ROOT = 0; // TBD\r\n bytes16 constant internal WIT_2_GENESIS_BEACON_DDR_TALLIES_MERKLE_ROOT = 0; // TBD\r\n bytes16 constant internal WIT_2_GENESIS_BEACON_DRO_TALLIES_MERKLE_ROOT = 0; // TBD\r\n uint256 constant internal WIT_2_GENESIS_BEACON_NEXT_COMMITTEE_AGG_PUBKEY_0 = 0; // TBD\r\n uint256 constant internal WIT_2_GENESIS_BEACON_NEXT_COMMITTEE_AGG_PUBKEY_1 = 0; // TBD\r\n uint256 constant internal WIT_2_GENESIS_BEACON_NEXT_COMMITTEE_AGG_PUBKEY_2 = 0; // TBD\r\n uint256 constant internal WIT_2_GENESIS_BEACON_NEXT_COMMITTEE_AGG_PUBKEY_3 = 0; // TBD\r\n uint32 constant internal WIT_2_GENESIS_EPOCH = 0; // TBD\r\n uint32 constant internal WIT_2_GENESIS_TIMESTAMP = 0; // TBD\r\n uint32 constant internal WIT_2_SECS_PER_EPOCH = 20; // TBD\r\n uint32 constant internal WIT_2_FAST_FORWARD_COMMITTEE_SIZE = 64; // TBD\r\n\r\n\r\n function channel(address wrb) internal view returns (bytes4) {\r\n return bytes4(keccak256(abi.encode(address(wrb), block.chainid)));\r\n }\r\n\r\n struct Beacon {\r\n uint32 index;\r\n uint32 prevIndex;\r\n bytes24 prevRoot;\r\n bytes16 ddrTalliesMerkleRoot;\r\n bytes16 droTalliesMerkleRoot;\r\n uint256[4] nextCommitteeAggPubkey;\r\n }\r\n\r\n struct DataPullReport {\r\n QueryId queryId;\r\n QueryUUID queryHash; // KECCAK256(channel | blockhash(block.number - 1) | ...)\r\n bytes witDrRelayerSignature; // ECDSA.signature(queryHash)\r\n BlockNumber witDrResultEpoch;\r\n bytes witDrResultCborBytes;\r\n TransactionHash witDrTxHash;\r\n }\r\n\r\n struct DataPushReport {\r\n TransactionHash witDrTxHash;\r\n RadonHash queryRadHash;\r\n QuerySLA queryParams;\r\n Timestamp resultTimestamp;\r\n bytes resultCborBytes;\r\n }\r\n\r\n /// Data struct containing the Witnet-provided result to a Data Request.\r\n struct DataResult {\r\n ResultStatus status;\r\n RadonDataTypes dataType;\r\n TransactionHash drTxHash;\r\n uint256 finality;\r\n Timestamp timestamp;\r\n WitnetCBOR.CBOR value;\r\n }\r\n\r\n struct FastForward {\r\n Beacon beacon;\r\n uint256[2] committeeAggSignature;\r\n uint256[4][] committeeMissingPubkeys;\r\n }\r\n\r\n /// Struct containing both request and response data related to every query posted to the Witnet Request Board\r\n struct Query {\r\n QueryRequest request;\r\n QueryResponse response;\r\n QuerySLA slaParams; // Minimum Service-Level parameters to be committed by the Witnet blockchain.\r\n QueryUUID uuid; // Universal unique identifier determined by the payload, WRB instance, chain id and EVM's previous block hash.\r\n QueryEvmReward reward; // EVM amount in wei eventually to be paid to the legit reporter.\r\n BlockNumber checkpoint;\r\n }\r\n\r\n /// Possible status of a Witnet query.\r\n enum QueryStatus {\r\n Unknown,\r\n Posted,\r\n Reported,\r\n Finalized,\r\n Delayed,\r\n Expired,\r\n Disputed\r\n }\r\n\r\n struct QueryCallback {\r\n address consumer; // consumer contract address to which the query result will be reported\r\n uint24 gasLimit; // expected max amount of gas required by the callback method in the consumer contract\r\n }\r\n\r\n /// Data kept in EVM-storage for every Request posted to the Witnet Request Board.\r\n struct QueryRequest {\r\n address requester; // EVM address from which the request was posted.\r\n uint24 callbackGas; // Max callback gas limit upon response, if a callback is required.\r\n bytes radonBytecode; // Optional: Witnet Data Request bytecode to be solved by the Witnet blockchain.\r\n RadonHash radonHash; // Optional: Previously verified hash of the Witnet Data Request to be solved.\r\n }\r\n\r\n /// QueryResponse metadata and result as resolved by the Witnet blockchain.\r\n struct QueryResponse {\r\n address reporter; // EVM address from which the Data Request result was reported.\r\n Timestamp resultTimestamp; // Unix timestamp (seconds) at which the data request was resolved in the Witnet blockchain.\r\n TransactionHash resultDrTxHash; // Unique hash of the commit/reveal act in the Witnet blockchain that resolved the data request.\r\n bytes resultCborBytes; // CBOR-encode result to the request, as resolved in the Witnet blockchain.\r\n address disputer;\r\n }\r\n\r\n /// Structure containing all possible SLA security parameters for Wit/2.1 Data Requests\r\n struct QuerySLA {\r\n uint16 witResultMaxSize; // max size permitted to whatever query result may come from the Wit/Oracle blockchain.\r\n uint16 witCommitteeSize; // max number of eligibile witnesses in the Wit/Oracle blockchain for solving some query.\r\n uint64 witUnitaryReward; // min fees in nanowits to be paid for getting the query solved and reported from the Wit/Oracle.\r\n }\r\n\r\n enum ResultStatus {\r\n /// 0x00: No errors.\r\n NoErrors,\r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Source-specific format error sub-codes ============================================================================\r\n \r\n /// 0x01: At least one of the source scripts is not a valid CBOR-encoded value.\r\n SourceScriptNotCBOR, \r\n \r\n /// 0x02: The CBOR value decoded from a source script is not an Array.\r\n SourceScriptNotArray,\r\n \r\n /// 0x03: The Array value decoded form a source script is not a valid Data Request.\r\n SourceScriptNotRADON,\r\n \r\n /// 0x04: The request body of at least one data source was not properly formated.\r\n SourceRequestBody,\r\n \r\n /// 0x05: The request headers of at least one data source was not properly formated.\r\n SourceRequestHeaders,\r\n \r\n /// 0x06: The request URL of at least one data source was not properly formated.\r\n SourceRequestURL,\r\n \r\n /// Unallocated\r\n SourceFormat0x07, SourceFormat0x08, SourceFormat0x09, SourceFormat0x0A, SourceFormat0x0B, SourceFormat0x0C,\r\n SourceFormat0x0D, SourceFormat0x0E, SourceFormat0x0F, \r\n \r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Complexity error sub-codes ========================================================================================\r\n \r\n /// 0x10: The request contains too many sources.\r\n RequestTooManySources,\r\n \r\n /// 0x11: The script contains too many calls.\r\n ScriptTooManyCalls,\r\n \r\n /// Unallocated\r\n Complexity0x12, Complexity0x13, Complexity0x14, Complexity0x15, Complexity0x16, Complexity0x17, Complexity0x18,\r\n Complexity0x19, Complexity0x1A, Complexity0x1B, Complexity0x1C, Complexity0x1D, Complexity0x1E, Complexity0x1F,\r\n\r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Lack of support error sub-codes ===================================================================================\r\n \r\n /// 0x20: Some Radon operator code was found that is not supported (1+ args).\r\n UnsupportedOperator,\r\n \r\n /// 0x21: Some Radon filter opcode is not currently supported (1+ args).\r\n UnsupportedFilter,\r\n \r\n /// 0x22: Some Radon request type is not currently supported (1+ args).\r\n UnsupportedHashFunction,\r\n \r\n /// 0x23: Some Radon reducer opcode is not currently supported (1+ args)\r\n UnsupportedReducer,\r\n \r\n /// 0x24: Some Radon hash function is not currently supported (1+ args).\r\n UnsupportedRequestType, \r\n \r\n /// 0x25: Some Radon encoding function is not currently supported (1+ args).\r\n UnsupportedEncodingFunction,\r\n \r\n /// Unallocated\r\n Operator0x26, Operator0x27, \r\n \r\n /// 0x28: Wrong number (or type) of arguments were passed to some Radon operator.\r\n WrongArguments,\r\n \r\n /// Unallocated\r\n Operator0x29, Operator0x2A, Operator0x2B, Operator0x2C, Operator0x2D, Operator0x2E, Operator0x2F,\r\n \r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Retrieve-specific circumstantial error sub-codes ================================================================================\r\n /// 0x30: A majority of data sources returned an HTTP status code other than 200 (1+ args):\r\n HttpErrors,\r\n \r\n /// 0x31: A majority of data sources timed out:\r\n RetrievalsTimeout,\r\n \r\n /// Unallocated\r\n RetrieveCircumstance0x32, RetrieveCircumstance0x33, RetrieveCircumstance0x34, RetrieveCircumstance0x35,\r\n RetrieveCircumstance0x36, RetrieveCircumstance0x37, RetrieveCircumstance0x38, RetrieveCircumstance0x39,\r\n RetrieveCircumstance0x3A, RetrieveCircumstance0x3B, RetrieveCircumstance0x3C, RetrieveCircumstance0x3D,\r\n RetrieveCircumstance0x3E, RetrieveCircumstance0x3F,\r\n \r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Scripting-specific runtime error sub-code =========================================================================\r\n /// 0x40: Math operator caused an underflow.\r\n MathUnderflow,\r\n \r\n /// 0x41: Math operator caused an overflow.\r\n MathOverflow,\r\n \r\n /// 0x42: Math operator tried to divide by zero.\r\n MathDivisionByZero, \r\n \r\n /// 0x43: Wrong input to subscript call.\r\n WrongSubscriptInput,\r\n \r\n /// 0x44: Value cannot be extracted from input binary buffer.\r\n BufferIsNotValue,\r\n \r\n /// 0x45: Value cannot be decoded from expected type.\r\n Decode,\r\n \r\n /// 0x46: Unexpected empty array.\r\n EmptyArray,\r\n \r\n /// 0x47: Value cannot be encoded to expected type.\r\n Encode,\r\n \r\n /// 0x48: Failed to filter input values (1+ args).\r\n Filter,\r\n \r\n /// 0x49: Failed to hash input value.\r\n Hash,\r\n \r\n /// 0x4A: Mismatching array ranks.\r\n MismatchingArrays,\r\n \r\n /// 0x4B: Failed to process non-homogenous array.\r\n NonHomegeneousArray,\r\n \r\n /// 0x4C: Failed to parse syntax of some input value, or argument.\r\n Parse,\r\n \r\n /// 0x4D: Parsing logic limits were exceeded.\r\n ParseOverflow,\r\n \r\n /// Unallocated\r\n ScriptError0x4E, ScriptError0x4F,\r\n \r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Actual first-order result error codes =============================================================================\r\n \r\n /// 0x50: Not enough reveals were received in due time:\r\n InsufficientReveals,\r\n \r\n /// 0x51: No actual reveal majority was reached on tally stage:\r\n InsufficientMajority,\r\n \r\n /// 0x52: Not enough commits were received before tally stage:\r\n InsufficientCommits,\r\n \r\n /// 0x53: Generic error during tally execution (to be deprecated after WIP #0028)\r\n TallyExecution,\r\n \r\n /// 0x54: A majority of data sources could either be temporarily unresponsive or failing to report the requested data:\r\n CircumstantialFailure,\r\n \r\n /// 0x55: At least one data source is inconsistent when queried through multiple transports at once:\r\n InconsistentSources,\r\n \r\n /// 0x56: Any one of the (multiple) Retrieve, Aggregate or Tally scripts were badly formated:\r\n MalformedDataRequest,\r\n \r\n /// 0x57: Values returned from a majority of data sources don't match the expected schema:\r\n MalformedQueryResponses,\r\n \r\n /// Unallocated: \r\n OtherError0x58, OtherError0x59, OtherError0x5A, OtherError0x5B, OtherError0x5C, OtherError0x5D, OtherError0x5E, \r\n \r\n /// 0x5F: Size of serialized tally result exceeds allowance:\r\n OversizedTallyResult,\r\n\r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Inter-stage runtime error sub-codes ===============================================================================\r\n \r\n /// 0x60: Data aggregation reveals could not get decoded on the tally stage:\r\n MalformedReveals,\r\n \r\n /// 0x61: The result to data aggregation could not get encoded:\r\n EncodeReveals, \r\n \r\n /// 0x62: A mode tie ocurred when calculating some mode value on the aggregation or the tally stage:\r\n ModeTie, \r\n \r\n /// Unallocated:\r\n OtherError0x63, OtherError0x64, OtherError0x65, OtherError0x66, OtherError0x67, OtherError0x68, OtherError0x69, \r\n OtherError0x6A, OtherError0x6B, OtherError0x6C, OtherError0x6D, OtherError0x6E, OtherError0x6F,\r\n \r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Runtime access error sub-codes ====================================================================================\r\n \r\n /// 0x70: Tried to access a value from an array using an index that is out of bounds (1+ args):\r\n ArrayIndexOutOfBounds,\r\n \r\n /// 0x71: Tried to access a value from a map using a key that does not exist (1+ args):\r\n MapKeyNotFound,\r\n \r\n /// 0X72: Tried to extract value from a map using a JSON Path that returns no values (+1 args):\r\n JsonPathNotFound,\r\n \r\n /// Unallocated:\r\n OtherError0x73, OtherError0x74, OtherError0x75, OtherError0x76, OtherError0x77, OtherError0x78, \r\n OtherError0x79, OtherError0x7A, OtherError0x7B, OtherError0x7C, OtherError0x7D, OtherError0x7E, OtherError0x7F, \r\n OtherError0x80, OtherError0x81, OtherError0x82, OtherError0x83, OtherError0x84, OtherError0x85, OtherError0x86, \r\n OtherError0x87, OtherError0x88, OtherError0x89, OtherError0x8A, OtherError0x8B, OtherError0x8C, OtherError0x8D, \r\n OtherError0x8E, OtherError0x8F, OtherError0x90, OtherError0x91, OtherError0x92, OtherError0x93, OtherError0x94, \r\n OtherError0x95, OtherError0x96, OtherError0x97, OtherError0x98, OtherError0x99, OtherError0x9A, OtherError0x9B,\r\n OtherError0x9C, OtherError0x9D, OtherError0x9E, OtherError0x9F, OtherError0xA0, OtherError0xA1, OtherError0xA2, \r\n OtherError0xA3, OtherError0xA4, OtherError0xA5, OtherError0xA6, OtherError0xA7, OtherError0xA8, OtherError0xA9, \r\n OtherError0xAA, OtherError0xAB, OtherError0xAC, OtherError0xAD, OtherError0xAE, OtherError0xAF, OtherError0xB0,\r\n OtherError0xB1, OtherError0xB2, OtherError0xB3, OtherError0xB4, OtherError0xB5, OtherError0xB6, OtherError0xB7,\r\n OtherError0xB8, OtherError0xB9, OtherError0xBA, OtherError0xBB, OtherError0xBC, OtherError0xBD, OtherError0xBE,\r\n OtherError0xBF, OtherError0xC0, OtherError0xC1, OtherError0xC2, OtherError0xC3, OtherError0xC4, OtherError0xC5,\r\n OtherError0xC6, OtherError0xC7, OtherError0xC8, OtherError0xC9, OtherError0xCA, OtherError0xCB, OtherError0xCC,\r\n OtherError0xCD, OtherError0xCE, OtherError0xCF, OtherError0xD0, OtherError0xD1, OtherError0xD2, OtherError0xD3,\r\n OtherError0xD4, OtherError0xD5, OtherError0xD6, OtherError0xD7, OtherError0xD8, OtherError0xD9, OtherError0xDA,\r\n OtherError0xDB, OtherError0xDC, OtherError0xDD, OtherError0xDE, OtherError0xDF,\r\n \r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Inter-client generic error codes ==================================================================================\r\n /// Data requests that cannot be relayed into the Witnet blockchain should be reported\r\n /// with one of these errors. \r\n \r\n /// 0xE0: Requests that cannot be parsed must always get this error as their result.\r\n BridgeMalformedDataRequest,\r\n \r\n /// 0xE1: Witnesses exceeds 100\r\n BridgePoorIncentives,\r\n \r\n /// 0xE2: The request is rejected on the grounds that it may cause the submitter to spend or stake an\r\n /// amount of value that is unjustifiably high when compared with the reward they will be getting\r\n BridgeOversizedTallyResult,\r\n \r\n /// Unallocated:\r\n OtherError0xE3, OtherError0xE4, OtherError0xE5, OtherError0xE6, OtherError0xE7, OtherError0xE8, OtherError0xE9,\r\n OtherError0xEA, OtherError0xEB, OtherError0xEC, OtherError0xED, OtherError0xEE, OtherError0xEF, \r\n \r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Transient errors as determined by the Request Board contract ======================================================\r\n \r\n /// 0xF0: \r\n BoardAwaitingResult,\r\n\r\n /// 0xF1:\r\n BoardFinalizingResult,\r\n\r\n /// 0xF2:\r\n BoardBeingDisputed,\r\n\r\n /// Unallocated\r\n OtherError0xF3, OtherError0xF4, OtherError0xF5, OtherError0xF6, OtherError0xF7,\r\n\r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// Final errors as determined by the Request Board contract ==========================================================\r\n\r\n /// 0xF8:\r\n BoardAlreadyDelivered,\r\n\r\n /// 0xF9:\r\n BoardResolutionTimeout,\r\n\r\n /// Unallocated:\r\n OtherError0xFA, OtherError0xFB, OtherError0xFC, OtherError0xFD, OtherError0xFE,\r\n \r\n \r\n ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n /// 0xFF: Some tally error is not intercepted but it should (0+ args)\r\n UnhandledIntercept\r\n }\r\n\r\n /// Possible types either processed by Witnet Radon Scripts or included within results to Witnet Data Requests.\r\n enum RadonDataTypes {\r\n /* 0x00 */ Any, \r\n /* 0x01 */ Array,\r\n /* 0x02 */ Bool,\r\n /* 0x03 */ Bytes,\r\n /* 0x04 */ Integer,\r\n /* 0x05 */ Float,\r\n /* 0x06 */ Map,\r\n /* 0x07 */ String,\r\n Unused0x08, Unused0x09, Unused0x0A, Unused0x0B,\r\n Unused0x0C, Unused0x0D, Unused0x0E, Unused0x0F,\r\n /* 0x10 */ Same,\r\n /* 0x11 */ Inner,\r\n /* 0x12 */ Match,\r\n /* 0x13 */ Subscript\r\n }\r\n\r\n /// Structure defining some data filtering that can be applied at the Aggregation or the Tally stages\r\n /// within a Witnet Data Request resolution workflow.\r\n struct RadonFilter {\r\n RadonFilterOpcodes opcode;\r\n bytes cborArgs;\r\n }\r\n\r\n /// Filtering methods currently supported on the Witnet blockchain. \r\n enum RadonFilterOpcodes {\r\n /* 0x00 */ Reserved0x00, //GreaterThan,\r\n /* 0x01 */ Reserved0x01, //LessThan,\r\n /* 0x02 */ Reserved0x02, //Equals,\r\n /* 0x03 */ Reserved0x03, //AbsoluteDeviation,\r\n /* 0x04 */ Reserved0x04, //RelativeDeviation\r\n /* 0x05 */ StandardDeviation,\r\n /* 0x06 */ Reserved0x06, //Top,\r\n /* 0x07 */ Reserved0x07, //Bottom,\r\n /* 0x08 */ Mode,\r\n /* 0x09 */ Reserved0x09 //LessOrEqualThan\r\n }\r\n\r\n /// Structure defining the array of filters and reducting function to be applied at either the Aggregation\r\n /// or the Tally stages within a Witnet Data Request resolution workflow.\r\n struct RadonReducer {\r\n RadonReduceOpcodes opcode;\r\n RadonFilter[] filters;\r\n }\r\n\r\n /// Reducting functions currently supported on the Witnet blockchain.\r\n enum RadonReduceOpcodes {\r\n /* 0x00 */ Reserved0x00, //Minimum,\r\n /* 0x01 */ Reserved0x01, //Maximum,\r\n /* 0x02 */ Mode,\r\n /* 0x03 */ AverageMean,\r\n /* 0x04 */ Reserved0x04, //AverageMeanWeighted,\r\n /* 0x05 */ AverageMedian,\r\n /* 0x06 */ Reserved0x06, //AverageMedianWeighted,\r\n /* 0x07 */ StandardDeviation,\r\n /* 0x08 */ Reserved0x08, //AverageDeviation,\r\n /* 0x09 */ Reserved0x09, //MedianDeviation,\r\n /* 0x0A */ Reserved0x10, //MaximumDeviation,\r\n /* 0x0B */ ConcatenateAndHash\r\n }\r\n \r\n /// Structure containing the Retrieve-Attestation-Delivery parts of a Witnet-compliant Data Request.\r\n struct RadonRequest {\r\n RadonRetrieval[] retrieve;\r\n RadonReducer aggregate;\r\n RadonReducer tally;\r\n }\r\n\r\n /// Structure containing all the parameters that fully describe a Witnet Radon Retrieval within a Witnet Data Request.\r\n struct RadonRetrieval {\r\n uint8 argsCount;\r\n RadonRetrievalMethods method;\r\n RadonDataTypes dataType;\r\n string url;\r\n string body;\r\n string[2][] headers;\r\n bytes radonScript;\r\n }\r\n\r\n /// Possible Radon retrieval methods that can be used within a Radon Retrieval. \r\n enum RadonRetrievalMethods {\r\n /* 0 */ Unknown,\r\n /* 1 */ HttpGet,\r\n /* 2 */ RNG,\r\n /* 3 */ HttpPost,\r\n /* 4 */ HttpHead\r\n }\r\n\r\n /// Structure containing all possible SLA security parameters of a Witnet-compliant Data Request.\r\n\r\n struct RadonSLAv1 {\r\n uint8 numWitnesses;\r\n uint8 minConsensusPercentage;\r\n uint64 witnessReward;\r\n uint64 witnessCollateral;\r\n uint64 minerCommitRevealFee;\r\n }\r\n\r\n\r\n /// =======================================================================\r\n /// --- Witnet.Address helper functions -----------------------------------\r\n\r\n function eq(Address a, Address b) internal pure returns (bool) {\r\n return Address.unwrap(a) == Address.unwrap(b);\r\n }\r\n\r\n function fromBech32(string memory pkh, bool mainnet) internal pure returns (Address) {\r\n require(bytes(pkh).length == (mainnet ? 42 : 43), \"Bech32: invalid length\");\r\n return Address.wrap(bytes20(Bech32.fromBech32(pkh, mainnet ? \"wit\" : \"twit\")));\r\n }\r\n\r\n function toBech32(Address witAddress, bool mainnet) internal pure returns (string memory) {\r\n return Bech32.toBech32(address(Address.unwrap(witAddress)), mainnet ? \"wit\" : \"twit\");\r\n }\r\n\r\n function isZero(Address a) internal pure returns (bool) {\r\n return Address.unwrap(a) == bytes20(0);\r\n }\r\n\r\n \r\n /// =======================================================================\r\n /// --- Witnet.Beacon helper functions ------------------------------------\r\n\r\n function equals(Beacon storage self, Beacon calldata other)\r\n internal view returns (bool)\r\n {\r\n return (\r\n root(self) == root(other)\r\n );\r\n }\r\n\r\n function root(Beacon calldata self) internal pure returns (bytes24) {\r\n return bytes24(keccak256(abi.encode(\r\n self.index,\r\n self.prevIndex,\r\n self.prevRoot,\r\n self.ddrTalliesMerkleRoot,\r\n self.droTalliesMerkleRoot,\r\n self.nextCommitteeAggPubkey\r\n )));\r\n }\r\n \r\n function root(Beacon storage self) internal view returns (bytes24) {\r\n return bytes24(keccak256(abi.encode(\r\n self.index,\r\n self.prevIndex,\r\n self.prevRoot,\r\n self.ddrTalliesMerkleRoot,\r\n self.droTalliesMerkleRoot,\r\n self.nextCommitteeAggPubkey\r\n )));\r\n }\r\n\r\n \r\n /// =======================================================================\r\n /// --- BlockNumber helper functions --------------------------------------\r\n\r\n function egt(BlockNumber a, BlockNumber b) internal pure returns (bool) {\r\n return BlockNumber.unwrap(a) >= BlockNumber.unwrap(b);\r\n }\r\n\r\n function elt(BlockNumber a, BlockNumber b) internal pure returns (bool) {\r\n return BlockNumber.unwrap(a) <= BlockNumber.unwrap(b);\r\n }\r\n\r\n function gt(BlockNumber a, BlockNumber b) internal pure returns (bool) {\r\n return BlockNumber.unwrap(a) > BlockNumber.unwrap(b);\r\n }\r\n\r\n function lt(BlockNumber a, BlockNumber b) internal pure returns (bool) {\r\n return BlockNumber.unwrap(a) < BlockNumber.unwrap(b);\r\n }\r\n\r\n function isZero(BlockNumber b) internal pure returns (bool) {\r\n return (BlockNumber.unwrap(b) == 0);\r\n }\r\n\r\n\r\n /// ===============================================================================================================\r\n /// --- Data*Report helper methods --------------------------------------------------------------------------------\r\n\r\n function queryRelayer(DataPullReport calldata self) internal pure returns (address) {\r\n return recoverEvmAddr(\r\n self.witDrRelayerSignature, \r\n hashify(self.queryHash)\r\n );\r\n }\r\n\r\n function tallyHash(DataPullReport calldata self) internal pure returns (bytes32) {\r\n return keccak256(abi.encode(\r\n self.queryHash,\r\n self.witDrRelayerSignature,\r\n self.witDrTxHash,\r\n self.witDrResultEpoch,\r\n self.witDrResultCborBytes\r\n ));\r\n }\r\n\r\n function digest(DataPushReport calldata self) internal pure returns (bytes32) {\r\n return keccak256(abi.encode(\r\n self.witDrTxHash,\r\n self.queryRadHash,\r\n self.queryParams.witResultMaxSize,\r\n self.queryParams.witCommitteeSize,\r\n self.queryParams.witUnitaryReward,\r\n self.resultTimestamp,\r\n self.resultCborBytes\r\n ));\r\n }\r\n \r\n /// ========================================================================================================\r\n /// --- 'DataResult' helper methods ------------------------------------------------------------------------\r\n\r\n function noErrors(DataResult memory self) internal pure returns (bool) {\r\n return self.status == ResultStatus.NoErrors;\r\n }\r\n\r\n function keepWaiting(DataResult memory self) internal pure returns (bool) {\r\n return keepWaiting(self.status);\r\n }\r\n\r\n function hasErrors(DataResult memory self) internal pure returns (bool) {\r\n return hasErrors(self.status);\r\n }\r\n\r\n modifier _checkDataType(DataResult memory self, RadonDataTypes expectedDataType) {\r\n require(\r\n !keepWaiting(self)\r\n && self.dataType == expectedDataType\r\n , \"cbor: cannot fetch data\"\r\n ); _; \r\n self.dataType = peekRadonDataType(self.value);\r\n }\r\n\r\n function fetchAddress(DataResult memory self) \r\n internal pure \r\n _checkDataType(self, RadonDataTypes.Bytes) \r\n returns (address _res)\r\n {\r\n return toAddress(self.value.readBytes());\r\n }\r\n\r\n function fetchBool(DataResult memory self) \r\n internal pure \r\n _checkDataType(self, RadonDataTypes.Bool) \r\n returns (bool)\r\n {\r\n return self.value.readBool();\r\n }\r\n\r\n function fetchBytes(DataResult memory self)\r\n internal pure \r\n _checkDataType(self, RadonDataTypes.Bytes) \r\n returns (bytes memory)\r\n {\r\n return self.value.readBytes();\r\n }\r\n\r\n function fetchBytes4(DataResult memory self)\r\n internal pure \r\n _checkDataType(self, RadonDataTypes.Bytes) \r\n returns (bytes4)\r\n {\r\n return toBytes4(self.value.readBytes());\r\n }\r\n\r\n function fetchBytes32(DataResult memory self)\r\n internal pure \r\n _checkDataType(self, RadonDataTypes.Bytes) \r\n returns (bytes32)\r\n {\r\n return toBytes32(self.value.readBytes());\r\n }\r\n\r\n function fetchCborArray(DataResult memory self)\r\n internal pure \r\n _checkDataType(self, RadonDataTypes.Array) \r\n returns (WitnetCBOR.CBOR[] memory)\r\n {\r\n return self.value.readArray();\r\n }\r\n\r\n /// @dev Decode a fixed16 (half-precision) numeric value from the Result's CBOR 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 function fetchFloatFixed16(DataResult memory self)\r\n internal pure \r\n _checkDataType(self, RadonDataTypes.Float) \r\n returns (int32)\r\n {\r\n return self.value.readFloat16();\r\n }\r\n\r\n /// @dev Decode an array of fixed16 values from the Result's CBOR value.\r\n function fetchFloatFixed16Array(DataResult memory self)\r\n internal pure\r\n _checkDataType(self, RadonDataTypes.Array)\r\n returns (int32[] memory)\r\n {\r\n return self.value.readFloat16Array();\r\n }\r\n\r\n /// @dev Decode a `int64` value from the DataResult's CBOR value.\r\n function fetchInt(DataResult memory self)\r\n internal pure\r\n _checkDataType(self, RadonDataTypes.Integer)\r\n returns (int64)\r\n {\r\n return self.value.readInt();\r\n }\r\n\r\n function fetchInt64Array(DataResult memory self)\r\n internal pure\r\n _checkDataType(self, RadonDataTypes.Array)\r\n returns (int64[] memory)\r\n {\r\n return self.value.readIntArray();\r\n }\r\n\r\n function fetchString(DataResult memory self)\r\n internal pure\r\n _checkDataType(self, RadonDataTypes.String)\r\n returns (string memory)\r\n {\r\n return self.value.readString();\r\n }\r\n\r\n function fetchStringArray(DataResult memory self)\r\n internal pure\r\n _checkDataType(self, RadonDataTypes.Array)\r\n returns (string[] memory)\r\n {\r\n return self.value.readStringArray();\r\n }\r\n\r\n /// @dev Decode a `uint64` value from the DataResult's CBOR value.\r\n function fetchUint(DataResult memory self)\r\n internal pure\r\n _checkDataType(self, RadonDataTypes.Integer)\r\n returns (uint64)\r\n {\r\n return self.value.readUint();\r\n }\r\n\r\n function fetchUint64Array(DataResult memory self)\r\n internal pure\r\n _checkDataType(self, RadonDataTypes.Array)\r\n returns (uint64[] memory)\r\n {\r\n return self.value.readUintArray();\r\n }\r\n\r\n bytes7 private constant _CBOR_MAJOR_TYPE_TO_RADON_DATA_TYPES_MAP = 0x04040307010600;\r\n function peekRadonDataType(WitnetCBOR.CBOR memory cbor) internal pure returns (RadonDataTypes _type) {\r\n _type = RadonDataTypes.Any;\r\n if (!cbor.eof()) {\r\n if (cbor.majorType <= 6) {\r\n return RadonDataTypes(uint8(bytes1(_CBOR_MAJOR_TYPE_TO_RADON_DATA_TYPES_MAP[cbor.majorType])));\r\n \r\n } else if (cbor.majorType == 7) {\r\n if (cbor.additionalInformation == 20 || cbor.additionalInformation == 21) {\r\n return RadonDataTypes.Bool;\r\n \r\n } else if (cbor.additionalInformation >= 25 && cbor.additionalInformation <= 27) {\r\n return RadonDataTypes.Float;\r\n }\r\n }\r\n }\r\n }\r\n\r\n\r\n /// =======================================================================\r\n /// --- FastForward helper functions --------------------------------------\r\n\r\n function head(FastForward[] calldata rollup)\r\n internal pure returns (Beacon calldata)\r\n {\r\n return rollup[rollup.length - 1].beacon;\r\n }\r\n\r\n\r\n /// ===============================================================================================================\r\n /// --- Query* helper methods -------------------------------------------------------------------------------------\r\n\r\n function equalOrGreaterThan(QuerySLA calldata self, QuerySLA storage stored) internal view returns (bool) {\r\n return (\r\n self.witCommitteeSize >= stored.witCommitteeSize\r\n && self.witUnitaryReward >= stored.witUnitaryReward \r\n && self.witResultMaxSize <= stored.witResultMaxSize\r\n );\r\n }\r\n\r\n function hashify(QueryUUID hash) internal pure returns (bytes32) {\r\n return keccak256(abi.encode(QueryUUID.unwrap(hash)));\r\n }\r\n\r\n function hashify(QueryId _queryId, Witnet.RadonHash _radHash, bytes32 _slaHash) internal view returns (Witnet.QueryUUID) {\r\n return Witnet.QueryUUID.wrap(bytes15(\r\n keccak256(abi.encode(\r\n channel(address(this)), \r\n blockhash(block.number - 1),\r\n _queryId, Witnet.RadonHash.unwrap(_radHash), _slaHash\r\n ))\r\n ));\r\n }\r\n\r\n function hashify(QuerySLA memory querySLA) internal pure returns (bytes32) {\r\n return keccak256(abi.encodePacked(\r\n querySLA.witResultMaxSize,\r\n querySLA.witCommitteeSize,\r\n querySLA.witUnitaryReward\r\n ));\r\n }\r\n\r\n function isValid(QuerySLA memory self) internal pure returns (bool) {\r\n return (\r\n self.witResultMaxSize >= 0\r\n && self.witCommitteeSize > 0\r\n && self.witCommitteeSize <= 127\r\n && self.witUnitaryReward > 0\r\n );\r\n }\r\n\r\n function isZero(QueryId a) internal pure returns (bool) {\r\n return (QueryId.unwrap(a) == 0);\r\n }\r\n\r\n function toV1(QuerySLA calldata self) internal pure returns (RadonSLAv1 memory) {\r\n return RadonSLAv1({\r\n numWitnesses: uint8(self.witCommitteeSize),\r\n minConsensusPercentage: 51,\r\n witnessReward: self.witUnitaryReward,\r\n witnessCollateral: self.witUnitaryReward * self.witCommitteeSize,\r\n minerCommitRevealFee: self.witUnitaryReward / self.witCommitteeSize\r\n });\r\n }\r\n\r\n\r\n /// ===============================================================================================================\r\n /// --- RadonHash helper methods ----------------------------------------------------------------------------------\r\n\r\n function eq(RadonHash a, RadonHash b) internal pure returns (bool) {\r\n return RadonHash.unwrap(a) == RadonHash.unwrap(b);\r\n }\r\n \r\n function isZero(RadonHash h) internal pure returns (bool) {\r\n return RadonHash.unwrap(h) == bytes32(0);\r\n }\r\n\r\n \r\n /// ===============================================================================================================\r\n /// --- ResultStatus helper methods -------------------------------------------------------------------------------\r\n\r\n function hasErrors(ResultStatus self) internal pure returns (bool) {\r\n return (\r\n self != ResultStatus.NoErrors\r\n && !keepWaiting(self)\r\n );\r\n }\r\n\r\n function isCircumstantial(ResultStatus self) internal pure returns (bool) {\r\n return (self == ResultStatus.CircumstantialFailure);\r\n }\r\n\r\n function isRetriable(ResultStatus self) internal pure returns (bool) {\r\n return (\r\n lackOfConsensus(self)\r\n || isCircumstantial(self)\r\n || poorIncentives(self)\r\n );\r\n }\r\n\r\n function keepWaiting(ResultStatus self) internal pure returns (bool) {\r\n return (\r\n self == ResultStatus.BoardAwaitingResult\r\n || self == ResultStatus.BoardFinalizingResult\r\n );\r\n }\r\n\r\n function lackOfConsensus(ResultStatus self) internal pure returns (bool) {\r\n return (\r\n self == ResultStatus.InsufficientCommits\r\n || self == ResultStatus.InsufficientMajority\r\n || self == ResultStatus.InsufficientReveals\r\n );\r\n }\r\n\r\n function poorIncentives(ResultStatus self) internal pure returns (bool) {\r\n return (\r\n self == ResultStatus.OversizedTallyResult\r\n || self == ResultStatus.InsufficientCommits\r\n || self == ResultStatus.BridgePoorIncentives\r\n || self == ResultStatus.BridgeOversizedTallyResult\r\n );\r\n }\r\n\r\n\r\n /// ===============================================================================================================\r\n /// --- Timestamp helper methods ----------------------------------------------------------------------------------\r\n\r\n function gt(Timestamp a, Timestamp b) internal pure returns (bool) {\r\n return Timestamp.unwrap(a) > Timestamp.unwrap(b);\r\n }\r\n\r\n function egt(Timestamp a, Timestamp b) internal pure returns (bool) {\r\n return Timestamp.unwrap(a) >= Timestamp.unwrap(b);\r\n }\r\n\r\n function elt(Timestamp a, Timestamp b) internal pure returns (bool) {\r\n return Timestamp.unwrap(a) <= Timestamp.unwrap(b);\r\n }\r\n\r\n function isZero(Timestamp t) internal pure returns (bool) {\r\n return Timestamp.unwrap(t) == 0;\r\n }\r\n\r\n\r\n /// ===============================================================================================================\r\n /// --- 'bytes*' helper methods -----------------------------------------------------------------------------------\r\n\r\n function intoMemArray(bytes32[1] memory _values) internal pure returns (bytes32[] memory) {\r\n return abi.decode(abi.encode(uint256(32), 1, _values), (bytes32[]));\r\n }\r\n\r\n function intoMemArray(bytes32[2] memory _values) internal pure returns (bytes32[] memory) {\r\n return abi.decode(abi.encode(uint256(32), 2, _values), (bytes32[]));\r\n }\r\n\r\n function intoMemArray(bytes32[3] memory _values) internal pure returns (bytes32[] memory) {\r\n return abi.decode(abi.encode(uint256(32), 3, _values), (bytes32[]));\r\n }\r\n\r\n function intoMemArray(bytes32[4] memory _values) internal pure returns (bytes32[] memory) {\r\n return abi.decode(abi.encode(uint256(32), 4, _values), (bytes32[]));\r\n }\r\n\r\n function intoMemArray(bytes32[5] memory _values) internal pure returns (bytes32[] memory) {\r\n return abi.decode(abi.encode(uint256(32), 5, _values), (bytes32[]));\r\n }\r\n\r\n function intoMemArray(bytes32[6] memory _values) internal pure returns (bytes32[] memory) {\r\n return abi.decode(abi.encode(uint256(32), 6, _values), (bytes32[]));\r\n }\r\n\r\n function intoMemArray(bytes32[7] memory _values) internal pure returns (bytes32[] memory) {\r\n return abi.decode(abi.encode(uint256(32), 7, _values), (bytes32[]));\r\n }\r\n\r\n function intoMemArray(bytes32[8] memory _values) internal pure returns (bytes32[] memory) {\r\n return abi.decode(abi.encode(uint256(32), 8, _values), (bytes32[]));\r\n }\r\n \r\n function merkleHash(bytes32 a, bytes32 b) internal pure returns (bytes32) {\r\n return (a < b\r\n ? _merkleHash(a, b)\r\n : _merkleHash(b, a)\r\n );\r\n }\r\n\r\n function merkleRoot(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32 _root) {\r\n _root = leaf;\r\n for (uint _ix = 0; _ix < proof.length; _ix ++) {\r\n _root = merkleHash(_root, proof[_ix]);\r\n }\r\n }\r\n\r\n function radHash(bytes calldata bytecode) internal pure returns (Witnet.RadonHash) {\r\n return Witnet.RadonHash.wrap(keccak256(bytecode));\r\n }\r\n\r\n function recoverEvmAddr(bytes memory signature, bytes32 hash_)\r\n internal pure \r\n returns (address)\r\n {\r\n if (signature.length != 65) {\r\n return (address(0));\r\n }\r\n bytes32 r;\r\n bytes32 s;\r\n uint8 v;\r\n assembly {\r\n r := mload(add(signature, 0x20))\r\n s := mload(add(signature, 0x40))\r\n v := byte(0, mload(add(signature, 0x60)))\r\n }\r\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\r\n return address(0);\r\n }\r\n if (v != 27 && v != 28) {\r\n return address(0);\r\n }\r\n return ecrecover(hash_, v, r, s);\r\n }\r\n\r\n function verifyWitAddressAuthorization(\r\n address evmAuthorized, \r\n Address witSigner,\r\n bytes memory witSignature\r\n )\r\n internal pure\r\n returns (bool)\r\n {\r\n bytes32 _publicKeyX = recoverWitPublicKey(keccak256(abi.encodePacked(evmAuthorized)), witSignature);\r\n bytes20 _witSigner = Address.unwrap(witSigner);\r\n return (\r\n _witSigner == bytes20(sha256(abi.encodePacked(bytes1(0x00), _publicKeyX)))\r\n || _witSigner == bytes20(sha256(abi.encodePacked(bytes1(0x01), _publicKeyX)))\r\n || _witSigner == bytes20(sha256(abi.encodePacked(bytes1(0x02), _publicKeyX)))\r\n || _witSigner == bytes20(sha256(abi.encodePacked(bytes1(0x03), _publicKeyX)))\r\n );\r\n }\r\n\r\n function recoverWitPublicKey(bytes32 evmDigest, bytes memory witSignature)\r\n internal pure\r\n returns (bytes32 _witPublicKey)\r\n {\r\n if (witSignature.length == 65) {\r\n bytes32 r;\r\n bytes32 s;\r\n uint8 v;\r\n assembly {\r\n r := mload(add(witSignature, 0x20))\r\n s := mload(add(witSignature, 0x40))\r\n v := byte(0, mload(add(witSignature, 0x60)))\r\n }\r\n if (\r\n uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0\r\n && (v == 27 || v == 28)\r\n ) {\r\n (uint256 x,) = Secp256k1.recover(uint256(evmDigest), v - 27, uint256(r), uint256(s));\r\n _witPublicKey = bytes32(x);\r\n }\r\n }\r\n }\r\n\r\n function toAddress(bytes memory _value) internal pure returns (address) {\r\n return address(toBytes20(_value));\r\n }\r\n\r\n function toBytes4(bytes memory _value) internal pure returns (bytes4) {\r\n return bytes4(toFixedBytes(_value, 4));\r\n }\r\n \r\n function toBytes20(bytes memory _value) internal pure returns (bytes20) {\r\n return bytes20(toFixedBytes(_value, 20));\r\n }\r\n \r\n function toBytes32(bytes memory _value) internal pure returns (bytes32) {\r\n return toFixedBytes(_value, 32);\r\n }\r\n\r\n function toFixedBytes(bytes memory _value, uint8 _numBytes)\r\n internal pure\r\n returns (bytes32 _bytes32)\r\n {\r\n assert(_numBytes <= 32);\r\n unchecked {\r\n uint _len = _value.length > _numBytes ? _numBytes : _value.length;\r\n for (uint _i = 0; _i < _len; _i ++) {\r\n _bytes32 |= bytes32(_value[_i] & 0xff) >> (_i * 8);\r\n }\r\n }\r\n }\r\n \r\n /// @notice Converts bytes32 into string.\r\n function asAscii(bytes32 _bytes32)\r\n internal pure\r\n returns (string memory)\r\n {\r\n bytes memory _bytes = new bytes(_toStringLength(_bytes32));\r\n for (uint _i = 0; _i < _bytes.length;) {\r\n _bytes[_i] = _bytes32[_i];\r\n unchecked {\r\n _i ++;\r\n }\r\n }\r\n return string(_bytes);\r\n }\r\n\r\n function toHexString(bytes32 _bytes32) \r\n internal pure\r\n returns (string memory)\r\n {\r\n bytes memory _bytes = new bytes(64);\r\n for (uint8 _i; _i < _bytes.length;) {\r\n _bytes[_i ++] = _toHexChar(uint8(_bytes32[_i / 2] >> 4));\r\n _bytes[_i ++] = _toHexChar(uint8(_bytes32[_i / 2] & 0x0f));\r\n }\r\n return string(_bytes);\r\n }\r\n\r\n\r\n /// ==============================================================================