appchain.rb 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3cf165b17b0de81dc3dcc848600339523ad2e7920be7a4f620bdcca802d3525b
4
- data.tar.gz: 4067ce5f69b9e1b76c7143117ddd6d032348802b478e5afc953f53da722384b1
3
+ metadata.gz: dd176c97f662397947072cd9b6b08cb967cbc1ea171b44e5e2c9d4b348cd5e4a
4
+ data.tar.gz: 354f3c9e6dbad28a6d7e8a4c9053b942d11c889615e60903145d03daa879e1bb
5
5
  SHA512:
6
- metadata.gz: 839817784fd7e9351b8050e86d7c9353078a971c0d00bc7316f09fb928461ddc3359f05f082d420441f48a8034d559688d3c245424f4fe50cb0059256d6ab9bd
7
- data.tar.gz: 6fd4a13f92717af89484f62c05f2816e9e19d4521706ddfe4e1ed17540572c375b5358f4d4cce296f1d56ca5a5dc076503ca4038367652dbed49b3b99c494e04
6
+ metadata.gz: 57c287fc34a72b7b0fa5d51a859a11dcb37a69fa81455a659b75327ec42e0a0e5eebcddce7a90c9b256eaf7f29f3cf0fe9417d04013fccbb042296adb7c390df
7
+ data.tar.gz: 78cd56fc25a1ed429be686b1db3ae2b958b585e8aa3207b2ee40b95bf81b5fb4a679082c98dc4b8b0a4fa740450db7151a1d2f3d8a8363f892dbeba99416c2c3
@@ -3,9 +3,9 @@ sudo: false
3
3
  language: ruby
4
4
  cache: bundler
5
5
  rvm:
6
- - 2.4.4
7
- - 2.5.1
8
- before_install: gem install bundler -v 1.16.4
6
+ - 2.4.5
7
+ - 2.5.3
8
+ before_install: gem install bundler -v 1.16.6
9
9
  install:
10
10
  - cd secp256k1 && ./autogen.sh && ./configure --enable-module-recovery --enable-experimental --enable-module-ecdh && make && sudo make install && cd ..
11
11
  - bundle install
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- appchain.rb (0.1.0)
4
+ appchain.rb (0.2.0)
5
5
  activesupport (~> 5.2.1)
6
6
  ciri-crypto (= 0.1.1)
7
7
  faraday (~> 0.15.3)
@@ -33,7 +33,7 @@ GEM
33
33
  multipart-post (>= 1.2, < 3)
34
34
  ffi (1.9.25)
35
35
  google-protobuf (3.6.1-universal-darwin)
36
- i18n (1.1.0)
36
+ i18n (1.1.1)
37
37
  concurrent-ruby (~> 1.0)
38
38
  jaro_winkler (1.5.1)
39
39
  method_source (0.9.0)
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # AppChain.rb
2
2
 
