glueby 0.4.4 → 0.5.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.
data/glueby.gemspec CHANGED
@@ -1,33 +1,33 @@
1
- require_relative 'lib/glueby/version'
2
-
3
- Gem::Specification.new do |spec|
4
- spec.name = "glueby"
5
- spec.version = Glueby::VERSION
6
- spec.authors = ["azuchi"]
7
- spec.email = ["azuchi@chaintope.com"]
8
-
9
- spec.summary = %q{A Ruby library of smart contracts that can be used on Tapyrus.}
10
- spec.description = %q{A Ruby library of smart contracts that can be used on Tapyrus.}
11
- spec.homepage = "https://github.com/chaintope/glueby"
12
- spec.license = "MIT"
13
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
-
15
-
16
- spec.metadata["homepage_uri"] = spec.homepage
17
- spec.metadata["source_code_uri"] = "https://github.com/chaintope/glueby"
18
- spec.metadata["changelog_uri"] = "https://github.com/chaintope/glueby"
19
-
20
- # Specify which files should be added to the gem when it is released.
21
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
- end
25
- spec.bindir = "exe"
26
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
- spec.require_paths = ["lib"]
28
-
29
- spec.add_runtime_dependency 'tapyrus', '>= 0.2.9'
30
- spec.add_runtime_dependency 'activerecord', '~> 6.1.3'
31
- spec.add_development_dependency 'sqlite3'
32
- spec.add_development_dependency 'rails', '~> 6.1.3'
33
- end
1
+ require_relative 'lib/glueby/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "glueby"
5
+ spec.version = Glueby::VERSION
6
+ spec.authors = ["azuchi"]
7
+ spec.email = ["azuchi@chaintope.com"]
8
+
9
+ spec.summary = %q{A Ruby library of smart contracts that can be used on Tapyrus.}
10
+ spec.description = %q{A Ruby library of smart contracts that can be used on Tapyrus.}
11
+ spec.homepage = "https://github.com/chaintope/glueby"
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
+
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/chaintope/glueby"
18
+ spec.metadata["changelog_uri"] = "https://github.com/chaintope/glueby"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_runtime_dependency 'tapyrus', '>= 0.2.9'
30
+ spec.add_runtime_dependency 'activerecord', '~> 6.1.3'
31
+ spec.add_development_dependency 'sqlite3'
32
+ spec.add_development_dependency 'rails', '~> 6.1.3'
33
+ 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,16 +1,16 @@
1
- class CreateUtxo < ActiveRecord::Migration<%= migration_version %>
2
- def change
3
- create_table :glueby_utxos<%= table_options %> do |t|
4
- t.string :txid
5
- t.integer :index
6
- t.bigint :value
7
- t.string :script_pubkey
8
- t.string :label, index: true
9
- t.integer :status
10
- t.belongs_to :key, null: true
11
- t.timestamps
12
- end
13
-
14
- add_index :glueby_utxos, [:txid, :index], unique: true
15
- end
16
- end
1
+ class CreateUtxo < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ create_table :glueby_utxos<%= table_options %> do |t|
4
+ t.string :txid
5
+ t.integer :index
6
+ t.bigint :value
7
+ t.string :script_pubkey
8
+ t.string :label, index: true
9
+ t.integer :status
10
+ t.belongs_to :key, null: true
11
+ t.timestamps
12
+ end
13
+
14
+ add_index :glueby_utxos, [:txid, :index], 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
@@ -10,11 +10,17 @@ module Glueby
10
10
  # end
11
11
  class Configuration
12
12
 
13
- attr_reader :fee_provider_bears
13
+ attr_reader :fee_provider_bears, :use_utxo_provider
14
14
  alias_method :fee_provider_bears?, :fee_provider_bears
15
+ alias_method :use_utxo_provider?, :use_utxo_provider
16
+
17
+ module Errors
18
+ class InvalidConfiguration < StandardError; end
19
+ end
15
20
 
16
21
  def initialize
17
22
  @fee_provider_bears = false
23
+ @use_utxo_provider = false
18
24
  end
19
25
 
20
26
  # Specify wallet adapter.
@@ -54,9 +60,27 @@ module Glueby
54
60
  # Specify FeeProvider configuration.
55
61
  # @param [Hash] config
56
62
  # @option config [Integer] :fixed_fee - The fee that Fee Provider pays on each transaction.
57
- # @option config [Integer] :utxo_pool_size - Fee Provider tries to keep the number of utxo in utxo pool as this size using `glueby:fee_provider:manage_utxo_pool` rake task
63
+ # @option config [Integer] :utxo_pool_size - Fee Provider tries to keep the number of utxo in utxo pool as this size using `glueby:fee_provider:manage_utxo_pool` rake task. this size should not be greater than 2000.
58
64
  def fee_provider_config=(config)
59
65
  FeeProvider.configure(config)
60
66
  end
