Git Product home page Git Product logo

solidity-shell's Introduction

get in touch with Consensys Diligence
[ 🌐 📩 🔥 ]

Solidity Shell

An interactive Solidity shell with lightweight session recording and remote compiler support.

💾 npm install -g solidity-shell

  solidity-shell
 
🚀 Entering interactive Solidity shell. '.help' and '.exit' are your friends.
 »  ℹ️  ganache-mgr: starting temp. ganache instance ...
 »
 »  uint a = 100
 »  uint b = 200
 »  a + b + 2 + uint8(50)
352
 »  $_
352

Oh, did you know that we automatically fetch a matching remote compiler when you change the solidity pragma? It is as easy as typing pragma solidity 0.5.0 and solidity-shell will do the rest 🙌.

Hints

  • pragma solidity <version> attempts to dynamically load the selected compiler version (remote compiler, may take a couple of seconds).
  • use { <statement>; } to ignore a calls return value.
  • Sessions can be saved and restored using the .session command. Your previous session is always stored and can be loaded via .session load previous (not safe when running concurrent shells).
  • .reset completely removes all statements. .undo removes the last statement.
  • See what's been generated under the hood? call .dump.
  • Settings are saved on exit (not safe when running concurrent shells). call config set <key> <value> to change settings like ganache port, ganache autostart, etc.
  • $_ is a placeholder for the last known result. Feel free to use that placeholder in your scripts :)
  • Special commands are dot-prefixed. Everything else is evaluated as Solidity code.
  • import "<path>" assumes that path is relative to the current working-dir (CWD) or {CWD}/node_modules/. There's experimental support for HTTPs URL's. You can disable https resolving by setting » .config set resolveHttpImports false.
 »  import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/master/contracts/token/ERC721/IERC721.sol"

Usage

Cmdline Passthru

Any arguments provided after an empty -- are directly passed to ganacheCmd (default: ganache-cli). This way, for example, you can start a solidity shell on a ganache fork of mainnet via infura. Check ganache-cli --help for a list of available options.

⇒  solidity-shell -- --fork https://mainnet.infura.io/v3/yourApiToken
 
🚀 Entering interactive Solidity shell. Type '.help' for help, '.exit' to exit.
 »  ℹ️  ganache-mgr: starting temp. ganache instance ...
 »
 »  interface ERC20 {
multi> function name() external view returns (string memory);
multi> }
 
 »  ERC20(0xB8c77482e45F1F44dE1745F52C74426C631bDD52).name()
BNB

Repl

🚀 Entering interactive Solidity ^0.8.11 shell. '.help' and '.exit' are your friends.
 »  ℹ️  ganache-mgr: starting temp. ganache instance ...
 »
 »  .help

📚 Help:
   -----

 $_ is a placeholder holding the most recent evaluation result.
 pragma solidity <version> to change the compiler version.


 General:
    .help                                ... this help :)
    .exit                                ... exit the shell


 Source:
    .fetch 
            interface <address> <name> [chain=mainnet] ... fetch and load an interface declaration from an ABI spec on etherscan.io
    .inspect
            bytecode                     ... show bytecode of underlying contract
            opcodes                      ... show disassembled opcodes of underlying contract
            storageLayout                ... show variable to storage slot mapping for underlying contract
            storage <slot> <num> [<address>] ... show raw storage at slot of underlying deployed contract 
            deployed                     ... debug: show internal contract object


 Blockchain:
    .chain                         
            restart                      ... restart the blockchain service
            set-provider <fork-url>      ... "internal" | <shell-command: e.g. ganache-cli> | <https://localhost:8545>
                                            - fork url e.g. https://mainnet.infura.io/v3/yourApiKey  
            accounts                     ... return eth_getAccounts
            eth_<X> [...args]            ... initiate an arbitrary eth JSONrpc method call to blockchain provider.

 Settings:
    .config                              ... show settings
            set <key> <value>            ... set setting
            unset <key>                  ... unset setting
 Session:
    .session                             ... list sessions
            load <id>                    ... load session
            save <id>                    ... save session
    .undo                                ... undo last command
    .reset                               ... reset cmd history. start from scratch.

 Debug:
    .proc                                ... show processes managed by solidity-shell (ganache)
    .dump                                ... show template contract
    .echo                                ... every shell needs an echo command


cheers 🙌 
    @tintinweb 
    ConsenSys Diligence @ https://consensys.net/diligence/
    https://github.com/tintinweb/solidity-shell/ 

Examples

solidity-shell

