2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Upgrading from Plugin Node V1 to V2 Using Hard Reset

Last updated at Posted at 2024-01-03

Introduction

This guide provides instructions on how to upgrade from Plugin Node 1.0 to 2.0. The official Plugin documentation recommends performing a hard or soft reset of the V1 node before setting up V2. Here, we will guide you through performing a hard reset, setting up Plugin 2.0, and obtaining a new node address. If you happen to own a Plugin 1.0 node set up with Docker, a hard reset is likely the best option.

【日本語】

このガイドは、Plugin Node 1.0から2.0へ、アップグレードを行う方法を提供しています。Plugin公式ドキュメントでは、V1ノードをハードリセットまたはソフトリセットをしてからV2をセットアップするようにと書かれています。。ここではハードリセットを実行してから、Plugin2.0をセットアップし、新しいノードアドレスを取得する方法をガイドします。また、もしもあなたがDockerでセットアップしたPlugin1.0ノードを所有している場合も、おそらくこのハードリセットが一番良い選択肢になるでしょう。

Screenshot by Dropbox Capture.png

1. Processing on V1 nodes

On Plugin Node 1.0, we perform the following five steps:

Pluginノード1.0上で、以下の5つの手順を実行します:

  1. Updating Linux systems
  2. Output a JSON file of Node Address
  3. Initializing Backup Folder and Permissions Setup
  4. Store the necessary files in the backup directory
  5. VPS Hard Reset
【日本語】
  1. Linuxシステム更新
  2. ノードアドレスのJSONファイルを出力
  3. バックアップフォルダと権限のセットアップの初期化
  4. backupディレクトリに必要なファイルを格納
  5. VPSのハードリセット

1-1. Plugin Node Preparation Commands

Commands for updating Linux systems, installing tools, configuring security, and cleaning for plugin node setup.

プラグインノード用のLinuxシステム更新、ツールインストール、セキュリティ設定、クリーニングのコマンド群

1-1
sudo apt update -y && sudo apt upgrade -y && sudo apt install -y git nano ufw curl tree htop && sudo apt autoremove -y && sudo apt autoclean -y && sudo timedatectl set-timezone UTC

1-2. Node Address Keystore File Output

The command outputs the node address keystore file to the home directory.

ノードアドレスのキーストアファイルをホームディレクトリに出力します。

1-2
cd ~/plugin-deployment/ && ./pli_node_scripts.sh keys

Screenshot by Dropbox Capture.png

1-3. Perform Full Backup Before Upgrading to V2

Initializing Backup Folder and Permissions Setup

Lets now run the setup script to ensure that the backup folder & permissions are in place.

バックアップフォルダと権限が整っていることを確認するために、セットアップスクリプトを実行しましょう。

1-3-1
./_plinode_setup_bkup.sh

Perform Full Backup

Before upgrading to Plugin Node 2.0, it is recommended to perform a full backup in Plugin Node 1.0 (using commands 1-3-2). Additionally, create a directory named originals/pluginV1 within the /plinode_backups/ directory and copy the relevant files from Plugin Node 1.0 (using commands 1-3-3).

【日本語】

Plugin Node 2.0にアップグレードする前に、1.0でフルバックアップを実行し(コマンド1-3-2)、さらに/plinode_backups/ディレクトリ内にoriginals/pluginV1ディレクトリを作成し、Plugin Node 1.0の関連するファイルをコピー(コマンド1-3-3)しておくことをお勧めします。

1-3-2
cd ~/plugin-deployment/ && ./_plinode_backup.sh -full

Screenshot by Dropbox Capture.png

1-3-3
mkdir -p /plinode_backups/originals/pluginV1/ && cd ~/plugin-deployment/ && cp -u 2_nodeStartPM2.sh 3_initiatorStartPM2.sh .env.apicred .env.password /plinode_backups/originals/pluginV1/ && cd ~ && cp -u plinode_$(hostname -f).vars plinode_$(hostname -f)_keys*.json /plinode_backups/originals/pluginV1/ && tree -a /plinode_backups/ 

