---
# System prepended metadata

title: eth_call Investigation Notes

---

---
title: eth_call Investigation Notes
---

# Input Parameters

### Block Number

- latest block number

    ```json=
    // Returns output of NUMBER opcode
    // Code: 0x684360005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": null,
                "to": "{{contractAddress}}",
                "data":""
            },
            "pending"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x00000000000000000000000000000000000000000000000000000000000000df"
    }
    // current block is 224 (pending) so this is the last which is 223
    ```

- pending
    ```json=
    // Returns output of NUMBER opcode
    // Code: 0x684360005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": null,
                "to": "{{contractAddress}}",
                "data":""
            },
            "pending"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x00000000000000000000000000000000000000000000000000000000000000c1"
    }
    // current block is 225 so this is the one in progress
    ```
- earliest
    ```json=
    // Returns output of NUMBER opcode
    // Code: 0x684360005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": null,
                "to": "{{contractAddress}}",
                "data":""
            },
            "earliest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x"
    }
    // earliest retrieves the genesis block
    ```
- mispelled
    ```json
    // Returns output of NUMBER opcode
    // Code: 0x684360005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": null,
                "to": "{{contractAddress}}",
                "data":""
            },
            "latst"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "error": {
            "code": -32602,
            "message": "invalid argument 1: hex string without 0x prefix"
        }
    }
    ```
- null or undefined
    ```json
    // Returns output of NUMBER opcode
    // Code: 0x684360005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": null,
                "to": "{{contractAddress}}",
                "data":""
            },
            null
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "error": {
            "code": -32000,
            "message": "invalid arguments; neither block nor hash specified"
        }
    }
    ```
- block height (hex encoded height)
    - valid height
    ```json
    // Returns output of NUMBER opcode
    // Code: 0x684360005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": null,
                "to": "{{contractAddress}}",
                "data":""
            },
            "0x1"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x0000000000000000000000000000000000000000000000000000000000000001"
    }
    ```
    - height greater than current block
    ```json
    // Returns output of NUMBER opcode
    // Code: 0x684360005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": null,
                "to": "{{contractAddress}}",
                "data":""
            },
            "0x8"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "error": {
            "code": -32000,
            "message": "header not found"
        }
    }
    ```

### <i>from</i>
- null account
    ```json
    // Code: 0x683360005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": null,
                "to": "{{contractAddress}}",
                "data":""
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x0000000000000000000000000000000000000000000000000000000000000000"
    }
    ```
- non-null account
    ```json
    // Code: 0x683360005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "{{Account1}}",
                "to": "{{contractAddress}}",
                "data":""
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x000000000000000000000000c228a058717372e08f58a113df1bdff35babd05a"
    }
    ```
- non-existent account
    ```json
    // Code: 0x683360005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "0xc228a058718372e08f58f113df1bdff35babd05a",
                "to": "{{contractAddress}}",
                "data":""
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x000000000000000000000000c228a058718372e08f58f113df1bdff35babd05a"
    }
    ```
- improperly formatted account 
    - length
        ```json
        // Code: 0x683360005260206000f360005260096017f3
        // request
        {
            "jsonrpc": "2.0",
            "method": "eth_call",
            "params": [
                {
                    "from": "0xc228a058718372e08f58f113dff35babd05a",
                    "to": "{{contractAddress}}",
                    "data":""
                },
                "latest"
            ],
            "id": 8
        }
        // response
        {
            "jsonrpc": "2.0",
            "id": 8,
            "error": {
                "code": -32602,
                "message": "invalid argument 0: hex string has length 36, want 40 for common.Address"
            }
        }
        ```
    - invalid characters
        ```json
        // Code: 0x683360005260206000f360005260096017f3
        // request
        {
            "jsonrpc": "2.0",
            "method": "eth_call",
            "params": [
                {
                    "from": "0xc228a05871837#e08f58f113df1bdff35babd05a",
                    "to": "{{contractAddress}}",
                    "data":""
                },
                "latest"
            ],
            "id": 8
        }
        // response
        {
            "jsonrpc": "2.0",
            "id": 8,
            "error": {
                "code": -32602,
                "message": "invalid argument 0: json: cannot unmarshal invalid hex string into Go struct field CallArgs.from of type common.Address"
            }
        }
        ```
