glueby 0.4.1 → 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.
- 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 [](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)
|
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
|
|