Screenshot by Dropbox Capture.png

1-4. Transferring the Backup Directory to Your Local PC

Use SFTP or a similar method to transfer the /plinode_backups/ directory to your local PC. In the screenshot, I am using Turmius. Of course, it is also possible to execute commands.

【日本語】

SFTPなどを使用して、/plinode_backups/ディレクトリをローカルPCに転送してください。スクリーンショットでは、Turmiusを使っています。もちろんコマンドで実行することも可能です。

Screenshot by Dropbox Capture.png

1-5. VPS Dashboard Ubuntu 20.04 Hard Reset

Please perform a hard reset (reinstallation of Ubuntu 20.04) from your VPS service provider's dashboard. Once the hard reset is complete, please proceed to the next step.

VPSサービスプロバイダーのダッシュボードからハードリセット(Ubuntu 20.04の再インストール)を実行してください。ハードリセットが完了したら、次へ進んでください。

2. Build V2 Node

Upgrade to V2 Node.

  1. Updating Linux systems
  2. Download the script pluginV2Install
  3. Run setup script
  4. Depositing XDC and PLI into Node Address
【日本語】

V2 Nodeにアップグレードしていきます。

  1. Linuxシステム更新
  2. pluginV2Installスクリプトをダウンロード
  3. セットアップスクリプトの実行
  4. Node Addressに1XDCと1PLIを入金

2-1. Updating Linux systems

Commands for updating Linux systems, installing tools, configuring security, and cleaning for plugin node setup.

プラグインノード用のLinuxシステム更新、ツールインストール、セキュリティ設定、クリーニングのコマンド群

2-1
sudo apt update -y && sudo apt upgrade -y && sudo apt install -y git nano ufw curl tree htop && sudo apt autoremove -y && sudo apt autoclean -y && sudo timedatectl set-timezone UTC

2-2. git clone pluginV2Install

2-2-1
cd && git clone https://github.com/GoPlugin/pluginV2Install.git
cd ~/pluginV2Install/
chmod +x *.sh

Screenshot by Dropbox Capture.png

------ Important ------

On December 25, 2023, at 17:10

The mainnet RPC is set to https://erpc.xinfin.network by default, but I have noticed that it can be unstable at times. Therefore, personally, I believe it would be desirable to change it to https://earpc.xinfin.network. The following commands are used to change the https://erpc.xinfin.network string to https://earpc.xinfin.network in the ~/pluginV2Install/sample.vars file. Finally, please verify if the change has been made correctly using the grep command.

【日本語】

2023年12月25日、17時10分
メインネットのRPCはデフォルトで https://erpc.xinfin.network に設定されていますが、時に不安定であることが確認されています。そのため、個人的には https://earpc.xinfin.network に変更することが望ましいと考えています。次のコマンドは、~/pluginV2Install/sample.vars ファイル内の https://erpc.xinfin.network という文字列を https://earpc.xinfin.network に変更するためのものです。最後に、変更が正しく行われたかを確認するために grep コマンドを使用してください。

Before After
https://erpc.xinfin.network https://earpc.xinfin.network
2-2-2
sed -i -e "s|https://erpc.xinfin.network|https://earpc.xinfin.network|g" ~/pluginV2Install/sample.vars
grep "mainnet_httpUrl" ~/pluginV2Install/sample.vars

Screenshot by Dropbox Capture.png

2-3. Run setup script

2-3-1
./pli_node_scripts.sh mainnet

Important
Confirm the script is complete and follow the instructions to run the command below.

重要
スクリプトが完了していることを確認して、指示に従って下記コマンドを実行してください。

2-3-2
source ~/.profile

Screenshot by Dropbox Capture.png

2-4. Depositing XDC and PLI into Node Address for Testing

Use XDCPay or MetaMask to deposit 1 XDC and 1 PLI into the NodeAddress for testing. Please ensure the amount is within the maximum limit of 10 XDC and 5 PLI.

  1. Click on the gear icon located in the top right corner of the dashboard.
  2. Click on 'Key Management'.
  3. Scroll down to the bottom of the screen and locate the 'Address' under 'EVM Chain Accounts'. This will be your 'Node Address'.
  4. Send 1XDC and 1PLI to this Node Address.
  5. Verify that the balances of XDC and PLI have increased.