### <i>to</i>
- null
    ```json
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "{{Account1}}",
                "to": null,
                "data":null
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x"
    }
    ```
- improper formatting
    - length
        ```json
        // request
        {
            "jsonrpc": "2.0",
            "method": "eth_call",
            "params": [
                {
                    "from": "{{Account1}}",
                    "to": "0x91a2ac564fac17965ee2db773500fde39f0cfb",
                    "data":null
                },
                "latest"
            ],
            "id": 8
        }
        // response
        {
            "jsonrpc": "2.0",
            "id": 8,
            "error": {
                "code": -32602,
                "message": "invalid argument 0: hex string has length 38, want 40 for common.Address"
            }
        }
        ```
    - invalid characters
        ```json
        // request
        {
            "jsonrpc": "2.0",
            "method": "eth_call",
            "params": [
                {
                    "from": "{{Account1}}",
                    "to": "0x91a2#c564fac17965ee2db77359800fde39f0cfb",
                    "data":null
                },
                "latest"
            ],
            "id": 8
        }
        // response
        {
            "jsonrpc": "2.0",
            "id": 8,
            "error": {
                "code": -32602,
                "message": "invalid argument 0: json: cannot unmarshal invalid hex string into Go struct field CallArgs.to of type common.Address"
            }
        }
        ```
- Account doesn't exist
    ```json
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "{{Account1}}",
                "to": "0x91a2ac564fac17964ee2db77359800fde39f0cfb",
                "data":""
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x"
    }
    ```
### <i>gas</i>
- output of GAS opcode
    - if gas is not defined

        ```json
        // code returns output of GAS opcode
        // code 0x685a60005260206000f360005260096017f3
        // request
        {
            "jsonrpc": "2.0",
            "method": "eth_call",
            "params": [
                {
                    "from": "{{Account1}}",
                    "to": "{{contractAddress}}",
                    "data":null
                },
                "latest"
            ],
            "id": 8
        }
        // response
        {
            "jsonrpc": "2.0",
            "id": 8,
            "result": "0x00000000000000000000000000000000000000000000000000000000017d2636"
        }
        ```
    - gas is defined (above limit)
        ```json
        // code returns output of GAS opcode
        // code 0x685a60005260206000f360005260096017f3
        // request
        {
            "jsonrpc": "2.0",
            "method": "eth_call",
            "params": [
                {
                    "from": "{{Account1}}",
                    "to": "{{contractAddress}}",
                    "data":null,
                    "gas": "0x33333"
                },
                "latest"
            ],
            "id": 8
        }
        // response
        {
            "jsonrpc": "2.0",
            "id": 8,
            "result": "0x000000000000000000000000000000000000000000000000000000000002e129"
        }
        ```
    - gas is defined (below limit)
        ```json
        // code returns output of GAS opcode
        // code 0x685a60005260206000f360005260096017f3
        // request
        {
            "jsonrpc": "2.0",
            "method": "eth_call",
            "params": [
                {
                    "from": "{{Account1}}",
                    "to": "{{contractAddress}}",
                    "data":null,
                    "gas": "0x3333"
                },
                "latest"
            ],
            "id": 8
        }
        // response
        {
            "jsonrpc": "2.0",
            "id": 8,
            "error": {
                "code": -32000,
                "message": "err: intrinsic gas too low: have 13107, want 21000 (supplied gas 13107)"
            }
        }
        ```
    - gas is higher implicit but below actual
        ```json
        // code returns output of GAS opcode after storing and then loading from 
        // storage (very expensive)
        // 0x6e5a60005560005460005260206000f3600052600f6011f3
        // request
        {
            "jsonrpc": "2.0",
            "method": "eth_call",
            "params": [
                {
                    "from": "{{Account1}}",
                    "to": "{{contractAddress}}",
                    "data":null,
                    "gas": "0x5208" // exactly implicit
                },
                "latest"
            ],
            "id": 8
        }
        // response
        {
            "jsonrpc": "2.0",
            "id": 8,
            "error": {
                "code": -32000,
                "message": "out of gas"
            }
        }
        ```
    
- if gas is not hex encoded it will return

    ```jsx
    "error": {
        "code": -32602,
        "message": "invalid argument 0: json: cannot unmarshal hex number with leading zero digits into Go struct field CallArgs.gas of type hexutil.Uint64"
    }
    ```

