{"id":35138791,"url":"https://github.com/icostan/cryptos-ruby","last_synced_at":"2026-04-20T23:33:02.362Z","repository":{"id":56843927,"uuid":"154360649","full_name":"icostan/cryptos-ruby","owner":"icostan","description":"Crypto craft your own transactions, atomic-swaps.","archived":false,"fork":false,"pushed_at":"2019-04-23T14:33:27.000Z","size":94,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-30T17:31:10.440Z","etag":null,"topics":["atomic-swaps","bitcoin","crypto","cryptography","ecdsa","elliptic-curves","finite-fields","learning-by-doing","litecoin","math","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/icostan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-23T16:22:41.000Z","updated_at":"2023-05-13T05:15:22.000Z","dependencies_parsed_at":"2022-08-26T12:51:38.374Z","dependency_job_id":null,"html_url":"https://github.com/icostan/cryptos-ruby","commit_stats":null,"previous_names":["icostan/cryptos"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/icostan/cryptos-ruby","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icostan%2Fcryptos-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icostan%2Fcryptos-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icostan%2Fcryptos-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icostan%2Fcryptos-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/icostan","download_url":"https://codeload.github.com/icostan/cryptos-ruby/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icostan%2Fcryptos-ruby/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32070656,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T21:26:33.338Z","status":"ssl_error","status_checked_at":"2026-04-20T21:26:22.081Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atomic-swaps","bitcoin","crypto","cryptography","ecdsa","elliptic-curves","finite-fields","learning-by-doing","litecoin","math","ruby"],"created_at":"2025-12-28T10:44:56.165Z","updated_at":"2026-04-20T23:33:02.351Z","avatar_url":"https://github.com/icostan.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cryptos-ruby\n\n[![Build Status](https://travis-ci.org/icostan/cryptos-ruby.svg?branch=master)](https://travis-ci.org/icostan/cryptos-ruby)\n[![Maintainability](https://api.codeclimate.com/v1/badges/3e4566b45ebc3f887cef/maintainability)](https://codeclimate.com/github/icostan/cryptos-ruby/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/3e4566b45ebc3f887cef/test_coverage)](https://codeclimate.com/github/icostan/cryptos-ruby/test_coverage)\n[![Gem Version](https://badge.fury.io/rb/cryptos.svg)](https://badge.fury.io/rb/cryptos)\n\n### The Why - the vision and goals\n\n  * I believe there are none of very few Ruby implementations and support for different crypto technologies\n  * I like to craft my own wallets, transactions, block explorers in all shapes and forms\n  * I dream to execute atomic swaps in 3 lines of Ruby code\n\n### The How - the actions\n\n  * Implementing basic cryptography from scratch - elliptic curves math, digital signature schemes, etc\n  * Building a simple and easy to use Ruby API\n  * Lean and continuous improvement along the way while I understand more advanced cryptography: pairing, lattices\n\n### The What - the features\n\n  * Generate private and public keys\n  * Generate addresses for Bitcoin, Litecoin, Ethereum and much more\n  * Create transaction to spend standard inputs or more complex multisig, hashed timelock contracts, swaps\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'cryptos'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install cryptos\n\n## Usage\n\n### Bitcoin and friends\n\n#### Generate keys and address\n\nAlright, let's begin, first thing first, lets generate private and public keys:\n\n```ruby\n2.5.3 \u003e private_key = Cryptos::PrivateKey.generate\n =\u003e #\u003cCryptos::PrivateKey:0x00007f8cc10c0ad0 @value=1991485315816438798044329630916774278846523543844864946402119577704095054145, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337\u003e\n2.5.3 \u003e public_key = Cryptos::PublicKey.new private_key\n =\u003e #\u003cCryptos::PublicKey:0x00007f8cc105ed58 @private_key=#\u003cCryptos::PrivateKey:0x00007f8cc10c0ad0 @value=1991485315816438798044329630916774278846523543844864946402119577704095054145, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337\u003e, @x=107779388491921327681974754398507503201871466663959093103394577491037829153768, @y=78060352001932916201234328232450653863791592111885208305671830584742527863131\u003e\n```\n\nBased on public key above lets create a Bitcoin address:\n\n```ruby\n2.5.3 \u003e from_address = Cryptos::Bitcoin::Address.new public_key\n =\u003e #\u003cCryptos::Bitcoin::Address:0x00007f8cc12fc560 @public_key=#\u003cCryptos::PublicKey:0x00007f8cc105ed58 @private_key=#\u003cCryptos::PrivateKey:0x00007f8cc10c0ad0 @value=1991485315816438798044329630916774278846523543844864946402119577704095054145, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337\u003e, @x=107779388491921327681974754398507503201871466663959093103394577491037829153768, @y=78060352001932916201234328232450653863791592111885208305671830584742527863131\u003e, @testnet=true\u003e\n```\n\n#### Scenario 1: Spend coinbase transaction\n\nBefore going any further we need to install bitcoin-core daemon and start node in regtest mode:\n\n```shell\n# in MacOS\nbrew install bitcoin\n\n# in Linux (Debian based)\napt-get install bitcoin\n\n# start Bitcoin daemon in regtest mode\nbitcoind -regtest -printtoconsole\n```\n\nNow we create a simple Cli connector that will communicate to underlying bitcoin daemon.\n\n```ruby\n2.5.3 :004 \u003e cli = Cryptos::Connectors::Cli.new\n =\u003e #\u003cCryptos::Connectors::Cli:0x00007f8cc12ece30 @program=\"bitcoin-cli\", @network=\"regtest\", @verbose=false\u003e\n```\n\nImport address into node and generate 101 blocks. If you ask why 101 then it is because coinbase transactions are spendable after 100 confirmatinos.\n\n```ruby\n2.5.3 :005 \u003e from_address.import cli\n =\u003e true\n2.5.3 :006 \u003e cli.generate_to_address from_address, blocks: 101\n =\u003e true\n```\n\nGenerate and import destination address to send BTC to then check that it has no money in it.\n\n```ruby\n2.5.3 :007 \u003e to_address = Cryptos::Bitcoin::Address.new Cryptos::PublicKey.new Cryptos::PrivateKey.generate\n =\u003e #\u003cCryptos::Bitcoin::Address:0x00007f8cc134f2b0 @public_key=#\u003cCryptos::PublicKey:0x00007f8cc128fa78 @private_key=#\u003cCryptos::PrivateKey:0x00007f8cc128faa0 @value=104555233989943463494354097619221894829574308702717051161491781222000198727347, @order=115792089237316195423570985008687907852837564279074904382605163141518161494337\u003e, @x=1402024405898287938501468401055931693243587868828983898835308320263377717122, @y=89146164815925753866667564550747587615674131412309491381641677989226156891240\u003e, @testnet=true\u003e\n2.5.3 :008 \u003e to_address.import cli\n =\u003e true\n2.5.3 :009 \u003e to_address.get_balance cli\n =\u003e \"0.00000000\"\n```\n\nAlright, now we get to real stuff, transactions: create input from our ```from_address```, send 123_456_789 Satoshis (1.23456789 BTC) to our ```to_address``` and change amount back to ```from_address```.\n\n```ruby\n2.5.3 :010 \u003e input = Cryptos::Input.from_utxo cli, from_address\n =\u003e #\u003cstruct Cryptos::Input value=2500000000.0, tx_hash=\"33fc8506d7a5880cfddca3c950f95fa461398fb764da4527169d5574a7c00c7b\", index=0, script_sig=nil, sequence=68719476735\u003e\n2.5.3 :011 \u003e output = Cryptos::Output.p2pkh to_address, 123_456_789\n =\u003e #\u003cstruct Cryptos::Output value=123456789, script_pubkey=#\u003cCryptos::Script:0x00007f8cc12ed8a8 @script=\"OP_DUP OP_HASH160 9aae79929e4364ab3aabe1f83a875304d1b67a3a OP_EQUALVERIFY OP_CHECKSIG\"\u003e\u003e\n2.5.3 :012 \u003e change = Cryptos::Output.p2pkh_change from_address, input, output\n =\u003e #\u003cstruct Cryptos::Output value=2376533211.0, script_pubkey=#\u003cCryptos::Script:0x00007f8cc12cfdd0 @script=\"OP_DUP OP_HASH160 57a58e05aedfbb6bd97b373baf65ce7cc318351b OP_EQUALVERIFY OP_CHECKSIG\"\u003e\u003e\n2.5.3 :013 \u003e transaction = Cryptos::Transaction.from_ioc input, output, change\n =\u003e #\u003cstruct Cryptos::Transaction version=1, inputs=[#\u003cstruct Cryptos::Input value=2500000000.0, tx_hash=\"33fc8506d7a5880cfddca3c950f95fa461398fb764da4527169d5574a7c00c7b\", index=0, script_sig=nil, sequence=68719476735\u003e], outputs=[#\u003cstruct Cryptos::Output value=123456789, script_pubkey=#\u003cCryptos::Script:0x00007f8cc12ed8a8 @script=\"OP_DUP OP_HASH160 9aae79929e4364ab3aabe1f83a875304d1b67a3a OP_EQUALVERIFY OP_CHECKSIG\"\u003e\u003e, #\u003cstruct Cryptos::Output value=2376533211.0, script_pubkey=#\u003cCryptos::Script:0x00007f8cc12cfdd0 @script=\"OP_DUP OP_HASH160 57a58e05aedfbb6bd97b373baf65ce7cc318351b OP_EQUALVERIFY OP_CHECKSIG\"\u003e\u003e], locktime=0\u003e\n```\n\nSign and broadcast the transaction:\n\n```ruby\n2.5.3 :014 \u003e transaction.sign_single_input from_address\n =\u003e \"01000000017b0cc0a774559d162745da64b78f3961a45ff950c9a3dcfd0c88a5d70685fc33000000006a473044022020b53986c2ef08d54137e57f1c231a0c2fe1b6dc88c7208ecef6f7474bae985002203027db653202da53ce081da46431ef1f88f3e1bf47254940a58740a86506cbc3012103ee48f8db1d9a5dfc1b620dbe9566b77d995e0325b91d3b661a697272920f43e8ffffffff0215cd5b07000000001976a9149aae79929e4364ab3aabe1f83a875304d1b67a3a88acdb04a78d000000001976a91457a58e05aedfbb6bd97b373baf65ce7cc318351b88ac00000000\"\n2.5.3 :015 \u003e transaction.broadcast cli\n =\u003e true\n```\n\nMine new block that will contain our hand crafted transaction and VOILA! output amount was transafered to new address.\n\n```ruby\n2.5.3 :016 \u003e cli.generate blocks: 1\n =\u003e true\n2.5.3 :017 \u003e cli.get_received_by_address to_address\n =\u003e \"1.23456789\"\n```\n\n#### Scenario 2: Spend multisig transaction\n\n[multisig transaction](spec/cryptos/litecoin_spec.rb)\n\n#### Scenario 3: Atomic swaps between BTC and LTC\n\n[atomic swap](spec/cryptos/swaps_spec.rb)\n\n### Monero\n\n#### Generate keys and address:\n\n```ruby\n2.5.3 :015 \u003e seed = \"vinegar talent sorry hybrid ultimate template nimbly jukebox axes inactive veered toenail pride plotting chrome victim agnostic science bailed paddles wounded peaches king laptop king\"\n =\u003e \"vinegar talent sorry hybrid ultimate template nimbly jukebox axes inactive veered toenail pride plotting chrome victim agnostic science bailed paddles wounded peaches king laptop king\"\n2.5.3 :016 \u003e wallet = Cryptos::Monero::Wallet.from_mnemonic seed\n =\u003e #\u003cCryptos::Monero::Wallet:0x00007faa600bfad8 @seed=\"6ee02ef8647856f4080882a1ec4fabee19ec047ca24d3abb13c0ce589a46f702\"\u003e\n2.5.3 :017 \u003e private_spend_key = wallet.private_spend_key\n =\u003e #\u003cCryptos::Monero::PrivateSpendKey:0x00007faa600aac50 @value=1341524205595389594312687854960107116555340486708078533906470082005332582510, @order=7237005577332262213973186563042994240857116359379907606001950938285454250989, @little=true\u003e\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo 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](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/icostan/cryptos. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\n## Code of Conduct\n\nEveryone interacting in the CryptoCrafts project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/icostan/cryptos/blob/master/CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficostan%2Fcryptos-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ficostan%2Fcryptos-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficostan%2Fcryptos-ruby/lists"}