【日本語】

XDCPayまたはMetaMaskを使って、テストに必要な 1 XDCと 1 PLIをNodeAddressに入金します。最大でも 10 XDC、5 PLI以内にしてください。

  1. ダッシュボードの右上にある歯車のアイコンをクリックします。
  2. 「Key Management」をクリックします。
  3. 画面の下部までスクロールし、「EVM Chain Accounts」の下にある「Address」を探します。これがあなたの「Node Address」になります。
  4. このNode Addressに1XDCと1PLIを送ります。
  5. XDCとPLIの残高が増加したことを確認します。

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

The upgrade of the plugin node is now complete.

以上でプラグインノードのアップグレードは完了です。

3. Backup After Plugin V2 Upgrade

Once you have confirmed the successful import of the V1 node address into the dashboard, it is recommended to perform a backup.

V1ノードアドレスがダッシュボードに正常にインポートされたことを確認したら、バックアップを実行することをおすすめします。

3-1. Initializing Backup Folder and Permissions Setup

Lets now run the setup script to ensure that the backup folder & permissions are in place.

バックアップフォルダと権限が整っていることを確認するために、セットアップスクリプトを実行しましょう。

3-1
cd ~/pluginV2Install/ && ./_plinode_setup_bkup.sh

3-2. Full Backup

Run the following commands to perform a FULL backup. As per the usage above this backups up both the conf files & the db.

以下のコマンドを実行して、完全なバックアップを実行してください。上記の使用法に従い、設定ファイルとデータベースの両方をバックアップします。

3-2
cd ~/pluginV2Install/ && ./_plinode_backup.sh -full

3-3. Create originals/pluginV2 Directory and Copy Relevant Files

After a successful upgrade to Plugin Node 2.0, create a directory named originals/pluginV2 within the /plinode_backups/ directory and copy the relevant files from that moment into it.

Plugin Node 2.0のアップグレードが成功した場合、/plinode_backups/ディレクトリ内にoriginals/pluginV2ディレクトリを作成し、その時点で関連するファイルをコピーしてください。

3-3
mkdir -p /plinode_backups/originals/pluginV2 && cd ~/pluginV2/ && cp -u ~/pluginV2/apicredentials.txt config.toml secrets.toml /plinode_backups/originals/pluginV2/ && cd ~ &&cp -u ~/plinode_$(hostname -f).vars plinode_$(hostname -f)_keys*.json /plinode_backups/originals/pluginV2/ && tree -a /plinode_backups/

Screenshot by Dropbox Capture.png

3-4. Transferring the Backup Directory to Your Local PC

Use SFTP or a similar method to transfer the /plinode_backups/ directory to your local PC. In the screenshot, I am using Turmius. Of course, it is also possible to execute commands.

【日本語】

SFTPなどを使用して、/plinode_backups/ディレクトリをローカルPCに転送してください。スクリーンショットでは、Turmiusを使っています。もちろんコマンドで実行することも可能です。

Screenshot by Dropbox Capture.png

4. Setup of Job and Deployment of Contract

4-1. Oracle Contract

Using Remix, create an Oracle contract.

17-1
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
import "@goplugin/contracts2_3/src/v0.7/Operator.sol";

/**
* A. Pli Mainnet Token: 0xFf7412Ea7C8445C46a8254dFB557Ac1E48094391
* A. Pli Apothem Token: 0x33f4212b027E22aF7e6BA21Fc572843C0D701CD1
*/

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

Please enter the contract address of PLI (either on the mainnet or Apothem) and your Wallet Address (replace "xdc" at the beginning with "0x").

Your Wallet Address will be the owner of this contract.

PLI Mainnet Contract Address
0xFf7412Ea7C8445C46a8254dFB557Ac1E48094391
PLI Apothem Contract Address
0x33f4212b027E22aF7e6BA21Fc572843C0D701CD1

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

