casper_network 1.0.2 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +221 -78
  3. data/lib/casper_network.rb +7 -4
  4. data/lib/crypto/asymmetric_key.rb +19 -18
  5. data/lib/crypto/ed25519.rb +114 -0
  6. data/lib/crypto/ed25519_key.rb +111 -10
  7. data/lib/crypto/keys.rb +1 -2
  8. data/lib/crypto/keys_util.rb +20 -0
  9. data/lib/entity/deploy.rb +154 -1
  10. data/lib/entity/deploy_executable.rb +50 -7
  11. data/lib/entity/deploy_executable_item_internal.rb +1 -1
  12. data/lib/entity/deploy_header.rb +17 -0
  13. data/lib/entity/deploy_named_argument.rb +61 -2
  14. data/lib/entity/module_bytes.rb +9 -2
  15. data/lib/include.rb +2 -0
  16. data/lib/serialization/cl_value_serializer.rb +69 -12
  17. data/lib/serialization/deploy_serializer.rb +129 -15
  18. data/lib/types/cl_option.rb +9 -1
  19. data/lib/types/cl_public_key.rb +2 -0
  20. data/lib/types/cl_value.rb +8 -0
  21. data/lib/utils/byte_utils.rb +28 -0
  22. data/lib/utils/helpers.rb +10 -0
  23. data/lib/version.rb +1 -1
  24. data/spec/cl_value_serializer_spec.rb +15 -1
  25. data/spec/deploy_executable_spec.rb +90 -0
  26. data/spec/testnet_spec.rb +5 -3
  27. metadata +7 -24
  28. data/lib/crypto/00_asymmetric_key.rb +0 -95
  29. data/lib/crypto/01_ed25519.rb +0 -67
  30. data/lib/crypto/key_pair.rb +0 -40
  31. data/lib/crypto/secp256k1_key.rb +0 -0
  32. data/lib/crypto/test_ed25519_key.rb +0 -44
  33. data/lib/entity/executable_deploy_item.rb +0 -11
  34. data/lib/serialization/test.rb +0 -431
  35. data/lib/types/cl_account_hash.rb +0 -24
  36. data/lib/types/cl_account_hash_type.rb +0 -22
  37. data/lib/utils/utils.rb +0 -2
  38. data/spec/a_spec.rb +0 -697
  39. data/spec/cl_public_spec.rb +0 -169
  40. data/spec/crypto_spec.rb +0 -42
  41. data/spec/deploy_executable_serializer_spec.rb +0 -0
  42. data/spec/deploy_serializer_test_spec.rb +0 -225
  43. data/spec/string_spec.rb +0 -68
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3446db6dad9ec70e0ad842479120abfe4cb919a7c65be7af300da5473a6e342f
4
- data.tar.gz: d101cdc5acccc2ea222fb41a36baf819499cea70faaad98c8cbeb35a7955a833
3
+ metadata.gz: b46d9a498eaea47808ae5b3bf9455f8858692215494aac8f2816e0a6493b8ad8
4
+ data.tar.gz: cfd0376e3a0349028674273347d27506699ee1cacc573dbaf62d870accc5f3ca
5
5
  SHA512:
