How to connect Ruby with a personal/test blockchain like Ganache?

145 views Asked by At

I want to deploy a smart contract on Ganache blockchain. As a backend, I want to make use of Ruby. I tried ethereum.rb, and I am able to read the basic account information on Ganache using the following code:

require 'ethereum.rb'

client = Ethereum::HttpClient.new('HTTP://127.0.0.1:7545')
blockNumber = client.eth_block_number
balance = client.get_balance("0x9040DD204B561700e2D08bDCBE5215c976F059d4")
puts blockNumber["result"].to_i(16)
puts "Balance: ", balance

Later, I found that ethereum.rb only supports OpenEthereum, and thus maybe for that reason I wasn't able to create or read smart contracts using it.

What options do I have to connect Ruby with Ganache?

1

There are 1 answers

0
q9f On

You can use the eth gem.

require "eth"

client = Eth::Client.create "http://127.0.0.1:7545"
# => #<Eth::Client::Http:0x000055cd9e1c7430 @gas_limit=21000, @host="127.0.0.1", @id=0, @max_fee_per_gas=0.2e11, @max_priority_fee_per_gas=0, @port=7545, @ssl=false, @uri=#<URI::HTTP http://127.0.0.1:7545>>

block_number = client.eth_block_number["result"].to_i(16)
# => 6912685

address = Eth::Address.new "0xCaA29806044A08E533963b2e573C1230A2cd9a2d"
# => #<Eth::Address:0x000055cd9d6e0738 @address="0xCaA29806044A08E533963b2e573C1230A2cd9a2d">

balance = client.eth_get_balance(address)["result"].to_i(16) / Eth::Unit::ETHER
# => 3.889366000364757678

It also has full smart contract support:

ens_registry_abi = '[{"inputs":[{"internalType":"contract ENS","name":"_old","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"label","type":"bytes32"},{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"resolver","type":"address"}],"name":"NewResolver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"NewTTL","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"old","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"recordExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setRecord","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"resolver","type":"address"}],"name":"setResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"}],"name":"setSubnodeOwner","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setSubnodeRecord","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setTTL","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"ttl","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"}]'

ens_registry_address = Eth::Address.new "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
# => #<Eth::Address:0x000055cd9e6467b8 @address="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e">

ens_registry_name = "ENSRegistryWithFallback"
# => "ENSRegistryWithFallback"

ens_registry = Eth::Contract.from_abi(name: ens_registry_name, address: ens_registry_address, abi: ens_registry_abi)
# => #<Eth::Contract::ENSRegistryWithFallback:0x000055cd9e1c4960>

ens_registry.address
# => "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"

client.call(ens_registry, "old")
# => "0x112234455c3a32fd11230c42e7bccd4a84e02010"

Feel free to submit a ticket if you think there is any API missing or not working.