PLI Mainnet Contract Address
0xFf7412Ea7C8445C46a8254dFB557Ac1E48094391
PLI Apothem Contract Address
0x33f4212b027E22aF7e6BA21Fc572843C0D701CD1

4-2. Job setup

Sample Job Code - Cryptocompare -
type = "directrequest"
schemaVersion = 1
name = "Sample Request Cryptocompare_XDC_USD"
# It is recommended to give a memorable name to 'name'. 
# You can use it for searching later.
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
# Please replace contractAddress with your oracle address.
minContractPaymentLinkJuels = "0"
observationSource = """
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"]
 
decode_cbor [type="cborparse" data="$(decode_log.data)"]
 
fetch [type="http" method=GET url="https://min-api.cryptocompare.com/data/price?fsym=XDC&tsyms=USD"]
parse [type="jsonparse" path="USD" data="$(fetch)"]
 
multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"]
 
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"]
 
encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ]
 
submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"] //paste the Oracle Address which you deployed in ‘to’ field
 
decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""
# Please paste your Oracle Address in the 'to' field on the second line from the bottom.

JOB SETUP

  1. The value of the name key should be changed.
  2. The Oracle Address will be changed in two locations.
  3. The URL will be modified.
    Regarding CMC, the APIKEY will be updated.
  4. The path will be modified.

# Cryptocompare

Sample Job Code - Cryptocompare -
Sample Job Code - Cryptocompare -
type = "directrequest"
schemaVersion = 1
name = "Sample Request Cryptocompare_XDC_USD"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"]
 
decode_cbor [type="cborparse" data="$(decode_log.data)"]
 
fetch [type="http" method=GET url="https://min-api.cryptocompare.com/data/price?fsym=XDC&tsyms=USD"]
parse [type="jsonparse" path="USD" data="$(fetch)"]
 
multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"]
 
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"]
 
encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ]
 
submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"] //paste the Oracle Address which you deployed in ‘to’ field
 
decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""

# Coingecko

Sample Job Code - Coingecko -
Sample Job Code - Coingecko -
type = "directrequest"
schemaVersion = 1
name = "Sample Request CoinGecko_PLI_USD"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"]
 
decode_cbor [type="cborparse" data="$(decode_log.data)"]
 
fetch [type="http" method=GET url="https://api.coingecko.com/api/v3/simple/price?include_last_updated_at=true&precision=10&ids=plugin&vs_currencies=usd"]
parse [type="jsonparse" path="plugin,usd" data="$(fetch)"]
 
multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"]
 
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"]
 
encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ]
 
submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"] //paste the Oracle Address which you deployed in ‘to’ field
 
decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""

# Binance

Sample Job Code - Binance -
Sample Job Code - Binance -
type = "directrequest"
schemaVersion = 1
name = "Sample Request Binance_XRP_USDT"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"]
 
decode_cbor [type="cborparse" data="$(decode_log.data)"]
 
fetch [type="http" method=GET url="https://api1.binance.com/api/v3/ticker/price?symbol=XRPUSDT"]
parse [type="jsonparse" path="price" data="$(fetch)"]
 
multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"]
 
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"]
 
encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ]
 
submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"] //paste the Oracle Address which you deployed in ‘to’ field
 
decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""

# Bitrue

Sample Job Code - Bitrue -
Sample Job Code - Bitrue -
type = "directrequest"
schemaVersion = 1
name = "Sample Request Bitrue_XDC_USDT"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"]
 
decode_cbor [type="cborparse" data="$(decode_log.data)"]
 
fetch [type="http" method=GET url="https://openapi.bitrue.com/api/v1/ticker/price?symbol=XDCUSDT"]
parse [type="jsonparse" path="price" data="$(fetch)"]
 
multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"]
 
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"]
 
encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ]
 
submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"] //paste the Oracle Address which you deployed in ‘to’ field
 
decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""

# Kucoin

Sample Job Code - Kucoin -
Sample Job Code - Kucoin -
type = "directrequest"
schemaVersion = 1
name = "Sample Request Kucoin_XDC_USDT"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"]
 
decode_cbor [type="cborparse" data="$(decode_log.data)"]
 
fetch [type="http" method=GET url="https://api.kucoin.com/api/v1/market/orderbook/level1?symbol=XDC-USDT"]
parse [type="jsonparse" path="data,price" data="$(fetch)"]
 
multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"]
 
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"]
 
encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ]
 
submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"] //paste the Oracle Address which you deployed in ‘to’ field
 
decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""

# CMC / CoinMarcketCap

  • Please change YOUR_API_KEY to your own API.
fetch [type=http method=GET url="https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?symbol=XDC&convert=USDT" allowUnrestrictedNetworkAccess="true" headers="[\\"X-CMC_PRO_API_KEY\\", \\"YOUR_API_KEY\\"]"]
  • parse [type="jsonparse" path="data,XDC,0,quote,USDT,price" data="$(fetch)"]
Sample Job Code - CMC -
Sample Job Code - CMC -
type = "directrequest"
schemaVersion = 1
name = "CMC_XDC-USD"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
 
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"] 

decode_cbor [type="cborparse" data="$(decode_log.data)"] 

fetch [type=http method=GET url="https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?symbol=XDC&convert=USDT" allowUnrestrictedNetworkAccess="true" headers="[\\"X-CMC_PRO_API_KEY\\", \\"YOUR_API_KEY\\"]"]

parse [type="jsonparse" path="data,XDC,0,quote,USDT,price" data="$(fetch)"]

multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"] 

encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"] 

encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)" 
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ] 

submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"]

decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx 
"""

