glueby 0.4.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,387 +1,463 @@
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
-
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.
5
-
6
- ## Features
7
-
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
- ## Installation
31
-
32
- Add this line to your application's Gemfile:
33
-
34
- ```ruby
35
- gem 'glueby'
36
- ```
37
-
38
- And then execute:
39
-
40
- $ bundle install
41
-
42
- Or install it yourself as:
43
-
44
- $ gem install glueby
45
-
46
- ### Setup for Ruby on Rails application development
47
-
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
- ```
131
-
132
- TPC amount is shown as tapyrus unit. 1 TPC = 100000000 tapyrus.
133
-
134
- ## Timestamp
135
-
136
- ```ruby
137
-
138
- Glurby.configure do |config|
139
- config.wallet_adapter = :activerecord
140
- config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
141
- end
142
-
143
- wallet = Glueby::Wallet.create
144
- timestamp = Glueby::Contract::Timestamp.new(wallet: wallet, content: "\x01\x02\x03")
145
- timestamp.save!
146
- # "a01eace94ce6cdc30f389609de8a7584a4e208ee82fec33a2f5875b7cee47097"
147
-
148
- ```
149
-
150
- We can see the timestamp transaction using getrawblockchain command
151
-
152
- ```bash
153
- > tapyrus-cli -rpcport=12381 -rpcuser=user -rpcpassword=pass getrawtransaction a01eace94ce6cdc30f389609de8a7584a4e208ee82fec33a2f5875b7cee47097 1
154
-
155
- {
156
- "txid": "a01eace94ce6cdc30f389609de8a7584a4e208ee82fec33a2f5875b7cee47097",
157
- "hash": "a559a84d94cff58619bb735862eb93ff7a3b8fe122a8f2f4c10b7814fb15459a",
158
- "features": 1,
159
- "size": 234,
160
- "vsize": 234,
161
- "weight": 936,
162
- "locktime": 0,
163
- "vin": [
164
- {
165
- "txid": "12658e0289da70d43ae3777a174ac8c40f89cbe6564ed6606f197764b3556200",
166
- "vout": 0,
167
- "scriptSig": {
168
- "asm": "3044022067285c57a57fc0d7f64576abbec65639b0f4a8c31b5605eefe881edccb97c62402201ddec93c0c9bf3bb5707757e97e7fa6566c0183b41537e4f9ec46dcfe401864d[ALL] 03b8ad9e3271a20d5eb2b622e455fcffa5c9c90e38b192772b2e1b58f6b442e78d",
169
- "hex": "473044022067285c57a57fc0d7f64576abbec65639b0f4a8c31b5605eefe881edccb97c62402201ddec93c0c9bf3bb5707757e97e7fa6566c0183b41537e4f9ec46dcfe401864d012103b8ad9e3271a20d5eb2b622e455fcffa5c9c90e38b192772b2e1b58f6b442e78d"
170
- },
171
- "sequence": 4294967295
172
- }
173
- ],
174
- "vout": [
175
- {
176
- "value": 0.00000000,
177
- "n": 0,
178
- "scriptPubKey": {
179
- "asm": "OP_RETURN 039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81",
180
- "hex": "6a20039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81",
181
- "type": "nulldata"
182
- }
183
- },
184
- {
185
- "value": 49.99990000,
186
- "n": 1,
187
- "scriptPubKey": {
188
- "asm": "OP_DUP OP_HASH160 3c0422f624f2503193c7413eff32839b9e151b54 OP_EQUALVERIFY OP_CHECKSIG",
189
- "hex": "76a9143c0422f624f2503193c7413eff32839b9e151b5488ac",
190
- "reqSigs": 1,
191
- "type": "pubkeyhash",
192
- "addresses": [
193
- "16ULVva73ZhQiZu9o3njXc3TZ3aSog7FQQ"
194
- ]
195
- }
196
- }
197
- ],
198
- "hex": "0100000001006255b36477196f60d64e56e6cb890fc4c84a177a77e33ad470da89028e6512000000006a473044022067285c57a57fc0d7f64576abbec65639b0f4a8c31b5605eefe881edccb97c62402201ddec93c0c9bf3bb5707757e97e7fa6566c0183b41537e4f9ec46dcfe401864d012103b8ad9e3271a20d5eb2b622e455fcffa5c9c90e38b192772b2e1b58f6b442e78dffffffff020000000000000000226a20039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81f0ca052a010000001976a9143c0422f624f2503193c7413eff32839b9e151b5488ac00000000",
199
- "blockhash": "d33efc626114f89445d12c27f453c209382a3cb49de132bf978449093f2d2dbb",
200
- "confirmations": 3,
201
- "time": 1590822803,
202
- "blocktime": 1590822803
203
- }
204
- ```
205
-
206
- ### Rails support
207
-
208
- Glueby supports ruby on rails integration.
209
-
210
- To use in rails, Add dependency to Gemfile.
211
-
212
- Then invoke install task.
213
-
214
- ```
215
- bin/rails glueby:contract:install
216
- ```
217
-
218
- Install task creates a file `glueby.rb` in `config/initializers` directory like this.
219
-
220
- ```ruby
221
- # Edit configuration for connection to tapyrus core
222
- Glueby.configure do |config|
223
- config.wallet_adapter = :activerecord
224
- config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
225
- end
226
-
227
- # Uncomment next line when using timestamp feature
228
- # Glueby::BlockSyncer.register_syncer(Glueby::Contract::Timestamp::Syncer)
229
- ```
230
-
231
- If you use timestamp feature, use `glueby:contract:timestamp` generator.
232
-
233
- ```
234
- bin/rails g glueby:contract:timestamp
235
- create db/migrate/20200613065511_create_timestamp.rb
236
- bin/rails db:migrate
237
- == 20200613065511 CreateTimestamp: migrating ==================================
238
- -- create_table(:timestamps)
239
- -> 0.0023s
240
- == 20200613065511 CreateTimestamp: migrated (0.0024s) =========================
241
- ```
242
-
243
- Now, Glueby::Contract::AR::Timestamp model is available
244
-
245
- ```ruby
246
- irb(main):001:0> wallet = Glueby::Wallet.create
247
- => #<Glueby::Wallet:0x00007fe8333f7d98 @internal_wallet=#<Glueby::Internal::Wallet:0x00007fe8333f7dc0 @id="70a58204a7f4cb10d973b762f17fdb4b">>
248
- irb(main):003:0> t = Glueby::Contract::AR::Timestamp.new(wallet_id: wallet.id, content:"\x01010101", prefix: "app")
249
- (0.5ms) SELECT sqlite_version(*)
250
- => #<Glueby::Contract::AR::Timestamp id: nil, txid: nil, status: "init", content_hash: "9ccc644b03a88358a754962903a659a2d338767ee61674dde5...", prefix: "app", wallet_id: "70a58204a7f4cb10d973b762f17fdb4b">
251
- irb(main):004:0> t.save
252
- (0.1ms) begin transaction
253
- Glueby::Contract::AR::Timestamp Create (0.4ms) INSERT INTO "timestamps" ("status", "content_hash", "prefix", "wallet_id") VALUES (?, ?, ?, ?) [["status", 0], ["content_hash", "9ccc644b03a88358a754962903a659a2d338767ee61674dde5434702a6256e6d"], ["prefix", "app"], ["wallet_id", "70a58204a7f4cb10d973b762f17fdb4b"]]
254
- (2.1ms) commit transaction
255
- => true
256
- ```
257
-
258
- After create timestamp model, run `glueby:contract:timestamp:create` task to broadcast the transaction to the Tapyrus Core Network and update status(init -> unconfirmed).
259
-
260
- ```
261
- bin/rails glueby:contract:timestamp:create
262
- broadcasted (id=1, txid=8d602ca8ebdd50fa70b5ee6bc6351965b614d0a4843adacf9f43fedd7112fbf4)
263
- ```
264
-
265
- Run `glueby:block_syncer:start` task to confirm the transaction and update status(unconfirmed -> confirmded).
266
-
267
- ```
268
- bin/rails glueby:block_syncer:start
269
- ```
270
-
271
- ## Use fee provider mode
272
-
273
- Glueby contracts have two different way of fee provisions.
274
-
275
- 1. `:sender_pays_itself`
276
- 2. `:fee_provider_bears`
277
-
278
- The first one: `:sender_pays_itself`, is the default behavior.
279
- In the second Fee Provider mode, the Fee Provider module pays a fee instead of the transaction's sender.
280
-
281
- ### Fee Provider Specification
282
-
283
- * Fee Provider pays fixed amount fee, and it is configurable.
284
- * Fee Provider needs to have enough funds into their wallet.
285
- * Fee Provider is managed to keep some number of UTXOs that have fixed fee value by rake tasks.
286
-
287
- ### Setting up Fee Provider
288
-
289
- 1. Set like below
290
-
291
- ```ruby
292
- Glueby.configure do |config|
293
- # Use FeeProvider to supply inputs for fees on each transaction that is created on Glueby.
294
- config.fee_provider_bears!
295
- config.fee_provider_config = {
296
- # The fee that Fee Provider pays on each transaction.
297
- fixed_fee: 1000,
298
- # Fee Provider tries to keep the number of utxo in utxo pool as this size using `glueby:fee_provider:manage_utxo_pool` rake task
299
- utxo_pool_size: 20
300
- }
301
- end
302
- ```
303
-
304
- 2. Deposit TPC into Fee Provider's wallet
305
-
306
- Get an address from the wallet.
307
-
308
- ```
309
- $ bundle exec rake glueby:fee_provider:address
310
- mqYTLdLCUCCZkTkcpbVx1GqpvV1gK4euRD
311
- ```
312
-
313
- Send TPC to the address.
314
-
315
- If you use `Glueby::Contract::Payment` to the sending, you can do like this:
316
-
317
- ```ruby
318
- Glueby::Contract::Payment.transfer(sender: sender, receiver_address: 'mqYTLdLCUCCZkTkcpbVx1GqpvV1gK4euRD', amount: 1_000_000)
319
- ```
320
-
321
- 3. Manage UTXO pool
322
-
323
- The Fee Provider's wallet has to keep some UTXOs with `fixed_fee` amount for paying fees using `manage_utxo_pool` rake task below.
324
- 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.
325
-
326
- ```
327
- $ bundle exec rake glueby:fee_provider:manage_utxo_pool
328
- Status: Ready
329
- TPC amount: 999_000
330
- UTXO pool size: 20
331
-
332
- Configuration:
333
- fixed_fee = 1_000
334
- utxo_pool_size = 20
335
- ```
336
-
337
- This shows that the UTXO pool has 20 UTXOs with `fixed_fee` amount for paying fees and has other UTXOs that never use for paying fees.
338
- The sum of all the UTXOs that includes both kinds of UTXO is 999_000 tapyrus.
339
-
340
- If the wallet doesn't have enough amount, the rake task shows an error like:
341
-
342
- ```
343
- $ bundle exec rake glueby:fee_provider:manage_utxo_pool
344
- Status: Insufficient Amount
345
- TPC amount: 15_000
346
- UTXO pool size: 15
347
-
348
- 1. Please replenishment TPC which is for paying fee to FeeProvider.
349
- FeeProvider needs 21000 tapyrus at least for paying 20 transaction fees.
350
- FeeProvider wallet's address is '1DBgMCNBdjQ1Ntz1vpwx2HMYJmc9kw88iT'
351
- 2. Then create UTXOs for paying in UTXO pool with 'rake glueby:fee_provider:manage_utxo_pool'
352
-
353
- Configuration:
354
- fixed_fee = 1_000
355
- utxo_pool_size = 20
356
- ```
357
-
358
- If you want to get the status information, you can use the `status` task.
359
-
360
- ```
361
- $ bundle exec rake glueby:fee_provider:status
362
- Status: Ready
363
- TPC amount: 999_000
364
- UTXO pool size: 20
365
-
366
- Configuration:
367
- fixed_fee = 1_000
368
- utxo_pool_size = 20
369
- ```
370
-
371
- ## Development
372
-
373
- 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.
374
-
375
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
376
-
377
- ## Contributing
378
-
379
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/glueby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/tapyrus-contractrb/blob/master/CODE_OF_CONDUCT.md).
380
-
381
- ## License
382
-
383
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
384
-
385
- ## Code of Conduct
386
-
387
- Everyone interacting in the Glueby project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/glueby/blob/master/CODE_OF_CONDUCT.md).
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
+
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.
5
+
6
+ ## Features
7
+
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)
33
+
34
+ ## Installation
35
+
36
+ Add this line to your application's Gemfile:
37
+
38
+ ```ruby
39
+ gem 'glueby'
40
+ ```
41
+
42
+ And then execute:
43
+
44
+ $ bundle install
45
+
46
+ Or install it yourself as:
47
+
48
+ $ gem install glueby
49
+
50
+ ### Setup for Ruby on Rails application development
51
+
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.
102
+
103
+ $ rails db:migrate
104
+
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
139
+
140
+ ```ruby
141
+
142
+ Glurby.configure do |config|
143
+ config.wallet_adapter = :activerecord
144
+ config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
145
+ end
146
+
147
+ wallet = Glueby::Wallet.create
148
+ timestamp = Glueby::Contract::Timestamp.new(wallet: wallet, content: "\x01\x02\x03")
149
+ timestamp.save!
150
+ # "a01eace94ce6cdc30f389609de8a7584a4e208ee82fec33a2f5875b7cee47097"
151
+
152
+ ```
153
+
154
+ We can see the timestamp transaction using getrawblockchain command
155
+
156
+ ```bash
157
+ > tapyrus-cli -rpcport=12381 -rpcuser=user -rpcpassword=pass getrawtransaction a01eace94ce6cdc30f389609de8a7584a4e208ee82fec33a2f5875b7cee47097 1
158
+
159
+ {
160
+ "txid": "a01eace94ce6cdc30f389609de8a7584a4e208ee82fec33a2f5875b7cee47097",
161
+ "hash": "a559a84d94cff58619bb735862eb93ff7a3b8fe122a8f2f4c10b7814fb15459a",
162
+ "features": 1,
163
+ "size": 234,
164
+ "vsize": 234,
165
+ "weight": 936,
166
+ "locktime": 0,
167
+ "vin": [
168
+ {
169
+ "txid": "12658e0289da70d43ae3777a174ac8c40f89cbe6564ed6606f197764b3556200",
170
+ "vout": 0,
171
+ "scriptSig": {
172
+ "asm": "3044022067285c57a57fc0d7f64576abbec65639b0f4a8c31b5605eefe881edccb97c62402201ddec93c0c9bf3bb5707757e97e7fa6566c0183b41537e4f9ec46dcfe401864d[ALL] 03b8ad9e3271a20d5eb2b622e455fcffa5c9c90e38b192772b2e1b58f6b442e78d",
173
+ "hex": "473044022067285c57a57fc0d7f64576abbec65639b0f4a8c31b5605eefe881edccb97c62402201ddec93c0c9bf3bb5707757e97e7fa6566c0183b41537e4f9ec46dcfe401864d012103b8ad9e3271a20d5eb2b622e455fcffa5c9c90e38b192772b2e1b58f6b442e78d"
174
+ },
175
+ "sequence": 4294967295
176
+ }
177
+ ],
178
+ "vout": [
179
+ {
180
+ "value": 0.00000000,
181
+ "n": 0,
182
+ "scriptPubKey": {
183
+ "asm": "OP_RETURN 039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81",
184
+ "hex": "6a20039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81",
185
+ "type": "nulldata"
186
+ }
187
+ },
188
+ {
189
+ "value": 49.99990000,
190
+ "n": 1,
191
+ "scriptPubKey": {
192
+ "asm": "OP_DUP OP_HASH160 3c0422f624f2503193c7413eff32839b9e151b54 OP_EQUALVERIFY OP_CHECKSIG",
193
+ "hex": "76a9143c0422f624f2503193c7413eff32839b9e151b5488ac",
194
+ "reqSigs": 1,
195
+ "type": "pubkeyhash",
196
+ "addresses": [
197
+ "16ULVva73ZhQiZu9o3njXc3TZ3aSog7FQQ"
198
+ ]
199
+ }
200
+ }
201
+ ],
202
+ "hex": "0100000001006255b36477196f60d64e56e6cb890fc4c84a177a77e33ad470da89028e6512000000006a473044022067285c57a57fc0d7f64576abbec65639b0f4a8c31b5605eefe881edccb97c62402201ddec93c0c9bf3bb5707757e97e7fa6566c0183b41537e4f9ec46dcfe401864d012103b8ad9e3271a20d5eb2b622e455fcffa5c9c90e38b192772b2e1b58f6b442e78dffffffff020000000000000000226a20039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81f0ca052a010000001976a9143c0422f624f2503193c7413eff32839b9e151b5488ac00000000",
203
+ "blockhash": "d33efc626114f89445d12c27f453c209382a3cb49de132bf978449093f2d2dbb",
204
+ "confirmations": 3,
205
+ "time": 1590822803,
206
+ "blocktime": 1590822803
207
+ }
208
+ ```
209
+
210
+ ### Rails support
211
+
212
+ Glueby supports ruby on rails integration.
213
+
214
+ To use in rails, Add dependency to Gemfile.
215
+
216
+ Then invoke install task.
217
+
218
+ ```
219
+ bin/rails glueby:contract:install
220
+ ```
221
+
222
+ Install task creates a file `glueby.rb` in `config/initializers` directory like this.
223
+
224
+ ```ruby
225
+ # Edit configuration for connection to tapyrus core
226
+ Glueby.configure do |config|
227
+ config.wallet_adapter = :activerecord
228
+ config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
229
+ end
230
+
231
+ # Uncomment next line when using timestamp feature
232
+ # Glueby::BlockSyncer.register_syncer(Glueby::Contract::Timestamp::Syncer)
233
+ ```
234
+
235
+ If you use timestamp feature, use `glueby:contract:timestamp` generator.
236
+
237
+ ```
238
+ bin/rails g glueby:contract:timestamp
239
+ create db/migrate/20200613065511_create_timestamp.rb
240
+ bin/rails db:migrate
241
+ == 20200613065511 CreateTimestamp: migrating ==================================
242
+ -- create_table(:timestamps)
243
+ -> 0.0023s
244
+ == 20200613065511 CreateTimestamp: migrated (0.0024s) =========================
245
+ ```
246
+
247
+ Now, Glueby::Contract::AR::Timestamp model is available
248
+
249
+ ```ruby
250
+ irb(main):001:0> wallet = Glueby::Wallet.create
251
+ => #<Glueby::Wallet:0x00007fe8333f7d98 @internal_wallet=#<Glueby::Internal::Wallet:0x00007fe8333f7dc0 @id="70a58204a7f4cb10d973b762f17fdb4b">>
252
+ irb(main):003:0> t = Glueby::Contract::AR::Timestamp.new(wallet_id: wallet.id, content:"\x01010101", prefix: "app")
253
+ (0.5ms) SELECT sqlite_version(*)
254
+ => #<Glueby::Contract::AR::Timestamp id: nil, txid: nil, status: "init", content_hash: "9ccc644b03a88358a754962903a659a2d338767ee61674dde5...", prefix: "app", wallet_id: "70a58204a7f4cb10d973b762f17fdb4b">
255
+ irb(main):004:0> t.save
256
+ (0.1ms) begin transaction
257
+ Glueby::Contract::AR::Timestamp Create (0.4ms) INSERT INTO "timestamps" ("status", "content_hash", "prefix", "wallet_id") VALUES (?, ?, ?, ?) [["status", 0], ["content_hash", "9ccc644b03a88358a754962903a659a2d338767ee61674dde5434702a6256e6d"], ["prefix", "app"], ["wallet_id", "70a58204a7f4cb10d973b762f17fdb4b"]]
258
+ (2.1ms) commit transaction
259
+ => true
260
+ ```
261
+
262
+ After create timestamp model, run `glueby:contract:timestamp:create` task to broadcast the transaction to the Tapyrus Core Network and update status(init -> unconfirmed).
263
+
264
+ ```
265
+ bin/rails glueby:contract:timestamp:create
266
+ broadcasted (id=1, txid=8d602ca8ebdd50fa70b5ee6bc6351965b614d0a4843adacf9f43fedd7112fbf4)
267
+ ```
268
+
269
+ Run `glueby:block_syncer:start` task to confirm the transaction and update status(unconfirmed -> confirmded).
270
+
271
+ ```
272
+ bin/rails glueby:block_syncer:start
273
+ ```
274
+
275
+ ## Use fee provider mode
276
+
277
+ Glueby contracts have two different way of fee provisions.
278
+
279
+ 1. `:sender_pays_itself`
280
+ 2. `:fee_provider_bears`
281
+
282
+ The first one: `:sender_pays_itself`, is the default behavior.
283
+ In the second Fee Provider mode, the Fee Provider module pays a fee instead of the transaction's sender.
284
+
285
+ ### Fee Provider Specification
286
+
287
+ * Fee Provider pays fixed amount fee, and it is configurable.
288
+ * Fee Provider needs to have enough funds into their wallet.
289
+ * Fee Provider is managed to keep some number of UTXOs that have fixed fee value by rake tasks.
290
+
291
+ ### Setting up Fee Provider
292
+
293
+ 1. Set like below
294
+
295
+ ```ruby
296
+ Glueby.configure do |config|
297
+ # Use FeeProvider to supply inputs for fees on each transaction that is created on Glueby.
298
+ config.fee_provider_bears!
299
+ config.fee_provider_config = {
300
+ # The fee that Fee Provider pays on each transaction.
301
+ fixed_fee: 1000,
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.
304
+ utxo_pool_size: 20
305
+ }
306
+ end
307
+ ```
308
+
309
+ 2. Deposit TPC into Fee Provider's wallet
310
+
311
+ Get an address from the wallet.
312
+
313
+ ```
314
+ $ bundle exec rake glueby:fee_provider:address
315
+ mqYTLdLCUCCZkTkcpbVx1GqpvV1gK4euRD
316
+ ```
317
+
318
+ Send TPC to the address.
319
+
320
+ If you use `Glueby::Contract::Payment` to the sending, you can do like this:
321
+
322
+ ```ruby
323
+ Glueby::Contract::Payment.transfer(sender: sender, receiver_address: 'mqYTLdLCUCCZkTkcpbVx1GqpvV1gK4euRD', amount: 1_000_000)
324
+ ```
325
+
326
+ 3. Manage UTXO pool
327
+
328
+ The Fee Provider's wallet has to keep some UTXOs with `fixed_fee` amount for paying fees using `manage_utxo_pool` rake task below.
329
+ 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.
330
+
331
+ ```
332
+ $ bundle exec rake glueby:fee_provider:manage_utxo_pool
333
+ Status: Ready
334
+ TPC amount: 999_000
335
+ UTXO pool size: 20
336
+
337
+ Configuration:
338
+ fixed_fee = 1_000
339
+ utxo_pool_size = 20
340
+ ```
341
+
342
+ This shows that the UTXO pool has 20 UTXOs with `fixed_fee` amount for paying fees and has other UTXOs that never use for paying fees.
343
+ The sum of all the UTXOs that includes both kinds of UTXO is 999_000 tapyrus.
344
+
345
+ If the wallet doesn't have enough amount, the rake task shows an error like:
346
+
347
+ ```
348
+ $ bundle exec rake glueby:fee_provider:manage_utxo_pool
349
+ Status: Insufficient Amount
350
+ TPC amount: 15_000
351
+ UTXO pool size: 15
352
+
353
+ 1. Please replenishment TPC which is for paying fee to FeeProvider.
354
+ FeeProvider needs 21000 tapyrus at least for paying 20 transaction fees.
355
+ FeeProvider wallet's address is '1DBgMCNBdjQ1Ntz1vpwx2HMYJmc9kw88iT'
356
+ 2. Then create UTXOs for paying in UTXO pool with 'rake glueby:fee_provider:manage_utxo_pool'
357
+
358
+ Configuration:
359
+ fixed_fee = 1_000
360
+ utxo_pool_size = 20
361
+ ```
362
+
363
+ If you want to get the status information, you can use the `status` task.
364
+
365
+ ```
366
+ $ bundle exec rake glueby:fee_provider:status
367
+ Status: Ready
368
+ TPC amount: 999_000
369
+ UTXO pool size: 20
370
+
371
+ Configuration:
372
+ fixed_fee = 1_000
373
+ utxo_pool_size = 20
374
+ ```
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
+
447
+ ## Development
448
+
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.
450
+
451
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
452
+
453
+ ## Contributing
454
+
455
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/glueby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/tapyrus-contractrb/blob/master/CODE_OF_CONDUCT.md).
456
+
457
+ ## License
458
+
459
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
460
+
461
+ ## Code of Conduct
462
+
463
+ Everyone interacting in the Glueby project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/glueby/blob/master/CODE_OF_CONDUCT.md).