- if gas is too low it will return

    ```jsx
    "error": {
        "code": -32000,
        "message": "err: intrinsic gas too low: have 1, want 21204 (supplied gas 1)"
    }
    ```

- if sufficient gas it returns

    ```jsx
    "result": "0x0000000000000000000000000000000000000000000000000000000000000002"
    ```

- with gas equal to anything greater than `"0xffffffffffffffff"` which is equivalent to saying that gas must be less than or equal to `2^64 - 1`

    ```jsx
    "error": {
        "code": -32602,
        "message": "invalid argument 0: json: cannot unmarshal hex number > 64 bits into Go struct field CallArgs.gas of type hexutil.Uint64"
    }
    ```
    
- effects on GASLIMIT
    - no gas set
        ```json
        // code returns output of GASLIMIT opcode
        // 0x684560005260206000f360005260096017f3
        // request
        {
            "jsonrpc": "2.0",
            "method": "eth_call",
            "params": [
                {
                    "from": "{{Account1}}",
                    "to": "{{contractAddress}}",
                    "data":null
                },
                "latest"
            ],
            "id": 8
        }
        // response
        {
            "jsonrpc": "2.0",
            "id": 8,
            "result": "0x0000000000000000000000000000000000000000000000000000000000997eb0" // 10059440
        }
        // the above response does not change unless a transaction is processed on-chain 
        // (e.g. deploying another contract)
        ```
    - gas sent (above implicit)
        ```json
        // code returns output of GASLIMIT opcode
        // 0x684560005260206000f360005260096017f3
        // request
        {
            "jsonrpc": "2.0",
            "method": "eth_call",
            "params": [
                {
                    "from": "{{Account1}}",
                    "to": "{{contractAddress}}",
                    "data":null,
                    "gas": "0x5500"
                },
                "latest"
            ],
            "id": 8
        }
        // response
        {
            "jsonrpc": "2.0",
            "id": 8,
            "result": "0x0000000000000000000000000000000000000000000000000000000000995852" // 10049618
        }
        ```

### <i>gasPrice</i>

- gasPrice as null
    ```json
    // returns the output of GASPRICE opcode
    // 0x683a60005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "{{Account1}}",
                "to": "{{contractAddress}}",
                "data":null,
                "gas": "0x5500"
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x0000000000000000000000000000000000000000000000000000000000000000"
    }
    ```
- gasPrice set
    - low
    ```json
    // returns the output of GASPRICE opcode
    // 0x683a60005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "{{Account1}}",
                "to": "{{contractAddress}}",
                "data":null,
                "gas": "0x5500",
                "gasPrice": "0x1"
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x0000000000000000000000000000000000000000000000000000000000000001"
    }
    ```
    - very high
    ```json
    // returns the output of GASPRICE opcode
    // 0x683a60005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "{{Account1}}",
                "to": "{{contractAddress}}",
                "data":null,
                "gas": "0x5500",
                "gasPrice": "0x1000000000000000000000000000000000000000000000000000000000000"
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x0001000000000000000000000000000000000000000000000000000000000000"
    }
    ```
    - too high
    ```json
    // returns the output of GASPRICE opcode
    // 0x683a60005260206000f360005260096017f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "{{Account1}}",
                "to": "{{contractAddress}}",
                "data":null,
                "gas": "0x5500",
                "gasPrice": "0x10000000000000000000000000000000000000000000000000000000000000"
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "error": {
            "code": -32000,
            "message": "err: insufficient funds for gas * price + value: address 0xC228a058717372E08F58a113dF1BDfF35bABD05a have 115792089237316195423570985008687907853269984665640564039357534007913129639927 want 615145474073242288187720857858654510470496793536215496459618415042038501212160 (supplied gas 21760)"
        }
    }
    ```

### <i>value</i>

