glueby 1.1.2 → 1.2.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf5bddcac51622b30df3af390b3755b5f98509cb890a4d7505b60bc08b44f896
4
- data.tar.gz: 7e456329486fe6f1bef94899827c59a56ae9f6e327fc6149170cb84adb104965
3
+ metadata.gz: 7615df66be0078e89e4ed0aedd30bcfdb45b86ad9eac3c67fd9d6b65b93e9276
4
+ data.tar.gz: ca247aec2c3951be9b294055d43dbe042bebd1d435d5e05dd763e11152bc355b
5
5
  SHA512:
6
- metadata.gz: '0849f5053fe790bbdbeb4e81829ced6597af38c9dea55c94ab07c2d1e7ce767f064a607451b575d30f5fd2cad8e2155d9de300dfdca9f72abaf0f62f446831a1'
7
- data.tar.gz: e1513b7c30d6a3b1c807b3150d4b22c46615fa41167cc2b0e33a14489599811b71cfef5c875e2fdf98ed4ec6f73c360e41b4250787be66371e74bfc2de843c39
6
+ metadata.gz: 92d9640a75627b4513729a96b870d7b056a1f09ef5716bbcc708a6bc60b04ceea786963569792810a40acceb5f8e2eeb318a07a059b4d1e7e606f83119b68919
7
+ data.tar.gz: f035ad6414ae3bf17a8cab97ea1c90a5ab3effbd9e876165151a786846080a619c979bc8f211371488adf4d383d5c5719235c9ece38c07949d8db0c2623ccfe2
@@ -9,19 +9,19 @@ name: Ruby
9
9
 
10
10
  on:
11
11
  push:
12
- branches: [master, v1.1]
12
+ branches: [master, v1.1, v1.2]
13
13
  pull_request:
14
- branches: [master, v1.1]
14
+ branches: [master, v1.1, v1.2]
15
15
 
16
16
  jobs:
17
17
  test:
18
18
  runs-on: ubuntu-latest
19
19
  strategy:
20
20
  matrix:
21
- ruby-version: ["2.6", "2.7", "3.0", "3.1"]
21
+ ruby-version: ["2.7", "3.0", "3.1", "3.2"]
22
22
 
23
23
  steps:
24
- - run: docker pull tapyrus/tapyrusd:v0.5.1
24
+ - run: docker pull tapyrus/tapyrusd:v0.5.2
25
25
  - uses: actions/checkout@v2
26
26
  - name: Set up Ruby
27
27
  # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-3.0.0
1
+ ruby-3.2.2
data/README.md CHANGED
@@ -72,7 +72,7 @@ Or install it yourself as:
72
72
 
73
73
  Starts tapryusd container
74
74
 
75
- $ docker run -d --name 'tapyrus_node_dev' -p 12381:12381 -e GENESIS_BLOCK_WITH_SIG='0100000000000000000000000000000000000000000000000000000000000000000000002b5331139c6bc8646bb4e5737c51378133f70b9712b75548cb3c05f9188670e7440d295e7300c5640730c4634402a3e66fb5d921f76b48d8972a484cc0361e66ef74f45e012103af80b90d25145da28c583359beb47b21796b2fe1a23c1511e443e7a64dfdb27d40e05f064662d6b9acf65ae416379d82e11a9b78cdeb3a316d1057cd2780e3727f70a61f901d10acbe349cd11e04aa6b4351e782c44670aefbe138e99a5ce75ace01010000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a010000001976a91445d405b9ed450fec89044f9b7a99a4ef6fe2cd3f88ac00000000' tapyrus/tapyrusd:v0.5.1
75
+ $ docker run -d --name 'tapyrus_node_dev' -p 12381:12381 -e GENESIS_BLOCK_WITH_SIG='0100000000000000000000000000000000000000000000000000000000000000000000002b5331139c6bc8646bb4e5737c51378133f70b9712b75548cb3c05f9188670e7440d295e7300c5640730c4634402a3e66fb5d921f76b48d8972a484cc0361e66ef74f45e012103af80b90d25145da28c583359beb47b21796b2fe1a23c1511e443e7a64dfdb27d40e05f064662d6b9acf65ae416379d82e11a9b78cdeb3a316d1057cd2780e3727f70a61f901d10acbe349cd11e04aa6b4351e782c44670aefbe138e99a5ce75ace01010000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a010000001976a91445d405b9ed450fec89044f9b7a99a4ef6fe2cd3f88ac00000000' tapyrus/tapyrusd:v0.5.2
76
76
 