Transaction vars: msg.sender etc.

 »  msg.sender
0x70e9B09abd6A13D2F5083CD5814076b77427199F
 »  address(uint160(address(msg.sender)))
0x70e9B09abd6A13D2F5083CD5814076b77427199F

Contracts, Structs, Functions

  solidity-shell
 
🚀 Entering interactive Solidity shell. Type '.help' for help, '.exit' to exit.
 »  ℹ️  ganache-mgr: starting temp. ganache instance ...
 »
 »  contract TestContract {}
 »  new TestContract()
0xFBC1B2e79D816E36a1E1e923dd6c6fad463F4368
 »  msg.sender
0x363830C6aee2F0c43922bcB785C570a7cca613b5
 »  block.timestamp
1630339581
 »  struct yolo {uint8 x; uint8 y;}
 »  function mytest(uint x) public pure returns(uint) {
multi> return x -5;
multi> }
 »  mytest(100)
95

solidity-shell2

Advanced usage

 »  struct yolo {uint8 x; uint8 y;}
 »  .dump
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.7;

contract TestContract {}

struct yolo {uint8 x; uint8 y;}

contract MainContract {

    

    function main() public  {
        uint a = 100;
        uint b = 200;
        a + b + 2 + uint8(50);
        new TestContract();
        msg.sender;
        block.timestamp;
        return ;
    }
}

Fetch Interface Declaration from Etherscan

shell-fetch-interface

.fetch interface <address> <interfaceName> [optional: chain=mainnet]

⇒  solidity-shell --fork https://mainnet.infura.io/v3/<yourApiKey>                                                                                                
 
🚀 Entering interactive Solidity ^0.8.16 shell (🧁:Ganache built-in). '.help' and '.exit' are your friends.
 »  
 »  .fetch interface 0x40cfEe8D71D67108Db46F772B7e2CD55813Bf2FB Test
 »  interface Test {
    
    ... omitted ...

    function symbol() external view returns (string memory);

    function tokenURI(uint256 tokenId) external view returns (string memory);

    function totalSupply() external view returns (uint256);

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    function transferOwnership(address newOwner) external;

    function withdraw() external;
}

 »  Test t = Test(0x40cfEe8D71D67108Db46F772B7e2CD55813Bf2FB)
 »  t.symbol()
MGX

Inspect Contract Storage on Ganache Fork

  1. Run solidity shell in fork-mode.
  2. Display contract storage at latest block.
⇒  solidity-shell --fork https://mainnet.infura.io/v3/<yourApiKey>    

🚀 Entering interactive Solidity ^0.8.16 shell (🧁:Ganache built-in, ⇉ fork-mode). '.help' and '.exit' are your friends.
 »  .inspect storage 0 10 0x40cfEe8D71D67108Db46F772B7e2CD55813Bf2FB
 »  
     📚 Contract:      0x40cfee8d71d67108db46f772b7e2cd55813bf2fb @ latest block

     slot              1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
  --------------------------------------------------------------------------------------------------------------------
  0x000000 (   0)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1d c7    ................................
  0x000001 (   1)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................................
  0x000002 (   2)      54 68 65 20 4d 61 67 69 78 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12    The Magix.......................
  0x000003 (   3)      4d 47 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06    MGX.............................
  0x000004 (   4)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................................
  0x000005 (   5)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................................
  0x000006 (   6)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................................
  0x000007 (   7)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................................
  0x000008 (   8)      00 00 00 00 00 00 00 00 00 00 00 00 d7 4e 84 57 2f 5f 7b 5d 41 47 4e be d9 b3 02 0a 2e 52 6f c6    .............N.W/_{]AGN......Ro.
  0x000009 (   9)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 0f    ..............................'.

Inspect Generated Contract

  solidity-shell       
 
🚀 Entering interactive Solidity ^0.8.16 shell (🧁:Ganache built-in, ⇉ fork-mode). '.help' and '.exit' are your friends.
 »  1+1
2
 »  .inspect bytecode
6080604052348015610010576000 ... 03a7bab64736f6c63430008100033
 »  .inspect opcodes
PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE ... SLOAD 0xDA POP GASPRICE PUSH28 0xAB64736F6C6343000810003300000000000000000000000000000000 
 »  .inspect storageLayout
{ storage: [], types: null }
 »  .inspect storage 0 4
 »  
     📚 Contract:      0xCa1061046396daF801dEB0D848FcfeA055fAfBFC @ latest block

     slot              1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
  --------------------------------------------------------------------------------------------------------------------
  0x000000 (   0)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................................
  0x000001 (   1)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................................
  0x000002 (   2)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................................
  0x000003 (   3)      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................................