# Coinranking

fetch [type=http method=GET url="https://api.coinranking.com/v2/coin/77jGXSqWJ1ofG?referenceCurrencyUuid=yhjMzLPhuIDl" allowUnrestrictedNetworkAccess="true" headers="[\\"x-access-token\\", \\"YOUR_API_KEY\\"]"]
  • path="data,coin,price"
Sample Job Code - coinranking -
Sample Job Code - Coinranking -
type = "directrequest"
schemaVersion = 1
name = "Coinranking_XDC-USD"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
 
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"] 

decode_cbor [type="cborparse" data="$(decode_log.data)"] 

fetch [type=http method=GET url="https://api.coinranking.com/v2/coin/77jGXSqWJ1ofG?referenceCurrencyUuid=yhjMzLPhuIDl" allowUnrestrictedNetworkAccess="true" headers="[\\"x-access-token\\", \\"YOUR_API_KEY\\"]"]

parse [type="jsonparse" path="data,coin,price" data="$(fetch)"] 

multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"] 

encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"] 

encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)" 
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ] 

submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"]

decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx 
"""

# Coinpaprika

Coinpaprika - Free
fetch [type=http method=GET url="https://api.coinpaprika.com/v1/tickers/cgo-comtech-gold?quotes=USD" allowUnrestrictedNetworkAccess="true"]
Coinpaprika - Paid
fetch [type=http method=GET url="https://api-pro.coinpaprika.com/v1/tickers/cgo-comtech-gold?quotes=USD" allowUnrestrictedNetworkAccess="true" headers="[\\"Authorization\\", \\"YOUR_API_KEY\\"]"]
Sample Job Code - Coinpaprika -
Sample Job Code - Coinpaprika -
type = "directrequest"
schemaVersion = 1
name = "Coinpaprika_CGO-USD"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
 
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"] 

decode_cbor [type="cborparse" data="$(decode_log.data)"] 

fetch [type=http method=GET url="https://api.coinpaprika.com/v1/tickers/cgo-comtech-gold?quotes=USD" allowUnrestrictedNetworkAccess="true" headers="[\\"Authorization\\", \\"YOUR_API_KEY\\"]"]
parse [type="jsonparse" path="quotes,USD,price" data="$(fetch)"] 

multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"] 

encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"] 

encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)" 
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ] 

submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"]

decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx 
"""

