From 10f747a8d7c0f19928b77dfc1495bb28dfa5ef92 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Tue, 18 Dec 2018 19:25:44 -0500 Subject: [PATCH 01/46] fix txFormat tests --- remix-lib/test/txFormat.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/remix-lib/test/txFormat.js b/remix-lib/test/txFormat.js index c8192ed80b..48397a0619 100644 --- a/remix-lib/test/txFormat.js +++ b/remix-lib/test/txFormat.js @@ -15,7 +15,8 @@ tape('ContractParameters - (TxFormat.buildData) - format input parameters', func output = JSON.parse(output) var contract = output.contracts['test.sol']['uintContractTest'] context = { output, contract } - var bytecode = '608060405234801561001057600080fd5b5061011e806100206000396000f3fe608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634b521953146044575b600080fd5b348015604f57600080fd5b5060a360048036036060811015606457600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505060a5565b005b8260008190555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505056fea165627a7a7230582053a6bee96a62b9079722b2a0004a405aa29803abc12ed6dd0322007ebb44a5f60029' + var bytecode = '608060405234801561001057600080fd5b50610118806100206000396000f3fe6080604052600436106039576000357c0100000000000000000000000000000000000000000000000000000000900480634b52195314603e575b600080fd5b348015604957600080fd5b50609d60048036036060811015605e57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050609f565b005b8260008190555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505056fea165627a7a72305820eef04af1d305b2d1a4227d962175cf0c1ddc8c5a50f11189b73615d73344a0270029' + t.test('(TxFormat.buildData)', function (st) { st.plan(3) testWithInput(st, '123123, "0xf7a10e525d4b168f45f74db1b61f63d3e7619ea8", "34"', bytecode + '000000000000000000000000000000000000000000000000000000000001e0f3000000000000000000000000f7a10e525d4b168f45f74db1b61f63d3e7619ea80000000000000000000000000000000000000000000000000000000000000022') @@ -97,7 +98,7 @@ function testLinkLibrary2 (st, callbackDeployLibraries) { } } - var data = '608060405234801561001057600080fd5b5061026b806100206000396000f3fe608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636d4ce63c14610046575b600080fd5b34801561005257600080fd5b5061005b61005d565b005b73f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156100bd57600080fd5b505af41580156100d1573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561013557600080fd5b505af4158015610149573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156101ad57600080fd5b505af41580156101c1573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561022557600080fd5b505af4158015610239573d6000803e3d6000fd5b5050505056fea165627a7a72305820d2fdcf2968ba13c89dd82748af1cac609a670e333fce635bc2212c2a50508be70029' + var data = '608060405234801561001057600080fd5b50610265806100206000396000f3fe60806040526004361061003b576000357c0100000000000000000000000000000000000000000000000000000000900480636d4ce63c14610040575b600080fd5b34801561004c57600080fd5b50610055610057565b005b73f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156100b757600080fd5b505af41580156100cb573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561012f57600080fd5b505af4158015610143573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156101a757600080fd5b505af41580156101bb573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561021f57600080fd5b505af4158015610233573d6000803e3d6000fd5b5050505056fea165627a7a7230582056535474e1f8ba4f728b0d6fff8855d02828ff110ccef98edd3965c6c2a9a4b10029' var deployMsg = ['creation of library test.sol:lib1 pending...', 'creation of library test.sol:lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 pending...'] @@ -235,7 +236,7 @@ library lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_li } } -contract testContractLinkLibrary { +contract testContractLinkLibrary { function get () public { lib1.getEmpty(); lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2.getEmpty(); @@ -246,17 +247,17 @@ contract testContractLinkLibrary { var encodeFunctionCall = `pragma solidity ^0.5.0; -contract testContractLinkLibrary { +contract testContractLinkLibrary { function get (uint _p, string memory _o) public { } }` var fallbackFunction = `pragma solidity ^0.5.0; -contract fallbackFunctionContract { +contract fallbackFunctionContract { function get (uint _p, string memory _o) public { } - + function () external {} }` @@ -271,7 +272,7 @@ contract test { function t (p memory _p, uint _i) public returns (p memory) { return _p; } - + function t () public returns (p memory) { p memory mm; mm.a = 123; @@ -282,17 +283,17 @@ contract test { var abiEncoderV2ArrayOfTuple = `pragma experimental ABIEncoderV2; contract test { - + struct MyStruct {uint256 num; string _string;} - + constructor (MyStruct[] memory _structs, string memory _str) public { - + } - + function addStructs(MyStruct[] memory _structs) public returns (MyStruct[] memory strucmts) { strucmts = _structs; } - + function addStructs(MyStruct memory _structs) public returns (MyStruct memory _strucmts) { _strucmts = _structs; } From 11b933ea675e9753c0822cb367911ecd67bbbfdd Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Wed, 10 Oct 2018 07:52:21 -0400 Subject: [PATCH 02/46] test --- remix-debug/compilation.json | 6415 ++++++++++++++++++++++++++ remix-debug/contextManager.js | 59 + remix-debug/lib_test.js | 0 remix-debug/src/debugger/debugger.js | 44 +- remix-debug/test.js | 87 + 5 files changed, 6585 insertions(+), 20 deletions(-) create mode 100644 remix-debug/compilation.json create mode 100644 remix-debug/contextManager.js create mode 100644 remix-debug/lib_test.js create mode 100644 remix-debug/test.js diff --git a/remix-debug/compilation.json b/remix-debug/compilation.json new file mode 100644 index 0000000000..323166a4ad --- /dev/null +++ b/remix-debug/compilation.json @@ -0,0 +1,6415 @@ +{ + "data": { + "contracts": { + "browser/ballot.sol": { + "Ballot": { + "abi": [{ + "constant": false, + "inputs": [{ + "name": "to", + "type": "address" + }], + "name": "delegate", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { + "constant": false, + "inputs": [{ + "name": "toVoter", + "type": "address" + }], + "name": "giveRightToVote", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { + "inputs": [{ + "name": "_numProposals", + "type": "uint8" + }], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, { + "constant": false, + "inputs": [{ + "name": "toProposal", + "type": "uint8" + }], + "name": "vote", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { + "constant": true, + "inputs": [], + "name": "winningProposal", + "outputs": [{ + "name": "_winningProposal", + "type": "uint8" + }], + "payable": false, + "stateMutability": "view", + "type": "function" + }], + "devdoc": { + "methods": {} + }, + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "608060405234801561001057600080fd5b50604051602080610487833981016040908152905160008054600160a060020a0319163317808255600160a060020a03168152600160208190529290209190915560ff8116610060600282610067565b50506100b1565b81548183558181111561008b5760008381526020902061008b918101908301610090565b505050565b6100ae91905b808211156100aa5760008155600101610096565b5090565b90565b6103c7806100c06000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416635c19a95c8114610066578063609ff1bd146100895780639e7b8d61146100b4578063b3f98adc146100d5575b600080fd5b34801561007257600080fd5b50610087600160a060020a03600435166100f0565b005b34801561009557600080fd5b5061009e610250565b6040805160ff9092168252519081900360200190f35b3480156100c057600080fd5b50610087600160a060020a03600435166102bb565b3480156100e157600080fd5b5061008760ff6004351661031b565b33600090815260016020819052604082209081015490919060ff16156101155761024b565b5b600160a060020a0383811660009081526001602081905260409091200154620100009004161580159061016d5750600160a060020a0383811660009081526001602081905260409091200154620100009004163314155b1561019f57600160a060020a039283166000908152600160208190526040909120015462010000900490921691610116565b600160a060020a0383163314156101b55761024b565b506001818101805460ff1916821775ffffffffffffffffffffffffffffffffffffffff0000191662010000600160a060020a0386169081029190911790915560009081526020829052604090209081015460ff16156102435781546001820154600280549091610100900460ff1690811061022c57fe5b60009182526020909120018054909101905561024b565b815481540181555b505050565b600080805b60025460ff821610156102b6578160028260ff1681548110151561027557fe5b906000526020600020016000015411156102ae576002805460ff831690811061029a57fe5b906000526020600020016000015491508092505b600101610255565b505090565b600054600160a060020a0316331415806102f15750600160a060020a0381166000908152600160208190526040909120015460ff165b156102fb57610318565b600160a060020a0381166000908152600160208190526040909120555b50565b3360009081526001602081905260409091209081015460ff1680610344575060025460ff831610155b1561034e57610397565b6001818101805460ff191690911761ff00191661010060ff85169081029190911790915581546002805491929091811061038457fe5b6000918252602090912001805490910190555b50505600a165627a7a72305820ce66bb0ee0898d1afc8d56202dd09955892767cfba6bcf0ddb23181288192c450029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP1 PUSH2 0x487 DUP4 CODECOPY DUP2 ADD PUSH1 0x40 SWAP1 DUP2 MSTORE SWAP1 MLOAD PUSH1 0x0 DUP1 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB NOT AND CALLER OR DUP1 DUP3 SSTORE PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE SWAP3 SWAP1 KECCAK256 SWAP2 SWAP1 SWAP2 SSTORE PUSH1 0xFF DUP2 AND PUSH2 0x60 PUSH1 0x2 DUP3 PUSH2 0x67 JUMP JUMPDEST POP POP PUSH2 0xB1 JUMP JUMPDEST DUP2 SLOAD DUP2 DUP4 SSTORE DUP2 DUP2 GT ISZERO PUSH2 0x8B JUMPI PUSH1 0x0 DUP4 DUP2 MSTORE PUSH1 0x20 SWAP1 KECCAK256 PUSH2 0x8B SWAP2 DUP2 ADD SWAP1 DUP4 ADD PUSH2 0x90 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH2 0xAE SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH2 0xAA JUMPI PUSH1 0x0 DUP2 SSTORE PUSH1 0x1 ADD PUSH2 0x96 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x3C7 DUP1 PUSH2 0xC0 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x61 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x5C19A95C DUP2 EQ PUSH2 0x66 JUMPI DUP1 PUSH4 0x609FF1BD EQ PUSH2 0x89 JUMPI DUP1 PUSH4 0x9E7B8D61 EQ PUSH2 0xB4 JUMPI DUP1 PUSH4 0xB3F98ADC EQ PUSH2 0xD5 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x72 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x87 PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB PUSH1 0x4 CALLDATALOAD AND PUSH2 0xF0 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x95 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x9E PUSH2 0x250 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0xFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xC0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x87 PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB PUSH1 0x4 CALLDATALOAD AND PUSH2 0x2BB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xE1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x87 PUSH1 0xFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x31B JUMP JUMPDEST CALLER PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP3 KECCAK256 SWAP1 DUP2 ADD SLOAD SWAP1 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x115 JUMPI PUSH2 0x24B JUMP JUMPDEST JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP4 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH3 0x10000 SWAP1 DIV AND ISZERO DUP1 ISZERO SWAP1 PUSH2 0x16D JUMPI POP PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP4 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH3 0x10000 SWAP1 DIV AND CALLER EQ ISZERO JUMPDEST ISZERO PUSH2 0x19F JUMPI PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP3 DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH3 0x10000 SWAP1 DIV SWAP1 SWAP3 AND SWAP2 PUSH2 0x116 JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP4 AND CALLER EQ ISZERO PUSH2 0x1B5 JUMPI PUSH2 0x24B JUMP JUMPDEST POP PUSH1 0x1 DUP2 DUP2 ADD DUP1 SLOAD PUSH1 0xFF NOT AND DUP3 OR PUSH22 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 NOT AND PUSH3 0x10000 PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP7 AND SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 OR SWAP1 SWAP2 SSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SWAP1 DUP2 ADD SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x243 JUMPI DUP2 SLOAD PUSH1 0x1 DUP3 ADD SLOAD PUSH1 0x2 DUP1 SLOAD SWAP1 SWAP2 PUSH2 0x100 SWAP1 DIV PUSH1 0xFF AND SWAP1 DUP2 LT PUSH2 0x22C JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD DUP1 SLOAD SWAP1 SWAP2 ADD SWAP1 SSTORE PUSH2 0x24B JUMP JUMPDEST DUP2 SLOAD DUP2 SLOAD ADD DUP2 SSTORE JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 JUMPDEST PUSH1 0x2 SLOAD PUSH1 0xFF DUP3 AND LT ISZERO PUSH2 0x2B6 JUMPI DUP2 PUSH1 0x2 DUP3 PUSH1 0xFF AND DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x275 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 ADD SLOAD GT ISZERO PUSH2 0x2AE JUMPI PUSH1 0x2 DUP1 SLOAD PUSH1 0xFF DUP4 AND SWAP1 DUP2 LT PUSH2 0x29A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 ADD SLOAD SWAP2 POP DUP1 SWAP3 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0x255 JUMP JUMPDEST POP POP SWAP1 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND CALLER EQ ISZERO DUP1 PUSH2 0x2F1 JUMPI POP PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0x2FB JUMPI PUSH2 0x318 JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 SSTORE JUMPDEST POP JUMP JUMPDEST CALLER PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 SWAP1 DUP2 ADD SLOAD PUSH1 0xFF AND DUP1 PUSH2 0x344 JUMPI POP PUSH1 0x2 SLOAD PUSH1 0xFF DUP4 AND LT ISZERO JUMPDEST ISZERO PUSH2 0x34E JUMPI PUSH2 0x397 JUMP JUMPDEST PUSH1 0x1 DUP2 DUP2 ADD DUP1 SLOAD PUSH1 0xFF NOT AND SWAP1 SWAP2 OR PUSH2 0xFF00 NOT AND PUSH2 0x100 PUSH1 0xFF DUP6 AND SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 OR SWAP1 SWAP2 SSTORE DUP2 SLOAD PUSH1 0x2 DUP1 SLOAD SWAP2 SWAP3 SWAP1 SWAP2 DUP2 LT PUSH2 0x384 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD DUP1 SLOAD SWAP1 SWAP2 ADD SWAP1 SSTORE JUMPDEST POP POP JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xce PUSH7 0xBB0EE0898D1AFC DUP14 JUMP KECCAK256 0x2d 0xd0 SWAP10 SSTORE DUP10 0x27 PUSH8 0xCFBA6BCF0DDB2318 SLT DUP9 NOT 0x2c GASLIMIT STOP 0x29 ", + "sourceMap": "24:2138:0:-;;;373:167;8:9:-1;5:2;;;30:1;27;20:12;5:2;373:167:0;;;;;;;;;;;;;;;;427:11;:24;;-1:-1:-1;;;;;;427:24:0;441:10;427:24;;;;-1:-1:-1;;;;;468:11:0;461:19;;427:24;373:167;461:19;;;;;;:30;;;;501:32;;;;:9;:32;;:::i;:::-;;373:167;24:2138;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "6080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416635c19a95c8114610066578063609ff1bd146100895780639e7b8d61146100b4578063b3f98adc146100d5575b600080fd5b34801561007257600080fd5b50610087600160a060020a03600435166100f0565b005b34801561009557600080fd5b5061009e610250565b6040805160ff9092168252519081900360200190f35b3480156100c057600080fd5b50610087600160a060020a03600435166102bb565b3480156100e157600080fd5b5061008760ff6004351661031b565b33600090815260016020819052604082209081015490919060ff16156101155761024b565b5b600160a060020a0383811660009081526001602081905260409091200154620100009004161580159061016d5750600160a060020a0383811660009081526001602081905260409091200154620100009004163314155b1561019f57600160a060020a039283166000908152600160208190526040909120015462010000900490921691610116565b600160a060020a0383163314156101b55761024b565b506001818101805460ff1916821775ffffffffffffffffffffffffffffffffffffffff0000191662010000600160a060020a0386169081029190911790915560009081526020829052604090209081015460ff16156102435781546001820154600280549091610100900460ff1690811061022c57fe5b60009182526020909120018054909101905561024b565b815481540181555b505050565b600080805b60025460ff821610156102b6578160028260ff1681548110151561027557fe5b906000526020600020016000015411156102ae576002805460ff831690811061029a57fe5b906000526020600020016000015491508092505b600101610255565b505090565b600054600160a060020a0316331415806102f15750600160a060020a0381166000908152600160208190526040909120015460ff165b156102fb57610318565b600160a060020a0381166000908152600160208190526040909120555b50565b3360009081526001602081905260409091209081015460ff1680610344575060025460ff831610155b1561034e57610397565b6001818101805460ff191690911761ff00191661010060ff85169081029190911790915581546002805491929091811061038457fe5b6000918252602090912001805490910190555b50505600a165627a7a72305820ce66bb0ee0898d1afc8d56202dd09955892767cfba6bcf0ddb23181288192c450029", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x61 JUMPI PUSH4 0xFFFFFFFF PUSH29 0x100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 CALLDATALOAD DIV AND PUSH4 0x5C19A95C DUP2 EQ PUSH2 0x66 JUMPI DUP1 PUSH4 0x609FF1BD EQ PUSH2 0x89 JUMPI DUP1 PUSH4 0x9E7B8D61 EQ PUSH2 0xB4 JUMPI DUP1 PUSH4 0xB3F98ADC EQ PUSH2 0xD5 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x72 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x87 PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB PUSH1 0x4 CALLDATALOAD AND PUSH2 0xF0 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x95 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x9E PUSH2 0x250 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0xFF SWAP1 SWAP3 AND DUP3 MSTORE MLOAD SWAP1 DUP2 SWAP1 SUB PUSH1 0x20 ADD SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xC0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x87 PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB PUSH1 0x4 CALLDATALOAD AND PUSH2 0x2BB JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xE1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x87 PUSH1 0xFF PUSH1 0x4 CALLDATALOAD AND PUSH2 0x31B JUMP JUMPDEST CALLER PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 DUP3 KECCAK256 SWAP1 DUP2 ADD SLOAD SWAP1 SWAP2 SWAP1 PUSH1 0xFF AND ISZERO PUSH2 0x115 JUMPI PUSH2 0x24B JUMP JUMPDEST JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP4 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH3 0x10000 SWAP1 DIV AND ISZERO DUP1 ISZERO SWAP1 PUSH2 0x16D JUMPI POP PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP4 DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH3 0x10000 SWAP1 DIV AND CALLER EQ ISZERO JUMPDEST ISZERO PUSH2 0x19F JUMPI PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB SWAP3 DUP4 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH3 0x10000 SWAP1 DIV SWAP1 SWAP3 AND SWAP2 PUSH2 0x116 JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP4 AND CALLER EQ ISZERO PUSH2 0x1B5 JUMPI PUSH2 0x24B JUMP JUMPDEST POP PUSH1 0x1 DUP2 DUP2 ADD DUP1 SLOAD PUSH1 0xFF NOT AND DUP3 OR PUSH22 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 NOT AND PUSH3 0x10000 PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP7 AND SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 OR SWAP1 SWAP2 SSTORE PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SWAP1 DUP2 ADD SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x243 JUMPI DUP2 SLOAD PUSH1 0x1 DUP3 ADD SLOAD PUSH1 0x2 DUP1 SLOAD SWAP1 SWAP2 PUSH2 0x100 SWAP1 DIV PUSH1 0xFF AND SWAP1 DUP2 LT PUSH2 0x22C JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD DUP1 SLOAD SWAP1 SWAP2 ADD SWAP1 SSTORE PUSH2 0x24B JUMP JUMPDEST DUP2 SLOAD DUP2 SLOAD ADD DUP2 SSTORE JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 JUMPDEST PUSH1 0x2 SLOAD PUSH1 0xFF DUP3 AND LT ISZERO PUSH2 0x2B6 JUMPI DUP2 PUSH1 0x2 DUP3 PUSH1 0xFF AND DUP2 SLOAD DUP2 LT ISZERO ISZERO PUSH2 0x275 JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 ADD SLOAD GT ISZERO PUSH2 0x2AE JUMPI PUSH1 0x2 DUP1 SLOAD PUSH1 0xFF DUP4 AND SWAP1 DUP2 LT PUSH2 0x29A JUMPI INVALID JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 ADD PUSH1 0x0 ADD SLOAD SWAP2 POP DUP1 SWAP3 POP JUMPDEST PUSH1 0x1 ADD PUSH2 0x255 JUMP JUMPDEST POP POP SWAP1 JUMP JUMPDEST PUSH1 0x0 SLOAD PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB AND CALLER EQ ISZERO DUP1 PUSH2 0x2F1 JUMPI POP PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 ADD SLOAD PUSH1 0xFF AND JUMPDEST ISZERO PUSH2 0x2FB JUMPI PUSH2 0x318 JUMP JUMPDEST PUSH1 0x1 PUSH1 0xA0 PUSH1 0x2 EXP SUB DUP2 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 SSTORE JUMPDEST POP JUMP JUMPDEST CALLER PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 DUP2 SWAP1 MSTORE PUSH1 0x40 SWAP1 SWAP2 KECCAK256 SWAP1 DUP2 ADD SLOAD PUSH1 0xFF AND DUP1 PUSH2 0x344 JUMPI POP PUSH1 0x2 SLOAD PUSH1 0xFF DUP4 AND LT ISZERO JUMPDEST ISZERO PUSH2 0x34E JUMPI PUSH2 0x397 JUMP JUMPDEST PUSH1 0x1 DUP2 DUP2 ADD DUP1 SLOAD PUSH1 0xFF NOT AND SWAP1 SWAP2 OR PUSH2 0xFF00 NOT AND PUSH2 0x100 PUSH1 0xFF DUP6 AND SWAP1 DUP2 MUL SWAP2 SWAP1 SWAP2 OR SWAP1 SWAP2 SSTORE DUP2 SLOAD PUSH1 0x2 DUP1 SLOAD SWAP2 SWAP3 SWAP1 SWAP2 DUP2 LT PUSH2 0x384 JUMPI INVALID JUMPDEST PUSH1 0x0 SWAP2 DUP3 MSTORE PUSH1 0x20 SWAP1 SWAP2 KECCAK256 ADD DUP1 SLOAD SWAP1 SWAP2 ADD SWAP1 SSTORE JUMPDEST POP POP JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xce PUSH7 0xBB0EE0898D1AFC DUP14 JUMP KECCAK256 0x2d 0xd0 SWAP10 SSTORE DUP10 0x27 PUSH8 0xCFBA6BCF0DDB2318 SLT DUP9 NOT 0x2c GASLIMIT STOP 0x29 ", + "sourceMap": "24:2138:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;867:577;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;867:577:0;-1:-1:-1;;;;;867:577:0;;;;;;;1796:364;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1796:364:0;;;;;;;;;;;;;;;;;;;;;;;650:164;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;650:164:0;-1:-1:-1;;;;;650:164:0;;;;;1504:286;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1504:286:0;;;;;;;867:577;944:10;914:20;937:18;;;:6;:18;;;;;;;990:12;;;;937:18;;914:20;990:12;;986:25;;;1004:7;;986:25;1020:115;-1:-1:-1;;;;;1027:10:0;;;1058:1;1027:10;;;:6;:10;;;;;;;;:19;;;;;;:33;;;;:70;;-1:-1:-1;;;;;;1064:10:0;;;;;;;:6;:10;;;;;;;;:19;;;;;;1087:10;1064:33;;1027:70;1020:115;;;-1:-1:-1;;;;;1116:10:0;;;;;;;:6;:10;;;;;;;;:19;;;;;;;;;1020:115;;;-1:-1:-1;;;;;1149:16:0;;1155:10;1149:16;1145:29;;;1167:7;;1145:29;-1:-1:-1;1198:4:0;1183:12;;;:19;;-1:-1:-1;;1183:19:0;;;-1:-1:-1;;1212:20:0;;-1:-1:-1;;;;;1212:20:0;;;;;;;;;;;;-1:-1:-1;1269:10:0;;;;;;;;;;1293:16;;;;1183:19;1293:16;1289:148;;;1363:13;;1333:15;;;;1323:9;:26;;:9;;1333:15;;;;;;1323:26;;;;;;;;;;;;;;;:53;;;;;;;1289:148;;;1424:13;;1403:34;;;;;1289:148;867:577;;;:::o;1796:364::-;1848:22;;;1920:234;1948:9;:16;1941:23;;;;1920:234;;;2018:16;1990:9;2000:4;1990:15;;;;;;;;;;;;;;;;;;;:25;;;:44;1986:168;;;2073:9;:15;;;;;;;;;;;;;;;;;;;:25;;;2054:44;;2135:4;2116:23;;1986:168;1966:6;;1920:234;;;1796:364;;;:::o;650:164::-;727:11;;-1:-1:-1;;;;;727:11:0;713:10;:25;;;:50;;-1:-1:-1;;;;;;742:15:0;;;;;;:6;:15;;;;;;;;:21;;;;713:50;709:63;;;765:7;;709:63;-1:-1:-1;;;;;781:15:0;;;;;;806:1;781:15;;;;;;;;:26;650:164;;:::o;1504:286::-;1583:10;1553:20;1576:18;;;:6;:18;;;;;;;;1608:12;;;;;;;:46;;-1:-1:-1;1638:9:0;:16;1624:30;;;;;1608:46;1604:59;;;1656:7;;1604:59;1687:4;1672:12;;;:19;;-1:-1:-1;;1672:19:0;;;;-1:-1:-1;;1701:24:0;1672:19;;1701:24;;;;;;;;;;;;1770:13;;1735:9;:21;;1770:13;;1735:9;;:21;;;;;;;;;;;;;;;:48;;;;;;;1504:286;;;:::o" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "193400", + "executionCost": "infinite", + "totalCost": "infinite" + }, + "external": { + "delegate(address)": "infinite", + "giveRightToVote(address)": "21101", + "vote(uint8)": "41761", + "winningProposal()": "infinite" + } + }, + "legacyAssembly": { + ".code": [{ + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "80" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "40" + }, { + "begin": 24, + "end": 2162, + "name": "MSTORE" + }, { + "begin": 373, + "end": 540, + "name": "CALLVALUE" + }, { + "begin": 8, + "end": 17, + "name": "DUP1" + }, { + "begin": 5, + "end": 7, + "name": "ISZERO" + }, { + "begin": 5, + "end": 7, + "name": "PUSH [tag]", + "value": "1" + }, { + "begin": 5, + "end": 7, + "name": "JUMPI" + }, { + "begin": 30, + "end": 31, + "name": "PUSH", + "value": "0" + }, { + "begin": 27, + "end": 28, + "name": "DUP1" + }, { + "begin": 20, + "end": 32, + "name": "REVERT" + }, { + "begin": 5, + "end": 7, + "name": "tag", + "value": "1" + }, { + "begin": 5, + "end": 7, + "name": "JUMPDEST" + }, { + "begin": 373, + "end": 540, + "name": "POP" + }, { + "begin": 373, + "end": 540, + "name": "PUSH", + "value": "40" + }, { + "begin": 373, + "end": 540, + "name": "MLOAD" + }, { + "begin": 373, + "end": 540, + "name": "PUSH", + "value": "20" + }, { + "begin": 373, + "end": 540, + "name": "DUP1" + }, { + "begin": 373, + "end": 540, + "name": "PUSHSIZE" + }, { + "begin": 373, + "end": 540, + "name": "DUP4" + }, { + "begin": 373, + "end": 540, + "name": "CODECOPY" + }, { + "begin": 373, + "end": 540, + "name": "DUP2" + }, { + "begin": 373, + "end": 540, + "name": "ADD" + }, { + "begin": 373, + "end": 540, + "name": "PUSH", + "value": "40" + }, { + "begin": 373, + "end": 540, + "name": "SWAP1" + }, { + "begin": 373, + "end": 540, + "name": "DUP2" + }, { + "begin": 373, + "end": 540, + "name": "MSTORE" + }, { + "begin": 373, + "end": 540, + "name": "SWAP1" + }, { + "begin": 373, + "end": 540, + "name": "MLOAD" + }, { + "begin": 427, + "end": 438, + "name": "PUSH", + "value": "0" + }, { + "begin": 427, + "end": 451, + "name": "DUP1" + }, { + "begin": 427, + "end": 451, + "name": "SLOAD" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": -1, + "end": -1, + "name": "NOT" + }, { + "begin": 427, + "end": 451, + "name": "AND" + }, { + "begin": 441, + "end": 451, + "name": "CALLER" + }, { + "begin": 427, + "end": 451, + "name": "OR" + }, { + "begin": 427, + "end": 451, + "name": "DUP1" + }, { + "begin": 427, + "end": 451, + "name": "DUP3" + }, { + "begin": 427, + "end": 451, + "name": "SSTORE" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 468, + "end": 479, + "name": "AND" + }, { + "begin": 461, + "end": 480, + "name": "DUP2" + }, { + "begin": 461, + "end": 480, + "name": "MSTORE" + }, { + "begin": 427, + "end": 451, + "name": "PUSH", + "value": "1" + }, { + "begin": 373, + "end": 540, + "name": "PUSH", + "value": "20" + }, { + "begin": 461, + "end": 480, + "name": "DUP2" + }, { + "begin": 461, + "end": 480, + "name": "SWAP1" + }, { + "begin": 461, + "end": 480, + "name": "MSTORE" + }, { + "begin": 461, + "end": 480, + "name": "SWAP3" + }, { + "begin": 461, + "end": 480, + "name": "SWAP1" + }, { + "begin": 461, + "end": 480, + "name": "KECCAK256" + }, { + "begin": 461, + "end": 491, + "name": "SWAP2" + }, { + "begin": 461, + "end": 491, + "name": "SWAP1" + }, { + "begin": 461, + "end": 491, + "name": "SWAP2" + }, { + "begin": 461, + "end": 491, + "name": "SSTORE" + }, { + "begin": 501, + "end": 533, + "name": "PUSH", + "value": "FF" + }, { + "begin": 501, + "end": 533, + "name": "DUP2" + }, { + "begin": 501, + "end": 533, + "name": "AND" + }, { + "begin": 501, + "end": 533, + "name": "PUSH [tag]", + "value": "4" + }, { + "begin": 501, + "end": 510, + "name": "PUSH", + "value": "2" + }, { + "begin": 501, + "end": 533, + "name": "DUP3" + }, { + "begin": 501, + "end": 533, + "name": "PUSH [tag]", + "value": "5" + }, { + "begin": 501, + "end": 533, + "name": "JUMP", + "value": "[in]" + }, { + "begin": 501, + "end": 533, + "name": "tag", + "value": "4" + }, { + "begin": 501, + "end": 533, + "name": "JUMPDEST" + }, { + "begin": 501, + "end": 533, + "name": "POP" + }, { + "begin": 373, + "end": 540, + "name": "POP" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "6" + }, { + "begin": 24, + "end": 2162, + "name": "JUMP" + }, { + "begin": 24, + "end": 2162, + "name": "tag", + "value": "5" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPDEST" + }, { + "begin": 24, + "end": 2162, + "name": "DUP2" + }, { + "begin": 24, + "end": 2162, + "name": "SLOAD" + }, { + "begin": 24, + "end": 2162, + "name": "DUP2" + }, { + "begin": 24, + "end": 2162, + "name": "DUP4" + }, { + "begin": 24, + "end": 2162, + "name": "SSTORE" + }, { + "begin": 24, + "end": 2162, + "name": "DUP2" + }, { + "begin": 24, + "end": 2162, + "name": "DUP2" + }, { + "begin": 24, + "end": 2162, + "name": "GT" + }, { + "begin": 24, + "end": 2162, + "name": "ISZERO" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "8" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPI" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "0" + }, { + "begin": 24, + "end": 2162, + "name": "DUP4" + }, { + "begin": 24, + "end": 2162, + "name": "DUP2" + }, { + "begin": 24, + "end": 2162, + "name": "MSTORE" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "20" + }, { + "begin": 24, + "end": 2162, + "name": "SWAP1" + }, { + "begin": 24, + "end": 2162, + "name": "KECCAK256" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "8" + }, { + "begin": 24, + "end": 2162, + "name": "SWAP2" + }, { + "begin": 24, + "end": 2162, + "name": "DUP2" + }, { + "begin": 24, + "end": 2162, + "name": "ADD" + }, { + "begin": 24, + "end": 2162, + "name": "SWAP1" + }, { + "begin": 24, + "end": 2162, + "name": "DUP4" + }, { + "begin": 24, + "end": 2162, + "name": "ADD" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "9" + }, { + "begin": 24, + "end": 2162, + "name": "JUMP", + "value": "[in]" + }, { + "begin": 24, + "end": 2162, + "name": "tag", + "value": "8" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPDEST" + }, { + "begin": 24, + "end": 2162, + "name": "POP" + }, { + "begin": 24, + "end": 2162, + "name": "POP" + }, { + "begin": 24, + "end": 2162, + "name": "POP" + }, { + "begin": 24, + "end": 2162, + "name": "JUMP", + "value": "[out]" + }, { + "begin": 24, + "end": 2162, + "name": "tag", + "value": "9" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPDEST" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "10" + }, { + "begin": 24, + "end": 2162, + "name": "SWAP2" + }, { + "begin": 24, + "end": 2162, + "name": "SWAP1" + }, { + "begin": 24, + "end": 2162, + "name": "tag", + "value": "11" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPDEST" + }, { + "begin": 24, + "end": 2162, + "name": "DUP1" + }, { + "begin": 24, + "end": 2162, + "name": "DUP3" + }, { + "begin": 24, + "end": 2162, + "name": "GT" + }, { + "begin": 24, + "end": 2162, + "name": "ISZERO" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "12" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPI" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "0" + }, { + "begin": 24, + "end": 2162, + "name": "DUP2" + }, { + "begin": 24, + "end": 2162, + "name": "SSTORE" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "1" + }, { + "begin": 24, + "end": 2162, + "name": "ADD" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "11" + }, { + "begin": 24, + "end": 2162, + "name": "JUMP" + }, { + "begin": 24, + "end": 2162, + "name": "tag", + "value": "12" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPDEST" + }, { + "begin": 24, + "end": 2162, + "name": "POP" + }, { + "begin": 24, + "end": 2162, + "name": "SWAP1" + }, { + "begin": 24, + "end": 2162, + "name": "JUMP" + }, { + "begin": 24, + "end": 2162, + "name": "tag", + "value": "10" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPDEST" + }, { + "begin": 24, + "end": 2162, + "name": "SWAP1" + }, { + "begin": 24, + "end": 2162, + "name": "JUMP", + "value": "[out]" + }, { + "begin": 24, + "end": 2162, + "name": "tag", + "value": "6" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPDEST" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH #[$]", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, { + "begin": 24, + "end": 2162, + "name": "DUP1" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [$]", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "0" + }, { + "begin": 24, + "end": 2162, + "name": "CODECOPY" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "0" + }, { + "begin": 24, + "end": 2162, + "name": "RETURN" + }], + ".data": { + "0": { + ".auxdata": "a165627a7a72305820ce66bb0ee0898d1afc8d56202dd09955892767cfba6bcf0ddb23181288192c450029", + ".code": [{ + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "80" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "40" + }, { + "begin": 24, + "end": 2162, + "name": "MSTORE" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "4" + }, { + "begin": 24, + "end": 2162, + "name": "CALLDATASIZE" + }, { + "begin": 24, + "end": 2162, + "name": "LT" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "1" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPI" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "FFFFFFFF" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "100000000000000000000000000000000000000000000000000000000" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "0" + }, { + "begin": 24, + "end": 2162, + "name": "CALLDATALOAD" + }, { + "begin": 24, + "end": 2162, + "name": "DIV" + }, { + "begin": 24, + "end": 2162, + "name": "AND" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "5C19A95C" + }, { + "begin": 24, + "end": 2162, + "name": "DUP2" + }, { + "begin": 24, + "end": 2162, + "name": "EQ" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "2" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPI" + }, { + "begin": 24, + "end": 2162, + "name": "DUP1" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "609FF1BD" + }, { + "begin": 24, + "end": 2162, + "name": "EQ" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "3" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPI" + }, { + "begin": 24, + "end": 2162, + "name": "DUP1" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "9E7B8D61" + }, { + "begin": 24, + "end": 2162, + "name": "EQ" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "4" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPI" + }, { + "begin": 24, + "end": 2162, + "name": "DUP1" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "B3F98ADC" + }, { + "begin": 24, + "end": 2162, + "name": "EQ" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH [tag]", + "value": "5" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPI" + }, { + "begin": 24, + "end": 2162, + "name": "tag", + "value": "1" + }, { + "begin": 24, + "end": 2162, + "name": "JUMPDEST" + }, { + "begin": 24, + "end": 2162, + "name": "PUSH", + "value": "0" + }, { + "begin": 24, + "end": 2162, + "name": "DUP1" + }, { + "begin": 24, + "end": 2162, + "name": "REVERT" + }, { + "begin": 867, + "end": 1444, + "name": "tag", + "value": "2" + }, { + "begin": 867, + "end": 1444, + "name": "JUMPDEST" + }, { + "begin": 867, + "end": 1444, + "name": "CALLVALUE" + }, { + "begin": 8, + "end": 17, + "name": "DUP1" + }, { + "begin": 5, + "end": 7, + "name": "ISZERO" + }, { + "begin": 5, + "end": 7, + "name": "PUSH [tag]", + "value": "6" + }, { + "begin": 5, + "end": 7, + "name": "JUMPI" + }, { + "begin": 30, + "end": 31, + "name": "PUSH", + "value": "0" + }, { + "begin": 27, + "end": 28, + "name": "DUP1" + }, { + "begin": 20, + "end": 32, + "name": "REVERT" + }, { + "begin": 5, + "end": 7, + "name": "tag", + "value": "6" + }, { + "begin": 5, + "end": 7, + "name": "JUMPDEST" + }, { + "begin": -1, + "end": -1, + "name": "POP" + }, { + "begin": 867, + "end": 1444, + "name": "PUSH [tag]", + "value": "7" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 867, + "end": 1444, + "name": "PUSH", + "value": "4" + }, { + "begin": 867, + "end": 1444, + "name": "CALLDATALOAD" + }, { + "begin": 867, + "end": 1444, + "name": "AND" + }, { + "begin": 867, + "end": 1444, + "name": "PUSH [tag]", + "value": "8" + }, { + "begin": 867, + "end": 1444, + "name": "JUMP" + }, { + "begin": 867, + "end": 1444, + "name": "tag", + "value": "7" + }, { + "begin": 867, + "end": 1444, + "name": "JUMPDEST" + }, { + "begin": 867, + "end": 1444, + "name": "STOP" + }, { + "begin": 1796, + "end": 2160, + "name": "tag", + "value": "3" + }, { + "begin": 1796, + "end": 2160, + "name": "JUMPDEST" + }, { + "begin": 1796, + "end": 2160, + "name": "CALLVALUE" + }, { + "begin": 8, + "end": 17, + "name": "DUP1" + }, { + "begin": 5, + "end": 7, + "name": "ISZERO" + }, { + "begin": 5, + "end": 7, + "name": "PUSH [tag]", + "value": "9" + }, { + "begin": 5, + "end": 7, + "name": "JUMPI" + }, { + "begin": 30, + "end": 31, + "name": "PUSH", + "value": "0" + }, { + "begin": 27, + "end": 28, + "name": "DUP1" + }, { + "begin": 20, + "end": 32, + "name": "REVERT" + }, { + "begin": 5, + "end": 7, + "name": "tag", + "value": "9" + }, { + "begin": 5, + "end": 7, + "name": "JUMPDEST" + }, { + "begin": 1796, + "end": 2160, + "name": "POP" + }, { + "begin": 1796, + "end": 2160, + "name": "PUSH [tag]", + "value": "10" + }, { + "begin": 1796, + "end": 2160, + "name": "PUSH [tag]", + "value": "11" + }, { + "begin": 1796, + "end": 2160, + "name": "JUMP" + }, { + "begin": 1796, + "end": 2160, + "name": "tag", + "value": "10" + }, { + "begin": 1796, + "end": 2160, + "name": "JUMPDEST" + }, { + "begin": 1796, + "end": 2160, + "name": "PUSH", + "value": "40" + }, { + "begin": 1796, + "end": 2160, + "name": "DUP1" + }, { + "begin": 1796, + "end": 2160, + "name": "MLOAD" + }, { + "begin": 1796, + "end": 2160, + "name": "PUSH", + "value": "FF" + }, { + "begin": 1796, + "end": 2160, + "name": "SWAP1" + }, { + "begin": 1796, + "end": 2160, + "name": "SWAP3" + }, { + "begin": 1796, + "end": 2160, + "name": "AND" + }, { + "begin": 1796, + "end": 2160, + "name": "DUP3" + }, { + "begin": 1796, + "end": 2160, + "name": "MSTORE" + }, { + "begin": 1796, + "end": 2160, + "name": "MLOAD" + }, { + "begin": 1796, + "end": 2160, + "name": "SWAP1" + }, { + "begin": 1796, + "end": 2160, + "name": "DUP2" + }, { + "begin": 1796, + "end": 2160, + "name": "SWAP1" + }, { + "begin": 1796, + "end": 2160, + "name": "SUB" + }, { + "begin": 1796, + "end": 2160, + "name": "PUSH", + "value": "20" + }, { + "begin": 1796, + "end": 2160, + "name": "ADD" + }, { + "begin": 1796, + "end": 2160, + "name": "SWAP1" + }, { + "begin": 1796, + "end": 2160, + "name": "RETURN" + }, { + "begin": 650, + "end": 814, + "name": "tag", + "value": "4" + }, { + "begin": 650, + "end": 814, + "name": "JUMPDEST" + }, { + "begin": 650, + "end": 814, + "name": "CALLVALUE" + }, { + "begin": 8, + "end": 17, + "name": "DUP1" + }, { + "begin": 5, + "end": 7, + "name": "ISZERO" + }, { + "begin": 5, + "end": 7, + "name": "PUSH [tag]", + "value": "12" + }, { + "begin": 5, + "end": 7, + "name": "JUMPI" + }, { + "begin": 30, + "end": 31, + "name": "PUSH", + "value": "0" + }, { + "begin": 27, + "end": 28, + "name": "DUP1" + }, { + "begin": 20, + "end": 32, + "name": "REVERT" + }, { + "begin": 5, + "end": 7, + "name": "tag", + "value": "12" + }, { + "begin": 5, + "end": 7, + "name": "JUMPDEST" + }, { + "begin": -1, + "end": -1, + "name": "POP" + }, { + "begin": 650, + "end": 814, + "name": "PUSH [tag]", + "value": "7" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 650, + "end": 814, + "name": "PUSH", + "value": "4" + }, { + "begin": 650, + "end": 814, + "name": "CALLDATALOAD" + }, { + "begin": 650, + "end": 814, + "name": "AND" + }, { + "begin": 650, + "end": 814, + "name": "PUSH [tag]", + "value": "14" + }, { + "begin": 650, + "end": 814, + "name": "JUMP" + }, { + "begin": 1504, + "end": 1790, + "name": "tag", + "value": "5" + }, { + "begin": 1504, + "end": 1790, + "name": "JUMPDEST" + }, { + "begin": 1504, + "end": 1790, + "name": "CALLVALUE" + }, { + "begin": 8, + "end": 17, + "name": "DUP1" + }, { + "begin": 5, + "end": 7, + "name": "ISZERO" + }, { + "begin": 5, + "end": 7, + "name": "PUSH [tag]", + "value": "15" + }, { + "begin": 5, + "end": 7, + "name": "JUMPI" + }, { + "begin": 30, + "end": 31, + "name": "PUSH", + "value": "0" + }, { + "begin": 27, + "end": 28, + "name": "DUP1" + }, { + "begin": 20, + "end": 32, + "name": "REVERT" + }, { + "begin": 5, + "end": 7, + "name": "tag", + "value": "15" + }, { + "begin": 5, + "end": 7, + "name": "JUMPDEST" + }, { + "begin": -1, + "end": -1, + "name": "POP" + }, { + "begin": 1504, + "end": 1790, + "name": "PUSH [tag]", + "value": "7" + }, { + "begin": 1504, + "end": 1790, + "name": "PUSH", + "value": "FF" + }, { + "begin": 1504, + "end": 1790, + "name": "PUSH", + "value": "4" + }, { + "begin": 1504, + "end": 1790, + "name": "CALLDATALOAD" + }, { + "begin": 1504, + "end": 1790, + "name": "AND" + }, { + "begin": 1504, + "end": 1790, + "name": "PUSH [tag]", + "value": "17" + }, { + "begin": 1504, + "end": 1790, + "name": "JUMP" + }, { + "begin": 867, + "end": 1444, + "name": "tag", + "value": "8" + }, { + "begin": 867, + "end": 1444, + "name": "JUMPDEST" + }, { + "begin": 944, + "end": 954, + "name": "CALLER" + }, { + "begin": 914, + "end": 934, + "name": "PUSH", + "value": "0" + }, { + "begin": 937, + "end": 955, + "name": "SWAP1" + }, { + "begin": 937, + "end": 955, + "name": "DUP2" + }, { + "begin": 937, + "end": 955, + "name": "MSTORE" + }, { + "begin": 937, + "end": 943, + "name": "PUSH", + "value": "1" + }, { + "begin": 937, + "end": 955, + "name": "PUSH", + "value": "20" + }, { + "begin": 937, + "end": 955, + "name": "DUP2" + }, { + "begin": 937, + "end": 955, + "name": "SWAP1" + }, { + "begin": 937, + "end": 955, + "name": "MSTORE" + }, { + "begin": 937, + "end": 955, + "name": "PUSH", + "value": "40" + }, { + "begin": 937, + "end": 955, + "name": "DUP3" + }, { + "begin": 937, + "end": 955, + "name": "KECCAK256" + }, { + "begin": 990, + "end": 1002, + "name": "SWAP1" + }, { + "begin": 990, + "end": 1002, + "name": "DUP2" + }, { + "begin": 990, + "end": 1002, + "name": "ADD" + }, { + "begin": 990, + "end": 1002, + "name": "SLOAD" + }, { + "begin": 937, + "end": 955, + "name": "SWAP1" + }, { + "begin": 937, + "end": 955, + "name": "SWAP2" + }, { + "begin": 914, + "end": 934, + "name": "SWAP1" + }, { + "begin": 990, + "end": 1002, + "name": "PUSH", + "value": "FF" + }, { + "begin": 990, + "end": 1002, + "name": "AND" + }, { + "begin": 986, + "end": 1011, + "name": "ISZERO" + }, { + "begin": 986, + "end": 1011, + "name": "PUSH [tag]", + "value": "19" + }, { + "begin": 986, + "end": 1011, + "name": "JUMPI" + }, { + "begin": 1004, + "end": 1011, + "name": "PUSH [tag]", + "value": "27" + }, { + "begin": 1004, + "end": 1011, + "name": "JUMP" + }, { + "begin": 986, + "end": 1011, + "name": "tag", + "value": "19" + }, { + "begin": 986, + "end": 1011, + "name": "JUMPDEST" + }, { + "begin": 1020, + "end": 1135, + "name": "tag", + "value": "20" + }, { + "begin": 1020, + "end": 1135, + "name": "JUMPDEST" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 1027, + "end": 1037, + "name": "DUP4" + }, { + "begin": 1027, + "end": 1037, + "name": "DUP2" + }, { + "begin": 1027, + "end": 1037, + "name": "AND" + }, { + "begin": 1058, + "end": 1059, + "name": "PUSH", + "value": "0" + }, { + "begin": 1027, + "end": 1037, + "name": "SWAP1" + }, { + "begin": 1027, + "end": 1037, + "name": "DUP2" + }, { + "begin": 1027, + "end": 1037, + "name": "MSTORE" + }, { + "begin": 1027, + "end": 1033, + "name": "PUSH", + "value": "1" + }, { + "begin": 1027, + "end": 1037, + "name": "PUSH", + "value": "20" + }, { + "begin": 1027, + "end": 1037, + "name": "DUP2" + }, { + "begin": 1027, + "end": 1037, + "name": "SWAP1" + }, { + "begin": 1027, + "end": 1037, + "name": "MSTORE" + }, { + "begin": 1027, + "end": 1037, + "name": "PUSH", + "value": "40" + }, { + "begin": 1027, + "end": 1037, + "name": "SWAP1" + }, { + "begin": 1027, + "end": 1037, + "name": "SWAP2" + }, { + "begin": 1027, + "end": 1037, + "name": "KECCAK256" + }, { + "begin": 1027, + "end": 1046, + "name": "ADD" + }, { + "begin": 1027, + "end": 1046, + "name": "SLOAD" + }, { + "begin": 1027, + "end": 1046, + "name": "PUSH", + "value": "10000" + }, { + "begin": 1027, + "end": 1046, + "name": "SWAP1" + }, { + "begin": 1027, + "end": 1046, + "name": "DIV" + }, { + "begin": 1027, + "end": 1046, + "name": "AND" + }, { + "begin": 1027, + "end": 1060, + "name": "ISZERO" + }, { + "begin": 1027, + "end": 1060, + "name": "DUP1" + }, { + "begin": 1027, + "end": 1060, + "name": "ISZERO" + }, { + "begin": 1027, + "end": 1060, + "name": "SWAP1" + }, { + "begin": 1027, + "end": 1097, + "name": "PUSH [tag]", + "value": "22" + }, { + "begin": 1027, + "end": 1097, + "name": "JUMPI" + }, { + "begin": -1, + "end": -1, + "name": "POP" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 1064, + "end": 1074, + "name": "DUP4" + }, { + "begin": 1064, + "end": 1074, + "name": "DUP2" + }, { + "begin": 1064, + "end": 1074, + "name": "AND" + }, { + "begin": 1064, + "end": 1074, + "name": "PUSH", + "value": "0" + }, { + "begin": 1064, + "end": 1074, + "name": "SWAP1" + }, { + "begin": 1064, + "end": 1074, + "name": "DUP2" + }, { + "begin": 1064, + "end": 1074, + "name": "MSTORE" + }, { + "begin": 1064, + "end": 1070, + "name": "PUSH", + "value": "1" + }, { + "begin": 1064, + "end": 1074, + "name": "PUSH", + "value": "20" + }, { + "begin": 1064, + "end": 1074, + "name": "DUP2" + }, { + "begin": 1064, + "end": 1074, + "name": "SWAP1" + }, { + "begin": 1064, + "end": 1074, + "name": "MSTORE" + }, { + "begin": 1064, + "end": 1074, + "name": "PUSH", + "value": "40" + }, { + "begin": 1064, + "end": 1074, + "name": "SWAP1" + }, { + "begin": 1064, + "end": 1074, + "name": "SWAP2" + }, { + "begin": 1064, + "end": 1074, + "name": "KECCAK256" + }, { + "begin": 1064, + "end": 1083, + "name": "ADD" + }, { + "begin": 1064, + "end": 1083, + "name": "SLOAD" + }, { + "begin": 1064, + "end": 1083, + "name": "PUSH", + "value": "10000" + }, { + "begin": 1064, + "end": 1083, + "name": "SWAP1" + }, { + "begin": 1064, + "end": 1083, + "name": "DIV" + }, { + "begin": 1064, + "end": 1083, + "name": "AND" + }, { + "begin": 1087, + "end": 1097, + "name": "CALLER" + }, { + "begin": 1064, + "end": 1097, + "name": "EQ" + }, { + "begin": 1064, + "end": 1097, + "name": "ISZERO" + }, { + "begin": 1027, + "end": 1097, + "name": "tag", + "value": "22" + }, { + "begin": 1027, + "end": 1097, + "name": "JUMPDEST" + }, { + "begin": 1020, + "end": 1135, + "name": "ISZERO" + }, { + "begin": 1020, + "end": 1135, + "name": "PUSH [tag]", + "value": "21" + }, { + "begin": 1020, + "end": 1135, + "name": "JUMPI" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 1116, + "end": 1126, + "name": "SWAP3" + }, { + "begin": 1116, + "end": 1126, + "name": "DUP4" + }, { + "begin": 1116, + "end": 1126, + "name": "AND" + }, { + "begin": 1116, + "end": 1126, + "name": "PUSH", + "value": "0" + }, { + "begin": 1116, + "end": 1126, + "name": "SWAP1" + }, { + "begin": 1116, + "end": 1126, + "name": "DUP2" + }, { + "begin": 1116, + "end": 1126, + "name": "MSTORE" + }, { + "begin": 1116, + "end": 1122, + "name": "PUSH", + "value": "1" + }, { + "begin": 1116, + "end": 1126, + "name": "PUSH", + "value": "20" + }, { + "begin": 1116, + "end": 1126, + "name": "DUP2" + }, { + "begin": 1116, + "end": 1126, + "name": "SWAP1" + }, { + "begin": 1116, + "end": 1126, + "name": "MSTORE" + }, { + "begin": 1116, + "end": 1126, + "name": "PUSH", + "value": "40" + }, { + "begin": 1116, + "end": 1126, + "name": "SWAP1" + }, { + "begin": 1116, + "end": 1126, + "name": "SWAP2" + }, { + "begin": 1116, + "end": 1126, + "name": "KECCAK256" + }, { + "begin": 1116, + "end": 1135, + "name": "ADD" + }, { + "begin": 1116, + "end": 1135, + "name": "SLOAD" + }, { + "begin": 1116, + "end": 1135, + "name": "PUSH", + "value": "10000" + }, { + "begin": 1116, + "end": 1135, + "name": "SWAP1" + }, { + "begin": 1116, + "end": 1135, + "name": "DIV" + }, { + "begin": 1116, + "end": 1135, + "name": "SWAP1" + }, { + "begin": 1116, + "end": 1135, + "name": "SWAP3" + }, { + "begin": 1116, + "end": 1135, + "name": "AND" + }, { + "begin": 1116, + "end": 1135, + "name": "SWAP2" + }, { + "begin": 1020, + "end": 1135, + "name": "PUSH [tag]", + "value": "20" + }, { + "begin": 1020, + "end": 1135, + "name": "JUMP" + }, { + "begin": 1020, + "end": 1135, + "name": "tag", + "value": "21" + }, { + "begin": 1020, + "end": 1135, + "name": "JUMPDEST" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 1149, + "end": 1165, + "name": "DUP4" + }, { + "begin": 1149, + "end": 1165, + "name": "AND" + }, { + "begin": 1155, + "end": 1165, + "name": "CALLER" + }, { + "begin": 1149, + "end": 1165, + "name": "EQ" + }, { + "begin": 1145, + "end": 1174, + "name": "ISZERO" + }, { + "begin": 1145, + "end": 1174, + "name": "PUSH [tag]", + "value": "23" + }, { + "begin": 1145, + "end": 1174, + "name": "JUMPI" + }, { + "begin": 1167, + "end": 1174, + "name": "PUSH [tag]", + "value": "27" + }, { + "begin": 1167, + "end": 1174, + "name": "JUMP" + }, { + "begin": 1145, + "end": 1174, + "name": "tag", + "value": "23" + }, { + "begin": 1145, + "end": 1174, + "name": "JUMPDEST" + }, { + "begin": -1, + "end": -1, + "name": "POP" + }, { + "begin": 1198, + "end": 1202, + "name": "PUSH", + "value": "1" + }, { + "begin": 1183, + "end": 1195, + "name": "DUP2" + }, { + "begin": 1183, + "end": 1195, + "name": "DUP2" + }, { + "begin": 1183, + "end": 1195, + "name": "ADD" + }, { + "begin": 1183, + "end": 1202, + "name": "DUP1" + }, { + "begin": 1183, + "end": 1202, + "name": "SLOAD" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "FF" + }, { + "begin": -1, + "end": -1, + "name": "NOT" + }, { + "begin": 1183, + "end": 1202, + "name": "AND" + }, { + "begin": 1183, + "end": 1202, + "name": "DUP3" + }, { + "begin": 1183, + "end": 1202, + "name": "OR" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000" + }, { + "begin": -1, + "end": -1, + "name": "NOT" + }, { + "begin": 1212, + "end": 1232, + "name": "AND" + }, { + "begin": 1212, + "end": 1232, + "name": "PUSH", + "value": "10000" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 1212, + "end": 1232, + "name": "DUP7" + }, { + "begin": 1212, + "end": 1232, + "name": "AND" + }, { + "begin": 1212, + "end": 1232, + "name": "SWAP1" + }, { + "begin": 1212, + "end": 1232, + "name": "DUP2" + }, { + "begin": 1212, + "end": 1232, + "name": "MUL" + }, { + "begin": 1212, + "end": 1232, + "name": "SWAP2" + }, { + "begin": 1212, + "end": 1232, + "name": "SWAP1" + }, { + "begin": 1212, + "end": 1232, + "name": "SWAP2" + }, { + "begin": 1212, + "end": 1232, + "name": "OR" + }, { + "begin": 1212, + "end": 1232, + "name": "SWAP1" + }, { + "begin": 1212, + "end": 1232, + "name": "SWAP2" + }, { + "begin": 1212, + "end": 1232, + "name": "SSTORE" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "0" + }, { + "begin": 1269, + "end": 1279, + "name": "SWAP1" + }, { + "begin": 1269, + "end": 1279, + "name": "DUP2" + }, { + "begin": 1269, + "end": 1279, + "name": "MSTORE" + }, { + "begin": 1269, + "end": 1279, + "name": "PUSH", + "value": "20" + }, { + "begin": 1269, + "end": 1279, + "name": "DUP3" + }, { + "begin": 1269, + "end": 1279, + "name": "SWAP1" + }, { + "begin": 1269, + "end": 1279, + "name": "MSTORE" + }, { + "begin": 1269, + "end": 1279, + "name": "PUSH", + "value": "40" + }, { + "begin": 1269, + "end": 1279, + "name": "SWAP1" + }, { + "begin": 1269, + "end": 1279, + "name": "KECCAK256" + }, { + "begin": 1293, + "end": 1309, + "name": "SWAP1" + }, { + "begin": 1293, + "end": 1309, + "name": "DUP2" + }, { + "begin": 1293, + "end": 1309, + "name": "ADD" + }, { + "begin": 1293, + "end": 1309, + "name": "SLOAD" + }, { + "begin": 1183, + "end": 1202, + "name": "PUSH", + "value": "FF" + }, { + "begin": 1293, + "end": 1309, + "name": "AND" + }, { + "begin": 1289, + "end": 1437, + "name": "ISZERO" + }, { + "begin": 1289, + "end": 1437, + "name": "PUSH [tag]", + "value": "24" + }, { + "begin": 1289, + "end": 1437, + "name": "JUMPI" + }, { + "begin": 1363, + "end": 1376, + "name": "DUP2" + }, { + "begin": 1363, + "end": 1376, + "name": "SLOAD" + }, { + "begin": 1333, + "end": 1348, + "name": "PUSH", + "value": "1" + }, { + "begin": 1333, + "end": 1348, + "name": "DUP3" + }, { + "begin": 1333, + "end": 1348, + "name": "ADD" + }, { + "begin": 1333, + "end": 1348, + "name": "SLOAD" + }, { + "begin": 1323, + "end": 1332, + "name": "PUSH", + "value": "2" + }, { + "begin": 1323, + "end": 1349, + "name": "DUP1" + }, { + "begin": 1323, + "end": 1349, + "name": "SLOAD" + }, { + "begin": 1323, + "end": 1332, + "name": "SWAP1" + }, { + "begin": 1323, + "end": 1332, + "name": "SWAP2" + }, { + "begin": 1333, + "end": 1348, + "name": "PUSH", + "value": "100" + }, { + "begin": 1333, + "end": 1348, + "name": "SWAP1" + }, { + "begin": 1333, + "end": 1348, + "name": "DIV" + }, { + "begin": 1333, + "end": 1348, + "name": "PUSH", + "value": "FF" + }, { + "begin": 1333, + "end": 1348, + "name": "AND" + }, { + "begin": 1333, + "end": 1348, + "name": "SWAP1" + }, { + "begin": 1323, + "end": 1349, + "name": "DUP2" + }, { + "begin": 1323, + "end": 1349, + "name": "LT" + }, { + "begin": 1323, + "end": 1349, + "name": "PUSH [tag]", + "value": "25" + }, { + "begin": 1323, + "end": 1349, + "name": "JUMPI" + }, { + "begin": 1323, + "end": 1349, + "name": "INVALID" + }, { + "begin": 1323, + "end": 1349, + "name": "tag", + "value": "25" + }, { + "begin": 1323, + "end": 1349, + "name": "JUMPDEST" + }, { + "begin": 1323, + "end": 1349, + "name": "PUSH", + "value": "0" + }, { + "begin": 1323, + "end": 1349, + "name": "SWAP2" + }, { + "begin": 1323, + "end": 1349, + "name": "DUP3" + }, { + "begin": 1323, + "end": 1349, + "name": "MSTORE" + }, { + "begin": 1323, + "end": 1349, + "name": "PUSH", + "value": "20" + }, { + "begin": 1323, + "end": 1349, + "name": "SWAP1" + }, { + "begin": 1323, + "end": 1349, + "name": "SWAP2" + }, { + "begin": 1323, + "end": 1349, + "name": "KECCAK256" + }, { + "begin": 1323, + "end": 1349, + "name": "ADD" + }, { + "begin": 1323, + "end": 1376, + "name": "DUP1" + }, { + "begin": 1323, + "end": 1376, + "name": "SLOAD" + }, { + "begin": 1323, + "end": 1376, + "name": "SWAP1" + }, { + "begin": 1323, + "end": 1376, + "name": "SWAP2" + }, { + "begin": 1323, + "end": 1376, + "name": "ADD" + }, { + "begin": 1323, + "end": 1376, + "name": "SWAP1" + }, { + "begin": 1323, + "end": 1376, + "name": "SSTORE" + }, { + "begin": 1289, + "end": 1437, + "name": "PUSH [tag]", + "value": "27" + }, { + "begin": 1289, + "end": 1437, + "name": "JUMP" + }, { + "begin": 1289, + "end": 1437, + "name": "tag", + "value": "24" + }, { + "begin": 1289, + "end": 1437, + "name": "JUMPDEST" + }, { + "begin": 1424, + "end": 1437, + "name": "DUP2" + }, { + "begin": 1424, + "end": 1437, + "name": "SLOAD" + }, { + "begin": 1403, + "end": 1437, + "name": "DUP2" + }, { + "begin": 1403, + "end": 1437, + "name": "SLOAD" + }, { + "begin": 1403, + "end": 1437, + "name": "ADD" + }, { + "begin": 1403, + "end": 1437, + "name": "DUP2" + }, { + "begin": 1403, + "end": 1437, + "name": "SSTORE" + }, { + "begin": 1289, + "end": 1437, + "name": "tag", + "value": "27" + }, { + "begin": 1289, + "end": 1437, + "name": "JUMPDEST" + }, { + "begin": 867, + "end": 1444, + "name": "POP" + }, { + "begin": 867, + "end": 1444, + "name": "POP" + }, { + "begin": 867, + "end": 1444, + "name": "POP" + }, { + "begin": 867, + "end": 1444, + "name": "JUMP", + "value": "[out]" + }, { + "begin": 1796, + "end": 2160, + "name": "tag", + "value": "11" + }, { + "begin": 1796, + "end": 2160, + "name": "JUMPDEST" + }, { + "begin": 1848, + "end": 1870, + "name": "PUSH", + "value": "0" + }, { + "begin": 1848, + "end": 1870, + "name": "DUP1" + }, { + "begin": 1848, + "end": 1870, + "name": "DUP1" + }, { + "begin": 1920, + "end": 2154, + "name": "tag", + "value": "29" + }, { + "begin": 1920, + "end": 2154, + "name": "JUMPDEST" + }, { + "begin": 1948, + "end": 1957, + "name": "PUSH", + "value": "2" + }, { + "begin": 1948, + "end": 1964, + "name": "SLOAD" + }, { + "begin": 1941, + "end": 1964, + "name": "PUSH", + "value": "FF" + }, { + "begin": 1941, + "end": 1964, + "name": "DUP3" + }, { + "begin": 1941, + "end": 1964, + "name": "AND" + }, { + "begin": 1941, + "end": 1964, + "name": "LT" + }, { + "begin": 1920, + "end": 2154, + "name": "ISZERO" + }, { + "begin": 1920, + "end": 2154, + "name": "PUSH [tag]", + "value": "30" + }, { + "begin": 1920, + "end": 2154, + "name": "JUMPI" + }, { + "begin": 2018, + "end": 2034, + "name": "DUP2" + }, { + "begin": 1990, + "end": 1999, + "name": "PUSH", + "value": "2" + }, { + "begin": 2000, + "end": 2004, + "name": "DUP3" + }, { + "begin": 1990, + "end": 2005, + "name": "PUSH", + "value": "FF" + }, { + "begin": 1990, + "end": 2005, + "name": "AND" + }, { + "begin": 1990, + "end": 2005, + "name": "DUP2" + }, { + "begin": 1990, + "end": 2005, + "name": "SLOAD" + }, { + "begin": 1990, + "end": 2005, + "name": "DUP2" + }, { + "begin": 1990, + "end": 2005, + "name": "LT" + }, { + "begin": 1990, + "end": 2005, + "name": "ISZERO" + }, { + "begin": 1990, + "end": 2005, + "name": "ISZERO" + }, { + "begin": 1990, + "end": 2005, + "name": "PUSH [tag]", + "value": "32" + }, { + "begin": 1990, + "end": 2005, + "name": "JUMPI" + }, { + "begin": 1990, + "end": 2005, + "name": "INVALID" + }, { + "begin": 1990, + "end": 2005, + "name": "tag", + "value": "32" + }, { + "begin": 1990, + "end": 2005, + "name": "JUMPDEST" + }, { + "begin": 1990, + "end": 2005, + "name": "SWAP1" + }, { + "begin": 1990, + "end": 2005, + "name": "PUSH", + "value": "0" + }, { + "begin": 1990, + "end": 2005, + "name": "MSTORE" + }, { + "begin": 1990, + "end": 2005, + "name": "PUSH", + "value": "20" + }, { + "begin": 1990, + "end": 2005, + "name": "PUSH", + "value": "0" + }, { + "begin": 1990, + "end": 2005, + "name": "KECCAK256" + }, { + "begin": 1990, + "end": 2005, + "name": "ADD" + }, { + "begin": 1990, + "end": 2015, + "name": "PUSH", + "value": "0" + }, { + "begin": 1990, + "end": 2015, + "name": "ADD" + }, { + "begin": 1990, + "end": 2015, + "name": "SLOAD" + }, { + "begin": 1990, + "end": 2034, + "name": "GT" + }, { + "begin": 1986, + "end": 2154, + "name": "ISZERO" + }, { + "begin": 1986, + "end": 2154, + "name": "PUSH [tag]", + "value": "34" + }, { + "begin": 1986, + "end": 2154, + "name": "JUMPI" + }, { + "begin": 2073, + "end": 2082, + "name": "PUSH", + "value": "2" + }, { + "begin": 2073, + "end": 2088, + "name": "DUP1" + }, { + "begin": 2073, + "end": 2088, + "name": "SLOAD" + }, { + "begin": 2073, + "end": 2088, + "name": "PUSH", + "value": "FF" + }, { + "begin": 2073, + "end": 2088, + "name": "DUP4" + }, { + "begin": 2073, + "end": 2088, + "name": "AND" + }, { + "begin": 2073, + "end": 2088, + "name": "SWAP1" + }, { + "begin": 2073, + "end": 2088, + "name": "DUP2" + }, { + "begin": 2073, + "end": 2088, + "name": "LT" + }, { + "begin": 2073, + "end": 2088, + "name": "PUSH [tag]", + "value": "35" + }, { + "begin": 2073, + "end": 2088, + "name": "JUMPI" + }, { + "begin": 2073, + "end": 2088, + "name": "INVALID" + }, { + "begin": 2073, + "end": 2088, + "name": "tag", + "value": "35" + }, { + "begin": 2073, + "end": 2088, + "name": "JUMPDEST" + }, { + "begin": 2073, + "end": 2088, + "name": "SWAP1" + }, { + "begin": 2073, + "end": 2088, + "name": "PUSH", + "value": "0" + }, { + "begin": 2073, + "end": 2088, + "name": "MSTORE" + }, { + "begin": 2073, + "end": 2088, + "name": "PUSH", + "value": "20" + }, { + "begin": 2073, + "end": 2088, + "name": "PUSH", + "value": "0" + }, { + "begin": 2073, + "end": 2088, + "name": "KECCAK256" + }, { + "begin": 2073, + "end": 2088, + "name": "ADD" + }, { + "begin": 2073, + "end": 2098, + "name": "PUSH", + "value": "0" + }, { + "begin": 2073, + "end": 2098, + "name": "ADD" + }, { + "begin": 2073, + "end": 2098, + "name": "SLOAD" + }, { + "begin": 2054, + "end": 2098, + "name": "SWAP2" + }, { + "begin": 2054, + "end": 2098, + "name": "POP" + }, { + "begin": 2135, + "end": 2139, + "name": "DUP1" + }, { + "begin": 2116, + "end": 2139, + "name": "SWAP3" + }, { + "begin": 2116, + "end": 2139, + "name": "POP" + }, { + "begin": 1986, + "end": 2154, + "name": "tag", + "value": "34" + }, { + "begin": 1986, + "end": 2154, + "name": "JUMPDEST" + }, { + "begin": 1966, + "end": 1972, + "name": "PUSH", + "value": "1" + }, { + "begin": 1966, + "end": 1972, + "name": "ADD" + }, { + "begin": 1920, + "end": 2154, + "name": "PUSH [tag]", + "value": "29" + }, { + "begin": 1920, + "end": 2154, + "name": "JUMP" + }, { + "begin": 1920, + "end": 2154, + "name": "tag", + "value": "30" + }, { + "begin": 1920, + "end": 2154, + "name": "JUMPDEST" + }, { + "begin": 1796, + "end": 2160, + "name": "POP" + }, { + "begin": 1796, + "end": 2160, + "name": "POP" + }, { + "begin": 1796, + "end": 2160, + "name": "SWAP1" + }, { + "begin": 1796, + "end": 2160, + "name": "JUMP", + "value": "[out]" + }, { + "begin": 650, + "end": 814, + "name": "tag", + "value": "14" + }, { + "begin": 650, + "end": 814, + "name": "JUMPDEST" + }, { + "begin": 727, + "end": 738, + "name": "PUSH", + "value": "0" + }, { + "begin": 727, + "end": 738, + "name": "SLOAD" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 727, + "end": 738, + "name": "AND" + }, { + "begin": 713, + "end": 723, + "name": "CALLER" + }, { + "begin": 713, + "end": 738, + "name": "EQ" + }, { + "begin": 713, + "end": 738, + "name": "ISZERO" + }, { + "begin": 713, + "end": 738, + "name": "DUP1" + }, { + "begin": 713, + "end": 763, + "name": "PUSH [tag]", + "value": "38" + }, { + "begin": 713, + "end": 763, + "name": "JUMPI" + }, { + "begin": -1, + "end": -1, + "name": "POP" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 742, + "end": 757, + "name": "DUP2" + }, { + "begin": 742, + "end": 757, + "name": "AND" + }, { + "begin": 742, + "end": 757, + "name": "PUSH", + "value": "0" + }, { + "begin": 742, + "end": 757, + "name": "SWAP1" + }, { + "begin": 742, + "end": 757, + "name": "DUP2" + }, { + "begin": 742, + "end": 757, + "name": "MSTORE" + }, { + "begin": 742, + "end": 748, + "name": "PUSH", + "value": "1" + }, { + "begin": 742, + "end": 757, + "name": "PUSH", + "value": "20" + }, { + "begin": 742, + "end": 757, + "name": "DUP2" + }, { + "begin": 742, + "end": 757, + "name": "SWAP1" + }, { + "begin": 742, + "end": 757, + "name": "MSTORE" + }, { + "begin": 742, + "end": 757, + "name": "PUSH", + "value": "40" + }, { + "begin": 742, + "end": 757, + "name": "SWAP1" + }, { + "begin": 742, + "end": 757, + "name": "SWAP2" + }, { + "begin": 742, + "end": 757, + "name": "KECCAK256" + }, { + "begin": 742, + "end": 763, + "name": "ADD" + }, { + "begin": 742, + "end": 763, + "name": "SLOAD" + }, { + "begin": 742, + "end": 763, + "name": "PUSH", + "value": "FF" + }, { + "begin": 742, + "end": 763, + "name": "AND" + }, { + "begin": 713, + "end": 763, + "name": "tag", + "value": "38" + }, { + "begin": 713, + "end": 763, + "name": "JUMPDEST" + }, { + "begin": 709, + "end": 772, + "name": "ISZERO" + }, { + "begin": 709, + "end": 772, + "name": "PUSH [tag]", + "value": "39" + }, { + "begin": 709, + "end": 772, + "name": "JUMPI" + }, { + "begin": 765, + "end": 772, + "name": "PUSH [tag]", + "value": "37" + }, { + "begin": 765, + "end": 772, + "name": "JUMP" + }, { + "begin": 709, + "end": 772, + "name": "tag", + "value": "39" + }, { + "begin": 709, + "end": 772, + "name": "JUMPDEST" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "1" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "A0" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "2" + }, { + "begin": -1, + "end": -1, + "name": "EXP" + }, { + "begin": -1, + "end": -1, + "name": "SUB" + }, { + "begin": 781, + "end": 796, + "name": "DUP2" + }, { + "begin": 781, + "end": 796, + "name": "AND" + }, { + "begin": 781, + "end": 796, + "name": "PUSH", + "value": "0" + }, { + "begin": 781, + "end": 796, + "name": "SWAP1" + }, { + "begin": 781, + "end": 796, + "name": "DUP2" + }, { + "begin": 781, + "end": 796, + "name": "MSTORE" + }, { + "begin": 806, + "end": 807, + "name": "PUSH", + "value": "1" + }, { + "begin": 781, + "end": 796, + "name": "PUSH", + "value": "20" + }, { + "begin": 781, + "end": 796, + "name": "DUP2" + }, { + "begin": 781, + "end": 796, + "name": "SWAP1" + }, { + "begin": 781, + "end": 796, + "name": "MSTORE" + }, { + "begin": 781, + "end": 796, + "name": "PUSH", + "value": "40" + }, { + "begin": 781, + "end": 796, + "name": "SWAP1" + }, { + "begin": 781, + "end": 796, + "name": "SWAP2" + }, { + "begin": 781, + "end": 796, + "name": "KECCAK256" + }, { + "begin": 781, + "end": 807, + "name": "SSTORE" + }, { + "begin": 650, + "end": 814, + "name": "tag", + "value": "37" + }, { + "begin": 650, + "end": 814, + "name": "JUMPDEST" + }, { + "begin": 650, + "end": 814, + "name": "POP" + }, { + "begin": 650, + "end": 814, + "name": "JUMP", + "value": "[out]" + }, { + "begin": 1504, + "end": 1790, + "name": "tag", + "value": "17" + }, { + "begin": 1504, + "end": 1790, + "name": "JUMPDEST" + }, { + "begin": 1583, + "end": 1593, + "name": "CALLER" + }, { + "begin": 1553, + "end": 1573, + "name": "PUSH", + "value": "0" + }, { + "begin": 1576, + "end": 1594, + "name": "SWAP1" + }, { + "begin": 1576, + "end": 1594, + "name": "DUP2" + }, { + "begin": 1576, + "end": 1594, + "name": "MSTORE" + }, { + "begin": 1576, + "end": 1582, + "name": "PUSH", + "value": "1" + }, { + "begin": 1576, + "end": 1594, + "name": "PUSH", + "value": "20" + }, { + "begin": 1576, + "end": 1594, + "name": "DUP2" + }, { + "begin": 1576, + "end": 1594, + "name": "SWAP1" + }, { + "begin": 1576, + "end": 1594, + "name": "MSTORE" + }, { + "begin": 1576, + "end": 1594, + "name": "PUSH", + "value": "40" + }, { + "begin": 1576, + "end": 1594, + "name": "SWAP1" + }, { + "begin": 1576, + "end": 1594, + "name": "SWAP2" + }, { + "begin": 1576, + "end": 1594, + "name": "KECCAK256" + }, { + "begin": 1608, + "end": 1620, + "name": "SWAP1" + }, { + "begin": 1608, + "end": 1620, + "name": "DUP2" + }, { + "begin": 1608, + "end": 1620, + "name": "ADD" + }, { + "begin": 1608, + "end": 1620, + "name": "SLOAD" + }, { + "begin": 1608, + "end": 1620, + "name": "PUSH", + "value": "FF" + }, { + "begin": 1608, + "end": 1620, + "name": "AND" + }, { + "begin": 1608, + "end": 1620, + "name": "DUP1" + }, { + "begin": 1608, + "end": 1654, + "name": "PUSH [tag]", + "value": "41" + }, { + "begin": 1608, + "end": 1654, + "name": "JUMPI" + }, { + "begin": -1, + "end": -1, + "name": "POP" + }, { + "begin": 1638, + "end": 1647, + "name": "PUSH", + "value": "2" + }, { + "begin": 1638, + "end": 1654, + "name": "SLOAD" + }, { + "begin": 1624, + "end": 1654, + "name": "PUSH", + "value": "FF" + }, { + "begin": 1624, + "end": 1654, + "name": "DUP4" + }, { + "begin": 1624, + "end": 1654, + "name": "AND" + }, { + "begin": 1624, + "end": 1654, + "name": "LT" + }, { + "begin": 1624, + "end": 1654, + "name": "ISZERO" + }, { + "begin": 1608, + "end": 1654, + "name": "tag", + "value": "41" + }, { + "begin": 1608, + "end": 1654, + "name": "JUMPDEST" + }, { + "begin": 1604, + "end": 1663, + "name": "ISZERO" + }, { + "begin": 1604, + "end": 1663, + "name": "PUSH [tag]", + "value": "42" + }, { + "begin": 1604, + "end": 1663, + "name": "JUMPI" + }, { + "begin": 1656, + "end": 1663, + "name": "PUSH [tag]", + "value": "40" + }, { + "begin": 1656, + "end": 1663, + "name": "JUMP" + }, { + "begin": 1604, + "end": 1663, + "name": "tag", + "value": "42" + }, { + "begin": 1604, + "end": 1663, + "name": "JUMPDEST" + }, { + "begin": 1687, + "end": 1691, + "name": "PUSH", + "value": "1" + }, { + "begin": 1672, + "end": 1684, + "name": "DUP2" + }, { + "begin": 1672, + "end": 1684, + "name": "DUP2" + }, { + "begin": 1672, + "end": 1684, + "name": "ADD" + }, { + "begin": 1672, + "end": 1691, + "name": "DUP1" + }, { + "begin": 1672, + "end": 1691, + "name": "SLOAD" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "FF" + }, { + "begin": -1, + "end": -1, + "name": "NOT" + }, { + "begin": 1672, + "end": 1691, + "name": "AND" + }, { + "begin": 1672, + "end": 1691, + "name": "SWAP1" + }, { + "begin": 1672, + "end": 1691, + "name": "SWAP2" + }, { + "begin": 1672, + "end": 1691, + "name": "OR" + }, { + "begin": -1, + "end": -1, + "name": "PUSH", + "value": "FF00" + }, { + "begin": -1, + "end": -1, + "name": "NOT" + }, { + "begin": 1701, + "end": 1725, + "name": "AND" + }, { + "begin": 1672, + "end": 1691, + "name": "PUSH", + "value": "100" + }, { + "begin": 1672, + "end": 1691, + "name": "PUSH", + "value": "FF" + }, { + "begin": 1701, + "end": 1725, + "name": "DUP6" + }, { + "begin": 1701, + "end": 1725, + "name": "AND" + }, { + "begin": 1701, + "end": 1725, + "name": "SWAP1" + }, { + "begin": 1701, + "end": 1725, + "name": "DUP2" + }, { + "begin": 1701, + "end": 1725, + "name": "MUL" + }, { + "begin": 1701, + "end": 1725, + "name": "SWAP2" + }, { + "begin": 1701, + "end": 1725, + "name": "SWAP1" + }, { + "begin": 1701, + "end": 1725, + "name": "SWAP2" + }, { + "begin": 1701, + "end": 1725, + "name": "OR" + }, { + "begin": 1701, + "end": 1725, + "name": "SWAP1" + }, { + "begin": 1701, + "end": 1725, + "name": "SWAP2" + }, { + "begin": 1701, + "end": 1725, + "name": "SSTORE" + }, { + "begin": 1770, + "end": 1783, + "name": "DUP2" + }, { + "begin": 1770, + "end": 1783, + "name": "SLOAD" + }, { + "begin": 1735, + "end": 1744, + "name": "PUSH", + "value": "2" + }, { + "begin": 1735, + "end": 1756, + "name": "DUP1" + }, { + "begin": 1735, + "end": 1756, + "name": "SLOAD" + }, { + "begin": 1770, + "end": 1783, + "name": "SWAP2" + }, { + "begin": 1770, + "end": 1783, + "name": "SWAP3" + }, { + "begin": 1735, + "end": 1744, + "name": "SWAP1" + }, { + "begin": 1735, + "end": 1744, + "name": "SWAP2" + }, { + "begin": 1735, + "end": 1756, + "name": "DUP2" + }, { + "begin": 1735, + "end": 1756, + "name": "LT" + }, { + "begin": 1735, + "end": 1756, + "name": "PUSH [tag]", + "value": "43" + }, { + "begin": 1735, + "end": 1756, + "name": "JUMPI" + }, { + "begin": 1735, + "end": 1756, + "name": "INVALID" + }, { + "begin": 1735, + "end": 1756, + "name": "tag", + "value": "43" + }, { + "begin": 1735, + "end": 1756, + "name": "JUMPDEST" + }, { + "begin": 1735, + "end": 1756, + "name": "PUSH", + "value": "0" + }, { + "begin": 1735, + "end": 1756, + "name": "SWAP2" + }, { + "begin": 1735, + "end": 1756, + "name": "DUP3" + }, { + "begin": 1735, + "end": 1756, + "name": "MSTORE" + }, { + "begin": 1735, + "end": 1756, + "name": "PUSH", + "value": "20" + }, { + "begin": 1735, + "end": 1756, + "name": "SWAP1" + }, { + "begin": 1735, + "end": 1756, + "name": "SWAP2" + }, { + "begin": 1735, + "end": 1756, + "name": "KECCAK256" + }, { + "begin": 1735, + "end": 1756, + "name": "ADD" + }, { + "begin": 1735, + "end": 1783, + "name": "DUP1" + }, { + "begin": 1735, + "end": 1783, + "name": "SLOAD" + }, { + "begin": 1735, + "end": 1783, + "name": "SWAP1" + }, { + "begin": 1735, + "end": 1783, + "name": "SWAP2" + }, { + "begin": 1735, + "end": 1783, + "name": "ADD" + }, { + "begin": 1735, + "end": 1783, + "name": "SWAP1" + }, { + "begin": 1735, + "end": 1783, + "name": "SSTORE" + }, { + "begin": 1504, + "end": 1790, + "name": "tag", + "value": "40" + }, { + "begin": 1504, + "end": 1790, + "name": "JUMPDEST" + }, { + "begin": 1504, + "end": 1790, + "name": "POP" + }, { + "begin": 1504, + "end": 1790, + "name": "POP" + }, { + "begin": 1504, + "end": 1790, + "name": "JUMP", + "value": "[out]" + }] + } + } + }, + "methodIdentifiers": { + "delegate(address)": "5c19a95c", + "giveRightToVote(address)": "9e7b8d61", + "vote(uint8)": "b3f98adc", + "winningProposal()": "609ff1bd" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.4.25+commit.59dbf8f1\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"winningProposal\",\"outputs\":[{\"name\":\"_winningProposal\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"toVoter\",\"type\":\"address\"}],\"name\":\"giveRightToVote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"toProposal\",\"type\":\"uint8\"}],\"name\":\"vote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_numProposals\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{\"delegate(address)\":{\"notice\":\"Delegate your vote to the voter $(to).\"},\"giveRightToVote(address)\":{\"notice\":\"Give $(toVoter) the right to vote on this ballot. May only be called by $(chairperson).\"},\"vote(uint8)\":{\"notice\":\"Give a single vote to proposal $(toProposal).\"}}}},\"settings\":{\"compilationTarget\":{\"browser/ballot.sol\":\"Ballot\"},\"evmVersion\":\"byzantium\",\"libraries\":{},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"browser/ballot.sol\":{\"keccak256\":\"0xf5e17a682643d68dac41e468e63c07dd2de956fe2627f6d4925bd0d7a5613b8d\",\"urls\":[\"bzzr://5405f025f3fe1155284788e11f994c2bd78aa861e0fab004b1da38b8a4e91d0e\"]}},\"version\":1}", + "userdoc": { + "methods": { + "delegate(address)": { + "notice": "Delegate your vote to the voter $(to)." + }, + "giveRightToVote(address)": { + "notice": "Give $(toVoter) the right to vote on this ballot. May only be called by $(chairperson)." + }, + "vote(uint8)": { + "notice": "Give a single vote to proposal $(toProposal)." + } + } + } + } + } + }, + "errors": [{ + "component": "general", + "formattedMessage": "browser/ballot.sol:19:5: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use \"constructor(...) { ... }\" instead.\n function Ballot(uint8 _numProposals) public {\n ^ (Relevant source part starts here and spans across multiple lines).\n", + "message": "Defining constructors as functions with the same name as the contract is deprecated. Use \"constructor(...) { ... }\" instead.", + "severity": "warning", + "sourceLocation": { + "end": 540, + "file": "browser/ballot.sol", + "start": 373 + }, + "type": "Warning" + }], + "sources": { + "browser/ballot.sol": { + "id": 0, + "legacyAST": { + "attributes": { + "absolutePath": "browser/ballot.sol", + "exportedSymbols": { + "Ballot": [238] + } + }, + "children": [{ + "attributes": { + "literals": ["solidity", "^", "0.4", ".0"] + }, + "id": 1, + "name": "PragmaDirective", + "src": "0:23:0" + }, { + "attributes": { + "baseContracts": [null], + "contractDependencies": [null], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": [238], + "name": "Ballot", + "scope": 239 + }, + "children": [{ + "attributes": { + "canonicalName": "Ballot.Voter", + "name": "Voter", + "scope": 238, + "visibility": "public" + }, + "children": [{ + "attributes": { + "constant": false, + "name": "weight", + "scope": 10, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "uint", + "type": "uint256" + }, + "id": 2, + "name": "ElementaryTypeName", + "src": "70:4:0" + }], + "id": 3, + "name": "VariableDeclaration", + "src": "70:11:0" + }, { + "attributes": { + "constant": false, + "name": "voted", + "scope": 10, + "stateVariable": false, + "storageLocation": "default", + "type": "bool", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "bool", + "type": "bool" + }, + "id": 4, + "name": "ElementaryTypeName", + "src": "91:4:0" + }], + "id": 5, + "name": "VariableDeclaration", + "src": "91:10:0" + }, { + "attributes": { + "constant": false, + "name": "vote", + "scope": 10, + "stateVariable": false, + "storageLocation": "default", + "type": "uint8", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "uint8", + "type": "uint8" + }, + "id": 6, + "name": "ElementaryTypeName", + "src": "111:5:0" + }], + "id": 7, + "name": "VariableDeclaration", + "src": "111:10:0" + }, { + "attributes": { + "constant": false, + "name": "delegate", + "scope": 10, + "stateVariable": false, + "storageLocation": "default", + "type": "address", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "address", + "type": "address" + }, + "id": 8, + "name": "ElementaryTypeName", + "src": "131:7:0" + }], + "id": 9, + "name": "VariableDeclaration", + "src": "131:16:0" + }], + "id": 10, + "name": "StructDefinition", + "src": "47:107:0" + }, { + "attributes": { + "canonicalName": "Ballot.Proposal", + "name": "Proposal", + "scope": 238, + "visibility": "public" + }, + "children": [{ + "attributes": { + "constant": false, + "name": "voteCount", + "scope": 13, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "uint", + "type": "uint256" + }, + "id": 11, + "name": "ElementaryTypeName", + "src": "185:4:0" + }], + "id": 12, + "name": "VariableDeclaration", + "src": "185:14:0" + }], + "id": 13, + "name": "StructDefinition", + "src": "159:47:0" + }, { + "attributes": { + "constant": false, + "name": "chairperson", + "scope": 238, + "stateVariable": true, + "storageLocation": "default", + "type": "address", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "address", + "type": "address" + }, + "id": 14, + "name": "ElementaryTypeName", + "src": "212:7:0" + }], + "id": 15, + "name": "VariableDeclaration", + "src": "212:19:0" + }, { + "attributes": { + "constant": false, + "name": "voters", + "scope": 238, + "stateVariable": true, + "storageLocation": "default", + "type": "mapping(address => struct Ballot.Voter)", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "type": "mapping(address => struct Ballot.Voter)" + }, + "children": [{ + "attributes": { + "name": "address", + "type": "address" + }, + "id": 16, + "name": "ElementaryTypeName", + "src": "245:7:0" + }, { + "attributes": { + "contractScope": null, + "name": "Voter", + "referencedDeclaration": 10, + "type": "struct Ballot.Voter" + }, + "id": 17, + "name": "UserDefinedTypeName", + "src": "256:5:0" + }], + "id": 18, + "name": "Mapping", + "src": "237:25:0" + }], + "id": 19, + "name": "VariableDeclaration", + "src": "237:32:0" + }, { + "attributes": { + "constant": false, + "name": "proposals", + "scope": 238, + "stateVariable": true, + "storageLocation": "default", + "type": "struct Ballot.Proposal[]", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "length": null, + "type": "struct Ballot.Proposal[]" + }, + "children": [{ + "attributes": { + "contractScope": null, + "name": "Proposal", + "referencedDeclaration": 13, + "type": "struct Ballot.Proposal" + }, + "id": 20, + "name": "UserDefinedTypeName", + "src": "275:8:0" + }], + "id": 21, + "name": "ArrayTypeName", + "src": "275:10:0" + }], + "id": 22, + "name": "VariableDeclaration", + "src": "275:20:0" + }, { + "attributes": { + "constant": false, + "documentation": "Create a new ballot with $(_numProposals) different proposals.", + "implemented": true, + "isConstructor": true, + "modifiers": [null], + "name": "Ballot", + "payable": false, + "scope": 238, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": [{ + "children": [{ + "attributes": { + "constant": false, + "name": "_numProposals", + "scope": 46, + "stateVariable": false, + "storageLocation": "default", + "type": "uint8", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "uint8", + "type": "uint8" + }, + "id": 23, + "name": "ElementaryTypeName", + "src": "389:5:0" + }], + "id": 24, + "name": "VariableDeclaration", + "src": "389:19:0" + }], + "id": 25, + "name": "ParameterList", + "src": "388:21:0" + }, { + "attributes": { + "parameters": [null] + }, + "children": [], + "id": 26, + "name": "ParameterList", + "src": "417:0:0" + }, { + "children": [{ + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 15, + "type": "address", + "value": "chairperson" + }, + "id": 27, + "name": "Identifier", + "src": "427:11:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "sender", + "referencedDeclaration": null, + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 253, + "type": "msg", + "value": "msg" + }, + "id": 28, + "name": "Identifier", + "src": "441:3:0" + }], + "id": 29, + "name": "MemberAccess", + "src": "441:10:0" + }], + "id": 30, + "name": "Assignment", + "src": "427:24:0" + }], + "id": 31, + "name": "ExpressionStatement", + "src": "427:24:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "weight", + "referencedDeclaration": 3, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Voter storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 19, + "type": "mapping(address => struct Ballot.Voter storage ref)", + "value": "voters" + }, + "id": 32, + "name": "Identifier", + "src": "461:6:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 15, + "type": "address", + "value": "chairperson" + }, + "id": 33, + "name": "Identifier", + "src": "468:11:0" + }], + "id": 34, + "name": "IndexAccess", + "src": "461:19:0" + }], + "id": 35, + "name": "MemberAccess", + "src": "461:26:0" + }, { + "attributes": { + "argumentTypes": null, + "hexvalue": "31", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 1", + "value": "1" + }, + "id": 36, + "name": "Literal", + "src": "490:1:0" + }], + "id": 37, + "name": "Assignment", + "src": "461:30:0" + }], + "id": 38, + "name": "ExpressionStatement", + "src": "461:30:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "length", + "referencedDeclaration": null, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 22, + "type": "struct Ballot.Proposal storage ref[] storage ref", + "value": "proposals" + }, + "id": 39, + "name": "Identifier", + "src": "501:9:0" + }], + "id": 41, + "name": "MemberAccess", + "src": "501:16:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 24, + "type": "uint8", + "value": "_numProposals" + }, + "id": 42, + "name": "Identifier", + "src": "520:13:0" + }], + "id": 43, + "name": "Assignment", + "src": "501:32:0" + }], + "id": 44, + "name": "ExpressionStatement", + "src": "501:32:0" + }], + "id": 45, + "name": "Block", + "src": "417:123:0" + }], + "id": 46, + "name": "FunctionDefinition", + "src": "373:167:0" + }, { + "attributes": { + "constant": false, + "documentation": "Give $(toVoter) the right to vote on this ballot.\n May only be called by $(chairperson).", + "implemented": true, + "isConstructor": false, + "modifiers": [null], + "name": "giveRightToVote", + "payable": false, + "scope": 238, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": [{ + "children": [{ + "attributes": { + "constant": false, + "name": "toVoter", + "scope": 70, + "stateVariable": false, + "storageLocation": "default", + "type": "address", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "address", + "type": "address" + }, + "id": 47, + "name": "ElementaryTypeName", + "src": "675:7:0" + }], + "id": 48, + "name": "VariableDeclaration", + "src": "675:15:0" + }], + "id": 49, + "name": "ParameterList", + "src": "674:17:0" + }, { + "attributes": { + "parameters": [null] + }, + "children": [], + "id": 50, + "name": "ParameterList", + "src": "699:0:0" + }, { + "children": [{ + "attributes": { + "falseBody": null + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "||", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "!=", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "sender", + "referencedDeclaration": null, + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 253, + "type": "msg", + "value": "msg" + }, + "id": 51, + "name": "Identifier", + "src": "713:3:0" + }], + "id": 52, + "name": "MemberAccess", + "src": "713:10:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 15, + "type": "address", + "value": "chairperson" + }, + "id": 53, + "name": "Identifier", + "src": "727:11:0" + }], + "id": 54, + "name": "BinaryOperation", + "src": "713:25:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "voted", + "referencedDeclaration": 5, + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Voter storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 19, + "type": "mapping(address => struct Ballot.Voter storage ref)", + "value": "voters" + }, + "id": 55, + "name": "Identifier", + "src": "742:6:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 48, + "type": "address", + "value": "toVoter" + }, + "id": 56, + "name": "Identifier", + "src": "749:7:0" + }], + "id": 57, + "name": "IndexAccess", + "src": "742:15:0" + }], + "id": 58, + "name": "MemberAccess", + "src": "742:21:0" + }], + "id": 59, + "name": "BinaryOperation", + "src": "713:50:0" + }, { + "attributes": { + "expression": null, + "functionReturnParameters": 50 + }, + "id": 60, + "name": "Return", + "src": "765:7:0" + }], + "id": 61, + "name": "IfStatement", + "src": "709:63:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "weight", + "referencedDeclaration": 3, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Voter storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 19, + "type": "mapping(address => struct Ballot.Voter storage ref)", + "value": "voters" + }, + "id": 62, + "name": "Identifier", + "src": "781:6:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 48, + "type": "address", + "value": "toVoter" + }, + "id": 63, + "name": "Identifier", + "src": "788:7:0" + }], + "id": 64, + "name": "IndexAccess", + "src": "781:15:0" + }], + "id": 65, + "name": "MemberAccess", + "src": "781:22:0" + }, { + "attributes": { + "argumentTypes": null, + "hexvalue": "31", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 1", + "value": "1" + }, + "id": 66, + "name": "Literal", + "src": "806:1:0" + }], + "id": 67, + "name": "Assignment", + "src": "781:26:0" + }], + "id": 68, + "name": "ExpressionStatement", + "src": "781:26:0" + }], + "id": 69, + "name": "Block", + "src": "699:115:0" + }], + "id": 70, + "name": "FunctionDefinition", + "src": "650:164:0" + }, { + "attributes": { + "constant": false, + "documentation": "Delegate your vote to the voter $(to).", + "implemented": true, + "isConstructor": false, + "modifiers": [null], + "name": "delegate", + "payable": false, + "scope": 238, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": [{ + "children": [{ + "attributes": { + "constant": false, + "name": "to", + "scope": 154, + "stateVariable": false, + "storageLocation": "default", + "type": "address", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "address", + "type": "address" + }, + "id": 71, + "name": "ElementaryTypeName", + "src": "885:7:0" + }], + "id": 72, + "name": "VariableDeclaration", + "src": "885:10:0" + }], + "id": 73, + "name": "ParameterList", + "src": "884:12:0" + }, { + "attributes": { + "parameters": [null] + }, + "children": [], + "id": 74, + "name": "ParameterList", + "src": "904:0:0" + }, { + "children": [{ + "attributes": { + "assignments": [76] + }, + "children": [{ + "attributes": { + "constant": false, + "name": "sender", + "scope": 154, + "stateVariable": false, + "storageLocation": "storage", + "type": "struct Ballot.Voter", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "contractScope": null, + "name": "Voter", + "referencedDeclaration": 10, + "type": "struct Ballot.Voter" + }, + "id": 75, + "name": "UserDefinedTypeName", + "src": "914:5:0" + }], + "id": 76, + "name": "VariableDeclaration", + "src": "914:20:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Voter storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 19, + "type": "mapping(address => struct Ballot.Voter storage ref)", + "value": "voters" + }, + "id": 77, + "name": "Identifier", + "src": "937:6:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "sender", + "referencedDeclaration": null, + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 253, + "type": "msg", + "value": "msg" + }, + "id": 78, + "name": "Identifier", + "src": "944:3:0" + }], + "id": 79, + "name": "MemberAccess", + "src": "944:10:0" + }], + "id": 80, + "name": "IndexAccess", + "src": "937:18:0" + }], + "id": 81, + "name": "VariableDeclarationStatement", + "src": "914:41:0" + }, { + "attributes": { + "falseBody": null + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "voted", + "referencedDeclaration": 5, + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 76, + "type": "struct Ballot.Voter storage pointer", + "value": "sender" + }, + "id": 82, + "name": "Identifier", + "src": "990:6:0" + }], + "id": 83, + "name": "MemberAccess", + "src": "990:12:0" + }, { + "attributes": { + "expression": null, + "functionReturnParameters": 74 + }, + "id": 84, + "name": "Return", + "src": "1004:7:0" + }], + "id": 85, + "name": "IfStatement", + "src": "986:25:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "&&", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "!=", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "delegate", + "referencedDeclaration": 9, + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Voter storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 19, + "type": "mapping(address => struct Ballot.Voter storage ref)", + "value": "voters" + }, + "id": 86, + "name": "Identifier", + "src": "1027:6:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 72, + "type": "address", + "value": "to" + }, + "id": 87, + "name": "Identifier", + "src": "1034:2:0" + }], + "id": 88, + "name": "IndexAccess", + "src": "1027:10:0" + }], + "id": 89, + "name": "MemberAccess", + "src": "1027:19:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": true, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": [null], + "type": "address", + "type_conversion": true + }, + "children": [{ + "attributes": { + "argumentTypes": [{ + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(address)", + "value": "address" + }, + "id": 90, + "name": "ElementaryTypeNameExpression", + "src": "1050:7:0" + }, { + "attributes": { + "argumentTypes": null, + "hexvalue": "30", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 0", + "value": "0" + }, + "id": 91, + "name": "Literal", + "src": "1058:1:0" + }], + "id": 92, + "name": "FunctionCall", + "src": "1050:10:0" + }], + "id": 93, + "name": "BinaryOperation", + "src": "1027:33:0" + }, { + "attributes": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "!=", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "delegate", + "referencedDeclaration": 9, + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Voter storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 19, + "type": "mapping(address => struct Ballot.Voter storage ref)", + "value": "voters" + }, + "id": 94, + "name": "Identifier", + "src": "1064:6:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 72, + "type": "address", + "value": "to" + }, + "id": 95, + "name": "Identifier", + "src": "1071:2:0" + }], + "id": 96, + "name": "IndexAccess", + "src": "1064:10:0" + }], + "id": 97, + "name": "MemberAccess", + "src": "1064:19:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "sender", + "referencedDeclaration": null, + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 253, + "type": "msg", + "value": "msg" + }, + "id": 98, + "name": "Identifier", + "src": "1087:3:0" + }], + "id": 99, + "name": "MemberAccess", + "src": "1087:10:0" + }], + "id": 100, + "name": "BinaryOperation", + "src": "1064:33:0" + }], + "id": 101, + "name": "BinaryOperation", + "src": "1027:70:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 72, + "type": "address", + "value": "to" + }, + "id": 102, + "name": "Identifier", + "src": "1111:2:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "delegate", + "referencedDeclaration": 9, + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Voter storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 19, + "type": "mapping(address => struct Ballot.Voter storage ref)", + "value": "voters" + }, + "id": 103, + "name": "Identifier", + "src": "1116:6:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 72, + "type": "address", + "value": "to" + }, + "id": 104, + "name": "Identifier", + "src": "1123:2:0" + }], + "id": 105, + "name": "IndexAccess", + "src": "1116:10:0" + }], + "id": 106, + "name": "MemberAccess", + "src": "1116:19:0" + }], + "id": 107, + "name": "Assignment", + "src": "1111:24:0" + }], + "id": 108, + "name": "ExpressionStatement", + "src": "1111:24:0" + }], + "id": 109, + "name": "WhileStatement", + "src": "1020:115:0" + }, { + "attributes": { + "falseBody": null + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "==", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 72, + "type": "address", + "value": "to" + }, + "id": 110, + "name": "Identifier", + "src": "1149:2:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "sender", + "referencedDeclaration": null, + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 253, + "type": "msg", + "value": "msg" + }, + "id": 111, + "name": "Identifier", + "src": "1155:3:0" + }], + "id": 112, + "name": "MemberAccess", + "src": "1155:10:0" + }], + "id": 113, + "name": "BinaryOperation", + "src": "1149:16:0" + }, { + "attributes": { + "expression": null, + "functionReturnParameters": 74 + }, + "id": 114, + "name": "Return", + "src": "1167:7:0" + }], + "id": 115, + "name": "IfStatement", + "src": "1145:29:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "voted", + "referencedDeclaration": 5, + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 76, + "type": "struct Ballot.Voter storage pointer", + "value": "sender" + }, + "id": 116, + "name": "Identifier", + "src": "1183:6:0" + }], + "id": 118, + "name": "MemberAccess", + "src": "1183:12:0" + }, { + "attributes": { + "argumentTypes": null, + "hexvalue": "74727565", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "bool", + "type": "bool", + "value": "true" + }, + "id": 119, + "name": "Literal", + "src": "1198:4:0" + }], + "id": 120, + "name": "Assignment", + "src": "1183:19:0" + }], + "id": 121, + "name": "ExpressionStatement", + "src": "1183:19:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "delegate", + "referencedDeclaration": 9, + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 76, + "type": "struct Ballot.Voter storage pointer", + "value": "sender" + }, + "id": 122, + "name": "Identifier", + "src": "1212:6:0" + }], + "id": 124, + "name": "MemberAccess", + "src": "1212:15:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 72, + "type": "address", + "value": "to" + }, + "id": 125, + "name": "Identifier", + "src": "1230:2:0" + }], + "id": 126, + "name": "Assignment", + "src": "1212:20:0" + }], + "id": 127, + "name": "ExpressionStatement", + "src": "1212:20:0" + }, { + "attributes": { + "assignments": [129] + }, + "children": [{ + "attributes": { + "constant": false, + "name": "delegateTo", + "scope": 154, + "stateVariable": false, + "storageLocation": "storage", + "type": "struct Ballot.Voter", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "contractScope": null, + "name": "Voter", + "referencedDeclaration": 10, + "type": "struct Ballot.Voter" + }, + "id": 128, + "name": "UserDefinedTypeName", + "src": "1242:5:0" + }], + "id": 129, + "name": "VariableDeclaration", + "src": "1242:24:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Voter storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 19, + "type": "mapping(address => struct Ballot.Voter storage ref)", + "value": "voters" + }, + "id": 130, + "name": "Identifier", + "src": "1269:6:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 72, + "type": "address", + "value": "to" + }, + "id": 131, + "name": "Identifier", + "src": "1276:2:0" + }], + "id": 132, + "name": "IndexAccess", + "src": "1269:10:0" + }], + "id": 133, + "name": "VariableDeclarationStatement", + "src": "1242:37:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "voted", + "referencedDeclaration": 5, + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 129, + "type": "struct Ballot.Voter storage pointer", + "value": "delegateTo" + }, + "id": 134, + "name": "Identifier", + "src": "1293:10:0" + }], + "id": 135, + "name": "MemberAccess", + "src": "1293:16:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "+=", + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "voteCount", + "referencedDeclaration": 12, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Proposal storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 22, + "type": "struct Ballot.Proposal storage ref[] storage ref", + "value": "proposals" + }, + "id": 136, + "name": "Identifier", + "src": "1323:9:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "vote", + "referencedDeclaration": 7, + "type": "uint8" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 129, + "type": "struct Ballot.Voter storage pointer", + "value": "delegateTo" + }, + "id": 137, + "name": "Identifier", + "src": "1333:10:0" + }], + "id": 138, + "name": "MemberAccess", + "src": "1333:15:0" + }], + "id": 139, + "name": "IndexAccess", + "src": "1323:26:0" + }], + "id": 140, + "name": "MemberAccess", + "src": "1323:36:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "weight", + "referencedDeclaration": 3, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 76, + "type": "struct Ballot.Voter storage pointer", + "value": "sender" + }, + "id": 141, + "name": "Identifier", + "src": "1363:6:0" + }], + "id": 142, + "name": "MemberAccess", + "src": "1363:13:0" + }], + "id": 143, + "name": "Assignment", + "src": "1323:53:0" + }], + "id": 144, + "name": "ExpressionStatement", + "src": "1323:53:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "+=", + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "weight", + "referencedDeclaration": 3, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 129, + "type": "struct Ballot.Voter storage pointer", + "value": "delegateTo" + }, + "id": 145, + "name": "Identifier", + "src": "1403:10:0" + }], + "id": 147, + "name": "MemberAccess", + "src": "1403:17:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "weight", + "referencedDeclaration": 3, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 76, + "type": "struct Ballot.Voter storage pointer", + "value": "sender" + }, + "id": 148, + "name": "Identifier", + "src": "1424:6:0" + }], + "id": 149, + "name": "MemberAccess", + "src": "1424:13:0" + }], + "id": 150, + "name": "Assignment", + "src": "1403:34:0" + }], + "id": 151, + "name": "ExpressionStatement", + "src": "1403:34:0" + }], + "id": 152, + "name": "IfStatement", + "src": "1289:148:0" + }], + "id": 153, + "name": "Block", + "src": "904:540:0" + }], + "id": 154, + "name": "FunctionDefinition", + "src": "867:577:0" + }, { + "attributes": { + "constant": false, + "documentation": "Give a single vote to proposal $(toProposal).", + "implemented": true, + "isConstructor": false, + "modifiers": [null], + "name": "vote", + "payable": false, + "scope": 238, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": [{ + "children": [{ + "attributes": { + "constant": false, + "name": "toProposal", + "scope": 196, + "stateVariable": false, + "storageLocation": "default", + "type": "uint8", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "uint8", + "type": "uint8" + }, + "id": 155, + "name": "ElementaryTypeName", + "src": "1518:5:0" + }], + "id": 156, + "name": "VariableDeclaration", + "src": "1518:16:0" + }], + "id": 157, + "name": "ParameterList", + "src": "1517:18:0" + }, { + "attributes": { + "parameters": [null] + }, + "children": [], + "id": 158, + "name": "ParameterList", + "src": "1543:0:0" + }, { + "children": [{ + "attributes": { + "assignments": [160] + }, + "children": [{ + "attributes": { + "constant": false, + "name": "sender", + "scope": 196, + "stateVariable": false, + "storageLocation": "storage", + "type": "struct Ballot.Voter", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "contractScope": null, + "name": "Voter", + "referencedDeclaration": 10, + "type": "struct Ballot.Voter" + }, + "id": 159, + "name": "UserDefinedTypeName", + "src": "1553:5:0" + }], + "id": 160, + "name": "VariableDeclaration", + "src": "1553:20:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Voter storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 19, + "type": "mapping(address => struct Ballot.Voter storage ref)", + "value": "voters" + }, + "id": 161, + "name": "Identifier", + "src": "1576:6:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "sender", + "referencedDeclaration": null, + "type": "address" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 253, + "type": "msg", + "value": "msg" + }, + "id": 162, + "name": "Identifier", + "src": "1583:3:0" + }], + "id": 163, + "name": "MemberAccess", + "src": "1583:10:0" + }], + "id": 164, + "name": "IndexAccess", + "src": "1576:18:0" + }], + "id": 165, + "name": "VariableDeclarationStatement", + "src": "1553:41:0" + }, { + "attributes": { + "falseBody": null + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "||", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "voted", + "referencedDeclaration": 5, + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 160, + "type": "struct Ballot.Voter storage pointer", + "value": "sender" + }, + "id": 166, + "name": "Identifier", + "src": "1608:6:0" + }], + "id": 167, + "name": "MemberAccess", + "src": "1608:12:0" + }, { + "attributes": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": ">=", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 156, + "type": "uint8", + "value": "toProposal" + }, + "id": 168, + "name": "Identifier", + "src": "1624:10:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "length", + "referencedDeclaration": null, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 22, + "type": "struct Ballot.Proposal storage ref[] storage ref", + "value": "proposals" + }, + "id": 169, + "name": "Identifier", + "src": "1638:9:0" + }], + "id": 170, + "name": "MemberAccess", + "src": "1638:16:0" + }], + "id": 171, + "name": "BinaryOperation", + "src": "1624:30:0" + }], + "id": 172, + "name": "BinaryOperation", + "src": "1608:46:0" + }, { + "attributes": { + "expression": null, + "functionReturnParameters": 158 + }, + "id": 173, + "name": "Return", + "src": "1656:7:0" + }], + "id": 174, + "name": "IfStatement", + "src": "1604:59:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "voted", + "referencedDeclaration": 5, + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 160, + "type": "struct Ballot.Voter storage pointer", + "value": "sender" + }, + "id": 175, + "name": "Identifier", + "src": "1672:6:0" + }], + "id": 177, + "name": "MemberAccess", + "src": "1672:12:0" + }, { + "attributes": { + "argumentTypes": null, + "hexvalue": "74727565", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "bool", + "type": "bool", + "value": "true" + }, + "id": 178, + "name": "Literal", + "src": "1687:4:0" + }], + "id": 179, + "name": "Assignment", + "src": "1672:19:0" + }], + "id": 180, + "name": "ExpressionStatement", + "src": "1672:19:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "uint8" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "vote", + "referencedDeclaration": 7, + "type": "uint8" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 160, + "type": "struct Ballot.Voter storage pointer", + "value": "sender" + }, + "id": 181, + "name": "Identifier", + "src": "1701:6:0" + }], + "id": 183, + "name": "MemberAccess", + "src": "1701:11:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 156, + "type": "uint8", + "value": "toProposal" + }, + "id": 184, + "name": "Identifier", + "src": "1715:10:0" + }], + "id": 185, + "name": "Assignment", + "src": "1701:24:0" + }], + "id": 186, + "name": "ExpressionStatement", + "src": "1701:24:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "+=", + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "voteCount", + "referencedDeclaration": 12, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Proposal storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 22, + "type": "struct Ballot.Proposal storage ref[] storage ref", + "value": "proposals" + }, + "id": 187, + "name": "Identifier", + "src": "1735:9:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 156, + "type": "uint8", + "value": "toProposal" + }, + "id": 188, + "name": "Identifier", + "src": "1745:10:0" + }], + "id": 189, + "name": "IndexAccess", + "src": "1735:21:0" + }], + "id": 190, + "name": "MemberAccess", + "src": "1735:31:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "weight", + "referencedDeclaration": 3, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 160, + "type": "struct Ballot.Voter storage pointer", + "value": "sender" + }, + "id": 191, + "name": "Identifier", + "src": "1770:6:0" + }], + "id": 192, + "name": "MemberAccess", + "src": "1770:13:0" + }], + "id": 193, + "name": "Assignment", + "src": "1735:48:0" + }], + "id": 194, + "name": "ExpressionStatement", + "src": "1735:48:0" + }], + "id": 195, + "name": "Block", + "src": "1543:247:0" + }], + "id": 196, + "name": "FunctionDefinition", + "src": "1504:286:0" + }, { + "attributes": { + "constant": true, + "documentation": null, + "implemented": true, + "isConstructor": false, + "modifiers": [null], + "name": "winningProposal", + "payable": false, + "scope": 238, + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + "children": [{ + "attributes": { + "parameters": [null] + }, + "children": [], + "id": 197, + "name": "ParameterList", + "src": "1820:2:0" + }, { + "children": [{ + "attributes": { + "constant": false, + "name": "_winningProposal", + "scope": 237, + "stateVariable": false, + "storageLocation": "default", + "type": "uint8", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "uint8", + "type": "uint8" + }, + "id": 198, + "name": "ElementaryTypeName", + "src": "1848:5:0" + }], + "id": 199, + "name": "VariableDeclaration", + "src": "1848:22:0" + }], + "id": 200, + "name": "ParameterList", + "src": "1847:24:0" + }, { + "children": [{ + "attributes": { + "assignments": [202] + }, + "children": [{ + "attributes": { + "constant": false, + "name": "winningVoteCount", + "scope": 237, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "uint256", + "type": "uint256" + }, + "id": 201, + "name": "ElementaryTypeName", + "src": "1882:7:0" + }], + "id": 202, + "name": "VariableDeclaration", + "src": "1882:24:0" + }, { + "attributes": { + "argumentTypes": null, + "hexvalue": "30", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 0", + "value": "0" + }, + "id": 203, + "name": "Literal", + "src": "1909:1:0" + }], + "id": 204, + "name": "VariableDeclarationStatement", + "src": "1882:28:0" + }, { + "children": [{ + "attributes": { + "assignments": [206] + }, + "children": [{ + "attributes": { + "constant": false, + "name": "prop", + "scope": 237, + "stateVariable": false, + "storageLocation": "default", + "type": "uint8", + "value": null, + "visibility": "internal" + }, + "children": [{ + "attributes": { + "name": "uint8", + "type": "uint8" + }, + "id": 205, + "name": "ElementaryTypeName", + "src": "1925:5:0" + }], + "id": 206, + "name": "VariableDeclaration", + "src": "1925:10:0" + }, { + "attributes": { + "argumentTypes": null, + "hexvalue": "30", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 0", + "value": "0" + }, + "id": 207, + "name": "Literal", + "src": "1938:1:0" + }], + "id": 208, + "name": "VariableDeclarationStatement", + "src": "1925:14:0" + }, { + "attributes": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "<", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 206, + "type": "uint8", + "value": "prop" + }, + "id": 209, + "name": "Identifier", + "src": "1941:4:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "length", + "referencedDeclaration": null, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 22, + "type": "struct Ballot.Proposal storage ref[] storage ref", + "value": "proposals" + }, + "id": 210, + "name": "Identifier", + "src": "1948:9:0" + }], + "id": 211, + "name": "MemberAccess", + "src": "1948:16:0" + }], + "id": 212, + "name": "BinaryOperation", + "src": "1941:23:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "++", + "prefix": false, + "type": "uint8" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 206, + "type": "uint8", + "value": "prop" + }, + "id": 213, + "name": "Identifier", + "src": "1966:4:0" + }], + "id": 214, + "name": "UnaryOperation", + "src": "1966:6:0" + }], + "id": 215, + "name": "ExpressionStatement", + "src": "1966:6:0" + }, { + "attributes": { + "falseBody": null + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": ">", + "type": "bool" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "voteCount", + "referencedDeclaration": 12, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Proposal storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 22, + "type": "struct Ballot.Proposal storage ref[] storage ref", + "value": "proposals" + }, + "id": 216, + "name": "Identifier", + "src": "1990:9:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 206, + "type": "uint8", + "value": "prop" + }, + "id": 217, + "name": "Identifier", + "src": "2000:4:0" + }], + "id": 218, + "name": "IndexAccess", + "src": "1990:15:0" + }], + "id": 219, + "name": "MemberAccess", + "src": "1990:25:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 202, + "type": "uint256", + "value": "winningVoteCount" + }, + "id": 220, + "name": "Identifier", + "src": "2018:16:0" + }], + "id": 221, + "name": "BinaryOperation", + "src": "1990:44:0" + }, { + "children": [{ + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 202, + "type": "uint256", + "value": "winningVoteCount" + }, + "id": 222, + "name": "Identifier", + "src": "2054:16:0" + }, { + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "voteCount", + "referencedDeclaration": 12, + "type": "uint256" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Ballot.Proposal storage ref" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 22, + "type": "struct Ballot.Proposal storage ref[] storage ref", + "value": "proposals" + }, + "id": 223, + "name": "Identifier", + "src": "2073:9:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 206, + "type": "uint8", + "value": "prop" + }, + "id": 224, + "name": "Identifier", + "src": "2083:4:0" + }], + "id": 225, + "name": "IndexAccess", + "src": "2073:15:0" + }], + "id": 226, + "name": "MemberAccess", + "src": "2073:25:0" + }], + "id": 227, + "name": "Assignment", + "src": "2054:44:0" + }], + "id": 228, + "name": "ExpressionStatement", + "src": "2054:44:0" + }, { + "children": [{ + "attributes": { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "uint8" + }, + "children": [{ + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 199, + "type": "uint8", + "value": "_winningProposal" + }, + "id": 229, + "name": "Identifier", + "src": "2116:16:0" + }, { + "attributes": { + "argumentTypes": null, + "overloadedDeclarations": [null], + "referencedDeclaration": 206, + "type": "uint8", + "value": "prop" + }, + "id": 230, + "name": "Identifier", + "src": "2135:4:0" + }], + "id": 231, + "name": "Assignment", + "src": "2116:23:0" + }], + "id": 232, + "name": "ExpressionStatement", + "src": "2116:23:0" + }], + "id": 233, + "name": "Block", + "src": "2036:118:0" + }], + "id": 234, + "name": "IfStatement", + "src": "1986:168:0" + }], + "id": 235, + "name": "ForStatement", + "src": "1920:234:0" + }], + "id": 236, + "name": "Block", + "src": "1872:288:0" + }], + "id": 237, + "name": "FunctionDefinition", + "src": "1796:364:0" + }], + "id": 238, + "name": "ContractDefinition", + "src": "24:2138:0" + }], + "id": 239, + "name": "SourceUnit", + "src": "0:2162:0" + } + } + } + }, + "source": { + "sources": { + "browser/ballot.sol": { + "content": "pragma solidity ^0.4.0;\ncontract Ballot {\n\n struct Voter {\n uint weight;\n bool voted;\n uint8 vote;\n address delegate;\n }\n struct Proposal {\n uint voteCount;\n }\n\n address chairperson;\n mapping(address => Voter) voters;\n Proposal[] proposals;\n\n /// Create a new ballot with $(_numProposals) different proposals.\n function Ballot(uint8 _numProposals) public {\n chairperson = msg.sender;\n voters[chairperson].weight = 1;\n proposals.length = _numProposals;\n }\n\n /// Give $(toVoter) the right to vote on this ballot.\n /// May only be called by $(chairperson).\n function giveRightToVote(address toVoter) public {\n if (msg.sender != chairperson || voters[toVoter].voted) return;\n voters[toVoter].weight = 1;\n }\n\n /// Delegate your vote to the voter $(to).\n function delegate(address to) public {\n Voter storage sender = voters[msg.sender]; // assigns reference\n if (sender.voted) return;\n while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)\n to = voters[to].delegate;\n if (to == msg.sender) return;\n sender.voted = true;\n sender.delegate = to;\n Voter storage delegateTo = voters[to];\n if (delegateTo.voted)\n proposals[delegateTo.vote].voteCount += sender.weight;\n else\n delegateTo.weight += sender.weight;\n }\n\n /// Give a single vote to proposal $(toProposal).\n function vote(uint8 toProposal) public {\n Voter storage sender = voters[msg.sender];\n if (sender.voted || toProposal >= proposals.length) return;\n sender.voted = true;\n sender.vote = toProposal;\n proposals[toProposal].voteCount += sender.weight;\n }\n\n function winningProposal() public constant returns (uint8 _winningProposal) {\n uint256 winningVoteCount = 0;\n for (uint8 prop = 0; prop < proposals.length; prop++)\n if (proposals[prop].voteCount > winningVoteCount) {\n winningVoteCount = proposals[prop].voteCount;\n _winningProposal = prop;\n }\n }\n}" + } + }, + "target": "browser/ballot.sol" + } + } diff --git a/remix-debug/contextManager.js b/remix-debug/contextManager.js new file mode 100644 index 0000000000..8a1b1b70d2 --- /dev/null +++ b/remix-debug/contextManager.js @@ -0,0 +1,59 @@ +var remixLib = require('remix-lib') + +var EventManager = remixLib.EventManager +var executionContext = remixLib.execution.executionContext +var Web3Providers = remixLib.vm.Web3Providers +var DummyProvider = remixLib.vm.DummyProvider +var init = remixLib.init + +class ContextManager { + constructor () { + this.executionContext = executionContext + this.web3 = this.executionContext.web3() + this.event = new EventManager() + } + + initProviders () { + this.web3Providers = new Web3Providers() + this.addProvider('DUMMYWEB3', new DummyProvider()) + this.switchProvider('DUMMYWEB3') + + this.addProvider('vm', this.executionContext.vm()) + this.addProvider('injected', this.executionContext.internalWeb3()) + this.addProvider('web3', this.executionContext.internalWeb3()) + this.switchProvider(this.executionContext.getProvider()) + } + + getWeb3 () { + return this.web3 + } + + addProvider (type, obj) { + this.web3Providers.addProvider(type, obj) + this.event.trigger('providerAdded', [type]) + } + + switchProvider (type) { + var self = this + this.web3Providers.get(type, function (error, obj) { + if (error) { + console.log('provider ' + type + ' not defined') + } else { + self.web3 = obj + self.executionContext.detectNetwork((error, network) => { + if (error || !network) { + self.web3 = obj + } else { + var webDebugNode = init.web3DebugNode(network.name) + self.web3 = (!webDebugNode ? obj : webDebugNode) + } + self.event.trigger('providerChanged', [type, self.web3]) + }) + self.event.trigger('providerChanged', [type, self.web3]) + } + }) + } + +} + +module.exports = ContextManager diff --git a/remix-debug/lib_test.js b/remix-debug/lib_test.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/remix-debug/src/debugger/debugger.js b/remix-debug/src/debugger/debugger.js index 79721a8184..4f07c76587 100644 --- a/remix-debug/src/debugger/debugger.js +++ b/remix-debug/src/debugger/debugger.js @@ -11,7 +11,8 @@ function Debugger (options) { var self = this this.event = new EventManager() - this.offsetToLineColumnConverter = options.offsetToLineColumnConverter + // TODO: temporarily commented out + // this.offsetToLineColumnConverter = options.offsetToLineColumnConverter this.compiler = options.compiler this.debugger = new Ethdebugger({ @@ -25,11 +26,12 @@ function Debugger (options) { } }) - this.breakPointManager = new remixLib.code.BreakpointManager(this.debugger, (sourceLocation) => { - return self.offsetToLineColumnConverter.offsetToLineColumn(sourceLocation, sourceLocation.file, this.compiler.lastCompilationResult.source.sources, this.compiler.lastCompilationResult.data.sources) - }, (step) => { - self.event.trigger('breakpointStep', [step]) - }) + // TODO: temporarily commented out + // this.breakPointManager = new remixLib.code.BreakpointManager(this.debugger, (sourceLocation) => { + // return self.offsetToLineColumnConverter.offsetToLineColumn(sourceLocation, sourceLocation.file, this.compiler.lastCompilationResult.source.sources, this.compiler.lastCompilationResult.data.sources) + // }, (step) => { + // self.event.trigger('breakpointStep', [step]) + // }) this.debugger.setBreakpointManager(this.breakPointManager) @@ -47,20 +49,22 @@ function Debugger (options) { } Debugger.prototype.registerAndHighlightCodeItem = function (index) { - const self = this - // register selected code item, highlight the corresponding source location - if (!self.compiler.lastCompilationResult) return - self.debugger.traceManager.getCurrentCalledAddressAt(index, (error, address) => { - if (error) return console.log(error) - self.debugger.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, index, self.compiler.lastCompilationResult.data.contracts, function (error, rawLocation) { - if (!error && self.compiler.lastCompilationResult && self.compiler.lastCompilationResult.data) { - var lineColumnPos = self.offsetToLineColumnConverter.offsetToLineColumn(rawLocation, rawLocation.file, self.compiler.lastCompilationResult.source.sources, self.compiler.lastCompilationResult.data.sources) - self.event.trigger('newSourceLocation', [lineColumnPos, rawLocation]) - } else { - self.event.trigger('newSourceLocation', [null]) - } - }) - }) + return + // TODO: temporarily commented out + // const self = this + // // register selected code item, highlight the corresponding source location + // if (!self.compiler.lastCompilationResult) return + // self.debugger.traceManager.getCurrentCalledAddressAt(index, (error, address) => { + // if (error) return console.log(error) + // self.debugger.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, index, self.compiler.lastCompilationResult.data.contracts, function (error, rawLocation) { + // if (!error && self.compiler.lastCompilationResult && self.compiler.lastCompilationResult.data) { + // var lineColumnPos = self.offsetToLineColumnConverter.offsetToLineColumn(rawLocation, rawLocation.file, self.compiler.lastCompilationResult.source.sources, self.compiler.lastCompilationResult.data.sources) + // self.event.trigger('newSourceLocation', [lineColumnPos, rawLocation]) + // } else { + // self.event.trigger('newSourceLocation', [null]) + // } + // }) + // }) } Debugger.prototype.updateWeb3 = function (web3) { diff --git a/remix-debug/test.js b/remix-debug/test.js new file mode 100644 index 0000000000..34ce6c03bc --- /dev/null +++ b/remix-debug/test.js @@ -0,0 +1,87 @@ + +// options +// * executionContext +// * offsetToLineColumnConverter +// *** disable for now +// * compiler +// ** lastCompilationResult + +var remixLib = require('remix-lib') +//var executionContext = remixLib.execution.executionContext + +var Debugger = require('./src/debugger/debugger.js') + +var compilation = { +} + +compilation.lastCompilationResult = require('./compilation.json') + +// connecting to a node +// var Web3 = require('web3') +// web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) +// global.my_web3 = web3 + +// with vm +var ContextManager = require('./contextManager.js') +var contextManager = new ContextManager() + +_debugger = new Debugger({ + //web3: web3, + web3: contextManager.getWeb3(), + //executionContext: executionContext, + //offsetToLineColumnConverter: this.registry.get('offsettolinecolumnconverter').api, + compiler: compilation +}) + +// with vm +contextManager.initProviders() +contextManager.event.register('providerChanged', () => { + _debugger.updateWeb3(contextManager.getWeb3()) +}) + +contextManager.switchProvider('vm') + +_debugger.event.register('debuggerStatus', function (isActive) { + console.dir("debugger status") + console.dir(isActive) +}); + +_debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { + console.dir("newSourceLocation") +}); + +_debugger.event.register('debuggerUnloaded', function() { + console.dir("debugger unloaded") +}); + +let _web3 = _debugger.debugger.web3 +// let web3 = _debugger.debugger.executionContext.web3() + + + +let blockNumber = null +let txNumber = null +let tx = null + +// let code = compilation.lastCompilationResult.data.contracts['browser/ballot.sol'].Ballot.evm.bytecode.object +// _web3.eth.sendTransaction({data: "0x" + code, from: _web3.eth.accounts[0], gas: 800000}, (err, txHash) => { +// console.dir(err) +// console.dir(txHash) +// +// txNumber = txHash +// +// _debugger.debug(blockNumber, txNumber, tx, () => { +// console.dir('debugger started') +// }) +// +// }) + +//_debugger.debug(blockNumber, txNumber, tx, () => { +// console.dir('debugger started') +//}) + +//_debugger.debugger.web3.eth.accounts() + +console.dir("done!") + +module.exports = _debugger From 888e01a6a78acdee83fb3ecaf31bac1e7ee06b05 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Wed, 10 Oct 2018 07:55:21 -0400 Subject: [PATCH 03/46] init providers only after already listening to events --- remix-debug/test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/remix-debug/test.js b/remix-debug/test.js index 34ce6c03bc..124a7dca9b 100644 --- a/remix-debug/test.js +++ b/remix-debug/test.js @@ -34,11 +34,12 @@ _debugger = new Debugger({ }) // with vm -contextManager.initProviders() contextManager.event.register('providerChanged', () => { _debugger.updateWeb3(contextManager.getWeb3()) }) +contextManager.initProviders() + contextManager.switchProvider('vm') _debugger.event.register('debuggerStatus', function (isActive) { From 00e15ce8156abe13d78b8f6ac9d72b50dbdcf90b Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Wed, 10 Oct 2018 14:50:08 -0400 Subject: [PATCH 04/46] add offsetToLineColumnConverter to remix-lib --- remix-lib/index.js | 2 ++ remix-lib/src/offsetToLineColumnConverter.js | 32 ++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 remix-lib/src/offsetToLineColumnConverter.js diff --git a/remix-lib/index.js b/remix-lib/index.js index 64304009cc..97a2f68b17 100644 --- a/remix-lib/index.js +++ b/remix-lib/index.js @@ -5,6 +5,7 @@ var uiHelper = require('./src/helpers/uiHelper') var compilerHelper = require('./src/helpers/compilerHelper') var SourceMappingDecoder = require('./src/sourceMappingDecoder') var SourceLocationTracker = require('./src/sourceLocationTracker') +var OffsetToColumnConverter = require('./src/offsetToLineColumnConverter') var init = require('./src/init') var util = require('./src/util') var Web3Providers = require('./src/web3Provider/web3Providers') @@ -56,6 +57,7 @@ function modules () { }, SourceMappingDecoder: SourceMappingDecoder, SourceLocationTracker: SourceLocationTracker, + OffsetToColumnConverter: OffsetToColumnConverter, Storage: Storage, init: init, util: util, diff --git a/remix-lib/src/offsetToLineColumnConverter.js b/remix-lib/src/offsetToLineColumnConverter.js new file mode 100644 index 0000000000..44d0458a09 --- /dev/null +++ b/remix-lib/src/offsetToLineColumnConverter.js @@ -0,0 +1,32 @@ +'use strict' +var SourceMappingDecoder = require('./sourceMappingDecoder') + +function offsetToColumnConverter (compilerEvent) { + this.lineBreakPositionsByContent = {} + this.sourceMappingDecoder = new SourceMappingDecoder() + var self = this + if (compilerEvent) { + compilerEvent.register('compilationFinished', function (success, data, source) { + self.clear() + }) + } +} + +offsetToColumnConverter.prototype.offsetToLineColumn = function (rawLocation, file, sources, asts) { + if (!this.lineBreakPositionsByContent[file]) { + for (var filename in asts) { + var source = asts[filename] + if (source.id === file) { + this.lineBreakPositionsByContent[file] = this.sourceMappingDecoder.getLinebreakPositions(sources[filename].content) + break + } + } + } + return this.sourceMappingDecoder.convertOffsetToLineColumn(rawLocation, this.lineBreakPositionsByContent[file]) +} + +offsetToColumnConverter.prototype.clear = function () { + this.lineBreakPositionsByContent = {} +} + +module.exports = offsetToColumnConverter From 693b411a5ac3afc4f4ceb65dc2660fdf52de6fa2 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Wed, 10 Oct 2018 14:51:49 -0400 Subject: [PATCH 05/46] re-add offset component; add missing vmdebugger start --- remix-debug/src/debugger/debugger.js | 47 ++++++++++++++-------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/remix-debug/src/debugger/debugger.js b/remix-debug/src/debugger/debugger.js index 4f07c76587..b6bb8ee616 100644 --- a/remix-debug/src/debugger/debugger.js +++ b/remix-debug/src/debugger/debugger.js @@ -3,6 +3,7 @@ var Ethdebugger = require('../Ethdebugger') var remixLib = require('remix-lib') var EventManager = remixLib.EventManager var traceHelper = remixLib.helpers.trace +var OffsetToColumnConverter = remixLib.OffsetToColumnConverter var StepManager = require('./stepManager') var VmDebuggerLogic = require('./VmDebugger') @@ -11,8 +12,7 @@ function Debugger (options) { var self = this this.event = new EventManager() - // TODO: temporarily commented out - // this.offsetToLineColumnConverter = options.offsetToLineColumnConverter + this.offsetToLineColumnConverter = options.offsetToLineColumnConverter || (new OffsetToColumnConverter()) this.compiler = options.compiler this.debugger = new Ethdebugger({ @@ -26,12 +26,11 @@ function Debugger (options) { } }) - // TODO: temporarily commented out - // this.breakPointManager = new remixLib.code.BreakpointManager(this.debugger, (sourceLocation) => { - // return self.offsetToLineColumnConverter.offsetToLineColumn(sourceLocation, sourceLocation.file, this.compiler.lastCompilationResult.source.sources, this.compiler.lastCompilationResult.data.sources) - // }, (step) => { - // self.event.trigger('breakpointStep', [step]) - // }) + this.breakPointManager = new remixLib.code.BreakpointManager(this.debugger, (sourceLocation) => { + return self.offsetToLineColumnConverter.offsetToLineColumn(sourceLocation, sourceLocation.file, this.compiler.lastCompilationResult.source.sources, this.compiler.lastCompilationResult.data.sources) + }, (step) => { + self.event.trigger('breakpointStep', [step]) + }) this.debugger.setBreakpointManager(this.breakPointManager) @@ -49,22 +48,20 @@ function Debugger (options) { } Debugger.prototype.registerAndHighlightCodeItem = function (index) { - return - // TODO: temporarily commented out - // const self = this - // // register selected code item, highlight the corresponding source location - // if (!self.compiler.lastCompilationResult) return - // self.debugger.traceManager.getCurrentCalledAddressAt(index, (error, address) => { - // if (error) return console.log(error) - // self.debugger.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, index, self.compiler.lastCompilationResult.data.contracts, function (error, rawLocation) { - // if (!error && self.compiler.lastCompilationResult && self.compiler.lastCompilationResult.data) { - // var lineColumnPos = self.offsetToLineColumnConverter.offsetToLineColumn(rawLocation, rawLocation.file, self.compiler.lastCompilationResult.source.sources, self.compiler.lastCompilationResult.data.sources) - // self.event.trigger('newSourceLocation', [lineColumnPos, rawLocation]) - // } else { - // self.event.trigger('newSourceLocation', [null]) - // } - // }) - // }) + const self = this + // register selected code item, highlight the corresponding source location + if (!self.compiler.lastCompilationResult) return + self.debugger.traceManager.getCurrentCalledAddressAt(index, (error, address) => { + if (error) return console.log(error) + self.debugger.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, index, self.compiler.lastCompilationResult.data.contracts, function (error, rawLocation) { + if (!error && self.compiler.lastCompilationResult && self.compiler.lastCompilationResult.data) { + var lineColumnPos = self.offsetToLineColumnConverter.offsetToLineColumn(rawLocation, rawLocation.file, self.compiler.lastCompilationResult.source.sources, self.compiler.lastCompilationResult.data.sources) + self.event.trigger('newSourceLocation', [lineColumnPos, rawLocation]) + } else { + self.event.trigger('newSourceLocation', [null]) + } + }) + }) } Debugger.prototype.updateWeb3 = function (web3) { @@ -115,8 +112,10 @@ Debugger.prototype.debugTx = function (tx, loadingCb) { }) this.vmDebuggerLogic = new VmDebuggerLogic(this.debugger, tx, this.step_manager, this.debugger.traceManager, this.debugger.codeManager, this.debugger.solidityProxy, this.debugger.callTree) + this.vmDebuggerLogic.start() this.step_manager.event.register('stepChanged', this, function (stepIndex) { + console.dir("stepChanged, going to trigger the other components.. " + stepIndex); self.debugger.codeManager.resolveStep(stepIndex, tx) self.step_manager.event.trigger('indexChanged', [stepIndex]) self.vmDebuggerLogic.event.trigger('indexChanged', [stepIndex]) From afe0e596ee960f8fdcde3f39bca79366bee420c6 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Wed, 10 Oct 2018 14:52:10 -0400 Subject: [PATCH 06/46] update test script --- remix-debug/test.js | 81 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 15 deletions(-) diff --git a/remix-debug/test.js b/remix-debug/test.js index 124a7dca9b..1b7264619f 100644 --- a/remix-debug/test.js +++ b/remix-debug/test.js @@ -17,8 +17,8 @@ var compilation = { compilation.lastCompilationResult = require('./compilation.json') // connecting to a node -// var Web3 = require('web3') -// web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) +var Web3 = require('web3') +web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // global.my_web3 = web3 // with vm @@ -40,7 +40,10 @@ contextManager.event.register('providerChanged', () => { contextManager.initProviders() -contextManager.switchProvider('vm') +contextManager.addProvider('myweb3', web3) +contextManager.switchProvider('myweb3') + +//contextManager.switchProvider('vm') _debugger.event.register('debuggerStatus', function (isActive) { console.dir("debugger status") @@ -49,6 +52,18 @@ _debugger.event.register('debuggerStatus', function (isActive) { _debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { console.dir("newSourceLocation") + + if (!lineColumnPos || !lineColumnPos.start) return; + + let line + //let line = compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line].slice(lineColumnPos.start.column, lineColumnPos.start.column + lineColumnPos.end.column) + line = compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line - 1] + console.dir(line) + line = compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line] + console.dir(line) + console.dir("^^^^^^^^^^^^^^^ ") + line = compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line + 1] + console.dir(line) }); _debugger.event.register('debuggerUnloaded', function() { @@ -64,18 +79,54 @@ let blockNumber = null let txNumber = null let tx = null -// let code = compilation.lastCompilationResult.data.contracts['browser/ballot.sol'].Ballot.evm.bytecode.object -// _web3.eth.sendTransaction({data: "0x" + code, from: _web3.eth.accounts[0], gas: 800000}, (err, txHash) => { -// console.dir(err) -// console.dir(txHash) -// -// txNumber = txHash -// -// _debugger.debug(blockNumber, txNumber, tx, () => { -// console.dir('debugger started') -// }) -// -// }) +let code = compilation.lastCompilationResult.data.contracts['browser/ballot.sol'].Ballot.evm.bytecode.object +_web3.eth.sendTransaction({data: "0x" + code, from: _web3.eth.accounts[0], gas: 800000}, (err, txHash) => { + //console.dir(err) + //console.dir(txHash) + + + txNumber = txHash + global.mytx = txHash + + _debugger.event.register('newSourceLocation', (lineColumnPos, rawLocation) => { + console.dir("************ new source location *********") + console.dir(lineColumnPos) + console.dir(rawLocation) + }) + + _debugger.debug(blockNumber, txNumber, tx, () => { + + _debugger.step_manager.event.register('stepChanged', (stepIndex) => { + console.dir("---------") + console.dir("stepChanged: " + stepIndex) + console.dir("---------") + }) + + _debugger.step_manager.event.register('traceLengthChanged', (traceLength) => { + console.dir("---------") + console.dir("traceLengthChanged: " + traceLength) + console.dir("---------") + }); + + _debugger.vmDebuggerLogic.event.register('codeManagerChanged', (code, address, index) => { + console.dir("---------") + console.dir("codeManagerChanged") + console.dir("address: " + address) + console.dir("asm code: " + code[index]) + console.dir("---------") + }); + + _debugger.vmDebuggerLogic.event.register('traceManagerMemoryUpdate', (data) => { + console.dir("---------") + console.dir("traceManagerMemoryUpdate") + console.dir(data) + console.dir("---------") + }); + + console.dir('debugger started') + }) + +}) //_debugger.debug(blockNumber, txNumber, tx, () => { // console.dir('debugger started') From 1f0e23b5655bb42d0ba9b0b107c829d5f5ecc3a4 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Thu, 11 Oct 2018 10:31:51 -0400 Subject: [PATCH 07/46] add basic cmd line debugger --- remix-debug/rdb.js | 59 ++++++++ .../{ => src/cmdline}/contextManager.js | 0 remix-debug/src/cmdline/index.js | 103 +++++++++++++ remix-debug/test.js | 139 ------------------ 4 files changed, 162 insertions(+), 139 deletions(-) create mode 100644 remix-debug/rdb.js rename remix-debug/{ => src/cmdline}/contextManager.js (100%) create mode 100644 remix-debug/src/cmdline/index.js delete mode 100644 remix-debug/test.js diff --git a/remix-debug/rdb.js b/remix-debug/rdb.js new file mode 100644 index 0000000000..19b589b424 --- /dev/null +++ b/remix-debug/rdb.js @@ -0,0 +1,59 @@ +var CmdLine = require('./src/cmdline/index.js') + +var compilation = require('./compilation.json') + +var cmd_line = new CmdLine() +cmd_line.connect("http", "http://localhost:8545") +cmd_line.loadCompilationResult(compilation) +cmd_line.initDebugger() + +var deployContract = function (cb) { + let _web3 = cmd_line.debugger.debugger.web3 + + let blockNumber = null + let txNumber = null + let tx = null + + let code = compilation.data.contracts['browser/ballot.sol'].Ballot.evm.bytecode.object + _web3.eth.sendTransaction({data: "0x" + code, from: _web3.eth.accounts[0], gas: 800000}, cb) +} + +deployContract((err, tx) => { + cmd_line.startDebug(tx, "browser/ballot.sol") +}) + +const repl = require('repl') + +const r = repl.start({ + prompt: '> ', + eval: (cmd, context, filename, cb) => { + let command = cmd.trim() + if (command === 'next' || command === 'n') { + cmd_line.debugger.step_manager.stepOverForward() + } + if (command === 'previous' || command === 'p' || command === 'prev') { + cmd_line.debugger.step_manager.stepOverBack() + } + if (command === 'step' || command === 's') { + cmd_line.debugger.step_manager.stepIntoForward() + } + if (command === 'stepback' || command === 'sb') { + cmd_line.debugger.step_manager.stepIntoBack() + } + if (command === 'exit' || command === 'quit') { + process.exit(0) + } + if (command === 'var local' || command === 'v l' || command === 'vl') { + cmd_line.displayLocals() + } + if (command === 'var global' || command === 'v g' || command === 'vg') { + cmd_line.displayGlobals() + } + if (command.split(' ')[0] === 'jump') { + let stepIndex = parseInt(command.split(' ')[1], 10) + cmd_line.debugger.step_manager.jumpTo(stepIndex) + } + cb(null, ''); + } +}); + diff --git a/remix-debug/contextManager.js b/remix-debug/src/cmdline/contextManager.js similarity index 100% rename from remix-debug/contextManager.js rename to remix-debug/src/cmdline/contextManager.js diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js new file mode 100644 index 0000000000..dabcc358c5 --- /dev/null +++ b/remix-debug/src/cmdline/index.js @@ -0,0 +1,103 @@ +var Web3 = require('web3') +var Debugger = require('../debugger/debugger.js') +var ContextManager = require('./contextManager.js') + +class CmdLine { + + constructor () { + } + + connect (providerType, url) { + if (providerType !== 'http') throw new Error("unsupported provider type") + this.web3 = new Web3(new Web3.providers.HttpProvider(url)) + } + + loadCompilationResult (compilationResult) { + this.compilation = {} + this.compilation.lastCompilationResult = compilationResult + } + + initDebugger () { + const self = this + this.contextManager = new ContextManager() + + this.debugger = new Debugger({ + web3: this.contextManager.getWeb3(), + compiler: this.compilation + }) + + this.contextManager.event.register('providerChanged', () => { + self.debugger.updateWeb3(self.contextManager.getWeb3()) + }) + + this.contextManager.initProviders() + + this.contextManager.addProvider('debugger_web3', this.web3) + this.contextManager.switchProvider('debugger_web3') + } + + // TODO: is filename really necessary? + startDebug(txNumber, filename) { + const self = this + this.debugger.debug(null, txNumber, null, () => { + + self.debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { + console.dir("newSourceLocation") + + if (!lineColumnPos || !lineColumnPos.start) return; + + let line + line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line - 1] + console.dir(line) + line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line] + console.dir(line) + console.dir("^^^^^^^^^^^^^^^ ") + line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line + 1] + console.dir(line) + }); + + self.debugger.step_manager.event.register('stepChanged', (stepIndex) => { + // console.dir("---------") + // console.dir("stepChanged: " + stepIndex) + // console.dir("---------") + }) + + self.debugger.step_manager.event.register('traceLengthChanged', (traceLength) => { + // console.dir("---------") + // console.dir("traceLengthChanged: " + traceLength) + // console.dir("---------") + }); + + self.debugger.vmDebuggerLogic.event.register('solidityState', (data) => { + self.solidityState = data + }); + + self.debugger.vmDebuggerLogic.event.register('solidityLocals', (data) => { + self.solidityLocals = data + }); + + self.debugger.vmDebuggerLogic.event.register('traceManagerMemoryUpdate', (data) => { + // console.dir("---------") + // console.dir("traceManagerMemoryUpdate") + // console.dir(data) + // console.dir("---------") + }); + + }) + } + + displayLocals () { + console.dir(this.solidityLocals) + } + + displayGlobals () { + console.dir(this.solidityState) + if (this.solidityState && this.solidityState.voters) { + console.dir(this.solidityState.voters) + console.dir(this.solidityState.voters.value) + } + } +} + +module.exports = CmdLine + diff --git a/remix-debug/test.js b/remix-debug/test.js deleted file mode 100644 index 1b7264619f..0000000000 --- a/remix-debug/test.js +++ /dev/null @@ -1,139 +0,0 @@ - -// options -// * executionContext -// * offsetToLineColumnConverter -// *** disable for now -// * compiler -// ** lastCompilationResult - -var remixLib = require('remix-lib') -//var executionContext = remixLib.execution.executionContext - -var Debugger = require('./src/debugger/debugger.js') - -var compilation = { -} - -compilation.lastCompilationResult = require('./compilation.json') - -// connecting to a node -var Web3 = require('web3') -web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) -// global.my_web3 = web3 - -// with vm -var ContextManager = require('./contextManager.js') -var contextManager = new ContextManager() - -_debugger = new Debugger({ - //web3: web3, - web3: contextManager.getWeb3(), - //executionContext: executionContext, - //offsetToLineColumnConverter: this.registry.get('offsettolinecolumnconverter').api, - compiler: compilation -}) - -// with vm -contextManager.event.register('providerChanged', () => { - _debugger.updateWeb3(contextManager.getWeb3()) -}) - -contextManager.initProviders() - -contextManager.addProvider('myweb3', web3) -contextManager.switchProvider('myweb3') - -//contextManager.switchProvider('vm') - -_debugger.event.register('debuggerStatus', function (isActive) { - console.dir("debugger status") - console.dir(isActive) -}); - -_debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { - console.dir("newSourceLocation") - - if (!lineColumnPos || !lineColumnPos.start) return; - - let line - //let line = compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line].slice(lineColumnPos.start.column, lineColumnPos.start.column + lineColumnPos.end.column) - line = compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line - 1] - console.dir(line) - line = compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line] - console.dir(line) - console.dir("^^^^^^^^^^^^^^^ ") - line = compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line + 1] - console.dir(line) -}); - -_debugger.event.register('debuggerUnloaded', function() { - console.dir("debugger unloaded") -}); - -let _web3 = _debugger.debugger.web3 -// let web3 = _debugger.debugger.executionContext.web3() - - - -let blockNumber = null -let txNumber = null -let tx = null - -let code = compilation.lastCompilationResult.data.contracts['browser/ballot.sol'].Ballot.evm.bytecode.object -_web3.eth.sendTransaction({data: "0x" + code, from: _web3.eth.accounts[0], gas: 800000}, (err, txHash) => { - //console.dir(err) - //console.dir(txHash) - - - txNumber = txHash - global.mytx = txHash - - _debugger.event.register('newSourceLocation', (lineColumnPos, rawLocation) => { - console.dir("************ new source location *********") - console.dir(lineColumnPos) - console.dir(rawLocation) - }) - - _debugger.debug(blockNumber, txNumber, tx, () => { - - _debugger.step_manager.event.register('stepChanged', (stepIndex) => { - console.dir("---------") - console.dir("stepChanged: " + stepIndex) - console.dir("---------") - }) - - _debugger.step_manager.event.register('traceLengthChanged', (traceLength) => { - console.dir("---------") - console.dir("traceLengthChanged: " + traceLength) - console.dir("---------") - }); - - _debugger.vmDebuggerLogic.event.register('codeManagerChanged', (code, address, index) => { - console.dir("---------") - console.dir("codeManagerChanged") - console.dir("address: " + address) - console.dir("asm code: " + code[index]) - console.dir("---------") - }); - - _debugger.vmDebuggerLogic.event.register('traceManagerMemoryUpdate', (data) => { - console.dir("---------") - console.dir("traceManagerMemoryUpdate") - console.dir(data) - console.dir("---------") - }); - - console.dir('debugger started') - }) - -}) - -//_debugger.debug(blockNumber, txNumber, tx, () => { -// console.dir('debugger started') -//}) - -//_debugger.debugger.web3.eth.accounts() - -console.dir("done!") - -module.exports = _debugger From af2c763f80b4862479eef5705c2c8234f4bd0730 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Thu, 11 Oct 2018 10:51:50 -0400 Subject: [PATCH 08/46] improve displaying current step --- remix-debug/src/cmdline/index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index dabcc358c5..6cacf83974 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -48,12 +48,13 @@ class CmdLine { let line line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line - 1] - console.dir(line) + console.dir(" " + (lineColumnPos.start.line - 1) + " " + line) line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line] - console.dir(line) - console.dir("^^^^^^^^^^^^^^^ ") + console.dir("=> " + lineColumnPos.start.line + " " + line) line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line + 1] - console.dir(line) + console.dir(" " + (lineColumnPos.start.line + 1) + " " + line) + line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line + 2] + console.dir(" " + (lineColumnPos.start.line + 2) + " " + line) }); self.debugger.step_manager.event.register('stepChanged', (stepIndex) => { From b8c7e30dff2a7de206941a5a2ae64fc7ac833dee Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Thu, 11 Oct 2018 13:02:02 -0400 Subject: [PATCH 09/46] add resolveToReducedTrace; clean up; improve output --- remix-debug/rdb.js | 8 +-- remix-debug/src/Ethdebugger.js | 1 - remix-debug/src/cmdline/index.js | 51 ++++++++----------- remix-debug/src/debugger/debugger.js | 1 - remix-debug/src/debugger/stepManager.js | 40 +++++++++++++-- .../src/solidity-decoder/internalCallTree.js | 4 +- .../src/solidity-decoder/solidityProxy.js | 2 +- 7 files changed, 64 insertions(+), 43 deletions(-) diff --git a/remix-debug/rdb.js b/remix-debug/rdb.js index 19b589b424..3eb2bf55af 100644 --- a/remix-debug/rdb.js +++ b/remix-debug/rdb.js @@ -29,16 +29,16 @@ const r = repl.start({ eval: (cmd, context, filename, cb) => { let command = cmd.trim() if (command === 'next' || command === 'n') { - cmd_line.debugger.step_manager.stepOverForward() + cmd_line.debugger.step_manager.stepOverForward(true) } if (command === 'previous' || command === 'p' || command === 'prev') { - cmd_line.debugger.step_manager.stepOverBack() + cmd_line.debugger.step_manager.stepOverBack(true) } if (command === 'step' || command === 's') { - cmd_line.debugger.step_manager.stepIntoForward() + cmd_line.debugger.step_manager.stepIntoForward(true) } if (command === 'stepback' || command === 'sb') { - cmd_line.debugger.step_manager.stepIntoBack() + cmd_line.debugger.step_manager.stepIntoBack(true) } if (command === 'exit' || command === 'quit') { process.exit(0) diff --git a/remix-debug/src/Ethdebugger.js b/remix-debug/src/Ethdebugger.js index 8f325280d7..7545bebebb 100644 --- a/remix-debug/src/Ethdebugger.js +++ b/remix-debug/src/Ethdebugger.js @@ -183,7 +183,6 @@ Ethdebugger.prototype.debug = function (tx) { tx.to = traceHelper.contractCreationToken('0') } this.setCompilationResult(this.opts.compilationResult()) - console.log('loading trace...') this.tx = tx var self = this this.traceManager.resolveTrace(tx, function (error, result) { diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index 6cacf83974..bb27b6fdab 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -42,48 +42,41 @@ class CmdLine { this.debugger.debug(null, txNumber, null, () => { self.debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { - console.dir("newSourceLocation") - if (!lineColumnPos || !lineColumnPos.start) return; - let line - line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line - 1] - console.dir(" " + (lineColumnPos.start.line - 1) + " " + line) - line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line] - console.dir("=> " + lineColumnPos.start.line + " " + line) - line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line + 1] - console.dir(" " + (lineColumnPos.start.line + 1) + " " + line) - line = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n")[lineColumnPos.start.line + 2] - console.dir(" " + (lineColumnPos.start.line + 2) + " " + line) - }); - - self.debugger.step_manager.event.register('stepChanged', (stepIndex) => { - // console.dir("---------") - // console.dir("stepChanged: " + stepIndex) - // console.dir("---------") - }) + let content = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n") - self.debugger.step_manager.event.register('traceLengthChanged', (traceLength) => { - // console.dir("---------") - // console.dir("traceLengthChanged: " + traceLength) - // console.dir("---------") + let line + line = content[lineColumnPos.start.line - 2] + if ( line !== undefined) { + console.dir(" " + (lineColumnPos.start.line - 1) + ": " + line) + } + line = content[lineColumnPos.start.line - 1] + if ( line !== undefined) { + console.dir(" " + lineColumnPos.start.line + ": " + line) + } + + let currentLineNumber = lineColumnPos.start.line + let currentLine = content[currentLineNumber] + console.dir("=> " + (currentLineNumber + 1) + ": " + currentLine) + + let startLine = lineColumnPos.start.line + for (var i=1; i < 4; i++) { + let line = content[startLine + i] + console.dir(" " + (startLine + i + 1) + ": " + line) + } }); self.debugger.vmDebuggerLogic.event.register('solidityState', (data) => { self.solidityState = data }); + // TODO: this doesnt work too well, it should request the data instead... self.debugger.vmDebuggerLogic.event.register('solidityLocals', (data) => { + if (JSON.stringify(data) === '{}') return self.solidityLocals = data }); - self.debugger.vmDebuggerLogic.event.register('traceManagerMemoryUpdate', (data) => { - // console.dir("---------") - // console.dir("traceManagerMemoryUpdate") - // console.dir(data) - // console.dir("---------") - }); - }) } diff --git a/remix-debug/src/debugger/debugger.js b/remix-debug/src/debugger/debugger.js index b6bb8ee616..de0ba0d386 100644 --- a/remix-debug/src/debugger/debugger.js +++ b/remix-debug/src/debugger/debugger.js @@ -115,7 +115,6 @@ Debugger.prototype.debugTx = function (tx, loadingCb) { this.vmDebuggerLogic.start() this.step_manager.event.register('stepChanged', this, function (stepIndex) { - console.dir("stepChanged, going to trigger the other components.. " + stepIndex); self.debugger.codeManager.resolveStep(stepIndex, tx) self.step_manager.event.trigger('indexChanged', [stepIndex]) self.vmDebuggerLogic.event.trigger('indexChanged', [stepIndex]) diff --git a/remix-debug/src/debugger/stepManager.js b/remix-debug/src/debugger/stepManager.js index 26e48ecd4b..eb64ffe401 100644 --- a/remix-debug/src/debugger/stepManager.js +++ b/remix-debug/src/debugger/stepManager.js @@ -1,5 +1,6 @@ var remixLib = require('remix-lib') var EventManager = remixLib.EventManager +var util = remixLib.util class DebuggerStepManager { @@ -81,43 +82,58 @@ class DebuggerStepManager { }) } - stepIntoBack () { + stepIntoBack (solidityMode) { if (!this.traceManager.isLoaded()) return var step = this.currentStepIndex - 1 this.currentStepIndex = step + if (solidityMode) { + step = this.resolveToReducedTrace(step, -1) + } if (!this.traceManager.inRange(step)) { return } this.event.trigger('stepChanged', [step]) } - stepIntoForward () { + stepIntoForward (solidityMode) { if (!this.traceManager.isLoaded()) return var step = this.currentStepIndex + 1 this.currentStepIndex = step + if (solidityMode) { + step = this.resolveToReducedTrace(step, 1) + } if (!this.traceManager.inRange(step)) { return } this.event.trigger('stepChanged', [step]) } - stepOverBack () { + stepOverBack (solidityMode) { if (!this.traceManager.isLoaded()) return var step = this.traceManager.findStepOverBack(this.currentStepIndex) + if (solidityMode) { + step = this.resolveToReducedTrace(step, -1) + } this.currentStepIndex = step this.event.trigger('stepChanged', [step]) } - stepOverForward () { + stepOverForward (solidityMode) { if (!this.traceManager.isLoaded()) return var step = this.traceManager.findStepOverForward(this.currentStepIndex) + if (solidityMode) { + step = this.resolveToReducedTrace(step, 1) + } this.currentStepIndex = step this.event.trigger('stepChanged', [step]) } - jumpOut () { + jumpOut (solidityMode) { if (!this.traceManager.isLoaded()) return var step = this.traceManager.findStepOut(this.currentStepIndex) + if (solidityMode) { + step = this.resolveToReducedTrace(step, 0) + } this.currentStepIndex = step this.event.trigger('stepChanged', [step]) } @@ -140,6 +156,20 @@ class DebuggerStepManager { this.debugger.breakpointManager.jumpPreviousBreakpoint(this.currentStepIndex, true) } + resolveToReducedTrace (value, incr) { + if (this.debugger.callTree.reducedTrace.length) { + var nextSource = util.findClosestIndex(value, this.debugger.callTree.reducedTrace) + nextSource = nextSource + incr + if (nextSource <= 0) { + nextSource = 0 + } else if (nextSource > this.debugger.callTree.reducedTrace.length) { + nextSource = this.debugger.callTree.reducedTrace.length - 1 + } + return this.debugger.callTree.reducedTrace[nextSource] + } + return value + } + } module.exports = DebuggerStepManager diff --git a/remix-debug/src/solidity-decoder/internalCallTree.js b/remix-debug/src/solidity-decoder/internalCallTree.js index 1f2559c0d8..974241de97 100644 --- a/remix-debug/src/solidity-decoder/internalCallTree.js +++ b/remix-debug/src/solidity-decoder/internalCallTree.js @@ -230,7 +230,7 @@ function resolveVariableDeclaration (tree, step, sourceLocation) { if (ast) { tree.variableDeclarationByFile[sourceLocation.file] = extractVariableDeclarations(ast, tree.astWalker) } else { - console.log('Ast not found for step ' + step + '. file ' + sourceLocation.file) + // console.log('Ast not found for step ' + step + '. file ' + sourceLocation.file) return null } } @@ -243,7 +243,7 @@ function resolveFunctionDefinition (tree, step, sourceLocation) { if (ast) { tree.functionDefinitionByFile[sourceLocation.file] = extractFunctionDefinitions(ast, tree.astWalker) } else { - console.log('Ast not found for step ' + step + '. file ' + sourceLocation.file) + // console.log('Ast not found for step ' + step + '. file ' + sourceLocation.file) return null } } diff --git a/remix-debug/src/solidity-decoder/solidityProxy.js b/remix-debug/src/solidity-decoder/solidityProxy.js index 63a42670e3..1fdb293315 100644 --- a/remix-debug/src/solidity-decoder/solidityProxy.js +++ b/remix-debug/src/solidity-decoder/solidityProxy.js @@ -117,7 +117,7 @@ class SolidityProxy { if (this.sources[file]) { return this.sources[file].legacyAST } else { - console.log('AST not found for file id ' + sourceLocation.file) + // console.log('AST not found for file id ' + sourceLocation.file) return null } } From cff01523d944f844084fcf8bb4ff97dd4bfd4594 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Tue, 16 Oct 2018 12:37:34 -0400 Subject: [PATCH 10/46] update lib; remove various console logs --- remix-debug/index.js | 4 +- remix-debug/package.json | 4 ++ remix-debug/rdb.js | 66 +++++++++++++++++-- remix-debug/src/cmdline/contextManager.js | 2 +- remix-debug/src/cmdline/index.js | 2 +- remix-debug/src/debugger/VmDebugger.js | 10 +-- .../src/solidity-decoder/internalCallTree.js | 1 - remix-debug/test/sol/ballot.sol | 65 ++++++++++++++++++ remix-debug/test/sol/simple_storage.sol | 22 +++++++ remix-lib/src/code/codeResolver.js | 1 - 10 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 remix-debug/test/sol/ballot.sol create mode 100644 remix-debug/test/sol/simple_storage.sol diff --git a/remix-debug/index.js b/remix-debug/index.js index 3ea8d98482..6c90d8fb0c 100644 --- a/remix-debug/index.js +++ b/remix-debug/index.js @@ -1,6 +1,7 @@ 'use strict' var EthDebugger = require('./src/Ethdebugger') var TransactionDebugger = require('./src/debugger/debugger') +var CmdLine = require('./src/cmdline') var StorageViewer = require('./src/storage/storageViewer') var StorageResolver = require('./src/storage/storageResolver') @@ -32,6 +33,7 @@ module.exports = { storage: { StorageViewer: StorageViewer, StorageResolver: StorageResolver - } + }, + CmdLine: CmdLine } diff --git a/remix-debug/package.json b/remix-debug/package.json index 097640ec00..3e7c3de0b2 100644 --- a/remix-debug/package.json +++ b/remix-debug/package.json @@ -10,6 +10,10 @@ { "name": "Liana Husikyan", "email": "liana@ethdev.com" + }, + { + "name": "Iuri Matias", + "email": "iuri.matias@gmail.com" } ], "main": "./index.js", diff --git a/remix-debug/rdb.js b/remix-debug/rdb.js index 3eb2bf55af..d0b14be406 100644 --- a/remix-debug/rdb.js +++ b/remix-debug/rdb.js @@ -1,7 +1,46 @@ var CmdLine = require('./src/cmdline/index.js') - var compilation = require('./compilation.json') +var solc = require('solc') +var fs = require('fs') + +//var filename = 'test/sol/ballot.sol' +var filename = 'test/sol/simple_storage.sol' +//var filename = 'browser/ballot.sol' + +var input_json = { + language: 'Solidity', + sources: { + //"test/sol/ballot.sol": {content: fs.readFileSync('test/sol/ballot.sol').toString()} + }, + settings: { + optimizer: { + enabled: true, + runs: 200 + }, + outputSelection: { + '*': { + '': [ 'legacyAST' ], + '*': [ 'abi', 'metadata', 'devdoc', 'userdoc', 'evm.legacyAssembly', 'evm.bytecode', 'evm.deployedBytecode', 'evm.methodIdentifiers', 'evm.gasEstimates' ] + } + } + } +} + +input_json.sources[filename] = {content: fs.readFileSync(filename).toString()} + +console.dir(input_json) + +console.log("compiling...") + +let compilationData = JSON.parse(solc.compileStandardWrapper(JSON.stringify(input_json))) +console.dir(Object.keys(compilationData)) +var compilation = {} +compilation.data = compilationData +compilation.source = { sources: input_json.sources } +console.dir(compilation) +console.dir(compilation.data.errors) + var cmd_line = new CmdLine() cmd_line.connect("http", "http://localhost:8545") cmd_line.loadCompilationResult(compilation) @@ -14,13 +53,27 @@ var deployContract = function (cb) { let txNumber = null let tx = null - let code = compilation.data.contracts['browser/ballot.sol'].Ballot.evm.bytecode.object + let code = compilation.data.contracts[filename].SimpleStorage.evm.bytecode.object + console.dir("deploying...") + console.dir(code) _web3.eth.sendTransaction({data: "0x" + code, from: _web3.eth.accounts[0], gas: 800000}, cb) } -deployContract((err, tx) => { - cmd_line.startDebug(tx, "browser/ballot.sol") -}) +let _web3 = cmd_line.debugger.debugger.web3 +// var tx = "0x8c44e1b6bcb557512184f851502e43160f415e2e12b2b98ba12b96b699b85859" +// var tx = "0xae365458de8c6669eb146ce2ade4c7767c0edddaee98f5c1878c7c5e5510a0de" +// var tx = "0x04aa74287b3c52e2ecab1cb066d22116317155503681870c516c95cdb148fa28" +// var tx = "0x04aa74287b3c52e2ecab1cb066d22116317155503681870c516c95cdb148fa28" +// var tx = "0x28bd66d99bc45b3f8d959126a26b8c97092892e63fc8ed90eb1598ebedf600ef" +// var tx = "0x3a7355c59f95db494872f33890dbabaceae1ca5330db86db49d24a5c29cd829a" +// _web3.eth.getTransactionReceipt(tx, (err, data) => { +// console.dir(err) +// console.dir(data) + + deployContract((err, tx) => { + cmd_line.startDebug(tx, filename) + }) +//}) const repl = require('repl') @@ -57,3 +110,6 @@ const r = repl.start({ } }); +module.exports = cmd_line + + diff --git a/remix-debug/src/cmdline/contextManager.js b/remix-debug/src/cmdline/contextManager.js index 8a1b1b70d2..82e165df34 100644 --- a/remix-debug/src/cmdline/contextManager.js +++ b/remix-debug/src/cmdline/contextManager.js @@ -37,7 +37,7 @@ class ContextManager { var self = this this.web3Providers.get(type, function (error, obj) { if (error) { - console.log('provider ' + type + ' not defined') + // console.log('provider ' + type + ' not defined') } else { self.web3 = obj self.executionContext.detectNetwork((error, network) => { diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index bb27b6fdab..56d5044e77 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -44,7 +44,7 @@ class CmdLine { self.debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { if (!lineColumnPos || !lineColumnPos.start) return; - let content = self.compilation.lastCompilationResult.source.sources['browser/ballot.sol'].content.split("\n") + let content = self.compilation.lastCompilationResult.source.sources[filename].content.split("\n") let line line = content[lineColumnPos.start.line - 2] diff --git a/remix-debug/src/debugger/VmDebugger.js b/remix-debug/src/debugger/VmDebugger.js index 32562d5a86..a21e5c5f61 100644 --- a/remix-debug/src/debugger/VmDebugger.js +++ b/remix-debug/src/debugger/VmDebugger.js @@ -64,7 +64,7 @@ class VmDebuggerLogic { self._traceManager.getCallDataAt(index, function (error, calldata) { if (error) { - console.log(error) + // console.log(error) self.event.trigger('traceManagerCallDataUpdate', [{}]) } else if (self.stepManager.currentStepIndex === index) { self.event.trigger('traceManagerCallDataUpdate', [calldata]) @@ -73,7 +73,7 @@ class VmDebuggerLogic { self._traceManager.getMemoryAt(index, function (error, memory) { if (error) { - console.log(error) + // console.log(error) self.event.trigger('traceManagerMemoryUpdate', [{}]) } else if (self.stepManager.currentStepIndex === index) { self.event.trigger('traceManagerMemoryUpdate', [ui.formatMemory(memory, 16)]) @@ -82,7 +82,7 @@ class VmDebuggerLogic { self._traceManager.getCallStackAt(index, function (error, callstack) { if (error) { - console.log(error) + // console.log(error) self.event.trigger('traceManagerCallStackUpdate', [{}]) } else if (self.stepManager.currentStepIndex === index) { self.event.trigger('traceManagerCallStackUpdate', [callstack]) @@ -91,7 +91,7 @@ class VmDebuggerLogic { self._traceManager.getStackAt(index, function (error, callstack) { if (error) { - console.log(error) + // console.log(error) self.event.trigger('traceManagerStackUpdate', [{}]) } else if (self.stepManager.currentStepIndex === index) { self.event.trigger('traceManagerStackUpdate', [callstack]) @@ -106,7 +106,7 @@ class VmDebuggerLogic { storageViewer.storageRange((error, storage) => { if (error) { - console.log(error) + // console.log(error) self.event.trigger('traceManagerStorageUpdate', [{}]) } else if (self.stepManager.currentStepIndex === index) { var header = storageViewer.isComplete(address) ? 'completely loaded' : 'partially loaded...' diff --git a/remix-debug/src/solidity-decoder/internalCallTree.js b/remix-debug/src/solidity-decoder/internalCallTree.js index 974241de97..16e1c2bb3d 100644 --- a/remix-debug/src/solidity-decoder/internalCallTree.js +++ b/remix-debug/src/solidity-decoder/internalCallTree.js @@ -38,7 +38,6 @@ class InternalCallTree { if (result.error) { this.event.trigger('callTreeBuildFailed', [result.error]) } else { - console.log('ready') createReducedTrace(this, traceManager.trace.length - 1) this.event.trigger('callTreeReady', [this.scopes, this.scopeStarts]) } diff --git a/remix-debug/test/sol/ballot.sol b/remix-debug/test/sol/ballot.sol new file mode 100644 index 0000000000..ec43956ce9 --- /dev/null +++ b/remix-debug/test/sol/ballot.sol @@ -0,0 +1,65 @@ +pragma solidity ^0.4.0; +contract Ballot { + + struct Voter { + uint weight; + bool voted; + uint8 vote; + address delegate; + } + struct Proposal { + uint voteCount; + } + + address chairperson; + mapping(address => Voter) voters; + Proposal[] proposals; + + /// Create a new ballot with $(_numProposals) different proposals. + function Ballot(uint8 _numProposals) public { + chairperson = msg.sender; + voters[chairperson].weight = 1; + proposals.length = _numProposals; + } + + /// Give $(toVoter) the right to vote on this ballot. + /// May only be called by $(chairperson). + function giveRightToVote(address toVoter) public { + if (msg.sender != chairperson || voters[toVoter].voted) return; + voters[toVoter].weight = 1; + } + + /// Delegate your vote to the voter $(to). + function delegate(address to) public { + Voter storage sender = voters[msg.sender]; // assigns reference + if (sender.voted) return; + while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender) + to = voters[to].delegate; + if (to == msg.sender) return; + sender.voted = true; + sender.delegate = to; + Voter storage delegateTo = voters[to]; + if (delegateTo.voted) + proposals[delegateTo.vote].voteCount += sender.weight; + else + delegateTo.weight += sender.weight; + } + + /// Give a single vote to proposal $(toProposal). + function vote(uint8 toProposal) public { + Voter storage sender = voters[msg.sender]; + if (sender.voted || toProposal >= proposals.length) return; + sender.voted = true; + sender.vote = toProposal; + proposals[toProposal].voteCount += sender.weight; + } + + function winningProposal() public constant returns (uint8 _winningProposal) { + uint256 winningVoteCount = 0; + for (uint8 prop = 0; prop < proposals.length; prop++) + if (proposals[prop].voteCount > winningVoteCount) { + winningVoteCount = proposals[prop].voteCount; + _winningProposal = prop; + } + } +} diff --git a/remix-debug/test/sol/simple_storage.sol b/remix-debug/test/sol/simple_storage.sol new file mode 100644 index 0000000000..00b1554807 --- /dev/null +++ b/remix-debug/test/sol/simple_storage.sol @@ -0,0 +1,22 @@ +pragma solidity ^0.4.25; + +contract SimpleStorage { + uint public storedData; + address owner; + + constructor(uint initialValue) public { + storedData = initialValue; + owner = msg.sender; + } + + function set(uint x) public { + storedData = x; + require(msg.sender != owner); + storedData = x + 2; + } + + function get() public view returns (uint retVal) { + return storedData; + } + +} diff --git a/remix-lib/src/code/codeResolver.js b/remix-lib/src/code/codeResolver.js index 363fb5aaff..da52a74d3c 100644 --- a/remix-lib/src/code/codeResolver.js +++ b/remix-lib/src/code/codeResolver.js @@ -29,7 +29,6 @@ CodeResolver.prototype.resolveCode = function (address, callBack) { } CodeResolver.prototype.loadCode = function (address, callback) { - console.log('loading new code from web3 ' + address) this.web3.eth.getCode(address, function (error, result) { if (error) { console.log(error) From 53a3fa57908d5124461dd51ba59f7d287ac678cc Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Tue, 16 Oct 2018 13:18:34 -0400 Subject: [PATCH 11/46] don't print source automatically; has to be required instead --- remix-debug/src/cmdline/index.js | 69 +++++++++++++++-------- remix-debug/src/debugger/solidityState.js | 7 ++- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index 56d5044e77..a1ae0cfade 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -1,10 +1,13 @@ var Web3 = require('web3') var Debugger = require('../debugger/debugger.js') var ContextManager = require('./contextManager.js') +var EventManager = require('events') class CmdLine { constructor () { + this.events = new EventManager() + this.lineColumnPos = null } connect (providerType, url) { @@ -36,35 +39,53 @@ class CmdLine { this.contextManager.switchProvider('debugger_web3') } + getSource() { + const self = this + + console.dir("getSource") + console.dir(this.lineColumnPos) + console.dir(this.filename) + + let lineColumnPos = this.lineColumnPos + + if (!lineColumnPos || !lineColumnPos.start) return; + + let content = self.compilation.lastCompilationResult.source.sources[this.filename].content.split("\n") + + let source = [] + + let line + line = content[lineColumnPos.start.line - 2] + if ( line !== undefined) { + source.push(" " + (lineColumnPos.start.line - 1) + ": " + line) + } + line = content[lineColumnPos.start.line - 1] + if ( line !== undefined) { + source.push(" " + lineColumnPos.start.line + ": " + line) + } + + let currentLineNumber = lineColumnPos.start.line + let currentLine = content[currentLineNumber] + source.push("=> " + (currentLineNumber + 1) + ": " + currentLine) + + let startLine = lineColumnPos.start.line + for (var i=1; i < 4; i++) { + let line = content[startLine + i] + source.push(" " + (startLine + i + 1) + ": " + line) + } + + return source + } + // TODO: is filename really necessary? startDebug(txNumber, filename) { const self = this + this.filename = filename this.debugger.debug(null, txNumber, null, () => { - self.debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { - if (!lineColumnPos || !lineColumnPos.start) return; - - let content = self.compilation.lastCompilationResult.source.sources[filename].content.split("\n") - - let line - line = content[lineColumnPos.start.line - 2] - if ( line !== undefined) { - console.dir(" " + (lineColumnPos.start.line - 1) + ": " + line) - } - line = content[lineColumnPos.start.line - 1] - if ( line !== undefined) { - console.dir(" " + lineColumnPos.start.line + ": " + line) - } - - let currentLineNumber = lineColumnPos.start.line - let currentLine = content[currentLineNumber] - console.dir("=> " + (currentLineNumber + 1) + ": " + currentLine) - - let startLine = lineColumnPos.start.line - for (var i=1; i < 4; i++) { - let line = content[startLine + i] - console.dir(" " + (startLine + i + 1) + ": " + line) - } + self.debugger.event.register('newSourceLocation', function (lineColumnPos, _rawLocation) { + self.lineColumnPos = lineColumnPos + self.events.emit("source") }); self.debugger.vmDebuggerLogic.event.register('solidityState', (data) => { diff --git a/remix-debug/src/debugger/solidityState.js b/remix-debug/src/debugger/solidityState.js index 8f2896c71c..d95894beca 100644 --- a/remix-debug/src/debugger/solidityState.js +++ b/remix-debug/src/debugger/solidityState.js @@ -36,7 +36,12 @@ class DebuggerSolidityState { } self.event.trigger('solidityStateUpdating') decodeTimeout = setTimeout(function () { - self.decode(index) + // necessary due to some states that can crash the debugger + try { + self.decode(index) + } catch(err) { + } + }, 500) } From 316f912a24806f44d4f199498fe3f679a302cbe8 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Tue, 16 Oct 2018 16:31:29 -0400 Subject: [PATCH 12/46] display errors --- remix-debug/rdb.js | 17 +++++++++++------ remix-debug/src/cmdline/index.js | 2 ++ remix-debug/src/debugger/solidityState.js | 6 ++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/remix-debug/rdb.js b/remix-debug/rdb.js index d0b14be406..42cac8fab3 100644 --- a/remix-debug/rdb.js +++ b/remix-debug/rdb.js @@ -6,6 +6,7 @@ var fs = require('fs') //var filename = 'test/sol/ballot.sol' var filename = 'test/sol/simple_storage.sol' +var short_filename = "simple_storage.sol" //var filename = 'browser/ballot.sol' var input_json = { @@ -27,7 +28,7 @@ var input_json = { } } -input_json.sources[filename] = {content: fs.readFileSync(filename).toString()} +input_json.sources[short_filename] = {content: fs.readFileSync(filename).toString()} console.dir(input_json) @@ -53,7 +54,7 @@ var deployContract = function (cb) { let txNumber = null let tx = null - let code = compilation.data.contracts[filename].SimpleStorage.evm.bytecode.object + let code = compilation.data.contracts[short_filename].SimpleStorage.evm.bytecode.object console.dir("deploying...") console.dir(code) _web3.eth.sendTransaction({data: "0x" + code, from: _web3.eth.accounts[0], gas: 800000}, cb) @@ -65,14 +66,18 @@ let _web3 = cmd_line.debugger.debugger.web3 // var tx = "0x04aa74287b3c52e2ecab1cb066d22116317155503681870c516c95cdb148fa28" // var tx = "0x04aa74287b3c52e2ecab1cb066d22116317155503681870c516c95cdb148fa28" // var tx = "0x28bd66d99bc45b3f8d959126a26b8c97092892e63fc8ed90eb1598ebedf600ef" -// var tx = "0x3a7355c59f95db494872f33890dbabaceae1ca5330db86db49d24a5c29cd829a" +var tx = "0xf510c4f0b1d9ee262d7b9e9e87b4262f275fe029c2c733feef7dfa1e2b1e32aa" // _web3.eth.getTransactionReceipt(tx, (err, data) => { // console.dir(err) // console.dir(data) - deployContract((err, tx) => { - cmd_line.startDebug(tx, filename) - }) +// deployContract((err, tx) => { + cmd_line.startDebug(tx, short_filename) + +cmd_line.events.on("source", () => { + cmd_line.getSource().forEach(console.dir) +}) + // }) //}) const repl = require('repl') diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index a1ae0cfade..ed1c626e6a 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -102,10 +102,12 @@ class CmdLine { } displayLocals () { + console.dir("= displayLocals") console.dir(this.solidityLocals) } displayGlobals () { + console.dir("= displayGlobals") console.dir(this.solidityState) if (this.solidityState && this.solidityState.voters) { console.dir(this.solidityState.voters) diff --git a/remix-debug/src/debugger/solidityState.js b/remix-debug/src/debugger/solidityState.js index d95894beca..c22d69c353 100644 --- a/remix-debug/src/debugger/solidityState.js +++ b/remix-debug/src/debugger/solidityState.js @@ -40,6 +40,8 @@ class DebuggerSolidityState { try { self.decode(index) } catch(err) { + console.dir("====> error") + console.dir(err) } }, 500) @@ -51,7 +53,11 @@ class DebuggerSolidityState { decode (index) { const self = this + console.dir("currentStepIndex") + console.dir(self.stepManager.currentStepIndex) self.traceManager.getCurrentCalledAddressAt(self.stepManager.currentStepIndex, function (error, address) { + console.dir(error) + console.dir(address) if (error) { return self.event.trigger('solidityState', [{}]) } From 7fe843d6ba7bbb7fa224294273ef4dd5ce7eb864 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Wed, 17 Oct 2018 19:31:15 -0400 Subject: [PATCH 13/46] add more events --- remix-debug/src/cmdline/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index ed1c626e6a..14302b3c4f 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -83,19 +83,21 @@ class CmdLine { this.filename = filename this.debugger.debug(null, txNumber, null, () => { - self.debugger.event.register('newSourceLocation', function (lineColumnPos, _rawLocation) { + self.debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { self.lineColumnPos = lineColumnPos - self.events.emit("source") + self.events.emit("source", [lineColumnPos, rawLocation]) }); self.debugger.vmDebuggerLogic.event.register('solidityState', (data) => { self.solidityState = data + self.events.emit("globals", data) }); // TODO: this doesnt work too well, it should request the data instead... self.debugger.vmDebuggerLogic.event.register('solidityLocals', (data) => { if (JSON.stringify(data) === '{}') return self.solidityLocals = data + self.events.emit("locals", data) }); }) From 388eca3a24b528f7bb2b8a545ef41caf113993fd Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Thu, 18 Oct 2018 12:06:02 -0400 Subject: [PATCH 14/46] remove unneeded console logs; prevent crash when step is out of bounds --- remix-debug/src/cmdline/index.js | 8 -------- remix-debug/src/debugger/debugger.js | 4 ++++ remix-debug/src/debugger/solidityLocals.js | 2 +- remix-debug/src/debugger/solidityState.js | 4 ---- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index 14302b3c4f..89baf560cb 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -42,10 +42,6 @@ class CmdLine { getSource() { const self = this - console.dir("getSource") - console.dir(this.lineColumnPos) - console.dir(this.filename) - let lineColumnPos = this.lineColumnPos if (!lineColumnPos || !lineColumnPos.start) return; @@ -111,10 +107,6 @@ class CmdLine { displayGlobals () { console.dir("= displayGlobals") console.dir(this.solidityState) - if (this.solidityState && this.solidityState.voters) { - console.dir(this.solidityState.voters) - console.dir(this.solidityState.voters.value) - } } } diff --git a/remix-debug/src/debugger/debugger.js b/remix-debug/src/debugger/debugger.js index de0ba0d386..37e3110ed6 100644 --- a/remix-debug/src/debugger/debugger.js +++ b/remix-debug/src/debugger/debugger.js @@ -115,6 +115,10 @@ Debugger.prototype.debugTx = function (tx, loadingCb) { this.vmDebuggerLogic.start() this.step_manager.event.register('stepChanged', this, function (stepIndex) { + if (!stepIndex) { + return self.event.trigger("endDebug") + } + self.debugger.codeManager.resolveStep(stepIndex, tx) self.step_manager.event.trigger('indexChanged', [stepIndex]) self.vmDebuggerLogic.event.trigger('indexChanged', [stepIndex]) diff --git a/remix-debug/src/debugger/solidityLocals.js b/remix-debug/src/debugger/solidityLocals.js index 96588857c5..64ac5ff358 100644 --- a/remix-debug/src/debugger/solidityLocals.js +++ b/remix-debug/src/debugger/solidityLocals.js @@ -40,7 +40,7 @@ class DebuggerSolidityLocals { self.stepManager.currentStepIndex, (error, result) => { if (error) { - return console.log(error) + return error; } var stack = result[0].value var memory = result[1].value diff --git a/remix-debug/src/debugger/solidityState.js b/remix-debug/src/debugger/solidityState.js index c22d69c353..78dffd8297 100644 --- a/remix-debug/src/debugger/solidityState.js +++ b/remix-debug/src/debugger/solidityState.js @@ -53,11 +53,7 @@ class DebuggerSolidityState { decode (index) { const self = this - console.dir("currentStepIndex") - console.dir(self.stepManager.currentStepIndex) self.traceManager.getCurrentCalledAddressAt(self.stepManager.currentStepIndex, function (error, address) { - console.dir(error) - console.dir(address) if (error) { return self.event.trigger('solidityState', [{}]) } From cdd5da32984a1ea876b91460ad2da8d4feb48577 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 19 Oct 2018 12:22:18 -0400 Subject: [PATCH 15/46] add callbacks so each step of the debugger is only called when it's ready --- remix-debug/src/cmdline/contextManager.js | 3 ++- remix-debug/src/cmdline/index.js | 9 +++++---- remix-lib/src/trace/traceManager.js | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/remix-debug/src/cmdline/contextManager.js b/remix-debug/src/cmdline/contextManager.js index 82e165df34..0785724588 100644 --- a/remix-debug/src/cmdline/contextManager.js +++ b/remix-debug/src/cmdline/contextManager.js @@ -33,7 +33,7 @@ class ContextManager { this.event.trigger('providerAdded', [type]) } - switchProvider (type) { + switchProvider (type, cb) { var self = this this.web3Providers.get(type, function (error, obj) { if (error) { @@ -48,6 +48,7 @@ class ContextManager { self.web3 = (!webDebugNode ? obj : webDebugNode) } self.event.trigger('providerChanged', [type, self.web3]) + if (cb) return cb(); }) self.event.trigger('providerChanged', [type, self.web3]) } diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index 89baf560cb..94a1d22ab0 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -20,7 +20,7 @@ class CmdLine { this.compilation.lastCompilationResult = compilationResult } - initDebugger () { + initDebugger (cb) { const self = this this.contextManager = new ContextManager() @@ -36,7 +36,7 @@ class CmdLine { this.contextManager.initProviders() this.contextManager.addProvider('debugger_web3', this.web3) - this.contextManager.switchProvider('debugger_web3') + this.contextManager.switchProvider('debugger_web3', cb) } getSource() { @@ -44,7 +44,7 @@ class CmdLine { let lineColumnPos = this.lineColumnPos - if (!lineColumnPos || !lineColumnPos.start) return; + if (!lineColumnPos || !lineColumnPos.start) return []; let content = self.compilation.lastCompilationResult.source.sources[this.filename].content.split("\n") @@ -74,7 +74,7 @@ class CmdLine { } // TODO: is filename really necessary? - startDebug(txNumber, filename) { + startDebug(txNumber, filename, cb) { const self = this this.filename = filename this.debugger.debug(null, txNumber, null, () => { @@ -96,6 +96,7 @@ class CmdLine { self.events.emit("locals", data) }); + cb() }) } diff --git a/remix-lib/src/trace/traceManager.js b/remix-lib/src/trace/traceManager.js index 98785c54e4..90662b1132 100644 --- a/remix-lib/src/trace/traceManager.js +++ b/remix-lib/src/trace/traceManager.js @@ -120,7 +120,7 @@ TraceManager.prototype.getStackAt = function (stepIndex, callback) { return callback(check, null) } var stack - if (this.trace[stepIndex].stack) { // there's always a stack + if (this.trace[stepIndex] && this.trace[stepIndex].stack) { // there's always a stack stack = this.trace[stepIndex].stack.slice(0) stack.reverse() callback(null, stack) From f80539315e83e436b302f803f4bdf11228493248 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 19 Oct 2018 15:29:02 -0400 Subject: [PATCH 16/46] add loadCompilationData method --- remix-debug/src/cmdline/index.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index 94a1d22ab0..7f6523684d 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -15,6 +15,13 @@ class CmdLine { this.web3 = new Web3(new Web3.providers.HttpProvider(url)) } + loadCompilationData (inputJson, outputJson) { + let data = {} + data.data = outputJson + data.source = { sources: inputJson.sources } + this.loadCompilationResult(data) + } + loadCompilationResult (compilationResult) { this.compilation = {} this.compilation.lastCompilationResult = compilationResult From a3403a31048b7a1ae19f3273c4ec2c84fe5f6ad3 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 19 Oct 2018 15:56:30 -0400 Subject: [PATCH 17/46] improve api by adding common methods --- remix-debug/src/cmdline/index.js | 33 +++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index 7f6523684d..48658ce863 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -80,7 +80,6 @@ class CmdLine { return source } - // TODO: is filename really necessary? startDebug(txNumber, filename, cb) { const self = this this.filename = filename @@ -107,6 +106,38 @@ class CmdLine { }) } + stepJumpNextBreakpoint() { + this.debugger.step_manager.stepJumpNextBreakpoint() + } + + stepJumpPreviousBreakpoint() { + this.debugger.step_manager.stepJumpPreviousBreakpoint() + } + + stepOverForward(solidityMode) { + this.debugger.step_manager.stepOverForward(solidityMode) + } + + stepOverBack(solidityMode) { + this.debugger.step_manager.stepOverBack(solidityMode) + } + + stepIntoForward(solidityMode) { + this.debugger.step_manager.stepIntoForward(solidityMode) + } + + stepIntoBack(solidityMode) { + this.debugger.step_manager.stepIntoBack(solidityMode) + } + + currentStep() { + return this.debugger.step_manager.currentStepIndex + } + + unload() { + return this.debugger.unload() + } + displayLocals () { console.dir("= displayLocals") console.dir(this.solidityLocals) From 62949d78b3ca8651ae39124d61a4b86a94386e4f Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 19 Oct 2018 16:14:53 -0400 Subject: [PATCH 18/46] add jumpto and get trace length steps --- remix-debug/src/cmdline/index.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index 48658ce863..fe942ca74c 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -130,6 +130,14 @@ class CmdLine { this.debugger.step_manager.stepIntoBack(solidityMode) } + jumpTo(step) { + this.debugger.step_manager.jumpTo(step) + } + + getTraceLength() { + return this.debugger.step_manager.traceLength + } + currentStep() { return this.debugger.step_manager.currentStepIndex } From 5dbf26897d45868eae4721becb55acf180a71d44 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 19 Oct 2018 18:01:01 -0400 Subject: [PATCH 19/46] fix breakpoint event; add method to trigger souce update --- remix-debug/src/cmdline/index.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index fe942ca74c..51d979f7e5 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -8,6 +8,7 @@ class CmdLine { constructor () { this.events = new EventManager() this.lineColumnPos = null + this.rawLocation = null } connect (providerType, url) { @@ -87,6 +88,7 @@ class CmdLine { self.debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { self.lineColumnPos = lineColumnPos + self.rawLocation = rawLocation self.events.emit("source", [lineColumnPos, rawLocation]) }); @@ -102,16 +104,23 @@ class CmdLine { self.events.emit("locals", data) }); - cb() + if (cb) { + // TODO: this should be an onReady event + setTimeout(cb, 1000); + } }) } + triggerSourceUpdate() { + this.events.emit("source", [this.lineColumnPos, this.rawLocation]) + } + stepJumpNextBreakpoint() { - this.debugger.step_manager.stepJumpNextBreakpoint() + this.debugger.step_manager.jumpNextBreakpoint() } stepJumpPreviousBreakpoint() { - this.debugger.step_manager.stepJumpPreviousBreakpoint() + this.debugger.step_manager.jumpPreviousBreakpoint() } stepOverForward(solidityMode) { From 4acd6ccf56ff9547d1026f2f243b4645e6d88e56 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 30 Nov 2018 17:56:21 -0500 Subject: [PATCH 20/46] add methods needed for solidity code navigation --- remix-debug/src/cmdline/index.js | 46 +++++++++++++++++++++++++ remix-debug/src/debugger/stepManager.js | 33 ++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index 51d979f7e5..c4b6e7c032 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -81,9 +81,18 @@ class CmdLine { return source } + getCurrentLine() { + let lineColumnPos = this.lineColumnPos + if (!lineColumnPos) return "" + let currentLineNumber = lineColumnPos.start.line + let content = this.compilation.lastCompilationResult.source.sources[this.filename].content.split("\n") + return content[currentLineNumber] + } + startDebug(txNumber, filename, cb) { const self = this this.filename = filename + this.txHash = txNumber this.debugger.debug(null, txNumber, null, () => { self.debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { @@ -111,6 +120,13 @@ class CmdLine { }) } + getVars() { + return { + locals: this.solidityLocals, + contract: this.solidityState + } + } + triggerSourceUpdate() { this.events.emit("source", [this.lineColumnPos, this.rawLocation]) } @@ -144,13 +160,43 @@ class CmdLine { } getTraceLength() { + if (!this.debugger.step_manager) return 0; return this.debugger.step_manager.traceLength } + getCodeFirstStep() { + if (!this.debugger.step_manager) return 0; + return this.debugger.step_manager.calculateFirstStep() + } + + getCodeTraceLength() { + if (!this.debugger.step_manager) return 0; + return this.debugger.step_manager.calculateCodeLength() + } + + nextStep() { + if (!this.debugger.step_manager) return 0; + return this.debugger.step_manager.nextStep() + } + + previousStep() { + if (!this.debugger.step_manager) return 0; + return this.debugger.step_manager.previousStep() + } + currentStep() { + if (!this.debugger.step_manager) return 0; return this.debugger.step_manager.currentStepIndex } + canGoNext() { + return this.currentStep() < this.getCodeTraceLength() + } + + canGoPrevious() { + return this.currentStep() > this.getCodeFirstStep() + } + unload() { return this.debugger.unload() } diff --git a/remix-debug/src/debugger/stepManager.js b/remix-debug/src/debugger/stepManager.js index eb64ffe401..84fa44e227 100644 --- a/remix-debug/src/debugger/stepManager.js +++ b/remix-debug/src/debugger/stepManager.js @@ -10,6 +10,7 @@ class DebuggerStepManager { this.traceManager = traceManager this.currentStepIndex = 0 this.traceLength = 0 + this.codeTraceLength = 0 this.revertionPoint = null this.listenToEvents() @@ -26,6 +27,7 @@ class DebuggerStepManager { if (self.traceLength !== newLength) { self.event.trigger('traceLengthChanged', [newLength]) self.traceLength = newLength + self.codeTraceLength = self.calculateCodeLength() } self.jumpTo(0) }) @@ -156,6 +158,37 @@ class DebuggerStepManager { this.debugger.breakpointManager.jumpPreviousBreakpoint(this.currentStepIndex, true) } + calculateFirstStep() { + let step = this.resolveToReducedTrace(0, 1) + return this.resolveToReducedTrace(step, 1) + } + + calculateCodeStepList() { + let step = 0 + let steps = [] + while (step < this.traceLength) { + let _step = this.resolveToReducedTrace(step, 1) + if (!_step) break; + steps.push(_step) + step += 1 + } + steps = steps.filter((item, pos, self) => { return steps.indexOf(item) === pos }) + return steps + } + + calculateCodeLength() { + let steps = this.calculateCodeStepList().reverse() + return this.calculateCodeStepList().reverse()[1] || this.traceLength; + } + + nextStep() { + return this.resolveToReducedTrace(this.currentStepIndex, 1); + } + + previousStep() { + return this.resolveToReducedTrace(this.currentStepIndex, -1); + } + resolveToReducedTrace (value, incr) { if (this.debugger.callTree.reducedTrace.length) { var nextSource = util.findClosestIndex(value, this.debugger.callTree.reducedTrace) From a3cd1b7a84f087fe9c34a433dd17b23205409cc8 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 30 Nov 2018 18:06:41 -0500 Subject: [PATCH 21/46] cleanup --- remix-debug/rdb.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/remix-debug/rdb.js b/remix-debug/rdb.js index 42cac8fab3..d69a22565c 100644 --- a/remix-debug/rdb.js +++ b/remix-debug/rdb.js @@ -4,15 +4,12 @@ var compilation = require('./compilation.json') var solc = require('solc') var fs = require('fs') -//var filename = 'test/sol/ballot.sol' var filename = 'test/sol/simple_storage.sol' var short_filename = "simple_storage.sol" -//var filename = 'browser/ballot.sol' var input_json = { language: 'Solidity', sources: { - //"test/sol/ballot.sol": {content: fs.readFileSync('test/sol/ballot.sol').toString()} }, settings: { optimizer: { @@ -61,15 +58,7 @@ var deployContract = function (cb) { } let _web3 = cmd_line.debugger.debugger.web3 -// var tx = "0x8c44e1b6bcb557512184f851502e43160f415e2e12b2b98ba12b96b699b85859" -// var tx = "0xae365458de8c6669eb146ce2ade4c7767c0edddaee98f5c1878c7c5e5510a0de" -// var tx = "0x04aa74287b3c52e2ecab1cb066d22116317155503681870c516c95cdb148fa28" -// var tx = "0x04aa74287b3c52e2ecab1cb066d22116317155503681870c516c95cdb148fa28" -// var tx = "0x28bd66d99bc45b3f8d959126a26b8c97092892e63fc8ed90eb1598ebedf600ef" var tx = "0xf510c4f0b1d9ee262d7b9e9e87b4262f275fe029c2c733feef7dfa1e2b1e32aa" -// _web3.eth.getTransactionReceipt(tx, (err, data) => { -// console.dir(err) -// console.dir(data) // deployContract((err, tx) => { cmd_line.startDebug(tx, short_filename) From f7aa459cc5373ba3e5a137da595e643896e890c0 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Wed, 12 Dec 2018 09:58:19 -0500 Subject: [PATCH 22/46] remove uneeded file; remove decoupling --- remix-debug/lib_test.js | 0 remix-debug/rdb.js | 10 +++++----- 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 remix-debug/lib_test.js diff --git a/remix-debug/lib_test.js b/remix-debug/lib_test.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/remix-debug/rdb.js b/remix-debug/rdb.js index d69a22565c..3c87641e04 100644 --- a/remix-debug/rdb.js +++ b/remix-debug/rdb.js @@ -76,16 +76,16 @@ const r = repl.start({ eval: (cmd, context, filename, cb) => { let command = cmd.trim() if (command === 'next' || command === 'n') { - cmd_line.debugger.step_manager.stepOverForward(true) + cmd_line.stepOverForward(true) } if (command === 'previous' || command === 'p' || command === 'prev') { - cmd_line.debugger.step_manager.stepOverBack(true) + cmd_line.stepOverBack(true) } if (command === 'step' || command === 's') { - cmd_line.debugger.step_manager.stepIntoForward(true) + cmd_line.stepIntoForward(true) } if (command === 'stepback' || command === 'sb') { - cmd_line.debugger.step_manager.stepIntoBack(true) + cmd_line.stepIntoBack(true) } if (command === 'exit' || command === 'quit') { process.exit(0) @@ -98,7 +98,7 @@ const r = repl.start({ } if (command.split(' ')[0] === 'jump') { let stepIndex = parseInt(command.split(' ')[1], 10) - cmd_line.debugger.step_manager.jumpTo(stepIndex) + cmd_line.jumpTo(stepIndex) } cb(null, ''); } From 87fea226a13bbe0d34711ae5a2441ac0099e3ee7 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Wed, 12 Dec 2018 11:06:30 -0500 Subject: [PATCH 23/46] make linter happy --- remix-debug/rdb.js | 87 ++++++++-------- remix-debug/src/cmdline/contextManager.js | 2 +- remix-debug/src/cmdline/index.js | 111 ++++++++++----------- remix-debug/src/debugger/debugger.js | 4 +- remix-debug/src/debugger/solidityLocals.js | 2 +- remix-debug/src/debugger/solidityState.js | 5 +- remix-debug/src/debugger/stepManager.js | 20 ++-- 7 files changed, 114 insertions(+), 117 deletions(-) diff --git a/remix-debug/rdb.js b/remix-debug/rdb.js index 3c87641e04..7a81771c64 100644 --- a/remix-debug/rdb.js +++ b/remix-debug/rdb.js @@ -1,13 +1,13 @@ var CmdLine = require('./src/cmdline/index.js') -var compilation = require('./compilation.json') +// var compilation = require('./compilation.json') var solc = require('solc') var fs = require('fs') var filename = 'test/sol/simple_storage.sol' -var short_filename = "simple_storage.sol" +var shortFilename = 'simple_storage.sol' -var input_json = { +var inputJson = { language: 'Solidity', sources: { }, @@ -25,85 +25,84 @@ var input_json = { } } -input_json.sources[short_filename] = {content: fs.readFileSync(filename).toString()} +inputJson.sources[shortFilename] = {content: fs.readFileSync(filename).toString()} -console.dir(input_json) +console.dir(inputJson) -console.log("compiling...") +console.log('compiling...') -let compilationData = JSON.parse(solc.compileStandardWrapper(JSON.stringify(input_json))) +let compilationData = JSON.parse(solc.compileStandardWrapper(JSON.stringify(inputJson))) console.dir(Object.keys(compilationData)) var compilation = {} compilation.data = compilationData -compilation.source = { sources: input_json.sources } +compilation.source = { sources: inputJson.sources } console.dir(compilation) console.dir(compilation.data.errors) -var cmd_line = new CmdLine() -cmd_line.connect("http", "http://localhost:8545") -cmd_line.loadCompilationResult(compilation) -cmd_line.initDebugger() - -var deployContract = function (cb) { - let _web3 = cmd_line.debugger.debugger.web3 - - let blockNumber = null - let txNumber = null - let tx = null - - let code = compilation.data.contracts[short_filename].SimpleStorage.evm.bytecode.object - console.dir("deploying...") - console.dir(code) - _web3.eth.sendTransaction({data: "0x" + code, from: _web3.eth.accounts[0], gas: 800000}, cb) -} - -let _web3 = cmd_line.debugger.debugger.web3 -var tx = "0xf510c4f0b1d9ee262d7b9e9e87b4262f275fe029c2c733feef7dfa1e2b1e32aa" +var cmdLine = new CmdLine() +cmdLine.connect('http', 'http://localhost:8545') +cmdLine.loadCompilationResult(compilation) +cmdLine.initDebugger() + +// var deployContract = function (cb) { +// let _web3 = cmdLine.debugger.debugger.web3 +// +// let blockNumber = null +// let txNumber = null +// let tx = null +// +// let code = compilation.data.contracts[shortFilename].SimpleStorage.evm.bytecode.object +// console.dir('deploying...') +// console.dir(code) +// _web3.eth.sendTransaction({data: '0x' + code, from: _web3.eth.accounts[0], gas: 800000}, cb) +// } + +// let _web3 = cmdLine.debugger.debugger.web3 +var tx = '0xf510c4f0b1d9ee262d7b9e9e87b4262f275fe029c2c733feef7dfa1e2b1e32aa' // deployContract((err, tx) => { - cmd_line.startDebug(tx, short_filename) +cmdLine.startDebug(tx, shortFilename) -cmd_line.events.on("source", () => { - cmd_line.getSource().forEach(console.dir) +cmdLine.events.on('source', () => { + cmdLine.getSource().forEach(console.dir) }) // }) -//}) +// }) const repl = require('repl') -const r = repl.start({ +repl.start({ prompt: '> ', eval: (cmd, context, filename, cb) => { let command = cmd.trim() if (command === 'next' || command === 'n') { - cmd_line.stepOverForward(true) + cmdLine.stepOverForward(true) } if (command === 'previous' || command === 'p' || command === 'prev') { - cmd_line.stepOverBack(true) + cmdLine.stepOverBack(true) } if (command === 'step' || command === 's') { - cmd_line.stepIntoForward(true) + cmdLine.stepIntoForward(true) } if (command === 'stepback' || command === 'sb') { - cmd_line.stepIntoBack(true) + cmdLine.stepIntoBack(true) } if (command === 'exit' || command === 'quit') { process.exit(0) } if (command === 'var local' || command === 'v l' || command === 'vl') { - cmd_line.displayLocals() + cmdLine.displayLocals() } if (command === 'var global' || command === 'v g' || command === 'vg') { - cmd_line.displayGlobals() + cmdLine.displayGlobals() } if (command.split(' ')[0] === 'jump') { let stepIndex = parseInt(command.split(' ')[1], 10) - cmd_line.jumpTo(stepIndex) + cmdLine.jumpTo(stepIndex) } - cb(null, ''); + cb(null, '') } -}); - -module.exports = cmd_line +}) +module.exports = cmdLine diff --git a/remix-debug/src/cmdline/contextManager.js b/remix-debug/src/cmdline/contextManager.js index 0785724588..cb7c475eaa 100644 --- a/remix-debug/src/cmdline/contextManager.js +++ b/remix-debug/src/cmdline/contextManager.js @@ -48,7 +48,7 @@ class ContextManager { self.web3 = (!webDebugNode ? obj : webDebugNode) } self.event.trigger('providerChanged', [type, self.web3]) - if (cb) return cb(); + if (cb) return cb() }) self.event.trigger('providerChanged', [type, self.web3]) } diff --git a/remix-debug/src/cmdline/index.js b/remix-debug/src/cmdline/index.js index c4b6e7c032..f5734f084c 100644 --- a/remix-debug/src/cmdline/index.js +++ b/remix-debug/src/cmdline/index.js @@ -12,7 +12,7 @@ class CmdLine { } connect (providerType, url) { - if (providerType !== 'http') throw new Error("unsupported provider type") + if (providerType !== 'http') throw new Error('unsupported provider type') this.web3 = new Web3(new Web3.providers.HttpProvider(url)) } @@ -47,167 +47,166 @@ class CmdLine { this.contextManager.switchProvider('debugger_web3', cb) } - getSource() { + getSource () { const self = this let lineColumnPos = this.lineColumnPos - if (!lineColumnPos || !lineColumnPos.start) return []; + if (!lineColumnPos || !lineColumnPos.start) return [] - let content = self.compilation.lastCompilationResult.source.sources[this.filename].content.split("\n") + let content = self.compilation.lastCompilationResult.source.sources[this.filename].content.split('\n') let source = [] let line line = content[lineColumnPos.start.line - 2] - if ( line !== undefined) { - source.push(" " + (lineColumnPos.start.line - 1) + ": " + line) + if (line !== undefined) { + source.push(' ' + (lineColumnPos.start.line - 1) + ': ' + line) } line = content[lineColumnPos.start.line - 1] - if ( line !== undefined) { - source.push(" " + lineColumnPos.start.line + ": " + line) + if (line !== undefined) { + source.push(' ' + lineColumnPos.start.line + ': ' + line) } let currentLineNumber = lineColumnPos.start.line let currentLine = content[currentLineNumber] - source.push("=> " + (currentLineNumber + 1) + ": " + currentLine) + source.push('=> ' + (currentLineNumber + 1) + ': ' + currentLine) let startLine = lineColumnPos.start.line - for (var i=1; i < 4; i++) { + for (var i = 1; i < 4; i++) { let line = content[startLine + i] - source.push(" " + (startLine + i + 1) + ": " + line) + source.push(' ' + (startLine + i + 1) + ': ' + line) } return source } - getCurrentLine() { + getCurrentLine () { let lineColumnPos = this.lineColumnPos - if (!lineColumnPos) return "" + if (!lineColumnPos) return '' let currentLineNumber = lineColumnPos.start.line - let content = this.compilation.lastCompilationResult.source.sources[this.filename].content.split("\n") + let content = this.compilation.lastCompilationResult.source.sources[this.filename].content.split('\n') return content[currentLineNumber] } - startDebug(txNumber, filename, cb) { + startDebug (txNumber, filename, cb) { const self = this this.filename = filename this.txHash = txNumber this.debugger.debug(null, txNumber, null, () => { - self.debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { self.lineColumnPos = lineColumnPos self.rawLocation = rawLocation - self.events.emit("source", [lineColumnPos, rawLocation]) - }); + self.events.emit('source', [lineColumnPos, rawLocation]) + }) self.debugger.vmDebuggerLogic.event.register('solidityState', (data) => { self.solidityState = data - self.events.emit("globals", data) - }); + self.events.emit('globals', data) + }) // TODO: this doesnt work too well, it should request the data instead... self.debugger.vmDebuggerLogic.event.register('solidityLocals', (data) => { if (JSON.stringify(data) === '{}') return self.solidityLocals = data - self.events.emit("locals", data) - }); + self.events.emit('locals', data) + }) if (cb) { // TODO: this should be an onReady event - setTimeout(cb, 1000); + setTimeout(cb, 1000) } }) } - getVars() { + getVars () { return { locals: this.solidityLocals, contract: this.solidityState } } - triggerSourceUpdate() { - this.events.emit("source", [this.lineColumnPos, this.rawLocation]) + triggerSourceUpdate () { + this.events.emit('source', [this.lineColumnPos, this.rawLocation]) } - stepJumpNextBreakpoint() { - this.debugger.step_manager.jumpNextBreakpoint() + stepJumpNextBreakpoint () { + this.debugger.step_manager.jumpNextBreakpoint() } - stepJumpPreviousBreakpoint() { - this.debugger.step_manager.jumpPreviousBreakpoint() + stepJumpPreviousBreakpoint () { + this.debugger.step_manager.jumpPreviousBreakpoint() } - stepOverForward(solidityMode) { - this.debugger.step_manager.stepOverForward(solidityMode) + stepOverForward (solidityMode) { + this.debugger.step_manager.stepOverForward(solidityMode) } - stepOverBack(solidityMode) { - this.debugger.step_manager.stepOverBack(solidityMode) + stepOverBack (solidityMode) { + this.debugger.step_manager.stepOverBack(solidityMode) } - stepIntoForward(solidityMode) { - this.debugger.step_manager.stepIntoForward(solidityMode) + stepIntoForward (solidityMode) { + this.debugger.step_manager.stepIntoForward(solidityMode) } - stepIntoBack(solidityMode) { - this.debugger.step_manager.stepIntoBack(solidityMode) + stepIntoBack (solidityMode) { + this.debugger.step_manager.stepIntoBack(solidityMode) } - jumpTo(step) { + jumpTo (step) { this.debugger.step_manager.jumpTo(step) } - getTraceLength() { - if (!this.debugger.step_manager) return 0; + getTraceLength () { + if (!this.debugger.step_manager) return 0 return this.debugger.step_manager.traceLength } - getCodeFirstStep() { - if (!this.debugger.step_manager) return 0; + getCodeFirstStep () { + if (!this.debugger.step_manager) return 0 return this.debugger.step_manager.calculateFirstStep() } - getCodeTraceLength() { - if (!this.debugger.step_manager) return 0; + getCodeTraceLength () { + if (!this.debugger.step_manager) return 0 return this.debugger.step_manager.calculateCodeLength() } - nextStep() { - if (!this.debugger.step_manager) return 0; + nextStep () { + if (!this.debugger.step_manager) return 0 return this.debugger.step_manager.nextStep() } - previousStep() { - if (!this.debugger.step_manager) return 0; + previousStep () { + if (!this.debugger.step_manager) return 0 return this.debugger.step_manager.previousStep() } - currentStep() { - if (!this.debugger.step_manager) return 0; + currentStep () { + if (!this.debugger.step_manager) return 0 return this.debugger.step_manager.currentStepIndex } - canGoNext() { + canGoNext () { return this.currentStep() < this.getCodeTraceLength() } - canGoPrevious() { + canGoPrevious () { return this.currentStep() > this.getCodeFirstStep() } - unload() { + unload () { return this.debugger.unload() } displayLocals () { - console.dir("= displayLocals") + console.dir('= displayLocals') console.dir(this.solidityLocals) } displayGlobals () { - console.dir("= displayGlobals") + console.dir('= displayGlobals') console.dir(this.solidityState) } } diff --git a/remix-debug/src/debugger/debugger.js b/remix-debug/src/debugger/debugger.js index 37e3110ed6..0d9ede06de 100644 --- a/remix-debug/src/debugger/debugger.js +++ b/remix-debug/src/debugger/debugger.js @@ -112,11 +112,11 @@ Debugger.prototype.debugTx = function (tx, loadingCb) { }) this.vmDebuggerLogic = new VmDebuggerLogic(this.debugger, tx, this.step_manager, this.debugger.traceManager, this.debugger.codeManager, this.debugger.solidityProxy, this.debugger.callTree) - this.vmDebuggerLogic.start() + this.vmDebuggerLogic.start() this.step_manager.event.register('stepChanged', this, function (stepIndex) { if (!stepIndex) { - return self.event.trigger("endDebug") + return self.event.trigger('endDebug') } self.debugger.codeManager.resolveStep(stepIndex, tx) diff --git a/remix-debug/src/debugger/solidityLocals.js b/remix-debug/src/debugger/solidityLocals.js index 64ac5ff358..fca807e27b 100644 --- a/remix-debug/src/debugger/solidityLocals.js +++ b/remix-debug/src/debugger/solidityLocals.js @@ -40,7 +40,7 @@ class DebuggerSolidityLocals { self.stepManager.currentStepIndex, (error, result) => { if (error) { - return error; + return error } var stack = result[0].value var memory = result[1].value diff --git a/remix-debug/src/debugger/solidityState.js b/remix-debug/src/debugger/solidityState.js index 78dffd8297..a7d9d0e256 100644 --- a/remix-debug/src/debugger/solidityState.js +++ b/remix-debug/src/debugger/solidityState.js @@ -39,11 +39,10 @@ class DebuggerSolidityState { // necessary due to some states that can crash the debugger try { self.decode(index) - } catch(err) { - console.dir("====> error") + } catch (err) { + console.dir('====> error') console.dir(err) } - }, 500) } diff --git a/remix-debug/src/debugger/stepManager.js b/remix-debug/src/debugger/stepManager.js index 84fa44e227..2e39115cab 100644 --- a/remix-debug/src/debugger/stepManager.js +++ b/remix-debug/src/debugger/stepManager.js @@ -158,17 +158,17 @@ class DebuggerStepManager { this.debugger.breakpointManager.jumpPreviousBreakpoint(this.currentStepIndex, true) } - calculateFirstStep() { + calculateFirstStep () { let step = this.resolveToReducedTrace(0, 1) return this.resolveToReducedTrace(step, 1) } - calculateCodeStepList() { + calculateCodeStepList () { let step = 0 let steps = [] while (step < this.traceLength) { let _step = this.resolveToReducedTrace(step, 1) - if (!_step) break; + if (!_step) break steps.push(_step) step += 1 } @@ -176,17 +176,17 @@ class DebuggerStepManager { return steps } - calculateCodeLength() { - let steps = this.calculateCodeStepList().reverse() - return this.calculateCodeStepList().reverse()[1] || this.traceLength; + calculateCodeLength () { + this.calculateCodeStepList().reverse() + return this.calculateCodeStepList().reverse()[1] || this.traceLength } - nextStep() { - return this.resolveToReducedTrace(this.currentStepIndex, 1); + nextStep () { + return this.resolveToReducedTrace(this.currentStepIndex, 1) } - previousStep() { - return this.resolveToReducedTrace(this.currentStepIndex, -1); + previousStep () { + return this.resolveToReducedTrace(this.currentStepIndex, -1) } resolveToReducedTrace (value, incr) { From 203a2f3799f3b756566cacf182ae2fd6abb8b7cf Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Oct 2018 22:08:28 -0400 Subject: [PATCH 24/46] Work on #1013 --- remix-tests/src/index.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/remix-tests/src/index.js b/remix-tests/src/index.js index 91aa7e3a01..d0e90f0d58 100644 --- a/remix-tests/src/index.js +++ b/remix-tests/src/index.js @@ -164,8 +164,26 @@ var runTestFiles = function (filepath, isDirectory, web3, opts) { } if (isDirectory) { - fs.readdirSync(filepath).forEach(filename => { - gatherContractsFrom(filename) + fs.walkSync = function (start, callback) { + fs.readdirSync(start).forEach(name => { + if (name === 'node_modules') { + return; // hack + } + var abspath = path.join(start, name); + if (fs.statSync(abspath).isDirectory()) { + fs.walkSync(abspath, callback); + } else { + callback(abspath); + } + }); + }; + fs.walkSync(filepath, foundpath => { + if (foundpath.indexOf('_test.sol') < 0) { + return + } + Object.keys(compilationResult[foundpath]).forEach(contractName => { + contractsToTest.push(contractName) + }) }) } else { gatherContractsFrom(filepath) From 580d85aa8044d019fedac972e981e73ed25882cd Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Oct 2018 22:09:13 -0400 Subject: [PATCH 25/46] Work on multiple directories --- remix-tests/src/compiler.js | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index 83d3506ac5..52d8250c04 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -37,16 +37,31 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { // should be replaced with remix's & browser solidity compiler code filepath = (isDirectory ? filename : path.dirname(filename)) - fs.readdirSync(filepath).forEach(file => { + // https://github.com/mikeal/node-utils/blob/master/file/lib/main.js + fs.walkSync = function (start, callback) { + fs.readdirSync(start).forEach(name => { + if (name === 'node_modules') { + return; // hack + } + var abspath = path.join(start, name); + if (fs.statSync(abspath).isDirectory()) { + fs.walkSync(abspath, callback); + } else { + callback(abspath); + } + }); + }; + + fs.walkSync(filepath, foundpath => { // only process .sol files - if (file.split('.').pop() === 'sol') { - let c = fs.readFileSync(path.join(filepath, file)).toString() + if (foundpath.split('.').pop() === 'sol') { + let c = fs.readFileSync(foundpath).toString() const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm let includeTestLibs = '\nimport \'remix_tests.sol\';\n' if (file.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { c = includeTestLibs.concat(c) } - sources[file] = { content: c } + sources[foundpath] = { content: c } } }) @@ -62,7 +77,7 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { compiler.event.register('compilationFinished', this, function (success, data, source) { next(null, data) }) - compiler.compile(sources, filepath) + compiler.compile(sources, false) } ], function (err, result) { let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') From c12b83a574326cf7b701f4224a21701fa676cafe Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Oct 2018 22:30:36 -0400 Subject: [PATCH 26/46] less semicolons --- remix-tests/src/compiler.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index 52d8250c04..2c9d55921d 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -41,16 +41,16 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { fs.walkSync = function (start, callback) { fs.readdirSync(start).forEach(name => { if (name === 'node_modules') { - return; // hack + return // hack } - var abspath = path.join(start, name); + var abspath = path.join(start, name) if (fs.statSync(abspath).isDirectory()) { - fs.walkSync(abspath, callback); + fs.walkSync(abspath, callback) } else { - callback(abspath); + callback(abspath) } - }); - }; + }) + } fs.walkSync(filepath, foundpath => { // only process .sol files From ad1f68eddc93d50695fec4e9c8e93522c2d528dd Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Oct 2018 22:31:36 -0400 Subject: [PATCH 27/46] Less semicolons --- remix-tests/src/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/remix-tests/src/index.js b/remix-tests/src/index.js index d0e90f0d58..dfefef5329 100644 --- a/remix-tests/src/index.js +++ b/remix-tests/src/index.js @@ -167,16 +167,16 @@ var runTestFiles = function (filepath, isDirectory, web3, opts) { fs.walkSync = function (start, callback) { fs.readdirSync(start).forEach(name => { if (name === 'node_modules') { - return; // hack + return // hack } - var abspath = path.join(start, name); + var abspath = path.join(start, name) if (fs.statSync(abspath).isDirectory()) { - fs.walkSync(abspath, callback); + fs.walkSync(abspath, callback) } else { - callback(abspath); + callback(abspath) } - }); - }; + }) + } fs.walkSync(filepath, foundpath => { if (foundpath.indexOf('_test.sol') < 0) { return From 6ec4f03f0368aea8ad3deb1217b68b984fcc6dc1 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 6 Nov 2018 22:49:41 -0500 Subject: [PATCH 28/46] Expect full contract name in test run --- remix-tests/tests/testRunner.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/remix-tests/tests/testRunner.js b/remix-tests/tests/testRunner.js index 1871d19e13..b55292afcf 100644 --- a/remix-tests/tests/testRunner.js +++ b/remix-tests/tests/testRunner.js @@ -61,7 +61,7 @@ describe('testRunner', function () { it('should returns 5 messages', function () { assert.deepEqual(tests, [ - { type: 'contract', value: 'MyTest', filename: 'simple_storage_test.sol' }, + { type: 'contract', value: 'MyTest', filename: 'tests/examples_1/simple_storage_test.sol' }, { type: 'testFailure', value: 'Should trigger one fail', time: 1, context: 'MyTest', errMsg: 'the test 1 fails' }, { type: 'testPass', value: 'Should trigger one pass', time: 1, context: 'MyTest'}, { type: 'testPass', value: 'Initial value should be100', time: 1, context: 'MyTest' }, @@ -97,7 +97,7 @@ describe('testRunner', function () { it('should returns 3 messages', function () { assert.deepEqual(tests, [ - { type: 'contract', value: 'MyTest', filename: 'simple_storage_test.sol' }, + { type: 'contract', value: 'MyTest', filename: 'tests/examples_2/simple_storage_test.sol' }, { type: 'testPass', value: 'Initial value should be100', time: 1, context: 'MyTest' }, { type: 'testPass', value: 'Initial value should be200', time: 1, context: 'MyTest' } ]) @@ -133,8 +133,8 @@ describe('testRunner', function () { it('should returns 3 messages', function () { assert.deepEqual(tests, [ - { type: 'contract', value: 'StringTest', filename: 'simple_string_test.sol' }, - { type: 'testFailure', value: 'Value should be hello world', time: 1, context: 'StringTest', "errMsg": "initial value is not correct" }, + { type: 'contract', value: 'StringTest', filename: 'tests/examples_3/simple_string_test.sol' }, + { type: 'testFailure', value: 'Value should be hello world', time: 1, context: 'StringTest', "errMsg": "function returned false" }, { type: 'testPass', value: 'Value should not be hello world', time: 1, context: 'StringTest' }, { type: 'testPass', value: 'Initial value should be hello', time: 1, context: 'StringTest' }, ]) From b941bb42fd5b30da7749e6a58b302ce467ef330f Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Sat, 10 Nov 2018 10:16:30 +0530 Subject: [PATCH 29/46] unit testing fix for PR #1014 --- remix-tests/tests/testRunner.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/remix-tests/tests/testRunner.js b/remix-tests/tests/testRunner.js index b55292afcf..3b5dc673f6 100644 --- a/remix-tests/tests/testRunner.js +++ b/remix-tests/tests/testRunner.js @@ -29,8 +29,8 @@ function compileAndDeploy (filename, callback) { ], function (_err, contracts) { callback(null, compilationData, contracts, accounts) }) -} - +} + describe('testRunner', function () { describe('#runTest', function() { @@ -47,7 +47,7 @@ describe('testRunner', function () { results = _results done() } - TestRunner.runTest('MyTest', contracts.MyTest, compilationData['simple_storage_test.sol']['MyTest'], { accounts }, testCallback, resultsCallback) + TestRunner.runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], { accounts }, testCallback, resultsCallback) }) }) @@ -83,7 +83,7 @@ describe('testRunner', function () { results = _results done() } - TestRunner.runTest('MyTest', contracts.MyTest, compilationData['simple_storage_test.sol']['MyTest'], { accounts }, testCallback, resultsCallback) + TestRunner.runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], { accounts }, testCallback, resultsCallback) }) }) @@ -118,8 +118,8 @@ describe('testRunner', function () { results = _results done() } - TestRunner.runTest('StringTest', contracts.StringTest, compilationData['simple_string_test.sol']['StringTest'], { accounts }, testCallback, resultsCallback) - TestRunner.runTest('StringTest2', contracts.StringTest2, compilationData['simple_string_test.sol']['StringTest2'], { accounts }, testCallback, resultsCallback) + TestRunner.runTest('StringTest', contracts.StringTest, compilationData[filename]['StringTest'], { accounts }, testCallback, resultsCallback) + TestRunner.runTest('StringTest2', contracts.StringTest2, compilationData[filename]['StringTest2'], { accounts }, testCallback, resultsCallback) }) }) @@ -155,7 +155,7 @@ describe('testRunner', function () { results = _results done() } - TestRunner.runTest('IntegerTest', contracts.IntegerTest, compilationData['number_test.sol']['IntegerTest'], { accounts }, testCallback, resultsCallback) + TestRunner.runTest('IntegerTest', contracts.IntegerTest, compilationData[filename]['IntegerTest'], { accounts }, testCallback, resultsCallback) }) }) @@ -181,9 +181,9 @@ describe('testRunner', function () { results = _results done() } - - TestRunner.runTest('SenderTest', contracts.SenderTest, compilationData['sender_test.sol']['SenderTest'], { accounts }, testCallback, resultsCallback) - + + TestRunner.runTest('SenderTest', contracts.SenderTest, compilationData[filename]['SenderTest'], { accounts }, testCallback, resultsCallback) + }) }) From 84714c6899a733b8f4552bd9cb4ec02a4e69f54f Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Wed, 14 Nov 2018 19:06:25 +0530 Subject: [PATCH 30/46] Use gatherContractsFrom to collect contracts in fs.walkSync --- remix-tests/src/index.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/remix-tests/src/index.js b/remix-tests/src/index.js index dfefef5329..7e430bcacf 100644 --- a/remix-tests/src/index.js +++ b/remix-tests/src/index.js @@ -153,7 +153,7 @@ var runTestFiles = function (filepath, isDirectory, web3, opts) { function determineTestContractsToRun (compilationResult, contracts, next) { let contractsToTest = [] let contractsToTestDetails = [] - var gatherContractsFrom = (filename) => { + const gatherContractsFrom = (filename) => { if (filename.indexOf('_test.sol') < 0) { return } @@ -178,12 +178,7 @@ var runTestFiles = function (filepath, isDirectory, web3, opts) { }) } fs.walkSync(filepath, foundpath => { - if (foundpath.indexOf('_test.sol') < 0) { - return - } - Object.keys(compilationResult[foundpath]).forEach(contractName => { - contractsToTest.push(contractName) - }) + gatherContractsFrom(foundpath) }) } else { gatherContractsFrom(filepath) From 730595472bc6686d706a536d9df62757e26b4156 Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Fri, 16 Nov 2018 15:37:35 +0530 Subject: [PATCH 31/46] split index.js into multiple files, reuse functions --- remix-tests/src/compiler.js | 88 +++++------ remix-tests/src/fs.js | 20 +++ remix-tests/src/index.js | 247 +----------------------------- remix-tests/src/runTestFiles.js | 133 ++++++++++++++++ remix-tests/src/runTestSources.js | 107 +++++++++++++ 5 files changed, 303 insertions(+), 292 deletions(-) create mode 100644 remix-tests/src/fs.js create mode 100644 remix-tests/src/runTestFiles.js create mode 100644 remix-tests/src/runTestSources.js diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index 2c9d55921d..ff00ed2cab 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -1,5 +1,5 @@ /* eslint no-extend-native: "warn" */ -let fs = require('fs') +let fs = require('./fs') var async = require('async') var path = require('path') let RemixCompiler = require('remix-solidity').Compiler @@ -35,58 +35,50 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { } // TODO: for now assumes filepath dir contains all tests, later all this // should be replaced with remix's & browser solidity compiler code - filepath = (isDirectory ? filename : path.dirname(filename)) - // https://github.com/mikeal/node-utils/blob/master/file/lib/main.js - fs.walkSync = function (start, callback) { - fs.readdirSync(start).forEach(name => { - if (name === 'node_modules') { - return // hack + // This logic is wrong + // We should only look into current file if a full file name with path is given + // We should only walk through directory if a directory name is passed + try { + filepath = (isDirectory ? filename : path.dirname(filename)) + // walkSync only if it is a directory + fs.walkSync(filepath, foundpath => { + // only process .sol files + if (foundpath.split('.').pop() === 'sol') { + let c = fs.readFileSync(foundpath).toString() + const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm + if (foundpath.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { + c = c.replace(/(pragma solidity \^?\d+\.\d+\.\d+;)/, '$1\nimport \'remix_tests.sol\';') + } + sources[foundpath] = { content: c } } - var abspath = path.join(start, name) - if (fs.statSync(abspath).isDirectory()) { - fs.walkSync(abspath, callback) - } else { - callback(abspath) + }) + } catch (e) { + throw e + } finally { + async.waterfall([ + function loadCompiler (next) { + compiler = new RemixCompiler() + compiler.onInternalCompilerLoaded() + // compiler.event.register('compilerLoaded', this, function (version) { + next() + // }); + }, + function doCompilation (next) { + compiler.event.register('compilationFinished', this, function (success, data, source) { + next(null, data) + }) + compiler.compile(sources, false) + } + ], function (err, result) { + let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') + if (errors.length > 0) { + if (!isBrowser) require('signale').fatal(errors) + return cb(new Error('errors compiling')) } + cb(err, result.contracts) }) } - - fs.walkSync(filepath, foundpath => { - // only process .sol files - if (foundpath.split('.').pop() === 'sol') { - let c = fs.readFileSync(foundpath).toString() - const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm - let includeTestLibs = '\nimport \'remix_tests.sol\';\n' - if (file.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { - c = includeTestLibs.concat(c) - } - sources[foundpath] = { content: c } - } - }) - - async.waterfall([ - function loadCompiler (next) { - compiler = new RemixCompiler() - compiler.onInternalCompilerLoaded() - // compiler.event.register('compilerLoaded', this, function (version) { - next() - // }); - }, - function doCompilation (next) { - compiler.event.register('compilationFinished', this, function (success, data, source) { - next(null, data) - }) - compiler.compile(sources, false) - } - ], function (err, result) { - let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') - if (errors.length > 0) { - if (!isBrowser) require('signale').fatal(errors) - return cb(new Error('errors compiling')) - } - cb(err, result.contracts) - }) } function compileContractSources (sources, importFileCb, opts, cb) { diff --git a/remix-tests/src/fs.js b/remix-tests/src/fs.js new file mode 100644 index 0000000000..fa2dd4dfd7 --- /dev/null +++ b/remix-tests/src/fs.js @@ -0,0 +1,20 @@ +// Extend fs +var fs = require('fs') +const path = require('path') + +// https://github.com/mikeal/node-utils/blob/master/file/lib/main.js +fs.walkSync = function (start, callback) { + fs.readdirSync(start).forEach(name => { + if (name === 'node_modules') { + return // hack + } + var abspath = path.join(start, name) + if (fs.statSync(abspath).isDirectory()) { + fs.walkSync(abspath, callback) + } else { + callback(abspath) + } + }) +} + +module.exports = fs diff --git a/remix-tests/src/index.js b/remix-tests/src/index.js index 7e430bcacf..b2b64a0430 100644 --- a/remix-tests/src/index.js +++ b/remix-tests/src/index.js @@ -1,247 +1,6 @@ -const async = require('async') -const path = require('path') -const fs = require('fs') -require('colors') - -let Compiler = require('./compiler.js') -let Deployer = require('./deployer.js') -let TestRunner = require('./testRunner.js') - -const Web3 = require('web3') -const Provider = require('remix-simulator').Provider - -var createWeb3Provider = function () { - let web3 = new Web3() - web3.setProvider(new Provider()) - return web3 -} - -var runTestSources = function (contractSources, testCallback, resultCallback, finalCallback, importFileCb, opts) { - opts = opts || {} - let web3 = opts.web3 || createWeb3Provider() - let accounts = opts.accounts || null - async.waterfall([ - function getAccountList (next) { - if (accounts) return next() - web3.eth.getAccounts((_err, _accounts) => { - accounts = _accounts - next() - }) - }, - function compile (next) { - Compiler.compileContractSources(contractSources, importFileCb, { accounts }, next) - }, - function deployAllContracts (compilationResult, next) { - Deployer.deployAll(compilationResult, web3, function (err, contracts) { - if (err) { - next(err) - } - - next(null, compilationResult, contracts) - }) - }, - function determineTestContractsToRun (compilationResult, contracts, next) { - let contractsToTest = [] - let contractsToTestDetails = [] - - for (let filename in compilationResult) { - if (filename.indexOf('_test.sol') < 0) { - continue - } - Object.keys(compilationResult[filename]).forEach(contractName => { - contractsToTestDetails.push(compilationResult[filename][contractName]) - contractsToTest.push(contractName) - }) - } - - next(null, contractsToTest, contractsToTestDetails, contracts) - }, - function runTests (contractsToTest, contractsToTestDetails, contracts, next) { - let totalPassing = 0 - let totalFailing = 0 - let totalTime = 0 - let errors = [] - - var _testCallback = function (result) { - if (result.type === 'testFailure') { - errors.push(result) - } - testCallback(result) - } - - var _resultsCallback = function (_err, result, cb) { - resultCallback(_err, result, () => {}) - totalPassing += result.passingNum - totalFailing += result.failureNum - totalTime += result.timePassed - cb() - } - - async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => { - TestRunner.runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, _testCallback, (err, result) => { - if (err) { - return cb(err) - } - _resultsCallback(null, result, cb) - }) - }, function (err, _results) { - if (err) { - return next(err) - } - - let finalResults = {} - - finalResults.totalPassing = totalPassing || 0 - finalResults.totalFailing = totalFailing || 0 - finalResults.totalTime = totalTime || 0 - finalResults.errors = [] - - errors.forEach((error, _index) => { - finalResults.errors.push({context: error.context, value: error.value, message: error.errMsg}) - }) - - next(null, finalResults) - }) - } - ], finalCallback) -} - -var runTestFiles = function (filepath, isDirectory, web3, opts) { - opts = opts || {} - const { Signale } = require('signale') - // signale configuration - const options = { - types: { - result: { - badge: '\t✓', - label: '', - color: 'greenBright' - }, - name: { - badge: '\n\t◼', - label: '', - color: 'white' - }, - error: { - badge: '\t✘', - label: '', - color: 'redBright' - } - } - } - const signale = new Signale(options) - let accounts = opts.accounts || null - async.waterfall([ - function getAccountList (next) { - if (accounts) return next(null) - web3.eth.getAccounts((_err, _accounts) => { - accounts = _accounts - next(null) - }) - }, - function compile (next) { - Compiler.compileFileOrFiles(filepath, isDirectory, { accounts }, next) - }, - function deployAllContracts (compilationResult, next) { - Deployer.deployAll(compilationResult, web3, function (err, contracts) { - if (err) { - next(err) - } - next(null, compilationResult, contracts) - }) - }, - function determineTestContractsToRun (compilationResult, contracts, next) { - let contractsToTest = [] - let contractsToTestDetails = [] - const gatherContractsFrom = (filename) => { - if (filename.indexOf('_test.sol') < 0) { - return - } - Object.keys(compilationResult[path.basename(filename)]).forEach(contractName => { - contractsToTest.push(contractName) - contractsToTestDetails.push(compilationResult[path.basename(filename)][contractName]) - }) - } - - if (isDirectory) { - fs.walkSync = function (start, callback) { - fs.readdirSync(start).forEach(name => { - if (name === 'node_modules') { - return // hack - } - var abspath = path.join(start, name) - if (fs.statSync(abspath).isDirectory()) { - fs.walkSync(abspath, callback) - } else { - callback(abspath) - } - }) - } - fs.walkSync(filepath, foundpath => { - gatherContractsFrom(foundpath) - }) - } else { - gatherContractsFrom(filepath) - } - next(null, contractsToTest, contractsToTestDetails, contracts) - }, - function runTests (contractsToTest, contractsToTestDetails, contracts, next) { - let totalPassing = 0 - let totalFailing = 0 - let totalTime = 0 - let errors = [] - - var testCallback = function (result) { - if (result.type === 'contract') { - signale.name(result.value.white) - } else if (result.type === 'testPass') { - signale.result(result.value) - } else if (result.type === 'testFailure') { - signale.result(result.value.red) - errors.push(result) - } - } - var resultsCallback = function (_err, result, cb) { - totalPassing += result.passingNum - totalFailing += result.failureNum - totalTime += result.timePassed - cb() - } - - async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => { - TestRunner.runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, testCallback, (err, result) => { - if (err) { - return cb(err) - } - resultsCallback(null, result, cb) - }) - }, function (err, _results) { - if (err) { - return next(err) - } - - console.log('\n') - if (totalPassing > 0) { - console.log((' ' + totalPassing + ' passing ').green + ('(' + totalTime + 's)').grey) - } - if (totalFailing > 0) { - console.log((' ' + totalFailing + ' failing').red) - } - console.log('') - - errors.forEach((error, index) => { - console.log(' ' + (index + 1) + ') ' + error.context + ' ' + error.value) - console.log('') - console.log(('\t error: ' + error.errMsg).red) - }) - console.log('') - - next() - }) - } - ], function () { - }) -} +const runTestFiles = require('./runTestFiles.js') +const runTestSources = require('./runTestSources.js') +const TestRunner = require('./testRunner.js') module.exports = { runTestFiles: runTestFiles, diff --git a/remix-tests/src/runTestFiles.js b/remix-tests/src/runTestFiles.js new file mode 100644 index 0000000000..a733b76efd --- /dev/null +++ b/remix-tests/src/runTestFiles.js @@ -0,0 +1,133 @@ +const async = require('async') +const path = require('path') +const fs = require('./fs') +const TestRunner = require('./testRunner.js') +require('colors') + +let Compiler = require('./compiler.js') +let Deployer = require('./deployer.js') + +const runTestFiles = function (filepath, isDirectory, web3, opts) { + opts = opts || {} + const { Signale } = require('signale') + // signale configuration + const options = { + types: { + result: { + badge: '\t✓', + label: '', + color: 'greenBright' + }, + name: { + badge: '\n\t◼', + label: '', + color: 'white' + }, + error: { + badge: '\t✘', + label: '', + color: 'redBright' + } + } + } + const signale = new Signale(options) + let accounts = opts.accounts || null + async.waterfall([ + function getAccountList (next) { + if (accounts) return next(null) + web3.eth.getAccounts((_err, _accounts) => { + accounts = _accounts + next(null) + }) + }, + function compile (next) { + Compiler.compileFileOrFiles(filepath, isDirectory, { accounts }, next) + }, + function deployAllContracts (compilationResult, next) { + Deployer.deployAll(compilationResult, web3, function (err, contracts) { + if (err) { + next(err) + } + next(null, compilationResult, contracts) + }) + }, + function determineTestContractsToRun (compilationResult, contracts, next) { + let contractsToTest = [] + let contractsToTestDetails = [] + const gatherContractsFrom = (filename) => { + if (filename.indexOf('_test.sol') < 0) { + return + } + Object.keys(compilationResult[path.basename(filename)]).forEach(contractName => { + contractsToTest.push(contractName) + contractsToTestDetails.push(compilationResult[path.basename(filename)][contractName]) + }) + } + if (isDirectory) { + fs.walkSync(filepath, foundpath => { + gatherContractsFrom(foundpath) + }) + } else { + gatherContractsFrom(filepath) + } + next(null, contractsToTest, contractsToTestDetails, contracts) + }, + function runTests (contractsToTest, contractsToTestDetails, contracts, next) { + let totalPassing = 0 + let totalFailing = 0 + let totalTime = 0 + let errors = [] + + var testCallback = function (result) { + if (result.type === 'contract') { + signale.name(result.value.white) + } else if (result.type === 'testPass') { + signale.result(result.value) + } else if (result.type === 'testFailure') { + signale.result(result.value.red) + errors.push(result) + } + } + var resultsCallback = function (_err, result, cb) { + totalPassing += result.passingNum + totalFailing += result.failureNum + totalTime += result.timePassed + cb() + } + + async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => { + TestRunner.runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, testCallback, (err, result) => { + if (err) { + return cb(err) + } + resultsCallback(null, result, cb) + }) + }, function (err, _results) { + if (err) { + return next(err) + } + + console.log('\n') + if (totalPassing > 0) { + console.log((' ' + totalPassing + ' passing ').green + ('(' + totalTime + 's)').grey) + } + if (totalFailing > 0) { + console.log((' ' + totalFailing + ' failing').red) + } + console.log('') + + errors.forEach((error, index) => { + console.log(' ' + (index + 1) + ') ' + error.context + ' ' + error.value) + console.log('') + console.log(('\t error: ' + error.errMsg).red) + }) + console.log('') + + next() + }) + } + ], function () { + }) +} + +module.exports = runTestFiles diff --git a/remix-tests/src/runTestSources.js b/remix-tests/src/runTestSources.js new file mode 100644 index 0000000000..e91bd66a98 --- /dev/null +++ b/remix-tests/src/runTestSources.js @@ -0,0 +1,107 @@ +const async = require('async') +require('colors') + +let Compiler = require('./compiler.js') +let Deployer = require('./deployer.js') +let TestRunner = require('./testRunner.js') + +const Web3 = require('web3') +const Provider = require('remix-simulator').Provider + +var createWeb3Provider = function () { + let web3 = new Web3() + web3.setProvider(new Provider()) + return web3 +} + +const runTestSources = function (contractSources, testCallback, resultCallback, finalCallback, importFileCb, opts) { + opts = opts || {} + let web3 = opts.web3 || createWeb3Provider() + let accounts = opts.accounts || null + async.waterfall([ + function getAccountList (next) { + if (accounts) return next() + web3.eth.getAccounts((_err, _accounts) => { + accounts = _accounts + next() + }) + }, + function compile (next) { + Compiler.compileContractSources(contractSources, importFileCb, next) + }, + function deployAllContracts (compilationResult, next) { + Deployer.deployAll(compilationResult, web3, function (err, contracts) { + if (err) { + next(err) + } + + next(null, compilationResult, contracts) + }) + }, + function determineTestContractsToRun (compilationResult, contracts, next) { + let contractsToTest = [] + let contractsToTestDetails = [] + + for (let filename in compilationResult) { + if (filename.indexOf('_test.sol') < 0) { + continue + } + Object.keys(compilationResult[filename]).forEach(contractName => { + contractsToTestDetails.push(compilationResult[filename][contractName]) + contractsToTest.push(contractName) + }) + } + + next(null, contractsToTest, contractsToTestDetails, contracts) + }, + function runTests (contractsToTest, contractsToTestDetails, contracts, next) { + let totalPassing = 0 + let totalFailing = 0 + let totalTime = 0 + let errors = [] + + var _testCallback = function (result) { + if (result.type === 'testFailure') { + errors.push(result) + } + testCallback(result) + } + + var _resultsCallback = function (_err, result, cb) { + resultCallback(_err, result, () => {}) + totalPassing += result.passingNum + totalFailing += result.failureNum + totalTime += result.timePassed + cb() + } + + async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => { + TestRunner.runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, _testCallback, (err, result) => { + if (err) { + return cb(err) + } + _resultsCallback(null, result, cb) + }) + }, function (err, _results) { + if (err) { + return next(err) + } + + let finalResults = {} + + finalResults.totalPassing = totalPassing || 0 + finalResults.totalFailing = totalFailing || 0 + finalResults.totalTime = totalTime || 0 + finalResults.errors = [] + + errors.forEach((error, _index) => { + finalResults.errors.push({context: error.context, value: error.value, message: error.errMsg}) + }) + + next(null, finalResults) + }) + } + ], finalCallback) +} + +module.exports = runTestSources From 0efc902da50737a59457e83bcc228cc49f9c28af Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Mon, 19 Nov 2018 09:45:42 +0530 Subject: [PATCH 32/46] use filepath again --- remix-tests/src/compiler.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index ff00ed2cab..932e3911da 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -26,13 +26,14 @@ var isBrowser = !(typeof (window) === 'undefined' || userAgent.indexOf(' electro // TODO: replace this with remix's own compiler code function compileFileOrFiles (filename, isDirectory, opts, cb) { - let compiler, filepath + let compiler let accounts = opts.accounts || [] const sources = { 'tests.sol': { content: require('../sol/tests.sol.js') }, 'remix_tests.sol': { content: require('../sol/tests.sol.js') }, 'remix_accounts.sol': { content: writeTestAccountsContract(accounts) } } + const filepath = (isDirectory ? filename : path.dirname(filename)) // TODO: for now assumes filepath dir contains all tests, later all this // should be replaced with remix's & browser solidity compiler code @@ -40,7 +41,6 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { // We should only look into current file if a full file name with path is given // We should only walk through directory if a directory name is passed try { - filepath = (isDirectory ? filename : path.dirname(filename)) // walkSync only if it is a directory fs.walkSync(filepath, foundpath => { // only process .sol files @@ -68,7 +68,7 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { compiler.event.register('compilationFinished', this, function (success, data, source) { next(null, data) }) - compiler.compile(sources, false) + compiler.compile(sources, filepath) } ], function (err, result) { let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') From ff03ade1d0d08b8ed994f2a61ce9902e1bf7beff Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Tue, 20 Nov 2018 14:57:26 +0530 Subject: [PATCH 33/46] fix conflicts --- remix-tests/src/index.js | 252 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 249 insertions(+), 3 deletions(-) diff --git a/remix-tests/src/index.js b/remix-tests/src/index.js index b2b64a0430..d0e90f0d58 100644 --- a/remix-tests/src/index.js +++ b/remix-tests/src/index.js @@ -1,6 +1,252 @@ -const runTestFiles = require('./runTestFiles.js') -const runTestSources = require('./runTestSources.js') -const TestRunner = require('./testRunner.js') +const async = require('async') +const path = require('path') +const fs = require('fs') +require('colors') + +let Compiler = require('./compiler.js') +let Deployer = require('./deployer.js') +let TestRunner = require('./testRunner.js') + +const Web3 = require('web3') +const Provider = require('remix-simulator').Provider + +var createWeb3Provider = function () { + let web3 = new Web3() + web3.setProvider(new Provider()) + return web3 +} + +var runTestSources = function (contractSources, testCallback, resultCallback, finalCallback, importFileCb, opts) { + opts = opts || {} + let web3 = opts.web3 || createWeb3Provider() + let accounts = opts.accounts || null + async.waterfall([ + function getAccountList (next) { + if (accounts) return next() + web3.eth.getAccounts((_err, _accounts) => { + accounts = _accounts + next() + }) + }, + function compile (next) { + Compiler.compileContractSources(contractSources, importFileCb, { accounts }, next) + }, + function deployAllContracts (compilationResult, next) { + Deployer.deployAll(compilationResult, web3, function (err, contracts) { + if (err) { + next(err) + } + + next(null, compilationResult, contracts) + }) + }, + function determineTestContractsToRun (compilationResult, contracts, next) { + let contractsToTest = [] + let contractsToTestDetails = [] + + for (let filename in compilationResult) { + if (filename.indexOf('_test.sol') < 0) { + continue + } + Object.keys(compilationResult[filename]).forEach(contractName => { + contractsToTestDetails.push(compilationResult[filename][contractName]) + contractsToTest.push(contractName) + }) + } + + next(null, contractsToTest, contractsToTestDetails, contracts) + }, + function runTests (contractsToTest, contractsToTestDetails, contracts, next) { + let totalPassing = 0 + let totalFailing = 0 + let totalTime = 0 + let errors = [] + + var _testCallback = function (result) { + if (result.type === 'testFailure') { + errors.push(result) + } + testCallback(result) + } + + var _resultsCallback = function (_err, result, cb) { + resultCallback(_err, result, () => {}) + totalPassing += result.passingNum + totalFailing += result.failureNum + totalTime += result.timePassed + cb() + } + + async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => { + TestRunner.runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, _testCallback, (err, result) => { + if (err) { + return cb(err) + } + _resultsCallback(null, result, cb) + }) + }, function (err, _results) { + if (err) { + return next(err) + } + + let finalResults = {} + + finalResults.totalPassing = totalPassing || 0 + finalResults.totalFailing = totalFailing || 0 + finalResults.totalTime = totalTime || 0 + finalResults.errors = [] + + errors.forEach((error, _index) => { + finalResults.errors.push({context: error.context, value: error.value, message: error.errMsg}) + }) + + next(null, finalResults) + }) + } + ], finalCallback) +} + +var runTestFiles = function (filepath, isDirectory, web3, opts) { + opts = opts || {} + const { Signale } = require('signale') + // signale configuration + const options = { + types: { + result: { + badge: '\t✓', + label: '', + color: 'greenBright' + }, + name: { + badge: '\n\t◼', + label: '', + color: 'white' + }, + error: { + badge: '\t✘', + label: '', + color: 'redBright' + } + } + } + const signale = new Signale(options) + let accounts = opts.accounts || null + async.waterfall([ + function getAccountList (next) { + if (accounts) return next(null) + web3.eth.getAccounts((_err, _accounts) => { + accounts = _accounts + next(null) + }) + }, + function compile (next) { + Compiler.compileFileOrFiles(filepath, isDirectory, { accounts }, next) + }, + function deployAllContracts (compilationResult, next) { + Deployer.deployAll(compilationResult, web3, function (err, contracts) { + if (err) { + next(err) + } + next(null, compilationResult, contracts) + }) + }, + function determineTestContractsToRun (compilationResult, contracts, next) { + let contractsToTest = [] + let contractsToTestDetails = [] + var gatherContractsFrom = (filename) => { + if (filename.indexOf('_test.sol') < 0) { + return + } + Object.keys(compilationResult[path.basename(filename)]).forEach(contractName => { + contractsToTest.push(contractName) + contractsToTestDetails.push(compilationResult[path.basename(filename)][contractName]) + }) + } + + if (isDirectory) { + fs.walkSync = function (start, callback) { + fs.readdirSync(start).forEach(name => { + if (name === 'node_modules') { + return; // hack + } + var abspath = path.join(start, name); + if (fs.statSync(abspath).isDirectory()) { + fs.walkSync(abspath, callback); + } else { + callback(abspath); + } + }); + }; + fs.walkSync(filepath, foundpath => { + if (foundpath.indexOf('_test.sol') < 0) { + return + } + Object.keys(compilationResult[foundpath]).forEach(contractName => { + contractsToTest.push(contractName) + }) + }) + } else { + gatherContractsFrom(filepath) + } + next(null, contractsToTest, contractsToTestDetails, contracts) + }, + function runTests (contractsToTest, contractsToTestDetails, contracts, next) { + let totalPassing = 0 + let totalFailing = 0 + let totalTime = 0 + let errors = [] + + var testCallback = function (result) { + if (result.type === 'contract') { + signale.name(result.value.white) + } else if (result.type === 'testPass') { + signale.result(result.value) + } else if (result.type === 'testFailure') { + signale.result(result.value.red) + errors.push(result) + } + } + var resultsCallback = function (_err, result, cb) { + totalPassing += result.passingNum + totalFailing += result.failureNum + totalTime += result.timePassed + cb() + } + + async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => { + TestRunner.runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, testCallback, (err, result) => { + if (err) { + return cb(err) + } + resultsCallback(null, result, cb) + }) + }, function (err, _results) { + if (err) { + return next(err) + } + + console.log('\n') + if (totalPassing > 0) { + console.log((' ' + totalPassing + ' passing ').green + ('(' + totalTime + 's)').grey) + } + if (totalFailing > 0) { + console.log((' ' + totalFailing + ' failing').red) + } + console.log('') + + errors.forEach((error, index) => { + console.log(' ' + (index + 1) + ') ' + error.context + ' ' + error.value) + console.log('') + console.log(('\t error: ' + error.errMsg).red) + }) + console.log('') + + next() + }) + } + ], function () { + }) +} module.exports = { runTestFiles: runTestFiles, From 4ee3a6f496bf299cd6201e2a5a661554ea15817b Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Tue, 20 Nov 2018 14:58:46 +0530 Subject: [PATCH 34/46] fix conflicts --- remix-tests/src/compiler.js | 85 ++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index 932e3911da..9a42bd2397 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -37,48 +37,55 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { // TODO: for now assumes filepath dir contains all tests, later all this // should be replaced with remix's & browser solidity compiler code - // This logic is wrong - // We should only look into current file if a full file name with path is given - // We should only walk through directory if a directory name is passed - try { - // walkSync only if it is a directory - fs.walkSync(filepath, foundpath => { - // only process .sol files - if (foundpath.split('.').pop() === 'sol') { - let c = fs.readFileSync(foundpath).toString() - const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm - if (foundpath.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { - c = c.replace(/(pragma solidity \^?\d+\.\d+\.\d+;)/, '$1\nimport \'remix_tests.sol\';') - } - sources[foundpath] = { content: c } + // https://github.com/mikeal/node-utils/blob/master/file/lib/main.js + fs.walkSync = function (start, callback) { + fs.readdirSync(start).forEach(name => { + if (name === 'node_modules') { + return; // hack } - }) - } catch (e) { - throw e - } finally { - async.waterfall([ - function loadCompiler (next) { - compiler = new RemixCompiler() - compiler.onInternalCompilerLoaded() - // compiler.event.register('compilerLoaded', this, function (version) { - next() - // }); - }, - function doCompilation (next) { - compiler.event.register('compilationFinished', this, function (success, data, source) { - next(null, data) - }) - compiler.compile(sources, filepath) + var abspath = path.join(start, name); + if (fs.statSync(abspath).isDirectory()) { + fs.walkSync(abspath, callback); + } else { + callback(abspath); } - ], function (err, result) { - let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') - if (errors.length > 0) { - if (!isBrowser) require('signale').fatal(errors) - return cb(new Error('errors compiling')) + }); + }; + + fs.walkSync(filepath, foundpath => { + // only process .sol files + if (foundpath.split('.').pop() === 'sol') { + let c = fs.readFileSync(foundpath).toString() + const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm + if (foundpath.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { + c = c.replace(/(pragma solidity \^?\d+\.\d+\.\d+;)/, '$1\nimport \'remix_tests.sol\';') } - cb(err, result.contracts) - }) - } + sources[foundpath] = { content: c } + } + }) + + async.waterfall([ + function loadCompiler (next) { + compiler = new RemixCompiler() + compiler.onInternalCompilerLoaded() + // compiler.event.register('compilerLoaded', this, function (version) { + next() + // }); + }, + function doCompilation (next) { + compiler.event.register('compilationFinished', this, function (success, data, source) { + next(null, data) + }) + compiler.compile(sources, false) + } + ], function (err, result) { + let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') + if (errors.length > 0) { + if (!isBrowser) require('signale').fatal(errors) + return cb(new Error('errors compiling')) + } + cb(err, result.contracts) + }) } function compileContractSources (sources, importFileCb, opts, cb) { From aa9c054a1f1435f725c16d649782f63d2eb786b1 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Oct 2018 22:30:36 -0400 Subject: [PATCH 35/46] less semicolons --- remix-tests/src/compiler.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index 9a42bd2397..45a6004924 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -41,16 +41,16 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { fs.walkSync = function (start, callback) { fs.readdirSync(start).forEach(name => { if (name === 'node_modules') { - return; // hack + return // hack } - var abspath = path.join(start, name); + var abspath = path.join(start, name) if (fs.statSync(abspath).isDirectory()) { - fs.walkSync(abspath, callback); + fs.walkSync(abspath, callback) } else { - callback(abspath); + callback(abspath) } - }); - }; + }) + } fs.walkSync(filepath, foundpath => { // only process .sol files From 585a5703d1616f5f9cf043649316c6fa3c0a5b4b Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Oct 2018 22:31:13 -0400 Subject: [PATCH 36/46] Better indentation --- remix-tests/src/compiler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index 45a6004924..392dcc81a7 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -57,7 +57,7 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { if (foundpath.split('.').pop() === 'sol') { let c = fs.readFileSync(foundpath).toString() const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm - if (foundpath.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { + if (foundpath.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { c = c.replace(/(pragma solidity \^?\d+\.\d+\.\d+;)/, '$1\nimport \'remix_tests.sol\';') } sources[foundpath] = { content: c } From df8b2a1a96e067f679c3834ae12d5e999b35e82c Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Oct 2018 22:31:36 -0400 Subject: [PATCH 37/46] Less semicolons --- remix-tests/src/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/remix-tests/src/index.js b/remix-tests/src/index.js index d0e90f0d58..dfefef5329 100644 --- a/remix-tests/src/index.js +++ b/remix-tests/src/index.js @@ -167,16 +167,16 @@ var runTestFiles = function (filepath, isDirectory, web3, opts) { fs.walkSync = function (start, callback) { fs.readdirSync(start).forEach(name => { if (name === 'node_modules') { - return; // hack + return // hack } - var abspath = path.join(start, name); + var abspath = path.join(start, name) if (fs.statSync(abspath).isDirectory()) { - fs.walkSync(abspath, callback); + fs.walkSync(abspath, callback) } else { - callback(abspath); + callback(abspath) } - }); - }; + }) + } fs.walkSync(filepath, foundpath => { if (foundpath.indexOf('_test.sol') < 0) { return From fc01e7b576b8c6a46d5cc61fe5a0b7bde08b6ffa Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Tue, 20 Nov 2018 14:59:57 +0530 Subject: [PATCH 38/46] fix conflicts --- remix-tests/tests/testRunner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/remix-tests/tests/testRunner.js b/remix-tests/tests/testRunner.js index 3b5dc673f6..3a38c9d973 100644 --- a/remix-tests/tests/testRunner.js +++ b/remix-tests/tests/testRunner.js @@ -182,7 +182,7 @@ describe('testRunner', function () { done() } - TestRunner.runTest('SenderTest', contracts.SenderTest, compilationData[filename]['SenderTest'], { accounts }, testCallback, resultsCallback) + TestRunner.runTest('SenderTest', contracts.SenderTest, compilationData['sender_test.sol']['SenderTest'], { accounts }, testCallback, resultsCallback) }) }) From 0e6fe2a495103e1afd1c40ff478f4853bced1d51 Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Tue, 20 Nov 2018 15:00:39 +0530 Subject: [PATCH 39/46] fix conflicts --- remix-tests/tests/testRunner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/remix-tests/tests/testRunner.js b/remix-tests/tests/testRunner.js index 3a38c9d973..3b5dc673f6 100644 --- a/remix-tests/tests/testRunner.js +++ b/remix-tests/tests/testRunner.js @@ -182,7 +182,7 @@ describe('testRunner', function () { done() } - TestRunner.runTest('SenderTest', contracts.SenderTest, compilationData['sender_test.sol']['SenderTest'], { accounts }, testCallback, resultsCallback) + TestRunner.runTest('SenderTest', contracts.SenderTest, compilationData[filename]['SenderTest'], { accounts }, testCallback, resultsCallback) }) }) From 5793f1c9e2bcf618f08687a40db12b018e6c367d Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Wed, 14 Nov 2018 19:06:25 +0530 Subject: [PATCH 40/46] Use gatherContractsFrom to collect contracts in fs.walkSync --- remix-tests/src/index.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/remix-tests/src/index.js b/remix-tests/src/index.js index dfefef5329..7e430bcacf 100644 --- a/remix-tests/src/index.js +++ b/remix-tests/src/index.js @@ -153,7 +153,7 @@ var runTestFiles = function (filepath, isDirectory, web3, opts) { function determineTestContractsToRun (compilationResult, contracts, next) { let contractsToTest = [] let contractsToTestDetails = [] - var gatherContractsFrom = (filename) => { + const gatherContractsFrom = (filename) => { if (filename.indexOf('_test.sol') < 0) { return } @@ -178,12 +178,7 @@ var runTestFiles = function (filepath, isDirectory, web3, opts) { }) } fs.walkSync(filepath, foundpath => { - if (foundpath.indexOf('_test.sol') < 0) { - return - } - Object.keys(compilationResult[foundpath]).forEach(contractName => { - contractsToTest.push(contractName) - }) + gatherContractsFrom(foundpath) }) } else { gatherContractsFrom(filepath) From 90dce69ef5e10af02440d24e00c08e756f6ba24f Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Tue, 20 Nov 2018 15:01:42 +0530 Subject: [PATCH 41/46] fix conflicts --- remix-tests/src/compiler.js | 84 ++++++------ remix-tests/src/index.js | 247 +----------------------------------- 2 files changed, 42 insertions(+), 289 deletions(-) diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index 392dcc81a7..b45aef5184 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -37,55 +37,49 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { // TODO: for now assumes filepath dir contains all tests, later all this // should be replaced with remix's & browser solidity compiler code - // https://github.com/mikeal/node-utils/blob/master/file/lib/main.js - fs.walkSync = function (start, callback) { - fs.readdirSync(start).forEach(name => { - if (name === 'node_modules') { - return // hack + // This logic is wrong + // We should only look into current file if a full file name with path is given + // We should only walk through directory if a directory name is passed + try { + filepath = (isDirectory ? filename : path.dirname(filename)) + // walkSync only if it is a directory + fs.walkSync(filepath, foundpath => { + // only process .sol files + if (foundpath.split('.').pop() === 'sol') { + let c = fs.readFileSync(foundpath).toString() + const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm + if (foundpath.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { + c = c.replace(/(pragma solidity \^?\d+\.\d+\.\d+;)/, '$1\nimport \'remix_tests.sol\';') + } + sources[foundpath] = { content: c } } - var abspath = path.join(start, name) - if (fs.statSync(abspath).isDirectory()) { - fs.walkSync(abspath, callback) - } else { - callback(abspath) + }) + } catch (e) { + throw e + } finally { + async.waterfall([ + function loadCompiler (next) { + compiler = new RemixCompiler() + compiler.onInternalCompilerLoaded() + // compiler.event.register('compilerLoaded', this, function (version) { + next() + // }); + }, + function doCompilation (next) { + compiler.event.register('compilationFinished', this, function (success, data, source) { + next(null, data) + }) + compiler.compile(sources, false) + } + ], function (err, result) { + let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') + if (errors.length > 0) { + if (!isBrowser) require('signale').fatal(errors) + return cb(new Error('errors compiling')) } + cb(err, result.contracts) }) } - - fs.walkSync(filepath, foundpath => { - // only process .sol files - if (foundpath.split('.').pop() === 'sol') { - let c = fs.readFileSync(foundpath).toString() - const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm - if (foundpath.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { - c = c.replace(/(pragma solidity \^?\d+\.\d+\.\d+;)/, '$1\nimport \'remix_tests.sol\';') - } - sources[foundpath] = { content: c } - } - }) - - async.waterfall([ - function loadCompiler (next) { - compiler = new RemixCompiler() - compiler.onInternalCompilerLoaded() - // compiler.event.register('compilerLoaded', this, function (version) { - next() - // }); - }, - function doCompilation (next) { - compiler.event.register('compilationFinished', this, function (success, data, source) { - next(null, data) - }) - compiler.compile(sources, false) - } - ], function (err, result) { - let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') - if (errors.length > 0) { - if (!isBrowser) require('signale').fatal(errors) - return cb(new Error('errors compiling')) - } - cb(err, result.contracts) - }) } function compileContractSources (sources, importFileCb, opts, cb) { diff --git a/remix-tests/src/index.js b/remix-tests/src/index.js index 7e430bcacf..b2b64a0430 100644 --- a/remix-tests/src/index.js +++ b/remix-tests/src/index.js @@ -1,247 +1,6 @@ -const async = require('async') -const path = require('path') -const fs = require('fs') -require('colors') - -let Compiler = require('./compiler.js') -let Deployer = require('./deployer.js') -let TestRunner = require('./testRunner.js') - -const Web3 = require('web3') -const Provider = require('remix-simulator').Provider - -var createWeb3Provider = function () { - let web3 = new Web3() - web3.setProvider(new Provider()) - return web3 -} - -var runTestSources = function (contractSources, testCallback, resultCallback, finalCallback, importFileCb, opts) { - opts = opts || {} - let web3 = opts.web3 || createWeb3Provider() - let accounts = opts.accounts || null - async.waterfall([ - function getAccountList (next) { - if (accounts) return next() - web3.eth.getAccounts((_err, _accounts) => { - accounts = _accounts - next() - }) - }, - function compile (next) { - Compiler.compileContractSources(contractSources, importFileCb, { accounts }, next) - }, - function deployAllContracts (compilationResult, next) { - Deployer.deployAll(compilationResult, web3, function (err, contracts) { - if (err) { - next(err) - } - - next(null, compilationResult, contracts) - }) - }, - function determineTestContractsToRun (compilationResult, contracts, next) { - let contractsToTest = [] - let contractsToTestDetails = [] - - for (let filename in compilationResult) { - if (filename.indexOf('_test.sol') < 0) { - continue - } - Object.keys(compilationResult[filename]).forEach(contractName => { - contractsToTestDetails.push(compilationResult[filename][contractName]) - contractsToTest.push(contractName) - }) - } - - next(null, contractsToTest, contractsToTestDetails, contracts) - }, - function runTests (contractsToTest, contractsToTestDetails, contracts, next) { - let totalPassing = 0 - let totalFailing = 0 - let totalTime = 0 - let errors = [] - - var _testCallback = function (result) { - if (result.type === 'testFailure') { - errors.push(result) - } - testCallback(result) - } - - var _resultsCallback = function (_err, result, cb) { - resultCallback(_err, result, () => {}) - totalPassing += result.passingNum - totalFailing += result.failureNum - totalTime += result.timePassed - cb() - } - - async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => { - TestRunner.runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, _testCallback, (err, result) => { - if (err) { - return cb(err) - } - _resultsCallback(null, result, cb) - }) - }, function (err, _results) { - if (err) { - return next(err) - } - - let finalResults = {} - - finalResults.totalPassing = totalPassing || 0 - finalResults.totalFailing = totalFailing || 0 - finalResults.totalTime = totalTime || 0 - finalResults.errors = [] - - errors.forEach((error, _index) => { - finalResults.errors.push({context: error.context, value: error.value, message: error.errMsg}) - }) - - next(null, finalResults) - }) - } - ], finalCallback) -} - -var runTestFiles = function (filepath, isDirectory, web3, opts) { - opts = opts || {} - const { Signale } = require('signale') - // signale configuration - const options = { - types: { - result: { - badge: '\t✓', - label: '', - color: 'greenBright' - }, - name: { - badge: '\n\t◼', - label: '', - color: 'white' - }, - error: { - badge: '\t✘', - label: '', - color: 'redBright' - } - } - } - const signale = new Signale(options) - let accounts = opts.accounts || null - async.waterfall([ - function getAccountList (next) { - if (accounts) return next(null) - web3.eth.getAccounts((_err, _accounts) => { - accounts = _accounts - next(null) - }) - }, - function compile (next) { - Compiler.compileFileOrFiles(filepath, isDirectory, { accounts }, next) - }, - function deployAllContracts (compilationResult, next) { - Deployer.deployAll(compilationResult, web3, function (err, contracts) { - if (err) { - next(err) - } - next(null, compilationResult, contracts) - }) - }, - function determineTestContractsToRun (compilationResult, contracts, next) { - let contractsToTest = [] - let contractsToTestDetails = [] - const gatherContractsFrom = (filename) => { - if (filename.indexOf('_test.sol') < 0) { - return - } - Object.keys(compilationResult[path.basename(filename)]).forEach(contractName => { - contractsToTest.push(contractName) - contractsToTestDetails.push(compilationResult[path.basename(filename)][contractName]) - }) - } - - if (isDirectory) { - fs.walkSync = function (start, callback) { - fs.readdirSync(start).forEach(name => { - if (name === 'node_modules') { - return // hack - } - var abspath = path.join(start, name) - if (fs.statSync(abspath).isDirectory()) { - fs.walkSync(abspath, callback) - } else { - callback(abspath) - } - }) - } - fs.walkSync(filepath, foundpath => { - gatherContractsFrom(foundpath) - }) - } else { - gatherContractsFrom(filepath) - } - next(null, contractsToTest, contractsToTestDetails, contracts) - }, - function runTests (contractsToTest, contractsToTestDetails, contracts, next) { - let totalPassing = 0 - let totalFailing = 0 - let totalTime = 0 - let errors = [] - - var testCallback = function (result) { - if (result.type === 'contract') { - signale.name(result.value.white) - } else if (result.type === 'testPass') { - signale.result(result.value) - } else if (result.type === 'testFailure') { - signale.result(result.value.red) - errors.push(result) - } - } - var resultsCallback = function (_err, result, cb) { - totalPassing += result.passingNum - totalFailing += result.failureNum - totalTime += result.timePassed - cb() - } - - async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => { - TestRunner.runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, testCallback, (err, result) => { - if (err) { - return cb(err) - } - resultsCallback(null, result, cb) - }) - }, function (err, _results) { - if (err) { - return next(err) - } - - console.log('\n') - if (totalPassing > 0) { - console.log((' ' + totalPassing + ' passing ').green + ('(' + totalTime + 's)').grey) - } - if (totalFailing > 0) { - console.log((' ' + totalFailing + ' failing').red) - } - console.log('') - - errors.forEach((error, index) => { - console.log(' ' + (index + 1) + ') ' + error.context + ' ' + error.value) - console.log('') - console.log(('\t error: ' + error.errMsg).red) - }) - console.log('') - - next() - }) - } - ], function () { - }) -} +const runTestFiles = require('./runTestFiles.js') +const runTestSources = require('./runTestSources.js') +const TestRunner = require('./testRunner.js') module.exports = { runTestFiles: runTestFiles, From 74559369fa998886a43d7f15e9b048591134b03a Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Mon, 19 Nov 2018 09:45:42 +0530 Subject: [PATCH 42/46] use filepath again --- remix-tests/src/compiler.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index b45aef5184..932e3911da 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -41,7 +41,6 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { // We should only look into current file if a full file name with path is given // We should only walk through directory if a directory name is passed try { - filepath = (isDirectory ? filename : path.dirname(filename)) // walkSync only if it is a directory fs.walkSync(filepath, foundpath => { // only process .sol files @@ -69,7 +68,7 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { compiler.event.register('compilationFinished', this, function (success, data, source) { next(null, data) }) - compiler.compile(sources, false) + compiler.compile(sources, filepath) } ], function (err, result) { let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') From e159b42ffa112c5eb480222dba06c24c2cf33fb7 Mon Sep 17 00:00:00 2001 From: 0mkar <0mkar@protonmail.com> Date: Tue, 20 Nov 2018 22:42:24 +0530 Subject: [PATCH 43/46] path 0.5.0 updates for remix-tests testing --- remix-tests/tests/examples_3/simple_string_test.sol | 4 ++-- remix-tests/tests/testRunner.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/remix-tests/tests/examples_3/simple_string_test.sol b/remix-tests/tests/examples_3/simple_string_test.sol index 9bcc562167..f1f62cf33c 100644 --- a/remix-tests/tests/examples_3/simple_string_test.sol +++ b/remix-tests/tests/examples_3/simple_string_test.sol @@ -12,8 +12,8 @@ contract StringTest { return Assert.equal(foo.get(), "Hello world!", "initial value is not correct"); } - function valueShouldNotBeHelloWorld() public returns (bool) { - return Assert.notEqual(foo.get(), "Hello wordl!", "initial value is not correct"); + function valueShouldNotBeHelloWordl() public returns (bool) { + return Assert.notEqual(foo.get(), "Hello wordl!", "value should not be hello world"); } function valueShouldBeHelloWorld() public returns (bool) { diff --git a/remix-tests/tests/testRunner.js b/remix-tests/tests/testRunner.js index 3b5dc673f6..092052fb7f 100644 --- a/remix-tests/tests/testRunner.js +++ b/remix-tests/tests/testRunner.js @@ -134,8 +134,8 @@ describe('testRunner', function () { it('should returns 3 messages', function () { assert.deepEqual(tests, [ { type: 'contract', value: 'StringTest', filename: 'tests/examples_3/simple_string_test.sol' }, - { type: 'testFailure', value: 'Value should be hello world', time: 1, context: 'StringTest', "errMsg": "function returned false" }, - { type: 'testPass', value: 'Value should not be hello world', time: 1, context: 'StringTest' }, + { type: 'testFailure', value: 'Value should be hello world', time: 1, context: 'StringTest', "errMsg": "initial value is not correct" }, + { type: 'testPass', value: 'Value should not be hello wordl', time: 1, context: 'StringTest' }, { type: 'testPass', value: 'Initial value should be hello', time: 1, context: 'StringTest' }, ]) }) From 0b405ed75f0744a5dd8d58aed6c3fd63da5777eb Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 2 Jan 2019 13:27:04 +0100 Subject: [PATCH 44/46] always append remix-tests:sol reference --- remix-tests/src/compiler.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index 932e3911da..7b450e97c4 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -47,8 +47,9 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { if (foundpath.split('.').pop() === 'sol') { let c = fs.readFileSync(foundpath).toString() const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm + let includeTestLibs = '\nimport \'remix_tests.sol\';\n' if (foundpath.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { - c = c.replace(/(pragma solidity \^?\d+\.\d+\.\d+;)/, '$1\nimport \'remix_tests.sol\';') + c = includeTestLibs.concat(c) } sources[foundpath] = { content: c } } From 815e2a31c53159fb10d8f94998ef4fbb438d4149 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Tue, 8 Jan 2019 10:16:08 -0500 Subject: [PATCH 45/46] put package versions in line with npm --- remix-analyzer/package.json | 4 ++-- remix-debug/package.json | 4 ++-- remix-lib/package.json | 2 +- remix-simulator/package.json | 4 ++-- remix-solidity/package.json | 4 ++-- remix-tests/package.json | 8 ++++---- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/remix-analyzer/package.json b/remix-analyzer/package.json index 2e0bb6ded7..c5c5b9a751 100644 --- a/remix-analyzer/package.json +++ b/remix-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "remix-analyzer", - "version": "0.2.13", + "version": "0.3.1", "description": "Remix Analyzer", "main": "./index.js", "contributors": [ @@ -18,7 +18,7 @@ } ], "dependencies": { - "remix-lib": "0.3.13" + "remix-lib": "0.4.1" }, "scripts": { "lint": "standard", diff --git a/remix-debug/package.json b/remix-debug/package.json index 3e7c3de0b2..7db0079bfd 100644 --- a/remix-debug/package.json +++ b/remix-debug/package.json @@ -1,6 +1,6 @@ { "name": "remix-debug", - "version": "0.2.14", + "version": "0.3.1", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -21,7 +21,7 @@ "ethereumjs-util": "^4.5.0", "ethereumjs-vm": "2.4.0", "fast-async": "^6.1.2", - "remix-lib": "0.3.13" + "remix-lib": "0.4.1" }, "devDependencies": { "babel-eslint": "^7.1.1", diff --git a/remix-lib/package.json b/remix-lib/package.json index 882021f9d1..51b45d30b8 100644 --- a/remix-lib/package.json +++ b/remix-lib/package.json @@ -1,6 +1,6 @@ { "name": "remix-lib", - "version": "0.3.13", + "version": "0.4.1", "description": "Ethereum IDE and tools for the web", "contributors": [ { diff --git a/remix-simulator/package.json b/remix-simulator/package.json index 7b7771ba7c..ad25583866 100644 --- a/remix-simulator/package.json +++ b/remix-simulator/package.json @@ -1,6 +1,6 @@ { "name": "remix-simulator", - "version": "0.0.8", + "version": "0.1.1", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -21,7 +21,7 @@ "express-ws": "^4.0.0", "fast-async": "^6.3.7", "merge": "^1.2.0", - "remix-lib": "0.3.13", + "remix-lib": "0.4.1", "time-stamp": "^2.0.0", "web3": "1.0.0-beta.27" }, diff --git a/remix-solidity/package.json b/remix-solidity/package.json index de0b52a28e..5bf3707585 100644 --- a/remix-solidity/package.json +++ b/remix-solidity/package.json @@ -1,6 +1,6 @@ { "name": "remix-solidity", - "version": "0.2.14", + "version": "0.3.1", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -17,7 +17,7 @@ "ethereumjs-util": "^4.5.0", "ethereumjs-vm": "2.4.0", "fast-async": "^6.1.2", - "remix-lib": "0.3.13", + "remix-lib": "0.4.1", "solc": "^0.5.0", "webworkify": "^1.2.1" }, diff --git a/remix-tests/package.json b/remix-tests/package.json index 31995f3727..a78636e48f 100644 --- a/remix-tests/package.json +++ b/remix-tests/package.json @@ -1,6 +1,6 @@ { "name": "remix-tests", - "version": "0.0.21", + "version": "0.1.1", "description": "Tests for the Ethereum tool suite Remix", "main": "./src/index.js", "contributors": [ @@ -40,9 +40,9 @@ "change-case": "^3.0.1", "colors": "^1.1.2", "commander": "^2.13.0", - "remix-lib": "0.3.13", - "remix-simulator": "0.0.8", - "remix-solidity": "0.2.14", + "remix-lib": "0.4.1", + "remix-simulator": "0.1.1", + "remix-solidity": "0.3.1", "signale": "^1.2.1", "web3": "1.0.0-beta.36", "winston": "^3.0.0" From 05bbef224b3d046d39b8f97ed06019fcfc1079c4 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 8 Jan 2019 16:35:10 +0100 Subject: [PATCH 46/46] fix teste --- remix-lib/test/txFormat.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/remix-lib/test/txFormat.js b/remix-lib/test/txFormat.js index 48397a0619..39187f5169 100644 --- a/remix-lib/test/txFormat.js +++ b/remix-lib/test/txFormat.js @@ -15,7 +15,7 @@ tape('ContractParameters - (TxFormat.buildData) - format input parameters', func output = JSON.parse(output) var contract = output.contracts['test.sol']['uintContractTest'] context = { output, contract } - var bytecode = '608060405234801561001057600080fd5b50610118806100206000396000f3fe6080604052600436106039576000357c0100000000000000000000000000000000000000000000000000000000900480634b52195314603e575b600080fd5b348015604957600080fd5b50609d60048036036060811015605e57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050609f565b005b8260008190555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505056fea165627a7a72305820eef04af1d305b2d1a4227d962175cf0c1ddc8c5a50f11189b73615d73344a0270029' + var bytecode = '608060405234801561001057600080fd5b50610118806100206000396000f3fe6080604052348015600f57600080fd5b50600436106045576000357c0100000000000000000000000000000000000000000000000000000000900480634b52195314604a575b600080fd5b609d60048036036060811015605e57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050609f565b005b8260008190555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505056fea165627a7a723058201ef20c1b8cb426610dbcf2fd6ff80b99cee4cbf63c1af4e26c951310ff7233c70029' t.test('(TxFormat.buildData)', function (st) { st.plan(3) @@ -98,7 +98,7 @@ function testLinkLibrary2 (st, callbackDeployLibraries) { } } - var data = '608060405234801561001057600080fd5b50610265806100206000396000f3fe60806040526004361061003b576000357c0100000000000000000000000000000000000000000000000000000000900480636d4ce63c14610040575b600080fd5b34801561004c57600080fd5b50610055610057565b005b73f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156100b757600080fd5b505af41580156100cb573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561012f57600080fd5b505af4158015610143573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156101a757600080fd5b505af41580156101bb573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561021f57600080fd5b505af4158015610233573d6000803e3d6000fd5b5050505056fea165627a7a7230582056535474e1f8ba4f728b0d6fff8855d02828ff110ccef98edd3965c6c2a9a4b10029' + var data = '608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b5060043610610048576000357c0100000000000000000000000000000000000000000000000000000000900480636d4ce63c1461004d575b600080fd5b610055610057565b005b73f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156100b757600080fd5b505af41580156100cb573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561012f57600080fd5b505af4158015610143573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b1580156101a757600080fd5b505af41580156101bb573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b15801561021f57600080fd5b505af4158015610233573d6000803e3d6000fd5b5050505056fea165627a7a723058206775efae13f5e8ef63a78158d4c45f4eaa135657958a136d4e22968970f24aac0029' var deployMsg = ['creation of library test.sol:lib1 pending...', 'creation of library test.sol:lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 pending...']