Acknowledgements

  • Inspired by the great but unfortunately unmaintained solidity-repl.
  • Fetch interfaces from Etherscan is powered by abi-to-sol.

solidity-shell's People

Contributors

gnidan avatar tintinweb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

solidity-shell's Issues

Installer fails without ganache-cli

FYI, the solidity-shell npm module fails to install if ganache-cli is not present on the system. You may want to include a blurb about installing that first or maybe include it in your dependencies.

Import Statements not working

Not sure how to import contracts to interact with. Ends up with following error, tried using relative and absolute paths to the sol file.

image

uint128(~0) ?

Maybe it's me but reading https://eips.ethereum.org/EIPS/eip-1155 I see

Inside the contract code the two pieces of data needed to access the individual non-fungible can be extracted with uint128(~0) and the same mask shifted by 128.

But solidity shell throws when inputting uint128(~0) with:

  {
    component: 'general',
    errorCode: '9640',
    formattedMessage: 'TypeError: Explicit type conversion not allowed from "int_const -1" to "uint128".\n' +
      '\n',
    message: 'Explicit type conversion not allowed from "int_const -1" to "uint128".',
    severity: 'error',
    sourceLocation: { end: 276, file: '', start: 265 },
    type: 'TypeError'
  }

Potential windows difference

I retried on windows
node v16.13.2
npm 8.5.4
npm install -g solidity-shell ganache-cli

starting solidity-shell was giving:

🚀 Entering interactive Solidity ^0.8.11 shell. '.help' and '.exit' are your friends.
 »  ℹ️  ganache-mgr: starting temp. ganache instance ...
 »

 🧨 Unable to launch blockchain serivce: ➜ ℹ️  Error: spawn ganache-cli ENOENT

    Please verify that 'ganache-cli' (or similar service) is installed and available in your PATH.
    Otherwise, you can disable autostart by setting 'autostartGanache' to false in your settings or configure a different service and
 '.restartblockchain'.

I had to npm install -g ganache and ganache running in one terminal before starting solidity-shell in another. Cheers

some compiling Error occured

Recently when I run this script some compiling error occurred permanently!
The error is => ( SyntaxError: Unexpected token '.' ) which is related to the web3-core-method folder!
I looked for a relevant solution but I can't find anything :(

Improvement: etherscan API key

Issue: while fetching interfaces, the Ethescan api rate limit of 1req/5sec is hit.

Solution: allowing users to set an Etherscan api key, which would then be used (adding &apiKey=... to

let url = `${provider}/api?module=contract&action=getabi&address=${address}`;
). This would require storing user data tho (but might be nice to have for default provider too), happy to help with dotenv for instance

`Identifier already declared` error

I receive this error in solidity-shell.
image

It seems to occur after setting 512-bits worth of data or somewhere near there. Just doing a little quick testing, here is it happening on the 4th uint128 declaration:
image

Though it took three uint256's to trigger the first time.

Externally-fetched interfaces from Etherscan may not match internal solc version

I noticed that this project is invoking abi-to-sol by asking for Solidity v0.8.9, which differs from this project's solc dependency version of ^0.8.15. This probably isn't a big deal, but in the future it might make sense to align this generateSolidity({ solidityVersion }) field more formally with the version of solc that's running in this shell.

Note that this field accepts a semver range, and abi-to-sol seeks to output Solidity that is valid across all versions in that range... so you can probably start by doing a require("../../package.json").dependencies["solc"] or such and just use that instead of hardcoding some kind of version or version range literal.

Global variable block missing from the shell

As the title suggests, it looks like block and other global variables are missing on this shell

Here's my console output:

 »  block
[
  {
    component: 'general',
    errorCode: '5172',
    formattedMessage: 'TypeError: Name has to refer to a struct, enum or contract.\n\n',
    message: 'Name has to refer to a struct, enum or contract.',
    severity: 'error',
    sourceLocation: { end: 144, file: '', start: 139 },
    type: 'TypeError'
  }
]

Whereas msg seems to be there, even though you can refer to it (!?) But just to its internal properties

»  msg
[
  {
    component: 'general',
    errorCode: '5172',
    formattedMessage: 'TypeError: Name has to refer to a struct, enum or contract.\n\n',
    message: 'Name has to refer to a struct, enum or contract.',
    severity: 'error',
    sourceLocation: { end: 142, file: '', start: 139 },
    type: 'TypeError'
  }
]
 »  msg.data
