Plian
Search…
Plian Javascript Console

Opening the Javascript Console

Main Chain

To open the console for the main chain, execute:
1
~/pchain/bin/pchain attach ~/pchain/.pchain/pchain/pchain.ipc
Copied!

Subchain

To open the console for the subchain, execute:
1
~/pchain/bin/pchain attach ~/pchain/.pchain/child_0/pchain.ipc
Copied!

Creating an Executable Console

Main Chain

If you don't want to have to remember the command to open the console, you can create a simple bash script to open it. First, open a document called openconsole.sh
1
nano openconsole.sh
Copied!
That will open a text editor. In the text editor, copy and paste the below:
1
#!/bin/bash
2
3
~/pchain/bin/pchain attach ~/pchain/.pchain/pchain/pchain.ipc
Copied!
Then type ctrl-x then y to save and exit. To make it executable:
1
chmod u+x openconsole.sh
Copied!
The console can now be opened by executing the command ./openconsole.sh

Subchain

The same can be done for creating an executable to attach to the subchain. To do that, open a document called openconsolecc.sh
1
nano openconsolecc.sh
Copied!
That will open a text editor. In the text editor, copy and paste the below:
1
#!/bin/bash
2
3
~/pchain/bin/pchain attach ~/pchain/.pchain/pchain/pchain.ipc
Copied!
Then type ctrl-x then y to save and exit. To make it executable:
1
chmod u+x openconsolecc.sh
Copied!
The console can now be opened by executing the command ./openconsolecc.sh
Once the console opens, you will see something like this:
1
Welcome to the Pchain JavaScript console!
2
3
instance: pchain/linux-amd64/go1.12.5
4
coinbase: 0x00000017f6f17ce18faa53d7010fa66acd0e1fb9
5
at block: 20346346 (Sun, 07 Feb 2021 05:59:12 UTC)
6
datadir: /root/.pchain/pchain
7
modules: admin:1.0 chain:1.0 debug:1.0 del:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 pi:1.0 rpc:1.0 tdm:1.0 txpool:1.0 web3:1.0
8
9
>
Copied!
Don't worry if you don't have a coinbase line as that only shows when you have generated/imported a key.

How to Use It For General Node Maintenance

Import Keys

Imports the given unencrypted private key (hex string) into the key store, encrypting it with the passphrase.
Returns the address of the new account.
1
personal.importRawKey(keydata, passphrase)
Copied!

Create New Account

Generates a new private key and stores it in the key store directory. The key file is encrypted with the given passphrase. Returns the address of the new account.
At the Pchain console, newAccount will prompt for a passphrase when it is not supplied as the argument.
1
personal.newAccount()
Copied!

Unlock Your Account

Decrypts the key with the given address from the key store.
Both passphrase and unlock duration are optional when using the JavaScript console. If the passphrase is not supplied as an argument, the console will prompt for the passphrase interactively.
The unencrypted key will be held in memory until the unlock duration expires. If the unlock duration defaults to 300 seconds. An explicit duration of zero seconds unlocks the key until Pchain exits.
The account can be used with eth_sign and eth_sendTransaction while it is unlocked.
1
personal.unlockAccount(address, passphrase, duration)
Copied!

Send a Transaction

Creates a new message call transaction or a contract creation, if the data field contains code.
Parameters
    from: DATA, 20 Bytes - The address the transaction is sent from.
    to: DATA, 20 Bytes - (optional when creating a new contract) The address the transaction is directed to.
    gas: QUANTITY - (optional, default: 90000) Integer of the gas provided for the transaction execution. It will return unused gas.
    gasPrice: QUANTITY - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas
    value: QUANTITY - (optional) Integer of the value sent with this transaction
    data: DATA - The compiled code of a contract OR the hash of the invoked method signature and encoded parameters. For details see Pchain Contract ABI
    nonce: QUANTITY - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.
1
personal.sendTransaction({from: "youraddress", to: "toaddress", value: "amount"})
Copied!
Where the amount is in p-wei. Alternatively, you can replace the "amount" with another fuction to convert PI to p-wei:
1
personal.sendTransaction({from: "youraddress", to: "toaddress", value: web3.toWei(1.23, "pi")})
Copied!
This will error if your account is not unlocked, so you can either unlock it, or pass it your password:
1
personal.sendTransaction({from: "youraddress", to: "toaddress", value: web3.toWei(1.23, "pi")}, "password")
Copied!

Sign Message