77
77
  4. Modify the glueby configuration
78
78
 
data/glueby.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.description = %q{A Ruby library of smart contracts that can be used on Tapyrus.}
11
11
  spec.homepage = "https://github.com/chaintope/glueby"
12
12
  spec.license = "MIT"
13
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
14
14
 
15
15
 
16
16
  spec.metadata["homepage_uri"] = spec.homepage
@@ -27,8 +27,8 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ["lib"]
28
28
 
29
29
  spec.add_runtime_dependency 'tapyrus', '>= 0.3.1'
30
- spec.add_runtime_dependency 'activerecord', '~> 6.1.3'
30
+ spec.add_runtime_dependency 'activerecord', '~> 7.0.0'
31
31
  spec.add_development_dependency 'sqlite3'
32
32
  spec.add_development_dependency 'mysql2'
33
- spec.add_development_dependency 'rails', '~> 6.1.3'
33
+ spec.add_development_dependency 'rails', '~> 7.0.0'
34
34
  end
@@ -1,8 +1,8 @@
1
- # Edit configuration for connection to tapyrus core
2
- Glueby.configure do |config|
3
- config.wallet_adapter = :activerecord
4
- config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
5
- end
6
-
7
- # Uncomment next line when using timestamp feature
8
- # Glueby::BlockSyncer.register_syncer(Glueby::Contract::Timestamp::Syncer)
1
+ # Edit configuration for connection to tapyrus core
2
+ Glueby.configure do |config|
3
+ config.wallet_adapter = :activerecord
4
+ config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
5
+ end
6
+
7
+ # Uncomment next line when using timestamp feature
8
+ # Glueby::BlockSyncer.register_syncer(Glueby::Contract::Timestamp::Syncer)
@@ -1,16 +1,16 @@
1
- class CreateKey < ActiveRecord::Migration<%= migration_version %>
2
- def change
3
- create_table :glueby_keys<%= table_options %> do |t|
4
- t.string :private_key
5
- t.string :public_key
6
- t.string :script_pubkey
7
- t.string :label, index: true
8
- t.integer :purpose
9
- t.belongs_to :wallet
10
- t.timestamps
11
- end
12
-
13
- add_index :glueby_keys, [:script_pubkey], unique: true
14
- add_index :glueby_keys, [:private_key], unique: true
15
- end
16
- end
1
+ class CreateKey < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ create_table :glueby_keys<%= table_options %> do |t|
4
+ t.string :private_key
5
+ t.string :public_key
6
+ t.string :script_pubkey
7
+ t.string :label, index: true
8
+ t.integer :purpose
9
+ t.belongs_to :wallet
10
+ t.timestamps
11
+ end
12
+
13
+ add_index :glueby_keys, [:script_pubkey], unique: true
14
+ add_index :glueby_keys, [:private_key], unique: true
15
+ end
16
+ end
@@ -1,98 +1,98 @@
1
- module Glueby
2
- # You can use BlockSyncer when you need to synchronize the state of
3
- # an application with the state of a blockchain. When BlockSyncer
4
- # detects the generation of a new block, it executes the registered
5
- # syncer code on a block-by-block or transaction-by-transaction basis.
6
- # By using this, an application can detect that the issued transaction
7
- # has been captured in blocks, receive a new remittance, and so on.
8
- #
9
- # # Syncer logic registration
10
- #
11
- # For registration, create a class that implements the method that performs
12
- # synchronization processing and registers it in BlockSyncer. Implement
13
- # methods with the following name in that class.
14
- #
15
- # Method name | Arguments | Call conditions
16
- # ------------------ | --------------------- | ------------------------------
17
- # block_sync (block) | block: Tapyrus::Block | When a new block is created
18
- # block_tx (tx) | tx: Tapyrus::Tx | When a new block is created, it is executed for each tx contained in that block.
19
- #
20
- # @example Register a synchronous logic
21
- # class Syncer
22
- # def block_sync (block)
23
- # # sync a block
24
- # end
25
- #
26
- # def tx_sync (tx)
27
- # # sync a tx
28
- # end
29
- # end
30
- # BlockSyncer.register_syncer(Syncer)
31
- #
32
- # @example Unregister the synchronous logic
33
- # BlockSyncer.unregister_syncer(Syncer)
34
- #
35
- # # Run BlockSyncer
36
- #
37
- # Run the `glueby: block_syncer: start` rake task periodically with a program
38
- # for periodic execution such as cron. If it detects the generation of a new
39
- # block when it is executed, the synchronization process will be executed.
40
- # Determine the execution interval according to the requirements of the application.
41
- class BlockSyncer
42
- # @!attribute [r] height
43
- # @return [Integer] The block height to be synced
44
- attr_reader :height
45
-
46
- class << self
47
- # @!attribute r syncers
48
- # @return [Array<Class>] The syncer classes that is registered
49
- attr_reader :syncers
50
-
51
- # Register syncer class
52
- # @param [Class] syncer The syncer to be registered.
53
- def register_syncer(syncer)
54
- @syncers ||= []
55
- @syncers << syncer
56
- end
57
-
58
- # Unregister syncer class
59
- # @param [Class] syncer The syncer to be unregistered.
60
- def unregister_syncer(syncer)
61
- @syncers ||= []
62
- @syncers.delete(syncer)
63
- end
64
- end
65
-
66
- # @param [Integer] height The block height to be synced in the instance
67
- def initialize(height)
68
- @height = height
69
- end
70
-
71
- # Run a block synchronization
72
- def run
73
- return if self.class.syncers.nil?
74
-
75
- self.class.syncers.each do |syncer|
76
- instance = syncer.new
77
- instance.block_sync(block) if instance.respond_to?(:block_sync)
78
-
79
- if instance.respond_to?(:tx_sync)
80
- block.transactions.each { |tx| instance.tx_sync(tx) }
81
- end
82
- end
83
- end
84
-
85
- private
86
-
87
- def block
88
- @block ||= begin
89
- block = Glueby::Internal::RPC.client.getblock(block_hash, 0)
90
- Tapyrus::Block.parse_from_payload(block.htb)
91
- end
92
- end
93
-
94
- def block_hash
95
- @block_hash ||= Glueby::Internal::RPC.client.getblockhash(height)
96
- end
97
- end
1
+ module Glueby
2
+ # You can use BlockSyncer when you need to synchronize the state of
3
+ # an application with the state of a blockchain. When BlockSyncer
4
+ # detects the generation of a new block, it executes the registered
5
+ # syncer code on a block-by-block or transaction-by-transaction basis.
6
+ # By using this, an application can detect that the issued transaction
7
+ # has been captured in blocks, receive a new remittance, and so on.
8
+ #
9
+ # # Syncer logic registration
10
+ #
11
+ # For registration, create a class that implements the method that performs
12
+ # synchronization processing and registers it in BlockSyncer. Implement
13
+ # methods with the following name in that class.
14
+ #
15
+ # Method name | Arguments | Call conditions
16
+ # ------------------ | --------------------- | ------------------------------
17
+ # block_sync (block) | block: Tapyrus::Block | When a new block is created
18
+ # block_tx (tx) | tx: Tapyrus::Tx | When a new block is created, it is executed for each tx contained in that block.
19
+ #
20
+ # @example Register a synchronous logic
21
+ # class Syncer
22
+ # def block_sync (block)
23
+ # # sync a block
24
+ # end
25
+ #
26
+ # def tx_sync (tx)
27
+ # # sync a tx
28
+ # end
29
+ # end
30
+ # BlockSyncer.register_syncer(Syncer)
31
+ #
32
+ # @example Unregister the synchronous logic
33
+ # BlockSyncer.unregister_syncer(Syncer)
34
+ #
35
+ # # Run BlockSyncer
36
+ #
37
+ # Run the `glueby: block_syncer: start` rake task periodically with a program
38
+ # for periodic execution such as cron. If it detects the generation of a new
39
+ # block when it is executed, the synchronization process will be executed.
40
+ # Determine the execution interval according to the requirements of the application.
41
+ class BlockSyncer
42
+ # @!attribute [r] height
43
+ # @return [Integer] The block height to be synced
44
+ attr_reader :height
45
+
46
+ class << self
47
+ # @!attribute r syncers
48
+ # @return [Array<Class>] The syncer classes that is registered
49
+ attr_reader :syncers
50
+
51
+ # Register syncer class
52
+ # @param [Class] syncer The syncer to be registered.
53
+ def register_syncer(syncer)
54
+ @syncers ||= []
55
+ @syncers << syncer
56
+ end
57
+
58
+ # Unregister syncer class
59
+ # @param [Class] syncer The syncer to be unregistered.
60
+ def unregister_syncer(syncer)
61
+ @syncers ||= []
62
+ @syncers.delete(syncer)
63
+ end
64
+ end
65
+
66
+ # @param [Integer] height The block height to be synced in the instance
67
+ def initialize(height)
68
+ @height = height
69
+ end
70
+
71
+ # Run a block synchronization
72
+ def run
73
+ return if self.class.syncers.nil?
74
+
75
+ self.class.syncers.each do |syncer|
76
+ instance = syncer.new
77
+ instance.block_sync(block) if instance.respond_to?(:block_sync)
78
+
79
+ if instance.respond_to?(:tx_sync)
80
+ block.transactions.each { |tx| instance.tx_sync(tx) }
81
+ end
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def block
88
+ @block ||= begin
89
+ block = Glueby::Internal::RPC.client.getblock(block_hash, 0)
90
+ Tapyrus::Block.parse_from_payload(block.htb)
91
+ end
92
+ end
93
+
94
+ def block_hash
95
+ @block_hash ||= Glueby::Internal::RPC.client.getblockhash(height)
96
+ end
97
+ end
98
98
  end
