q9f / eth.rb

a straightforward library to build, sign, and broadcast ethereum transactions anywhere you can run ruby.
https://q9f.github.io/eth.rb
Apache License 2.0
204 stars 88 forks source link

eth/contract hello_world.sol : Unsupported method: eth_coinbase. Alchemy does not support mining eth... #115

Closed unixneo closed 2 years ago

unixneo commented 2 years ago

Hi Again, and thanks for this great gem and your fast support.

Made the change you suggested in (now closed) issue #113, but this leads to another error:

client.rb:453:in `send_command': etherbase must be explicitly specified (IOError)

Here is the module as tested:

module EthGem 
    require "eth"
    require "colorize"

    require_relative "#{Rails.root}/lib/assets/config.rb"

    class Core
       include Endpoint
       include Wallet
       def initialize

       end

       def self.contract(file)
        return nil if file.nil?
        chain = Eth::Client.create Endpoint::Provider.chainstack_ropsten
        puts "METAMASK_ETH_ADDRESS: #{Wallet::Address.metamask_eth}"
        deposit_contract = Eth::Address.new Wallet::Address.metamask_eth
        balance = (chain.get_balance deposit_contract).to_f
        puts "Balance is #{balance.round(8)}"

        contract_file = "#{Rails.root}/lib/assets/contracts/#{file}.sol"
        puts "FILE: #{contract_file}"
        contract = Eth::Contract.from_file(file: contract_file)   # changed based on issue #113

        #pp contract
        #pp chain
        chain.deploy_and_wait(contract)
       end

    end
end

Here is the calling (rails console) process:

MacStudio:eth tim$ rails c
Loading development environment (Rails 7.0.3)
irb(main):001:0> require "#{Rails.root}/lib/assets/eth.rb"
=> true
irb(main):002:0> EthGem::Core.contract("hello_world")
METAMASK_ETH_ADDRESS: 0xE179C056024150d56A4e94af9C5A36BCC0B4e502
Balance is 9.39999369999997e+19 
FILE: /Users/tim/rails/eth/lib/assets/contracts/hello_world.sol
/Users/tim/rails/eth/vendor/bundle/ruby/3.0.0/gems/eth-0.5.5/lib/eth/client.rb:453:in `send_command': etherbase must be explicitly specified (IOError)
irb(main):003:0> 

Looking at the line (453) where the error happens:

443     # Prepares parameters and sends the command to the client.
444     def send_command(command, args)
445       args << "latest" if ["eth_getBalance", "eth_call"].include? command
446       payload = {
447         jsonrpc: "2.0",
448         method: command,
449         params: marshal(args),
450         id: next_id,
451       }
452       output = JSON.parse(send(payload.to_json))
453       raise IOError, output["error"]["message"] unless output["error"].nil?
454       return output
455     end

hello_world.sol

MacStudio:eth tim$ cat /Users/tim/rails/eth/lib/assets/contracts/hello_world.sol
 // SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;           
contract HelloWorld {             
   function helloWorld() external pure returns (string memory) {
   return "Hello, World!";        
   }                              
}                                 

FWIW, get this same error with my earlier (issue #113) greeter.sol file as well:

irb(main):003:0> require "#{Rails.root}/lib/assets/eth.rb"
=> false
irb(main):004:0> EthGem::Core.contract("greeter")
METAMASK_ETH_ADDRESS: 0xE179C056024150d56A4e94af9C5A36BCC0B4e502
Balance is 9.39999369999997e+19                                                             
FILE: /Users/tim/rails/eth/lib/assets/contracts/greeter.sol                                 
/Users/tim/rails/eth/vendor/bundle/ruby/3.0.0/gems/eth-0.5.5/lib/eth/client.rb:183:in `deploy': Missing contract constructor params! (ArgumentError)
irb(main):005:0> 

I read the updated wiki (thanks for updating the docs, we all know that docs are our least favorite thing to do) and reviewed the steps again. Am I following your docs, to the letter, for endpoints such as CHAINSTACK or ALCHEMY, etc.? I think so, but maybe I'm missing something? Have reviewed the docs many times, but it seems I am following....

Where did I go wrong this time?

Thank you.

unixneo commented 2 years ago

DEBUGGING UPDATE

Changed the endpoint to alchemy using the goerli testnet since ropsten is deprecating

hain = Eth::Client.create Endpoint::Provider.alchemy_goerli

This this I get an more interesting error:

Unsupported method: eth_coinbase. Alchemy does not support mining eth...

MacStudio:client tim$ rails c
Loading development environment (Rails 7.0.3)
irb(main):001:0> require "#{Rails.root}/lib/assets/eth.rb"
=> true
irb(main):002:0> EthGem::Core.contract("hello_world")
METAMASK_ETH_ADDRESS: 0xE179C056024150d56A4e94af9C5A36BCC0B4e502
HELLO DEF SEND                  
"{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0x853a0d2313c0000\"}"
Balance is 6.0e+17              
FILE: /Users/tim/rails/eth/lib/assets/contracts/hello_world.sol
HELLO DEF SEND                  
"{\"jsonrpc\":\"2.0\",\"result\":\"0x5\",\"id\":2}"
HELLO DEF SEND
"{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32600,\"message\":\"Unsupported method: eth_coinbase. Alchemy does not support mining eth. See available methods at https://docs.alchemy.com/alchemy/documentation/apis\"},\"id\":3}"
/Users/tim/rails/eth/vendor/bundle/ruby/3.0.0/gems/eth-0.5.5/lib/eth/client.rb:453:in `send_command': Unsupported method: eth_coinbase. Alchemy does not support mining eth. See available methods at https://docs.alchemy.com/alchemy/documentation/apis (IOError)
irb(main):003:0> 

So, seems I need to disable or nil chain.eth_coinbase ?

Any ideas how best to do this?

unixneo commented 2 years ago

DEBUGGING. client.rb

  def default_account
      @default_account ||= Address.new eth_coinbase["result"]
    end

It appears this is part of the problem?

For test networks which do not mine, this call returns an error, correct?

What is the best way around this issue with test chains which do not mine?

Thanks

q9f commented 2 years ago

Thank you, this is actually a bug. I partially fixed it in #85 but have not seen this. :+1:

unixneo commented 2 years ago

Testing all these various blockchain provider endpoints is useful it seems.

See summary of first test results here:

https://community.unix.com/t/testing-eth-contract-deployment-using-the-eth-ruby-gem-against-provider-endpoints/387004

q9f commented 2 years ago

Do you want to submit a PR?

unixneo commented 2 years ago

Do you want to submit a PR?

I don't yet have the skills to debug the ETH protocol; but if I did, or if I ever do, I would be happy to help out anyway I can.

Not even sure where to start, to be honest. I've been focused on testing provider endpoints and not the underlying protocol; where would I start to debug / fix this issue?

My guess is it would be easier to just use the sender signing key?

    # Deploys a contract. Uses `eth_coinbase` or external signer
    # if no sender key is provided.

Is this documented on how to deploy a contract using a sender key? I'm happy to try that, if you think that is a good way forward @q9f

q9f commented 2 years ago

Oh, sure:

my_key = Eth::Key.new priv: "30137644b564785d01420f8043f043d74dcca64008e57c59f8ce713a0005a54b"
# ...
chain.deploy_and_wait(contract, sender_key: my_key)
unixneo commented 2 years ago

This issue is resolved. Thanks for your help @q9f