67
+
68
+ # Enable UtxoProvider feature
69
+ def enable_utxo_provider!
70
+ @use_utxo_provider = true
71
+ end
72
+
73
+ # Disable UtxoProvider feature
74
+ def disable_utxo_provider!
75
+ @use_utxo_provider = false
76
+ end
77
+
78
+ # Set UtxoProvider configuration
79
+ # @param [Hash] config
80
+ # @option config [Integer] :default_value - The fee that Fee Provider pays on each transaction.
81
+ # @option config [Integer] :utxo_pool_size - Utxo Provider tries to keep the number of utxo in utxo pool as this size using `glueby:utxo_provider:manage_utxo_pool` rake task. this size should not be greater than 2000.
82
+ def utxo_provider_config=(config)
83
+ UtxoProvider.configure(config)
84
+ end
61
85
  end
62
86
  end
@@ -1,13 +1,13 @@
1
- module Glueby
2
- module Contract
3
- class Timestamp
4
- class Syncer
5
- def block_sync(block)
6
- Glueby::Contract::AR::Timestamp
7
- .where(txid: block.transactions.map(&:txid), status: :unconfirmed)
8
- .update_all(status: :confirmed)
9
- end
10
- end
11
- end
12
- end
13
- end
1
+ module Glueby
2
+ module Contract
3
+ class Timestamp
4
+ class Syncer
5
+ def block_sync(block)
6
+ Glueby::Contract::AR::Timestamp
7
+ .where(txid: block.transactions.map(&:txid), status: :unconfirmed)
8
+ .update_all(status: :confirmed)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,102 +1,108 @@
1
- module Glueby
2
- module Contract
3
- # Timestamp feature allows users to send transaction with op_return output which has sha256 hash of arbitary data.
4
- # Timestamp transaction has
5
- # * 1 or more inputs enough to afford transaction fee.
6
- # * 1 output which has op_return, application specific prefix, and sha256 hash of data.
7
- # * 1 output to send the change TPC back to the wallet.
8
- #
9
- # Storing timestamp transaction to the blockchain enables everyone to verify that the data existed at that time and a user signed it.
10
- class Timestamp
11
- include Glueby::Contract::TxBuilder
12
-
13
- autoload :Syncer, 'glueby/contract/timestamp/syncer'
14
-
15
- module Util
16
- include Glueby::Internal::Wallet::TapyrusCoreWalletAdapter::Util
17
- module_function
18
-
19
- def create_tx(wallet, prefix, data, fee_estimator)
20
- tx = Tapyrus::Tx.new
21
- tx.outputs << Tapyrus::TxOut.new(value: 0, script_pubkey: create_script(prefix, data))
22
-
23
- fee = fee_estimator.fee(dummy_tx(tx))
24
- sum, outputs = wallet.internal_wallet.collect_uncolored_outputs(fee)
25
- fill_input(tx, outputs)
26
-
27
- fill_change_tpc(tx, wallet, sum - fee)
28
- wallet.internal_wallet.sign_tx(tx)
29
- end
30
-
31
- def create_payload(prefix, data)
32
- payload = +''
33
- payload << prefix
34
- payload << data
35
- payload
36
- end
37
-
38
- def create_script(prefix, data)
39
- script = Tapyrus::Script.new
40
- script << Tapyrus::Script::OP_RETURN
41
- script << create_payload(prefix, data)
42
- script
43
- end
44
-
45
- def get_transaction(tx)
46
- Glueby::Internal::RPC.client.getrawtransaction(tx.txid, 1)
47
- end
48
- end
49
- include Glueby::Contract::Timestamp::Util
50
-
51
- attr_reader :tx, :txid
52
-
53
- # @param [String] content Data to be hashed and stored in blockchain.
54
- # @param [String] prefix prefix of op_return data
55
- # @param [Glueby::Contract::FeeEstimator] fee_estimator
56
- # @param [Symbol] digest type which select of:
57
- # - :sha256
58
- # - :double_sha256
59
- # - :none
60
- # @raise [Glueby::Contract::Errors::UnsupportedDigestType] if digest unsupport
61
- def initialize(
62
- wallet:,
63
- content:,
64
- prefix: '',
65
- fee_estimator: Glueby::Contract::FixedFeeEstimator.new,
66
- digest: :sha256
67
- )
68
- @wallet = wallet
69
- @content = content
70
- @prefix = prefix
71
- @fee_estimator = fee_estimator
72
- @digest = digest
73
- end
74
-
75
- # broadcast to Tapyrus Core
76
- # @return [String] txid
77
- # @raise [TxAlreadyBroadcasted] if tx has been broadcasted.
78
- # @raise [InsufficientFunds] if result of listunspent is not enough to pay the specified amount
79
- def save!
80
- raise Glueby::Contract::Errors::TxAlreadyBroadcasted if @txid
81
-
82
- @tx = create_tx(@wallet, @prefix, digest_content, @fee_estimator)
83
- @txid = @wallet.internal_wallet.broadcast(@tx)
84
- end
85
-
86
- private
87
-
88
- def digest_content
89
- case @digest&.downcase
90
- when :sha256
91
- Tapyrus.sha256(@content)
92
- when :double_sha256
93
- Tapyrus.double_sha256(@content)
94
- when :none
95
- @content
96
- else
97
- raise Glueby::Contract::Errors::UnsupportedDigestType
98
- end
99
- end
100
- end
101
- end
102
- end
1
+ module Glueby
2
+ module Contract
3
+ # Timestamp feature allows users to send transaction with op_return output which has sha256 hash of arbitary data.
4
+ # Timestamp transaction has
5
+ # * 1 or more inputs enough to afford transaction fee.
6
+ # * 1 output which has op_return, application specific prefix, and sha256 hash of data.
7
+ # * 1 output to send the change TPC back to the wallet.
8
+ #
9
+ # Storing timestamp transaction to the blockchain enables everyone to verify that the data existed at that time and a user signed it.
10
+ class Timestamp
11
+ include Glueby::Contract::TxBuilder
12
+
13
+ autoload :Syncer, 'glueby/contract/timestamp/syncer'
14
+
15
+ module Util
16
+ include Glueby::Internal::Wallet::TapyrusCoreWalletAdapter::Util
17
+ module_function
18
+
19
+ def create_txs(wallet, prefix, data, fee_estimator, utxo_provider)
20
+ txb = Tapyrus::TxBuilder.new
21
+ txb.data(prefix + data)
22
+ fee = fee_estimator.fee(dummy_tx(txb.build))
23
+ if utxo_provider
24
+ script_pubkey = Tapyrus::Script.parse_from_addr(wallet.internal_wallet.receive_address)
25
+ funding_tx, index = utxo_provider.get_utxo(script_pubkey, fee)
26
+ txb.add_utxo({
27
+ script_pubkey: funding_tx.outputs[index].script_pubkey,
28
+ txid: funding_tx.txid,
29
+ index: index,
30
+ value: funding_tx.outputs[index].value
31
+ })
32
+ else
33
+ sum, outputs = wallet.internal_wallet.collect_uncolored_outputs(fee)
34
+ outputs.each do |utxo|
35
+ txb.add_utxo({
36
+ script_pubkey: Tapyrus::Script.parse_from_payload(utxo[:script_pubkey].htb),
37
+ txid: utxo[:txid],
38
+ index: utxo[:vout],
39
+ value: utxo[:amount]
40
+ })
41
+ end
42
+ end
43
+
44
+ txb.fee(fee).change_address(wallet.internal_wallet.change_address)
45
+ [funding_tx, wallet.internal_wallet.sign_tx(txb.build)]
46
+ end
47
+
48
+ def get_transaction(tx)
49
+ Glueby::Internal::RPC.client.getrawtransaction(tx.txid, 1)
50
+ end
51
+ end
52
+ include Glueby::Contract::Timestamp::Util
53
+
54
+ attr_reader :tx, :txid
55
+
56
+ # @param [String] content Data to be hashed and stored in blockchain.
57
+ # @param [String] prefix prefix of op_return data
58
+ # @param [Glueby::Contract::FeeEstimator] fee_estimator
59
+ # @param [Symbol] digest type which select of:
60
+ # - :sha256
61
+ # - :double_sha256
62
+ # - :none
63
+ # @raise [Glueby::Contract::Errors::UnsupportedDigestType] if digest unsupport
64
+ def initialize(
65
+ wallet:,
66
+ content:,
67
+ prefix: '',
68
+ fee_estimator: Glueby::Contract::FixedFeeEstimator.new,
69
+ digest: :sha256,
70
+ utxo_provider: nil
71
+ )
72
+ @wallet = wallet
73
+ @content = content
74
+ @prefix = prefix
75
+ @fee_estimator = fee_estimator
76
+ @digest = digest
77
+ @utxo_provider = utxo_provider
78
+ end
79
+
80
+ # broadcast to Tapyrus Core
81
+ # @return [String] txid
82
+ # @raise [TxAlreadyBroadcasted] if tx has been broadcasted.
83
+ # @raise [InsufficientFunds] if result of listunspent is not enough to pay the specified amount
84
+ def save!
85
+ raise Glueby::Contract::Errors::TxAlreadyBroadcasted if @txid
86
+
87
+ funding_tx, @tx = create_txs(@wallet, @prefix, digest_content, @fee_estimator, @utxo_provider)
88
+ @wallet.internal_wallet.broadcast(funding_tx) if funding_tx
89
+ @txid = @wallet.internal_wallet.broadcast(@tx)
90
+ end
91
+
92
+ private
93
+
94
+ def digest_content
95
+ case @digest&.downcase
96
+ when :sha256
97
+ Tapyrus.sha256(@content)
98
+ when :double_sha256
99
+ Tapyrus.double_sha256(@content)
100
+ when :none
101
+ @content
102
+ else
103
+ raise Glueby::Contract::Errors::UnsupportedDigestType
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end