@@ -99,9 +99,6 @@ module Glueby
99
99
  funding_tx, tx, p2c_address, payment_base = create_txs(fee_estimator, utxo_provider)
100
100
 
101
101
  if funding_tx
102
- ::ActiveRecord::Base.transaction(joinable: false, requires_new: true) do
103
- wallet.internal_wallet.broadcast(funding_tx)
104
- end
105
102
  logger.info("funding tx was broadcasted(id=#{id}, funding_tx.txid=#{funding_tx.txid})")
106
103
  end
107
104
  ::ActiveRecord::Base.transaction(joinable: false, requires_new: true) do
@@ -29,28 +29,23 @@ module Glueby
29
29
  # => 10_000
30
30
  #
31
31
  class Payment
32
- extend Glueby::Contract::TxBuilder
33
-
34
32
  class << self
35
33
  def transfer(sender:, receiver_address:, amount:, fee_estimator: FeeEstimator::Fixed.new)
36
34
  raise Glueby::Contract::Errors::InvalidAmount unless amount.positive?
37
35
 
38
- tx = Tapyrus::Tx.new
39
- dummy_fee = fee_estimator.fee(FeeEstimator.dummy_tx(tx))
40
-
41
- sum, outputs = sender.internal_wallet.collect_uncolored_outputs(dummy_fee + amount)
42
- fill_input(tx, outputs)
43
-
44
- receiver_script = Tapyrus::Script.parse_from_addr(receiver_address)
45
- tx.outputs << Tapyrus::TxOut.new(value: amount, script_pubkey: receiver_script)
46
-
47
- fee = fee_estimator.fee(tx)
36
+ txb = Internal::ContractBuilder.new(
37
+ sender_wallet: sender.internal_wallet,
38
+ fee_estimator: fee_estimator
39
+ )
48
40
 