# Tradermade

Tradermade
fetch [type=http method=GET url="https://marketdata.tradermade.com/api/v1/live?api_key=YOUR_API_KEY&currency=USDJPY" allowUnrestrictedNetworkAccess="true"]
Sample Job Code - Tradermade -
Sample Job Code - Tradermade -
type = "directrequest"
schemaVersion = 1
name = "Tradermade_USD-JPY"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
 
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"] 

decode_cbor [type="cborparse" data="$(decode_log.data)"] 

fetch [type=http method=GET url="https://marketdata.tradermade.com/api/v1/live?api_key=YOUR_API_KEY&currency=USDJPY" allowUnrestrictedNetworkAccess="true"]
parse [type="jsonparse" path="quotes,0,mid" data="$(fetch)"] 

multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"] 

encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"] 

encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)" 
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ] 

submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"]

decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx 
"""

# Bitfinex

Bitfinex
fetch [type=http method=GET url="https://api-pub.bitfinex.com/v2/ticker/tXDCUSD" allowUnrestrictedNetworkAccess="true"]
parse [type="jsonparse" path="6" data="$(fetch)"] 
Sample Job Code - Bitfinex -
Sample Job Code - Bitfinex -
type = "directrequest"
schemaVersion = 1
name = "Bitfirex_XDC-USD"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
 
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"] 

decode_cbor [type="cborparse" data="$(decode_log.data)"] 

fetch [type=http method=GET url="https://api-pub.bitfinex.com/v2/ticker/tXDCUSD" allowUnrestrictedNetworkAccess="true"]
parse [type="jsonparse" path="6" data="$(fetch)"] 

multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"] 

encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"] 

encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)" 
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ] 

submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"]

decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx 
"""

# BitMart

