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
- A Goerli node:
- Installed Ruby. See Installing Ruby.
- An Ethereum account funded with Goerli ether.
- Installed Solidity compiler.
Prepare a smart 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!
- Discover how you can save thousands in infra costs every month with our unbeatable pricing on the most complete Web3 development platform.
- Input your workload and see how affordable Chainstack is compared to other RPC providers.
- Connect to Ethereum, Solana, BNB Smart Chain, Polygon, Arbitrum, Base, Optimism, Avalanche, TON, Ronin, zkSync Era, Starknet, Scroll, Aptos, Fantom, Cronos, Gnosis Chain, Klaytn, Moonbeam, Celo, Aurora, Oasis Sapphire, Polygon zkEVM, Bitcoin, Tezos and Harmony mainnet or testnets through an interface designed to help you get the job done.
- To learn more about Chainstack, visit our Developer Portal or join our Discord server and Telegram group.
- Are you in need of testnet tokens? Request some from our faucets. Multi-chain faucet, Sepolia faucet, Holesky faucet, BNB faucet, zkSync faucet, Scroll faucet.
Have you already explored what you can achieve with Chainstack? Get started for free today.