0xdffeadd0

first steps

Hi, I am new to solidity and I am looking for a way how to quickly test snippets of solidity code, much like I am using dev tools in a browser. I heard yours is a good solution.

I just tried to install your package and I get this error with ganache-mgr. Do you know what might be the problem?

C:\Users\Qwerty>npm i solidity-shell -g
npm WARN deprecated [email protected]: This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.
npm WARN deprecated [email protected]: this library is no longer supported
npm WARN deprecated [email protected]: This module has been superseded by the multiformats module
npm WARN deprecated [email protected]: This module has been superseded by the multiformats module
npm WARN deprecated [email protected]: This module has been superseded by the multiformats module
npm WARN deprecated [email protected]: This module has been superseded by the multiformats module
npm WARN deprecated [email protected]: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated [email protected]: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated [email protected]: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated [email protected]: This module has been superseded by the multiformats module
npm WARN deprecated [email protected]: core-js@<3.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.

added 426 packages, and audited 428 packages in 1m

3 vulnerabilities (2 high, 1 critical)

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.

C:\Users\Qwerty>solidity-shell

🚀 Entering interactive Solidity ^0.8.7 shell. '.help' and '.exit' are your friends.
 »  ℹ️  ganache-mgr: starting temp. ganache instance ...
 »
💀  ganache-mgr: stopping temp. ganache instance


events.js:353
      throw er; // Unhandled 'error' event
      ^

Error: spawn ganache-cli ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:269:19)
    at onErrorNT (internal/child_process.js:467:16)
    at processTicksAndRejections (internal/process/task_queues.js:82:21)
Emitted 'error' event on ChildProcess instance at:
    at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
    at onErrorNT (internal/child_process.js:467:16)
    at processTicksAndRejections (internal/process/task_queues.js:82:21) {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'spawn ganache-cli',
  path: 'ganache-cli',
  spawnargs: []
}

C:\Users\Qwerty>npm -v
7.24.2

C:\Users\Qwerty>node -v
v14.17.0

does this support for loops

I am trying to do a for loop, but failing, am I doing something wrong?

 »  uint[] memory a = new uint[](2)
 »  for (uint i; i < 2; i++) {
multi> a[i] = i;
multi> }
 »  a
[
  {
    component: 'general',
    errorCode: '6933',
    formattedMessage: 'ParserError: Expected primary expression.\n\n',
    message: 'Expected primary expression.',
    severity: 'error',
    sourceLocation: { end: 255, file: '', start: 254 },
    type: 'ParserError'
  }
]

Inlining doesn't help either:

 »  .undo
 »  for (uint i; i<2; i++) { a[i] = i; }
 »  a
[
  {
    component: 'general',
    errorCode: '6933',
    formattedMessage: 'ParserError: Expected primary expression.\n\n',
    message: 'Expected primary expression.',
    severity: 'error',
    sourceLocation: { end: 255, file: '', start: 254 },
    type: 'ParserError'
  }
]

some compiling Error occured

Recently when I run this script some compiling error occurred permanently!
The error is => ( SyntaxError: Unexpected token '.' ) which is related to the web3-core-method folder!
I looked for a relevant solution but I can't find anything :(

Localhost doesn't work on MacOS Big Sur 11.6.1

This line throws after a fresh install on Big Sur. I fixed it by changing the ~/.solidity-shell/.config providerUrl value from http://localhost:8545 to http://127.0.0.1:8545. I was going to submit a PR, but assumed there might be security implications to this change. Given it's a one-liner, you can make it if you deem it safe enough :)

address[] usage in global context?

 »  address[] storage arr;
 »  arr
[
  {
    component: 'general',
    errorCode: '6651',
    formattedMessage: 'TypeError: Data location must be "memory" or "calldata" for return parameter in function, but "storage" was given.\n' +
      '\n',
    message: 'Data location must be "memory" or "calldata" for return parameter in function, but "storage" was given.',
    severity: 'error',
    sourceLocation: { end: 165, file: '', start: 140 },
    type: 'TypeError'
  }
]
 »  address[] memory arr2;
 »  arr2
 »  type(arr2)
BUG: cannot resolve type ://
[
  {
    component: 'general',
    errorCode: '4259',
    formattedMessage: 'TypeError: Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but address[] provided.\n' +
      '\n',
    message: 'Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but address[] provided.',
    severity: 'error',
    sourceLocation: { end: 248, file: '', start: 244 },
    type: 'TypeError'
  }
]
 »

What should be done?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.