DeFiCh / ain

DeFi Blockchain - enabling decentralized finance on Bitcoin
https://defichain.com
MIT License
408 stars 122 forks source link

EVM: standard (?) field `input` not allowed in eth transaction #2048

Closed kuegi closed 1 year ago

kuegi commented 1 year ago

even a simple eth_call fails with unknown field input, expected one of from, to, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gas, value, data, nonce, accessList, type if the input field is provided. But this seems to be standard in eth. The generated tx by web3.js contains data and input with the same content.

shohamc1 commented 1 year ago

Hey, which RPC are you referring to here?

I just checked the Ethereum docs (here and here), and none of them have an input field for eth_call.

kuegi commented 1 year ago

Problem happens both with eth_call and eth_sendTransaction. Interessting that its not in the ETH docs. Then the question is why web3.js adds it to the call (with same value as data ) https://github.com/web3/web3.js/blob/f8a2533c2b09ce0a62f8414f2f6eed83ab78ca1f/packages/web3-types/src/eth_types.ts#L66

I will try to investigate.

shohamc1 commented 1 year ago

May I know what you are trying to achieve with your script, and maybe share your code if you can.

eth_sendTransaction does not have an input field as well.

kuegi commented 1 year ago

I wanted to write a bot to interact with a SC deployed to DMC. SC is deployed and interaction via Remix works smoothly. but via web3 I get the mentioned error. will try to debug why web3 is adding the input.

can't add .ts files. the code is

import { Contract, Web3 } from 'web3'
const contractABI = [ /* pretty long, so removed here*/ ] as const
const dmcAddress= '0x67488912788Bf6C634909f4411047aE0136C801A'

async function interact(): Promise<void> {
  const w3: Web3 = new Web3('https://testnet-dmc.mydefichain.com:20551')
  const contract = new Contract(contractABI,dmcAddress , w3)

  const currentBlock = await w3.eth.getBlockNumber()

  const lastInputBlock: bigint = await contract.methods.lastInputBlock().call()
  const waitTime: bigint = await contract.methods.WAIT_TIME_BLOCKS().call()
  const lastSender = await contract.methods.lastInput().call()
  console.log('got data: ' + currentBlock + ' ' + lastSender + ' ' + lastInputBlock + ' ' + waitTime)
}

interact()
shohamc1 commented 1 year ago

This test is using web3.py and functions without error.

On web3.js I believe the code for declaring a new contract should look like

const web3 = new Web3(process.env.PROVIDER);
const contract = new web3.eth.Contract(ABI, contractAddress);
kuegi commented 1 year ago

Its explicitly being set by web3.js here https://github.com/web3/web3.js/blob/f8a2533c2b09ce0a62f8414f2f6eed83ab78ca1f/packages/web3-eth/src/utils/format_transaction.ts#L43-L56

they assert that data and input is same, and make sure that both are set.

(and same result if I create it with your code)

kuegi commented 1 year ago

And here, input is part of the rpc-api https://ethereum.github.io/execution-apis/api-documentation/ weirdly enough, there it doesn't include data image

maybe this is an old definition and it was input in the beginning and got changed to data ? But since this spec is linked from the docu that you provided up there, it seems that ethereum itself is not consistent if it should be data or input...

Meiswinkel1991 commented 1 year ago

I often use the docs from alchemy for such cases. In the following link you will find everything about eth_call.

https://docs.alchemy.com/reference/sdk-call

I personally have never heard of "input". Until now I have always worked with "data".

shohamc1 commented 1 year ago

@kuegi the linked PR should allow you to use eth_call from web3.js.

Tested with the following code

import Web3 from "web3"

const web3 = new Web3(process.env.PROVIDER);
const contract = new web3.eth.Contract(ABI, contractAddress);

console.log(await contract.methods.retrieve().call())
kuegi commented 1 year ago

@shohamc1 can confirm that eth_call works now, but interacting via transaction still fails on existing input