glueby 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +192 -10
- data/glueby.gemspec +2 -1
- data/lib/generators/glueby/contract/templates/initializer.rb.erb +7 -2
- data/lib/glueby/block_syncer.rb +98 -0
- data/lib/glueby/configuration.rb +26 -2
- data/lib/glueby/contract/timestamp/syncer.rb +13 -0
- data/lib/glueby/contract/timestamp.rb +33 -25
- data/lib/glueby/contract/token.rb +34 -8
- data/lib/glueby/contract/tx_builder.rb +97 -30
- data/lib/glueby/fee_provider/tasks.rb +6 -1
- data/lib/glueby/fee_provider.rb +11 -0
- data/lib/glueby/internal/wallet/abstract_wallet_adapter.rb +3 -1
- data/lib/glueby/internal/wallet/active_record_wallet_adapter/syncer.rb +14 -0
- data/lib/glueby/internal/wallet/active_record_wallet_adapter.rb +8 -3
- data/lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb +11 -10
- data/lib/glueby/internal/wallet.rb +24 -7
- data/lib/glueby/railtie.rb +11 -0
- data/lib/glueby/utxo_provider/tasks.rb +135 -0
- data/lib/glueby/utxo_provider.rb +85 -0
- data/lib/glueby/version.rb +1 -1
- data/lib/glueby.rb +6 -15
- data/lib/tasks/glueby/block_syncer.rake +29 -0
- data/lib/tasks/glueby/contract/timestamp.rake +12 -27
- data/lib/tasks/glueby/fee_provider.rake +5 -0
- data/lib/tasks/glueby/utxo_provider.rake +18 -0
- metadata +28 -8
- 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: 14bc1f60be9eefa4527231fb46fbb0d96b7a2253b1634d94b3a8464290d2ddbb
|
4
|
+
data.tar.gz: b268217f39285ae42fc2a4107bfcb5c32d9a71225e1fbb2b01296d24e62f1a1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a51e8f38bf391baec903a06e240294e8e75c5a881285f9be369009b77bf6fe9e8fe86fe41f43a1659344a6a38c1fcb3e2293951e8bb1a41d8beb282f63e96f6
|
7
|
+
data.tar.gz: 464fb058d159a083ab096bdb077981b65069e60d1fb73d664d6ea7fb09555c2e0794f4266bb114b5d4d315910f884a3548e6dfd1cd3412c93395f3433a75eaad
|
data/README.md
CHANGED
@@ -1,9 +1,35 @@
|
|
1
1
|
# Glueby [![Ruby](https://github.com/chaintope/glueby/actions/workflows/ruby.yml/badge.svg)](https://github.com/chaintope/glueby/actions/workflows/ruby.yml) [![Gem Version](https://badge.fury.io/rb/glueby.svg)](https://badge.fury.io/rb/glueby) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](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)
|
29
|
+
|
30
|
+
5. Utxo Provider
|
31
|
+
The UtxoProvider allows users to create a variety of transactions without having to manage the TPCs they hold in their wallets.
|
32
|
+
See more details at [Use utxo provider](#use-utxo-provider)
|
7
33
|
|
8
34
|
## Installation
|
9
35
|
|
@@ -21,13 +47,95 @@ Or install it yourself as:
|
|
21
47
|
|
22
48
|
$ gem install glueby
|
23
49
|
|
24
|
-
|
50
|
+
### Setup for Ruby on Rails application development
|
25
51
|
|
26
|
-
|
52
|
+
1. Add this line to your application's Gemfile
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
gem 'glueby'
|
56
|
+
```
|
57
|
+
|
58
|
+
and then execute
|
59
|
+
|
60
|
+
$ bundle install
|
61
|
+
|
62
|
+
2. Run installation rake task
|
63
|
+
|
64
|
+
$ rails glueby:contract:install
|
65
|
+
|
66
|
+
3. Run Tapyrus Core as dev mode
|
67
|
+
|
68
|
+
We recommend to run as a Docker container.
|
69
|
+
Docker image is here.
|
70
|
+
|
71
|
+
* [tapyus/tapyrusd](https://hub.docker.com/repository/docker/tapyrus/tapyrusd)
|
72
|
+
|
73
|
+
Starts tapryusd container
|
74
|
+
|
75
|
+
$ docker run -d --name 'tapyrus_node_dev' -p 12381:12381 -e GENESIS_BLOCK_WITH_SIG='0100000000000000000000000000000000000000000000000000000000000000000000002b5331139c6bc8646bb4e5737c51378133f70b9712b75548cb3c05f9188670e7440d295e7300c5640730c4634402a3e66fb5d921f76b48d8972a484cc0361e66ef74f45e012103af80b90d25145da28c583359beb47b21796b2fe1a23c1511e443e7a64dfdb27d40e05f064662d6b9acf65ae416379d82e11a9b78cdeb3a316d1057cd2780e3727f70a61f901d10acbe349cd11e04aa6b4351e782c44670aefbe138e99a5ce75ace01010000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a010000001976a91445d405b9ed450fec89044f9b7a99a4ef6fe2cd3f88ac00000000' tapyrus/tapyrusd:edge
|
76
|
+
|
77
|
+
4. Modify the glueby configuration
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
# Use tapyrus dev network
|
81
|
+
Tapyrus.chain_params = :dev
|
82
|
+
Glueby.configure do |config|
|
83
|
+
config.wallet_adapter = :activerecord
|
84
|
+
# Modify rpc connection info in config/initializers/glueby.rb that is created in step 3.
|
85
|
+
config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'rpcuser', password: 'rpcpassword' }
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
5. Generate db migration files for wallet feature
|
90
|
+
|
91
|
+
These are essential if you use `config.wallet_adapter = :activerecord` configuration.
|
92
|
+
|
93
|
+
$ rails g glueby:contract:block_syncer
|
94
|
+
$ rails g glueby:contract:wallet_adapter
|
95
|
+
|
96
|
+
If you want to use reissuable token or timestamp, you need to do below generators.
|
97
|
+
|
98
|
+
$ rails g glueby:contract:reissuable_token
|
99
|
+
$ rails g glueby:contract:timestamp
|
100
|
+
|
101
|
+
Then, run the migrations.
|
27
102
|
|
28
|
-
|
103
|
+
$ rails db:migrate
|
29
104
|
|
30
|
-
###
|
105
|
+
### Provide initial TPC (Tapyrus Coin) to wallets
|
106
|
+
|
107
|
+
To use contracts, wallets need to have TPC and it can be provided from coinbase tx.
|
108
|
+
|
109
|
+
1. Create a wallet and get receive address
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
wallet = Glueby::Wallet.create
|
113
|
+
wallet.balances # => {}
|
114
|
+
address = wallet.internal_wallet.receive_address
|
115
|
+
puts address
|
116
|
+
```
|
117
|
+
|
118
|
+
2. Generate a block
|
119
|
+
|
120
|
+
Set an address you got in previous step to `[Your address]`
|
121
|
+
|
122
|
+
$ docker exec tapyrus_node_dev tapyrus-cli -conf=/etc/tapyrus/tapyrus.conf generatetoaddress 1 "[Your address]" "cUJN5RVzYWFoeY8rUztd47jzXCu1p57Ay8V7pqCzsBD3PEXN7Dd4"
|
123
|
+
|
124
|
+
3. Sync blocks if you use `:activerecord` wallet adapter
|
125
|
+
|
126
|
+
You don't need to do this if you are using `:core` wallet_adapter.
|
127
|
+
|
128
|
+
$ rails glueby:contract:block_syncer:start
|
129
|
+
|
130
|
+
Here the wallet created in step 1 have 50 TPC and you can see like this:
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
wallet.balances # => {""=>5000000000}
|
134
|
+
```
|
135
|
+
|
136
|
+
TPC amount is shown as tapyrus unit. 1 TPC = 100000000 tapyrus.
|
137
|
+
|
138
|
+
## Timestamp
|
31
139
|
|
32
140
|
```ruby
|
33
141
|
|
@@ -99,7 +207,7 @@ We can see the timestamp transaction using getrawblockchain command
|
|
99
207
|
}
|
100
208
|
```
|
101
209
|
|
102
|
-
|
210
|
+
### Rails support
|
103
211
|
|
104
212
|
Glueby supports ruby on rails integration.
|
105
213
|
|
@@ -119,6 +227,9 @@ Glueby.configure do |config|
|
|
119
227
|
config.wallet_adapter = :activerecord
|
120
228
|
config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
|
121
229
|
end
|
230
|
+
|
231
|
+
# Uncomment next line when using timestamp feature
|
232
|
+
# Glueby::BlockSyncer.register_syncer(Glueby::Contract::Timestamp::Syncer)
|
122
233
|
```
|
123
234
|
|
124
235
|
If you use timestamp feature, use `glueby:contract:timestamp` generator.
|
@@ -155,11 +266,10 @@ bin/rails glueby:contract:timestamp:create
|
|
155
266
|
broadcasted (id=1, txid=8d602ca8ebdd50fa70b5ee6bc6351965b614d0a4843adacf9f43fedd7112fbf4)
|
156
267
|
```
|
157
268
|
|
158
|
-
Run `glueby:
|
269
|
+
Run `glueby:block_syncer:start` task to confirm the transaction and update status(unconfirmed -> confirmded).
|
159
270
|
|
160
271
|
```
|
161
|
-
bin/rails glueby:
|
162
|
-
confirmed (id=1, txid=8d602ca8ebdd50fa70b5ee6bc6351965b614d0a4843adacf9f43fedd7112fbf4)
|
272
|
+
bin/rails glueby:block_syncer:start
|
163
273
|
```
|
164
274
|
|
165
275
|
## Use fee provider mode
|
@@ -190,6 +300,7 @@ Glueby.configure do |config|
|
|
190
300
|
# The fee that Fee Provider pays on each transaction.
|
191
301
|
fixed_fee: 1000,
|
192
302
|
# Fee Provider tries to keep the number of utxo in utxo pool as this size using `glueby:fee_provider:manage_utxo_pool` rake task
|
303
|
+
# This size should not be greater than 2000.
|
193
304
|
utxo_pool_size: 20
|
194
305
|
}
|
195
306
|
end
|
@@ -262,6 +373,77 @@ Configuration:
|
|
262
373
|
utxo_pool_size = 20
|
263
374
|
```
|
264
375
|
|
376
|
+
## Use Utxo Provider
|
377
|
+
|
378
|
+
UtxoProvider will pay TPC on behalf of the user.
|
379
|
+
|
380
|
+
TPCs are required to create transactions in many cases where Glueby is used, such as issuing tokens or recording timestamps.
|
381
|
+
However, on the other hand, each user may not want to fund or manage TPCs.
|
382
|
+
|
383
|
+
The UtxoProvider allows users to create a variety of transactions without having to manage the TPCs they hold in their wallets.
|
384
|
+
|
385
|
+
### Set up Utxo Provider
|
386
|
+
|
387
|
+
1. Configure using Glueby.configure
|
388
|
+
|
389
|
+
```ruby
|
390
|
+
Glueby.configure do |config|
|
391
|
+
# using Utxo Provider
|
392
|
+
config.enable_utxo_provider!
|
393
|
+
|
394
|
+
# If not using Utxo Provider and each wallet manages TPCs by itself (Default behavior)
|
395
|
+
# config.disable_utxo_provider!
|
396
|
+
|
397
|
+
config.utxo_provider_config = {
|
398
|
+
# The amount that each utxo in utxo pool posses.
|
399
|
+
default_value: 1_000,
|
400
|
+
# The number of utxos in utxo pool. This size should not be greater than 2000.
|
401
|
+
utxo_pool_size: 20
|
402
|
+
}
|
403
|
+
end
|
404
|
+
```
|
405
|
+
|
406
|
+
2. Deposit TPC into Utxo Provider's wallet
|
407
|
+
|
408
|
+
Get an address from the wallet, and send enough TPCs to the address.
|
409
|
+
|
410
|
+
```
|
411
|
+
$ bundle exec rake glueby:utxo_provider:address
|
412
|
+
mqYTLdLCUCCZkTkcpbVx1GqpvV1gK4euRD
|
413
|
+
```
|
414
|
+
|
415
|
+
3. Manage UTXO pool
|
416
|
+
|
417
|
+
Run the rake task `glueby:utxo_provider:manage_utxo_pool`
|
418
|
+
This rake task tries to split UTOXs up to `utxo_pool_size`. If the pool has more than `utxo_pool_size` UTXOs, it does nothing
|
419
|
+
|
420
|
+
```
|
421
|
+
$ bundle exec rake glueby:utxo_provider:manage_utxo_pool
|
422
|
+
|
423
|
+
Status: Ready
|
424
|
+
TPC amount: 4_999_990_000
|
425
|
+
UTXO pool size: 20
|
426
|
+
|
427
|
+
Configuration:
|
428
|
+
default_value = 1_000
|
429
|
+
utxo_pool_size = 20
|
430
|
+
```
|
431
|
+
|
432
|
+
If you want to get the status information, you can use the `status` task.
|
433
|
+
|
434
|
+
```
|
435
|
+
$ bundle exec rake glueby:utxo_provider:status
|
436
|
+
Status: Ready q
|
437
|
+
TPC amount: 4_999_990_000
|
438
|
+
UTXO pool size: 20
|
439
|
+
|
440
|
+
Configuration:
|
441
|
+
default_value = 1_000
|
442
|
+
utxo_pool_size = 20
|
443
|
+
|
444
|
+
```
|
445
|
+
|
446
|
+
|
265
447
|
## Development
|
266
448
|
|
267
449
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/glueby.gemspec
CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.require_paths = ["lib"]
|
28
28
|
|
29
29
|
spec.add_runtime_dependency 'tapyrus', '>= 0.2.9'
|
30
|
-
spec.add_runtime_dependency 'activerecord'
|
30
|
+
spec.add_runtime_dependency 'activerecord', '~> 6.1.3'
|
31
31
|
spec.add_development_dependency 'sqlite3'
|
32
|
+
spec.add_development_dependency 'rails', '~> 6.1.3'
|
32
33
|
end
|
@@ -1,3 +1,8 @@
|
|
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
|
6
|
+
|
7
|
+
# Uncomment next line when using timestamp feature
|
8
|
+
# Glueby::BlockSyncer.register_syncer(Glueby::Contract::Timestamp::Syncer)
|
@@ -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
|
data/lib/glueby/configuration.rb
CHANGED
@@ -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
|
@@ -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
|
@@ -10,34 +10,39 @@ module Glueby
|
|
10
10
|
class Timestamp
|
11
11
|
include Glueby::Contract::TxBuilder
|
12
12
|
|
13
|
+
autoload :Syncer, 'glueby/contract/timestamp/syncer'
|
14
|
+
|
13
15
|
module Util
|
14
16
|
include Glueby::Internal::Wallet::TapyrusCoreWalletAdapter::Util
|
15
17
|
module_function
|
16
18
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
35
43
|
|
36
|
-
|
37
|
-
|
38
|
-
script << Tapyrus::Script::OP_RETURN
|
39
|
-
script << create_payload(prefix, data)
|
40
|
-
script
|
44
|
+
txb.fee(fee).change_address(wallet.internal_wallet.change_address)
|
45
|
+
[funding_tx, wallet.internal_wallet.sign_tx(txb.build)]
|
41
46
|
end
|
42
47
|
|
43
48
|
def get_transaction(tx)
|
@@ -61,13 +66,15 @@ module Glueby
|
|
61
66
|
content:,
|
62
67
|
prefix: '',
|
63
68
|
fee_estimator: Glueby::Contract::FixedFeeEstimator.new,
|
64
|
-
digest: :sha256
|
69
|
+
digest: :sha256,
|
70
|
+
utxo_provider: nil
|
65
71
|
)
|
66
72
|
@wallet = wallet
|
67
73
|
@content = content
|
68
74
|
@prefix = prefix
|
69
75
|
@fee_estimator = fee_estimator
|
70
76
|
@digest = digest
|
77
|
+
@utxo_provider = utxo_provider
|
71
78
|
end
|
72
79
|
|
73
80
|
# broadcast to Tapyrus Core
|
@@ -77,7 +84,8 @@ module Glueby
|
|
77
84
|
def save!
|
78
85
|
raise Glueby::Contract::Errors::TxAlreadyBroadcasted if @txid
|
79
86
|
|
80
|
-
@tx =
|
87
|
+
funding_tx, @tx = create_txs(@wallet, @prefix, digest_content, @fee_estimator, @utxo_provider)
|
88
|
+
@wallet.internal_wallet.broadcast(funding_tx) if funding_tx
|
81
89
|
@txid = @wallet.internal_wallet.broadcast(@tx)
|
82
90
|
end
|
83
91
|
|
@@ -80,7 +80,8 @@ module Glueby
|
|
80
80
|
private
|
81
81
|
|
82
82
|
def issue_reissuable_token(issuer:, amount:)
|
83
|
-
|
83
|
+
utxo_provider = Glueby::UtxoProvider.new if Glueby.configuration.use_utxo_provider?
|
84
|
+
funding_tx = create_funding_tx(wallet: issuer, utxo_provider: utxo_provider)
|
84
85
|
script_pubkey = funding_tx.outputs.first.script_pubkey
|
85
86
|
color_id = Tapyrus::Color::ColorIdentifier.reissuable(script_pubkey)
|
86
87
|
|
@@ -96,21 +97,37 @@ module Glueby
|
|
96
97
|
end
|
97
98
|
|
98
99
|
def issue_non_reissuable_token(issuer:, amount:)
|
99
|
-
|
100
|
+
utxo_provider = Glueby::UtxoProvider.new if Glueby.configuration.use_utxo_provider?
|
101
|
+
funding_tx = create_funding_tx(wallet: issuer, utxo_provider: utxo_provider) if utxo_provider
|
102
|
+
funding_tx = issuer.internal_wallet.broadcast(funding_tx) if funding_tx
|
103
|
+
|
104
|
+
tx = create_issue_tx_for_non_reissuable_token(funding_tx: funding_tx, issuer: issuer, amount: amount)
|
100
105
|
tx = issuer.internal_wallet.broadcast(tx)
|
101
106
|
|
102
107
|
out_point = tx.inputs.first.out_point
|
103
108
|
color_id = Tapyrus::Color::ColorIdentifier.non_reissuable(out_point)
|
104
|
-
|
109
|
+
if funding_tx
|
110
|
+
[[funding_tx, tx], color_id]
|
111
|
+
else
|
112
|
+
[[tx], color_id]
|
113
|
+
end
|
105
114
|
end
|
106
115
|
|
107
116
|
def issue_nft_token(issuer:)
|
108
|
-
|
117
|
+
utxo_provider = Glueby::UtxoProvider.new if Glueby.configuration.use_utxo_provider?
|
118
|
+
funding_tx = create_funding_tx(wallet: issuer, utxo_provider: utxo_provider) if utxo_provider
|
119
|
+
funding_tx = issuer.internal_wallet.broadcast(funding_tx) if funding_tx
|
120
|
+
|
121
|
+
tx = create_issue_tx_for_nft_token(funding_tx: funding_tx, issuer: issuer)
|
109
122
|
tx = issuer.internal_wallet.broadcast(tx)
|
110
123
|
|
111
124
|
out_point = tx.inputs.first.out_point
|
112
125
|
color_id = Tapyrus::Color::ColorIdentifier.nft(out_point)
|
113
|
-
|
126
|
+
if funding_tx
|
127
|
+
[[funding_tx, tx], color_id]
|
128
|
+
else
|
129
|
+
[[tx], color_id]
|
130
|
+
end
|
114
131
|
end
|
115
132
|
end
|
116
133
|
|
@@ -128,9 +145,10 @@ module Glueby
|
|
128
145
|
def reissue!(issuer:, amount:)
|
129
146
|
raise Glueby::Contract::Errors::InvalidAmount unless amount.positive?
|
130
147
|
raise Glueby::Contract::Errors::InvalidTokenType unless token_type == Tapyrus::Color::TokenTypes::REISSUABLE
|
148
|
+
utxo_provider = Glueby::UtxoProvider.new if Glueby.configuration.use_utxo_provider?
|
131
149
|
|
132
150
|
if validate_reissuer(wallet: issuer)
|
133
|
-
funding_tx = create_funding_tx(wallet: issuer, script: @script_pubkey)
|
151
|
+
funding_tx = create_funding_tx(wallet: issuer, script: @script_pubkey, utxo_provider: utxo_provider)
|
134
152
|
funding_tx = issuer.internal_wallet.broadcast(funding_tx)
|
135
153
|
tx = create_reissue_tx(funding_tx: funding_tx, issuer: issuer, amount: amount, color_id: color_id)
|
136
154
|
tx = issuer.internal_wallet.broadcast(tx)
|
@@ -153,7 +171,11 @@ module Glueby
|
|
153
171
|
def transfer!(sender:, receiver_address:, amount: 1)
|
154
172
|
raise Glueby::Contract::Errors::InvalidAmount unless amount.positive?
|
155
173
|
|
156
|
-
|
174
|
+
utxo_provider = Glueby::UtxoProvider.new if Glueby.configuration.use_utxo_provider?
|
175
|
+
funding_tx = create_funding_tx(wallet: sender, utxo_provider: utxo_provider) if utxo_provider
|
176
|
+
funding_tx = sender.internal_wallet.broadcast(funding_tx) if funding_tx
|
177
|
+
|
178
|
+
tx = create_transfer_tx(funding_tx: funding_tx, color_id: color_id, sender: sender, receiver_address: receiver_address, amount: amount)
|
157
179
|
sender.internal_wallet.broadcast(tx)
|
158
180
|
[color_id, tx]
|
159
181
|
end
|
@@ -169,7 +191,11 @@ module Glueby
|
|
169
191
|
def burn!(sender:, amount: 0)
|
170
192
|
raise Glueby::Contract::Errors::InvalidAmount unless amount.positive?
|
171
193
|
|
172
|
-
|
194
|
+
utxo_provider = Glueby::UtxoProvider.new if Glueby.configuration.use_utxo_provider?
|
195
|
+
funding_tx = create_funding_tx(wallet: sender, utxo_provider: utxo_provider) if utxo_provider
|
196
|
+
funding_tx = sender.internal_wallet.broadcast(funding_tx) if funding_tx
|
197
|
+
|
198
|
+
tx = create_burn_tx(funding_tx: funding_tx, color_id: color_id, sender: sender, amount: amount)
|
173
199
|
sender.internal_wallet.broadcast(tx)
|
174
200
|
end
|
175
201
|
|