Class: Coinbase::SmartContract
- Inherits:
-
Object
- Object
- Coinbase::SmartContract
- Defined in:
- lib/coinbase/smart_contract.rb
Overview
A representation of a SmartContract on the blockchain. rubocop:disable Metrics/ClassLength
Class Method Summary collapse
-
.create_multi_token_contract(address_id:, wallet_id:, uri:) ⇒ SmartContract
Creates a new ERC1155 multi-token contract, that can subsequently be deployed to the blockchain.
-
.create_nft_contract(address_id:, wallet_id:, name:, symbol:, base_uri:) ⇒ SmartContract
Creates a new ERC721 token contract, that can subsequently be deployed to the blockchain.
-
.create_token_contract(address_id:, wallet_id:, name:, symbol:, total_supply:) ⇒ SmartContract
Creates a new ERC20 token contract, that can subsequently be deployed to the blockchain.
- .list ⇒ Object
-
.list_events(network_id:, protocol_name:, contract_address:, contract_name:, event_name:, from_block_height:, to_block_height:) ⇒ Enumerable<Coinbase::ContractEvent>
Returns a list of ContractEvents for the provided network, contract, and event details.
-
.normalize_abi(abi) ⇒ Array<Hash>
Normalizes an ABI from a String or Array of Hashes to an Array of Hashes.
-
.read(contract_address:, method:, network: Coinbase.default_network, abi: nil, args: {}) ⇒ Object
Reads data from a deployed smart contract.
-
.register(contract_address:, abi:, name: nil, network: Coinbase.default_network) ⇒ Object
Registers an externally deployed smart contract with the API.
Instance Method Summary collapse
-
#abi ⇒ Array<Hash>
Returns the ABI of the Smart Contract.
-
#contract_address ⇒ String
Returns the contract address of the SmartContract.
-
#deploy! ⇒ SmartContract
Deploys the signed SmartContract to the blockchain.
-
#deployer_address ⇒ String?
Returns the address of the deployer of the SmartContract, if deployed via CDP.
-
#external? ⇒ Boolean
Returns whether the SmartContract is an externally registered contract or a CDP managed contract.
-
#id ⇒ String
Returns the SmartContract ID.
-
#initialize(model) ⇒ SmartContract
constructor
Returns a new SmartContract object.
-
#inspect ⇒ String
Same as to_s.
-
#name ⇒ String
Returns the name of the SmartContract.
-
#network ⇒ Coinbase::Network
Returns the Network of the SmartContract.
-
#options ⇒ Coinbase::Client::SmartContractOptions?
Returns the options of the SmartContract, if deployed via CDP.
-
#reload ⇒ SmartContract
Reloads the Smart Contract model with the latest version from the server side.
-
#sign(key) ⇒ SmartContract
Signs the SmartContract deployment transaction with the given key.
-
#status ⇒ String
Returns the status of the SmartContract, if deployed via CDP.
-
#to_s ⇒ String
Returns a string representation of the SmartContract.
-
#transaction ⇒ Coinbase::Transaction
Returns the transaction, if deployed via CDP.
-
#type ⇒ Coinbase::Client::SmartContractType
Returns the type of the SmartContract.
- #update(name: nil, abi: nil) ⇒ Object
-
#wait!(interval_seconds = 0.2, timeout_seconds = 20) ⇒ SmartContract
Waits until the Smart Contract deployment is signed or failed by polling the server at the given interval.
-
#wallet_id ⇒ String
Returns the ID of the wallet that deployed the SmartContract, if deployed via CDP.
Constructor Details
#initialize(model) ⇒ SmartContract
Returns a new SmartContract object.
313 314 315 316 317 |
# File 'lib/coinbase/smart_contract.rb', line 313 def initialize(model) raise unless model.is_a?(Coinbase::Client::SmartContract) @model = model end |
Class Method Details
.create_multi_token_contract(address_id:, wallet_id:, uri:) ⇒ SmartContract
Creates a new ERC1155 multi-token contract, that can subsequently be deployed to the blockchain.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/coinbase/smart_contract.rb', line 116 def create_multi_token_contract( address_id:, wallet_id:, uri: ) contract = Coinbase.call_api do smart_contracts_api.create_smart_contract( wallet_id, address_id, { type: Coinbase::Client::SmartContractType::ERC1155, options: Coinbase::Client::MultiTokenContractOptions.new( uri: uri ).to_body } ) end new(contract) end |
.create_nft_contract(address_id:, wallet_id:, name:, symbol:, base_uri:) ⇒ SmartContract
Creates a new ERC721 token contract, that can subsequently be deployed to the blockchain.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/coinbase/smart_contract.rb', line 85 def create_nft_contract( address_id:, wallet_id:, name:, symbol:, base_uri: ) contract = Coinbase.call_api do smart_contracts_api.create_smart_contract( wallet_id, address_id, { type: Coinbase::Client::SmartContractType::ERC721, options: Coinbase::Client::NFTContractOptions.new( name: name, symbol: symbol, base_uri: base_uri ).to_body } ) end new(contract) end |
.create_token_contract(address_id:, wallet_id:, name:, symbol:, total_supply:) ⇒ SmartContract
Creates a new ERC20 token contract, that can subsequently be deployed to the blockchain.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/coinbase/smart_contract.rb', line 52 def create_token_contract( address_id:, wallet_id:, name:, symbol:, total_supply: ) contract = Coinbase.call_api do smart_contracts_api.create_smart_contract( wallet_id, address_id, { type: Coinbase::Client::SmartContractType::ERC20, options: Coinbase::Client::TokenContractOptions.new( name: name, symbol: symbol, total_supply: BigDecimal(total_supply).to_i.to_s ).to_body } ) end new(contract) end |
.list ⇒ Object
200 201 202 203 204 205 206 207 208 |
# File 'lib/coinbase/smart_contract.rb', line 200 def list Coinbase::Pagination.enumerate( lambda { |page| smart_contracts_api.list_smart_contracts(page: page) } ) do |smart_contract| new(smart_contract) end end |
.list_events(network_id:, protocol_name:, contract_address:, contract_name:, event_name:, from_block_height:, to_block_height:) ⇒ Enumerable<Coinbase::ContractEvent>
Returns a list of ContractEvents for the provided network, contract, and event details.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/coinbase/smart_contract.rb', line 17 def list_events( network_id:, protocol_name:, contract_address:, contract_name:, event_name:, from_block_height:, to_block_height: ) Coinbase::Pagination.enumerate( lambda { |page| list_events_page( network_id, protocol_name, contract_address, contract_name, event_name, from_block_height, to_block_height, page ) } ) do |contract_event| Coinbase::ContractEvent.new(contract_event) end end |
.normalize_abi(abi) ⇒ Array<Hash>
Normalizes an ABI from a String or Array of Hashes to an Array of Hashes.
214 215 216 217 218 219 220 221 222 |
# File 'lib/coinbase/smart_contract.rb', line 214 def normalize_abi(abi) return abi if abi.is_a?(Array) raise ArgumentError, 'ABI must be an Array or a JSON string' unless abi.is_a?(String) JSON.parse(abi) rescue JSON::ParserError raise ArgumentError, 'Invalid ABI JSON' end |
.read(contract_address:, method:, network: Coinbase.default_network, abi: nil, args: {}) ⇒ Object
Reads data from a deployed smart contract.
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/coinbase/smart_contract.rb', line 176 def read( contract_address:, method:, network: Coinbase.default_network, abi: nil, args: {} ) network = Coinbase::Network.from_id(network) response = Coinbase.call_api do smart_contracts_api.read_contract( network.normalized_id, contract_address, { method: method, args: (args || {}).to_json, abi: abi&.to_json }.compact ) end convert_solidity_value(response) end |
.register(contract_address:, abi:, name: nil, network: Coinbase.default_network) ⇒ Object
Registers an externally deployed smart contract with the API.
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/coinbase/smart_contract.rb', line 142 def register( contract_address:, abi:, name: nil, network: Coinbase.default_network ) network = Coinbase::Network.from_id(network) normalized_abi = normalize_abi(abi) smart_contract = Coinbase.call_api do smart_contracts_api.register_smart_contract( network.normalized_id, contract_address, register_smart_contract_request: { abi: normalized_abi.to_json, contract_name: name }.compact ) end new(smart_contract) end |
Instance Method Details
#abi ⇒ Array<Hash>
Returns the ABI of the Smart Contract.
354 355 356 |
# File 'lib/coinbase/smart_contract.rb', line 354 def abi JSON.parse(@model.abi) end |
#contract_address ⇒ String
Returns the contract address of the SmartContract.
335 336 337 |
# File 'lib/coinbase/smart_contract.rb', line 335 def contract_address @model.contract_address end |
#deploy! ⇒ SmartContract
Deploys the signed SmartContract to the blockchain.
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'lib/coinbase/smart_contract.rb', line 430 def deploy! raise ManageExternalContractError, 'deploy' if external? raise TransactionNotSignedError unless transaction.signed? @model = Coinbase.call_api do smart_contracts_api.deploy_smart_contract( wallet_id, deployer_address, id, { signed_payload: transaction.signature } ) end @transaction = Coinbase::Transaction.new(@model.transaction) self end |
#deployer_address ⇒ String?
Returns the address of the deployer of the SmartContract, if deployed via CDP. Returns nil for externally registered contracts.
348 349 350 |
# File 'lib/coinbase/smart_contract.rb', line 348 def deployer_address @model.deployer_address end |
#external? ⇒ Boolean
Returns whether the SmartContract is an externally registered contract or a CDP managed contract.
380 381 382 |
# File 'lib/coinbase/smart_contract.rb', line 380 def external? @model.is_external end |
#id ⇒ String
Returns the SmartContract ID. NOTE: This is not the contract address and is primarily used before the contract is deployed.
323 324 325 |
# File 'lib/coinbase/smart_contract.rb', line 323 def id @model.smart_contract_id end |
#inspect ⇒ String
Same as to_s.
490 491 492 |
# File 'lib/coinbase/smart_contract.rb', line 490 def inspect to_s end |
#name ⇒ String
Returns the name of the SmartContract.
341 342 343 |
# File 'lib/coinbase/smart_contract.rb', line 341 def name @model.contract_name end |
#network ⇒ Coinbase::Network
Returns the Network of the SmartContract.
329 330 331 |
# File 'lib/coinbase/smart_contract.rb', line 329 def network @network ||= Coinbase::Network.from_id(@model.network_id) end |
#options ⇒ Coinbase::Client::SmartContractOptions?
Returns the options of the SmartContract, if deployed via CDP. Returns nil for externally registered contracts.
374 375 376 |
# File 'lib/coinbase/smart_contract.rb', line 374 def @model. end |
#reload ⇒ SmartContract
Reloads the Smart Contract model with the latest version from the server side.
450 451 452 453 454 455 456 457 458 459 460 |
# File 'lib/coinbase/smart_contract.rb', line 450 def reload raise ManageExternalContractError, 'reload' if external? @model = Coinbase.call_api do smart_contracts_api.get_smart_contract(wallet_id, deployer_address, id) end @transaction = Coinbase::Transaction.new(@model.transaction) if @model.transaction self end |
#sign(key) ⇒ SmartContract
Signs the SmartContract deployment transaction with the given key. This is required before broadcasting the SmartContract.
419 420 421 422 423 424 |
# File 'lib/coinbase/smart_contract.rb', line 419 def sign(key) raise ManageExternalContractError, 'sign' if external? raise unless key.is_a?(Eth::Key) transaction.sign(key) end |
#status ⇒ String
Returns the status of the SmartContract, if deployed via CDP.
392 393 394 |
# File 'lib/coinbase/smart_contract.rb', line 392 def status transaction&.status end |
#to_s ⇒ String
Returns a string representation of the SmartContract.
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 |
# File 'lib/coinbase/smart_contract.rb', line 496 def to_s Coinbase.pretty_print_object( self.class, **{ network: network.id, contract_address: contract_address, type: type, name: name, # Fields only present for CDP managed contracts. status: status, deployer_address: deployer_address, options: .nil? ? nil : Coinbase.pretty_print_object('Options', **) }.compact ) end |
#transaction ⇒ Coinbase::Transaction
Returns the transaction, if deployed via CDP.
386 387 388 |
# File 'lib/coinbase/smart_contract.rb', line 386 def transaction @transaction ||= @model.transaction.nil? ? nil : Coinbase::Transaction.new(@model.transaction) end |
#type ⇒ Coinbase::Client::SmartContractType
Returns the type of the SmartContract.
367 368 369 |
# File 'lib/coinbase/smart_contract.rb', line 367 def type @model.type end |
#update(name: nil, abi: nil) ⇒ Object
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
# File 'lib/coinbase/smart_contract.rb', line 396 def update(name: nil, abi: nil) req = {} req[:contract_name] = name unless name.nil? req[:abi] = self.class.normalize_abi(abi).to_json unless abi.nil? @model = Coinbase.call_api do smart_contracts_api.update_smart_contract( network.normalized_id, contract_address, update_smart_contract_request: req ) end self end |
#wait!(interval_seconds = 0.2, timeout_seconds = 20) ⇒ SmartContract
Waits until the Smart Contract deployment is signed or failed by polling the server at the given interval. deployment to land on-chain, in seconds
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 |
# File 'lib/coinbase/smart_contract.rb', line 468 def wait!(interval_seconds = 0.2, timeout_seconds = 20) raise ManageExternalContractError, 'wait!' if external? start_time = Time.now loop do reload return self if transaction.terminal_state? if Time.now - start_time > timeout_seconds raise Timeout::Error, 'SmartContract deployment timed out. Try waiting again.' end self.sleep interval_seconds end self end |
#wallet_id ⇒ String
Returns the ID of the wallet that deployed the SmartContract, if deployed via CDP. Returns nil for externally registered contracts.
361 362 363 |
# File 'lib/coinbase/smart_contract.rb', line 361 def wallet_id @model.wallet_id end |