3
3
  [![Build Status](https://travis-ci.org/cryptape/appchain.rb.svg?branch=master)](https://travis-ci.org/cryptape/appchain.rb)
4
+ [![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](https://www.rubydoc.info/github/cryptape/appchain.rb/master)
4
5
 
5
6
  Nervos AppChain Ruby SDK
6
7
 
@@ -44,8 +45,8 @@ transaction = AppChain::Transaction.new(
44
45
  valid_until_block: 1882078,
45
46
  data: "",
46
47
  value: "0x3e8",
47
- chain_id: 1,
48
- version: 0
48
+ chain_id: "1",
49
+ version: 1
49
50
  )
50
51
 
51
52
  # sign transaction with your private key
@@ -74,6 +75,18 @@ response = contract.call_func(method: :symbol)
74
75
  response = contract.send_func(tx: tx, private_key: private_key, method: :transfer, params: [address, tokens])
75
76
  ```
76
77
 
78
+ ## CHANGELOG
79
+
80
+ ### v0.1
81
+
82
+ * supports CITA 0.19
83
+
84
+ ### 0.2
85
+
86
+ * supports CITA 0.20 and 0.19
87
+ * set default transaction version to 1
88
+ * update TransactionSinger.decode output type to hash with symbol keys
89
+ * parse TransactionSinger.decode hash value to hex string if it's bytes.
77
90
 
78
91
  ## Contributing
79
92
 
@@ -40,7 +40,7 @@ module AppChain
40
40
  # @param tx [Hash] see rpc `call` doc for more info
41
41
  #
42
42
  # @return [any]
43
- def call_func(method:, params: [], tx: {})
43
+ def call_func(method:, params: [], tx: {}) # rubocop:disable Naming/UncommunicativeMethodParamName
44
44
  data, output_types = function_data_with_ot(method, *params)
45
45
  resp = @rpc.call_rpc(:call, params: [tx.merge(data: data, to: address), "latest"])
46
46
  result = resp["result"]
@@ -60,7 +60,7 @@ module AppChain
60
60
  # @param *params [Array] your params
61
61
  #
62
62
  # @return [nil | Hash] {hash: "", status: ""}, sendRawTransactionResult
63
- def send_func(tx:, private_key:, method:, params: [])
63
+ def send_func(tx:, private_key:, method:, params: []) # rubocop:disable Naming/UncommunicativeMethodParamName
64
64
  data, _output_types = function_data_with_ot(method, *params)
65
65
  transaction = if tx.is_a?(Hash)
66
66
  Transaction.from_hash(tx)
@@ -15,8 +15,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
15
15
  optional :state_root, :bytes, 4
16
16
  optional :transactions_root, :bytes, 5
17
17
  optional :receipts_root, :bytes, 6
18
- optional :gas_used, :uint64, 7
19
- optional :gas_limit, :uint64, 8
18
+ optional :quota_used, :uint64, 7
19
+ optional :quota_limit, :uint64, 8
20
20
  optional :proof, :message, 9, "Proof"
21
21
  optional :proposer, :bytes, 10
22
22
  end
@@ -25,8 +25,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
25
25
  optional :height, :uint64, 2
26
26
  end
27
27
  add_message "AccountGasLimit" do
28
- optional :common_gas_limit, :uint64, 1
29
- map :specific_gas_limit, :string, :uint64, 2
28
+ optional :common_quota_limit, :uint64, 1
29
+ map :specific_quota_limit, :string, :uint64, 2
30
30
  end
31
31
  add_message "RichStatus" do
32
32
  optional :hash, :bytes, 1
@@ -34,6 +34,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
34
34
  repeated :nodes, :bytes, 3
35
35
  optional :interval, :uint64, 4
36
36
  optional :version, :uint32, 5
37
+ repeated :validators, :bytes, 6
37
38
  end
38
39
  add_message "Transaction" do
39
40
  optional :to, :string, 1
@@ -44,6 +45,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
44
45
  optional :value, :bytes, 6
45
46
  optional :chain_id, :uint32, 7
46
47
  optional :version, :uint32, 8
48
+ optional :to_v1, :bytes, 9
49
+ optional :chain_id_v1, :bytes, 10
47
50
  end
48
51
  add_message "UnverifiedTransaction" do
49
52
  optional :transaction, :message, 1, "Transaction"
@@ -107,4 +110,3 @@ module AppChain::Protos
107
110
  ProofType = Google::Protobuf::DescriptorPool.generated_pool.lookup("ProofType").enummodule
108
111
  Crypto = Google::Protobuf::DescriptorPool.generated_pool.lookup("Crypto").enummodule
109
112
  end
110
-
@@ -70,8 +70,14 @@ module AppChain
70
70
  # @return [Hash]
71
71
  def transfer(to:, private_key:, value:, quota: 30_000)
72
72
  valid_until_block = block_number["result"].hex + 88
73
- chain_id = get_meta_data("latest").dig "result", "chainId"
74
- transaction = Transaction.new(nonce: Utils.nonce, valid_until_block: valid_until_block, chain_id: chain_id, to: to, value: value, quota: quota)
73
+ meta_data = get_meta_data("latest")["result"]
74
+ version = meta_data["version"]
75
+ chain_id = if version.zero?
76
+ meta_data["chainId"]
77
+ elsif version == 1
78
+ meta_data["chainIdV1"]
79
+ end
80
+ transaction = Transaction.new(nonce: Utils.nonce, valid_until_block: valid_until_block, chain_id: chain_id, to: to, value: value, quota: quota, version: version)
75
81
  send_transaction(transaction, private_key)
76
82
  end
77
83
  end
@@ -1,12 +1,16 @@
1
1
  # frozen_string_literal: true
2
+ require "active_support/core_ext/string"
2
3
 
3
4
  module AppChain
4
5
  class Transaction
6
+ class VersionError < StandardError
7
+ end
8
+
5
9
  attr_accessor :to, :nonce, :quota, :valid_until_block, :data, :value, :chain_id, :version
6
10
 
7
- # @param nonce [String]
11
+ # @param nonce [String] default is SecureRandom.hex; if you provide with nil or empty string, it will be assigned a random string.
8
12
  # @param valid_until_block [Integer]
9
- # @param chain_id [Integer]
13
+ # @param chain_id [Integer | String] hex string if version == 1
10
14
  # @param version [Integer]
11
15
  # @param to [String]
12
16
  # @param data [String]
@@ -14,13 +18,19 @@ module AppChain
14
18
  # @param quota [Integer]
15
19
  #
16
20
  # @return [void]
17
- def initialize(nonce:, valid_until_block:, chain_id:, version: 0, to: nil, data: nil, value: "0", quota: 1_000_000)
21
+ def initialize(valid_until_block:, chain_id:, nonce: nil, version: 1, to: nil, data: nil, value: "0", quota: 1_000_000) # rubocop:disable Metrics/ParameterLists
22
+ raise VersionError, "transaction version error, expected 0 or 1, got #{version}" unless [0, 1].include?(version)
23
+
18
24
  @to = to
19
- @nonce = nonce
25
+ @nonce = nonce.blank? ? SecureRandom.hex : nonce
20
26
  @quota = quota
21
27
  @valid_until_block = valid_until_block
22
28
  @data = data
23
- @chain_id = chain_id
29
+ @chain_id = if chain_id.is_a?(String)
30
+ chain_id.delete("-")
31
+ else
32
+ chain_id
33
+ end
24
34
  @version = version
25
35
  @value = if value.is_a?(Integer)
26
36
  Utils.to_hex(value)
@@ -38,7 +48,7 @@ module AppChain
38
48
  chain_id: h[:chain_id],
39
49
  to: h[:to],
40
50
  data: h[:data],
41
- version: h[:version] || 0,
51
+ version: h[:version] || 1,
42
52
  value: h[:value] || "0",
43
53
  quota: h[:quota] || 1_000_000
44
54
  )
@@ -13,16 +13,23 @@ module AppChain
13
13
  def encode(transaction, private_key)
14
14
  tx = AppChain::Protos::Transaction.new
15
15
 
16
- tx.nonce = transaction.nonce
17
16
  to = AppChain::Utils.remove_hex_prefix(transaction.to)&.downcase
18
- tx.to = to unless to.nil?
17
+
18
+ tx.nonce = transaction.nonce
19
19
  tx.quota = transaction.quota
20
20
  tx.data = AppChain::Utils.to_bytes(transaction.data)
21
+ tx.value = hex_to_bytes(transaction.value)
21
22
  tx.version = transaction.version
22
- tx.value = process_value(transaction.value)
23
- tx.chain_id = transaction.chain_id
24
23
  tx.valid_until_block = transaction.valid_until_block
25
24
 
25
+ if transaction.version.zero?
26
+ tx.to = to unless to.nil?
27
+ tx.chain_id = transaction.chain_id
28
+ elsif transaction.version == 1
29
+ tx.to_v1 = Utils.to_bytes(to) unless to.nil?
30
+ tx.chain_id_v1 = hex_to_bytes(transaction.chain_id)
31
+ end
32
+
26
33
  encoded_tx = Protos::Transaction.encode(tx)
27
34
 
28
35
  private_key_bytes = AppChain::Utils.to_bytes(private_key)
@@ -41,7 +48,7 @@ module AppChain
41
48
  # unsign transaction
42
49
  #
43
50
  # @param tx_content [String] hex string
44
- def decode(tx_content)
51
+ def simple_decode(tx_content)
45
52
  content_bytes = AppChain::Utils.to_bytes(tx_content)
46
53
  unverified_transaction = Protos::UnverifiedTransaction.decode(content_bytes)
47
54
 
@@ -57,22 +64,73 @@ module AppChain
57
64
  from_address_hex = Utils.from_bytes(from_address)
58
65
 
59
66
  sender = {
60
- "address" => from_address_hex,
61
- "public_key" => pubkey_hex
67
+ address: from_address_hex,
68
+ public_key: pubkey_hex
62
69
  }
63
70
 
64
71
  {
65
- "unverified_transaction" => unverified_transaction,
66
- "sender" => sender
72
+ unverified_transaction: unverified_transaction.to_h,
73
+ sender: sender
67
74
  }
68
75
  end
69
76
 
77
+ # decode and support forks
78
+ #
79
+ # @param tx_content [String] hex string
80
+ # @return [Hash]
81
+ def original_decode(tx_content)
82
+ data = simple_decode(tx_content)
83
+ utx = data[:unverified_transaction]
84
+ tx = utx[:transaction]
85
+ version = tx[:version]
86
+
87
+ if version == 0 # rubocop:disable Style/NumericPredicate
88
+ tx.delete(:to_v1)
89
+ tx.delete(:chain_id_v1)
90
+ elsif version == 1
91
+ tx[:to] = tx.delete(:to_v1)
92
+ tx[:chain_id] = tx.delete(:chain_id_v1)
93
+ else
94
+ raise Transaction::VersionError, "transaction version error, expected 0 or 1, got #{version}"
95
+ end
96
+
97
+ data
98
+ end
99
+
100
+ # decode and parse bytes to hex string
101
+ #
102
+ # @param tx_content [String] hex string
103
+ # @return [Hash]
104
+ def decode(tx_content)
105
+ data = original_decode(tx_content)
106
+ utx = data[:unverified_transaction]
107
+ tx = utx[:transaction]
108
+ version = tx[:version]
109
+
110
+ tx[:value] = Utils.from_bytes(tx[:value])
111
+ tx[:data] = Utils.from_bytes(tx[:data])
112
+ tx[:nonce] = Utils.add_prefix_for_not_blank(tx[:nonce])
113
+ utx[:signature] = Utils.from_bytes(utx[:signature])
114
+
115
+ if version == 0 # rubocop:disable Style/NumericPredicate
116
+ tx.delete(:to_v1)
117
+ tx.delete(:chain_id_v1)
118
+ tx[:to] = Utils.add_prefix_for_not_blank(tx[:to])
119
+ elsif version == 1
120
+ tx[:to] = Utils.from_bytes(tx[:to])
121
+ tx[:chain_id] = Utils.from_bytes(tx[:chain_id])
122
+ end
123
+
124
+ data
125
+ end
126
+
70
127
  private
71
128
 
72
129
  # @param value [String] hex string with or without `0x` prefix
130
+ # @param length [Integer] length, default is 64
73
131
  # @return [String] byte code string
74
- def process_value(value)
75
- AppChain::Utils.to_bytes(AppChain::Utils.remove_hex_prefix(value).rjust(64, "0"))
132
+ def hex_to_bytes(value, length = 64)
133
+ AppChain::Utils.to_bytes(AppChain::Utils.remove_hex_prefix(value).rjust(length, "0"))
76
134
  end
77
135
  end
78
136
  end
@@ -15,6 +15,15 @@ module AppChain
15
15
  HEX_PREFIX + hex
16
16
  end
17
17
 
18
+ # add `0x` prefix to not blank hex string
19
+ #
20
+ # @param hex [String]
21
+ def add_prefix_for_not_blank(hex)
22
+ return add_hex_prefix(hex) unless hex.blank?
23
+
24
+ hex
25
+ end
26
+
18
27
  # remove `0x` prefix from hex string
19
28
  #
20
29
  # @param hex [String]
@@ -55,7 +64,10 @@ module AppChain
55
64
  # @param bytes_str [String] byte code string
56
65
  # @return [String] normal string
57
66
  def from_bytes(bytes_str)
58
- AppChain::Utils.add_hex_prefix(bytes_str.unpack1("H*"))
67
+ hex = bytes_str.unpack1("H*")
68
+ return AppChain::Utils.add_hex_prefix(hex) unless hex.blank?
69
+
70
+ hex
59
71
  end
60
72
 
61
73
  # keccak 256 hash
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppChain
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appchain.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - classicalliu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-26 00:00:00.000000000 Z
11
+ date: 2018-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -219,7 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
219
  version: '0'
220
220
  requirements: []
221
221
  rubyforge_project:
222
- rubygems_version: 2.7.6
222
+ rubygems_version: 2.7.7
223
223
  signing_key:
224
224
  specification_version: 4
225
225
  summary: Ruby Nervos AppChain SDK