The sign method calculates a Pchain specific signature with: sign(keccack256("\x19Pchain Signed Message:\n" + len(message) + message))).
By adding a prefix to the message makes the calculated signature recognisable as a Pchain specific signature. This prevents misuse where a malicious DApp can sign arbitrary data (e.g. transaction) and use the signature to impersonate the victim.
See ecRecover to verify the signature.
1
personal.sign(message, account, [password])
Copied!

Check If Your Node Is Syncing

1
pi.syncing
Copied!
Returns either true or false. False can also mean you are fully synced.

Check If Your Node Is Mining

1
pi.mining
Copied!
Returns either true or false depending on whether your node is a member of the validation set for the current epoch.

Check Current Block Number

1
pi.blockNumber
Copied!
Returns the current block number your node is synced to.

Check Current Epoch

1
tdm.getCurrentEpochNumber
Copied!
Returns the current epoch number your node is synced to in hex.

Check Epoch Details

1
tdm.getEpoch("epochNumber")
Copied!
where epochNumber is the epoch number you want to get details on in hex, e.g. 0x16 for epoch 22. Returns details on epoch phases and the list of validators.
Example:
1
{
2
end_block: "0x1483995",
3
end_time: "0001-01-01T00:00:00Z",
4
number: "0x16",
5
reveal_end_block: "0x14739f4",
6
reveal_start_block: "0x1453ab4",
7
reward_per_block: "0x1bd572fe32063b0d",
8
start_block: "0x134410a",
9
start_time: "2021-02-03T21:45:33.18Z",
10
validators: [{
11
address: "0xdd619d482bc919b9ae199a4d23425c8a44ca414b",
12
public_key: "0x25ABA630012F59B503899FD74E503E6985F826A7C0129A596038C75AD80D8CEC50FAA34E98B1B05566CB0180D291BE01ACA93F0D631CE67B14B736CF63B2BB555F4997695661DB405D6FA78E065803827C328F36E53749670A088FBFEBA734AD70E5B6A92ABC6EA031F757CE9109E922D12EA32496B9B2C19C52E91D89732A98",
13
remain_epoch: "0x0",
14
voting_power: "0x2d0ff3bf21c88a9223f8cc"
15
},
Copied!

Check Your Balance

Returns the balance of the account of a given address in p-wei.
Parameters
    1.
    DATA, 20 Bytes - address to check for balance.
    2.
    QUANTITY|TAG - integer block number, or the string "latest", "earliest" or "pending", see the default block parameter
1
pi.getBalance("address","latest")
Copied!

Check Your Full Balance

Returns the full balance of the account of a given address. This includes the delegated balance as well as personal balance.
Parameters
    1.
    from: address, 20 Bytes - address to check for balance.
    2.
    blockNumber: QUANTITY|TAG - integer block number, or the string "latest", "earliest" or "pending"
    3.
    fullDetail: Boolean - If true it returns the full detail of proxied/reward object under this address
1
params: [
2
'0xd833b6738285f4a50cf42cf1a40c4000256589d4',
3
'latest',
4
true
5
]
Copied!
Returns
    1.
    balance: QUANTITY - integer of the current balance in p-wei.
    2.
    total_delegateBalance: QUANTITY - total delegate balance in p-wei to other address
    3.
    total_depositBalance: QUANTITY - deposit balance in p-wei for Validator Stake
    4.
    total_depositProxiedBalance: QUANTITY - total deposit proxied balance in p-wei for Validator Stake
    5.
    total_pendingRefundBalance: QUANTITY - total pending refund balance in p-wei which will be return to delegate at the end of Current Epoch
    6.
    total_proxiedBalance: QUANTITY - total proxied balance in p-wei delegate from other address
    7.
    total_rewardBalance: QUANTITY - total pending reward balance in p-wei of this address
    8.
    proxied_detail: Object - detail record of each address's proxied data, including proxied balance, deposit proxied balance and pending refund balance
    9.
    reward_detail: Object - detail record of this address's reward data, including how much balance in p-wei will be given at the end of each epoch
1
pi.getFullBalance('address','latest',true)
Copied!

Check Number of Peers Your Node is Connected To

1
web3.net.peerCount
Copied!
Returns the number of other nodes your node is connected to.

How to Use It For More Complex Purposes

The Javascript console allows you to not only use predefined functions to pull information from the network, but you can also create custom functions using Javascript to do anything you can think of using the variety of functions defined in the RPC and PWeb3 API.
Since it is a JavaScript console, you have complete ECMA5 functionality(Go Pchain uses Otto JS VM, which is a JS interpreter written in Go). You can declare variables, use control structures, define new methods, and even use any of setInterval, clearInterval, setTimeout, and clearTimeout.

Example: Check For Number of Transactions Between a Range of Blocks

From within the console, you can write a Javascript function
1
function checkTransactionCount(startBlockNumber, endBlockNumber) {
2
console.log("Searching for non-zero transaction counts between blocks " + startBlockNumber + " and " + endBlockNumber);
3
4
for (var i = startBlockNumber; i <= endBlockNumber; i++) {
5
var block = pi.getBlock(i);
6
if (block != null) {
7
if (block.transactions != null && block.transactions.length != 0) {
8
console.log("Block #" + i + " has " + block.transactions.length + " transactions")
9
}
10
}
11
}
12
}
Copied!
Then you can execute this function with:
1
checkTransactionCount(20370000,20375688)
Copied!
Which returns:
1
Searching for non-zero transaction counts between blocks 20370000 and 20375688
2
Block #20370175 has 1 transactions
3
Block #20370692 has 1 transactions
4
Block #20371258 has 1 transactions
5
Block #20372828 has 1 transactions
6
Block #20373711 has 1 transactions
7
Block #20373743 has 1 transactions
8
Block #20375586 has 1 transactions
Copied!

Example: Check For Blocks Your Node Has Mined

This one is a bit more complicated, requiring multiple function definitions. In practice, you can write these in a separate text editor as one concatenated function and paste it as one in order to simplify it down. This is broken down for simplicity.
First, a function to print transaction info:
1
function printTransaction(txHash) {
2
var tx = pi.getTransaction(txHash);
3
if (tx != null) {
4
console.log(" tx hash : " + tx.hash + "\n"
5
+ " nonce : " + tx.nonce + "\n"
6
+ " blockHash : " + tx.blockHash + "\n"
7
+ " blockNumber : " + tx.blockNumber + "\n"
8
+ " transactionIndex: " + tx.transactionIndex + "\n"
9
+ " from : " + tx.from + "\n"
10
+ " to : " + tx.to + "\n"
11
+ " value : " + tx.value + "\n"
12
+ " gasPrice : " + tx.gasPrice + "\n"
13
+ " gas : " + tx.gas + "\n"
14
+ " input : " + tx.input);
15
}
16
}
Copied!
Next, a function to print block info:
1
function printBlock(block) {
2
console.log("Block number : " + block.number + "\n"
3
+ " hash : " + block.hash + "\n"
4
+ " parentHash : " + block.parentHash + "\n"
5
+ " nonce : " + block.nonce + "\n"
6
+ " logsBloom : " + block.logsBloom + "\n"
7
+ " transactionsRoot: " + block.transactionsRoot + "\n"
8
+ " stateRoot : " + block.stateRoot + "\n"
9
+ " miner : " + block.miner + "\n"
10
+ " difficulty : " + block.difficulty + "\n"
11
+ " totalDifficulty : " + block.totalDifficulty + "\n"
12
+ " extraData : " + block.extraData + "\n"
13
+ " size : " + block.size + "\n"
14
+ " gasLimit : " + block.gasLimit + "\n"
15
+ " gasUsed : " + block.gasUsed + "\n"
16
+ " timestamp : " + block.timestamp + "\n"
17
+ " transactions : " + block.transactions);
18
if (block.transactions != null) {
19
console.log("--- transactions ---");
20
block.transactions.forEach( function(e) {
21
printTransaction(e);
22
})
23
}
24
}
Copied!
Then, a function to print block info from a specific miner.
1
function getMinedBlocks(miner, startBlockNumber, endBlockNumber) {
2
if (endBlockNumber == null) {
3
endBlockNumber = pi.blockNumber;
4
console.log("Using endBlockNumber: " + endBlockNumber);
5
}
6
if (startBlockNumber == null) {
7
startBlockNumber = endBlockNumber - 10000;
8
console.log("Using startBlockNumber: " + startBlockNumber);
9
}
10
console.log("Searching for miner \"" + miner + "\" within blocks " + startBlockNumber + " and " + endBlockNumber + "\"");
11
12
for (var i = startBlockNumber; i <= endBlockNumber; i++) {
13
if (i % 1000 == 0) {
14
console.log("Searching block " + i);
15
}
16
var block = pi.getBlock(i);
17
if (block != null) {
18
if (block.miner == miner || miner == "*") {
19
console.log("Found block " + block.number);
20
printBlock(block);
21
}
22
}
23
}
24
}
Copied!
If startBlockNumber is not specified, it will default to the last 10,000 blocks. This takes some time to scan, so reduce this number to 1000 to reduce the scanning time.
If endBlockNumber is not specified, it will default to the latest block number.
Then one last one just to make entering your node address easier:
1
function getMyMinedBlocks(startBlockNumber, endBlockNumber) {
2
getMinedBlocks(pi.accounts[0], startBlockNumber, endBlockNumber);
3
}
Copied!
Now you can use this to see block details of the blocks your node mined:
1
getMyMinedBlocks(startblock,endblock)
Copied!
Which returns for example from getMyMinedBlocks(20376850,20376860)
1
Found block 20376853
2
Block number : 20376853
3
hash : 0x349a56b0ee7ca3b5c18cdaa9b58dc91b1c8be8b7b7a63dea70a6a92bf5b44359
4
parentHash : 0xd60c0ea757b25c6748662b3baa65dd1451149d975ed53905fd9428ce57c947d3
5
nonce : 0x0000000000000000
6
logsBloom : 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
7
transactionsRoot: 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
8
stateRoot : 0x2dca9b62e62d06ad72aff4d138d0a85ff28b1b0e78daace3dbe1a23f193954f7
9
miner : 0x00000017f6f17ce18faa53d7010fa66acd0e1fb9
10
difficulty : 1
11
totalDifficulty : 20377877
12
extraData : 0x010670636861696e000000000136ed1516619f1d2e89d0c0000000000000000000160114ad0fa07abd61134aa4e662eb63919b75575f1dcc0114ec3de6ec08b0210b7dedd06466038f9c620da88a010114839fa0d18e9c6238174b5f78fcef76b1d204591300000000000000010114b917b1e4f6b807345c75e01db1b7fa4f43f1d393000000000136ed1500014035bfb83ef839b83b8c339f61c5d7f951f10636447c7ef3e93877295e442fcbfe42279b0d6fe94f78ce27c022765d0fd3c5154ecaba62bbb91ac6d0bfceb5f0ba01000000000000003501010001ed5e6cfd5fbf00
13
size : 740
14
gasLimit : 8000000
15
gasUsed : 0
16
timestamp : 1612745088
17
transactions :
18
--- transactions ---
19
Copied!
You can also check for specific blocks with any miner with wildcard "*":
1
getMinedBlocks("*",20370174,20370176)
Copied!
1
Found block 20370175
2
Block number : 20370175
3
hash : 0x8f69fd62ce38d37a523bc878387458c6edb0d8f0593afa038acd21704b16f4c3
4
parentHash : 0x624bb8297dbae4ae6c95fc2ed0bc5c05fbf43e2eab3e86fd52c9d2ad0393446c
5
nonce : 0x0000000000000000
6
logsBloom : 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
7
transactionsRoot: 0x35fda788d4cb76f443d4b696511e8b851989775acf9de51b107ba4ec6812650f
8
stateRoot : 0xe2d9be449c0617a0d8930d6ce0e1706a663085766b78d386013aae6f80a6d7bd
9
miner : 0xf6a94ecd6347a051709f7f96061c6a0265b59181
10
difficulty : 1
11
totalDifficulty : 20371199
12
extraData : 0x010670636861696e000000000136d2ff16619210a6ce05c0000000000000000000160114bf47a48e5c2e2d5e1989ff83080909950cf12e080114ec3de6ec08b0210b7dedd06466038f9c620da88a0101148fe06ad92093838406cf6f53dc2e2132b04ff9c500000000000000010114eb8a78690667a10e23f21ef2aa37d3b66531c0b9000000000136d2ff000140597c929f33c0ae8509849996798b13935d94f3bb8cc28f97dc8bcf8a99cb81e84b5cdf97667e64893c26196d870eb955ef97842a0e10815836c7bafddb18c60201000000000000003501010001ed5e6cfd7f3f00
13
size : 887
14
gasLimit : 8000000
15
gasUsed : 21000
16
timestamp : 1612730741
17
transactions : 0xa6ef4c9631a3f82d9efdaedc1394c13ddd3faa84ffd6aaf0b60878f8a2e25a21
18
--- transactions ---
19
tx hash : 0xa6ef4c9631a3f82d9efdaedc1394c13ddd3faa84ffd6aaf0b60878f8a2e25a21
20
nonce : 2329
21
blockHash : 0x8f69fd62ce38d37a523bc878387458c6edb0d8f0593afa038acd21704b16f4c3
22
blockNumber : 20370175
23
transactionIndex: 0
24
from : 0x0d0707963952f2fba59dd06f2b425ace40b492fe
25
to : 0x8a14cdaf595ce2db5cdcf5268d481615be2aa953
26
value : 4900000000000000000
27
gasPrice : 10000000000
28
gas : 30000
29
input : 0x
Copied!
The possibilities are pretty endless here. The only problem is
Last modified 6mo ago