glueby 0.4.1 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +113 -10
- data/lib/generators/glueby/contract/templates/initializer.rb.erb +4 -2
- data/lib/glueby.rb +5 -15
- data/lib/glueby/block_syncer.rb +98 -0
- data/lib/glueby/contract/timestamp.rb +2 -0
- data/lib/glueby/contract/timestamp/syncer.rb +13 -0
- data/lib/glueby/fee_provider/tasks.rb +6 -1
- data/lib/glueby/internal/wallet.rb +23 -4
- data/lib/glueby/internal/wallet/active_record_wallet_adapter.rb +6 -2
- data/lib/glueby/internal/wallet/active_record_wallet_adapter/syncer.rb +14 -0
- data/lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb +6 -5
- data/lib/glueby/railtie.rb +14 -0
- data/lib/glueby/version.rb +1 -1
- data/lib/tasks/glueby/block_syncer.rake +29 -0
- data/lib/tasks/glueby/contract/timestamp.rake +3 -25
- data/lib/tasks/glueby/fee_provider.rake +5 -0
- metadata +7 -4
- data/lib/tasks/glueby/contract/block_syncer.rake +0 -36
- data/lib/tasks/glueby/contract/wallet_adapter.rake +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbaba6627d1c34e6a2de2a3861016995481ad53163764a057c25fca123a8750b
|
4
|
+
data.tar.gz: 209020a3b503ac44cc9d4ef51e95d7ce71f17af59b92ffe3bb4863b4ae750604
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 559e4f224359df179cafc4f20c19f3f7c9723f6411103532ad6fd7d9727b5063c369b44e4e6c7872bc49d9355ec0cedd4f720c195302546cab7a5e5b429f6676
|
7
|
+
data.tar.gz: b4a4a1641820f23513ea56e1c240db966bcb9b0d62fd463d54f08e09f454125cdca4a087bc8db8c9b0181cd867ee667ec1b2bf5fbe1b95329541b3dd5fe2538b
|
data/README.md
CHANGED
@@ -1,9 +1,31 @@
|
|
1
1
|
# Glueby [](https://github.com/chaintope/glueby/actions/workflows/ruby.yml) [](https://badge.fury.io/rb/glueby) [](LICENSE)
|
2
2
|
|
3
|
+
Glueby is a smart contract library on the [Tapyrus blockchain](https://github.com/chaintope/tapyrus-core). This is
|
4
|
+
designed as you can use without any deep blockchain understanding.
|
3
5
|
|
4
|
-
|
6
|
+
## Features
|
5
7
|
|
6
|
-
|
8
|
+
Glueby has below features.
|
9
|
+
|
10
|
+
1. Wallet
|
11
|
+
You can manage wallets for application users. This wallet feature is a foundation of Contracts below to specify tx
|
12
|
+
sender and so on.
|
13
|
+
You can choose two sorts of wallet implementation :activerecord and :core. :activerecord is implemented using
|
14
|
+
ActiveRecord on RDB. :core uses the wallet that bundled with Tapyrus Core.
|
15
|
+
|
16
|
+
2. Contracts
|
17
|
+
You can use some smart contracts easily
|
18
|
+
- [Timestamp](#Timestamp): Record any data as a timestamp to a tapyrus blockchain.
|
19
|
+
- [Payment](./lib/glueby/contract/payment.rb): Transfer TPC.
|
20
|
+
- [Token](./lib/glueby/contract/token.rb): Issue, transfer and burn colored coin.
|
21
|
+
|
22
|
+
3. Sync blocks with your application
|
23
|
+
You can use BlockSyncer when you need to synchronize the state of an application with the state of a blockchain.
|
24
|
+
See more details at [BlockSyncer](./lib/glueby/block_syncer.rb).
|
25
|
+
|
26
|
+
4. Take over tx sender's fees
|
27
|
+
FeeProvider module can bear payments of sender's fees. You should provide funds for fees to FeeProvider before use.
|
28
|
+
See how to set up at [Use fee provider mode](#use-fee-provider-mode)
|
7
29
|
|
8
30
|
## Installation
|
9
31
|
|
@@ -21,13 +43,95 @@ Or install it yourself as:
|
|
21
43
|
|
22
44
|
$ gem install glueby
|
23
45
|
|
24
|
-
|
46
|
+
### Setup for Ruby on Rails application development
|
25
47
|
|
26
|
-
|
48
|
+
1. Add this line to your application's Gemfile
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
gem 'glueby'
|
52
|
+
```
|
53
|
+
|
54
|
+
and then execute
|
55
|
+
|
56
|
+
$ bundle install
|
57
|
+
|
58
|
+
2. Run installation rake task
|
59
|
+
|
60
|
+
$ rails glueby:contract:install
|
61
|
+
|
62
|
+
3. Run Tapyrus Core as dev mode
|
63
|
+
|
64
|
+
We recommend to run as a Docker container.
|
65
|
+
Docker image is here.
|
66
|
+
|
67
|
+
* [tapyus/tapyrusd](https://hub.docker.com/repository/docker/tapyrus/tapyrusd)
|
68
|
+
|
69
|
+
Starts tapryusd container
|
70
|
+
|
71
|
+
$ docker run -d --name 'tapyrus_node_dev' -p 12381:12381 -e GENESIS_BLOCK_WITH_SIG='0100000000000000000000000000000000000000000000000000000000000000000000002b5331139c6bc8646bb4e5737c51378133f70b9712b75548cb3c05f9188670e7440d295e7300c5640730c4634402a3e66fb5d921f76b48d8972a484cc0361e66ef74f45e012103af80b90d25145da28c583359beb47b21796b2fe1a23c1511e443e7a64dfdb27d40e05f064662d6b9acf65ae416379d82e11a9b78cdeb3a316d1057cd2780e3727f70a61f901d10acbe349cd11e04aa6b4351e782c44670aefbe138e99a5ce75ace01010000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a010000001976a91445d405b9ed450fec89044f9b7a99a4ef6fe2cd3f88ac00000000' tapyrus/tapyrusd:edge
|
72
|
+
|
73
|
+
4. Modify the glueby configuration
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
# Use tapyrus dev network
|
77
|
+
Tapyrus.chain_params = :dev
|
78
|
+
Glueby.configure do |config|
|
79
|
+
config.wallet_adapter = :activerecord
|
80
|
+
# Modify rpc connection info in config/initializers/glueby.rb that is created in step 3.
|
81
|
+
config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'rpcuser', password: 'rpcpassword' }
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
5. Generate db migration files for wallet feature
|
86
|
+
|
87
|
+
These are essential if you use `config.wallet_adapter = :activerecord` configuration.
|
88
|
+
|
89
|
+
$ rails g glueby:contract:block_syncer
|
90
|
+
$ rails g glueby:contract:wallet_adapter
|
91
|
+
|
92
|
+
If you want to use reissuable token or timestamp, you need to do below generators.
|
93
|
+
|
94
|
+
$ rails g glueby:contract:reissuable_token
|
95
|
+
$ rails g glueby:contract:timestamp
|
96
|
+
|
97
|
+
Then, run the migrations.
|
98
|
+
|
99
|
+
$ rails db:migrate
|
100
|
+
|
101
|
+
### Provide initial TPC (Tapyrus Coin) to wallets
|
102
|
+
|
103
|
+
To use contracts, wallets need to have TPC and it can be provided from coinbase tx.
|
104
|
+
|
105
|
+
1. Create a wallet and get receive address
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
wallet = Glueby::Wallet.create
|
109
|
+
wallet.balances # => {}
|
110
|
+
address = wallet.internal_wallet.receive_address
|
111
|
+
puts address
|
112
|
+
```
|
113
|
+
|
114
|
+
2. Generate a block
|
115
|
+
|
116
|
+
Set an address you got in previous step to `[Your address]`
|
117
|
+
|
118
|
+
$ docker exec tapyrus_node_dev tapyrus-cli -conf=/etc/tapyrus/tapyrus.conf generatetoaddress 1 "[Your address]" "cUJN5RVzYWFoeY8rUztd47jzXCu1p57Ay8V7pqCzsBD3PEXN7Dd4"
|
119
|
+
|
120
|
+
3. Sync blocks if you use `:activerecord` wallet adapter
|
121
|
+
|
122
|
+
You don't need to do this if you are using `:core` wallet_adapter.
|
123
|
+
|
124
|
+
$ rails glueby:contract:block_syncer:start
|
125
|
+
|
126
|
+
Here the wallet created in step 1 have 50 TPC and you can see like this:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
wallet.balances # => {""=>5000000000}
|
130
|
+
```
|
27
131
|
|
28
|
-
|
132
|
+
TPC amount is shown as tapyrus unit. 1 TPC = 100000000 tapyrus.
|
29
133
|
|
30
|
-
|
134
|
+
## Timestamp
|
31
135
|
|
32
136
|
```ruby
|
33
137
|
|
@@ -99,7 +203,7 @@ We can see the timestamp transaction using getrawblockchain command
|
|
99
203
|
}
|
100
204
|
```
|
101
205
|
|
102
|
-
|
206
|
+
### Rails support
|
103
207
|
|
104
208
|
Glueby supports ruby on rails integration.
|
105
209
|
|
@@ -155,11 +259,10 @@ bin/rails glueby:contract:timestamp:create
|
|
155
259
|
broadcasted (id=1, txid=8d602ca8ebdd50fa70b5ee6bc6351965b614d0a4843adacf9f43fedd7112fbf4)
|
156
260
|
```
|
157
261
|
|
158
|
-
Run `glueby:
|
262
|
+
Run `glueby:block_syncer:start` task to confirm the transaction and update status(unconfirmed -> confirmded).
|
159
263
|
|
160
264
|
```
|
161
|
-
bin/rails glueby:
|
162
|
-
confirmed (id=1, txid=8d602ca8ebdd50fa70b5ee6bc6351965b614d0a4843adacf9f43fedd7112fbf4)
|
265
|
+
bin/rails glueby:block_syncer:start
|
163
266
|
```
|
164
267
|
|
165
268
|
## Use fee provider mode
|
@@ -1,3 +1,5 @@
|
|
1
1
|
# Edit configuration for connection to tapyrus core
|
2
|
-
|
3
|
-
|
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
|
data/lib/glueby.rb
CHANGED
@@ -9,27 +9,17 @@ module Glueby
|
|
9
9
|
autoload :AR, 'glueby/active_record'
|
10
10
|
autoload :FeeProvider, 'glueby/fee_provider'
|
11
11
|
autoload :Configuration, 'glueby/configuration'
|
12
|
+
autoload :BlockSyncer, 'glueby/block_syncer'
|
13
|
+
|
14
|
+
if defined? ::Rails::Railtie
|
15
|
+
require 'glueby/railtie'
|
16
|
+
end
|
12
17
|
|
13
18
|
# Add prefix to activerecord table names
|
14
19
|
def self.table_name_prefix
|
15
20
|
'glueby_'
|
16
21
|
end
|
17
22
|
|
18
|
-
begin
|
19
|
-
class Railtie < ::Rails::Railtie
|
20
|
-
rake_tasks do
|
21
|
-
load "tasks/glueby/contract.rake"
|
22
|
-
load "tasks/glueby/contract/timestamp.rake"
|
23
|
-
load "tasks/glueby/contract/wallet_adapter.rake"
|
24
|
-
load "tasks/glueby/contract/block_syncer.rake"
|
25
|
-
load "tasks/glueby/fee_provider.rake"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
rescue
|
29
|
-
# Rake task is unavailable
|
30
|
-
puts "Rake task is unavailable"
|
31
|
-
end
|
32
|
-
|
33
23
|
# Returns the global [Configuration](RSpec/Core/Configuration) object.
|
34
24
|
def self.configuration
|
35
25
|
@configuration ||= Glueby::Configuration.new
|
@@ -0,0 +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
|
98
|
+
end
|
@@ -0,0 +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
|
@@ -44,7 +44,7 @@ module Glueby
|
|
44
44
|
.fee(fee_provider.fixed_fee)
|
45
45
|
.build
|
46
46
|
tx = wallet.sign_tx(tx)
|
47
|
-
wallet.broadcast(tx)
|
47
|
+
wallet.broadcast(tx, without_fee_provider: true)
|
48
48
|
ensure
|
49
49
|
status
|
50
50
|
end
|
@@ -80,6 +80,11 @@ module Glueby
|
|
80
80
|
EOS
|
81
81
|
end
|
82
82
|
|
83
|
+
# Show the address of Fee Provider
|
84
|
+
def address
|
85
|
+
puts wallet.receive_address
|
86
|
+
end
|
87
|
+
|
83
88
|
private
|
84
89
|
|
85
90
|
def check_wallet_amount!
|
@@ -34,8 +34,6 @@ module Glueby
|
|
34
34
|
autoload :Errors, 'glueby/internal/wallet/errors'
|
35
35
|
|
36
36
|
class << self
|
37
|
-
attr_writer :wallet_adapter
|
38
|
-
|
39
37
|
def create(wallet_id = nil)
|
40
38
|
begin
|
41
39
|
wallet_id = wallet_adapter.create_wallet(wallet_id)
|
@@ -58,6 +56,16 @@ module Glueby
|
|
58
56
|
wallet_adapter.wallets.map { |id| new(id) }
|
59
57
|
end
|
60
58
|
|
59
|
+
def wallet_adapter=(adapter)
|
60
|
+
if adapter.is_a?(ActiveRecordWalletAdapter)
|
61
|
+
BlockSyncer.register_syncer(ActiveRecordWalletAdapter::Syncer)
|
62
|
+
else
|
63
|
+
BlockSyncer.unregister_syncer(ActiveRecordWalletAdapter::Syncer)
|
64
|
+
end
|
65
|
+
|
66
|
+
@wallet_adapter = adapter
|
67
|
+
end
|
68
|
+
|
61
69
|
def wallet_adapter
|
62
70
|
@wallet_adapter or
|
63
71
|
raise Errors::ShouldInitializeWalletAdapter, 'You should initialize wallet adapter using `Glueby::Internal::Wallet.wallet_adapter = some wallet adapter instance`.'
|
@@ -74,6 +82,10 @@ module Glueby
|
|
74
82
|
wallet_adapter.balance(id, only_finalized)
|
75
83
|
end
|
76
84
|
|
85
|
+
# @param only_finalized [Boolean] The flag to get a UTXO with status only finalized
|
86
|
+
# @param label [String] This label is used to filtered the UTXOs with labeled if a key or Utxo is labeled.
|
87
|
+
# - If label is not specified (label=nil), all UTXOs will be returned.
|
88
|
+
# - If label=:unlabeled, only unlabeled UTXOs will be returned.
|
77
89
|
def list_unspent(only_finalized = true, label = nil)
|
78
90
|
wallet_adapter.list_unspent(id, only_finalized, label)
|
79
91
|
end
|
@@ -99,8 +111,15 @@ module Glueby
|
|
99
111
|
wallet_adapter.sign_tx(id, tx, prev_txs, sighashtype: sighashtype)
|
100
112
|
end
|
101
113
|
|
102
|
-
|
103
|
-
|
114
|
+
# Broadcast a transaction via Tapyrus Core RPC
|
115
|
+
# @param [Tapyrus::Tx] tx The tx that would be broadcasted
|
116
|
+
# @option [Boolean] without_fee_provider The flag to avoid to use FeeProvider temporary.
|
117
|
+
# @param [Proc] block The block that is called before broadcasting. It can be used to handle tx that is modified by FeeProvider.
|
118
|
+
def broadcast(tx, without_fee_provider: false, &block)
|
119
|
+
tx = FeeProvider.provide(tx) if !without_fee_provider && Glueby.configuration.fee_provider_bears?
|
120
|
+
|
121
|
+
block.call(tx) if block
|
122
|
+
|
104
123
|
wallet_adapter.broadcast(id, tx)
|
105
124
|
tx
|
106
125
|
end
|
@@ -54,6 +54,9 @@ module Glueby
|
|
54
54
|
# alice_wallet.balances
|
55
55
|
# ```
|
56
56
|
class ActiveRecordWalletAdapter < AbstractWalletAdapter
|
57
|
+
|
58
|
+
autoload :Syncer, 'glueby/internal/wallet/active_record_wallet_adapter/syncer'
|
59
|
+
|
57
60
|
def create_wallet(wallet_id = nil)
|
58
61
|
wallet_id = SecureRandom.hex(16) unless wallet_id
|
59
62
|
begin
|
@@ -90,7 +93,8 @@ module Glueby
|
|
90
93
|
wallet = AR::Wallet.find_by(wallet_id: wallet_id)
|
91
94
|
utxos = wallet.utxos
|
92
95
|
utxos = utxos.where(status: :finalized) if only_finalized
|
93
|
-
utxos = utxos.where(label: label) if label
|
96
|
+
utxos = utxos.where(label: label) if label && (label != :unlabeled)
|
97
|
+
utxos = utxos.where(label: nil) if label == :unlabeled
|
94
98
|
utxos.map do |utxo|
|
95
99
|
{
|
96
100
|
txid: utxo.txid,
|
@@ -118,7 +122,7 @@ module Glueby
|
|
118
122
|
|
119
123
|
def receive_address(wallet_id, label = nil)
|
120
124
|
wallet = AR::Wallet.find_by(wallet_id: wallet_id)
|
121
|
-
key = wallet.keys.create(purpose: :receive, label: label
|
125
|
+
key = wallet.keys.create(purpose: :receive, label: label)
|
122
126
|
key.address
|
123
127
|
end
|
124
128
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Glueby
|
2
|
+
module Internal
|
3
|
+
class Wallet
|
4
|
+
class ActiveRecordWalletAdapter
|
5
|
+
class Syncer
|
6
|
+
def tx_sync(tx)
|
7
|
+
Glueby::Internal::Wallet::AR::Utxo.destroy_for_inputs(tx)
|
8
|
+
Glueby::Internal::Wallet::AR::Utxo.create_or_update_for_outputs(tx)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -33,7 +33,7 @@ module Glueby
|
|
33
33
|
begin
|
34
34
|
RPC.client.createwallet(wallet_name(wallet_id))
|
35
35
|
rescue Tapyrus::RPC::Error => ex
|
36
|
-
if ex.rpc_error['code'] == RPC_WALLET_ERROR_ERROR_CODE && /Wallet wallet
|
36
|
+
if ex.rpc_error && ex.rpc_error['code'] == RPC_WALLET_ERROR_ERROR_CODE && /Wallet wallet-#{wallet_id} already exists\./ =~ ex.rpc_error['message']
|
37
37
|
raise Errors::WalletAlreadyCreated, "Wallet #{wallet_id} has been already created."
|
38
38
|
else
|
39
39
|
raise ex
|
@@ -52,9 +52,9 @@ module Glueby
|
|
52
52
|
def load_wallet(wallet_id)
|
53
53
|
RPC.client.loadwallet(wallet_name(wallet_id))
|
54
54
|
rescue Tapyrus::RPC::Error => ex
|
55
|
-
if ex.rpc_error['code'] == RPC_WALLET_ERROR_ERROR_CODE && /Duplicate -wallet filename specified/ =~ ex.rpc_error['message']
|
55
|
+
if ex.rpc_error && ex.rpc_error['code'] == RPC_WALLET_ERROR_ERROR_CODE && /Duplicate -wallet filename specified/ =~ ex.rpc_error['message']
|
56
56
|
raise Errors::WalletAlreadyLoaded, "Wallet #{wallet_id} has been already loaded."
|
57
|
-
elsif ex.rpc_error['code'] == RPC_WALLET_NOT_FOUND_ERROR_CODE
|
57
|
+
elsif ex.rpc_error && ex.rpc_error['code'] == RPC_WALLET_NOT_FOUND_ERROR_CODE
|
58
58
|
raise Errors::WalletNotFound, "Wallet #{wallet_id} does not found"
|
59
59
|
else
|
60
60
|
raise ex
|
@@ -88,7 +88,8 @@ module Glueby
|
|
88
88
|
min_conf = only_finalized ? 1 : 0
|
89
89
|
res = client.listunspent(min_conf)
|
90
90
|
|
91
|
-
res = res.filter { |i| i['label'] == label } if label
|
91
|
+
res = res.filter { |i| i['label'] == label } if label && (label != :unlabeled)
|
92
|
+
res = res.filter { |i| i['label'] == "" } if label == :unlabeled
|
92
93
|
|
93
94
|
res.map do |i|
|
94
95
|
script = Tapyrus::Script.parse_from_payload(i['scriptPubKey'].htb)
|
@@ -151,7 +152,7 @@ module Glueby
|
|
151
152
|
begin
|
152
153
|
yield(client)
|
153
154
|
rescue Tapyrus::RPC::Error => ex
|
154
|
-
if ex.rpc_error['code'] == RPC_WALLET_NOT_FOUND_ERROR_CODE
|
155
|
+
if ex.rpc_error && ex.rpc_error['code'] == RPC_WALLET_NOT_FOUND_ERROR_CODE
|
155
156
|
raise Errors::WalletUnloaded, "The wallet #{wallet_id} is unloaded. You should load before use it."
|
156
157
|
else
|
157
158
|
raise ex
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Glueby
|
2
|
+
class Railtie < ::Rails::Railtie
|
3
|
+
initializer "glueby.register_syncers" do
|
4
|
+
BlockSyncer.register_syncer(Contract::Timestamp::Syncer)
|
5
|
+
end
|
6
|
+
|
7
|
+
rake_tasks do
|
8
|
+
load "tasks/glueby/contract.rake"
|
9
|
+
load "tasks/glueby/contract/timestamp.rake"
|
10
|
+
load "tasks/glueby/block_syncer.rake"
|
11
|
+
load "tasks/glueby/fee_provider.rake"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/glueby/version.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
namespace :glueby do
|
2
|
+
namespace :contract do
|
3
|
+
namespace :block_syncer do
|
4
|
+
desc '[Deprecated use glueby:block_syncer:start instead] sync block into database'
|
5
|
+
task :start, [] => [:environment] do |_, _|
|
6
|
+
puts '[Deprecated] glueby:contract:block_syncer:start is deprecated. Use \'glueby:block_syncer:start\''
|
7
|
+
Rake::Task['glueby:block_syncer:start'].execute
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
namespace :glueby do
|
15
|
+
namespace :block_syncer do
|
16
|
+
desc 'sync block into database'
|
17
|
+
task :start, [] => [:environment] do |_, _|
|
18
|
+
latest_block_num = Glueby::Internal::RPC.client.getblockcount
|
19
|
+
synced_block = Glueby::AR::SystemInformation.synced_block_height
|
20
|
+
(synced_block.int_value + 1..latest_block_num).each do |height|
|
21
|
+
::ActiveRecord::Base.transaction do
|
22
|
+
Glueby::BlockSyncer.new(height).run
|
23
|
+
synced_block.update(info_value: height.to_s)
|
24
|
+
end
|
25
|
+
puts "success in synchronization (block height=#{height})"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -13,9 +13,9 @@ module Glueby
|
|
13
13
|
::ActiveRecord::Base.transaction do
|
14
14
|
wallet = Glueby::Wallet.load(t.wallet_id)
|
15
15
|
tx = create_tx(wallet, t.prefix, t.content_hash, Glueby::Contract::FixedFeeEstimator.new)
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
wallet.internal_wallet.broadcast(tx) do |tx|
|
17
|
+
t.update(txid: tx.txid, status: :unconfirmed)
|
18
|
+
end
|
19
19
|
puts "broadcasted (id=#{t.id}, txid=#{tx.txid})"
|
20
20
|
end
|
21
21
|
rescue => e
|
@@ -23,23 +23,6 @@ module Glueby
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
26
|
-
|
27
|
-
def confirm
|
28
|
-
timestamps = Glueby::Contract::AR::Timestamp.where(status: :unconfirmed)
|
29
|
-
timestamps.each do |t|
|
30
|
-
begin
|
31
|
-
::ActiveRecord::Base.transaction do
|
32
|
-
tx = get_transaction(t)
|
33
|
-
if tx['confirmations'] && tx['confirmations'] > 0
|
34
|
-
t.update(status: :confirmed)
|
35
|
-
puts "confirmed (id=#{t.id}, txid=#{tx['txid']})"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
rescue => e
|
39
|
-
puts "failed to confirm (id=#{t.id}, reason=#{e.message})"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
26
|
end
|
44
27
|
end
|
45
28
|
end
|
@@ -52,11 +35,6 @@ namespace :glueby do
|
|
52
35
|
task :create, [] => [:environment] do |_, _|
|
53
36
|
Glueby::Contract::Task::Timestamp.create
|
54
37
|
end
|
55
|
-
|
56
|
-
desc 'confirm glueby timestamp tx'
|
57
|
-
task :confirm, [] => [:environment] do |_, _|
|
58
|
-
Glueby::Contract::Task::Timestamp.confirm
|
59
|
-
end
|
60
38
|
end
|
61
39
|
end
|
62
40
|
end
|
@@ -9,5 +9,10 @@ namespace :glueby do
|
|
9
9
|
task :status, [] => [:environment] do |_, _|
|
10
10
|
Glueby::FeeProvider::Tasks.new.status
|
11
11
|
end
|
12
|
+
|
13
|
+
desc 'Show the address of the Glueby::FeeProvider'
|
14
|
+
task :address, [] => [:environment] do |_, _|
|
15
|
+
Glueby::FeeProvider::Tasks.new.address
|
16
|
+
end
|
12
17
|
end
|
13
18
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glueby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tapyrus
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- lib/glueby.rb
|
88
88
|
- lib/glueby/active_record.rb
|
89
89
|
- lib/glueby/active_record/system_information.rb
|
90
|
+
- lib/glueby/block_syncer.rb
|
90
91
|
- lib/glueby/configuration.rb
|
91
92
|
- lib/glueby/contract.rb
|
92
93
|
- lib/glueby/contract/active_record.rb
|
@@ -96,6 +97,7 @@ files:
|
|
96
97
|
- lib/glueby/contract/fee_estimator.rb
|
97
98
|
- lib/glueby/contract/payment.rb
|
98
99
|
- lib/glueby/contract/timestamp.rb
|
100
|
+
- lib/glueby/contract/timestamp/syncer.rb
|
99
101
|
- lib/glueby/contract/token.rb
|
100
102
|
- lib/glueby/contract/tx_builder.rb
|
101
103
|
- lib/glueby/fee_provider.rb
|
@@ -111,14 +113,15 @@ files:
|
|
111
113
|
- lib/glueby/internal/wallet/active_record/utxo.rb
|
112
114
|
- lib/glueby/internal/wallet/active_record/wallet.rb
|
113
115
|
- lib/glueby/internal/wallet/active_record_wallet_adapter.rb
|
116
|
+
- lib/glueby/internal/wallet/active_record_wallet_adapter/syncer.rb
|
114
117
|
- lib/glueby/internal/wallet/errors.rb
|
115
118
|
- lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb
|
119
|
+
- lib/glueby/railtie.rb
|
116
120
|
- lib/glueby/version.rb
|
117
121
|
- lib/glueby/wallet.rb
|
122
|
+
- lib/tasks/glueby/block_syncer.rake
|
118
123
|
- lib/tasks/glueby/contract.rake
|
119
|
-
- lib/tasks/glueby/contract/block_syncer.rake
|
120
124
|
- lib/tasks/glueby/contract/timestamp.rake
|
121
|
-
- lib/tasks/glueby/contract/wallet_adapter.rake
|
122
125
|
- lib/tasks/glueby/fee_provider.rake
|
123
126
|
homepage: https://github.com/chaintope/glueby
|
124
127
|
licenses:
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module Glueby
|
2
|
-
module Contract
|
3
|
-
module Task
|
4
|
-
module BlockSyncer
|
5
|
-
|
6
|
-
def sync_block
|
7
|
-
latest_block_num = Glueby::Internal::RPC.client.getblockcount
|
8
|
-
synced_block = Glueby::AR::SystemInformation.synced_block_height
|
9
|
-
(synced_block.int_value + 1..latest_block_num).each do |i|
|
10
|
-
::ActiveRecord::Base.transaction do
|
11
|
-
block_hash = Glueby::Internal::RPC.client.getblockhash(i)
|
12
|
-
import_block(block_hash)
|
13
|
-
synced_block.update(info_value: i.to_s)
|
14
|
-
puts "success in synchronization (block height=#{i.to_s})"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
namespace :glueby do
|
25
|
-
namespace :contract do
|
26
|
-
namespace :block_syncer do
|
27
|
-
include Glueby::Contract::Task::BlockSyncer
|
28
|
-
|
29
|
-
desc 'sync block into database'
|
30
|
-
task :start, [] => [:environment] do |_, _|
|
31
|
-
Glueby::Contract::Task::BlockSyncer.sync_block
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module Glueby
|
2
|
-
module Contract
|
3
|
-
module Task
|
4
|
-
module WalletAdapter
|
5
|
-
def import_block(block_hash)
|
6
|
-
block = Glueby::Internal::RPC.client.getblock(block_hash, 0)
|
7
|
-
block = Tapyrus::Block.parse_from_payload(block.htb)
|
8
|
-
block.transactions.each { |tx| import_tx(tx.txid) }
|
9
|
-
end
|
10
|
-
|
11
|
-
def import_tx(txid)
|
12
|
-
tx = Glueby::Internal::RPC.client.getrawtransaction(txid)
|
13
|
-
tx = Tapyrus::Tx.parse_from_payload(tx.htb)
|
14
|
-
Glueby::Internal::Wallet::AR::Utxo.destroy_for_inputs(tx)
|
15
|
-
Glueby::Internal::Wallet::AR::Utxo.create_or_update_for_outputs(tx)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
namespace :glueby do
|
23
|
-
namespace :contract do
|
24
|
-
namespace :wallet_adapter do
|
25
|
-
include Glueby::Contract::Task::WalletAdapter
|
26
|
-
|
27
|
-
desc 'import block into database'
|
28
|
-
task :import_block, [:block_hash] => [:environment] do |_, args|
|
29
|
-
block_hash = args[:block_hash]
|
30
|
-
|
31
|
-
::ActiveRecord::Base.transaction { import_block(block_hash) }
|
32
|
-
end
|
33
|
-
|
34
|
-
desc 'import transaction into database'
|
35
|
-
task :import_tx, [:txid] => [:environment] do |_, args|
|
36
|
-
txid = args[:txid]
|
37
|
-
|
38
|
-
::ActiveRecord::Base.transaction { import_tx(txid) }
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|