Deploying an Ethereum smart contract with the eth.rb Ruby gem

Introduction

Eth.rb is the maintained Ethereum library for the Ruby language replacing the deprecated ethereum.rb one.

This is a quick tutorial to walk you from zero to a fully deployed smart contract on the Ethereum Goerli testnet.

The tutorial is two-part purely for educational purposes:

  • Ruby console-based—to walk you through executing each of the commands with explanations.
  • Script-based—just a couple of Ruby scripts with the eth.rb gem to quickly deploy your contract and interact with it.

Prerequisites

Prepare a contract

For simplicity, let’s use the simple storage contract.

Create a simplestorage.sol file:

// SPDX-License-Identifier: GPL-3.0 
pragma solidity >=0.4.16 <0.9.0;
contract SimpleStorage {
 uint storedData;
function set(uint x) public {
  storedData = x;
 }
function get() public view returns (uint retVal) {
  return storedData;
 }
}

Console walkthrough

Clone the eth.rb repository:

git clone https://github.com/q9f/eth.rb

In the cloned repository, run the Ruby console:

ruby bin/console

In the console, import your Chainstack node HTTPS endpoint:

client = Eth::Client.create 'CHAINSTACK_NODE_URL'

Swap CHAINSTACK_NODE_URL with your endpoint.

Import the private key of your Ethereum account:

deployer_account = Eth::Key.new priv: 'PRIVATE_KEY'

Swap PRIVATE_KEY with your account private key.

Set the gas limit to spend on deploying the contract:

client.gas_limit=200000

Set the max fee to spend on the deployment transaction in Wei:

client.max_fee_per_gas=41000000000

Set the max tip to spend on the deployment transaction:

client.max_priority_fee_per_gas=40000000000

Import the contract:

contract = Eth::Contract.from_file(file: 'contracts/simplestorage.sol')

Set the deployment address as checksummed:

deployer_account.address

Deploy the contract:

client.deploy_and_wait(contract, sender_key: deployer_account, gas_limit: 200000)

You have deployed your simple storage contract. Now you are going to send a transaction that will write a value to the contract with the set function.

Set the contract ABI:

simplestorage_abi = '[{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"retVal","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}]'

Set the contract address:

simplestorage_address = "CONTRACT_ADDRESS"

Swap CONTRACT_ADDRESS with the address of your deployed contract.

Set the contract name:

simplestorage_name = "SimpleStorage"

Set the full contract:

simplestorage_contract = Eth::Contract.from_abi(name: simplestorage_name, address: simplestorage_address, abi: simplestorage_abi)

Checksum the contract address:

simplestorage_contract.address

Send the transaction that writes 1234 through the contract’s set function:

client.transact_and_wait(simplestorage_contract, "set", 1234, sender_key: deployer_account)

Now retrieve the set value:

client.call(simplestorage_contract, "get")

That’s it.

Now let’s do the same walkthrough with a couple of Ruby scripts.

Script walkthrough

Install the eth.rb gem:

gem install eth

Create the contract deployment script deploy.rb:

require 'eth'
require 'forwardable'
client = Eth::Client.create 'CHAINSTACK_NODE_URL'
deployer_account = Eth::Key.new priv: 'PRIVATE_KEY'
client.max_fee_per_gas=41000000000
client.max_priority_fee_per_gas=40000000000
contract = Eth::Contract.from_file(file: 'contracts/simplestorage.sol')
deployer_account.address
response = client.deploy_and_wait(contract, sender_key: deployer_account, gas_limit: 200000)
puts response

Swap CHAINSTACK_NODE_URL and PRIVATE_KEY with your values.

Run the script with ruby deploy.rb. Your contract will be deployed.

Now set 12345 to the contract with the transact.rb script:

require 'eth'
require 'forwardable'
client = Eth::Client.create 'https://nd-112-260-163.p2pify.com/f50e5157dac5bf2394f91f0a0df21644'
simplestorage_abi = '[{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"retVal","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}]'
simplestorage_address = "CONTRACT_ADDRESS"
simplestorage_name = "SimpleStorage"
simplestorage_contract = Eth::Contract.from_abi(name: simplestorage_name, address: simplestorage_address, abi: simplestorage_abi)
simplestorage_contract.address
deployer_account = Eth::Key.new priv: 'PRIVATE_KEY'
client.gas_limit=200000
client.max_fee_per_gas=41000000000
client.max_priority_fee_per_gas=40000000000
deployer_account.address
response = client.transact_and_wait(simplestorage_contract, "set", 12345, sender_key: deployer_account)
puts response

Swap CHAINSTACK_NODE_URL, CONTRACT_ADDRESS, and PRIVATE_KEY with your values.

Run the script with ruby transact.rb. The contract will have the value 12345 set.

Now read the value with a call to the contract with the call.rb script:

require 'eth'
require 'forwardable'
client = Eth::Client.create 'CHAINSTACK_NODE_URL'
simplestorage_abi = '[{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"retVal","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}]'
simplestorage_address = "CONTRACT_ADDRESS"
simplestorage_name = "SimpleStorage"
simplestorage_contract = Eth::Contract.from_abi(name: simplestorage_name, address: simplestorage_address, abi: simplestorage_abi)
simplestorage_contract.address
response = client.call(simplestorage_contract, "get")
puts response

Swap CHAINSTACK_NODE_URL and CONTRACT_ADDRESS with your values.

This is it.

Conclusion

You’ve learned how to manage accounts, deploy a contract, transact with a contract, and read the contract value with one of the lesser represented languages in the Ethereum ecosystem—Ruby and the eth.rb gem. Congrats!

  • Connect to the Ethereum, Polygon, BNB Smart Chain, Avalanche, Fantom, Solana, Harmony, Tezos and StarkNet mainnet or testnets through the interface designed to help you get the job done.
  • Get access to the Ethereum, Polygon, BNB Smart Chain, Avalanche, Fantom, and Tezos archive nodes to query the entire history of the mainnet—starting at just $49 per month.
  • Choose where you want to deploy, and we will provide you with the dedicated managed infrastructure that can handle high-volume, high-velocity read/write access to the network.
  • To learn more about Chainstack, visit our Knowledge Center or join our Discord server and Telegram group. 

Have you already explored what you can achieve with Chainstack? Get started for free today.

Give me trust

In part 1 of the Trust Trilogy, I took a sweeping view of the evolution of trust and what it means today for all of us. I tried to establish the unique and powerful nature of blockchain as a ‘controllable trust interface’ and touched lightly upon what it means for businesses.

Chainstack
May 7
Chainstack uses cookies to provide you with a secure and
personalized experience on its website. Learn more.