Class: Glueby::Contract::Token
- Inherits:
-
Object
- Object
- Glueby::Contract::Token
- Defined in:
- lib/glueby/contract/token.rb
Overview
This class represents custom token issued by application user. Application users can
-
issue their own tokens.
-
send to other users.
-
make the tokens disable.
Examples:
alice = Glueby::Wallet.create bob = Glueby::Wallet.create
Use ‘Glueby::Internal::Wallet#receive_address` to generate the address of bob bob.internal_wallet.receive_address
> ‘1CY6TSSARn8rAFD9chCghX5B7j4PKR8S1a’
Issue token = Token.issue!(issuer: alice, amount: 100) token.amount(wallet: alice)
> 100
Send token.transfer!(sender: alice, receiver_address: ‘1CY6TSSARn8rAFD9chCghX5B7j4PKR8S1a’, amount: 1) token.amount(wallet: alice)
> 99
token.amount(wallet: bob)
> 1
Burn token.burn!(sender: alice, amount: 10) token.amount(wallet: alice)
> 89
token.burn!(sender: alice) token.amount(wallet: alice)
> 0
Reissue token.reissue!(issuer: alice, amount: 100) token.amount(wallet: alice)
> 100
Issue with metadata / Get metadata token = Token.issue!(issuer: alice, amount: 100, metadata: ‘metadata’) token.metadata
> “metadata”
Instance Attribute Summary collapse
-
#color_id ⇒ Object
readonly
Returns the value of attribute color_id.
Class Method Summary collapse
-
.issue!(issuer:, token_type: Tapyrus::Color::TokenTypes::REISSUABLE, amount: 1, split: 1, fee_estimator: FeeEstimator::Fixed.new, metadata: nil) ⇒ Array<token, Array<tx>>
Issue new token with specified amount and token type.
- .only_finalized? ⇒ Boolean
-
.parse_from_payload(payload) ⇒ Glueby::Contract::Token
Restore token from payload.
Instance Method Summary collapse
-
#amount(wallet:) ⇒ Integer
Return balance of token in the specified wallet.
-
#burn!(sender:, amount: 0, fee_estimator: FeeEstimator::Fixed.new) ⇒ Object
Burn token If amount is not specified or 0, burn all token associated with the wallet.
-
#initialize(color_id:) ⇒ Token
constructor
Generate Token Instance.
-
#metadata ⇒ String
Return metadata for this token.
-
#multi_transfer!(sender:, receivers:, fee_estimator: FeeEstimator::Fixed.new) ⇒ Array<String, tx>
Send the tokens to multiple wallets.
-
#p2c_address ⇒ String
Return pay to contract address.
-
#payment_base ⇒ String
Return public key used to generate pay to contract address.
-
#reissue!(issuer:, amount:, split: 1, fee_estimator: FeeEstimator::Fixed.new) ⇒ Array<String, tx>
Re-issue the token with specified amount.
-
#script_pubkey ⇒ String
Return the script_pubkey of the token from ActiveRecord.
-
#to_payload ⇒ String
Return serialized payload.
-
#token_metadata ⇒ Glueby::Contract::AR::TokenMetadata
Return Glueby::Contract::AR::TokenMetadata instance for this token.
-
#token_type ⇒ Tapyrus::Color::TokenTypes
Return token type.
-
#transfer!(sender:, receiver_address:, amount: 1, fee_estimator: FeeEstimator::Fixed.new) ⇒ Array<String, tx>
Send the token to other wallet.
Constructor Details
#initialize(color_id:) ⇒ Token
Generate Token Instance
439 440 441 |
# File 'lib/glueby/contract/token.rb', line 439 def initialize(color_id:) @color_id = color_id end |
Instance Attribute Details
#color_id ⇒ Object (readonly)
Returns the value of attribute color_id.
230 231 232 |
# File 'lib/glueby/contract/token.rb', line 230 def color_id @color_id end |
Class Method Details
.issue!(issuer:, token_type: Tapyrus::Color::TokenTypes::REISSUABLE, amount: 1, split: 1, fee_estimator: FeeEstimator::Fixed.new, metadata: nil) ⇒ Array<token, Array<tx>>
Issue new token with specified amount and token type. REISSUABLE token can be reissued with #reissue! method, and NON_REISSUABLE and NFT token can not. Amount is set to 1 when the token type is NFT
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/glueby/contract/token.rb', line 68 def issue!(issuer:, token_type: Tapyrus::Color::TokenTypes::REISSUABLE, amount: 1, split: 1, fee_estimator: FeeEstimator::Fixed.new, metadata: nil) raise Glueby::Contract::Errors::InvalidAmount unless amount.positive? raise Glueby::Contract::Errors::InvalidSplit if token_type == Tapyrus::Color::TokenTypes::NFT && split > 1 txs, color_id = case token_type when Tapyrus::Color::TokenTypes::REISSUABLE issue_reissuable_token(issuer: issuer, amount: amount, split: split, fee_estimator: fee_estimator, metadata: ) when Tapyrus::Color::TokenTypes::NON_REISSUABLE issue_non_reissuable_token(issuer: issuer, amount: amount, split: split, fee_estimator: fee_estimator, metadata: ) when Tapyrus::Color::TokenTypes::NFT issue_nft_token(issuer: issuer, metadata: ) else raise Glueby::Contract::Errors::UnsupportedTokenType end [new(color_id: color_id), txs] end |
.only_finalized? ⇒ Boolean
85 86 87 |
# File 'lib/glueby/contract/token.rb', line 85 def only_finalized? Glueby::AR::SystemInformation.use_only_finalized_utxo? end |
.parse_from_payload(payload) ⇒ Glueby::Contract::Token
Restore token from payload
426 427 428 429 430 431 432 433 434 435 |
# File 'lib/glueby/contract/token.rb', line 426 def self.parse_from_payload(payload) color_id, script_pubkey = payload.unpack('a33a*') color_id = Tapyrus::Color::ColorIdentifier.parse_from_payload(color_id) if color_id.type == Tapyrus::Color::TokenTypes::REISSUABLE raise ArgumentError, 'script_pubkey should not be empty' if script_pubkey.empty? script_pubkey = Tapyrus::Script.parse_from_payload(script_pubkey) Glueby::Contract::AR::ReissuableToken.create!(color_id: color_id.to_hex, script_pubkey: script_pubkey.to_hex) end new(color_id: color_id) end |
Instance Method Details
#amount(wallet:) ⇒ Integer
Return balance of token in the specified wallet.
370 371 372 373 374 375 |
# File 'lib/glueby/contract/token.rb', line 370 def amount(wallet:) amount, _utxos = wallet .internal_wallet .collect_colored_outputs(color_id, nil, nil, only_finalized?) amount end |
#burn!(sender:, amount: 0, fee_estimator: FeeEstimator::Fixed.new) ⇒ Object
Burn token If amount is not specified or 0, burn all token associated with the wallet.
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/glueby/contract/token.rb', line 345 def burn!(sender:, amount: 0, fee_estimator: FeeEstimator::Fixed.new) raise Glueby::Contract::Errors::InvalidAmount unless amount.positive? balance = sender.balances(only_finalized?)[color_id.to_hex] raise Glueby::Contract::Errors::InsufficientTokens unless balance raise Glueby::Contract::Errors::InsufficientTokens if balance < amount builder = Internal::ContractBuilder .new( sender_wallet: sender.internal_wallet, fee_estimator: fee_estimator, use_unfinalized_utxo: !only_finalized?, use_auto_fulfill_inputs: true ) .burn(amount, color_id) .change_address(sender.internal_wallet.receive_address, color_id) Glueby::AR.transaction(isolation: :read_committed) do tx = builder.build sender.internal_wallet.broadcast(tx) end end |
#metadata ⇒ String
Return metadata for this token
379 380 381 |
# File 'lib/glueby/contract/token.rb', line 379 def &. end |
#multi_transfer!(sender:, receivers:, fee_estimator: FeeEstimator::Fixed.new) ⇒ Array<String, tx>
Send the tokens to multiple wallets
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/glueby/contract/token.rb', line 311 def multi_transfer!(sender:, receivers:, fee_estimator: FeeEstimator::Fixed.new) receivers.each do |r| raise Glueby::Contract::Errors::InvalidAmount unless r[:amount].positive? end txb = Internal::ContractBuilder .new( sender_wallet: sender.internal_wallet, fee_estimator: fee_estimator, use_unfinalized_utxo: !only_finalized?, use_auto_fulfill_inputs: true ) .change_address(sender.internal_wallet.receive_address, color_id) receivers.each do |r| txb.pay(r[:address], r[:amount].to_i, color_id) end tx = nil Glueby::AR.transaction(isolation: :read_committed) do tx = sender.internal_wallet.broadcast(txb.build) end [color_id, tx] end |
#p2c_address ⇒ String
Return pay to contract address
385 386 387 |
# File 'lib/glueby/contract/token.rb', line 385 def p2c_address &.p2c_address end |
#payment_base ⇒ String
Return public key used to generate pay to contract address
391 392 393 |
# File 'lib/glueby/contract/token.rb', line 391 def payment_base &.payment_base end |
#reissue!(issuer:, amount:, split: 1, fee_estimator: FeeEstimator::Fixed.new) ⇒ Array<String, tx>
Re-issue the token with specified amount. A wallet can issue the token only when it is REISSUABLE token.
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/glueby/contract/token.rb', line 243 def reissue!(issuer:, amount:, split: 1, fee_estimator: FeeEstimator::Fixed.new) raise Glueby::Contract::Errors::InvalidAmount unless amount.positive? raise Glueby::Contract::Errors::InvalidTokenType unless token_type == Tapyrus::Color::TokenTypes::REISSUABLE = Glueby::Contract::AR::TokenMetadata.find_by(color_id: color_id.to_hex) raise Glueby::Contract::Errors::UnknownScriptPubkey unless valid_reissuer?(wallet: issuer, token_metadata: ) txb = Internal::ContractBuilder.new( sender_wallet: issuer.internal_wallet, fee_estimator: fee_estimator, use_auto_fulfill_inputs: true ) if txb.add_p2c_utxo_to!( metadata: , amount: FeeEstimator::Fixed.new.fixed_fee, p2c_address: .p2c_address, payment_base: .payment_base, only_finalized: only_finalized?, fee_estimator: Contract::FeeEstimator::Fixed.new ) else txb.add_utxo_to!( address: @script_pubkey.to_addr, amount: FeeEstimator::Fixed.new.fixed_fee, only_finalized: only_finalized?, fee_estimator: Contract::FeeEstimator::Fixed.new ) end tx = txb.reissuable_split(@script_pubkey, issuer.internal_wallet.receive_address, amount, split) .build tx = issuer.internal_wallet.broadcast(tx) [color_id, tx] end |
#script_pubkey ⇒ String
Return the script_pubkey of the token from ActiveRecord
410 411 412 |
# File 'lib/glueby/contract/token.rb', line 410 def script_pubkey @script_pubkey ||= Glueby::Contract::AR::ReissuableToken.script_pubkey(@color_id.to_hex) end |
#to_payload ⇒ String
Return serialized payload
416 417 418 419 420 421 |
# File 'lib/glueby/contract/token.rb', line 416 def to_payload payload = +'' payload << @color_id.to_payload payload << @script_pubkey.to_payload if script_pubkey payload end |
#token_metadata ⇒ Glueby::Contract::AR::TokenMetadata
Return Glueby::Contract::AR::TokenMetadata instance for this token
397 398 399 400 |
# File 'lib/glueby/contract/token.rb', line 397 def return @token_metadata if defined? @token_metadata @token_metadata = Glueby::Contract::AR::TokenMetadata.find_by(color_id: color_id.to_hex) end |
#token_type ⇒ Tapyrus::Color::TokenTypes
Return token type
404 405 406 |
# File 'lib/glueby/contract/token.rb', line 404 def token_type color_id.type end |
#transfer!(sender:, receiver_address:, amount: 1, fee_estimator: FeeEstimator::Fixed.new) ⇒ Array<String, tx>
Send the token to other wallet
292 293 294 295 296 297 298 299 300 |
# File 'lib/glueby/contract/token.rb', line 292 def transfer!(sender:, receiver_address:, amount: 1, fee_estimator: FeeEstimator::Fixed.new) multi_transfer!( sender: sender, receivers: [{ address: receiver_address, amount: amount }], fee_estimator: fee_estimator) end |