49
- fill_change_tpc(tx, sender, sum - fee - amount)
41
+ _sum, outputs = sender.internal_wallet.collect_uncolored_outputs(txb.dummy_fee + amount)
42
+ outputs.each do |utxo|
43
+ txb.add_utxo(utxo)
44
+ end
50
45
 
51
- tx = sender.internal_wallet.sign_tx(tx)
46
+ txb.pay(receiver_address, amount)
52
47
 
53
- sender.internal_wallet.broadcast(tx)
48
+ sender.internal_wallet.broadcast(txb.build)
54
49
  end
55
50
  end
56
51
  end
@@ -4,21 +4,18 @@ module Glueby
4
4
  module TxBuilder
5
5
  # The simple Timestamp method
6
6
  class Simple
7
- include Glueby::Contract::TxBuilder
8
-
9
- attr_reader :funding_tx
10
-
11
7
  def initialize(wallet, fee_estimator)
12
8
  @wallet = wallet
13
9
  @fee_estimator = fee_estimator
14
10
 
15
- @txb = Tapyrus::TxBuilder.new
16
- @prev_txs = []
11
+ @txb = Internal::ContractBuilder.new(
12
+ sender_wallet: @wallet.internal_wallet,
13
+ fee_estimator: @fee_estimator
14
+ )
17
15
  end
18
16
 
19
17
  def build
