An open API service indexing awesome lists of open source software.

https://github.com/icostan/cryptos-ruby

Crypto craft your own transactions, atomic-swaps.
https://github.com/icostan/cryptos-ruby

atomic-swaps bitcoin crypto cryptography ecdsa elliptic-curves finite-fields learning-by-doing litecoin math ruby

Last synced: 2 months ago
JSON representation

Crypto craft your own transactions, atomic-swaps.

Awesome Lists containing this project

README

          

# Cryptos-ruby

[![Build Status](https://travis-ci.org/icostan/cryptos-ruby.svg?branch=master)](https://travis-ci.org/icostan/cryptos-ruby)
[![Maintainability](https://api.codeclimate.com/v1/badges/3e4566b45ebc3f887cef/maintainability)](https://codeclimate.com/github/icostan/cryptos-ruby/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/3e4566b45ebc3f887cef/test_coverage)](https://codeclimate.com/github/icostan/cryptos-ruby/test_coverage)
[![Gem Version](https://badge.fury.io/rb/cryptos.svg)](https://badge.fury.io/rb/cryptos)

### The Why - the vision and goals

* I believe there are none of very few Ruby implementations and support for different crypto technologies
* I like to craft my own wallets, transactions, block explorers in all shapes and forms
* I dream to execute atomic swaps in 3 lines of Ruby code

### The How - the actions

* Implementing basic cryptography from scratch - elliptic curves math, digital signature schemes, etc
* Building a simple and easy to use Ruby API
* Lean and continuous improvement along the way while I understand more advanced cryptography: pairing, lattices

### The What - the features

* Generate private and public keys
* Generate addresses for Bitcoin, Litecoin, Ethereum and much more
* Create transaction to spend standard inputs or more complex multisig, hashed timelock contracts, swaps

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'cryptos'
```

And then execute:

$ bundle

Or install it yourself as:

$ gem install cryptos

## Usage

### Bitcoin and friends

#### Generate keys and address

Alright, let's begin, first thing first, lets generate private and public keys:

```ruby
2.5.3 > private_key = Cryptos::PrivateKey.generate
=> #
2.5.3 > public_key = Cryptos::PublicKey.new private_key
=> #, @x=107779388491921327681974754398507503201871466663959093103394577491037829153768, @y=78060352001932916201234328232450653863791592111885208305671830584742527863131>
```

Based on public key above lets create a Bitcoin address:

```ruby
2.5.3 > from_address = Cryptos::Bitcoin::Address.new public_key
=> #, @x=107779388491921327681974754398507503201871466663959093103394577491037829153768, @y=78060352001932916201234328232450653863791592111885208305671830584742527863131>, @testnet=true>
```

#### Scenario 1: Spend coinbase transaction

Before going any further we need to install bitcoin-core daemon and start node in regtest mode:

```shell
# in MacOS
brew install bitcoin

# in Linux (Debian based)
apt-get install bitcoin

# start Bitcoin daemon in regtest mode
bitcoind -regtest -printtoconsole
```

Now we create a simple Cli connector that will communicate to underlying bitcoin daemon.

```ruby
2.5.3 :004 > cli = Cryptos::Connectors::Cli.new
=> #
```

Import address into node and generate 101 blocks. If you ask why 101 then it is because coinbase transactions are spendable after 100 confirmatinos.

```ruby
2.5.3 :005 > from_address.import cli
=> true
2.5.3 :006 > cli.generate_to_address from_address, blocks: 101
=> true
```

Generate and import destination address to send BTC to then check that it has no money in it.

```ruby
2.5.3 :007 > to_address = Cryptos::Bitcoin::Address.new Cryptos::PublicKey.new Cryptos::PrivateKey.generate
=> #, @x=1402024405898287938501468401055931693243587868828983898835308320263377717122, @y=89146164815925753866667564550747587615674131412309491381641677989226156891240>, @testnet=true>
2.5.3 :008 > to_address.import cli
=> true
2.5.3 :009 > to_address.get_balance cli
=> "0.00000000"
```

Alright, 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```.

```ruby
2.5.3 :010 > input = Cryptos::Input.from_utxo cli, from_address
=> #
2.5.3 :011 > output = Cryptos::Output.p2pkh to_address, 123_456_789
=> #>
2.5.3 :012 > change = Cryptos::Output.p2pkh_change from_address, input, output
=> #>
2.5.3 :013 > transaction = Cryptos::Transaction.from_ioc input, output, change
=> #], outputs=[#>, #>], locktime=0>
```

Sign and broadcast the transaction:

```ruby
2.5.3 :014 > transaction.sign_single_input from_address
=> "01000000017b0cc0a774559d162745da64b78f3961a45ff950c9a3dcfd0c88a5d70685fc33000000006a473044022020b53986c2ef08d54137e57f1c231a0c2fe1b6dc88c7208ecef6f7474bae985002203027db653202da53ce081da46431ef1f88f3e1bf47254940a58740a86506cbc3012103ee48f8db1d9a5dfc1b620dbe9566b77d995e0325b91d3b661a697272920f43e8ffffffff0215cd5b07000000001976a9149aae79929e4364ab3aabe1f83a875304d1b67a3a88acdb04a78d000000001976a91457a58e05aedfbb6bd97b373baf65ce7cc318351b88ac00000000"
2.5.3 :015 > transaction.broadcast cli
=> true
```

Mine new block that will contain our hand crafted transaction and VOILA! output amount was transafered to new address.

```ruby
2.5.3 :016 > cli.generate blocks: 1
=> true
2.5.3 :017 > cli.get_received_by_address to_address
=> "1.23456789"
```

#### Scenario 2: Spend multisig transaction

[multisig transaction](spec/cryptos/litecoin_spec.rb)

#### Scenario 3: Atomic swaps between BTC and LTC

[atomic swap](spec/cryptos/swaps_spec.rb)

### Monero

#### Generate keys and address:

```ruby
2.5.3 :015 > 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"
=> "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"
2.5.3 :016 > wallet = Cryptos::Monero::Wallet.from_mnemonic seed
=> #
2.5.3 :017 > private_spend_key = wallet.private_spend_key
=> #
```

## Development

After 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.

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](https://rubygems.org).

## Contributing

Bug 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.

## Code of Conduct

Everyone 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).