6
- metadata.gz: eb48b8c657010cfd2327c2d6ce1b060b29742084a0df40b682b03819f958c0c4c25aacc31c7049a5f749ad97aa92b53318274ae9cca98e3774d15c4e8db03ba7
7
- data.tar.gz: 5e14e5e989ff7078464ff63caafccf41c38bd3fc4c0b378a2119da76a92481c06783f4a34a5e578baed18568086935398ffbe1555ee7889c140e0d25a5f551fa
6
+ metadata.gz: 49bf35f83b681f3f023ad263d8cfa5c9f259235cfb01a226e8ae89197463d6b99dec6a73414c5ca9d0812c9002bd78fa1d9ea5812421d0178bc87199352cf14f
7
+ data.tar.gz: 94b5d574ed064525b0b0e4265652935595ec2337a6602d1bbee4a83f27c083ccd1fa26c8b045355294acb6435b01c19fd3ece4dfffa5a93aaef1a88cc1dc1564
data/README.md CHANGED
@@ -70,7 +70,20 @@ yardoc lib/**/*.rb lib/*.rb - README.md LICENSE CONTRIBUTING.md SECURITY.md
70
70
  yardoc --help
71
71
  ```
72
72
 
73
- ## Documentation:
73
+ ## Documentation
74
+
75
+ The SDK documentation can be found [here](https://www.rubydoc.info/gems/casper_network/1.1.2) in detail.
76
+
77
+ ### Serialization
78
+ Casper provides a custom implementation to serialize data structures used by the Casper node to their byte representation.
79
+ More information on this custom implementation can be found [here](https://caspernetwork.readthedocs.io/en/latest/implementation/serialization-standard.html).
80
+
81
+ * [Serialization](https://github.com/saitgulmez/casper-ruby-sdk/blob/main/docs/serialization.md#serialization)
82
+ * [Examples](https://github.com/saitgulmez/casper-ruby-sdk/blob/main/docs/serialization.md#examples)
83
+
84
+ ### Key Management
85
+ * [CLPublicKey](https://github.com/saitgulmez/casper-ruby-sdk/blob/main/docs/keys.md#public-keys)
86
+
74
87
  ### Casper-Ruby-Sdk RPC
75
88
  * [info_get_peers](https://github.com/saitgulmez/casper-ruby-sdk/blob/main/docs/rpc.md#info_get_peers)
76
89
  * [chain_get_StateRootHash](https://github.com/saitgulmez/casper-ruby-sdk/blob/main/docs/rpc.md#get-state_root_hash)
@@ -333,91 +346,221 @@ stake_amount = delegator.get_staked_amount # => 27871095039894
333
346
  ```
334
347
 
335
348
 
336
- ### Get 5 peer IP addresses randomly
349
+ ### Example
350
+ ```bash
351
+ # example.rb
352
+ # how to execute example.rb
353
+ $ ruby example.rb
354
+ ```
355
+
337
356
  ```ruby
357
+ # example.rb
338
358
  require 'casper_network'
359
+ # Class-Object Level
360
+ # Casper::CasperClient
361
+ node_ip_address = "5.9.23.55" # IP is taken from "testnet"
362
+ client = Casper::CasperClient.new(node_ip_address)
363
+
364
+ #********** info_get_peers *********************************#
365
+
366
+ # Uncomment following lines to see the outputs
367
+ # puts client.info_get_peers
368
+ # puts client.info_get_peers[0].get_node_id
369
+ # puts client.info_get_peers[0].get_address
370
+
371
+
372
+ #********** chain_get_StateRootHash *********************************#
373
+ # Uncomment following line to see the outputs
374
+ # puts client.chain_get_StateRootHash
339
375
 
340
- # In order to interact with casper network we should give a valid ip address to the constructor
341
376
 
342
- # if it does not work, please choose another node ip address from the Testnet
343
- # IP is taken from "Testnet"
344
- node_ip_address = "85.114.132.129"
377
+ #********** info_get_deploy(deploy_hash) *********************************#
378
+ deploy_hash = "0806cc477a5282574bc5302d7598cd33a09875704c5fef9264d984535c945e31"
379
+ deploy = client.info_get_deploy(deploy_hash)
380
+ # Uncomment following lines to see the outputs
381
+ # puts deploy
382
+ # hash = Casper::Entity::DeployHash.new(deploy.get_hash)
383
+ # puts hash
384
+ # header = Casper::Entity::DeployHeader.new(deploy.get_header)
385
+ # puts header
386
+ # payment = deploy.get_payment
387
+ # puts payment
388
+ # session = deploy.get_session
389
+ # puts session
390
+
391
+ # approvals = []
392
+ # num_of_approvals = deploy.get_approvals.size
393
+ # num_of_approvals.times do |i|
394
+ # approvals.push(Casper::Entity::DeployApproval.new(deploy.get_approvals[i]))
395
+ # end
396
+ # puts approvals[0].get_signer
397
+ # puts hash, header, payment, session, approvals
398
+
399
+ #********** info_get_status *********************************#
400
+ node_status = client.info_get_status
401
+ # Uncomment following lines to see the outputs
402
+ # puts node_status
403
+ # puts node_status.get_api_version
404
+ # puts node_status.get_chainspec_name
405
+ # puts node_status.get_starting_state_root_hash
406
+ # puts node_status.get_peers
407
+ # puts node_status.get_last_added_block_info
408
+ # puts node_status.get_our_public_signing_key
409
+ # puts node_status.get_round_length
410
+ # puts node_status.get_next_upgrade
411
+ # puts node_status.get_build_version
412
+ # puts node_status.get_uptime
413
+
414
+ #********** chain_get_block_transfers(block_hash = "") *********************************#
345
415
  # block_Hash taken from Testnet
346
- block_hash = "71e19e2e9629c716dc9578066cfeceace559d32fe51b08245ddd4d218f8c18da"
347
- # deploy_Hash taken from Testnet
348
- deploy_hash = "d3e0a1bd85ee74916e096cf4b18df391ada414d0915aeb865eff0ba75f04c3d8"
349
- state_root_hash = "2a62440a1e1e57bff71344aac8a7de169f6dd08d29cffe83b2fb5d6648971855"
416
+ block_hash = "ff2ad232c3efc22a385fce44df844fc696e904ce8ba78599a576aa68c76889c4"
417
+ transfers = client.chain_get_block_transfers(block_hash)
418
+ # Uncomment following lines to see the outputs
419
+ # puts transfers
420
+ # transfers.each do |transfer|
421
+ # puts transfer.get_deploy_hash
422
+ # puts transfer.get_from
423
+ # puts transfer.get_to
424
+ # puts transfer.get_source
425
+ # puts transfer.get_target
426
+ # puts transfer.get_amount
427
+ # puts transfer.get_gas
428
+ # puts transfer.get_id
429
+ # end
430
+
431
+
432
+
433
+ #********** chain_get_block(block_hash) *********************************#
434
+ block_hash = "ff2ad232c3efc22a385fce44df844fc696e904ce8ba78599a576aa68c76889c4"
435
+ block = client.chain_get_block(block_hash)
436
+ # Uncomment following lines to see the outputs
437
+ # puts block
438
+ # To retrieve BlockHeader object
439
+ # block_header = block.get_header
440
+ # puts block_header
441
+ # To access and print members of the block_header object (block_header is an instance of BlockHeader )
442
+ # puts block_header.get_parent_hash
443
+ # puts block_header.get_state_root_hash
444
+ # puts block_header.get_body_hash
445
+ # puts block_header.get_random_bit
446
+ # puts block_header.get_accumulated_seed
447
+ # puts block_header.get_era_end
448
+ # puts block_header.get_timestamp
449
+ # puts block_header.get_era_id
450
+ # puts block_header.get_height
451
+ # puts block_header.get_protocol_version
452
+
453
+ # To retrieve BlockBody object
454
+ # block_body = block.get_body
455
+ # To access and print members of the block_body object (block_body is an instance of BlockBody )
456
+ # puts block_body
457
+ # puts block_body.get_proposer
458
+ # puts block_body.get_deploy_hashes
459
+ # puts block_body.get_transfer_hashes
460
+
461
+ # To retrieve an array of BlockProof objects
462
+ # proofs = block.get_proofs
463
+ # To access and print members of the block_proof objects (block_proof is an instance of BlockProof )
464
+ # puts proofs
465
+ # To access and print each proof object and its members
466
+ # i = 0
467
+ # proofs.each do |proof|
468
+ # puts "proofs[#{i}]: #{proof}"
469
+ # puts "public_key: " + proof.get_public_key
470
+ # puts "signature: " + proof.get_signature
471
+ # i += 1
472
+ # end
473
+
474
+
475
+
476
+ #********** chain_get_eraInfo_by_SwitchBlock(block_hash) *********************************#
477
+ block_hash = "d2077716e5b8796723c5720237239720f54e6ada54e3357f2c4896f2a51a6d8f"
478
+ era_summary = client.chain_get_eraInfo_by_SwitchBlock(block_hash)
479
+ # Uncomment following lines to see the outputs
480
+ # puts era_summary
481
+ # puts era_summary.get_block_hash
482
+ # puts era_summary.get_era_id
483
+ # puts era_summary.get_stored_value
484
+ # puts era_summary.get_stored_value.get_stored_value
485
+ # puts era_summary.get_state_root_hash
486
+ # puts era_summary.get_merkle_proof
487
+ # era_summary.map { |k, v| puts "#{k}" }
488
+ #
489
+
490
+
491
+
492
+ #********** state_get_item(state_root_hash, key, path) *********************************#
493
+ node_ip_address = "65.108.78.120" # => Taken from Mainnet
494
+ client = Casper::CasperClient.new(node_ip_address)
495
+ # Retrieve the stored_value object which is an instance of StoredValue
496
+ # Uncomment following lines to see the outputs
497
+ stored_value = client.state_get_item("647C28545316E913969B032Cf506d5D242e0F857061E70Fb3DF55980611ace86", "bid-24b6D5Aabb8F0AC17D272763A405E9CECa9166B75B745Cf200695E172857c2dD", [])
498
+ # puts stored_value # => #<Casper::Entity::StoredValue:0x0000000003767a48>
499
+ # puts stored_value.get_key # => Bid
500
+ # puts stored_value.get_bid # => Retrieve and print Bid object related data
501
+ # # or
502
+ # puts stored_value.get_stored_value # => Retrieve and print Bid object related data
503
+
504
+
505
+
506
+
507
+ #********** state_get_dictionary_item(state_root_hash, item_key, uref) *********************************#
508
+ node_ip_address = "65.108.78.120" # => Taken from Mainnet
509
+ client = Casper::CasperClient.new(node_ip_address)
510
+ state_root_hash = "7b605ad991c949832fd966495afc3f97a2b8122a1a6afc2610b545a8c07e3456"
350
511
  item_key = "f870e3cadfde21d7d7686fdf3d1a8413838274d363ca7b27ae71fc9125eb6743"
351
- uref = "uref-9199d08ff4ca4d52cd7a05ba0d2694204b7ebff963fec1c216f81bf654e0e59f-007"
352
- switch_block_hash = "9e30104581a492f5c6faad4cdfb098311e3bf0e93897ebbfb47c3df62f5e6375"
512
+ uref = "uref-0d689e987db7ee5be246282c3a7badf0411e34baeeab8e9d73c1223ae4ad02e5-007"
513
+ # # Retrieve folowing data from the network and convert it into its proper CLValue
514
+ # # {"CLValue"=>{"cl_type"=>"String", "bytes"=>"1a00000068747470733a2f2f636173706572636f6d6d756e6974792e696f", "parsed"=>"https://caspercommunity.io"}}
515
+
516
+ # Uncomment following lines to see the outputs
517
+ # stored_value = client.state_get_dictionary_item(state_root_hash, item_key, uref)
518
+ # puts stored_value # => #<CLString:0x0000000002b3c8e0>
519
+ # puts stored_value.get_cl_type # => String
520
+ # puts stored_value.get_value # => https://caspercommunity.io
521
+ # puts CLValueBytesParsers::CLStringBytesParser.to_bytes(stored_value.get_value) # => 1a00000068747470733a2f2f636173706572636f6d6d756e6974792e696f
522
+
523
+
524
+
525
+ #********** state_get_balance(state_root_hash, balance_uref) *********************************#
526
+ node_ip_address = "65.108.78.120" # => Taken from Mainnet
527
+ client = Casper::CasperClient.new(node_ip_address)
528
+ state_root_hash = "610e932aef10d3e1fa04940c79a4a2789ee79c17046f1a9b45a2919f3600f3d5"
529
+ uref = "uref-7de5e973b7d70bc2b328814411f2009aafd8dba901cfc2c588ba65088dcd22bb-007"
353
530
 
531
+ # Uncomment following lines to see the outputs
532
+ # balance = client.state_get_balance(state_root_hash, uref)
533
+ # puts balance # => 29269647684075 (current balance 9/24/2022)
354
534
 
355
- # Uncomment following lines to test on Mainnet
356
- # if it does not work, please choose another node ip address from the Mainnet
357
- # IP is taken from "Mainnet"
358
- # node_ip_address = "65.108.78.12"
535
+
536
+ #********** state_get_AuctionInfo *********************************#
359
537
  # block_Hash taken from MainNet
360
- # block_hash = "5fdbdf3fa70d37821aa2d1752743e9653befc15e65e40c2655e1ce93a807260f"
361
- # # deploy_Hash taken from MainNet
362
- # deploy_hash = "52a40996a88523c475c12e5370ff90b0ae4ec051cfaa57cd048c136b1a83319d"
363
- # state_root_hash = "7b605ad991c949832fd966495afc3f97a2b8122a1a6afc2610b545a8c07e3456"
364
- # item_key = "f870e3cadfde21d7d7686fdf3d1a8413838274d363ca7b27ae71fc9125eb6743"
365
- # uref = "uref-0d689e987db7ee5be246282c3a7badf0411e34baeeab8e9d73c1223ae4ad02e5-007"
366
- # switch_block_hash = "4696285db1ca6572f425cada612257f85a58a6a4034c09846afe360ba40e5df0"
367
-
368
- if (IPAddress.valid? node_ip_address)
369
- client = Casper::CasperClient.new(node_ip_address)
370
- peers = client.info_get_peers.sample(5)
371
- puts "node_id and address of five randomly selected 5 peers:"
372
- puts peers
373
-
374
- # Store ip addresses of these peers into an array
375
- ips = []
376
- peers.select do |item|
377
- ip = item["address"]
378
- ips << ip[0, ip.index(':')]
379
- end
380
-
381
- clients = []
382
- puts "Randomly selected 5 peers ip addresses:"
383
- ips.each do |ip_address|
384
- # Create a client object for each iteration
385
- puts ip_address
386
- client = CasperClient.new(ip_address)
387
- clients.push(client)
388
- end
389
-
390
-
391
- clients.each do |client|
392
- puts client.info_get_peers
393
- puts client.chain_get_StateRootHash(block_hash)
394
- puts client.chain_get_StateRootHash
395
- puts client.info_get_deploy(deploy_hash)
396
- puts client.info_get_status
397
- puts client.chain_get_block_transfers(block_hash)
398
- puts client.chain_get_block_transfers
399
- puts client.chain_get_block(block_hash)
400
- puts client.chain_get_eraInfo_by_SwitchBlock(switch_block_hash)
401
- puts client.state_get_item("647C28545316E913969B032Cf506d5D242e0F857061E70Fb3DF55980611ace86", "bid-24b6D5Aabb8F0AC17D272763A405E9CECa9166B75B745Cf200695E172857c2dD", [])
402
- puts client.state_get_dictionary_item(state_root_hash, item_key, uref)
403
- state_root_hash = "610e932aef10d3e1fa04940c79a4a2789ee79c17046f1a9b45a2919f3600f3d5"
404
- uref = "uref-7de5e973b7d70bc2b328814411f2009aafd8dba901cfc2c588ba65088dcd22bb-007"
405
- puts client.state_get_balance(state_root_hash, uref)
406
- puts client.state_get_AuctionInfo
407
-
408
- end
409
- else
410
- puts "Invalid IP address"
411
- end
412
- ```
413
- - [Testnet](https://testnet.cspr.live/tools/peers), [Mainnet](https://cspr.live/tools/peers)
414
- - [doc](https://www.rubydoc.info/gems/casper_network/0.2.1)
538
+ block_hash = "5fdbdf3fa70d37821aa2d1752743e9653befc15e65e40c2655e1ce93a807260f"
539
+ node_ip_address = "65.108.78.120" # => Taken from Mainnet
540
+ client = Casper::CasperClient.new(node_ip_address)
415
541
 
542
+ # Uncomment following lines to see the outputs
543
+ # auction = client.state_get_AuctionInfo
544
+ # Retrieve and print an instance of AuctionState entity
545
+ # puts auction # => #<Casper::Entity::AuctionState:0x0000000003306bc0>
546
+ # Retrieve and print state root hash as a String value
547
+ # puts auction.get_state_root_hash # => "6448b55f1dd7c9ad337f4fd4c77586d7ae30da146e0b340932aba7e7efa9cbcb"
548
+ # Retrieve and print block height as an Integer value
549
+ # puts auction.get_block_height # => 1128800
550
+ # Retrieve and print an array of instances of EraValidor entity
551
+ # puts auction.get_era_validators # => [#<Casper::Entity::EraValidator:0x0000000002b69980>, #<Casper::Entity::EraValidator:0x0000000002b68940>]
552
+ # Retrieve and print an array of instances of Bid entity
553
+ # puts auction.get_bids # => [#<Casper::Entity::Bid:0x000000000430bcf0>, #<Casper::Entity::Bid:0x000000000430b6d8>....]
416
554
 
417
- ## TODO
418
- - [x] Ruby version of CLType primitives
419
- - [x] Ruby version for Casper domain-specific objects
420
- - [x] Serialization of Casper domain-specific objects
421
- - [ ] ED25519/SECP256K1 key pairs Wrappers implemented
422
- - [ ] PutDeploy call implemented and tested
423
- - [x] SDK calls will return Casper domain-specific objects
555
+ # Retrieve and print an instance of BidInfo, which is also the member of bid object
556
+ # bids = auction.get_bids
557
+ # bid = bids[0] # => #<Casper::Entity::Bid:0x0000000003773dc0>
558
+ # bid_info = bid.get_bid_info # => #<Casper::Entity::BidInfo:0x00000000042cffc0>
559
+ # Retrieve and print an array of delegator objects, which are instance of Delegator entity
560
+ # delegators = bid_info.get_delegators
561
+ # puts delegators # => [#<Casper::Entity::Delegator:0x000000000396c550>, #<Casper::Entity::Delegator:0x000000000396c500>.....]
562
+ # How to access members of one of the above delegator instances
563
+ # For instance, access to stake amount at first delegator
564
+ # delegator = delegators[0]
565
+ # stake_amount = delegator.get_staked_amount # => 27871095039894
566
+ ```
@@ -15,6 +15,8 @@ require_relative './serialization/deploy_serializer.rb'
15
15
  # Dir["./serialization/*.rb"].each {|file| require file }
16
16
  # Dir["./types/*.rb"].each {|file| require file }
17
17
  require_relative './include.rb'
18
+ require_relative './crypto/ed25519_key.rb'
19
+ require_relative './crypto/asymmetric_key.rb'
18
20
  module Casper
19
21
  # Interacting with the network
20
22
  class CasperClient
@@ -281,7 +283,7 @@ module Casper
281
283
  state_root_hash = @auction_state[:state_root_hash]
282
284
  block_height = @auction_state[:block_height]
283
285
  era_validators = @auction_state[:era_validators]
284
- @auction_state
286
+
285
287
  bids = @auction_state[:bids]
286
288
  Casper::Entity::AuctionState.new(state_root_hash, block_height, era_validators, bids)
287
289
  }
@@ -293,9 +295,10 @@ module Casper
293
295
 
294
296
  # @param [Deploy] deploy
295
297
  def put_deploy(deploy)
296
- client = Jimson::Client.new(url)
297
- response = client.account_put_deploy(deploy)
298
- response['deploy_hash']
298
+ client = Jimson::Client.new(@url)
299
+ response = client.account_put_deploy({
300
+ "deploy" => deploy
301
+ })
299
302
  end
300
303
 
301
304
  end
@@ -3,15 +3,15 @@ require_relative '../types/cl_public_key.rb'
3
3
  require_relative '../utils/hex_utils.rb'
4
4
  require_relative '../utils/hash_utils.rb'
5
5
 
6
- CLPublicKeyTag = {
7
- ED25519: 1,
8
- SECP256K1: 2
9
- }
6
+ # CLPublicKeyTag = {
7
+ # ED25519: 1,
8
+ # SECP256K1: 2
9
+ # }
10
10
 
11
- SignatureAlgorithm = {
12
- Ed25519: 'ed25519',
13
- Secp256K1: 'secp256k1'
14
- }
11
+ # SignatureAlgorithm = {
12
+ # Ed25519: 'ed25519',
13
+ # Secp256K1: 'secp256k1'
14
+ # }
15
15
 
16
16
  class AsymmetricKey
17
17
  attr_reader :public_key, :private_key, :signature_algorithm
@@ -19,7 +19,8 @@ class AsymmetricKey
19
19
  # @param [CLPublicKey] public_key
20
20
  # @param [Array] private_key
21
21
  # @param [SignatureAlgorithm] signature_algorithm
22
- def initialize(public_key, private_key, signature_algorithm)
22
+ def initialize(public_key = CLPublicKey.new([204, 238, 25, 54, 110, 175, 3, 72, 124, 184, 17, 151, 174, 142, 220,
23
+ 177, 180, 127, 33, 76, 238, 0, 214, 89, 115, 128, 9, 107, 159, 132, 99, 193], 1), private_key = nil, signature_algorithm = nil)
23
24
  @public_key = public_key
24
25
  @private_key = private_key
25
26
  @signature_algorithm = signature_algorithm
@@ -49,15 +50,15 @@ class AsymmetricKey
49
50
  end
50
51
 
51
52
  # @return [Array<Integer>]
52
- def account_hash
53
- @tag = @public_key.get_cl_public_key_tag
54
- key_name = CLPublicKeyTag.key(@tag).to_s
55
- prefix = key_name.downcase.unpack("C*") + [0]
56
- bytes = prefix + @public_key.get_value
57
- result_array = Utils::HashUtils.byte_hash(bytes)
58
- @public_key.get_value.length == 0 ? [] : result_array
59
- #*** @public_key.to_account_hash_byte_array
60
- end
53
+ # def account_hash
54
+ # @tag = @public_key.get_cl_public_key_tag
55
+ # key_name = CLPublicKeyTag.key(@tag).to_s
56
+ # prefix = key_name.downcase.unpack("C*") + [0]
57
+ # bytes = prefix + @public_key.get_value
58
+ # result_array = Utils::HashUtils.byte_hash(bytes)
59
+ # @public_key.get_value.length == 0 ? [] : result_array
60
+ # #*** @public_key.to_account_hash_byte_array
61
+ # end
61
62
 
62
63
  # @param [String] path_to_private_key
63
64
  def create_from_private_key_file(path_to_private_key)
@@ -0,0 +1,114 @@
1
+ require 'ed25519'
2
+ require 'blake2b'
3
+ require 'chilkat'
4
+ signing_key = Ed25519::SigningKey.generate
5
+ # puts "signing_key:\t #{signing_key}"
6
+ # puts "seed:\t #{signing_key.seed}"
7
+ # puts "keypair:\t #{signing_key.keypair}"
8
+ # puts "verify_key:\t #{signing_key.verify_key}"
9
+ # serialized_deploy_to_hash = "dc7edd3dde249343bc379564724b3e30116d8d84702a589513728f2e09bcd167"
10
+ # signature = Ed25519.provider.sign("MC4CAQAwBQYDK2VwBCIEIKf7pd4LhteUsRPmagsm7by7YWZVM+thD/fWoP+QDZO7", serialized_deploy_to_hash)
11
+
12
+ # key = Blake2b::Key.none
13
+ # signature = "01" + Blake2b.hex(signature, key, 64)
14
+ # puts signature
15
+ # message = "hello"
16
+ # signature = signing_key.sign(message)
17
+ # puts "signature:\t #{signature}"
18
+
19
+ # verify_key = signing_key.verify_key
20
+ # puts "verify_key:\t #{verify_key}"
21
+
22
+ # check_validity_of_signature = verify_key.verify(signature, message)
23
+ # puts "check_validity_of_signature:\t #{check_validity_of_signature}"
24
+
25
+ # # Serializing Keys
26
+ # signature_key_bytes = signing_key.to_bytes
27
+ # puts "signature_key_bytes:\t #{signature_key_bytes}"
28
+ # verify_key_bytes = verify_key.to_bytes
29
+ # puts "verify_key_bytes:\t #{verify_key_bytes}"
30
+
31
+ # signing_key = Ed25519::SigningKey.new(signature_key_bytes)
32
+ # puts "signing_key:\t #{signing_key}"
33
+ # verify_key = Ed25519::VerifyKey.new(verify_key_bytes)
34
+ # puts "verify_key:\t #{verify_key}
35
+
36
+
37
+ #************************************************************************************************************
38
+
39
+
40
+ # Load an Ed25519 key
41
+ privKey = Chilkat::CkPrivateKey.new()
42
+
43
+ # Load an Ed25519 key from an unencrypted PEM file (no password required).
44
+ success = privKey.LoadAnyFormatFile("#{Dir.home}/Downloads/ed25519_secret_key.pem","")
45
+ if (success == false)
46
+ print privKey.lastErrorText() + "\n";
47
+ exit
48
+ end
49
+
50
+ # The key type should be "ed25519" to indicate an Ed25519 key.
51
+ print "key type = " + privKey.keyType() + "\n";
52
+ # key type = ed25519
53
+
54
+ # # What is the size of the private key in bits? (should always be 256 bits for Ed25519)
55
+ print "size in bits = " + privKey.get_BitLength().to_s() + "\n";
56
+ # size in bits = 256
57
+
58
+ # # Get the private and public key parts in raw hex format:
59
+ sbPubKeyHex = Chilkat::CkStringBuilder.new()
60
+ privKeyHex = privKey.getRawHex(sbPubKeyHex)
61
+
62
+ # # We should have a 32-byte private key (a 64 character hex string).
63
+ print "private key = " + privKeyHex + "\n";
64
+ # private key = a7fba5de0b86d794b113e66a0b26edbcbb61665533eb610ff7d6a0ff900d93bb
65
+
66
+ # # We should have a 32-byte public key (a 64 character hex string).
67
+ print "public key = " + sbPubKeyHex.getAsString() + "\n";
68
+ # public key = ccee19366eaf03487cb81197ae8edcb1b47f214cee00d6597380096b9f8463c1
69
+
70
+
71
+
72
+ # This example assumes the Chilkat API to have been previously unlocked.
73
+ # See Global Unlock Sample for sample code.
74
+
75
+ privKeyHex = "a7fba5de0b86d794b113e66a0b26edbcbb61665533eb610ff7d6a0ff900d93bb"
76
+ pubKeyHex = "ccee19366eaf03487cb81197ae8edcb1b47f214cee00d6597380096b9f8463c1"
77
+
78
+ privKey = Chilkat::CkPrivateKey.new()
79
+ # This example shows only one way of loading an Ed25519 private key.
80
+ # Chilkat can load other formats (JWK, PEM, ASN.1 DER, etc.)
81
+ # You may do so by calling LoadAnyFormat or LoadAnyFormatFile.
82
+ success = privKey.LoadEd25519(privKeyHex,pubKeyHex)
83
+ if (success == false)
84
+ print privKey.lastErrorText() + "\n";
85
+ exit
86
+ end
87
+
88
+ # The data to be signed...
89
+ bd = Chilkat::CkBinData.new()
90
+ deploy_hash = "633435d9660122917fd5b4de16b7f495959cd832b9ef293486c6893dc694ec26"
91
+ bd.AppendString(deploy_hash,"utf-8")
92
+ eddsa = Chilkat::CkEdDSA.new()
93
+ hexSig = eddsa.signBdENC(bd,"hexlower",privKey)
94
+
95
+ print "signature = " + "01" + hexSig + "\n";
96
+
97
+ # The expected output is: 016d49ac6138e556c9174c9c8e0d512bbb4697bbe3e96a28d8c1be83ea05c3a5945b6b87e4c974ae04e6cbcbac78bbbce672648444e269bdf30d27686fa03a440e
98
+
99
+ # # Verify the signature..
100
+ pubKey = Chilkat::CkPublicKey.new()
101
+ success = pubKey.LoadEd25519(pubKeyHex)
102
+ if (success == false)
103
+ print pubKey.lastErrorText() + "\n";
104
+ exit
105
+ end
106
+ puts pubKey
107
+ bVerified = eddsa.VerifyBdENC(bd,hexSig,"hexlower",pubKey)
108
+ if (bVerified == false)
109
+ print eddsa.lastErrorText() + "\n";
110
+ print "Failed to verify the signature." + "\n";
111
+ exit
112
+ end
113
+
114
+ print "The Ed25519 signature is verified!" + "\n";
@@ -1,23 +1,129 @@
1
1
  require 'openssl'
2
2
  require 'ed25519'
3
- require_relative './asymmetric_key.rb'
3
+ require 'blake2b'
4
+ require 'chilkat'
5
+
6
+ # CLPublicKeyTag = {
7
+ # ED25519: 1,
8
+ # SECP256K1: 2
9
+ # }
4
10
 
5
11
  # ED25519 private key length in bytes
6
12
  PRIVATE_KEY_LENGTH = 32
7
13
 
8
- class Ed25519Key < AsymmetricKey
14
+ class Ed25519Key
15
+ # attr_reader :public_key, :private_key, :signature_algorithm
16
+ attr_accessor :public_key_hex, :signature_algorithm, :privKey, :private_key_hex
17
+ # attr_reader :private_key_hex, :privKey
18
+ include Utils::HashUtils
19
+
20
+ def initialize()
21
+ # file_path = "#{Dir.home}/ed25519_secret_key.pem"
22
+ @file_path = "#{Dir.home}/ed25519_secret_key.pem"
23
+ @privKey = Chilkat::CkPrivateKey.new()
24
+
25
+ # This loads an Ed25519 key from an unencrypted PEM file (no password required).
26
+ success = @privKey.LoadAnyFormatFile(@file_path,"")
27
+ if (success == false)
28
+ print @privKey.lastErrorText() + "\n";
29
+ exit
30
+ end
31
+
32
+ @signature_algorithm = @privKey.keyType()
33
+
34
+ # 32-byte (256-bit)
35
+ @private_key_bit_length = @privKey.get_BitLength
36
+
37
+ # Get the private and public key parts in raw hex format
38
+ sbPubKeyHex = Chilkat::CkStringBuilder.new()
39
+
40
+ @private_key_hex = @privKey.getRawHex(sbPubKeyHex)
41
+
42
+ @public_key_hex = sbPubKeyHex.getAsString()
43
+
44
+ success = @privKey.LoadEd25519(@private_key_hex, @public_key_hex)
45
+ if (success == false)
46
+ print @privKey.lastErrorText() + "\n";
47
+ exit
48
+ end
49
+ end
50
+
51
+ def get_public_key
52
+ raise ArgumentError, "Expected a 64 character hex String" unless @public_key_hex.length == 64
53
+ return "01" + @public_key_hex
54
+ end
55
+
56
+ def get_private_key
57
+ raise ArgumentError, "Expected a 64 character hex String" unless @private_key_hex.length == 64
58
+ return @private_key_hex
59
+ end
60
+
61
+ # @return [String] an encoded string, as specified by the encoding argument.
62
+ def get_private_key_base_encoded_format(encoding)
63
+ # encoding can be "base64"
64
+ privKey.getPkcs1ENC(encoding)
65
+ end
66
+
67
+ def sign(message)
68
+ success = @privKey.LoadEd25519(@private_key_hex, @public_key_hex)
69
+ if (success == false)
70
+ print @privKey.lastErrorText() + "\n";
71
+ exit
72
+ end
73
+ @message = message
74
+ # @message = Utils::ByteUtils.hex_to_byte_array(@message)
75
+
76
+
77
+ byteData = Chilkat::CkByteData.new()
78
+ byteData.appendEncoded(@message, "hex");
79
+
80
+ @bd = Chilkat::CkBinData.new()
81
+ @bd.AppendBinary(byteData)
82
+
83
+ @signer = Chilkat::CkEdDSA.new()
84
+ @signature = @signer.signBdENC(@bd, "hexlower", @privKey)
85
+ if @signature_algorithm == "ed25519"
86
+ @prefix = "0#{CLPublicKeyTag[:ED25519]}"
87
+ @signature = @prefix + @signature
88
+ end
89
+ @signature
90
+ end
91
+
92
+ # Verify the signature
93
+ def verify(signature, message)
94
+ pubKey = Chilkat::CkPublicKey.new()
95
+ success = pubKey.LoadEd25519(@public_key_hex)
96
+ if (success == false)
97
+ print pubKey.lastErrorText() + "\n";
98
+ exit
99
+ end
100
+ # Remove prefix "01"
101
+ signature = signature[2...]
102
+ verified = @signer.VerifyBdENC(@bd, signature, "hex", pubKey);
103
+ if (verified == false)
104
+ print @signer.lastErrorText() + "\n";
105
+ print "Failed to verify the signature." + "\n";
106
+ exit
107
+ end
108
+ return true
9
109
 
10
- def initialize(public_key, private_key)
11
- super(public_key, private_key, SignatureAlgorithm[:Ed25519])
12
110
  end
13
111
 
112
+ def public_key
113
+ if @signature_algorithm == "ed25519" && @private_key_hex.length == 64
114
+ prefix = "01"
115
+ @public_key = prefix + @public_key_hex
116
+ end
117
+ end
118
+
119
+
14
120
  # @param [Array] public_key
15
121
  # @return [String]
16
122
  # def self.account_hex(public_key)
17
123
  # '01' + Utils::Base16.encode16(public_key)
18
124
  # end
19
125
 
20
-
126
+ # @param [String] private_key_path
21
127
  def create_from_private_key_file(private_key_path)
22
128
 
23
129
  end
@@ -28,11 +134,6 @@ class Ed25519Key < AsymmetricKey
28
134
  def export_private_key_in_pem
29
135
  end
30
136
 
31
- def sign(msg)
32
- end
33
-
34
- def verify(signature, msg)
35
- end
36
137
 
37
138
  def private_to_public_key(private_key)
38
139
  end