- effect on contract BALANCE
    - undefined (no effect)
    - defined and greater than 0
    ```json
    // code returns BALANCE of contract ACCOUNT opcode
    // 0x69303160005260206000f3600052600a6016f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "{{Account1}}",
                "to": "{{contractAddress}}",
                "data":null,
                "value": "0x1"
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x0000000000000000000000000000000000000000000000000000000000000001"
    }
    ```
    - very large (below value is greater than from account value)
    ```json
    // code returns BALANCE of contract ACCOUNT opcode
    // 0x69303160005260206000f3600052600a6016f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "{{Account1}}",
                "to": "{{contractAddress}}",
                "data":null,
                "value": "0x1000000000000000000000000000000000000000000000000000000000000000"
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "result": "0x1000000000000000000000000000000000000000000000000000000000000000"
    }
    ```
    - too large
    ```json
    // code returns BALANCE of contract ACCOUNT opcode
    // 0x69303160005260206000f3600052600a6016f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": "{{Account1}}",
                "to": "{{contractAddress}}",
                "data":null,
                "value": "0x10000000000000000000000000000000000000000000000000000000000000000"
            },
            "latest"
        ],
        "id": 8
    }
    // response (if amount transfered is too large but account had enough)
    {
        "jsonrpc": "2.0",
        "id": 8,
        "error": {
            "code": -32602,
            "message": "invalid argument 0: json: cannot unmarshal hex number > 256 bits into Go struct field CallArgs.value of type *hexutil.Big"
        }
    }
    // reponse (if from account didn't have enough value)
    {
        "jsonrpc": "2.0",
        "id": 8,
        "error": {
            "code": -32000,
            "message": "err: insufficient funds for transfer: address 0x9fc48f3BD757d35a7c286af4735B7250b4A4929b (supplied gas 25000000)"
        }
    }
    ```
    - from account undefined (any amount greater than 0)
    ```json
    // code returns BALANCE of contract ACCOUNT opcode
    // 0x69303160005260206000f3600052600a6016f3
    // request
    {
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "from": null,
                "to": "{{contractAddress}}",
                "data":null,
                "value": "0x1000000000000000000000000000000000000000000000000000000000000000"
            },
            "latest"
        ],
        "id": 8
    }
    // response
    {
        "jsonrpc": "2.0",
        "id": 8,
        "error": {
            "code": -32000,
            "message": "err: insufficient funds for transfer: address 0x0000000000000000000000000000000000000000 (supplied gas 25000000)"
        }
    }
    ```

### `eth_call` from accounts with too little ETH or Zero?
`eth_call` succeeds despite not having enough balance

### What is TIMESTAMP?
seconds since 1/1/1970 (UNIX Epoch time) of the specified block

# Request format
```bash=
### Request
curl 
-H "Content-Type: application/json" 
http://localhost:8545/ 
-X POST 
--data 
'{
  "method": "eth_call",
  "params": [
    {
      "from": "0x85f7c2480b66ca340e9f2a534dbf8b660137889f",
      "to": "0x52e596894ea366943da485eaca43f1813aac551d",
      "data": "0x6ffa1caa0000000000000000000000000000000000000000000000000000000000000005"
    },
    "latest"
  ],
  "id": 1,
  "jsonrpc": "2.0"
}' 
### Response
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x000000000000000000000000000000000000000000000000000000000000000a"
}
```

# Call data types

