EthWorks / ethereum.rb

Ethereum library for the Ruby language
MIT License
731 stars 229 forks source link

error: max fee per gas less than block base fee #177

Closed sg552 closed 2 years ago

sg552 commented 2 years ago

Hi, how to call the contract https://testnet.snowtrace.io/address/0x140a09c157d956c6b90ad8c4b120f0bdfef538e7 's method: retrieve ? is there a complete exmaple to call the contract's method?

( the contract's souce code is the sample from remix, which code is shown as below: )

pragma solidity >=0.7.0 <0.9.0;
contract Storage {
    uint256 number;
    function store(uint256 num) public {
        number = num;
    }
   function retrieve() public view returns (uint256){
        return number;
    }
}

I have check the README and issue list, however not found any related anser. many thanks!

Steps to reproduce

  1. install this gem
  2. choose the fuji test net work,
  3. open irb and :
    
    require 'ethereum.rb'

client = Ethereum::HttpClient.new('https://api.avax-test.network/ext/bc/C/rpc') => #<Ethereum::HttpClient:0x000055e407783430 @id=0, @log=false, @batch=nil, @formatter=#, @gas_price=22000000000, @gas_limit=4000000, @host="api.avax-test.network", @port=443, @proxy=nil, @ssl=true, @uri=#<URI::HTTPS https://api.avax-test.network/ext/bc/C/rpc>>

client.eth_gas_price => {"jsonrpc"=>"2.0", "id"=>1, "result"=>"0x5d21dba00"}

abi = %Q{[ { "inputs": [], "name": "retrieve", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "num", "type": "uint256" } ], "name": "store", "outputs": [], "stateMutability": "nonpayable", "type": "function" } ]} contract = Ethereum::Contract.create(client: client, name: "Sample", address: "0xcd25ae27b778d887956c1e0AFFd2C658d37239BF", abi: abi) => #


till now, everything looks good, but when I call the contract method:  ( retrieve ) 

contract.call.retrieve


### Expected behavior
should get 341 or 351 or any number

### Actual behavior

the error shows up: 

irb(main):042:0> contract.call.retrieve Traceback (most recent call last): 9: from /home/siwei/.rbenv/versions/2.6.1/bin/irb:23:in <main>' 8: from /home/siwei/.rbenv/versions/2.6.1/bin/irb:23:inload' 7: from /home/siwei/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in <top (required)>' 6: from (irb):42 5: from /home/siwei/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/ethereum.rb-2.5/lib/ethereum/contract.rb:322:inblock (2 levels) in create_function_proxies' 4: from /home/siwei/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/ethereum.rb-2.5/lib/ethereum/contract.rb:179:in call' 3: from /home/siwei/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/ethereum.rb-2.5/lib/ethereum/contract.rb:173:incall_raw' 2: from /home/siwei/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/ethereum.rb-2.5/lib/ethereum/client.rb:137:in block (2 levels) in <class:Client>' 1: from /home/siwei/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/ethereum.rb-2.5/lib/ethereum/client.rb:129:insend_command' IOError (err: max fee per gas less than block base fee: address 0x0000000000000000000000000000000000000000, maxFeePerGas: 22000000000 baseFee: 25000000000 (supplied gas 4000000))



### System configuration
**Ruby version**:   2.6.1p33
**Solc version**:   0.8.7
**Parity version**:  FUJI test network 
**OS**:  ubuntu 18

### Failure Logs
no log content in /tmp/ethereum_ruby_http.log
sg552 commented 2 years ago

OK, problem found. I need to assign the default address before call contract methods, also set the gas_price to more than 25 giwei, and also make sure the default account's balance is enough .

require 'ethereum.rb'

client = Ethereum::HttpClient.new('https://api.avax-test.network/ext/bc/C/rpc')

client.default_account = '0xa97D4D83Bb3EFE403E1e02B079A21B89947cE7A6'
client.gas_price = (25 * 1e9).to_i

abi = %Q{[ { "inputs": [], "name": "retrieve", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "vi
contract = Ethereum::Contract.create(
  client: client,
  name: "Sample",
  address: "0x3d27fbCBACBb0a0134Bf2CEF88ee75A27A28d1d3",
  abi: abi)

contract.call.retrieve

As far as I know, for querying a contract's READ ONLY method, it's not necessary to

  1. perform a TX which cost gas fee
  2. need a address which must have > 0 balance.

e.g. This raw curl query also works well (notice the last 2 charactors) :

curl https://api.avax-test.network/ext/bc/C/rpc -H 'content-type:application/json;' -X POST --data '{"jsonrpc":"2.0", "method":"eth_call", "params":[{"from": "0xa97D4D83Bb3EFE403E1e02B079A21B89947cE7C8", "to": "0x3d27fbCBACBb0a0134Bf2CEF88ee75A27A28d1d3", "data": "0x2e64cec10000000000000000000000000000000000000000000000000000000000000000"}, "latest"], "id":1}'


However, the acual POST body sent by `ethereum.rb` is: 

, payload: "{\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[{\"to\":\"0x3d27fbCBACBb0a0134Bf2CEF88ee75A27A28d1d3\",\"from\":\"0xa97D4D83Bb3EFE403E1e02B079A21B89947cE7A6\",\"data\":\"0x2e64cec10000000000000000000000000000000000000000000000000000000000000000\",\"gas\":\"0x3d0900\",\"gasPrice\":\"0x5d21dba00\"},\"latest\"],\"id\":1}", header: {"Content-Type"=>"application/json"}, uri: #<URI::HTTPS https://api.avax-test.network/ext/bc/C/rpc>



It contains `gas`, `gasPrice` for this READONLY method, so ethereum network will ask for the `from` address having enough balance. 

so, do we need a PR for this?