Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multi Chain
Multichain Addresses
N/ALatest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 8304867 | 330 days 16 hrs ago | IN | Create: Parser | 0 ETH | 0.0145689 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH | ||||
9212641 | 172 days 7 hrs ago | 0 ETH |
Loading...
Loading
Contract Name:
Parser
Compiler Version
v0.8.11+commit.d7f03943
Optimization Enabled:
No with 100 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import { IERC20 } from './interfaces/IERC20.sol'; import { IDSLContext } from './interfaces/IDSLContext.sol'; import { IProgramContext } from './interfaces/IProgramContext.sol'; import { IParser } from './interfaces/IParser.sol'; import { IPreprocessor } from './interfaces/IPreprocessor.sol'; import { StringUtils } from './libs/StringUtils.sol'; import { ByteUtils } from './libs/ByteUtils.sol'; import { Preprocessor } from './Preprocessor.sol'; import { ErrorsParser } from './libs/Errors.sol'; // import 'hardhat/console.sol'; /** * @dev Parser of DSL code. This contract is a singleton and should not * be deployed more than once * * One of the core contracts of the project. It parses DSL expression * that comes from user. After parsing code in Parser * a bytecode of the DSL program is generated as stored in ProgramContext * * DSL code in postfix notation as string -> Parser -> raw bytecode */ contract Parser is IParser { using StringUtils for string; using ByteUtils for bytes; string[] internal cmds; // DSL code in postfix form (output of Preprocessor) uint256 internal cmdIdx; // Current parsing index of DSL code /** * @dev Transform DSL code from array in infix notation to raw bytecode * @param _dslCtxAddr DSLContext contract address * @param _programCtxAddr ProgramContext contract address * @param _codeRaw Input code as a string in infix notation */ function parse( address _preprAddr, address _dslCtxAddr, address _programCtxAddr, string memory _codeRaw ) external { string[] memory _code = IPreprocessor(_preprAddr).transform(_dslCtxAddr, _codeRaw); parseCode(_dslCtxAddr, _programCtxAddr, _code); } /** * @dev Сonverts a list of commands to bytecode */ function parseCode(address _dslCtxAddr, address _programCtxAddr, string[] memory _code) public { cmdIdx = 0; bytes memory b; bytes memory program; IProgramContext(_programCtxAddr).setProgram(b); // TODO: set to 0 that program in the program context _setCmdsArray(_code); // remove empty strings IProgramContext(_programCtxAddr).setPc(0); IProgramContext(_programCtxAddr).stack().clear(); while (cmdIdx < cmds.length) { program = _parseOpcodeWithParams(_dslCtxAddr, _programCtxAddr, program); } IProgramContext(_programCtxAddr).setProgram(program); } /** * @dev Asm functions * Concatenates the previous program bytecode with the next command * that contains in the `cmds` list. `cmdIdx` is helping to follow * what exactly the command is in the process * Example of code for : * ``` * cmds = ['bool', 'true'] // current cmds * cmdIdx = 0 // current parsing index of DSL code * program = '' * ``` * * So it will be executed the asmSetLocalBool() function where: * - `_parseVariable()` internal function will update the previous empty * `program` with the bytecode of `bool` opcode * * Result is `program = '0x18'` (see Context.sol for `addOpcode('bool'..)` * to check the code for `bool` opcode) * cmdIdx = 0 // current parsing index of DSL code is the same * * - `asmBool()` function will concatenate previous `program` with the bytecode of `true` value * `program` with the bytecode `0x01` (see return values for Parser.sol for `asmBool()` function * * ``` * cmdIdx = 1 // parsing index of DSL code was updated * program = '0x1801' * ``` */ /** * @dev Updates the program with the bool value * * Example of a command: * ``` * bool true * ``` */ function asmSetLocalBool( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); newProgram = asmBool(newProgram, address(0), address(0)); } /** * @dev Updates the program with the local variable value * * Example of a command: * ``` * (uint256 5 + uint256 7) setUint256 VARNAME * ``` */ function asmSetUint256( bytes memory _program, address, address ) public returns (bytes memory newProgram) { return _parseVariable(_program); } /** * @dev Updates the program with the name(its position) of the array * * Example of a command: * ``` * declare ARR_NAME * ``` */ function asmDeclare( bytes memory _program, address _ctxDSLAddr, address ) public returns (bytes memory newProgram) { newProgram = _parseBranchOf(_program, _ctxDSLAddr, 'declareArr'); // program += bytecode for type of array newProgram = _parseVariable(newProgram); // program += bytecode for `ARR_NAME` } function asmCompound( bytes memory _program, address _ctxDSLAddr, address ) public returns (bytes memory newProgram) { // program += bytecode for type of transaction for compound contract (deposit/withdraw) newProgram = _parseBranchOf(_program, _ctxDSLAddr, 'compound'); _nextCmd(); // skip `all` keyword newProgram = _parseVariable(newProgram); // program += bytecode for `TOKEN` } /** * @dev Updates the program with the element by index from the provived array's name * * Example of a command: * ``` * get 3 USERS * ``` */ function asmGet( bytes memory _program, address, address ) public returns (bytes memory newProgram) { string memory _value = _nextCmd(); bytes4 _arrName = bytes4(keccak256(abi.encodePacked(_nextCmd()))); newProgram = bytes.concat(_program, bytes32(_value.toUint256()), _arrName); } /** * @dev Updates the program with the new item for the array, can be `uint256`, * `address` and `struct name` types. * * Example of a command: * ``` * push ITEM ARR_NAME * ``` */ function asmPush( bytes memory _program, address, address ) public returns (bytes memory newProgram) { string memory _value = _nextCmd(); bytes4 _arrName = bytes4(keccak256(abi.encodePacked(_nextCmd()))); if (_value.mayBeAddress()) { bytes memory _sliced = bytes(_value).slice(2, 42); // without first `0x` symbols newProgram = bytes.concat(_program, bytes32(_sliced.fromHexBytes())); } else if (_value.mayBeNumber()) { newProgram = bytes.concat(_program, bytes32(_value.toUint256())); } else { // only for struct names! newProgram = bytes.concat( _program, bytes32(bytes4(keccak256(abi.encodePacked(_value)))) ); } newProgram = bytes.concat(newProgram, _arrName); } /** * @dev Updates the program with the loadLocal variable * * Example of command: * ``` * var NUMBER * ``` */ function asmVar( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); } /** * @dev Updates the program with the loadRemote variable * * Example of a command: * ``` * loadRemote bool MARY_ADDRESS 9A676e781A523b5d0C0e43731313A708CB607508 * ``` */ function asmLoadRemote( bytes memory _program, address _ctxDSLAddr, address ) public returns (bytes memory newProgram) { newProgram = _parseBranchOf(_program, _ctxDSLAddr, 'loadRemote'); // program += bytecode for `loadRemote bool` newProgram = _parseVariable(newProgram); // program += bytecode for `MARY_ADDRESS` newProgram = _parseAddress(newProgram); // program += bytecode for `9A676e781A523b5...` } /** * @dev Concatenates and updates previous `program` with the `0x01` * bytecode of `true` value otherwise `0x00` for `false` */ function asmBool( bytes memory _program, address, address ) public returns (bytes memory newProgram) { bytes1 value = bytes1(_nextCmd().equal('true') ? 0x01 : 0x00); newProgram = bytes.concat(_program, value); } /** * @dev Concatenates and updates previous `program` with the * bytecode of uint256 value */ function asmUint256(bytes memory _program, address, address) public returns (bytes memory) { uint256 value = _nextCmd().toUint256(); return bytes.concat(_program, bytes32(value)); } /** * @dev Updates previous `program` with the amount that will be send (in wei) * * Example of a command: * ``` * sendEth RECEIVER 1234 * ``` */ function asmSend( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); // program += bytecode for `sendEth RECEIVER` newProgram = asmUint256(newProgram, address(0), address(0)); // program += bytecode for `1234` } /** * @dev Updates previous `program` with the amount of tokens * that will be transfer to reciever(in wei). The `TOKEN` and `RECEIVER` * parameters should be stored in smart contract * * Example of a command: * ``` * transfer TOKEN RECEIVER 1234 * ``` */ function asmTransfer( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); // token address newProgram = _parseVariable(newProgram); // receiver address newProgram = asmUint256(newProgram, address(0), address(0)); // amount } /** * @dev Updates previous `program` with the amount of tokens * that will be transfer to reciever(in wei). The `TOKEN`, `RECEIVER`, `AMOUNT` * parameters should be stored in smart contract * * Example of a command: * ``` * transferVar TOKEN RECEIVER AMOUNT * ``` */ function asmTransferVar( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); // token address newProgram = _parseVariable(newProgram); // receiver newProgram = _parseVariable(newProgram); // amount } /** * @dev Updates previous `program` with the amount of tokens * that will be transfer from the certain address to reciever(in wei). * The `TOKEN`, `FROM`, `TO` address parameters should be stored in smart contract * * Example of a command: * ``` * transferFrom TOKEN FROM TO 1234 * ``` */ function asmTransferFrom( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); // token address newProgram = _parseVariable(newProgram); // from newProgram = _parseVariable(newProgram); // to newProgram = asmUint256(newProgram, address(0), address(0)); // amount } /** * @dev Updates previous `program` with the amount of tokens * that will be transfer from the certain address to reciever(in wei). * The `TOKEN`, `FROM`, `TO`, `AMOUNT` parameters should be stored in smart contract * * Example of a command: * ``` * transferFromVar TOKEN FROM TO AMOUNT * ``` */ function asmTransferFromVar( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); // token address newProgram = _parseVariable(newProgram); // from newProgram = _parseVariable(newProgram); // to newProgram = _parseVariable(newProgram); // amount } /** * @dev Updates previous `program` with getting the amount of tokens * The `TOKEN`, `USER` address parameters should be stored in smart contract * * Example of a command: * ``` * balanceOf TOKEN USER * ``` */ function asmBalanceOf( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); // token address newProgram = _parseVariable(newProgram); // user address } function asmAllowanceMintBurn( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); // token address, token address, token address newProgram = _parseVariable(newProgram); // owner, to, owner newProgram = _parseVariable(newProgram); // spender, amount, amount } /** * @dev Updates previous `program` with getting the length of the dsl array by its name * The command return non zero value only if the array name was declared and have at least one value. * Check: `declareArr` and `push` commands for DSL arrays * * Example of a command: * ``` * lengthOf ARR_NAME * ``` */ function asmLengthOf(bytes memory _program, address, address) public returns (bytes memory) { return _parseVariable(_program); // array name } /** * @dev Updates previous `program` with the name of the dsl array that will * be used to sum uint256 variables * * Example of a command: * ``` * sumOf ARR_NAME * ``` */ function asmSumOf(bytes memory _program, address, address) public returns (bytes memory) { return _parseVariable(_program); // array name } /** * @dev Updates previous `program` with the name of the dsl array and * name of variable in the DSL structure that will * be used to sum uint256 variables * * Example of a command: * ``` * struct BOB { * lastPayment: 3 * } * * struct ALISA { * lastPayment: 300 * } * * sumThroughStructs USERS.lastPayment * or shorter version * sumOf USERS.lastPayment * ``` */ function asmSumThroughStructs( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); // array name newProgram = _parseVariable(newProgram); // variable name } /** * @dev Updates previous `program` for positive and negative branch position * * Example of a command: * ``` * 6 > 5 // condition is here must return true or false * ifelse AA BB * end * * branch AA { * // code for `positive` branch * } * * branch BB { * // code for `negative` branch * } * ``` */ function asmIfelse( bytes memory _program, address, address _programCtxAddr ) public returns (bytes memory newProgram) { string memory _true = _nextCmd(); // "positive" branch name string memory _false = _nextCmd(); // "negative" branch name // set `positive` branch position _setLabelPos(_programCtxAddr, _true, _program.length); newProgram = bytes.concat(_program, bytes2(0)); // placeholder for `positive` branch offset // set `negative` branch position _setLabelPos(_programCtxAddr, _false, newProgram.length); newProgram = bytes.concat(newProgram, bytes2(0)); // placeholder for `negative` branch offset } /** * @dev Updates previous `program` for positive branch position * * Example of a command: * ``` * 6 > 5 // condition is here must return true or false * if POSITIVE_ACTION * end * * POSITIVE_ACTION { * // code for `positive` branch * } * ``` */ function asmIf( bytes memory _program, address, address _programCtxAddr ) public returns (bytes memory newProgram) { _setLabelPos(_programCtxAddr, _nextCmd(), _program.length); newProgram = bytes.concat(_program, bytes2(0)); // placeholder for `true` branch offset } /** * @dev Updates previous `program` for function code * * Example of a command: * ``` * func NAME_OF_FUNCTION * * NAME_OF_FUNCTION { * // code for the body of function * } * ``` */ function asmFunc( bytes memory _program, address, address _programCtxAddr ) public returns (bytes memory newProgram) { // set `name of function` position _setLabelPos(_programCtxAddr, _nextCmd(), _program.length); newProgram = bytes.concat(_program, bytes2(0)); // placeholder for `name of function` offset } /** * @dev Updates previous `program` for DSL struct. * This function rebuilds variable parameters using a name of the structure, dot symbol * and the name of each parameter in the structure * * Example of DSL command: * ``` * struct BOB { * account: 0x47f8a90ede3d84c7c0166bd84a4635e4675accfc, * lastPayment: 3 * } * ``` * * Example of commands that uses for this functions: * `cmds = ['struct', 'BOB', 'lastPayment', '3', 'account', '0x47f..', 'endStruct']` * * `endStruct` word is used as an indicator for the ending loop for the structs parameters */ function asmStruct( bytes memory _program, address, address _programCtxAddr ) public returns (bytes memory newProgram) { // parse the name of structure - `BOB` string memory _structName = _nextCmd(); newProgram = _program; // parsing name/value parameters till found the 'endStruct' word do { // parse the name of variable - `balance`, `account` string memory _variable = _nextCmd(); // create the struct name of variable - `BOB.balance`, `BOB.account` string memory _name = _structName.concat('.').concat(_variable); // TODO: let's think how not to use setter in Parser here.. IProgramContext(_programCtxAddr).setStructVars(_structName, _variable, _name); // TODO: store sertain bytes for each word separate in bytes string? newProgram = bytes.concat(newProgram, bytes4(keccak256(abi.encodePacked(_name)))); // parse the value of `balance` variable - `456`, `0x345...` string memory _value = _nextCmd(); if (_value.mayBeAddress()) { // remove first `0x` symbols bytes memory _sliced = bytes(_value).slice(2, 42); newProgram = bytes.concat(newProgram, bytes32(_sliced.fromHexBytes())); } else if (_value.mayBeNumber()) { newProgram = bytes.concat(newProgram, bytes32(_value.toUint256())); } else if (_variable.equal('vote') && _value.equal('YES')) { // voting process, change stored value in the array 1 newProgram = bytes.concat(newProgram, bytes32(uint256(1))); } else if (_variable.equal('vote') && _value.equal('NO')) { // voting process, change stored value in the array to 0 newProgram = bytes.concat(newProgram, bytes32(0)); } // else { // // if the name of the variable // program = bytes.concat(program, bytes32(keccak256(abi.encodePacked(_value)))); // } } while (!(cmds[cmdIdx].equal('endStruct'))); newProgram = _parseVariable(newProgram); // parse the 'endStruct' word } /** * @dev Parses variable names in for-loop & skip the unnecessary `in` parameter * Ex. ['for', 'LP_INITIAL', 'in', 'LPS_INITIAL'] */ function asmForLoop( bytes memory _program, address, address ) public returns (bytes memory newProgram) { // parse temporary variable name newProgram = _parseVariable(_program); _nextCmd(); // skip `in` keyword newProgram = _parseVariable(newProgram); } /** * @dev Parses the `record id` and the `agreement address` parameters * Ex. ['enableRecord', 'RECORD_ID', 'at', 'AGREEMENT_ADDRESS'] */ function asmEnableRecord( bytes memory _program, address, address ) public returns (bytes memory newProgram) { newProgram = _parseVariable(_program); _nextCmd(); // skip `at` keyword newProgram = _parseVariable(newProgram); } /** * Internal functions */ /** * @dev returns `true` if the name of `if/ifelse branch` or `function` exists in the labelPos list * otherwise returns `false` */ function _isLabel(address _programCtxAddr, string memory _name) internal view returns (bool) { return _getLabelPos(_programCtxAddr, _name) > 0; } function _getLabelPos( address _programCtxAddr, string memory _name ) internal view returns (uint256) { return IProgramContext(_programCtxAddr).labelPos(_name); } /** * @dev Updates the bytecode `program` in dependence on * commands that were provided in `cmds` list */ function _parseOpcodeWithParams( address _dslCtxAddr, address _programCtxAddr, bytes memory _program ) internal returns (bytes memory newProgram) { string storage cmd = _nextCmd(); bytes1 opcode = IDSLContext(_dslCtxAddr).opCodeByName(cmd); // TODO: simplify bytes4 _selector = bytes4(keccak256(abi.encodePacked(cmd))); bool isStructVar = IProgramContext(_programCtxAddr).isStructVar(cmd); if (_isLabel(_programCtxAddr, cmd)) { bytes2 _branchLocation = bytes2(uint16(_program.length)); uint256 labelPos = _getLabelPos(_programCtxAddr, cmd); newProgram = bytes.concat( _program.slice(0, labelPos), // programBefore _branchLocation, _program.slice(labelPos + 2, _program.length) // programAfter ); // TODO: move isValidVarName() check to Preprocessor // (it should automatically add `var` before all variable names) } else if (cmd.isValidVarName() || isStructVar) { opcode = IDSLContext(_dslCtxAddr).opCodeByName('var'); newProgram = bytes.concat(_program, opcode, _selector); } else if (opcode == 0x0) { revert(string(abi.encodePacked('Parser: "', cmd, '" command is unknown'))); } else { newProgram = bytes.concat(_program, opcode); _selector = IDSLContext(_dslCtxAddr).asmSelectors(cmd); if (_selector != 0x0) { // TODO: address, address (bool success, bytes memory data) = address(this).delegatecall( abi.encodeWithSelector(_selector, newProgram, _dslCtxAddr, _programCtxAddr) ); require(success, ErrorsParser.PRS1); newProgram = abi.decode(data, (bytes)); } // if no selector then opcode without params } } /** * @dev Returns next commad from the cmds list, increases the * command index `cmdIdx` by 1 * @return nextCmd string */ function _nextCmd() internal returns (string storage) { return cmds[cmdIdx++]; } /** * @dev Updates previous `program` with the next provided command */ function _parseVariable(bytes memory _program) internal returns (bytes memory newProgram) { bytes4 _cmd = bytes4(keccak256(abi.encodePacked(_nextCmd()))); newProgram = bytes.concat(_program, _cmd); } /** * @dev Updates previous `program` with the branch name, like `loadLocal` or `loadRemote` * of command and its additional used type */ function _parseBranchOf( bytes memory _program, address _ctxDSLAddr, string memory baseOpName ) internal returns (bytes memory newProgram) { newProgram = bytes.concat( _program, IDSLContext(_ctxDSLAddr).branchCodes(baseOpName, _nextCmd()) ); } /** * @dev Updates previous `program` with the address command that is a value */ function _parseAddress(bytes memory _program) internal returns (bytes memory newProgram) { string memory _addr = _nextCmd(); _addr = _addr.substr(2, _addr.length()); // cut `0x` from the beginning of the address newProgram = bytes.concat(_program, _addr.fromHex()); } /** * @dev Deletes empty elements from the _input array and sets the result as a `cmds` storage array */ function _setCmdsArray(string[] memory _input) internal { uint256 i; delete cmds; while (i < _input.length && !_input[i].equal('')) { cmds.push(_input[i++]); } } function _setLabelPos(address _programCtxAddr, string memory _name, uint256 _value) internal { IProgramContext(_programCtxAddr).setLabelPos(_name, _value); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import '../helpers/Stack.sol'; interface IDSLContext { enum OpcodeLibNames { ComparisonOpcodes, BranchingOpcodes, LogicalOpcodes, OtherOpcodes } function comparisonOpcodes() external view returns (address); function branchingOpcodes() external view returns (address); function logicalOpcodes() external view returns (address); function otherOpcodes() external view returns (address); function opCodeByName(string memory _name) external view returns (bytes1 _opcode); function selectorByOpcode(bytes1 _opcode) external view returns (bytes4 _selecotor); function numOfArgsByOpcode(string memory _name) external view returns (uint8 _numOfArgs); function isCommand(string memory _name) external view returns (bool _isCommand); function opcodeLibNameByOpcode(bytes1 _opcode) external view returns (OpcodeLibNames _name); function asmSelectors(string memory _name) external view returns (bytes4 _selecotor); function opsPriors(string memory _name) external view returns (uint256 _priority); function operators(uint256 _index) external view returns (string memory _operator); function branchSelectors( string memory _baseOpName, bytes1 _branchCode ) external view returns (bytes4 _selector); function branchCodes( string memory _baseOpName, string memory _branchName ) external view returns (bytes1 _branchCode); function aliases(string memory _alias) external view returns (string memory _baseCmd); // Functions function operatorsLen() external view returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import { IDSLContext } from './IDSLContext.sol'; import { Preprocessor } from '../Preprocessor.sol'; interface IParser { // Variables event ExecRes(bool result); event NewConditionalTx(address txObj); // Functions function parse( address _preprAddr, address _dslCtxAddr, address _programCtxAddr, string memory _codeRaw ) external; function parseCode( address _dslCtxAddr, address _programCtxAddr, string[] memory _code ) external; function asmSetLocalBool( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmSetUint256( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmVar( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmLoadRemote( bytes memory _program, address _ctxDSLAddr, address ) external returns (bytes memory newProgram); function asmDeclare( bytes memory _program, address _ctxDSLAddr, address ) external returns (bytes memory newProgram); function asmCompound( bytes memory _program, address _ctxDSLAddr, address ) external returns (bytes memory newProgram); function asmBool( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmUint256( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmSend( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmTransfer( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmTransferVar( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmTransferFrom( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmBalanceOf( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmAllowanceMintBurn( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmLengthOf( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmSumOf( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmSumThroughStructs( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmTransferFromVar( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmIfelse( bytes memory _program, address _ctxDSLAddr, address _programCtxAddr ) external returns (bytes memory newProgram); function asmIf( bytes memory _program, address _ctxDSLAddr, address _programCtxAddr ) external returns (bytes memory newProgram); function asmFunc( bytes memory _program, address _ctxDSLAddr, address _programCtxAddr ) external returns (bytes memory newProgram); function asmGet( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmPush( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmStruct( bytes memory _program, address _ctxDSLAddr, address _programCtxAddr ) external returns (bytes memory newProgram); function asmForLoop( bytes memory _program, address, address ) external returns (bytes memory newProgram); function asmEnableRecord( bytes memory _program, address, address ) external returns (bytes memory newProgram); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import { IDSLContext } from './interfaces/IDSLContext.sol'; import { IPreprocessor } from './interfaces/IPreprocessor.sol'; import { StringStack } from './libs/StringStack.sol'; import { StringUtils } from './libs/StringUtils.sol'; import { ErrorsPreprocessor } from './libs/Errors.sol'; /** * @dev Preprocessor of DSL code * @dev This contract is a singleton and should not be deployed more than once * * It can remove comments that were created by user in the DSL code string. It * transforms the users DSL code string to the list of commands that can be used * in a Parser contract. * * DSL code in postfix notation as * user's string code -> Preprocessor -> each command is separated in the commands list */ library Preprocessor { using StringUtils for string; using StringStack for string[]; /************************ * == MAIN FUNCTIONS == * ***********************/ /** * @dev The main function that transforms the user's DSL code string to the list of commands. * * Example: * The user's DSL code string is * ``` * uint256 6 setUint256 A * ``` * The end result after executing a `transform()` function is * ``` * ['uint256', '6', 'setUint256', 'A'] * ``` * * @param _ctxAddr is a context contract address * @param _program is a user's DSL code string * @return code The list of commands that storing `result` */ function transform( address _ctxAddr, string memory _program ) external view returns (string[] memory code) { // _program = removeComments(_program); code = split(_program, '\n ,:(){}', '(){}'); code = removeSyntacticSugar(code); code = simplifyCode(code, _ctxAddr); code = infixToPostfix(_ctxAddr, code); return code; } /** * @dev Searches the comments in the program and removes comment lines * Example: * The user's DSL code string is * ``` * bool true * // uint256 2 * uint256 5 * ``` * The end result after executing a `removeComments()` function is * ``` * bool true * ``` * @param _program is a current program string * @return _cleanedProgram new string program that contains only clean code without comments */ function removeComments( string memory _program ) public pure returns (string memory _cleanedProgram) { bool isCommented; // searchedSymbolLen is a flag that uses for searching a correct end symbol uint256 searchedSymbolLen; // 1 - search \n symbol, 2 - search */ symbol uint256 tempIndex; // uses for checking if the index was changed uint256 i; string memory char; while (i < _program.length()) { char = _program.char(i); tempIndex = i; if (isCommented) { (tempIndex, isCommented) = _getEndCommentSymbol( searchedSymbolLen, i, _program, char ); } else { (searchedSymbolLen, tempIndex, isCommented) = _getCommentSymbol(i, _program, char); } if (tempIndex > i) { i = tempIndex; continue; } if (isCommented) { i += 1; continue; } _cleanedProgram = _cleanedProgram.concat(char); i += 1; } } /** * @dev Splits the user's DSL code string to the list of commands * avoiding several symbols: * - removes additional and useless symbols as ' ', `\\n` * - defines and adding help 'end' symbol for the ifelse condition * - defines and cleans the code from `{` and `}` symbols * * Example: * The user's DSL code string is * ``` * (var TIMESTAMP > var INIT) * ``` * The end result after executing a `split()` function is * ``` * ['var', 'TIMESTAMP', '>', 'var', 'INIT'] * ``` * * @param _program is a user's DSL code string * @param _separators Separators that will be used to split the string * @param _separatorsToKeep we're using symbols from this string as separators but not removing * them from the resulting array * @return The list of commands that storing in `result` */ function split( string memory _program, string memory _separators, string memory _separatorsToKeep ) public pure returns (string[] memory) { string[] memory _result = new string[](50); uint256 resultCtr; string memory buffer; // here we collect DSL commands, var names, etc. symbol by symbol string memory char; for (uint256 i = 0; i < _program.length(); i++) { char = _program.char(i); if (char.isIn(_separators)) { if (buffer.length() > 0) { _result[resultCtr++] = buffer; buffer = ''; } } else { buffer = buffer.concat(char); } if (char.isIn(_separatorsToKeep)) { _result[resultCtr++] = char; } } if (buffer.length() > 0) { _result[resultCtr++] = buffer; buffer = ''; } return _result; } /** * @dev Removes scientific notation from numbers and removes currency symbols * Example * 1e3 = 1,000 * 1 GWEI = 1,000,000,000 * 1 ETH = 1,000,000,000,000,000,000 * @param _code Array of DSL commands * @return Code without syntactic sugar */ function removeSyntacticSugar(string[] memory _code) public pure returns (string[] memory) { string[] memory _result = new string[](50); uint256 _resultCtr; string memory _chunk; string memory _prevChunk; uint256 i; while (i < _nonEmptyArrLen(_code)) { _prevChunk = i == 0 ? '' : _code[i - 1]; _chunk = _code[i++]; _chunk = _checkScientificNotation(_chunk); if (_isCurrencySymbol(_chunk)) { (_resultCtr, _chunk) = _processCurrencySymbol(_resultCtr, _chunk, _prevChunk); } _result[_resultCtr++] = _chunk; } return _result; } /** * @dev Depending on the type of the command it gets simplified * @param _code Array of DSL commands * @param _ctxAddr Context contract address * @return Simplified code */ function simplifyCode( string[] memory _code, address _ctxAddr ) public view returns (string[] memory) { string[] memory _result = new string[](50); uint256 _resultCtr; string memory _chunk; string memory _prevChunk; uint256 i; while (i < _nonEmptyArrLen(_code)) { _prevChunk = i == 0 ? '' : _code[i - 1]; _chunk = _code[i++]; if (IDSLContext(_ctxAddr).isCommand(_chunk)) { (_result, _resultCtr, i) = _processCommand(_result, _resultCtr, _code, i, _ctxAddr); } else if (_isCurlyBracket(_chunk)) { (_result, _resultCtr) = _processCurlyBracket(_result, _resultCtr, _chunk); } else if (_isAlias(_chunk, _ctxAddr)) { (_result, _resultCtr) = _processAlias(_result, _resultCtr, _ctxAddr, _chunk); } else if (_chunk.equal('insert')) { (_result, _resultCtr, i) = _processArrayInsert(_result, _resultCtr, _code, i); } else { (_result, _resultCtr) = _checkIsNumberOrAddress(_result, _resultCtr, _chunk); _result[_resultCtr++] = _chunk; } } return _result; } /** * @dev Transforms code in infix format to the postfix format * @param _code Array of DSL commands * @param _ctxAddr Context contract address * @return Code in the postfix format */ function infixToPostfix( address _ctxAddr, string[] memory _code ) public view returns (string[] memory) { string[] memory _result = new string[](50); string[] memory _stack = new string[](50); uint256 _resultCtr; string memory _chunk; uint256 i; while (i < _nonEmptyArrLen(_code)) { _chunk = _code[i++]; if (_isOperator(_chunk, _ctxAddr)) { (_result, _resultCtr, _stack) = _processOperator( _stack, _result, _resultCtr, _ctxAddr, _chunk ); } else if (_isParenthesis(_chunk)) { (_result, _resultCtr, _stack) = _processParenthesis( _stack, _result, _resultCtr, _chunk ); } else { _result[_resultCtr++] = _chunk; } } // Note: now we have a stack with DSL commands and we will pop from it and save to the resulting array to move // from postfix to infix notation while (_stack.stackLength() > 0) { (_stack, _result[_resultCtr++]) = _stack.popFromStack(); } return _result; } /*************************** * == PROCESS FUNCTIONS == * **************************/ /** * @dev Process insert into array command * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @param _code Current DSL code that we're processing * @param i Current pointer to the element in _code array that we're processing * @return Modified _result array, mofified _resultCtr, and modified `i` */ function _processArrayInsert( string[] memory _result, uint256 _resultCtr, string[] memory _code, uint256 i ) internal pure returns (string[] memory, uint256, uint256) { // Get the necessary params of `insert` command // Notice: `insert 1234 into NUMBERS` -> `push 1234 NUMBERS` string memory _insertVal = _code[i]; string memory _arrName = _code[i + 2]; _result[_resultCtr++] = 'push'; _result[_resultCtr++] = _insertVal; _result[_resultCtr++] = _arrName; return (_result, _resultCtr, i + 3); } /** * @dev Process summing over array comand * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @param _code Current DSL code that we're processing * @param i Current pointer to the element in _code array that we're processing * @return Modified _result array, mofified _resultCtr, and modified `i` */ function _processSumOfCmd( string[] memory _result, uint256 _resultCtr, string[] memory _code, uint256 i ) internal pure returns (string[] memory, uint256, uint256) { // Ex. (sumOf) `USERS.balance` -> ['USERS', 'balance'] // Ex. (sumOf) `USERS` ->['USERS'] string[] memory _sumOfArgs = split(_code[i], '.', ''); // Ex. `sumOf USERS.balance` -> sum over array of structs // Ex. `sumOf USERS` -> sum over a regular array if (_nonEmptyArrLen(_sumOfArgs) == 2) { // process `sumOf` over array of structs _result[_resultCtr++] = 'sumThroughStructs'; _result[_resultCtr++] = _sumOfArgs[0]; _result[_resultCtr++] = _sumOfArgs[1]; } else { // process `sumOf` over a regular array _result[_resultCtr++] = 'sumOf'; _result[_resultCtr++] = _sumOfArgs[0]; } return (_result, _resultCtr, i + 1); } /** * @dev Process for-loop * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @param _code Current DSL code that we're processing * @param i Current pointer to the element in _code array that we're processing * @return Modified _result array, mofified _resultCtr, and modified `i` */ function _processForCmd( string[] memory _result, uint256 _resultCtr, string[] memory _code, uint256 i ) internal pure returns (string[] memory, uint256, uint256) { // TODO } /** * @dev Process `struct` comand * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @param _code Current DSL code that we're processing * @param i Current pointer to the element in _code array that we're processing * @return Modified _result array, mofified _resultCtr, and modified `i` */ function _processStruct( string[] memory _result, uint256 _resultCtr, string[] memory _code, uint256 i ) internal pure returns (string[] memory, uint256, uint256) { // 'struct', 'BOB', '{', 'balance', '456', '}' _result[_resultCtr++] = 'struct'; _result[_resultCtr++] = _code[i]; // struct name // skip `{` (index is i + 1) uint256 j = i + 1; while (!_code[j + 1].equal('}')) { _result[_resultCtr++] = _code[j + 1]; // struct key _result[_resultCtr++] = _code[j + 2]; // struct value j = j + 2; } _result[_resultCtr++] = 'endStruct'; return (_result, _resultCtr, j + 2); } /** * @dev Process `ETH`, `WEI` symbols in the code * @param _resultCtr Current pointer to the empty element in the _result param * @param _chunk The current piece of code that we're processing (should be the currency symbol) * @param _prevChunk The previous piece of code * @return Mofified _resultCtr, and modified `_prevChunk` */ function _processCurrencySymbol( uint256 _resultCtr, string memory _chunk, string memory _prevChunk ) internal pure returns (uint256, string memory) { uint256 _currencyMultiplier = _getCurrencyMultiplier(_chunk); try _prevChunk.toUint256() { _prevChunk = StringUtils.toString(_prevChunk.toUint256() * _currencyMultiplier); } catch { _prevChunk = StringUtils.toString( _prevChunk.parseScientificNotation().toUint256() * _currencyMultiplier ); } // this is to rewrite old number (ex. 100) with an extended number (ex. 100 GWEI = 100000000000) if (_resultCtr > 0) { --_resultCtr; } return (_resultCtr, _prevChunk); } /** * @dev Process DSL alias * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @param _ctxAddr Context contract address * @param _chunk The current piece of code that we're processing * @return Modified _result array, mofified _resultCtr, and modified `i` */ function _processAlias( string[] memory _result, uint256 _resultCtr, address _ctxAddr, string memory _chunk ) internal view returns (string[] memory, uint256) { uint256 i; // Replace alises with base commands _chunk = IDSLContext(_ctxAddr).aliases(_chunk); // Process multi-command aliases // Ex. `uint256[]` -> `declareArr uint256` string[] memory _chunks = split(_chunk, ' ', ''); // while we've not finished processing all the program - keep going while (i < _nonEmptyArrLen(_chunks)) { _result[_resultCtr++] = _chunks[i++]; } return (_result, _resultCtr); } /** * @dev Process any DSL command * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @param _code Current DSL code that we're processing * @param i Current pointer to the element in _code array that we're processing * @param _ctxAddr Context contract address * @return Modified _result array, mofified _resultCtr, and modified `i` */ function _processCommand( string[] memory _result, uint256 _resultCtr, string[] memory _code, uint256 i, address _ctxAddr ) internal view returns (string[] memory, uint256, uint256) { string memory _chunk = _code[i - 1]; if (_chunk.equal('struct')) { (_result, _resultCtr, i) = _processStruct(_result, _resultCtr, _code, i); } else if (_chunk.equal('sumOf')) { (_result, _resultCtr, i) = _processSumOfCmd(_result, _resultCtr, _code, i); } else if (_chunk.equal('for')) { (_result, _resultCtr, i) = _processForCmd(_result, _resultCtr, _code, i); } else { uint256 _skipCtr = IDSLContext(_ctxAddr).numOfArgsByOpcode(_chunk) + 1; i--; // this is to include the command name in the loop below // add command arguments while (_skipCtr > 0) { _result[_resultCtr++] = _code[i++]; _skipCtr--; } } return (_result, _resultCtr, i); } /** * @dev Process open and closed parenthesis * @param _stack Stack that is used to process parenthesis * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @param _chunk The current piece of code that we're processing * @return Modified _result array, mofified _resultCtr, and modified _stack */ function _processParenthesis( string[] memory _stack, string[] memory _result, uint256 _resultCtr, string memory _chunk ) internal pure returns (string[] memory, uint256, string[] memory) { if (_chunk.equal('(')) { // opening bracket _stack = _stack.pushToStack(_chunk); } else if (_chunk.equal(')')) { // closing bracket (_result, _resultCtr, _stack) = _processClosingParenthesis(_stack, _result, _resultCtr); } return (_result, _resultCtr, _stack); } /** * @dev Process closing parenthesis * @param _stack Stack that is used to process parenthesis * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @return Modified _result array, mofified _resultCtr, and modified _stack */ function _processClosingParenthesis( string[] memory _stack, string[] memory _result, uint256 _resultCtr ) public pure returns (string[] memory, uint256, string[] memory) { while (!_stack.seeLastInStack().equal('(')) { (_stack, _result[_resultCtr++]) = _stack.popFromStack(); } (_stack, ) = _stack.popFromStack(); // remove '(' that is left return (_result, _resultCtr, _stack); } /** * @dev Process curly brackets * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @param _chunk The current piece of code that we're processing * @return Modified _result array, mofified _resultCtr */ function _processCurlyBracket( string[] memory _result, uint256 _resultCtr, string memory _chunk ) internal pure returns (string[] memory, uint256) { // if `_chunk` equal `{` - do nothing if (_chunk.equal('}')) { _result[_resultCtr++] = 'end'; } return (_result, _resultCtr); } /** * @dev Process any operator in DSL * @param _stack Stack that is used to process parenthesis * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @param _ctxAddr Context contract address * @param _chunk The current piece of code that we're processing * @return Modified _result array, mofified _resultCtr, and modified _stack */ function _processOperator( string[] memory _stack, string[] memory _result, uint256 _resultCtr, address _ctxAddr, string memory _chunk ) internal view returns (string[] memory, uint256, string[] memory) { while ( _stack.stackLength() > 0 && IDSLContext(_ctxAddr).opsPriors(_chunk) <= IDSLContext(_ctxAddr).opsPriors(_stack.seeLastInStack()) ) { (_stack, _result[_resultCtr++]) = _stack.popFromStack(); } _stack = _stack.pushToStack(_chunk); return (_result, _resultCtr, _stack); } /************************** * == HELPER FUNCTIONS == * *************************/ /** * @dev Checks if chunk is a currency symbol * @param _chunk is a current chunk from the DSL string code * @return True or false based on whether chunk is a currency symbol or not */ function _isCurrencySymbol(string memory _chunk) internal pure returns (bool) { return _chunk.equal('ETH') || _chunk.equal('GWEI'); } /** * @dev Checks if chunk is an operator * @param _ctxAddr Context contract address * @return True or false based on whether chunk is an operator or not */ function _isOperator(string memory _chunk, address _ctxAddr) internal view returns (bool) { for (uint256 i = 0; i < IDSLContext(_ctxAddr).operatorsLen(); i++) { if (_chunk.equal(IDSLContext(_ctxAddr).operators(i))) return true; } return false; } /** * @dev Checks if a string is an alias to a command from DSL * @param _ctxAddr Context contract address * @return True or false based on whether chunk is an alias or not */ function _isAlias(string memory _chunk, address _ctxAddr) internal view returns (bool) { return !IDSLContext(_ctxAddr).aliases(_chunk).equal(''); } /** * @dev Checks if chunk is a parenthesis * @param _chunk Current piece of code that we're processing * @return True or false based on whether chunk is a parenthesis or not */ function _isParenthesis(string memory _chunk) internal pure returns (bool) { return _chunk.equal('(') || _chunk.equal(')'); } /** * @dev Checks if chunk is a curly bracket * @param _chunk Current piece of code that we're processing * @return True or false based on whether chunk is a curly bracket or not */ function _isCurlyBracket(string memory _chunk) internal pure returns (bool) { return _chunk.equal('{') || _chunk.equal('}'); } /** * @dev Parses scientific notation in the chunk if there is any * @param _chunk Current piece of code that we're processing * @return Chunk without a scientific notation */ function _checkScientificNotation(string memory _chunk) internal pure returns (string memory) { if (_chunk.mayBeNumber() && !_chunk.mayBeAddress()) { return _parseScientificNotation(_chunk); } return _chunk; } /** * @dev As the string of values can be simple and complex for DSL this function returns a number in * Wei regardless of what type of number parameter was provided by the user. * For example: * `uint256 1000000` - simple * `uint256 1e6 - complex` * @param _chunk provided number * @return updatedChunk amount in Wei of provided _chunk value */ function _parseScientificNotation( string memory _chunk ) internal pure returns (string memory updatedChunk) { try _chunk.toUint256() { updatedChunk = _chunk; } catch { updatedChunk = _chunk.parseScientificNotation(); } } /** * @dev Checks if chunk is a number or address and processes it if so * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @param _chunk Current piece of code that we're processing * @return Modified _result array, mofified _resultCtr */ function _checkIsNumberOrAddress( string[] memory _result, uint256 _resultCtr, string memory _chunk ) internal pure returns (string[] memory, uint256) { if (_chunk.mayBeAddress()) return (_result, _resultCtr); if (_chunk.mayBeNumber()) { (_result, _resultCtr) = _addUint256(_result, _resultCtr); } return (_result, _resultCtr); } /** * @dev Adds `uint256` to a number * @param _result Output array that the function is modifying * @param _resultCtr Current pointer to the empty element in the _result param * @return Modified _result array, mofified _resultCtr */ function _addUint256( string[] memory _result, uint256 _resultCtr ) internal pure returns (string[] memory, uint256) { if (_resultCtr == 0 || (!(_result[_resultCtr - 1].equal('uint256')))) { _result[_resultCtr++] = 'uint256'; } return (_result, _resultCtr); } /** * @dev checks the value, and returns the corresponding multiplier. * If it is Ether, then it returns 1000000000000000000, * If it is GWEI, then it returns 1000000000 * @param _chunk is a command from DSL command list * @return returns the corresponding multiplier. */ function _getCurrencyMultiplier(string memory _chunk) internal pure returns (uint256) { if (_chunk.equal('ETH')) { return 1000000000000000000; } else if (_chunk.equal('GWEI')) { return 1000000000; } else return 0; } /** * @dev Checks if a symbol is a comment, then increases `i` to the next * no-comment symbol avoiding an additional iteration * @param i is a current index of a char that might be changed * @param _program is a current program string * @param _char Current character * @return Searched symbol length * @return New index * @return Is code commented or not */ function _getCommentSymbol( uint256 i, string memory _program, string memory _char ) internal pure returns (uint256, uint256, bool) { if (_canGetSymbol(i + 1, _program)) { string memory nextChar = _program.char(i + 1); if (_char.equal('/') && nextChar.equal('/')) { return (1, i + 2, true); } else if (_char.equal('/') && nextChar.equal('*')) { return (2, i + 2, true); } } return (0, i, false); } /** * @dev Checks if a symbol is an end symbol of a comment, then increases _index to the next * no-comment symbol avoiding an additional iteration * @param _ssl is a searched symbol len that might be 0, 1, 2 * @param i is a current index of a char that might be changed * @param _p is a current program string * @param _char Current character * @return A new index of a char * @return Is code commented or not */ function _getEndCommentSymbol( uint256 _ssl, uint256 i, string memory _p, string memory _char ) internal pure returns (uint256, bool) { if (_ssl == 1 && _char.equal('\n')) { return (i + 1, false); } else if (_ssl == 2 && _char.equal('*') && _canGetSymbol(i + 1, _p)) { string memory nextChar = _p.char(i + 1); if (nextChar.equal('/')) { return (i + 2, false); } } return (i, true); } /** * @dev Checks if it is possible to get next char from a _program * @param _index is a current index of a char * @param _program is a current program string * @return True if program has the next symbol, otherwise is false */ function _canGetSymbol(uint256 _index, string memory _program) internal pure returns (bool) { try _program.char(_index) { return true; } catch Error(string memory) { return false; } } /** * @dev Returns the length of a string array excluding empty elements * Ex. nonEmptyArrLen['h', 'e', 'l', 'l', 'o', '', '', '']) == 5 (not 8) * @param _arr Input string array * @return i The legth of the array excluding empty elements */ function _nonEmptyArrLen(string[] memory _arr) internal pure returns (uint256 i) { while (i < _arr.length && !_arr[i].equal('')) { i++; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import '../helpers/Stack.sol'; interface IProgramContext { // Variables function ANYONE() external view returns (address); function stack() external view returns (Stack); function program() external view returns (bytes memory); function currentProgram() external view returns (bytes memory); function programAt(uint256 _start, uint256 _size) external view returns (bytes memory); function pc() external view returns (uint256); function nextpc() external view returns (uint256); function appAddr() external view returns (address); function msgSender() external view returns (address); function msgValue() external view returns (uint256); function isStructVar(string memory _varName) external view returns (bool); function labelPos(string memory _name) external view returns (uint256); function setLabelPos(string memory _name, uint256 _value) external; function forLoopIterationsRemaining() external view returns (uint256); function setProgram(bytes memory _data) external; function setPc(uint256 _pc) external; function setNextPc(uint256 _nextpc) external; function incPc(uint256 _val) external; function setMsgSender(address _msgSender) external; function setMsgValue(uint256 _msgValue) external; function setStructVars( string memory _structName, string memory _varName, string memory _fullName ) external; function structParams( bytes4 _structName, bytes4 _varName ) external view returns (bytes4 _fullName); function setForLoopIterationsRemaining(uint256 _forLoopIterationsRemaining) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import { ErrorsStringUtils } from './Errors.sol'; import { ByteUtils } from './ByteUtils.sol'; /** * @dev Library that simplifies working with strings in Solidity */ library StringUtils { /** * @dev Get character in string by index * @param _s Input string * @param _index Target index in the string * @return Character by index */ function char(string memory _s, uint256 _index) public pure returns (string memory) { require(_index < length(_s), ErrorsStringUtils.SUT1); bytes memory _sBytes = new bytes(1); _sBytes[0] = bytes(_s)[_index]; return string(_sBytes); } /** * @dev Compares two strings * @param _s1 One string * @param _s2 Another string * @return Are string equal */ function equal(string memory _s1, string memory _s2) internal pure returns (bool) { return keccak256(abi.encodePacked(_s1)) == keccak256(abi.encodePacked(_s2)); } /** * @dev Gets length of the string * @param _s Input string * @return The lenght of the string */ function length(string memory _s) internal pure returns (uint256) { return bytes(_s).length; } /** * @dev Concats two strings * @param _s1 One string * @param _s2 Another string * @return The concatenation of the strings */ function concat(string memory _s1, string memory _s2) internal pure returns (string memory) { return string(abi.encodePacked(_s1, _s2)); } /** * @dev Creates a substring from a string * Ex. substr('0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE', 2, 42) => '9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE' * @param _str Input string * @param _start Start index (inclusive) * @param _end End index (not inclusive) * @return Substring */ function substr( string memory _str, uint256 _start, uint256 _end ) public pure returns (string memory) { bytes memory strBytes = bytes(_str); bytes memory result = new bytes(_end - _start); for (uint256 i = _start; i < _end; i++) { result[i - _start] = strBytes[i]; } return string(result); } /** * @dev Checks is _char is present in the _string * Ex. `_`.in('123_456') => true * Ex. `8`.in('123456') => false * @param _char Searched character * @param _string String to search in * @return Is the character presented in the string */ function isIn(string memory _char, string memory _string) public pure returns (bool) { for (uint256 i = 0; i < length(_string); i++) { if (equal(char(_string, i), _char)) return true; } return false; } // Convert an hexadecimal string (without "0x" prefix) to raw bytes function fromHex(string memory s) public pure returns (bytes memory) { return ByteUtils.fromHexBytes(bytes(s)); } /** * @dev Converts a `uint256` to its ASCII `string` decimal representation * @notice Inspired by OraclizeAPI's implementation - MIT licence * https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol * @param _num Input number * @return Number represented as a string */ function toString(uint256 _num) internal pure returns (string memory) { if (_num == 0) { return '0'; } uint256 _temp = _num; uint256 _digits; while (_temp != 0) { _digits++; _temp /= 10; } bytes memory _buffer = new bytes(_digits); while (_num != 0) { _digits -= 1; _buffer[_digits] = bytes1(uint8(48 + uint256(_num % 10))); _num /= 10; } return string(_buffer); } /** * @dev Converts a decimal number (provided as a string) to uint256 * @param _s Input decimal number (provided as a string) * @return value Unsigned integer from input string */ function toUint256(string memory _s) public pure returns (uint256 value) { bytes memory b = bytes(_s); uint256 tmp; for (uint256 i = 0; i < b.length; i++) { tmp = uint8(b[i]); require(tmp >= 0x30 && tmp <= 0x39, ErrorsStringUtils.SUT3); value = value * 10 + (tmp - 0x30); // 0x30 ascii is '0' } } /** * @dev Converts a decimal number (provided as a string) with e symbol (1e18) to number (returned as a string) * @param _s Input decimal number (provided as a string) * @return result Unsigned integer in a string format */ function parseScientificNotation(string memory _s) public pure returns (string memory result) { bool isFound; // was `e` symbol found uint256 tmp; bytes memory b = bytes(_s); string memory base; string memory decimals; for (uint256 i = 0; i < b.length; i++) { tmp = uint8(b[i]); if (tmp >= 0x30 && tmp <= 0x39) { if (!isFound) { base = concat(base, string(abi.encodePacked(b[i]))); } else { decimals = concat(decimals, string(abi.encodePacked(b[i]))); } } else if (tmp == 0x65 && !isFound) { isFound = true; } else { // use only one `e` sympol between values without spaces; example: 1e18 or 456e10 revert(ErrorsStringUtils.SUT5); } } require(!equal(base, ''), ErrorsStringUtils.SUT9); require(!equal(decimals, ''), ErrorsStringUtils.SUT6); result = toString(toUint256(base) * (10 ** toUint256(decimals))); } /** * @dev If the string starts with a number, so we assume that it's a number. * @param _string is a current string for checking * @return isNumber that is true if the string starts with a number, otherwise is false */ function mayBeNumber(string memory _string) public pure returns (bool) { require(!equal(_string, ''), ErrorsStringUtils.SUT7); bytes1 _byte = bytes(_string)[0]; return uint8(_byte) >= 48 && uint8(_byte) <= 57; } /** * @dev If the string starts with `0x` symbols, so we assume that it's an address. * @param _string is a current string for checking * @return isAddress that is true if the string starts with `0x` symbols, otherwise is false */ function mayBeAddress(string memory _string) public pure returns (bool) { require(!equal(_string, ''), ErrorsStringUtils.SUT7); if (bytes(_string).length != 42) return false; bytes1 _byte = bytes(_string)[0]; bytes1 _byte2 = bytes(_string)[1]; return uint8(_byte) == 48 && uint8(_byte2) == 120; } /** * @dev Checks is string is a valid DSL variable name (matches regexp /^([A-Z_$][A-Z\d_$]*)$/g) * @param _s is a current string to check * @return isCapital whether the string is a valid DSL variable name or not */ function isValidVarName(string memory _s) public pure returns (bool) { require(!equal(_s, ''), ErrorsStringUtils.SUT7); uint8 A = 0x41; uint8 Z = 0x5a; uint8 underscore = 0x5f; uint8 dollar = 0x24; uint8 zero = 0x30; uint8 nine = 0x39; uint8 symbol; // This is the same as applying regexp /^([A-Z_$][A-Z\d_$]*)$/g for (uint256 i = 0; i < length(_s); i++) { symbol = uint8(bytes(_s)[i]); if ( (i == 0 && !((symbol >= A && symbol <= Z) || symbol == underscore || symbol == dollar)) || (i > 0 && !((symbol >= A && symbol <= Z) || (symbol >= zero && symbol <= nine) || symbol == underscore || symbol == dollar)) ) { return false; } } return true; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import { ErrorsByteUtils } from './Errors.sol'; // import "hardhat/console.sol"; /** * Library to simplify working with bytes */ library ByteUtils { function slice( bytes calldata _data, uint256 _start, uint256 _end ) public pure returns (bytes memory) { require(_start < _end, ErrorsByteUtils.BUT1); require(_end <= _data.length, ErrorsByteUtils.BUT2); return _data[_start:_end]; } /** * Convert an hexadecimal string in bytes (without "0x" prefix) to raw bytes */ function fromHexBytes(bytes memory ss) public pure returns (bytes memory) { require(ss.length % 2 == 0, ErrorsByteUtils.BUT4); // length must be even bytes memory r = new bytes(ss.length / 2); for (uint256 i = 0; i < ss.length / 2; ++i) { r[i] = bytes1(fromHexChar(ss[2 * i]) * 16 + fromHexChar(ss[2 * i + 1])); } return r; } /** * @dev Convert an hexadecimal character to their value */ function fromHexChar(bytes1 c) public pure returns (uint8) { if (c >= bytes1('0') && c <= bytes1('9')) { return uint8(c) - uint8(bytes1('0')); } if (c >= bytes1('a') && c <= bytes1('f')) { return 10 + uint8(c) - uint8(bytes1('a')); } if (c >= bytes1('A') && c <= bytes1('F')) { return 10 + uint8(c) - uint8(bytes1('A')); } revert(ErrorsByteUtils.BUT3); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; interface IPreprocessor { function transform( address _ctxAddr, string memory _program ) external view returns (string[] memory); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; // import 'hardhat/console.sol'; /** * @title List of Agreement errors */ library ErrorsAgreement { string constant AGR1 = 'AGR1'; // Agreement: bad record signatory string constant AGR2 = 'AGR2'; // Agreement: not all required records are executed string constant AGR3 = 'AGR3'; // Agreement: record fulfilment error string constant AGR4 = 'AGR4'; // Agreement: signatures are invalid string constant AGR5 = 'AGR5'; // Agreement: the transaction should have at least one condition string constant AGR6 = 'AGR6'; // Agreement: not all record conditions are satisfied string constant AGR7 = 'AGR7'; // Agreement: record already was executed by this signatory string constant AGR8 = 'AGR8'; // Agreement: the variable name is reserved string constant AGR9 = 'AGR9'; // Agreement: this record does not exist string constant AGR10 = 'AGR10'; // Agreement: this record has not yet been archived string constant AGR11 = 'AGR11'; // Agreement: not an owner string constant AGR12 = 'AGR12'; // Agreement: zero address string constant AGR13 = 'AGR13'; // Agreement: the record is not activated string constant AGR14 = 'AGR14'; // Agreement: the record is pre-define. can not be changed string constant AGR15 = 'AGR15'; // Agreement: time can not be in the past string constant AGR16 = 'AGR16'; // Agreement: out of range } library ErrorsGovernance { string constant GOV1 = 'GOV1'; // Governance: You can not vote YES anymore string constant GOV2 = 'GOV2'; // Governance: You can not vote NO anymore } /** * @title List of Context errors */ library ErrorsContext { string constant CTX1 = 'CTX1'; // Context: address is zero string constant CTX2 = 'CTX2'; // Context: empty opcode selector string constant CTX3 = 'CTX3'; // Context: duplicate opcode name or code string constant CTX4 = 'CTX4'; // Context: slicing out of range string constant CTX5 = 'CTX5'; // Context: duplicate opcode branch string constant CTX6 = 'CTX6'; // Context: wrong application address string constant CTX7 = 'CTX7'; // Context: the application address has already set } /** * @title List of Stack errors */ library ErrorsStack { string constant STK1 = 'STK1'; // Stack: uint256 type mismatch string constant STK2 = 'STK2'; // Stack: string type mismatch string constant STK3 = 'STK3'; // Stack: address type mismatch string constant STK4 = 'STK4'; // Stack: stack is empty } /** * @title List of OtherOpcodes errors */ library ErrorsGeneralOpcodes { string constant OP1 = 'OP1'; // Opcodes: opSetLocal call not success string constant OP2 = 'OP2'; // Opcodes: tries to get an item from non-existing array string constant OP3 = 'OP3'; // Opcodes: opLoadRemote call not success string constant OP4 = 'OP4'; // Opcodes: tries to put an item to non-existing array string constant OP5 = 'OP5'; // Opcodes: opLoadLocal call not success string constant OP6 = 'OP6'; // Opcodes: array is empty string constant OP8 = 'OP8'; // Opcodes: wrong type of array } /** * @title List of BranchingOpcodes errors */ library ErrorsBranchingOpcodes { string constant BR1 = 'BR1'; // BranchingOpcodes: LinkedList.getType() delegate call error string constant BR2 = 'BR2'; // BranchingOpcodes: array doesn't exist string constant BR3 = 'BR3'; // BranchingOpcodes: LinkedList.get() delegate call error } /** * @title List of Parser errors */ library ErrorsParser { string constant PRS1 = 'PRS1'; // Parser: delegatecall to asmSelector failure string constant PRS2 = 'PRS2'; // Parser: the name of variable can not be empty } /** * @title List of Preprocessor errors */ library ErrorsPreprocessor { string constant PRP1 = 'PRP1'; // Preprocessor: amount of parameters can not be 0 string constant PRP2 = 'PRP2'; // Preprocessor: invalid parameters for the function } /** * @title List of OpcodesHelpers errors */ library ErrorsOpcodeHelpers { string constant OPH1 = 'OPH1'; // Opcodes: mustCall call not success string constant OPH2 = 'OPH2'; // Opcodes: mustDelegateCall call not success } /** * @title List of ByteUtils errors */ library ErrorsByteUtils { string constant BUT1 = 'BUT1'; // ByteUtils: 'end' index must be greater than 'start' string constant BUT2 = 'BUT2'; // ByteUtils: 'end' is greater than the length of the array string constant BUT3 = 'BUT3'; // ByteUtils: a hex value not from the range 0-9, a-f, A-F string constant BUT4 = 'BUT4'; // ByteUtils: hex lenght not even } /** * @title List of Executor errors */ library ErrorsExecutor { string constant EXC1 = 'EXC1'; // Executor: empty program string constant EXC2 = 'EXC2'; // Executor: did not find selector for opcode string constant EXC3 = 'EXC3'; // Executor: call not success string constant EXC4 = 'EXC4'; // Executor: call to program context not success } /** * @title List of StringUtils errors */ library ErrorsStringUtils { string constant SUT1 = 'SUT1'; // StringUtils: index out of range string constant SUT3 = 'SUT3'; // StringUtils: non-decimal character string constant SUT4 = 'SUT4'; // StringUtils: base was not provided string constant SUT5 = 'SUT5'; // StringUtils: invalid format string constant SUT6 = 'SUT6'; // StringUtils: decimals were not provided string constant SUT7 = 'SUT7'; // StringUtils: a string was not provided string constant SUT9 = 'SUT9'; // StringUtils: base was not provided }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import { ErrorsStack } from '../libs/Errors.sol'; contract Stack { uint256[] public stack; function length() external view returns (uint256) { return _length(); } function seeLast() external view returns (uint256) { return _seeLast(); } function push(uint256 data) external { stack.push(data); } function pop() external returns (uint256) { uint256 data = _seeLast(); stack.pop(); return data; } function clear() external { delete stack; } function _length() internal view returns (uint256) { return stack.length; } function _seeLast() internal view returns (uint256) { require(_length() > 0, ErrorsStack.STK4); return stack[_length() - 1]; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import { ErrorsStack } from '../libs/Errors.sol'; import { StringUtils } from './StringUtils.sol'; // TODO: add tests for this file /** * @dev This library has all the functions to use solidity string array as a struct */ library StringStack { using StringUtils for string; /** * @dev Push element to array in the first position * As the array has fixed size, we drop the last element * when addind a new one to the beginning of the array * @param _stack String stack * @param _element String to be added to the stack * @return Modified stack */ function pushToStack( string[] memory _stack, string memory _element ) external pure returns (string[] memory) { _stack[stackLength(_stack)] = _element; return _stack; } function popFromStack( string[] memory _stack ) external pure returns (string[] memory, string memory) { string memory _topElement = seeLastInStack(_stack); _stack[stackLength(_stack) - 1] = ''; return (_stack, _topElement); } function stackLength(string[] memory _stack) public pure returns (uint256) { uint256 i; while (!_stack[i].equal('')) { i++; } return i; } function seeLastInStack(string[] memory _stack) public pure returns (string memory) { uint256 _len = stackLength(_stack); require(_len > 0, ErrorsStack.STK4); return _stack[_len - 1]; } }
{ "optimizer": { "enabled": false, "runs": 100 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": { "contracts/dsl/libs/ByteUtils.sol": { "ByteUtils": "0x1c407cdd4975532bb5f3f614fb3b48478f597f49" }, "contracts/dsl/libs/StringUtils.sol": { "StringUtils": "0xd816c20e28cc704028c475108f4dc535e237ebd9" } } }
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"result","type":"bool"}],"name":"ExecRes","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"txObj","type":"address"}],"name":"NewConditionalTx","type":"event"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmAllowanceMintBurn","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmBalanceOf","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmBool","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"_ctxDSLAddr","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmCompound","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"_ctxDSLAddr","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmDeclare","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmEnableRecord","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmForLoop","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"_programCtxAddr","type":"address"}],"name":"asmFunc","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmGet","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"_programCtxAddr","type":"address"}],"name":"asmIf","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"_programCtxAddr","type":"address"}],"name":"asmIfelse","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmLengthOf","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"_ctxDSLAddr","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmLoadRemote","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmPush","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmSend","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmSetLocalBool","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmSetUint256","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"_programCtxAddr","type":"address"}],"name":"asmStruct","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmSumOf","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmSumThroughStructs","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmTransfer","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmTransferFrom","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmTransferFromVar","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmTransferVar","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmUint256","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_program","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"asmVar","outputs":[{"internalType":"bytes","name":"newProgram","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_preprAddr","type":"address"},{"internalType":"address","name":"_dslCtxAddr","type":"address"},{"internalType":"address","name":"_programCtxAddr","type":"address"},{"internalType":"string","name":"_codeRaw","type":"string"}],"name":"parse","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dslCtxAddr","type":"address"},{"internalType":"address","name":"_programCtxAddr","type":"address"},{"internalType":"string[]","name":"_code","type":"string[]"}],"name":"parseCode","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50614523806100206000396000f3fe608060405234801561001057600080fd5b50600436106101845760003560e01c806390d95d80116100d9578063c45e3e5011610087578063c45e3e5014610551578063c92b45e114610581578063cbfc5ad4146105b1578063cedba5f1146105e1578063dc19dabd14610611578063f5a4363e14610641578063f7edbb701461067157610184565b806390d95d80146104155780639609ebb3146104455780639714a18214610461578063997f430614610491578063b9c34291146104c1578063b9dd4c83146104f1578063bfd5b4451461052157610184565b80635887e21b116101365780635887e21b146102d957806368bf5659146103095780636960e80b14610339578063861826411461036957806386b8d4e81461039957806389995a9e146103c95780638bc0a7a7146103e557610184565b8063021d30be1461018957806303dc1cee146101b957806305feb51f146101e95780630f47ec74146102195780632909fb3e1461024957806353edd023146102795780635694922f146102a9575b600080fd5b6101a3600480360381019061019e91906130d0565b6106a1565b6040516101b091906131c7565b60405180910390f35b6101d360048036038101906101ce91906130d0565b6106b5565b6040516101e091906131c7565b60405180910390f35b61020360048036038101906101fe91906130d0565b6106dd565b60405161021091906131c7565b60405180910390f35b610233600480360381019061022e91906130d0565b610851565b60405161024091906131c7565b60405180910390f35b610263600480360381019061025e91906130d0565b610865565b60405161027091906131c7565b60405180910390f35b610293600480360381019061028e91906130d0565b6109a4565b6040516102a091906131c7565b60405180910390f35b6102c360048036038101906102be91906130d0565b6109b8565b6040516102d091906131c7565b60405180910390f35b6102f360048036038101906102ee91906130d0565b6109e5565b60405161030091906131c7565b60405180910390f35b610323600480360381019061031e91906130d0565b610a44565b60405161033091906131c7565b60405180910390f35b610353600480360381019061034e91906130d0565b610a66565b60405161036091906131c7565b60405180910390f35b610383600480360381019061037e91906130d0565b610abc565b60405161039091906131c7565b60405180910390f35b6103b360048036038101906103ae91906130d0565b610b1d565b6040516103c091906131c7565b60405180910390f35b6103e360048036038101906103de9190613370565b610b3c565b005b6103ff60048036038101906103fa91906130d0565b610d89565b60405161040c91906131c7565b60405180910390f35b61042f600480360381019061042a91906130d0565b610ea4565b60405161043c91906131c7565b60405180910390f35b61045f600480360381019061045a91906133df565b610eb8565b005b61047b600480360381019061047691906130d0565b610f4f565b60405161048891906131c7565b60405180910390f35b6104ab60048036038101906104a691906130d0565b6117a5565b6040516104b891906131c7565b60405180910390f35b6104db60048036038101906104d691906130d0565b6117dd565b6040516104e891906131c7565b60405180910390f35b61050b600480360381019061050691906130d0565b6118aa565b60405161051891906131c7565b60405180910390f35b61053b600480360381019061053691906130d0565b611ce8565b60405161054891906131c7565b60405180910390f35b61056b600480360381019061056691906130d0565b611d10565b60405161057891906131c7565b60405180910390f35b61059b600480360381019061059691906130d0565b611d3a565b6040516105a891906131c7565b60405180910390f35b6105cb60048036038101906105c691906130d0565b611d5c565b6040516105d891906131c7565b60405180910390f35b6105fb60048036038101906105f691906130d0565b611ef9565b60405161060891906131c7565b60405180910390f35b61062b600480360381019061062691906130d0565b611fc6565b60405161063891906131c7565b60405180910390f35b61065b600480360381019061065691906130d0565b611ff0565b60405161066891906131c7565b60405180910390f35b61068b600480360381019061068691906130d0565b61200f565b60405161069891906131c7565b60405180910390f35b60606106ac84612044565b90509392505050565b60606106c084612044565b90506106ca6120a2565b506106d481612044565b90509392505050565b606060006106e96120a2565b80546106f490613491565b80601f016020809104026020016040519081016040528092919081815260200182805461072090613491565b801561076d5780601f106107425761010080835404028352916020019161076d565b820191906000526020600020905b81548152906001019060200180831161075057829003601f168201915b50505050509050600061077e6120a2565b60405160200161078e9190613562565b604051602081830303815290604052805190602001209050858273d816c20e28cc704028c475108f4dc535e237ebd96370121b7190916040518263ffffffff1660e01b81526004016107e091906135ce565b602060405180830381865af41580156107fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108219190613626565b60001b8260405160200161083793929190613707565b604051602081830303815290604052925050509392505050565b606061085c84612044565b90509392505050565b606060006108716120a2565b805461087c90613491565b80601f01602080910402602001604051908101604052809291908181526020018280546108a890613491565b80156108f55780601f106108ca576101008083540402835291602001916108f5565b820191906000526020600020905b8154815290600101906020018083116108d857829003601f168201915b505050505073d816c20e28cc704028c475108f4dc535e237ebd96370121b7190916040518263ffffffff1660e01b815260040161093291906135ce565b602060405180830381865af415801561094f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109739190613626565b9050848160001b60405160200161098b929190613740565b6040516020818303038152906040529150509392505050565b60606109af84612044565b90509392505050565b60606109c384612044565b90506109ce81612044565b90506109dc81600080610865565b90509392505050565b6060610a2784846040518060400160405280600881526020017f636f6d706f756e640000000000000000000000000000000000000000000000008152506120dc565b9050610a316120a2565b50610a3b81612044565b90509392505050565b6060610a4f84612044565b9050610a5d81600080610d89565b90509392505050565b6060610aa884846040518060400160405280600a81526020017f6465636c617265417272000000000000000000000000000000000000000000008152506120dc565b9050610ab381612044565b90509392505050565b6060610afe84846040518060400160405280600a81526020017f6c6f616452656d6f7465000000000000000000000000000000000000000000008152506120dc565b9050610b0981612044565b9050610b148161218b565b90509392505050565b6060610b2884612044565b9050610b3381612044565b90509392505050565b60006001819055506060808373ffffffffffffffffffffffffffffffffffffffff1663bcf80c9d836040518263ffffffff1660e01b8152600401610b8091906131c7565b600060405180830381600087803b158015610b9a57600080fd5b505af1158015610bae573d6000803e3d6000fd5b50505050610bbb83612358565b8373ffffffffffffffffffffffffffffffffffffffff1663f26c917860006040518263ffffffff1660e01b8152600401610bf591906137ad565b600060405180830381600087803b158015610c0f57600080fd5b505af1158015610c23573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff1663138ef1516040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c969190613806565b73ffffffffffffffffffffffffffffffffffffffff166352efea6e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610cdd57600080fd5b505af1158015610cf1573d6000803e3d6000fd5b505050505b6000805490506001541015610d1757610d10858583612421565b9050610cf6565b8373ffffffffffffffffffffffffffffffffffffffff1663bcf80c9d826040518263ffffffff1660e01b8152600401610d5091906131c7565b600060405180830381600087803b158015610d6a57600080fd5b505af1158015610d7e573d6000803e3d6000fd5b505050505050505050565b60606000610e656040518060400160405280600481526020017f7472756500000000000000000000000000000000000000000000000000000000815250610dce6120a2565b8054610dd990613491565b80601f0160208091040260200160405190810160405280929190818152602001828054610e0590613491565b8015610e525780601f10610e2757610100808354040283529160200191610e52565b820191906000526020600020905b815481529060010190602001808311610e3557829003601f168201915b5050505050612c5490919063ffffffff16565b610e70576000610e73565b60015b60f81b90508481604051602001610e8b929190613880565b6040516020818303038152906040529150509392505050565b6060610eaf84612044565b90509392505050565b60008473ffffffffffffffffffffffffffffffffffffffff16630411de8885846040518363ffffffff1660e01b8152600401610ef5929190613901565b600060405180830381865afa158015610f12573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610f3b9190613a56565b9050610f48848483610b3c565b5050505050565b60606000610f5b6120a2565b8054610f6690613491565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9290613491565b8015610fdf5780601f10610fb457610100808354040283529160200191610fdf565b820191906000526020600020905b815481529060010190602001808311610fc257829003601f168201915b505050505090508491505b6000610ff46120a2565b8054610fff90613491565b80601f016020809104026020016040519081016040528092919081815260200182805461102b90613491565b80156110785780601f1061104d57610100808354040283529160200191611078565b820191906000526020600020905b81548152906001019060200180831161105b57829003601f168201915b5050505050905060006110db826110cd6040518060400160405280600181526020017f2e0000000000000000000000000000000000000000000000000000000000000081525086612cad90919063ffffffff16565b612cad90919063ffffffff16565b90508473ffffffffffffffffffffffffffffffffffffffff1663d598989e8484846040518463ffffffff1660e01b815260040161111a93929190613a9f565b600060405180830381600087803b15801561113457600080fd5b505af1158015611148573d6000803e3d6000fd5b50505050838160405160200161115e9190613b1c565b60405160208183030381529060405280519060200120604051602001611185929190613b33565b604051602081830303815290604052935060006111a06120a2565b80546111ab90613491565b80601f01602080910402602001604051908101604052809291908181526020018280546111d790613491565b80156112245780601f106111f957610100808354040283529160200191611224565b820191906000526020600020905b81548152906001019060200180831161120757829003601f168201915b505050505090508073d816c20e28cc704028c475108f4dc535e237ebd9634863d3e190916040518263ffffffff1660e01b815260040161126491906135ce565b602060405180830381865af4158015611281573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a59190613b93565b156113e457600081731c407cdd4975532bb5f3f614fb3b48478f597f4963e004139690916002602a6040518463ffffffff1660e01b81526004016112eb93929190613c80565b600060405180830381865af4158015611308573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906113319190613d2e565b90508581731c407cdd4975532bb5f3f614fb3b48478f597f49632c16769b90916040518263ffffffff1660e01b815260040161136d9190613d77565b600060405180830381865af415801561138a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906113b39190613d2e565b6113bc90613dcb565b6040516020016113cd929190613740565b60405160208183030381529060405295505061169a565b8073d816c20e28cc704028c475108f4dc535e237ebd963dba27b1c90916040518263ffffffff1660e01b815260040161141d91906135ce565b602060405180830381865af415801561143a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145e9190613b93565b1561150857848173d816c20e28cc704028c475108f4dc535e237ebd96370121b7190916040518263ffffffff1660e01b815260040161149d91906135ce565b602060405180830381865af41580156114ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114de9190613626565b60001b6040516020016114f2929190613740565b6040516020818303038152906040529450611699565b6115506040518060400160405280600481526020017f766f74650000000000000000000000000000000000000000000000000000000081525084612c5490919063ffffffff16565b80156115a0575061159f6040518060400160405280600381526020017f594553000000000000000000000000000000000000000000000000000000000081525082612c5490919063ffffffff16565b5b156115d25784600160001b6040516020016115bc929190613740565b6040516020818303038152906040529450611698565b61161a6040518060400160405280600481526020017f766f74650000000000000000000000000000000000000000000000000000000081525084612c5490919063ffffffff16565b801561166a57506116696040518060400160405280600281526020017f4e4f00000000000000000000000000000000000000000000000000000000000081525082612c5490919063ffffffff16565b5b1561169757846000801b604051602001611685929190613740565b60405160208183030381529060405294505b5b5b5b50505061178d6040518060400160405280600981526020017f656e6453747275637400000000000000000000000000000000000000000000008152506000600154815481106116ec576116eb613e32565b5b90600052602060002001805461170190613491565b80601f016020809104026020016040519081016040528092919081815260200182805461172d90613491565b801561177a5780601f1061174f5761010080835404028352916020019161177a565b820191906000526020600020905b81548152906001019060200180831161175d57829003601f168201915b5050505050612c5490919063ffffffff16565b15610fea5761179b82612044565b9150509392505050565b60606117b084612044565b90506117bb81612044565b90506117c681612044565b90506117d481600080610865565b90509392505050565b606061187b826117eb6120a2565b80546117f690613491565b80601f016020809104026020016040519081016040528092919081815260200182805461182290613491565b801561186f5780601f106118445761010080835404028352916020019161186f565b820191906000526020600020905b81548152906001019060200180831161185257829003601f168201915b50505050508651612cd9565b83600060f01b604051602001611892929190613eae565b60405160208183030381529060405290509392505050565b606060006118b66120a2565b80546118c190613491565b80601f01602080910402602001604051908101604052809291908181526020018280546118ed90613491565b801561193a5780601f1061190f5761010080835404028352916020019161193a565b820191906000526020600020905b81548152906001019060200180831161191d57829003601f168201915b50505050509050600061194b6120a2565b60405160200161195b9190613562565b6040516020818303038152906040528051906020012090508173d816c20e28cc704028c475108f4dc535e237ebd9634863d3e190916040518263ffffffff1660e01b81526004016119ac91906135ce565b602060405180830381865af41580156119c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ed9190613b93565b15611b2c57600082731c407cdd4975532bb5f3f614fb3b48478f597f4963e004139690916002602a6040518463ffffffff1660e01b8152600401611a3393929190613c80565b600060405180830381865af4158015611a50573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611a799190613d2e565b90508681731c407cdd4975532bb5f3f614fb3b48478f597f49632c16769b90916040518263ffffffff1660e01b8152600401611ab59190613d77565b600060405180830381865af4158015611ad2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611afb9190613d2e565b611b0490613dcb565b604051602001611b15929190613740565b604051602081830303815290604052935050611cbb565b8173d816c20e28cc704028c475108f4dc535e237ebd963dba27b1c90916040518263ffffffff1660e01b8152600401611b6591906135ce565b602060405180830381865af4158015611b82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba69190613b93565b15611c5057858273d816c20e28cc704028c475108f4dc535e237ebd96370121b7190916040518263ffffffff1660e01b8152600401611be591906135ce565b602060405180830381865af4158015611c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c269190613626565b60001b604051602001611c3a929190613740565b6040516020818303038152906040529250611cba565b8582604051602001611c629190613b1c565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916604051602001611ca8929190613740565b60405160208183030381529060405292505b5b8281604051602001611cce929190613b33565b604051602081830303815290604052925050509392505050565b6060611cf384612044565b9050611cfd6120a2565b50611d0781612044565b90509392505050565b6060611d1b84612044565b9050611d2681612044565b9050611d3181612044565b90509392505050565b6060611d4584612044565b9050611d5381600080610865565b90509392505050565b60606000611d686120a2565b8054611d7390613491565b80601f0160208091040260200160405190810160405280929190818152602001828054611d9f90613491565b8015611dec5780601f10611dc157610100808354040283529160200191611dec565b820191906000526020600020905b815481529060010190602001808311611dcf57829003601f168201915b505050505090506000611dfd6120a2565b8054611e0890613491565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3490613491565b8015611e815780601f10611e5657610100808354040283529160200191611e81565b820191906000526020600020905b815481529060010190602001808311611e6457829003601f168201915b50505050509050611e9484838851612cd9565b85600060f01b604051602001611eab929190613eae565b6040516020818303038152906040529250611ec884828551612cd9565b82600060f01b604051602001611edf929190613eae565b604051602081830303815290604052925050509392505050565b6060611f9782611f076120a2565b8054611f1290613491565b80601f0160208091040260200160405190810160405280929190818152602001828054611f3e90613491565b8015611f8b5780601f10611f6057610100808354040283529160200191611f8b565b820191906000526020600020905b815481529060010190602001808311611f6e57829003601f168201915b50505050508651612cd9565b83600060f01b604051602001611fae929190613eae565b60405160208183030381529060405290509392505050565b6060611fd184612044565b9050611fdc81612044565b9050611fe781612044565b90509392505050565b6060611ffb84612044565b905061200681612044565b90509392505050565b606061201a84612044565b905061202581612044565b905061203081612044565b905061203b81612044565b90509392505050565b606060006120506120a2565b6040516020016120609190613562565b604051602081830303815290604052805190602001209050828160405160200161208b929190613b33565b604051602081830303815290604052915050919050565b600080600160008154809291906120b890613f05565b91905055815481106120cd576120cc613e32565b5b90600052602060002001905090565b6060838373ffffffffffffffffffffffffffffffffffffffff16635bf3e5d7846121046120a2565b6040518363ffffffff1660e01b8152600401612121929190613fce565b602060405180830381865afa15801561213e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121629190614031565b604051602001612173929190613880565b60405160208183030381529060405290509392505050565b606060006121976120a2565b80546121a290613491565b80601f01602080910402602001604051908101604052809291908181526020018280546121ce90613491565b801561221b5780601f106121f05761010080835404028352916020019161221b565b820191906000526020600020905b8154815290600101906020018083116121fe57829003601f168201915b505050505090508073d816c20e28cc704028c475108f4dc535e237ebd96339c27bd49091600261224a85612d4b565b6040518463ffffffff1660e01b81526004016122689392919061406d565b600060405180830381865af4158015612285573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122ae91906140ab565b9050828173d816c20e28cc704028c475108f4dc535e237ebd9638e7e34d790916040518263ffffffff1660e01b81526004016122ea91906135ce565b600060405180830381865af4158015612307573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906123309190613d2e565b6040516020016123419291906140f4565b604051602081830303815290604052915050919050565b60008060006123679190612df0565b5b8151811080156123b157506123af6040518060200160405280600081525083838151811061239957612398613e32565b5b6020026020010151612c5490919063ffffffff16565b155b1561241d5760008282806123c490613f05565b9350815181106123d7576123d6613e32565b5b6020026020010151908060018154018082558091505060019003906000526020600020016000909190919091509080519060200190612417929190612e11565b50612368565b5050565b6060600061242d6120a2565b905060008573ffffffffffffffffffffffffffffffffffffffff1663f3f8d4e3836040518263ffffffff1660e01b815260040161246a9190614118565b602060405180830381865afa158015612487573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ab9190614031565b90506000826040516020016124c09190613562565b60405160208183030381529060405280519060200120905060008673ffffffffffffffffffffffffffffffffffffffff1663402a652a856040518263ffffffff1660e01b81526004016125139190614118565b602060405180830381865afa158015612530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125549190613b93565b90506125e98785805461256690613491565b80601f016020809104026020016040519081016040528092919081815260200182805461259290613491565b80156125df5780601f106125b4576101008083540402835291602001916125df565b820191906000526020600020905b8154815290600101906020018083116125c257829003601f168201915b5050505050612d56565b156127cd576000865160f01b9050600061268c8987805461260990613491565b80601f016020809104026020016040519081016040528092919081815260200182805461263590613491565b80156126825780601f1061265757610100808354040283529160200191612682565b820191906000526020600020905b81548152906001019060200180831161266557829003601f168201915b5050505050612d6c565b905087731c407cdd4975532bb5f3f614fb3b48478f597f4963e004139690916000846040518463ffffffff1660e01b81526004016126cc93929190614149565b600060405180830381865af41580156126e9573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906127129190613d2e565b8289731c407cdd4975532bb5f3f614fb3b48478f597f4963e0041396909160028661273d9190614187565b8d516040518463ffffffff1660e01b815260040161275d939291906141dd565b600060405180830381865af415801561277a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906127a39190613d2e565b6040516020016127b59392919061421b565b60405160208183030381529060405296505050612c49565b8380546127d990613491565b80601f016020809104026020016040519081016040528092919081815260200182805461280590613491565b80156128525780601f1061282757610100808354040283529160200191612852565b820191906000526020600020905b81548152906001019060200180831161283557829003601f168201915b505050505073d816c20e28cc704028c475108f4dc535e237ebd963fe4f41c890916040518263ffffffff1660e01b815260040161288f91906135ce565b602060405180830381865af41580156128ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128d09190613b93565b806128d85750805b15612982578773ffffffffffffffffffffffffffffffffffffffff1663f3f8d4e36040518163ffffffff1660e01b81526004016129149061429c565b602060405180830381865afa158015612931573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129559190614031565b925085838360405160200161296c939291906142bc565b6040516020818303038152906040529450612c48565b600060f81b837effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415612a0c57836040516020016129c1919061438d565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a0391906143ba565b60405180910390fd5b8583604051602001612a1f929190613880565b60405160208183030381529060405294508773ffffffffffffffffffffffffffffffffffffffff16633cb9ceff856040518263ffffffff1660e01b8152600401612a699190614118565b602060405180830381865afa158015612a86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aaa9190614408565b9150600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612c47576000803073ffffffffffffffffffffffffffffffffffffffff1684888c8c604051602401612b0693929190614435565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051612b709190614473565b600060405180830381855af49150503d8060008114612bab576040519150601f19603f3d011682016040523d82523d6000602084013e612bb0565b606091505b5091509150816040518060400160405280600481526020017f505253310000000000000000000000000000000000000000000000000000000081525090612c2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2491906143ba565b60405180910390fd5b5080806020019051810190612c429190613d2e565b965050505b5b5b505050509392505050565b600081604051602001612c679190613b1c565b6040516020818303038152906040528051906020012083604051602001612c8e9190613b1c565b6040516020818303038152906040528051906020012014905092915050565b60608282604051602001612cc292919061448a565b604051602081830303815290604052905092915050565b8273ffffffffffffffffffffffffffffffffffffffff1663c0a00cda83836040518363ffffffff1660e01b8152600401612d149291906144bd565b600060405180830381600087803b158015612d2e57600080fd5b505af1158015612d42573d6000803e3d6000fd5b50505050505050565b600081519050919050565b600080612d638484612d6c565b11905092915050565b60008273ffffffffffffffffffffffffffffffffffffffff16635981f3db836040518263ffffffff1660e01b8152600401612da791906143ba565b602060405180830381865afa158015612dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612de89190613626565b905092915050565b5080546000825590600052602060002090810190612e0e9190612e97565b50565b828054612e1d90613491565b90600052602060002090601f016020900481019282612e3f5760008555612e86565b82601f10612e5857805160ff1916838001178555612e86565b82800160010185558215612e86579182015b82811115612e85578251825591602001919060010190612e6a565b5b509050612e939190612ebb565b5090565b5b80821115612eb75760008181612eae9190612ed8565b50600101612e98565b5090565b5b80821115612ed4576000816000905550600101612ebc565b5090565b508054612ee490613491565b6000825580601f10612ef65750612f15565b601f016020900490600052602060002090810190612f149190612ebb565b5b50565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612f7f82612f36565b810181811067ffffffffffffffff82111715612f9e57612f9d612f47565b5b80604052505050565b6000612fb1612f18565b9050612fbd8282612f76565b919050565b600067ffffffffffffffff821115612fdd57612fdc612f47565b5b612fe682612f36565b9050602081019050919050565b82818337600083830152505050565b600061301561301084612fc2565b612fa7565b90508281526020810184848401111561303157613030612f31565b5b61303c848285612ff3565b509392505050565b600082601f83011261305957613058612f2c565b5b8135613069848260208601613002565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061309d82613072565b9050919050565b6130ad81613092565b81146130b857600080fd5b50565b6000813590506130ca816130a4565b92915050565b6000806000606084860312156130e9576130e8612f22565b5b600084013567ffffffffffffffff81111561310757613106612f27565b5b61311386828701613044565b9350506020613124868287016130bb565b9250506040613135868287016130bb565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b60005b8381101561317957808201518184015260208101905061315e565b83811115613188576000848401525b50505050565b60006131998261313f565b6131a3818561314a565b93506131b381856020860161315b565b6131bc81612f36565b840191505092915050565b600060208201905081810360008301526131e1818461318e565b905092915050565b600067ffffffffffffffff82111561320457613203612f47565b5b602082029050602081019050919050565b600080fd5b600067ffffffffffffffff82111561323557613234612f47565b5b61323e82612f36565b9050602081019050919050565b600061325e6132598461321a565b612fa7565b90508281526020810184848401111561327a57613279612f31565b5b613285848285612ff3565b509392505050565b600082601f8301126132a2576132a1612f2c565b5b81356132b284826020860161324b565b91505092915050565b60006132ce6132c9846131e9565b612fa7565b905080838252602082019050602084028301858111156132f1576132f0613215565b5b835b8181101561333857803567ffffffffffffffff81111561331657613315612f2c565b5b808601613323898261328d565b855260208501945050506020810190506132f3565b5050509392505050565b600082601f83011261335757613356612f2c565b5b81356133678482602086016132bb565b91505092915050565b60008060006060848603121561338957613388612f22565b5b6000613397868287016130bb565b93505060206133a8868287016130bb565b925050604084013567ffffffffffffffff8111156133c9576133c8612f27565b5b6133d586828701613342565b9150509250925092565b600080600080608085870312156133f9576133f8612f22565b5b6000613407878288016130bb565b9450506020613418878288016130bb565b9350506040613429878288016130bb565b925050606085013567ffffffffffffffff81111561344a57613449612f27565b5b6134568782880161328d565b91505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806134a957607f821691505b602082108114156134bd576134bc613462565b5b50919050565b600081905092915050565b60008190508160005260206000209050919050565b600081546134f081613491565b6134fa81866134c3565b94506001821660008114613515576001811461352657613559565b60ff19831686528186019350613559565b61352f856134ce565b60005b8381101561355157815481890152600182019150602081019050613532565b838801955050505b50505092915050565b600061356e82846134e3565b915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006135a082613579565b6135aa8185613584565b93506135ba81856020860161315b565b6135c381612f36565b840191505092915050565b600060208201905081810360008301526135e88184613595565b905092915050565b6000819050919050565b613603816135f0565b811461360e57600080fd5b50565b600081519050613620816135fa565b92915050565b60006020828403121561363c5761363b612f22565b5b600061364a84828501613611565b91505092915050565b600081905092915050565b60006136698261313f565b6136738185613653565b935061368381856020860161315b565b80840191505092915050565b6000819050919050565b6000819050919050565b6136b46136af8261368f565b613699565b82525050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b6137016136fc826136ba565b6136e6565b82525050565b6000613713828661365e565b915061371f82856136a3565b60208201915061372f82846136f0565b600482019150819050949350505050565b600061374c828561365e565b915061375882846136a3565b6020820191508190509392505050565b6000819050919050565b6000819050919050565b600061379761379261378d84613768565b613772565b6135f0565b9050919050565b6137a78161377c565b82525050565b60006020820190506137c2600083018461379e565b92915050565b60006137d382613092565b9050919050565b6137e3816137c8565b81146137ee57600080fd5b50565b600081519050613800816137da565b92915050565b60006020828403121561381c5761381b612f22565b5b600061382a848285016137f1565b91505092915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b61387a61387582613833565b61385f565b82525050565b600061388c828561365e565b91506138988284613869565b6001820191508190509392505050565b6138b181613092565b82525050565b600082825260208201905092915050565b60006138d382613579565b6138dd81856138b7565b93506138ed81856020860161315b565b6138f681612f36565b840191505092915050565b600060408201905061391660008301856138a8565b818103602083015261392881846138c8565b90509392505050565b600061394461393f8461321a565b612fa7565b9050828152602081018484840111156139605761395f612f31565b5b61396b84828561315b565b509392505050565b600082601f83011261398857613987612f2c565b5b8151613998848260208601613931565b91505092915050565b60006139b46139af846131e9565b612fa7565b905080838252602082019050602084028301858111156139d7576139d6613215565b5b835b81811015613a1e57805167ffffffffffffffff8111156139fc576139fb612f2c565b5b808601613a098982613973565b855260208501945050506020810190506139d9565b5050509392505050565b600082601f830112613a3d57613a3c612f2c565b5b8151613a4d8482602086016139a1565b91505092915050565b600060208284031215613a6c57613a6b612f22565b5b600082015167ffffffffffffffff811115613a8a57613a89612f27565b5b613a9684828501613a28565b91505092915050565b60006060820190508181036000830152613ab981866138c8565b90508181036020830152613acd81856138c8565b90508181036040830152613ae181846138c8565b9050949350505050565b6000613af682613579565b613b0081856134c3565b9350613b1081856020860161315b565b80840191505092915050565b6000613b288284613aeb565b915081905092915050565b6000613b3f828561365e565b9150613b4b82846136f0565b6004820191508190509392505050565b60008115159050919050565b613b7081613b5b565b8114613b7b57600080fd5b50565b600081519050613b8d81613b67565b92915050565b600060208284031215613ba957613ba8612f22565b5b6000613bb784828501613b7e565b91505092915050565b600082825260208201905092915050565b6000613bdc8261313f565b613be68185613bc0565b9350613bf681856020860161315b565b613bff81612f36565b840191505092915050565b6000819050919050565b6000613c2f613c2a613c2584613c0a565b613772565b6135f0565b9050919050565b613c3f81613c14565b82525050565b6000819050919050565b6000613c6a613c65613c6084613c45565b613772565b6135f0565b9050919050565b613c7a81613c4f565b82525050565b60006060820190508181036000830152613c9a8186613bd1565b9050613ca96020830185613c36565b613cb66040830184613c71565b949350505050565b6000613cd1613ccc84612fc2565b612fa7565b905082815260208101848484011115613ced57613cec612f31565b5b613cf884828561315b565b509392505050565b600082601f830112613d1557613d14612f2c565b5b8151613d25848260208601613cbe565b91505092915050565b600060208284031215613d4457613d43612f22565b5b600082015167ffffffffffffffff811115613d6257613d61612f27565b5b613d6e84828501613d00565b91505092915050565b60006020820190508181036000830152613d918184613bd1565b905092915050565b6000819050602082019050919050565b6000613db5825161368f565b80915050919050565b600082821b905092915050565b6000613dd68261313f565b82613de084613d99565b9050613deb81613da9565b92506020821015613e2b57613e267fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802613dbe565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffff00000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b613ea8613ea382613e61565b613e8d565b82525050565b6000613eba828561365e565b9150613ec68284613e97565b6002820191508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f10826135f0565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613f4357613f42613ed6565b5b600182019050919050565b60008154613f5b81613491565b613f6581866138b7565b94506001821660008114613f805760018114613f9257613fc5565b60ff1983168652602086019350613fc5565b613f9b856134ce565b60005b83811015613fbd57815481890152600182019150602081019050613f9e565b808801955050505b50505092915050565b60006040820190508181036000830152613fe881856138c8565b90508181036020830152613ffc8184613f4e565b90509392505050565b61400e81613833565b811461401957600080fd5b50565b60008151905061402b81614005565b92915050565b60006020828403121561404757614046612f22565b5b60006140558482850161401c565b91505092915050565b614067816135f0565b82525050565b600060608201905081810360008301526140878186613595565b90506140966020830185613c36565b6140a3604083018461405e565b949350505050565b6000602082840312156140c1576140c0612f22565b5b600082015167ffffffffffffffff8111156140df576140de612f27565b5b6140eb84828501613973565b91505092915050565b6000614100828561365e565b915061410c828461365e565b91508190509392505050565b600060208201905081810360008301526141328184613f4e565b905092915050565b6141438161377c565b82525050565b600060608201905081810360008301526141638186613bd1565b9050614172602083018561413a565b61417f604083018461405e565b949350505050565b6000614192826135f0565b915061419d836135f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156141d2576141d1613ed6565b5b828201905092915050565b600060608201905081810360008301526141f78186613bd1565b9050614206602083018561405e565b614213604083018461405e565b949350505050565b6000614227828661365e565b91506142338285613e97565b600282019150614243828461365e565b9150819050949350505050565b7f7661720000000000000000000000000000000000000000000000000000000000600082015250565b60006142866003836138b7565b915061429182614250565b602082019050919050565b600060208201905081810360008301526142b581614279565b9050919050565b60006142c8828661365e565b91506142d48285613869565b6001820191506142e482846136f0565b600482019150819050949350505050565b7f5061727365723a20220000000000000000000000000000000000000000000000600082015250565b600061432b6009836134c3565b9150614336826142f5565b600982019050919050565b7f2220636f6d6d616e6420697320756e6b6e6f776e000000000000000000000000600082015250565b60006143776014836134c3565b915061438282614341565b601482019050919050565b60006143988261431e565b91506143a482846134e3565b91506143af8261436a565b915081905092915050565b600060208201905081810360008301526143d481846138c8565b905092915050565b6143e5816136ba565b81146143f057600080fd5b50565b600081519050614402816143dc565b92915050565b60006020828403121561441e5761441d612f22565b5b600061442c848285016143f3565b91505092915050565b6000606082019050818103600083015261444f818661318e565b905061445e60208301856138a8565b61446b60408301846138a8565b949350505050565b600061447f828461365e565b915081905092915050565b60006144968285613aeb565b91506144a28284613aeb565b91508190509392505050565b6144b7816135f0565b82525050565b600060408201905081810360008301526144d781856138c8565b90506144e660208301846144ae565b939250505056fea26469706673582212201e0b8ec899002850ccacf7b3432f0c6e7ccb7bef54a6e0ec209708e1b0ae02f464736f6c634300080b0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101845760003560e01c806390d95d80116100d9578063c45e3e5011610087578063c45e3e5014610551578063c92b45e114610581578063cbfc5ad4146105b1578063cedba5f1146105e1578063dc19dabd14610611578063f5a4363e14610641578063f7edbb701461067157610184565b806390d95d80146104155780639609ebb3146104455780639714a18214610461578063997f430614610491578063b9c34291146104c1578063b9dd4c83146104f1578063bfd5b4451461052157610184565b80635887e21b116101365780635887e21b146102d957806368bf5659146103095780636960e80b14610339578063861826411461036957806386b8d4e81461039957806389995a9e146103c95780638bc0a7a7146103e557610184565b8063021d30be1461018957806303dc1cee146101b957806305feb51f146101e95780630f47ec74146102195780632909fb3e1461024957806353edd023146102795780635694922f146102a9575b600080fd5b6101a3600480360381019061019e91906130d0565b6106a1565b6040516101b091906131c7565b60405180910390f35b6101d360048036038101906101ce91906130d0565b6106b5565b6040516101e091906131c7565b60405180910390f35b61020360048036038101906101fe91906130d0565b6106dd565b60405161021091906131c7565b60405180910390f35b610233600480360381019061022e91906130d0565b610851565b60405161024091906131c7565b60405180910390f35b610263600480360381019061025e91906130d0565b610865565b60405161027091906131c7565b60405180910390f35b610293600480360381019061028e91906130d0565b6109a4565b6040516102a091906131c7565b60405180910390f35b6102c360048036038101906102be91906130d0565b6109b8565b6040516102d091906131c7565b60405180910390f35b6102f360048036038101906102ee91906130d0565b6109e5565b60405161030091906131c7565b60405180910390f35b610323600480360381019061031e91906130d0565b610a44565b60405161033091906131c7565b60405180910390f35b610353600480360381019061034e91906130d0565b610a66565b60405161036091906131c7565b60405180910390f35b610383600480360381019061037e91906130d0565b610abc565b60405161039091906131c7565b60405180910390f35b6103b360048036038101906103ae91906130d0565b610b1d565b6040516103c091906131c7565b60405180910390f35b6103e360048036038101906103de9190613370565b610b3c565b005b6103ff60048036038101906103fa91906130d0565b610d89565b60405161040c91906131c7565b60405180910390f35b61042f600480360381019061042a91906130d0565b610ea4565b60405161043c91906131c7565b60405180910390f35b61045f600480360381019061045a91906133df565b610eb8565b005b61047b600480360381019061047691906130d0565b610f4f565b60405161048891906131c7565b60405180910390f35b6104ab60048036038101906104a691906130d0565b6117a5565b6040516104b891906131c7565b60405180910390f35b6104db60048036038101906104d691906130d0565b6117dd565b6040516104e891906131c7565b60405180910390f35b61050b600480360381019061050691906130d0565b6118aa565b60405161051891906131c7565b60405180910390f35b61053b600480360381019061053691906130d0565b611ce8565b60405161054891906131c7565b60405180910390f35b61056b600480360381019061056691906130d0565b611d10565b60405161057891906131c7565b60405180910390f35b61059b600480360381019061059691906130d0565b611d3a565b6040516105a891906131c7565b60405180910390f35b6105cb60048036038101906105c691906130d0565b611d5c565b6040516105d891906131c7565b60405180910390f35b6105fb60048036038101906105f691906130d0565b611ef9565b60405161060891906131c7565b60405180910390f35b61062b600480360381019061062691906130d0565b611fc6565b60405161063891906131c7565b60405180910390f35b61065b600480360381019061065691906130d0565b611ff0565b60405161066891906131c7565b60405180910390f35b61068b600480360381019061068691906130d0565b61200f565b60405161069891906131c7565b60405180910390f35b60606106ac84612044565b90509392505050565b60606106c084612044565b90506106ca6120a2565b506106d481612044565b90509392505050565b606060006106e96120a2565b80546106f490613491565b80601f016020809104026020016040519081016040528092919081815260200182805461072090613491565b801561076d5780601f106107425761010080835404028352916020019161076d565b820191906000526020600020905b81548152906001019060200180831161075057829003601f168201915b50505050509050600061077e6120a2565b60405160200161078e9190613562565b604051602081830303815290604052805190602001209050858273d816c20e28cc704028c475108f4dc535e237ebd96370121b7190916040518263ffffffff1660e01b81526004016107e091906135ce565b602060405180830381865af41580156107fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108219190613626565b60001b8260405160200161083793929190613707565b604051602081830303815290604052925050509392505050565b606061085c84612044565b90509392505050565b606060006108716120a2565b805461087c90613491565b80601f01602080910402602001604051908101604052809291908181526020018280546108a890613491565b80156108f55780601f106108ca576101008083540402835291602001916108f5565b820191906000526020600020905b8154815290600101906020018083116108d857829003601f168201915b505050505073d816c20e28cc704028c475108f4dc535e237ebd96370121b7190916040518263ffffffff1660e01b815260040161093291906135ce565b602060405180830381865af415801561094f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109739190613626565b9050848160001b60405160200161098b929190613740565b6040516020818303038152906040529150509392505050565b60606109af84612044565b90509392505050565b60606109c384612044565b90506109ce81612044565b90506109dc81600080610865565b90509392505050565b6060610a2784846040518060400160405280600881526020017f636f6d706f756e640000000000000000000000000000000000000000000000008152506120dc565b9050610a316120a2565b50610a3b81612044565b90509392505050565b6060610a4f84612044565b9050610a5d81600080610d89565b90509392505050565b6060610aa884846040518060400160405280600a81526020017f6465636c617265417272000000000000000000000000000000000000000000008152506120dc565b9050610ab381612044565b90509392505050565b6060610afe84846040518060400160405280600a81526020017f6c6f616452656d6f7465000000000000000000000000000000000000000000008152506120dc565b9050610b0981612044565b9050610b148161218b565b90509392505050565b6060610b2884612044565b9050610b3381612044565b90509392505050565b60006001819055506060808373ffffffffffffffffffffffffffffffffffffffff1663bcf80c9d836040518263ffffffff1660e01b8152600401610b8091906131c7565b600060405180830381600087803b158015610b9a57600080fd5b505af1158015610bae573d6000803e3d6000fd5b50505050610bbb83612358565b8373ffffffffffffffffffffffffffffffffffffffff1663f26c917860006040518263ffffffff1660e01b8152600401610bf591906137ad565b600060405180830381600087803b158015610c0f57600080fd5b505af1158015610c23573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff1663138ef1516040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c969190613806565b73ffffffffffffffffffffffffffffffffffffffff166352efea6e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610cdd57600080fd5b505af1158015610cf1573d6000803e3d6000fd5b505050505b6000805490506001541015610d1757610d10858583612421565b9050610cf6565b8373ffffffffffffffffffffffffffffffffffffffff1663bcf80c9d826040518263ffffffff1660e01b8152600401610d5091906131c7565b600060405180830381600087803b158015610d6a57600080fd5b505af1158015610d7e573d6000803e3d6000fd5b505050505050505050565b60606000610e656040518060400160405280600481526020017f7472756500000000000000000000000000000000000000000000000000000000815250610dce6120a2565b8054610dd990613491565b80601f0160208091040260200160405190810160405280929190818152602001828054610e0590613491565b8015610e525780601f10610e2757610100808354040283529160200191610e52565b820191906000526020600020905b815481529060010190602001808311610e3557829003601f168201915b5050505050612c5490919063ffffffff16565b610e70576000610e73565b60015b60f81b90508481604051602001610e8b929190613880565b6040516020818303038152906040529150509392505050565b6060610eaf84612044565b90509392505050565b60008473ffffffffffffffffffffffffffffffffffffffff16630411de8885846040518363ffffffff1660e01b8152600401610ef5929190613901565b600060405180830381865afa158015610f12573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610f3b9190613a56565b9050610f48848483610b3c565b5050505050565b60606000610f5b6120a2565b8054610f6690613491565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9290613491565b8015610fdf5780601f10610fb457610100808354040283529160200191610fdf565b820191906000526020600020905b815481529060010190602001808311610fc257829003601f168201915b505050505090508491505b6000610ff46120a2565b8054610fff90613491565b80601f016020809104026020016040519081016040528092919081815260200182805461102b90613491565b80156110785780601f1061104d57610100808354040283529160200191611078565b820191906000526020600020905b81548152906001019060200180831161105b57829003601f168201915b5050505050905060006110db826110cd6040518060400160405280600181526020017f2e0000000000000000000000000000000000000000000000000000000000000081525086612cad90919063ffffffff16565b612cad90919063ffffffff16565b90508473ffffffffffffffffffffffffffffffffffffffff1663d598989e8484846040518463ffffffff1660e01b815260040161111a93929190613a9f565b600060405180830381600087803b15801561113457600080fd5b505af1158015611148573d6000803e3d6000fd5b50505050838160405160200161115e9190613b1c565b60405160208183030381529060405280519060200120604051602001611185929190613b33565b604051602081830303815290604052935060006111a06120a2565b80546111ab90613491565b80601f01602080910402602001604051908101604052809291908181526020018280546111d790613491565b80156112245780601f106111f957610100808354040283529160200191611224565b820191906000526020600020905b81548152906001019060200180831161120757829003601f168201915b505050505090508073d816c20e28cc704028c475108f4dc535e237ebd9634863d3e190916040518263ffffffff1660e01b815260040161126491906135ce565b602060405180830381865af4158015611281573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a59190613b93565b156113e457600081731c407cdd4975532bb5f3f614fb3b48478f597f4963e004139690916002602a6040518463ffffffff1660e01b81526004016112eb93929190613c80565b600060405180830381865af4158015611308573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906113319190613d2e565b90508581731c407cdd4975532bb5f3f614fb3b48478f597f49632c16769b90916040518263ffffffff1660e01b815260040161136d9190613d77565b600060405180830381865af415801561138a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906113b39190613d2e565b6113bc90613dcb565b6040516020016113cd929190613740565b60405160208183030381529060405295505061169a565b8073d816c20e28cc704028c475108f4dc535e237ebd963dba27b1c90916040518263ffffffff1660e01b815260040161141d91906135ce565b602060405180830381865af415801561143a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145e9190613b93565b1561150857848173d816c20e28cc704028c475108f4dc535e237ebd96370121b7190916040518263ffffffff1660e01b815260040161149d91906135ce565b602060405180830381865af41580156114ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114de9190613626565b60001b6040516020016114f2929190613740565b6040516020818303038152906040529450611699565b6115506040518060400160405280600481526020017f766f74650000000000000000000000000000000000000000000000000000000081525084612c5490919063ffffffff16565b80156115a0575061159f6040518060400160405280600381526020017f594553000000000000000000000000000000000000000000000000000000000081525082612c5490919063ffffffff16565b5b156115d25784600160001b6040516020016115bc929190613740565b6040516020818303038152906040529450611698565b61161a6040518060400160405280600481526020017f766f74650000000000000000000000000000000000000000000000000000000081525084612c5490919063ffffffff16565b801561166a57506116696040518060400160405280600281526020017f4e4f00000000000000000000000000000000000000000000000000000000000081525082612c5490919063ffffffff16565b5b1561169757846000801b604051602001611685929190613740565b60405160208183030381529060405294505b5b5b5b50505061178d6040518060400160405280600981526020017f656e6453747275637400000000000000000000000000000000000000000000008152506000600154815481106116ec576116eb613e32565b5b90600052602060002001805461170190613491565b80601f016020809104026020016040519081016040528092919081815260200182805461172d90613491565b801561177a5780601f1061174f5761010080835404028352916020019161177a565b820191906000526020600020905b81548152906001019060200180831161175d57829003601f168201915b5050505050612c5490919063ffffffff16565b15610fea5761179b82612044565b9150509392505050565b60606117b084612044565b90506117bb81612044565b90506117c681612044565b90506117d481600080610865565b90509392505050565b606061187b826117eb6120a2565b80546117f690613491565b80601f016020809104026020016040519081016040528092919081815260200182805461182290613491565b801561186f5780601f106118445761010080835404028352916020019161186f565b820191906000526020600020905b81548152906001019060200180831161185257829003601f168201915b50505050508651612cd9565b83600060f01b604051602001611892929190613eae565b60405160208183030381529060405290509392505050565b606060006118b66120a2565b80546118c190613491565b80601f01602080910402602001604051908101604052809291908181526020018280546118ed90613491565b801561193a5780601f1061190f5761010080835404028352916020019161193a565b820191906000526020600020905b81548152906001019060200180831161191d57829003601f168201915b50505050509050600061194b6120a2565b60405160200161195b9190613562565b6040516020818303038152906040528051906020012090508173d816c20e28cc704028c475108f4dc535e237ebd9634863d3e190916040518263ffffffff1660e01b81526004016119ac91906135ce565b602060405180830381865af41580156119c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ed9190613b93565b15611b2c57600082731c407cdd4975532bb5f3f614fb3b48478f597f4963e004139690916002602a6040518463ffffffff1660e01b8152600401611a3393929190613c80565b600060405180830381865af4158015611a50573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611a799190613d2e565b90508681731c407cdd4975532bb5f3f614fb3b48478f597f49632c16769b90916040518263ffffffff1660e01b8152600401611ab59190613d77565b600060405180830381865af4158015611ad2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611afb9190613d2e565b611b0490613dcb565b604051602001611b15929190613740565b604051602081830303815290604052935050611cbb565b8173d816c20e28cc704028c475108f4dc535e237ebd963dba27b1c90916040518263ffffffff1660e01b8152600401611b6591906135ce565b602060405180830381865af4158015611b82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba69190613b93565b15611c5057858273d816c20e28cc704028c475108f4dc535e237ebd96370121b7190916040518263ffffffff1660e01b8152600401611be591906135ce565b602060405180830381865af4158015611c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c269190613626565b60001b604051602001611c3a929190613740565b6040516020818303038152906040529250611cba565b8582604051602001611c629190613b1c565b604051602081830303815290604052805190602001207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916604051602001611ca8929190613740565b60405160208183030381529060405292505b5b8281604051602001611cce929190613b33565b604051602081830303815290604052925050509392505050565b6060611cf384612044565b9050611cfd6120a2565b50611d0781612044565b90509392505050565b6060611d1b84612044565b9050611d2681612044565b9050611d3181612044565b90509392505050565b6060611d4584612044565b9050611d5381600080610865565b90509392505050565b60606000611d686120a2565b8054611d7390613491565b80601f0160208091040260200160405190810160405280929190818152602001828054611d9f90613491565b8015611dec5780601f10611dc157610100808354040283529160200191611dec565b820191906000526020600020905b815481529060010190602001808311611dcf57829003601f168201915b505050505090506000611dfd6120a2565b8054611e0890613491565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3490613491565b8015611e815780601f10611e5657610100808354040283529160200191611e81565b820191906000526020600020905b815481529060010190602001808311611e6457829003601f168201915b50505050509050611e9484838851612cd9565b85600060f01b604051602001611eab929190613eae565b6040516020818303038152906040529250611ec884828551612cd9565b82600060f01b604051602001611edf929190613eae565b604051602081830303815290604052925050509392505050565b6060611f9782611f076120a2565b8054611f1290613491565b80601f0160208091040260200160405190810160405280929190818152602001828054611f3e90613491565b8015611f8b5780601f10611f6057610100808354040283529160200191611f8b565b820191906000526020600020905b815481529060010190602001808311611f6e57829003601f168201915b50505050508651612cd9565b83600060f01b604051602001611fae929190613eae565b60405160208183030381529060405290509392505050565b6060611fd184612044565b9050611fdc81612044565b9050611fe781612044565b90509392505050565b6060611ffb84612044565b905061200681612044565b90509392505050565b606061201a84612044565b905061202581612044565b905061203081612044565b905061203b81612044565b90509392505050565b606060006120506120a2565b6040516020016120609190613562565b604051602081830303815290604052805190602001209050828160405160200161208b929190613b33565b604051602081830303815290604052915050919050565b600080600160008154809291906120b890613f05565b91905055815481106120cd576120cc613e32565b5b90600052602060002001905090565b6060838373ffffffffffffffffffffffffffffffffffffffff16635bf3e5d7846121046120a2565b6040518363ffffffff1660e01b8152600401612121929190613fce565b602060405180830381865afa15801561213e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121629190614031565b604051602001612173929190613880565b60405160208183030381529060405290509392505050565b606060006121976120a2565b80546121a290613491565b80601f01602080910402602001604051908101604052809291908181526020018280546121ce90613491565b801561221b5780601f106121f05761010080835404028352916020019161221b565b820191906000526020600020905b8154815290600101906020018083116121fe57829003601f168201915b505050505090508073d816c20e28cc704028c475108f4dc535e237ebd96339c27bd49091600261224a85612d4b565b6040518463ffffffff1660e01b81526004016122689392919061406d565b600060405180830381865af4158015612285573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122ae91906140ab565b9050828173d816c20e28cc704028c475108f4dc535e237ebd9638e7e34d790916040518263ffffffff1660e01b81526004016122ea91906135ce565b600060405180830381865af4158015612307573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906123309190613d2e565b6040516020016123419291906140f4565b604051602081830303815290604052915050919050565b60008060006123679190612df0565b5b8151811080156123b157506123af6040518060200160405280600081525083838151811061239957612398613e32565b5b6020026020010151612c5490919063ffffffff16565b155b1561241d5760008282806123c490613f05565b9350815181106123d7576123d6613e32565b5b6020026020010151908060018154018082558091505060019003906000526020600020016000909190919091509080519060200190612417929190612e11565b50612368565b5050565b6060600061242d6120a2565b905060008573ffffffffffffffffffffffffffffffffffffffff1663f3f8d4e3836040518263ffffffff1660e01b815260040161246a9190614118565b602060405180830381865afa158015612487573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ab9190614031565b90506000826040516020016124c09190613562565b60405160208183030381529060405280519060200120905060008673ffffffffffffffffffffffffffffffffffffffff1663402a652a856040518263ffffffff1660e01b81526004016125139190614118565b602060405180830381865afa158015612530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125549190613b93565b90506125e98785805461256690613491565b80601f016020809104026020016040519081016040528092919081815260200182805461259290613491565b80156125df5780601f106125b4576101008083540402835291602001916125df565b820191906000526020600020905b8154815290600101906020018083116125c257829003601f168201915b5050505050612d56565b156127cd576000865160f01b9050600061268c8987805461260990613491565b80601f016020809104026020016040519081016040528092919081815260200182805461263590613491565b80156126825780601f1061265757610100808354040283529160200191612682565b820191906000526020600020905b81548152906001019060200180831161266557829003601f168201915b5050505050612d6c565b905087731c407cdd4975532bb5f3f614fb3b48478f597f4963e004139690916000846040518463ffffffff1660e01b81526004016126cc93929190614149565b600060405180830381865af41580156126e9573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906127129190613d2e565b8289731c407cdd4975532bb5f3f614fb3b48478f597f4963e0041396909160028661273d9190614187565b8d516040518463ffffffff1660e01b815260040161275d939291906141dd565b600060405180830381865af415801561277a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906127a39190613d2e565b6040516020016127b59392919061421b565b60405160208183030381529060405296505050612c49565b8380546127d990613491565b80601f016020809104026020016040519081016040528092919081815260200182805461280590613491565b80156128525780601f1061282757610100808354040283529160200191612852565b820191906000526020600020905b81548152906001019060200180831161283557829003601f168201915b505050505073d816c20e28cc704028c475108f4dc535e237ebd963fe4f41c890916040518263ffffffff1660e01b815260040161288f91906135ce565b602060405180830381865af41580156128ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128d09190613b93565b806128d85750805b15612982578773ffffffffffffffffffffffffffffffffffffffff1663f3f8d4e36040518163ffffffff1660e01b81526004016129149061429c565b602060405180830381865afa158015612931573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129559190614031565b925085838360405160200161296c939291906142bc565b6040516020818303038152906040529450612c48565b600060f81b837effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415612a0c57836040516020016129c1919061438d565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a0391906143ba565b60405180910390fd5b8583604051602001612a1f929190613880565b60405160208183030381529060405294508773ffffffffffffffffffffffffffffffffffffffff16633cb9ceff856040518263ffffffff1660e01b8152600401612a699190614118565b602060405180830381865afa158015612a86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aaa9190614408565b9150600060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612c47576000803073ffffffffffffffffffffffffffffffffffffffff1684888c8c604051602401612b0693929190614435565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051612b709190614473565b600060405180830381855af49150503d8060008114612bab576040519150601f19603f3d011682016040523d82523d6000602084013e612bb0565b606091505b5091509150816040518060400160405280600481526020017f505253310000000000000000000000000000000000000000000000000000000081525090612c2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2491906143ba565b60405180910390fd5b5080806020019051810190612c429190613d2e565b965050505b5b5b505050509392505050565b600081604051602001612c679190613b1c565b6040516020818303038152906040528051906020012083604051602001612c8e9190613b1c565b6040516020818303038152906040528051906020012014905092915050565b60608282604051602001612cc292919061448a565b604051602081830303815290604052905092915050565b8273ffffffffffffffffffffffffffffffffffffffff1663c0a00cda83836040518363ffffffff1660e01b8152600401612d149291906144bd565b600060405180830381600087803b158015612d2e57600080fd5b505af1158015612d42573d6000803e3d6000fd5b50505050505050565b600081519050919050565b600080612d638484612d6c565b11905092915050565b60008273ffffffffffffffffffffffffffffffffffffffff16635981f3db836040518263ffffffff1660e01b8152600401612da791906143ba565b602060405180830381865afa158015612dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612de89190613626565b905092915050565b5080546000825590600052602060002090810190612e0e9190612e97565b50565b828054612e1d90613491565b90600052602060002090601f016020900481019282612e3f5760008555612e86565b82601f10612e5857805160ff1916838001178555612e86565b82800160010185558215612e86579182015b82811115612e85578251825591602001919060010190612e6a565b5b509050612e939190612ebb565b5090565b5b80821115612eb75760008181612eae9190612ed8565b50600101612e98565b5090565b5b80821115612ed4576000816000905550600101612ebc565b5090565b508054612ee490613491565b6000825580601f10612ef65750612f15565b601f016020900490600052602060002090810190612f149190612ebb565b5b50565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612f7f82612f36565b810181811067ffffffffffffffff82111715612f9e57612f9d612f47565b5b80604052505050565b6000612fb1612f18565b9050612fbd8282612f76565b919050565b600067ffffffffffffffff821115612fdd57612fdc612f47565b5b612fe682612f36565b9050602081019050919050565b82818337600083830152505050565b600061301561301084612fc2565b612fa7565b90508281526020810184848401111561303157613030612f31565b5b61303c848285612ff3565b509392505050565b600082601f83011261305957613058612f2c565b5b8135613069848260208601613002565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061309d82613072565b9050919050565b6130ad81613092565b81146130b857600080fd5b50565b6000813590506130ca816130a4565b92915050565b6000806000606084860312156130e9576130e8612f22565b5b600084013567ffffffffffffffff81111561310757613106612f27565b5b61311386828701613044565b9350506020613124868287016130bb565b9250506040613135868287016130bb565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b60005b8381101561317957808201518184015260208101905061315e565b83811115613188576000848401525b50505050565b60006131998261313f565b6131a3818561314a565b93506131b381856020860161315b565b6131bc81612f36565b840191505092915050565b600060208201905081810360008301526131e1818461318e565b905092915050565b600067ffffffffffffffff82111561320457613203612f47565b5b602082029050602081019050919050565b600080fd5b600067ffffffffffffffff82111561323557613234612f47565b5b61323e82612f36565b9050602081019050919050565b600061325e6132598461321a565b612fa7565b90508281526020810184848401111561327a57613279612f31565b5b613285848285612ff3565b509392505050565b600082601f8301126132a2576132a1612f2c565b5b81356132b284826020860161324b565b91505092915050565b60006132ce6132c9846131e9565b612fa7565b905080838252602082019050602084028301858111156132f1576132f0613215565b5b835b8181101561333857803567ffffffffffffffff81111561331657613315612f2c565b5b808601613323898261328d565b855260208501945050506020810190506132f3565b5050509392505050565b600082601f83011261335757613356612f2c565b5b81356133678482602086016132bb565b91505092915050565b60008060006060848603121561338957613388612f22565b5b6000613397868287016130bb565b93505060206133a8868287016130bb565b925050604084013567ffffffffffffffff8111156133c9576133c8612f27565b5b6133d586828701613342565b9150509250925092565b600080600080608085870312156133f9576133f8612f22565b5b6000613407878288016130bb565b9450506020613418878288016130bb565b9350506040613429878288016130bb565b925050606085013567ffffffffffffffff81111561344a57613449612f27565b5b6134568782880161328d565b91505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806134a957607f821691505b602082108114156134bd576134bc613462565b5b50919050565b600081905092915050565b60008190508160005260206000209050919050565b600081546134f081613491565b6134fa81866134c3565b94506001821660008114613515576001811461352657613559565b60ff19831686528186019350613559565b61352f856134ce565b60005b8381101561355157815481890152600182019150602081019050613532565b838801955050505b50505092915050565b600061356e82846134e3565b915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006135a082613579565b6135aa8185613584565b93506135ba81856020860161315b565b6135c381612f36565b840191505092915050565b600060208201905081810360008301526135e88184613595565b905092915050565b6000819050919050565b613603816135f0565b811461360e57600080fd5b50565b600081519050613620816135fa565b92915050565b60006020828403121561363c5761363b612f22565b5b600061364a84828501613611565b91505092915050565b600081905092915050565b60006136698261313f565b6136738185613653565b935061368381856020860161315b565b80840191505092915050565b6000819050919050565b6000819050919050565b6136b46136af8261368f565b613699565b82525050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b6137016136fc826136ba565b6136e6565b82525050565b6000613713828661365e565b915061371f82856136a3565b60208201915061372f82846136f0565b600482019150819050949350505050565b600061374c828561365e565b915061375882846136a3565b6020820191508190509392505050565b6000819050919050565b6000819050919050565b600061379761379261378d84613768565b613772565b6135f0565b9050919050565b6137a78161377c565b82525050565b60006020820190506137c2600083018461379e565b92915050565b60006137d382613092565b9050919050565b6137e3816137c8565b81146137ee57600080fd5b50565b600081519050613800816137da565b92915050565b60006020828403121561381c5761381b612f22565b5b600061382a848285016137f1565b91505092915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b61387a61387582613833565b61385f565b82525050565b600061388c828561365e565b91506138988284613869565b6001820191508190509392505050565b6138b181613092565b82525050565b600082825260208201905092915050565b60006138d382613579565b6138dd81856138b7565b93506138ed81856020860161315b565b6138f681612f36565b840191505092915050565b600060408201905061391660008301856138a8565b818103602083015261392881846138c8565b90509392505050565b600061394461393f8461321a565b612fa7565b9050828152602081018484840111156139605761395f612f31565b5b61396b84828561315b565b509392505050565b600082601f83011261398857613987612f2c565b5b8151613998848260208601613931565b91505092915050565b60006139b46139af846131e9565b612fa7565b905080838252602082019050602084028301858111156139d7576139d6613215565b5b835b81811015613a1e57805167ffffffffffffffff8111156139fc576139fb612f2c565b5b808601613a098982613973565b855260208501945050506020810190506139d9565b5050509392505050565b600082601f830112613a3d57613a3c612f2c565b5b8151613a4d8482602086016139a1565b91505092915050565b600060208284031215613a6c57613a6b612f22565b5b600082015167ffffffffffffffff811115613a8a57613a89612f27565b5b613a9684828501613a28565b91505092915050565b60006060820190508181036000830152613ab981866138c8565b90508181036020830152613acd81856138c8565b90508181036040830152613ae181846138c8565b9050949350505050565b6000613af682613579565b613b0081856134c3565b9350613b1081856020860161315b565b80840191505092915050565b6000613b288284613aeb565b915081905092915050565b6000613b3f828561365e565b9150613b4b82846136f0565b6004820191508190509392505050565b60008115159050919050565b613b7081613b5b565b8114613b7b57600080fd5b50565b600081519050613b8d81613b67565b92915050565b600060208284031215613ba957613ba8612f22565b5b6000613bb784828501613b7e565b91505092915050565b600082825260208201905092915050565b6000613bdc8261313f565b613be68185613bc0565b9350613bf681856020860161315b565b613bff81612f36565b840191505092915050565b6000819050919050565b6000613c2f613c2a613c2584613c0a565b613772565b6135f0565b9050919050565b613c3f81613c14565b82525050565b6000819050919050565b6000613c6a613c65613c6084613c45565b613772565b6135f0565b9050919050565b613c7a81613c4f565b82525050565b60006060820190508181036000830152613c9a8186613bd1565b9050613ca96020830185613c36565b613cb66040830184613c71565b949350505050565b6000613cd1613ccc84612fc2565b612fa7565b905082815260208101848484011115613ced57613cec612f31565b5b613cf884828561315b565b509392505050565b600082601f830112613d1557613d14612f2c565b5b8151613d25848260208601613cbe565b91505092915050565b600060208284031215613d4457613d43612f22565b5b600082015167ffffffffffffffff811115613d6257613d61612f27565b5b613d6e84828501613d00565b91505092915050565b60006020820190508181036000830152613d918184613bd1565b905092915050565b6000819050602082019050919050565b6000613db5825161368f565b80915050919050565b600082821b905092915050565b6000613dd68261313f565b82613de084613d99565b9050613deb81613da9565b92506020821015613e2b57613e267fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802613dbe565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffff00000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b613ea8613ea382613e61565b613e8d565b82525050565b6000613eba828561365e565b9150613ec68284613e97565b6002820191508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f10826135f0565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613f4357613f42613ed6565b5b600182019050919050565b60008154613f5b81613491565b613f6581866138b7565b94506001821660008114613f805760018114613f9257613fc5565b60ff1983168652602086019350613fc5565b613f9b856134ce565b60005b83811015613fbd57815481890152600182019150602081019050613f9e565b808801955050505b50505092915050565b60006040820190508181036000830152613fe881856138c8565b90508181036020830152613ffc8184613f4e565b90509392505050565b61400e81613833565b811461401957600080fd5b50565b60008151905061402b81614005565b92915050565b60006020828403121561404757614046612f22565b5b60006140558482850161401c565b91505092915050565b614067816135f0565b82525050565b600060608201905081810360008301526140878186613595565b90506140966020830185613c36565b6140a3604083018461405e565b949350505050565b6000602082840312156140c1576140c0612f22565b5b600082015167ffffffffffffffff8111156140df576140de612f27565b5b6140eb84828501613973565b91505092915050565b6000614100828561365e565b915061410c828461365e565b91508190509392505050565b600060208201905081810360008301526141328184613f4e565b905092915050565b6141438161377c565b82525050565b600060608201905081810360008301526141638186613bd1565b9050614172602083018561413a565b61417f604083018461405e565b949350505050565b6000614192826135f0565b915061419d836135f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156141d2576141d1613ed6565b5b828201905092915050565b600060608201905081810360008301526141f78186613bd1565b9050614206602083018561405e565b614213604083018461405e565b949350505050565b6000614227828661365e565b91506142338285613e97565b600282019150614243828461365e565b9150819050949350505050565b7f7661720000000000000000000000000000000000000000000000000000000000600082015250565b60006142866003836138b7565b915061429182614250565b602082019050919050565b600060208201905081810360008301526142b581614279565b9050919050565b60006142c8828661365e565b91506142d48285613869565b6001820191506142e482846136f0565b600482019150819050949350505050565b7f5061727365723a20220000000000000000000000000000000000000000000000600082015250565b600061432b6009836134c3565b9150614336826142f5565b600982019050919050565b7f2220636f6d6d616e6420697320756e6b6e6f776e000000000000000000000000600082015250565b60006143776014836134c3565b915061438282614341565b601482019050919050565b60006143988261431e565b91506143a482846134e3565b91506143af8261436a565b915081905092915050565b600060208201905081810360008301526143d481846138c8565b905092915050565b6143e5816136ba565b81146143f057600080fd5b50565b600081519050614402816143dc565b92915050565b60006020828403121561441e5761441d612f22565b5b600061442c848285016143f3565b91505092915050565b6000606082019050818103600083015261444f818661318e565b905061445e60208301856138a8565b61446b60408301846138a8565b949350505050565b600061447f828461365e565b915081905092915050565b60006144968285613aeb565b91506144a28284613aeb565b91508190509392505050565b6144b7816135f0565b82525050565b600060408201905081810360008301526144d781856138c8565b90506144e660208301846144ae565b939250505056fea26469706673582212201e0b8ec899002850ccacf7b3432f0c6e7ccb7bef54a6e0ec209708e1b0ae02f464736f6c634300080b0033
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.