Bitfinex
fetch [type="http" method=GET url="https://api-cloud.bitmart.com/spot/quotation/v3/ticker?symbol=PLI_USDT"]
parse [type="jsonparse" path="data,last" data="$(fetch)"]
Sample Job Code - BitMart -
Sample Job Code - BitMart -
type = "directrequest"
schemaVersion = 1
name = "Sample Request BitMart_PLI_USDT"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
minContractPaymentLinkJuels = "0"
observationSource = """
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"]
 
decode_cbor [type="cborparse" data="$(decode_log.data)"]
 
fetch [type="http" method=GET url="https://api-cloud.bitmart.com/spot/quotation/v3/ticker?symbol=PLI_USDT"]
parse [type="jsonparse" path="data,last" data="$(fetch)"]
 
multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"]
 
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"]
 
encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ]
 
submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"] //paste the Oracle Address which you deployed in ‘to’ field
 
decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""

Bitrue
Screenshot by Dropbox Capture.png

Cryptocomapre
Screenshot by Dropbox Capture.png

Get the JOBID and remove the hyphen -.

JOBIDを取得し、ハイフン-を取り除きます。

Screenshot by Dropbox Capture.png

4-3. CONSUMER CONTRACT

I will create a smart contract using Remix.

Remixを使って、スマートコントラクトを作成します。

Please feel free to make any necessary modifications to the following:

  • Mainnet or Apothem
    • Mainnet - 0xFf7412Ea7C8445C46a8254dFB557Ac1E48094391
    • Apothem - 0x33f4212b027E22aF7e6BA21Fc572843C0D701CD1
  • Oracle Address
    • Please change the leading 'xdc' to '0x'.
  • JOBID
    • Please remove the hyphen -.
  • API(peer)
    • Please make the URL the same as when creating the JOB.

Screenshot by Dropbox Capture.png

Consumer Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;


import "@goplugin/contracts2_3/src/v0.8/PluginClient.sol";
import "@goplugin/contracts2_3/src/v0.8/ConfirmedOwner.sol";

/**
* THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
* THIS EXAMPLE USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/


contract APIConsumer is PluginClient, ConfirmedOwner {
using Plugin for Plugin.Request;


uint256 public volume;
bytes32 private jobId;
uint256 private fee;


event RequestVolume(bytes32 indexed requestId, uint256 volume);


/**
* @notice Initialize the pli token and target oracle
*
* Details:
* A. Pli Token for Mainnt: 0xff7412ea7c8445c46a8254dfb557ac1e48094391
* B. Oracle: [Copy paste the Oracle Contract Address, which you deployed as first step in this page] (Plugin DevRel)
* C. jobId: <job ID>
*
*/
constructor() ConfirmedOwner(msg.sender) {
setPluginToken(0xFf7412Ea7C8445C46a8254dFB557Ac1E48094391);//Pli address as mentioned in ‘A’
setPluginOracle(<Copy paste the Oracle Contract Address>);//Oracle address
jobId = "<job ID>";//Job ID as stored in ‘C’ JOB SUBMISSION
fee = (0.001 * 1000000000000000000) / 10;
}


/**
* Create a Plugin request to retrieve API response, find the target
* data, then multiply by 1000000000000000000 (to remove decimal places from data).
*/
function requestVolumeData() public returns (bytes32 requestId) {
Plugin.Request memory req = buildPluginRequest(
jobId,
address(this),
this.fulfill.selector
);


// Set the URL to perform the GET request on
// req.add(
// "get",
// "<sample_api_link>/data/pricemultifull?fsyms=ETH&tsyms=USD"
// );
req.add(
"get",
"<sample_api_link>/data/price?fsym=XDC&tsyms=USDT"
);


// Multiply the result by 1000000000000000000 to remove decimals
int256 timesAmount = 10 ** 18;
req.addInt("times", timesAmount);


// Sends the request
return sendPluginRequest(req, fee);
}


/**
* Receive the response in the form of uint256
*/
function fulfill(
bytes32 _requestId,
uint256 _volume
) public recordPluginFulfillment(_requestId) {
emit RequestVolume(_requestId, _volume);
volume = _volume;
}


/**
* Allow withdraw of Link tokens from the contract
*/
function withdrawPli() public onlyOwner {
PliTokenInterface pli = PliTokenInterface(PluginTokenAddress());
require(
pli.transfer(msg.sender, pli.balanceOf(address(this))),
"Unable to transfer"
);
}
}

Please pay attention to the version of the Remix compiler. It should be 0.8.7. In versions newer than 0.8.20, errors will occur.

Remixのコンパイラのバージョンに注意してください。0.8.7で良いでしょう0.8.20より新しいバージョンでは、エラーが出ます。

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

As of December 29, 2023, the gas fee on the XDC mainnet is 0.25 gwei. If the XDC network's mainnet officially transitions to XDCPoS2.0, the gas fee is expected to increase to 12.5 gwei.

2023年12月29日現在、XDCメインネットのガス代は 0.25gwei です。 XDCネットワークのメインネットが正式にXDCPoS2.0に移行した場合、ガス代は 12.5gwei になる予定です。

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

Please wait for about 2 to 3 minutes. You can see that it's complete on the dashboard.

2〜3分、待ちます。するとダッシュボードでCompletedと表示されていることがわかります。

image.png

You can also check it on the Remix. Please click on Volume.

Remixでも確認することができます。Volumeをクリックしてください。

Screenshot by Dropbox Capture.png

You can see that the value of the completed job's "multiply" task is the same.

CompleteしたJobのmultiply`タスクの値と同じであることがわかります。

Screenshot by Dropbox Capture.png

5. Backup Again

I recommend that you perform another backup once the job is complete. Please refer back to "3. Backup After Plugin V2 Upgrade" for this. In this case, it is sufficient to back up the database only. Use SFTP or a similar method to transfer the /plinode_backups/ directory to your local PC.

【日本語】

Jobがコンプリートしたら、再びバックアップをすることをおすすめします。"3. Backup After Plugin V2 Upgrade" に戻って、そちらを参照してください。この場合は、databaseのバックアップだけでも構いません。 SFTPなどを使用して、/plinode_backups/ディレクトリをローカルPCに転送してください。

5
cd ~/pluginV2Install/ && ./_plinode_backup.sh -db && tree -a /plinode_backups/ 

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

And that's the end of the guide.

以上です。

Troubleshooting

If you encounter the following symptoms when logging into the dashboard, it is possible that the RPC your node is connected to is unstable. In such cases, consider executing the following command to change the RPC:

  • ETH and PLI values are not displayed.
  • When opening the Node tab, the State is displayed as Unreachable.
【日本語】

ダッシュボードにログインした際に、以下の症状が現れる場合、おそらくノードが接続しているRPCが不安定である可能性があります。この場合、RPCを変更するために以下のコマンドを実行してみてください。

  • ETHPLIの値が表示されない
  • Nodeタブを開くとStateUnreachableと表示されている

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

Screenshot by Dropbox Capture.png

RPC Change Command

  • erpc.xinfin.network → earpc.xinfin.network RPC Change Command

    This command replaces a specified URL (https://erpc.xinfin.network) with another URL (https://earpc.xinfin.network) in multiple files and then checks whether the replacement was successful. The target files include ~/pluginV2Install/sample.vars, ~/plinode_$(hostname -f).vars, and ~/pluginV2/config.toml.

    【日本語】

    このコマンドは、指定したURL(https://erpc.xinfin.network)を別のURL(https://earpc.xinfin.network)に置換し、その後、置換が成功したかどうかを確認するコマンドです。対象ファイルは、`~/pluginV2Install/sample.vars`、`~/plinode_$(hostname -f).vars、および ~/pluginV2/config.toml` です。

    T-1
    sed -i -e "s|https://erpc.xinfin.network|https://earpc.xinfin.network|g" ~/pluginV2Install/sample.vars ~/plinode_$(hostname -f).vars ~/pluginV2/config.toml && grep "mainnet_httpUrl" ~/pluginV2Install/sample.vars ~/plinode_$(hostname -f).vars && grep "httpUrl" ~/pluginV2/config.toml
    

    If you want to revert to the default erpc.xinfin.network, execute the following command:

    デフォルトのerpc.xinfin.networkに戻したい場合、以下のコマンドを実行してください。

    • earpc.xinfin.network → erpc.xinfin.network RPC Change Command
    T-2
    sed -i -e "s|https://earpc.xinfin.network|https://erpc.xinfin.network|g" ~/pluginV2Install/sample.vars ~/plinode_$(hostname -f).vars ~/pluginV2/config.toml
    grep "mainnet_httpUrl" ~/pluginV2Install/sample.vars ~/plinode_$(hostname -f).vars && grep "httpUrl" ~/pluginV2/config.toml
    

RPC & Websocket Confirm Command

  • Verify the RPC & Websocket in the ~/pluginV2Install/sample.vars, ~/plinode_$(hostname -f).vars, and ~/pluginV2/config.toml files.

    T-3
    echo -e '\n【~/plinode_YOUR_HOSTENAME.vars】' && cat ~/plinode_$(hostname -f).vars | grep -E 'mainnet_wsUrl|mainnet_httpUrl' ;echo -e '\n【~/pluginV2Install/sample.vars】' && cat ~/pluginV2Install/sample.vars | grep -E 'mainnet_wsUrl|mainnet_httpUrl' ;echo -e '\n【~/pluginV2/config.toml】' && cat ~/pluginV2/config.toml | grep -E 'httpUrl|wsUrl' ;echo
    

    Screenshot by Dropbox Capture.png

Pm2 Restart Command

  • To apply the changes, restart the process.
    変更を反映させるために、プロセスを再起動させます。

    T-4
    pm2 restart all
    

    Finally, log in to the dashboard.

    最後にダッシュボードへログインします。

    T-5
    echo https://$(ip a | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1'):6689 && cat ~/pluginV2/apicredentials.txt 
    

    Screenshot by Dropbox Capture.png

    Screenshot by Dropbox Capture.png

Author: 11ppm

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?