scale.rb
scale.rb copied to clipboard
Ruby SCALE Codec Library & Substrate Client
scale.rb has many problems in design and development because of being unfamiliar with scale codec and substrate before, so it will not continue. I'm already working on a new implementation: https://github.com/wuminzhe/scale_rb.
Warning: After v0.2.19, the develop branch will do a structure refactor and big optimization.
scale.rb
Ruby SCALE Codec Library
SCALE is a lightweight, efficient, binary serialization and deserialization codec used by substrate. Most of the input and output data of the substrate API are encoded in SCALE data format.
This is a SCALE codec library implemented in ruby language for general use. It contains the implementation of low-level data formats, various substrate types, metadata support.
This work is the prerequisite of our subsequent series of projects. We hope to familiarize and quickly access Polkadot and Substrate through ruby. We plan to develop the back end of our applications in ruby language, and then interact with nodes or synchronize data through this library.
Please refer to the official doc for more details about SCALE low-level data format.
Because the feature of ruby 2.6 is used, the ruby version is required to be >= 2.6. it will be compatible with older ruby versions when released.
Installation
Add this line to your application's Gemfile:
gem 'scale.rb', '0.2.19'
And then execute:
$ bundle
Or install it yourself as:
$ gem install scale
Usage
- decode
require "scale"
Scale::TypeRegistry.instance.load # default
# Scale::TypeRegistry.instance.load spec_name: "pangolin"
# Scale::TypeRegistry.instance.load spec_name: "kusama"
# print hex changes if you set debug to true, default is false
Scale::Types.debug = true
# decode a compact integer
scale_bytes = Scale::Bytes.new("0x1501") # create scale_bytes object from scale encoded hex string
o = Scale::Types::Compact.decode(scale_bytes) # use scale type to decode scale_bytes object
p o.value # 69
#
type = Scale::Types::get("Vec<U8>")
o = type.decode(Scale::Bytes.new("0x080001"))
assert_eq o.value, [Scale::Types::U8.new(0), Scale::Types::U8.new(1)]
- encode
require "scale"
Scale::TypeRegistry.instance.load
o = Scale::Types::Compact.new(69)
p o.encode # "1501"
type = Scale::Types::get("Vec<U8>")
o = type.new([Scale::Types::U8.new(0), Scale::Types::U8.new(1)])
p o.encode # "080001"
- client
require "scale"
client = SubstrateClient.new "wss://rpc.darwinia.network"
v = Scale::Types.get("EthereumTransactionIndex")
.new(
[
Scale::Types::H256.new("0x803054c2beacabc36e15c3147bb87d8320a02e9b601be28820a622dedd1c7717"),
Scale::Types::U64.new(266)
]
)
storage = client.get_storage("EthereumBacking", "VerifiedProof", [v])
puts storage.to_human
# get the raw data
key = client.generate_storage_key("EthereumBacking", "VerifiedProof", [v])[0]
storage_raw = client.state_getStorageAt(key)
puts storage_raw
Please go to spec
dir for more examples.
Command line tools
After install scale.rb gem, there is a command named scale
available. You can use it directly in your terminal.
> scale
Commands:
scale decode TYPE_NAME HEX SPEC_NAME SPEC_VERSION # decode HEX string using TYPE_NAME
scale help [COMMAND] # Describe available commands or one specific command
scale specs # list all chain specs
scale type TYPE_NAME SPEC_NAME SPEC_VERSION # show type's ruby class
scale types SPEC_NAME SPEC_VERSION # list all types implemented for chain
examples in exec/scale
Running tests
- Download or clone the code to local, and enter the code root directory
- If rust is installed on your system (for instance,
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
), callmake
to build the FFI library - Run all tests
rspec
To run single test file:
rspec spec/types_spec.rb
rspec spec/extrinsic_spec.rb
rspec spec/metadata_spec.rb
rspec spec/types_ffi_spec.rb
Docker
-
update to latest image
docker pull itering/scale:latest
-
Run image:
docker run -it itering/scale:latest
This will enter the container with a linux shell opened.
/usr/src/app #
-
Type
rspec
to run all tests/usr/src/app # rspec ................... Finished in 0.00883 seconds (files took 0.09656 seconds to load) 19 examples, 0 failures
-
Or, type
./bin/console
to enter the ruby interactive environment and run any decode or encode code/usr/src/app # ./bin/console [1] pry(main)> scale_bytes = Scale::Bytes.new("0x1501") => #<Scale::Bytes:0x000055daa883ba70 @bytes=[21, 1], @data="0x1501", @offset=0> [2] pry(main)> o = Scale::Types::Compact.decode(scale_bytes) => #<Scale::Types::Compact:0x000055daa89b0db0 @value=69> [3] pry(main)> p o.value 69 => 69 [4] pry(main)>
-
Or, run command line tool:
/usr/src/app # scale types kusama HeadData => Scale::Types::HeadData Conviction => Scale::Types::Conviction EraRewards => Scale::Types::EraRewards ... Count: 303
Development
After checking out the repo, run bin/setup
to install dependencies. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/itering/scale.rb.
License
The gem is available as open source under the terms of the MIT License.