20
- @txb.fee(fee).change_address(@wallet.internal_wallet.change_address)
21
- sign_tx
18
+ @txb.build
22
19
  end
23
20
 
24
21
  def set_data(prefix, data)
@@ -35,64 +32,29 @@ module Glueby
35
32
 
36
33
  def set_inputs(utxo_provider)
37
34
  if utxo_provider
38
- script_pubkey = Tapyrus::Script.parse_from_addr(@wallet.internal_wallet.receive_address)
39
- @funding_tx, index = utxo_provider.get_utxo(script_pubkey, fee)
40
-
41
- utxo = {
42
- script_pubkey: @funding_tx.outputs[index].script_pubkey.to_hex,
43
- txid: @funding_tx.txid,
44
- vout: index,
45
- amount: funding_tx.outputs[index].value
46
- }
47
-
48
- @txb.add_utxo(to_tapyrusrb_utxo_hash(utxo))
49
- @prev_txs << to_sign_tx_utxo_hash(utxo)
35
+ @txb.add_utxo_to!(
36
+ address: @wallet.internal_wallet.receive_address,
37
+ amount: input_amount,
38
+ utxo_provider: utxo_provider
39
+ )
50
40
  else
41
+ fee = input_amount
42
+ return self if fee == 0
43
+
51
44
  _, outputs = @wallet.internal_wallet.collect_uncolored_outputs(fee)
52
- outputs.each do |utxo|
53
- @txb.add_utxo(to_tapyrusrb_utxo_hash(utxo))
54
- end
45
+ outputs.each { |utxo| @txb.add_utxo(utxo) }
55
46
  end
56
47
  self
57
48
  end
58
49
 
59
- private
60
-
61
- def fee
62
- @fee ||= @fee_estimator.fee(FeeEstimator.dummy_tx(@txb.build))
63
- end
64
-
65
- def sign_tx
66
- # General signing process skips signing to p2c inputs because no key of the p2c address in the wallet.
67
- @wallet.internal_wallet.sign_tx(@txb.build, @prev_txs)
50
+ def funding_tx
51
+ @txb.prev_txs.first
68
52
  end
69
53
 
70
- # @param utxo
71
- # @option utxo [String] :txid The txid
72
- # @option utxo [Integer] :vout The index of the output in the tx
73
- # @option utxo [Integer] :amount The value of the output
74
- # @option utxo [String] :script_pubkey The hex string of the script pubkey
75
- def to_tapyrusrb_utxo_hash(utxo)
76
- {
77
- script_pubkey: Tapyrus::Script.parse_from_payload(utxo[:script_pubkey].htb),
78
- txid: utxo[:txid],
79
- index: utxo[:vout],
80
- value: utxo[:amount]
81
- }
82
- end
54
+ private
83
55
 
84
- # @param utxo
85
- # @option utxo [String] :txid The txid
86
- # @option utxo [Integer] :vout The index of the output in the tx
87
- # @option utxo [Integer] :amount The value of the output
88
- # @option utxo [String] :script_pubkey The hex string of the script pubkey
89
- def to_sign_tx_utxo_hash(utxo)
90
- {
91
- scriptPubKey: utxo[:script_pubkey],
92
- txid: utxo[:txid],
93
- vout: utxo[:vout],
94
- amount: utxo[:amount]
95
- }
56
+ def input_amount
57
+ @txb.dummy_fee
96
58
  end
97
59
  end
98
60
  end
@@ -16,6 +16,12 @@ module Glueby
16
16
  @txb.pay(p2c_address, P2C_DEFAULT_VALUE)
17
17
  self
18
18
  end
19
+
20
+ private
21
+
22
+ def input_amount
23
+ super + P2C_DEFAULT_VALUE
24
+ end
19
25
  end
20
26
  end
21
27
  end
@@ -8,11 +8,12 @@ module Glueby
8
8
  @prev_payment_base = payment_base
9
9
  @prev_prefix = prefix
10
10
  @prev_data = data
11
- @txb.add_utxo(to_tapyrusrb_utxo_hash(@prev_timestamp_utxo))
11
+ @txb.add_utxo(@prev_timestamp_utxo)
12
12
  end
13
13
 
14
- def sign_tx
14
+ def build
15
15
  tx = super
16
+
16
17
  # Generates signature for the remain p2c input.
17
18
  @wallet.internal_wallet.sign_to_pay_to_contract_address(
18
19
  tx,