## Unsigned Integers
uses [08bb1114](#08bb1114)

For a given call to this contract we need to first format the data request; to establish a baseline of how things work right now, here're the results from the built-in methods
```javascript=
const data = await contract.methods.addAssembly(1,2).encodeABI() // the data to be sent to the contract
// '0x08bb111400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002'

const res = await ethers.call({to:"<Contract Address>", data})
// '0x0000000000000000000000000000000000000000000000000000000000000003'

// Can also make call with web3.js
const res = await contract.methods.addAssembly(1,2).call()
// '3'
```
But it's important that we understand what exactly goes into the request / is required for the `Call Data` type.
```javascript=
// 1) calculate the hash of the method call
const hash = web3Utils.sha3("addAssembly(uint256,uint256)") // uint256 comes from solidity types; but can be within uint8,uint16,...uint256
// hash -> '0x08bb1114a1f38d5f27cbb87d6d30555f5e86ce4cb3202bb7cef8b919a4a52301'

// 2) extract the first 4 bytes of that hash and append it to 0x...
const dataHeader = `0x${hash.slice(2,10)}`
// dataHeader -> '0x08bb1114'

// 3) hex encode each parameter and give 32 bytes of padding
const hexEncoded1 = web3Utils.toHex(1).slice(2)
// hexEncoded1 -> '1'
const hexEncoded2 = web3Utils.toHex(2).slice(2)
// hexEncoded2 -> '2'
const input1 = "0".repeat(64).concat(hexEncoded1).slice(-64)
// bytes1 -> '0000000000000000000000000000000000000000000000000000000000000001'
const input2 = "0".repeat(64).concat(hexEncoded2).slice(-64)
// bytes2 -> '0000000000000000000000000000000000000000000000000000000000000002'

// 4) concat dataHeader and inputs in order to receive data
const data = dataHeader.concat(input1, input2)
// data -> '0x08bb111400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002'
```

## String
uses [d8e928c](#d8e928c)
The call data is encoded with the following format:
```javascript=
const calldata1 = contract.methods.strAssemblyCalldata("a").encodeABI()
// calldata1 -> '0xd8e928c7000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000016100000000000000000000000000000000000000000000000000000000000000'
const memory1 = contract.methods.strAssemblyMemory("a").encodeABI()
// memory1 -> '0xf62b2952000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000016100000000000000000000000000000000000000000000000000000000000000'
const calldata2 = contract.methods.strAssemblyCalldata("aa").encodeABI()
// calldata2 -> '0xd8e928c7000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000026161000000000000000000000000000000000000000000000000000000000000'

// string call data can be broken into 4 parts
`0x${web3Utils.sha3("strAssemblyMemory(string)").slice(2,10)}`
// header -> 0xf62b2952 
?
// {unknown} -> 000000000000000000000000000000000000000000000000000000000000002
"0".repeat(64).concat(web3Utils.toHex("aa".length).slice(2)).slice(-64)
// string length -> 00000000000000000000000000000000000000000000000000000000000000002
web3Utils.toHex("aa").slice(2).concat("0".repeat(64)).slice(0,64)
// hex encoded string -> 6161000000000000000000000000000000000000000000000000000000000000
```
if the string is too long it will extend in increments of 64 bytes and each character is 2 bytes
```javascript=
contract.methods.strAssemblyCalldata("aadddddddddddddddddddddddddddddd").encodeABI()
// '0xd8e928c7000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000206161646464646464646464646464646464646464646464646464646464646464'
contract.methods.strAssemblyCalldata("aaddddddddddddddddddddddddddddddd").encodeABI()
// '0xd8e928c70000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002161616464646464646464646464646464646464646464646464646464646464646400000000000000000000000000000000000000000000000000000000000000'
// diff -> 6400000000000000000000000000000000000000000000000000000000000000

// each character is 2 bytes
contract.methods.strAssemblyMemory("a".repeat(32)).encodeABI()
// '0xf62b2952000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000206161616161616161616161616161616161616161616161616161616161616161'
contract.methods.strAssemblyMemory("a".repeat(64)).encodeABI()
// '0xf62b29520000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161'

```

## Boolean
uses [89a47ad8](#89a47ad8)

The request encoding follows expected types
```javascript=
await contract.methods.boolean(true).encodeABI()
// '0x89a47ad80000000000000000000000000000000000000000000000000000000000000001'

// breakdown...
`0x${web3Utils.sha3("boolean(bool)").slice(2,10)}`
// '0x89a47ad8'
"0".repeat(64).concat(web3Utils.toHex(true).slice(2)).slice(-64)
// '0000000000000000000000000000000000000000000000000000000000000001'
```

This is similarly followed in the case of 2 inputs / outputs
```javascript=
await contract.methods.boolean2(true,false).encodeABI()
'0xc89a4b3400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000'

// breakdown...
`0x${web3Utils.sha3("boolean2(bool,bool)").slice(2,10)}`
// '0xc89a4b34'
"0".repeat(64).concat(web3Utils.toHex(true).slice(2)).slice(-64)
// '0000000000000000000000000000000000000000000000000000000000000001'
"0".repeat(64).concat(web3Utils.toHex(false).slice(2)).slice(-64)
// '0000000000000000000000000000000000000000000000000000000000000000'
```

## Signed Integers
uses [291c4b98](#291c4b98)
```javascript=
await contract.methods.signedInt(-1).encodeABI()
// '0x291c4b98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'

`0x${web3Utils.sha3("signedInt(int256)").slice(2,10)}`
// '0x291c4b98'

// "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
// above is just the inverted hex of its positive counterpart

await contract.methods.addSignedInt(-2, -3).encodeABI()
// '0xc37ccbd3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd'
`0x${web3Utils.sha3("addSignedInt(int256,int256)").slice(2,10)}`
// '0xc37ccbd3'
```

# Return data types

## Unsigned Integers
Consider a simple contract
```solidity    
library Assembly {
    function addAssembly(uint x, uint y) public pure returns (uint) {
     assembly {
         // Add some code here
         let result := add(x, y)
         mstore(0x0, result)
         return(0x0, 32)
     }
 }
}
```

Then the response from a simple request will be ABI encoded
```javascript=
const data = contract.methods.addAssembly(1,2).encodeABI();
// data -> '0x08bb111400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002'
const res = await ethers.call({to: "<Contract Address", data});
// res -> '0x0000000000000000000000000000000000000000000000000000000000000003'
const hexEncoded3 = web3Utils.toHex(3).slice(2);
// hexEncoded3 -> '3'
const abiEncoded3 = "0x" + "0".repeat(64).concat(hexEncoded3).slice(-64);
// abiEncoded3 -> '0x0000000000000000000000000000000000000000000000000000000000000003'
// i.e. returns(uint256)
```

# Revert
Uses [8d558b8](#8d558b8)
Note that `signedInt(1) -> '0x291c4b980000000000000000000000000000000000000000000000000000000000000001'
`

when called, the method reverts with the following RPC output:
```bash
curl -H "Content-Type: application/json" http://localhost:8545/ -X POST --data '{"method":"eth_call","params":[{"from":"0x85f7c2480b66ca340e9f2a534dbf8b660137889f","to":"0x5d3320aaa0adf4a7665a10a4404a87b0c8805b01","data":"0x291c4b980000000000000000000000000000000000000000000000000000000000000001"},"latest"],"id":1,"jsonrpc":"2.0"}'
    > {"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"execution reverted"}}
```

# Gas
### Low Gas Limit
Uses [291c4b98](#291c4b98)
```javascript=
await contract.methods.addSignedInt(1,1).call({
    from: "<Any Non-Zero Balance Account>", 
    gas: "200"
})
```
```bash=

```

### Low Account Balance
Uses [291c4b98](#291c4b98)
For accounts with a low or zero balance the call allows for the synthetic transactions to occur
```javascript=
await contract.methods.addSignedInt(1,1).call({from: "0x72c90e03256099e1DC27DE3711F80bbdd5bE1925"})
// '2'
await contract.methods.addSignedInt(1,1).call({from: "0x72c90e03256099e1DC27DE3711F80bbdd5bE1925", gas: "100000"})
// '2'
await contract.methods.addSignedInt(1,1).call({from: "0x72c90e03256099e1DC27DE3711F80bbdd5bE1925", gasPrice: "200000000000000", gas: "100000"})
// '2'
```
This is also true when interfacing directly with geth RPC
```bash=
curl -H "Content-Type: application/json" http://localhost:8545/ -X POST --data '{"method":"eth_call","params":[{"from":"0x09b1b5f60ae2648bb1b329354361f6bc243c3b7e","to":"0x52e596894ea366943da485eaca43f1813aac551d","data":"0x6ffa1caa0000000000000000000000000000000000000000000000000000000000000005"},"latest"],"id":1,"jsonrpc":"2.0"}'
    > {"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000000a"}
```
In contrast when actually executing the action it will error if the account doesn't have enough balance
```javascript=
await contract.methods.addSignedInt(1,1).send({from: "0x72c90e03256099e1DC27DE3711F80bbdd5bE1925", gasPrice: "200000000000000", gas: "100000"}) // errors
```

# No Response Data
```bash
{"jsonrpc":"2.0","id":1,"result":"0x"}
```
It appears that the above occurs for, if any reason, a contract returns no data; so it allows for things to fail silently

Consider for instance the following bytecode `0x41` which is just the CODEBASE opcode


Appendix
---

# Errors

```bash=
# ganache
curl localhost:9545 -X POST {"method":"eth_call","params":[{"from":"0xe965c8ad2607884034e941e7f3f150c2ee9c9720","data":"0xc37ccbd300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"}],"id":46,"jsonrpc":"2.0"}
    > zsh: no matches found: params:[from:0xe965c8ad2607884034e941e7f3f150c2ee9c9720]
```

```bash=
# the 'from' address has double quotes typo
# geth
curl -H "Content-Type: application/json" http://localhost:8545/ -X POST --data '{"method":"eth_call","params":[{"from":""0x85f7c2480b66ca340e9f2a534dbf8b660137889f"","to":"0x7cde2049b4445a73b1573e344f78c0202d63ebe7b51e64497e1ab3cfdbc32862","data":"0xc37ccbd300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"},"latest"],"id":1,"jsonrpc":"2.0"}'
    > {"jsonrpc":"2.0","id":null,"error":{"code":-32700,"message":"parse error"}}
```

```bash=
# geth
curl -H "Content-Type: application/json" http://localhost:8545/ -X POST --data '{"method":"eth_call","params":[{"from":"accounts[0]","to":"0x7cde2049b4445a73b1573e344f78c0202d63ebe7b51e64497e1ab3cfdbc32862","data":"0xc37ccbd300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"},"latest"],"id":46,"jsonrpc":"2.0"}'
    > {"jsonrpc":"2.0","id":46,"error":{"code":-32602,"message":"invalid argument 0: json: cannot unmarshal hex string without 0x prefix into Go struct field CallArgs.from of type common.Address"}}
```

the return size must be 32, otherwise there is an overflow error (wrt to defining assembly returns in solidity)
```bash
Error: data out-of-bounds (length=16, offset=32, code=BUFFER_OVERRUN, version=abi/5.0.7)
    at Logger.makeError (/Users/alitamoore/ethereum/node_modules/@ethersproject/logger/lib/index.js:180:21)
    at Logger.throwError (/Users/alitamoore/ethereum/node_modules/@ethersproject/logger/lib/index.js:189:20)
    at Reader._peekBytes (/Users/alitamoore/ethereum/node_modules/web3-eth-abi/node_modules/@ethersproject/abi/lib/coders/abstract-coder.js:149:24)
    at Reader.readBytes (/Users/alitamoore/ethereum/node_modules/web3-eth-abi/node_modules/@ethersproject/abi/lib/coders/abstract-coder.js:161:26)
    at Reader.readValue (/Users/alitamoore/ethereum/node_modules/web3-eth-abi/node_modules/@ethersproject/abi/lib/coders/abstract-coder.js:167:48)
    at NumberCoder.decode (/Users/alitamoore/ethereum/node_modules/web3-eth-abi/node_modules/@ethersproject/abi/lib/coders/number.js:49:28) {
  reason: 'data out-of-bounds',
  code: 'BUFFER_OVERRUN',
  length: 16,
  offset: 32
}
```

#### Block Enum
The block enum is the second variable in the call and can only be "latest", "earliest", or "pending"; the following errors occur if this is violated

- if you submit a request without a second parameter defined it'll throw an error

```bash
{
    "jsonrpc":"2.0",
    "method":"eth_call",
    "params": [{
        "from": "{{Account1}}",
        "to": "0xee408b2d602d94e06a9d0241cc9dc0092eed1d53"
    }],
    "id": 1
}

>>>>
{
    "jsonrpc": "2.0",
    "id": 1,
    "error": {
        "code": -32602,
        "message": "missing value for required argument 1"
    }
}
```

- if you submit with something that is empty

```bash
{
    "jsonrpc":"2.0",
    "method":"eth_call",
    "params": [{
        "from": "{{Account1}}",
        "to": "0xee408b2d602d94e06a9d0241cc9dc0092eed1d53"
    }, ""],
    "id": 1
}

>>>>
{
    "jsonrpc": "2.0",
    "id": 1,
    "error": {
        "code": -32602,
        "message": "invalid argument 1: empty hex string"
    }
}
```

- if you submit with something that's not an accepted value

```bash
{
    "jsonrpc":"2.0",
    "method":"eth_call",
    "params": [{
        "from": "{{Account1}}",
        "to": "0xee408b2d602d94e06a9d0241cc9dc0092eed1d53"
    }, "fake"],
    "id": 1
}

>>>>>
{
    "jsonrpc": "2.0",
    "id": 1,
    "error": {
        "code": -32602,
        "message": "invalid argument 1: hex string without 0x prefix"
    }
}
```

# Contracts

##### 291c4b98
```solidity=
library Assembly {
    function signedInt(int _int) public pure returns (int) {
        return _int;
    }
    function addSignedInt(int _int1, int _int2) public pure returns (int) {
        return _int1 + _int2;
    }
}
```
```
```

##### d8e928c
```solidity=
library Assembly {
    function strAssemblyCalldata(string calldata _str) public pure returns (string calldata) {
        return _str;
    }

    function strAssemblyMemory(string memory _str) public pure returns (string memory) {
        return _str;
    }
}
```
```
```

##### 08bb1114
```solidity 
library Assembly {
    function addAssembly(uint x, uint y) public pure returns (uint) {
     assembly {
         // Add some code here
         let result := add(x, y)
         mstore(0x0, result)
         return(0x0, 32)
     }
 }
}
```
```
```

##### 89a47ad8
```solidity=
library Assembly {
    function boolean(bool _bool) public pure returns (bool) {
        return _bool;
    }
    function boolean2(bool _bool1, bool _bool2) public pure returns (bool, bool) {
    return (_bool1, _bool2);
    }
}
```
```
```

##### 8d558b8
```solidity=
library Assembly {
    function signedInt(int _int) public pure returns (int) {
        int apple = _int;
        revert();
        // return _int;
    }
    function addSignedInt(int _int1, int _int2) public pure returns (int) {
        return _int1 + _int2;
    }
}
```
```
0x6102a1610053600b82828239805160001a607314610046577f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061005d576000357c010000000000000000000000000000000000000000000000000000000090048063291c4b9814610062578063c37ccbd314610092575b600080fd5b61007c600480360381019061007791906100f8565b6100c2565b604051610089919061016c565b60405180910390f35b6100ac60048036038101906100a79190610121565b6100cd565b6040516100b9919061016c565b60405180910390f35b600080829050600080fd5b600081836100db9190610187565b905092915050565b6000813590506100f281610254565b92915050565b60006020828403121561010a57600080fd5b6000610118848285016100e3565b91505092915050565b6000806040838503121561013457600080fd5b6000610142858286016100e3565b9250506020610153858286016100e3565b9150509250929050565b6101668161021b565b82525050565b6000602082019050610181600083018461015d565b92915050565b60006101928261021b565b915061019d8361021b565b9250817f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038313600083121516156101d8576101d7610225565b5b817f80000000000000000000000000000000000000000000000000000000000000000383126000831216156102105761020f610225565b5b828201905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61025d8161021b565b811461026857600080fd5b5056fea2646970667358221220cef7a31d885883915a67926f53e4c6595dad92a6124c33b00a1fc55df8ff3a5a64736f6c63430008030033
```

#### Custom1

This was primarily used to investigate the behavior of specific edge-case opcodes
bytecode:
```
4160005260206000a04360005260206000a03360005260206000a04460005260206000a04260005260206000a0
```

Outputs (in logs):
```bash=
4160005260206000a0  # logs COINBASE output
4360005260206000a0  # logs NUMBER output
3360005260206000a0  # logs CALLER output
4460005260206000a0	# logs DIFFICULTY output
4260005260206000a0	# logs TIMESTAMP output

0x00000000000000000000000085f7c2480b66ca340e9f2a534dbf8b660137889f  # COINBASE
0x000000000000000000000000000000000000000000000000000000000000006c	# NUMBER -> 108
0x00000000000000000000000085f7c2480b66ca340e9f2a534dbf8b660137889f	# CALLER
0x0000000000000000000000000000000000000000000000000000000000000002	# DIFFICULTY
0x00000000000000000000000000000000000000000000000000000000607d03db	# TIMESTAMP -> 1618805723s since 1970

# once more a little bit later
0x00000000000000000000000085f7c2480b66ca340e9f2a534dbf8b660137889f	# COINBASE
0x000000000000000000000000000000000000000000000000000000000000006f	# NUMBER -> 111
0x00000000000000000000000085f7c2480b66ca340e9f2a534dbf8b660137889f	# CALLER
0x0000000000000000000000000000000000000000000000000000000000000002	# DIFFICULTY
0x00000000000000000000000000000000000000000000000000000000607d0682	# TIMESTAMP -> 1618806402s since 1970 Unix epoch
```