Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 125 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

Peerplays Community Docs

Loading...

Concepts

Loading...

Loading...

Technology

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Witnesses

Loading...

Loading...

Bookie Oracle Suite (BOS)

Data Proxies

Couch Potato

Random Number Generator (RNG)

Loading...

Loading...

API

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

GitLab

Loading...

Loading...

Loading...

Other Documentation

Known Issues

NFTs and Marketplace

Peerplays SONs

Bitcoin and Ethereum are slow, expensive to use, and not scalable enough for mass adoption and usability. They can’t support high transaction throughput.

SONs provide an alternative way for blockchains to communicate with each other, which opens up new possibilities in terms of scalability and interoperability.

Peerplays SONs are decentralized, trustless, and elective. The side chains are as secure as they can get. They can keep the scalability trilemma at bay (security, decentralization, and scalability).

Public open decentralized blockchains are the way to go forward. We here at Peerplays are committed to making sure whatever we create is not centralized and can’t be manipulated.

FAQ

1. What is the transaction finality time for withdrawals and deposits of BTC?

Six transaction confirmations are the recommended value for transaction finality on the Bitcoin blockchain and thus its recommended to set the value at 6 confirmations for Bitcoin SONs. (reference: https://web.archive.org/web/20210218094358/http://bitcoins.net/guides/bitcoin-confirmations)

2. What is the daily reward pool set at right now for sons nodes?

Funds equivalent of 200 PPY is set aside and its distributed among SONs proportional to their performance. This value can be changed by the committee.

3. I have also noticed that my server is running at 100% at all times. Is it trying to mine test btc?

No, when you are connected to SONs network as a seed or a SON itself, you won't be doing any PoW mining. SONs just listens on the Bitcoin network for any incoming transfers to Peerplays BTC addresses.

SON Fees & Performance Requirements

SONs get paid out from a daily reward pool for signing transactions and the weight of voting. Both the transactions they approve and reject are counted in. Bitcoin transactions in Peerplays blockchain get validated to ensure they originated from the SONs.

When a SON changes, their private key on the bitcoin address gets replaced with the private keys of the new incoming SON.

The performance of SONs is also tracked. Their errors, uptime, missed blocks, and similar errors provide historical performance data for voters. Witnesses have the power to freeze a SON or blacklist them if necessary.

Why are SONs important?

SONs help the blockchains scale and develop more quickly. Blockchains like Bitcoin or Ethereum have to validate every new transaction on their own. But SONS only have to periodically refresh information from the root chain with updates about transactions. Which means massive scalability without sacrificing security or decentralization!

The problem with blockchains out there that offer inter-blockchain communications like Cosmos and Polkadot is that they ‘talk’ only with other blockchains that are identical like them. This doesn’t really solve the problem of blockchains interacting with one another. It creates a situation where a ‘foreign’ blockchain must switch over to another blockchain that is able to communicate with a blockchain that is ‘compatible’ with Polkadot or Cosmos.

That’s why Peerplays SONs technology is an innovative, elegant solution.

Sidechain Operator Nodes (SONs)

Sidechain Operator Nodes - SONs facilitate the transfer of off-chain assets (like Bitcoin, Hive, or Ethereum tokens) between the Peerplays chain and the asset's native chain. These nodes often run the Peerplays node software and node software of other chains.

The software used to run Witness, API (full), Seed, and SON nodes is named witness_node. All these node types are run with the same software. What makes these nodes different is how that software is configured and how it's used.

SONs will also require the use of software supplied by other chains, like Bitcoin Core for example.

BOS nodes use a collection of software known as the Bookie Oracle Suite.

Power Up & Power Down

Why can't I vest my entire balance?

There as a 1PPY fee every time you power up (deposit) to your GPOS balance. So you must make sure you have enough PPY left to cover the transaction fee.

What would be a sensible amount to vest?

There's no hard and fast rule, it's going to depend on how active you are as a Peerplays wallet user and other factors. It's certainly beneficial to vest as much as you can as you're total participation rewards are based on how much you vest.

But you should note that as all wallet operations incur a small fee, vesting too much could actually stop you from withdrawing PPY from GPOS until you deposit more PPY to your wallet.

Why is the Power Down button disabled?

You can't power down until you have powered up for the first time, or if you've withdrawn from your GPOS balance leaving it at zero.

Why can't I withdraw any of my GPOS balance?

It's theoretically possible for this to happen if you don't have enough available PPY to pay the withdrawal fee. But the most likely reason is because there is a 30 day holding period on GPOS deposits before they can be withdrawn. For more information see GPOS Balance Holding Period.

Voting

Does GPOS affect how I vote?

Yes and no. The functionality of the voting feature in the Peerplays wallet hasn't changed in the newest version, only the steps you go through to vote have changed.

But GPOS will effect your voting habits as it requires regular participation.

What happens if I don't vote?

Simply put, you'll lose a percentage of your qualifying rewards for every month that you don't vote. If after six months you still haven't voted you won't qualify for any participation rewards.

Can I vote more than once a month?

Yes, you can vote as many times as you'd like to, and you can vote for more than one Witness or Advisor at the same time.

Why can't I vote for the same Witness twice?

Once a Witness or Advisor has been voted for and is in your approved list you can't currently re-select that person for voting again without first un-voting them. This is a known issue that will be fixed in the next release.

Will my voting performance go back to 100% once I vote?

Yes, regardless of your level of voting performance as soon as you vote it'll return to 100%. It will however, start to decay again if you don't vote regularly.

Can I just vote for a proxy and then let them manage my account?

Yes, this is the role of the proxy ... but if you do this make sure your proxy is reliable as your voting performance is in their hands, and you still need to vote once a month.

New to SONs?

Here's everything you need to know about how the Peerplays SONs work? what are the problems they solve?

Bitcoin and Ethereum are slow and expensive to use.

Currently, Bitcoin can process only 4.6 transactions per second. The average confirmation time for a BTC payment is about 10 minutes. For context, Visa does around 1,700 transactions per second on average. On the other hand, Ethereum fees are extremely expensive and through the roof. Scalability is a serious issue for both networks.

Is there any way to overcome these problems? Sidechains may provide a solution.

If you’re new to Sidechains, then this is the perfect place to start.

Participation Rewards

How are participation rewards different from traditional dividend payments?

GPOS introduces a number of significant changes to the old method of dividing the Peerplays rake between all token holders relative to how many tokens they hold.

The biggest change is that the percentage of the rake is based on the total of all GPOS vested balances, and not the cumulative value of all PPY in circulation. This gives the opportunity for regular voters to get a larger share of the rake than before by virtue of other unreliable voters.

I'm confused, just how exactly are my rewards calculated?

At first the new formula for calculating your estimated reward percentage can be a bit confusing; this example should help:

If you have a GPOS balance of 1,000PPY, and have voted recently, so you have qualified for a 100% reward, and the total GPOS balance on the blockchain is 4,000,000PPY when the rake is distributed, then your percentage of the rake would be:

(1,000 / 4,000,00) * 0.025%

What you'll actually receive as a dividend is based on the monthly rake, so if the rake is 100,000PPY then you'd receive 100,000 * 0.025% = 25PPY.

What are Sidechain Operating Nodes?

In order to improve the performance of Bitcoin and Ethereum, a unique mechanism is required. Sidechains can help move tokens, perform transactions faster and cheaper.

Sidechains provide the decentralized way to seamlessly transfer value between multiple blockchains and to operate Sidechain SONs node are used.

Sidechain Operating Nodes (SONs) means a lot to the blockchain world. SONs provide a way for blockchains to interact with each other. Those nodes are in harmony with each other like a handshake which ease the process of transferring tokens from Peerplays blockchain to and from another blockchain.

Sidechains solve a problem known as Inter-Blockchain Communication (IBC). This problem takes place when blockchains have different protocol types (also called consensus mechanisms, like Proof of Work, Proof of Stake, Delegated Proof of Stake, etc.)

Peerplays SONs are decentralized, trustless, and elective.

How do SONs Work?

Hinted through their names, these Sidechains run alongside a root or “parent chain.” When you transfer funds, they're locked on the parent chain and then released onto their respective sidechain. You can then move them around at will until you decide to return them back to their original chain.

Anyone can enable a Sidechain Operating Node. However, that is not enough to run a SON. You must be an ‘active participant’ in the Peerplays community and receive votes in order to qualify to become a SON. Since Peerplays blockchain is Gamified Proof of Stake, this incentivizes voting for those who run SONs.

Once a SON finds a particular transaction which is signed by 2/3rd of other SONs, that SON will post the transaction to the Peerplays blockchain. Upon receiving the transaction, the SON will verify the transaction details with the appropriate blockchain. If the data on the source blockchain sidechain seems to be intact, the SON will sign the transaction and publish it. This helps prevent any SON from malicious transactions.

Staking (PowerUp) in Peerplays

Downloads

The Diagram in PDF form to easily view and share:

83KB
NFT-Staking.pdf
pdf
Staking (PowerUp) in Peerplays - PDF

The Diagram in Draw.io's XML format. You can edit the diargam using this file in Draw.io:

12KB
NFT-Staking.xml
Staking (PowerUp) in Peerplays - XML

How do SONs impact me?

You can think of SONs as a two-way street. The value of two blockchain tokens is going back and forth safely and smoothly.

To paint a picture, let’s imagine you’re sending your bitcoin from an address to a sidechain. This bitcoin is then represented on the other side of the new blockchain. You are then able to move this represented bitcoin without touching your original bitcoin.

This offers scalability for bitcoin. For example, let’s say another blockchain can perform 50,000 transactions per second. Now Imagine being able to operate your bitcoin at that speed. This opens up endless possibilities about the applications Bitcoin could be used in.

It could really be the answer for worldwide adoption.

Wallet User Guide

Version 1.5 of the Peerplays Core Wallet added the GPOS functionality for the first time; this document will step you through the new features it implements to ensure you qualify for maximum participation rewards.

FAQ

GPOS Landing Page

The landing page is the entry point to use the different GPOS features.

Power Up

Clicking on Power Up will take you to the deposit screen where you can vest PPY towards GPOS and in turn, add to your participation rewards.

You can click Power Up at any time since you are free to come back and vest more PPY at your discretion.

Power Down

Clicking on Power Down is very similar to Power Up except this time you'll be taken to the withdraw screen.

You can withdraw form your GPOS balance at any time up to the value of your balance.

Important: If you have a GPOS balance of zero the Power Down button will be disabled

Vote

For anybody familiar with earlier versions of the Peerplays wallet, the voting section is much the same as before. Only the steps to go through to access this feature have changed.

Important: If you have a GPOS balance of zero the Vote button will be disabled

Decentralization

1. What is Decentralization?

You've been hearing the word decentralized being thrown around. What does it mean?

Decentralization refers to the transfer of control of an activity or organization to several local offices or authorities rather than one single entity. This can be ambiguous because "several" can refer to anything from as few as three to as many as there are members of an organization (like multiple boards of directors vs. every single member of the organization.) In many organizations, this can create a smoke screen where the perception of freedom is created to hide the real aim of the organization; control for the few. The more decentralized the organization, the greater capacity there is for its members having control. In order to assess the level of control we will have when joining an organization that claims to be decentralized, we must assess the organization’s methods of decentralization.

2. Quantifying Decentralization

Examine the level to which the organization has dispersed its control. First, how many modes of power have been decentralized and to what extent has each mode been decentralized? To judge the number of modes, we must understand these modes and the impact that they have on an organization. These modes are decision making, narrative, enforcement, and innovation.

2.1. Decision Making

Decision making refers to the ability to choose and implement avenues of change within bounds. This could mean the day-to-day decisions in each department, which has generally been the role of employees and managers within centralized systems. The power to make decisions extends to the highest level of the organization. Decision making determines how money is obtained, how it is distributed, which solutions are attempted, which risks are considered worth taking, how compensation is determined, and so on.

Much of the decision making power in centralized systems have been delegated across departments with a single party or small group of parties responsible for the implementation of suggestions made by each of these departments. For example, a human resources department may assess the compensation needs of all employees based on department and employee generated criteria and then propose a compensation and benefits package that every member of the organization would find fair. If, however, this package were to be vetoed by the CEO of the organization, the implementation of this package would not occur.

In a fully decentralized system, each employee would be asked for input, the suggestions would be compiled into a cohesive package and assessed for feasibility, and implemented once a sustainable agreement was found without the backing of a higher authority. While this may seem time consuming due to the need for negotiation among those providing opinion, ultimately the result of such negotiations allows each member to take ownership, feel valued, and have the opportunity to understand the reasoning for decisions. In this way, discontentment among staff is avoided and the organization has the support of all of its members.

2.2. Narrative

The narrative of an organization is the union of several pieces of human generated experience.

  • First, it is made of organizational data.

  • Second, it is made of the value system, mission statement, and goals of the organization as a whole.

  • Third, it is made of the values and goals of each individual member of an organization, including those that are never voiced (For example: plans for furthering education, competition among members, personal problems, etc.)

  • Fourth, it is made of communication.

To truly understand narrative and its impact on an organization, it can be helpful to think of Ecological systems theory developed by Urie Bronfenbrenner (see Figure 1 & ). While Bronfenbrenner’s theory relates to the development of people, an organization will be treated as an individual within public consciousness. Its development must be treated as any other individual, with the understanding that it too is made of individuals.

Both the narrative of each member and the narrative of the organization as a cohesive whole acting as an individual in the public sphere must be taken into account when control is considered. Errors in representation are always made when a group is unable to speak for themselves. The perception of individuals within a group and the group as a whole will come from how those outside the organization receive the narrative. The narrative of the organization as a whole will also create the perception of its members. To control the narrative is to control how you are seen. A negative perception at any level helps no one, and is often a source of much anger, resentment, and embarrassment among those who do not feel accurately represented. Representation matters.

2.3. Enforcement

Enforcement is the act of compelling observance of or compliance with a law, rule, culture, or obligation. The control of enforcement must be given careful consideration. In a centralized system, there is always a bottom tier that has no power to enforce, and no one has authority of the top tier outside of state and national law. While those without punitive authority are able to report to those higher or provide feedback to each other, they ultimately do not have the power to ensure that every member of their group is abiding by the established rules and culture. More often than not, only those at the highest level of the authoritative hierarchy are able to set rules and devise the means by which these rules are to be enforced. A lack of enforcement means that a rule is not taken seriously, and is therefore not a rule. Too much enforcement can generate fear and distrust of authority figures, which can negatively impact performance in a variety of ways.

The alternative to this hierarchical approach is to encourage as much organizational ownership as possible to the creation and enforcement of rules and organizational culture as possible. In an article published at , Lizz Fields-Pattinson promotes the idea that "when we have a stake in how we’re supposed to approach the world around us, we feel a sense of social belonging and alignment with the people who share that world-view," so it is beneficial to "involve more people in the decisions which affect rules or codes of conduct from the start, that way you encourage a larger number of engaged advocates to back your cause." This is echoed by Market Business News: "People feel motivated to follow through when they feel that they are part of the program."

While it may still be necessary within an organization to have an authority group that is charged with enforcement, there are ways to decentralize this mode of control so that there is no hierarchy. For example, in the beginning stages of the formation of rules and consequences, all member should be invited to share their vision of the standard by which operations are to be run and what should be the consequence for an individual that does not follow the standard. Once a code of conduct and levels of intervention have been established, a review process can occur within set cycles to ensure that new members have an opportunity to weigh in and necessary changes to the system can be established and implemented. To ensure that all members are held accountable, delegates can be chosen for a disciplinary committee on a rotational basis on which all individuals have the opportunity to serve. Team managers can be chosen based on experience and training criteria, but also be subject to peer review by those they manage. In a system such as this, all members have the opportunity to provide and receive feedback, and no one is in a strictly subordinate role.

2.4. Innovation

Innovation refers to the development of something new. This applies to products, but also any idea, method, or procedure at any level within the organization. In general, the control of innovation has everything to do with who is given the authority to try new things and to make suggests. In a typical centralized organization, innovation is reserved for specific departments and the categories of thought are siloed. Consider that human resources, research and development, manufacturing, and marketing often have no need to communicate, yet individuals within every department are affected by the ideas generated by each group. Also consider that individuals may have expertise separate from their job role. For example, a member of the production line may be obtaining a social work degree and therefore generate an idea that could be useful to human resources. If there is no means by which these ideas can easily be shared, they likely will not be. A suggestion box is only useful when the ideas within are actively considered.

3. What does this mean for me?

In a centralized system, primary decisions are made by the person or group at the very top of the organization, such as a board of directors or a CEO. To move away from this model, an organization may begin to allow latitudes to "lower" levels of the organization, but maintain functions such as research, development, and records keeping for the highest levels of the organization. So, even if basic decision making is now shared throughout the organization, the upper levels maintain control of innovation and any long-term changes are not easily accessible to those who have the power of basic decision making.

While blended systems such as these seem to allow freedom, those with voting power can only choose those options they believe are available to them. Consider that daily decisions may be short lived and have little impact on the direction of the company. Without the ability to innovate, the future direction of the company is still controlled by a central group. The suggestions leading to innovation will be generated by research and development which, being controlled by a centralized group rather than open to all, are funneled. Any decisions therefore are controlled by a central group.

The same is true for the control of narrative, especially by way of data and information regarding changes within the organization. Consider an organization’s turn over. If those involved in decision making are gradually replaced by others over time, those new to the organization will only know of what has recently come to pass without the ability to access all records. If the records are maintained by a central group, again there is the concern of funneling. When documentation is restricted, openness is jeopardized, as is timeliness. Further, a single copy of historical records is subject to corruption. Any changes made, whether accidental or intentional, will have no basis of comparison. If, however, every person with power of decision were to have their own copy of all documentation records, access will be automatically granted and immediate, and discrepancies will become apparent between copies.

When all aspects of an organization are fully decentralized, there is no limit to its innovative potential. Rather than suggestions being funneled from a centralized viewpoint. Each member is free to make suggestions relative to their perspective within the organization. Each suggestion may be assessed for utility by all those with power of decision and implemented with expediency. There is no need to wait for approval from a centralized power. Majority support cannot be overturned by a single voice. Once accepted and initiated, it will be up to market trends to decide outcomes. Counter-changes can be made just as quickly if market trends show a need. This flexibility in innovation allows for timely adjustments and increases the likelihood for rapid growth and success.

Likewise, the increased access of information allows for better integrity within the organization. Consider the human dynamic within organizations. While no one wants to think the worst of an organization’s members, mistakes will happen and people can give into temptation. In a centralized system of records keeping, it is up to a single group to catch all errors or intentional fudging. When there is no basis of comparison, it can take time to reconcile places where figures do not make sense. The more transactions occur, the longer it can take. When information is decentralized, however, there is a large basis for comparison and every individual with a copy has the ability to compare with others. Discrepancies are far more noticeable. If a single copy varies from the others, it becomes easier to fix and easier to trace its source. Unless each copy where to be simultaneously corrupted, there would be no way to hide a discrepancy. Since each copy is housed separately, it would be nearly impossible to effect a change across the entirety of records. The contents of the documentation are therefore trustworthy.

It is only when all aspects of an organization are delegated that an organization can truly claim to be decentralized.

Appendix A

Ecological systems theory was developed by Urie Bronfenbrenner. The six systems described in his theory, and outlined in Figure 1 (above) are as follows:

Individual (or Organization): This can represent a member of the organization or the organization itself, depending on the context.

Microsystem: Institutions and groups that most immediately and directly impact the individual's development.

Mesosystem: Consists of interconnections between the microsystems. For example, interactions between different departments within the organization that will impact the individual.

Exosystem: Involves links between social settings that do not involve the individual, yet have an impact on the individual. For example, the experiences of other organizations within the same industry.

Macrosystem: Describes the overarching culture that influences the developing individual, as well as the microsystems and mesosystems embedded in those cultures. Cultural contexts can differ based on geographic location, socioeconomic status, poverty, and ethnicity. Members of a cultural group often share a common identity, heritage, and values. Macrosystems evolve across time and from generation to generation.

Chronosystem (not pictured): Consists of the pattern of environmental events and transitions over the life course of the individual, as well as changing socio-historical circumstances.

Peer-to-Peer Autonomous Organizations: Flow Diagram

Flow Diagram

Downloads

PDF

XML

Introduction to Peerplays

The code for this documentation portal is on and we would welcome all contributions from the community.

What is Peerplays?

Peerplays is the humanizing crypto platform.

Peerplays is a decentralized, global crypto platform, bringing a new paradigm of fairness, transparency, speed, and security. Built with Graphene technology and Gamified Proof of Stake (GPoS), Peerplays provides the fastest, most decentralized blockchain consensus model available today.

Why Peerplays?

Peerplays is building an ecosystem of decentralized products and apps, offering people a real alternative to untrustworthy and greedy centers of control.

The Peerplays blockchain is a game-changer for people and communities around the world:

  1. Provably Fair – Every Peerplays software component has been designed to provide a fair experience. And, unlike with traditional platform operators, all Peerplays software is open-source and publicly audit-able. Peerplays sets new standards for provably-fair networking.

  2. 100% Real-Time Transparency – Peerplays publicly broadcasts each transaction as it is executed on the blockchain in real-time. As soon as a transaction is placed, anyone can view the full audit trail of that transaction, marking a step-change in economic standards for transparency.

  3. Fast, Secure, Anonymous Control – Peerplays integrates with all digital currencies (Bitcoin, ETH, HIVE, etc.) to provide fast, cryptographically-secured deposits and withdrawals, immediate access to funds, and anonymous control over each and every transaction.

  4. Most Trusted – Peerplays uses GPoS to create a fully decentralized blockchain. This removes third party operators from the equation (traditional firms and exchanges) creating a completely independent platform where 100% trust is built into the core technology. (In the same way, Bitcoin released money from the control of third party financial institutions).

  5. Most Reliable – Graphene technology gives Peerplays financial markets-grade performance and reliability with years of successful deployment logged via the BitShares blockchain.

  6. Global – With witness nodes spread across the world, and the capacity to process over 10,000 transactions per second, the Peerplays blockchain scales to deliver a truly global economic platform.

Who is Behind Peerplays?

A number of different groups and individuals share jurisdiction over the Peerplays blockchain, which ensures no single entity can gain control over the network. These groups and individuals include Witnesses, Advisors, and PPY token holders. For more information on the governance of the Peerplays blockchain, please visit the Governance section of this website.

The Peerplays blockchain software has been developed by the Peerplays Blockchain Standards Association (PBSA), a non-profit organization based in Canada. For more information on PBSA, please visit .

General

What is GPOS?

GPOS is short for Gamified Proof of Stake which is an advanced implementation of the DPOS consensus mechanism.

GPOS gives voting weight and rewards to all token holders that commit some of their PPY balance as a vested GPOS balance. For more information see .

What is a vested balance?

The best way to understand this is to compare it to the difference between stock options and shares. If you hold stock options you have a stake in the company, but the options have no value unless you can profit from them and to do this the options have to first be vested as shares.

GPOS works the same way, instead of all token holders being entitled to dividends just by virtue of holding tokens (shares), token holders now have a PPY balance (options) that they only profit from when they are vested in GPOS (become shares).

Are there any fees associated with GPOS?

Yes, there is a fee of 1PPY for Powering Up (depositing) and a nominal fee of 0.01PPY for Powering Down (withdrawing).

What happens to the fees?

The fees are 'burned', that is to say they return to the reserve. The reserve can then be drawn on for block rewards for the block producers.

Did I just lose some share of the Peerplays rake?

No, in fact far from it. GPOS gives you every opportunity to not just receive the same dividends as before but actually get higher dividends if there are token holders that don't vote. Just remember to vest a GPOS balance and then vote at least once a month.

Why is GPOS better for Peerplays?

GPOS encourages all PPY token holders to take a much bigger interest, and say, in the governance of the blockchain. This will strengthen the democratic process that goes into electing the operators of Peerplays, and make them much more accountable.

Before GPOS token holder voting was poor and that opened up the opportunity for one or two major token holders to influence the operation of the blockchain. Full participation by token holders in the voting process will mitigate this risk and keep the blockchain secure.

Power Up

After clicking on the Power Up button on the you'll be taken to the Power Up screen; from here you can add to your GPOS balance.

The functionality of this screen is very straightforward. Simply select an amount of PPY to vest by either entering it in the Deposit field, or scroll the amount up and down using the + and - buttons.

Important: You might think you can vest 100% of your PPY balance to get the maximum participation rewards. However, each time you create a vested balance there is a 1PPY transaction fee. This means that you must leave at least this amount in your balance in order to perform the Power Up.

In the example above the user has no vested balance. If an amount of 80PPY is vested the New GPOS Balance will be 80PPY and if the user power's up again the Opening GPOS Balance will be 80PPY as will the New GPOS Balance.

Click on the CANCEL button to leave this screen without saving any changes. Or click on SUBMIT to save changes and return to the

Note: Creating a GPOS balance doesn't yet qualify you to receive participation rewards, you must still .

GPOS Panel

What is the difference between Qualified Reward and Estimated Rake Reward?

Qualified Reward is the percentage your maximum possible reward based on voting performance. This reward decays at a rate of 16.67% per month.

Estimated Rake Reward is the potential percentage reward you could receive based on the Qualified Reward percentage, the amount of PPY you have vested and your share of the total GPOS balance.

For more information see

Why does the panel say I only qualify for 50% rewards even though I voted?

Voting qualifies you for participation rewards but the actual amount you qualify for is also based on the percentage of your PPY balance you've vested.

Why does my PPY balance show as 19.99PPY when it should be 20PPY?

Every time you withdraw from you GPOS balance there is a transaction fee of 0.01PPY.

My voting performance is 'OK Rewards', how do I improve this?

Basically, vote more often!

The performance rating is based on voting performance, to have a rating of 'OK' would mean that you've missed voting for about three months.

Thank you for voting!

You made it this far; now you qualify for participation rewards for contributing to the governance of Peerplays.

After you vote you'll see the following screen:

So like the avatar says, go and share your experience with your friends, family and the Peerplays community.

GPOS Panel
GPOS Landing Page
Power Up
Power Down
Vote
Thank you for voting!
General
GPOS Panel
Power Up & Power Down
Voting
Participation Rewards
GitHub
pbsa.info
Gamified Proof of Stake
Participation Rewards.

Gamified User Namespaces and Subject Matter Expert Committees

A brief introduction to GUNs and SMECs using the SPK network as an example.

1. Gamified User Namespaces

SPK network, a Peerplays community, will have its own namespace when users register that will always end with .SPK. Under this authority, dapp protocols will automatically whitelist these users for various operations relating to community governance. The gamified user namespace (GUN) will provide a means of onboarding new user accounts at little to no cost and will gamify the process of becoming a full user.

  1. Registration > randomname.SPK - keys (no fee)

  2. Deposit Funds > option to choose username.SPK (fee set by a Subject Matter Expert Committee, or SMEC)

  3. Engagement via Rewards Engine Parameter > option to choose username.SPK (fee set by SMEC)

The user accounts that operate under .SPK will have special switches which are associated with SPK network SMEC which will allow them to be able to vote on the rate of fees for operations. Before voting these operations will be whatever the current rate on Peerplays stands. Voting capabilities will be available only to the holders of SPK-NFTs, BRONCA-NFTs, or LARNIX-NFTs depending on what works best for the SPK network.

There will be many random sources which will be shared for account registration due to the faucets being built into network infrastructure nodes.

2. SKP Network NFTs Backed by Liquid Staking

SPK-NFTs are created by staking SPK and will have the capability to lock for up to 10 years (can be longer if set in the token parameters). If no period is selected they will, by default, stay locked with an inverse time to withdraw. This means if they stay locked for 30 days, it would take 30 days to withdraw if they initiated this on the 30th day to get their SPK out of the NFT. The NFT is then burned.

An alternative to destroying the NFTs would be to sell them on the NFT Marketplace and get access to their SPK or any other asset they want to sell it for instantly without the SPK needing to be unlocked from the NFT for whatever staking period may have been selected.

The staked SPK goes into the SPK Liquidity Pool with AMM DEX to power liquidity in SPK markets. The SPK market fees then flow back to all the SPK-NFT holders proportionally. The SPK-NFT that gets issued will have a PowerUP rating associated with the amount of SPK that was used to stake into the NFT. This gets used as the measure for rewards they receive. This means that the longer term someone commits to the staking period, the greater the rewards they will receive. When rewards are paid out they must be claimed by the user account and can be in the asset of their choosing supported in Peerplays. This means they could get SPK, BTC, PPY, HIVE, or any other assets available. If this is not desired, limited options can be made available in user interfaces.

These NFTs will be governed by dynamic properties while at the same time being capable of having custom "skins" for users preferences which can have additional gamification benefits.

For more information on Staking and Liquidity Pools, see here.

3. Subject Matter Expert Committees (SMECs)

Based on the SPK-NFT PowerUP, the user will be able to cast voting in various matters relating to the network.

Voting power is determined by the length of time the NFT has existed and the staked length. A linear scale starting from zero to the period staked provides that amount of weight multiplier the voter carries. This means someone who stakes for 10 years will not get the full weight multiplier on their stake, but instead will have it added to their account over the period of the stake with each coinday. Likewise, someone who has decided to stake by default with accumulating locking will experience the same multiplier effect over time. However, the staker of 10 years will have their weight increase from day one, as their multiplier has been predetermined by the 10 year commit.

This ensures that long term actors are the ones who will be able to carry more influence, but they will only have that influence accumulate over time. The only way for new people to gain this added vote power would be to accumulate SPK-NFTs from the marketplace which have been aged, thus increasing the subjective value of the SPK-NFTs.

Using the SPK-NFT the user can vote on the parameters of the network to determine what rates should be paid for fees on various operations. Some operations may be the rewards earned for holding SPK-NFTs that are generated from the DEX/AMM Liquidity Pools. These come from parameters set in the SPK market which will only be able to be controlled via voting among username.SPK accounts, and SPK-NFTs.

Another element which username.SPK users will be able to use are the operations of the SMEC which enables the users to vote for a committee of members which can be funded through various mechanisms. The SMEC do not have direct access to the funding pool but instead must approve proposals which should be used for their mission intent. Effectively the SMEC acts as a manager, and the ones who are doing the work are being paid by the proposal. Payouts for the funds only occur monthly when the SMEC publishes a progress report on the activity so as to provide concise communication feedback to the community at large.

Multiple SMECs can be created by the username.SPK community for any number of reasons beyond just funded work. Typically SMECs might include, but are not limited to, marketing, sales, development, legal, and payment gateways. The SPK.SMEC could also be configured so that the SPK market fees can flow to the SPK.SMEC for funding.

NFT marketplace in Python

Describing here the steps to verify the Marketplace_python on local or server machine.

Machine configuration : Local or server machine.

Step 1: Clone Marketplace_python binaries on machine

Project Url :

https://gitlab.com/PBSA/PeerplaysIO/tools-libs/python-peerplays/-/tree/nft

Clone binaries on Machine:

git clone https://gitlab.com/PBSA/PeerplaysIO/tools-libs/python-peerplays.git

Step: 2 Install virtual env on machine

Go to project:

cd python-peerplays

Run:

virtualenv -p python3 env

Step: 3 Install python requirements

Run:

source env/bin/activate

And then:

pip3 install -r requirements.txt

then:

pip3 install -r requirements-test.txt

Step: 4 Run unit tests

Run:

python -m unittest tests/test_market_place.py

Expected result should be as below:

(env) ubuntu@ip-172-31-13-101:~/python-peerplays$ python -m unittest tests/test_market_place.py
Not broadcasting anything!
Not broadcasting anything!
create_off Success!
Not broadcasting anything!
create_bid Success!
Not broadcasting anything!
cancel_offer Success!
All tests successful!
.
----------------------------------------------------------------------
Ran 1 test in 2.270s
OK
(env) ubuntu@ip-172-31-13-101:~/python-peerplays$

Intro to Peerplays Tokens

A brief guide to the various tokens of Peerplays.

1. Overview

Cryptocurrency (crypto) tokens represent tradable assets or utilities that reside on a blockchain. There are many uses for these tokens and their usefulness is growing in scope and scale at a remarkable pace. For example, just some of the things tokens are used for today:

  • a store of value, like fiat currency

  • fundraising via crowd sales

  • decentralized financial instruments (called DeFi)

  • digital intellectual property

  • digital objects (in-game items, etc.)

  • digital records (certifications, college degrees, etc.)

  • supply chain management

The Peerplays blockchain has its own set of tokens which enable the various features of the network. Each type of token brings more versatility to benefit everyone who enjoys Peerplays.

2. Token Types

Many different types of tokens exist in the world of crypto. Peerplays uses the following types to facilitate the transactions on the network.

Tokens are sometimes called "assets". The terms are pretty much interchangeable, at least for the purposes of this document.

2.1. Native Assets (coins)

The native assets within Peerplays are the coins which provide voting power when staked. The native asset of the Peerplays network itself is PPY. Communities within the Peerplays network may also have their own native asset. In this case, when the community native asset is staked, you would gain voting power for the governance of that community.

2.2. NFTs

NFTs, or Non-Fungible Tokens, are tokens that typically represent virtual objects. Such objects are indivisible by nature. A visual example of an NFT would be art prints. Many prints of a single piece of art can exist, but each print itself can't be divided. NFTs are often used for artwork because of this quality.

Another defining feature of NFTs is their ability to be verified thanks to blockchain technology. All NFTs are unique. Going back to the art prints example, it's possible to know exactly which print you own from a given set. You might have print number 6 out of 200 and this can be verified on the blockchain. Additionally, you can find all the transactions related to that NFT since its creation.

The Peerplays network allows you to create, exchange, and buy/sell NFTs. They're also used in Peerplays for token staking, governance, rewards, and countless uses within dApps.

2.3. Community Tokens

Community tokens (also called Fan tokens) are tokens which have been created to serve a particular community within the Peerplays network. Communities can have their own core token to provide voting power for the governance of that community. Other community tokens can exist to serve specific purposes within that community as well. The uses of community tokens are only limited by the imagination.

2.4. Sidechain Tokens

Sidechain tokens are assets which have originated off-chain that have been transferred onto the Peerplays chain through the services of Peerplays SONs. These sidechain assets include Peerplays versions of BTC, HIVE, or ETH and even Peerplays versions of NFTs living on the Ethereum chain. The external assets are backed by their counterparts, locked in a Peerplays controlled account on their native chains.

The sidechain tokens are prefixed with a "p" to denote that it is a Peerplays version of the token. For example, pBTC is Peerplays-Bitcoin and having a balance of 1 pBTC would mean having it backed by 1 BTC in a Peerplays controlled wallet. In this way, BTC can be deposited, withdrawn, and used across Peerplays as easily as any native token.

This means that tokens like BTC can be exchanged using the Peerplays Dex, staked to Peerplays liquidity pools, used in Peerplays based dApps, and to purchase NFTs.

3. Peerplays Tokens

3.1. PPY

PPY (Peerplays coin) is the native asset of the Peerplays network. Staking this asset provides voting power for voting on witnesses, SONs, advisors, and more. In addition, all exchanges that take place in the Peerplays Dex are based on exchanging assets with PPY. Currently a portion of all transaction fees within Peerplays is redistributed back to PPY holders as rewards, based on their amount of staked PPY.

PPY is the main store of value in Peerplays and is used to pay for transaction fees on the network.

3.2. BTFUN

BTFUN (BitFun) is the token created for BookiePro. BTFUN is used to place bets with a valueless token. It's used just for fun!

3.3. Peerplays NFTs

NFTs can be created on the Peerplays network for a wide variety of uses. DApp developers can issue NFTs to represent digital items, certificates, shares of ownership, and much more.

Appendix A
tribeculturechange.com
Figure 1: Bronfenbrenner's Ecological systems theory. See Appendix A for details.
84KB
PAO Flow Diagram.pdf
pdf
13KB
PAO Flow Diagram.xml
GPOS landing page
GPOS Landing Page.
vote

Power Down

If you have a GPOS balance then you can access the Power Down screen from the GPOS Landing Page.

After clicking on the Power Down button you'll be taken to the Power Down screen; from here you can withdraw from your GPOS balance.

Unsurprisingly the Power Down screen follows a very similar format to Power Up; you just use it to withdraw from your GPOS balance, instead of adding to it.

And just like the Power Up screen you can select an amount by scrolling up and down using the + and - buttons. The amount you select will be shown in the Withdraw field and reflected in your New GPOS Balance.

You can withdraw up to the total amount of your Opening GPOS Balance.

Note: There is a transaction fee of 0.01PPY each time a withdrawal is made.

In the example above the user has no vested balance. If an amount of 80PPY is vested the New GPOS Balance will be 80PPY and if the user power's up again the Opening GPOS Balance will be 80PPY as will the New GPOS Balance.

GPOS Balance Holding Period

In the example above note that although the Opening GPOS Balance is 80PPY the Available GPOS Balance is zero. This is because there is a 30 day holding period on new deposits. In this example the deposit was made the same day as the requested withdrawal.

The main reasons for having a holding period are:

  • It's in your best interest to maintain a GPOS balance, withdrawing from the balance will effect your participation rewards.

  • Withdrawing all the balance before 30 days could also effect your reward percentage by stopping you from voting.

  • There are fees associated with creating a balance and withdrawing from it. A holding period protects you from 'experimenting' with vesting and incurring unexpected fees.

Click on the CANCEL button to leave this screen without saving any changes. Or click on SUBMIT to save changes and return to the GPOS Landing Page.

Vote

If you have a GPOS balance then you can access the Vote screen from the GPOS Landing Page.

After clicking on the Vote button you'll be taken to the Vote screen from where you can vote for Witnesses, Advisors and Proxies.

The voting functionality hasn't changed from previous versions of the Peerplays Wallet so will only be documented briefly here.

Proxy

Proxy voting allows you to select another token holder to vote on your behalf. As far as GPOS goes this still constitutes participation as you have made a commitment to the operation of the blockchain.

However, since there are participation rewards at stake, and penalties for poor voting performance, if you use this option make sure you proxy your vote(s) to someone reliable!

Witness

Voting for a Witness is probably the most common use of a vote. By voting for a Witness you are playing an important role in the governance of Peerplays.

You can select one or more Witnesses from the list, or search for them, and then click ADD to add them to your approved list. Click PUBLISH CHANGES to cast your vote.

Advisors

The Peerplays Advisors are a committee that makes decisions on software changes to Peerplays and attributes and parameters of the blockchain. They are an important part of a DPOS consensus mechanism.

Selecting an Advisor works exactly the same way as selecting a Witness.

Important: Whether voting for Witnesses, Advisors or Proxies you must first click onPUBLISH CHANGES before you'll be able to click onFINISH.

Click on CANCEL to return to the GPOS Landing Page without voting, or click on FINISH to go to the Thank you for voting! screen.

NFT command reference

Step: 1 Create Metadata

Command used : nft_metadata_create <<account_name>> <<metadata_name>> <<metadata_symbol>> <<base_uri>> true true true

For example : nft_metadata_create account01 sknft sknft sknft null null true true true

Step:2 Update Metadata

Command used : nft_metadata_update <<account_name>> <<metadata_id>> <<new_name>> <<new_symbol>> <<new_base_uri>> null null true true true

For Example :nft_metadata_update account01 1.30.1 sknft01 sknft01 sknft01 null null true true true

Step: 3 Create NFT

Command used : nft_create <<account_name>> <<metadata_id>> <<Owner_account_name>> <<approve_aacount_name>> <<token_uri>> true

For Example : nft_create account01 1.30.0 account03 account03 sknftmint true

Step:4 Get NFT balance

Command used : nft_get_balance <<account_name>>

For Example : nft_get_balance account01

Step:5 To verify the owner of created NFT

Command used : nft_owner_of <<nft_id>>

For Example : nft_owner_of 1.31.1

Step:6 Safe NFT transfer

Command Used : nft_safe_transfer_from <<Operator_account_name>> <<transfer_from_account_name>> <<transfer_to_account_name>> <<nft_id>> true true

For Example : nft_safe_transfer_from account01 account01 aaccount02 1.31.1 true true

Step: 7 NFT Transfer

Command used : nft_transfer_from <<Operator_account_id>> <<From_account_id>> <<To_account_id>> <<nft_id>> true

For Example : nft_transfer_from 1.2.31 1.2.31 1.2.28 1.31.37 true

Step:8 NFT Approve

Command used : nft_approve <<new_operator_account_id>> <<new_account_id>> <<ndt_id>> true

For Example : nft_approve 1.2.19 1.2.19 1.31.1 true

Step : 9 To approve all NFTs at once

Command used: nft_set_approval_for_all <<Owner_account_id>> <<Operator_account_id>> true true

For example : nft_set_approval_for_all 1.2.21 1.2.21 true true

Step: 10 To see the approved account details

Command used : nft_get_approved <<approve_nft_id>>

For Example: nft_get_approved 1.31.0

Step:11 Approved for all

Command used: nft_is_approved_for_all <<owner_account_id>> <<operator_account_id>>

For Example : nft_is_approved_for_all 1.2.21 1.2.21

Step :12 Get list of all created NFT

Command used : nft_get_all_tokens

With this - all the created NFTs are listed on the machine.

Listeners

subscribe_to_market

Subscribe a listener to a betting market.

Apis.instance().db_api().exec( "subscribe_to_market", [updateListener, "1.3.0", "1.3.19"])
  • updateListener: An object of type updateListener.

  • 1.3.0: Start version.

  • 1.3.19: End version.

unsubscribe_from_market

Unsubscribe a listener from a betting market.

Apis.instance().db_api().exec( "unsubscribe_from_market", [updateListener, "1.3.0", "1.3.19"])
  • updateListener: An object of type updateListener.

  • 1.3.0: Start version.

  • 1.3.19: End version.

Service Infrastructure Pools

A specialized asset pool for Peerplays communities.

Service Infrastructure Pools (SIPs) are a special type of asset pool with their own purpose. SIPs exist to support the sustained growth of Peerplays communities. Where normal liquidity pools (LPs) enable asset swapping on the Peerplays chain, SIPs in contrast provide funding and rewards to the community they belong to.

1.1. Comparison of LPs and SIPs

The following table shows the similarities and differences between liquidity pools and service infrastructure pools.

Liquidity Pools

vs.

Service Infrastructure Pools

LPs provide the liquidity of assets so they can be instantly swapped.

What's the purpose?

Communities use SIPs as a steady stream of income for decentralized proposal funds and to reward community members.

Anyone can! LPs exist for any Peerplays asset.

Who can stake to it?

Communities can stake to SIPs automatically through the sale of their community tokens.

It's your choice. You can choose a locking period of up to 10 years.

How long are assets staked? (What's the locking period?)

Staking into a SIP is permanent. The staked assets will remain in the SIP forever.

You'll receive an NFT which represents your stake. This NFT will grant you voting power, and the right to claim rewards over time.

What do I get for staking?

Instead of staking directly to a SIP, the community will do so with the income it receives from selling a community token. So you receive some community token when you buy them directly from the community.

Your stake NFT is mature and you can Power Down the NFT to claim your stake back.

What happens when the locking period is reached?

There is no locking period for staking in SIPs.

1.2. How does a SIP work?

When you buy a community token directly from the community the assets you used to purchase those tokens get automatically staked into that community's SIP. The community will receive a special stake NFT to a community governance controlled rewards fund account. This special NFT cannot be traded, sold, sent, transferred, or otherwise moved from the account. It also cannot be Powered Down and has no locking period. It is completely permanent on that account.

The NFT represents that community's stake in its SIP. This guarantees a steady income to the community through its (now permanent) stake in income generating DeFi rewards pools. Depending on the assets received for the sales of their community token, the SIPs can be stakes of Peerplays assets like PPY or even off-chain assets like HIVE. Since these stakes are permanent and are executed on the community level, the special NFTs do not generate voting power like normal stake NFTs do for staking in LPs.

Through community governance, the community decides what to do with the rewards received from its SIP. The community could decide to create a decentralized proposal fund to make continual improvements. Or the community could decide to simply pass the rewards on to its members. The community could even decide to do both and set the rate of each. Communities in Peerplays are empowered to self-govern.

1.3. SIP flow diagram

The diagram below shows the essence of Service Infrastructure Pools.

Downloads

The Diagram in PDF form to easily view and share:

63KB
sip-basic-diagram.pdf
pdf
Service Infrastructure Pools Diagram (PDF)

The Diagram in Draw.io's XML format. You can edit the diagram using this file in Draw.io:

8KB
sip-basic-diagram.xml
Service Infrastructure Pool Diagram (Draw.io XML)

GPOS Panel

The GPOS Panel

The home page of the wallet now includes a panel to display your GPOS status.

The features of the panel are:

GPOS Balance

This is the total amount of PPY that has been vested. In the above example the amount is zero which is reflected in the Voting Performance as well.

Voting Performance

Voting performance is calculated based on the last time you voted for either Witnesses, Advisors or Proxies. The text and colour of the caption indicates your performance according to the following table:

Reward %

Text

Colour

0

No rewards

Dark Red

1- 16.68

Critical low

Red

16.69 - 33.33

Lower rewards

Orange

33.34 - 50

Low rewards

Yellow

50.01 - 66.66

OK rewards

Blue

66.67 - 83.33

Good rewards

Dark Green

83.34 < 100

Great rewards

Green

100

Max rewards

Same colour as

other captions

Get Started

Clicking on the GET STARTED button will begin the GPOS vesting process.

If you have a zero GPOS balance, which will always be the case if this is the first time you are using it, the button text will be Get Started. However, the text on the button will change to PATICIPATE once a balance is vested. See Power Up

Participate

As mentioned, this option is only available once you have a GPOS balance.

Clicking on PARTICIPATE will take you to the GPOS Landing Page as before, except this time both the Power Down and Vote buttons will be enabled.

Peerplays Core API

Logout

To logout of the account, the user has two option.

  1. The user can click on the account name in the header tab and choose logout option.

Fig-1: Logout option1

2. The user can click the menu option and logout will be at the bottom of the list.

Fig-2: Logout option2

Profile

The profile page displays the information about the orders, activities and notification of the account.

1. Orders

The order tab displays the collection of all details about the Open order and Order history happened from the beginning of account creation.

It also provide the option to download the PDF/CSV file in a single click.

2. Activities

This tab provide the list of activities happening in the account. Based on the time of activity, there is filter option to sort in either ascending/descending order.

With the Type filter, based on activities like create an account, fill order, cancel order, etc., it can be sorted.

Each activities has its own information about the activity, ID and Fee involved in it.

3. Notification

This tab provides the list of notifications occurred in the account. Based on the time of notification, there is filter option to sort in either ascending/descending order.

With the Type filter, based on notification like create account, fill order, cancel order, etc., it can be sorted.

Each notification has its own information about the activity, ID and Fee involved in it.

Account Creation

The page to create login for new users

Creating an Account

  1. Navigate to dashboard.

  2. Click on Create account to create a new login.

3. Enter the desired Username.

The user name should start with lowercase.

The user name should not contain,

  • Capital Letter

  • Special Characters

  • Only digits

4. For the first time, the password is auto-generated. Copy that password and paste it into the "re-enter your auto-generated master password" box.

5. Click "Download Recovery password file here" option to download the Keys to use for future login.

6. Enable the checkboxes and click on create account.

7. After successful login, the following screen will be displayed.

Python Peerplays

Introduction

Its the Python library for communicating with the Peerplays blockchain.

The code is maintained at

Ids

1.2.x : accounts

1.3.x : assets

Notes

p.rpc.get_account_balances("jemshid", [])

p.rpc.get_global_properties

private-key = ["TEST6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV","5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"]

Network Nodes API

The network node API is available from the full node via web-sockets.

Obtain Network Information

get_info

Return general network information, such as p2p port.

get_connected_peers

Get status of all current connections to peers.

get_potential_peers

Return list of potential peers.

get_advanced_node_parameters

Get advanced node parameters, such as desired and max number of connections.

Change Network Settings

add_node

Connect to a new peer

  • ep: The IP/Port of the peer to connect to

set_advanced_node_parameters

Set advanced node parameters, such as desired and max number of connections.

  • params: a JSON object containing the name/value pairs for the parameters to set

Bookie API

Block API

Block

get_blocks

Get signed blocks.

  • block_num_from: The lowest block number

  • block_num_to: The highest block number

A list of signed blocks from block_num_from to block_num_to

Popular API Calls
Account History API
Asset API
Block API
Crypto API
Database API
Network Broadcast API
Network Nodes API
Orders API
fc::variant_object graphene::app::network_node_api:get_info()const
std::vector<net::peer_status> graphene::app::network_node_api::get_connected_peers()const
std::vector<net::potential_peer_record> graphene::app::network_node_api::get_potential_peers()const
fc::variant_object graphene::app::network_node_api::get_advanced_node_parameters()const
void graphene::app::network_node_api::add_node(
    const fc::ip::endpoint &ep)
void graphene::app::network_node_api::set_advanced_node_parameters(
    const fc::variant_object &params)
vector<optional<signed_block>> graphene::app::block_api::get_blocks(
    uint32_t block_num_from, 
    uint32_t block_num_to)const
def transfer(self, to, amount, asset, memo="", account=None, **kwargs):
https://gitlab.com/PBSA/PeerplaysIO/tools-libs/python-peerplays
Fig-1: Order details
Fig-2: Account Activities
Fig-3: Account notifications
PeerplaysDEX
Fig-1: Dashboard Page
Fig-2: Login creation
Fig-3: Create account page
Fig-4: Login Creation Success

Consensus Mechanisms Compared

The differences among POW, POS, & POP (and their variations)

1. Consensus

In the realm of crypto-economies, consensus is the way decisions are made that impact a whole network despite having no central decision-maker. Systems must be in place to allow everyone to agree on transactions happening in real-time across the globe. This is why the developers of blockchains have carefully crafted mechanisms of consensus to try to preserve decentralization while also maintaining mutual agreement of all members of the network.

Here we will explain the most widely used and well known consensus mechanisms, Proof of Work and Proof of Stake. We will also introduce a new consensus mechanism which serves to be the latest evolution and a paradigm shift to the approach of consensus, Proof of Pulse.

2. Proof of Work

2.1. The Big Idea

Competitive: The one with the most computing power wins.

Proof of Work (POW) is essentially a puzzle-solving race to determine block creation. Block producers, known in this case as "miners", use ever-increasing levels of computing power to solve more and more difficult puzzles. The first miner to solve the puzzle produces a block on the network, receives a reward, and the process starts again with a new puzzle. Its main goal is to incentivize people to use their computing power to ensure the network continues to run, and the blocks are validated.

2.2. Incentivization

Miners are in a competitive race to produce blocks on the network. For every block produced, a reward is given to the producer. The difficulty of the puzzles increases over time to keep the block production at roughly 10 minutes per block (on the Bitcoin chain). The difficultly must increase due to more and more computing power coming online to earn rewards. This has the unfortunate side effect of being horribly inefficient. More and more electricity is being used to fuel the computing power, etc.

2.3. Network Security

In POW, the distribution of computing power matters most. If an individual or organization could gain 51% of the network computing resources, they could simply validate any block they wished. In essence, it would be a complete chain take-over. The power of cryptocurrencies comes from the decentralization of its ledger of transactions. If anyone could own 51% of the network resources, they would own the ledger and the network would no longer be decentralized.

3. Proof of Stake

3.1. The Big Idea

Competitive: The one with the most tokens wins.

Proof of Stake (POS) is another competitive consensus algorithm. But instead of a computing power race, the level of staked tokens is used as the determining factor of who can produce and validate blocks. This method is much more efficient than POW. The more staked tokens an account has, the more priority it is given to produce and validate blocks. Rewards at then given to the producers upon block production.

3.2. Incentivization

Block producers, sometimes called "Master Nodes" in POS, store vast amounts of the network's tokens in stakes. Depending on the chain in question, sometimes a certain (usually very high) level of stake is required to be a block producer. Higher stakes means more rights to produce blocks which in turn means more rewards. This translates to a classic "the rich get richer, the poor get poorer" scenario.

3.3. Network Security

In POS, the distribution of staked tokens matters most. Much like in POW, If an individual or organization could gain 51% of the staked tokens, they could simply validate any block they wished. Again, it would be a complete chain take-over. The power of cryptocurrencies comes from the decentralization of its ledger of transactions. If anyone could own 51% of the staked tokens, they would own the ledger and the network would no longer be decentralized.

3.4. Variations

Delegated Proof of Stake

Delegated Proof of Stake (DPOS) is a variation of POS in that instead of only the highest levels of stake getting a say, everybody with any amount of stake can participate. Although the same "Master Node" concept applies, anyone can apply their stake to back a Master Node. When the Master Nodes are rewarded, the rewards are shared proportionally with those who backed them up with their stake. It helps to spread the rewards a little, but it's like the blockchain equivalent of "trickle down" economics. It still requires huge stakes to have meaningful rewards.

In some chains, like Graphene based chains, DPOS is implemented more like a vote. Master Nodes ("Witnesses" in Graphene) are voted on by applying your stake as a vote for someone else's node. The winners of the vote are then the active block producers.

Gamified Proof of Stake

Gamified Proof of Stake (GPOS) is a further improvement on DPOS. Voting for Witnesses with staked tokens occurs like with other Graphene chains, but in this case the rewards given to the voters diminishes over time. Voters must periodically vote again to maintain their rewards income. This requires the voters to be more actively engaged in the network governance to reap the full benefits of their stake.

GPOS is where we start to see a major paradigm shift:

  • We're moving from competitive consensus to cooperative consensus.

  • The rewards shift from paying those that own capital (expensive computers, vast sums of tokens) to paying those that do work (node operators providing services).

  • People go from being passive users of a network to engaged participants in network governance.

  • The incentives shift from the extrinsic, "What can the network do for me?" to the intrinsic, "How can we improve the network for everyone?".

4. Proof of Pulse

4.1. The Big Idea

Cooperative: Everyone contributes to incremental network improvement.

Proof of Pulse (POP) generates network consensus spontaneously from the outcomes of continuous, randomized, and incremental voting. Every hour a round of voting, a "pulse", begins:

  1. First, a random subset of accounts are selected across the network.

  2. These accounts are each given one random item to vote on. (Fees, node operators, etc.)

  3. Each chosen account is notified, and there is a limited time to make their vote.

    1. Votes can only be: Up (in favor), Down (against), or Stay (no change).

    2. Votes are weighted by voting power of the account.

  4. The votes are tallied per item and the winning vote is how that particular item will change.

  5. The impact of the pulse will expire after 60 days.

This method ensures that, while everyone has a voice, it's the will of the collective whole that moves the network along.

4.2. Incentivization

The POP consensus mechanism relies on the intrinsic motivation of individuals who genuinely wish to improve the state of the network. There are no monetary rewards for casting votes or participating in blockchain governance. Node operators are paid for the work they perform for the network. One of the decisions of consensus is how much a node operator will be paid for their services.

Another form of income is to stake tokens to supply liquidity pools to enable instant token swaps. In this case, staked tokens will earn rewards from the transaction fees of the token swaps they are backing. Once again, the transaction fees are changed through decisions of consensus.

Note that in POP, rewards are only paid when some form of work is done. If you are a node operator, you are running software to provide a service. If you stake to a liquidity pool, people are using your tokens to make swaps in the exchange.

4.3. Network Security

The Attacker's Dilemma

An attacker's goal is to gain as much control over the network parameters as possible. This is usually done by using overwhelming resources to gain the majority of voting power or ability to edit the chain itself. In a POP system, an attacker has to make a decision:

  • Concentrate all of their voting power on one account...

    • but severely limit their chances of being included in the vote they wish to control!

  • Open hundreds of accounts to give themselves a much greater chance of being randomly assigned the votes they wish to control...

    • but spread their voting power too thin to actually control the vote!

As you can see, it's a bad situation for an attacker. They cannot simultaneously have "whale" levels of voting power and also guarantee they'll be assigned the votes they want to control. But it gets even worse for an attacker. Even if they hold massive voting power in their account, and get lucky enough to be randomly assigned the vote they want, they can't set chain parameters. Votes are only for incremental changes from the existing parameter levels. And on top of that, the effects of votes drop off over time. That is to say, a vote outcome today will not have an effect on the chain parameters after 60 days. So they would have to have absurd luck, again and again, to dominate the chain.

Proof of Pulse was designed specifically for consensus of the whole network.

5. Future of Consensus

Consensus is about agreement. That's why it's important to rethink the mechanisms we create to form consensus in this new decentralized world. Competitive structures don't seek agreement. Instead we can use cooperation to build a system that benefits everyone. We can use incentives to get work done rather than to pay those who are already at the top. We can build more human centered networks. This is what the Proof of Pulse consensus mechanism is all about.

Blockchain Inspection

Blockchain Inspection

get_block

Returns info about a specified block.

optional<signed_block_with_info> graphene::wallet::wallet_api::get_block(
    uint32_t num)
  • num: height of the block to retrieve

Info about the block, or null if not found.

get_account_count

Returns the number of accounts registered on the blockchain.

uint64_t graphene::wallet::wallet_api::get_account_count()const

The number of registered accounts

get_global_properties

Returns the block chain’s slowly-changing settings.

This object contains all of the properties of the blockchain that are fixed or that change only once per maintenance interval (daily) such as the current list of witnesses, committee_members, block interval, etc.

See get_dynamic_global_properties() for frequently changing properties.

global_property_object graphene::wallet::wallet_api::get_global_properties()const

The global properties.

get_dynamic_global_properties

Returns the block chain’s rapidly-changing properties. The returned object contains information that changes every block interval such as the head block number, the next witness, etc.See

get_global_properties() for less-frequently changing properties

dynamic_global_property_object graphene::wallet::wallet_api::get_dynamic_global_properties()const

The dynamic global properties.

get_object

Returns the blockchain object corresponding to the given id.

This generic function can be used to retrieve any object from the blockchain that is assigned an ID. Certain types of objects have specialized convenience functions to return their objects e.g., assets have get_asset(), accounts have get_account(), but this function will work for any object.

variant graphene::wallet::wallet_api::get_object(
    object_id_type id)const
  • id: the id of the object to return.

The requested object.

General Calls

General Calls

help

Returns a list of all commands supported by the wallet API.

This lists each command, along with its arguments and return types. For more detailed help on a single command, use gethelp()

string graphene::wallet::wallet_api::help()const

A multi-line string suitable for displaying on a terminal.

gethelp

Returns detailed help on a single API command.

string graphene::wallet::wallet_api::gethelp(
    const string &method)const
  • method: the name of the API command you want help with

A multi-line string suitable for displaying on a terminal.

info

Returns info about head block, chain_id, maintenance, participation, current active witnesses and committee members.

variant graphene::wallet::wallet_api::info()

Runtime info about the blockchain

about

Returns info such as client version, git version of graphene/fc, version of boost, openssl etc.

variant_object graphene::
wallet
::
wallet_api
::about()const

Compile time info and client and dependencies versions.

network_add_nodes

void graphene::wallet::wallet_api::network_add_nodes(
    const vector<string> &nodes)

nodes: Nodes to be added.

network_get_connected_peers

vector<variant> graphene::wallet::wallet_api::network_get_connected_peers()

List of connected peers.

NFT Operations in Python

Describing the steps to verify the NFT_python on local or server machine below.

Machine configuration : Local or server machine.

Step 1: Clone NFT_python binaries on machine

Project Url :

https://gitlab.com/PBSA/PeerplaysIO/tools-libs/python-peerplays/-/tree/nft

Clone binaries on Machine :

git clone https://gitlab.com/PBSA/PeerplaysIO/tools-libs/python-peerplays.git

Step: 2 Install virtual env on machine

Go to project :

cd python-peerplays

Run:

virtualenv -p python3 env

Step: 3 Install python requirements

Run:

source env/bin/activate

then,

pip3 install -r requirements.txt

And then,

pip3 install -r requirements-test.txt

Step: 4 Run unit tests

Run:

python3 -m unittest tests/test_nft.py

Expected result should be as below:

(env) ubuntu@ip-172-31-13-101:~/python-peerplays$ python3 -m unittest tests/test_nft.py
Not broadcasting anything!
nft_metadata_create Success!
Not broadcasting anything!
nft_metadata_update Success!
Not broadcasting anything!
nft_mint Success!
Not broadcasting anything!
nft_safe_transfer_from Success!
Not broadcasting anything!
nft_approve Success!
Not broadcasting anything!
nft_set_approval_for_all Success!
All tests successful!
.
----------------------------------------------------------------------
Ran 1 test in 3.449s

OK
(env) ubuntu@ip-172-31-13-101:~/python-peerplays$

Cheers, all unit tests are passed and you successfully verify the NFT_python

Creating an Account

vThere are two ways to create an account.

  1. Python-Peerplays way: If you already have an account, that can be used to create another account.

  2. Faucet Way

Python-Peerplays Way

You need a funded account to create additional accounts. The funded account should be upgraded to create new accounts. To upgrade an account

p.upgrade_account(account="account_name")

Once the account is upgraded

p.create_account(account_name="new_account_name", registrar="the_upgraded_account", owner_key='TEST6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV', active_key='TEST6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV', memo_key='TEST6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV')

Faucet Method

url = https://elizabeth-faucet.peerplays.download/api/v1/accounts

params = {'account': {
    'name': 'new_account_name',
    'owner_key': 'TEST6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV',
    'active_key': 'TEST6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV',
    'memo_key': 'TEST6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV',
    'refcode': '',
    'referrer': ''}}
    

requests.post(url, json=params)

Additional Methods

p.transfer(to, amount, asset, memo="", account=None)

Network Broadcast API

The network broadcast API is available from the full node via web-sockets.

Transactions

broadcast_transaction

Broadcast a transaction to the network.

The transaction will be checked for validity in the local database prior to broadcasting. If it fails to apply locally, an error will be thrown and the transaction will not be broadcast

void graphene::app::network_broadcast_api::broadcast_transaction(
    const precomputable_transaction &trx)
  • trx: The transaction to broadcast

broadcast_transaction_with_callback

This version of broadcast transaction registers a callback method that will be called when the transaction is included into a block. The callback method includes the transaction id, block number, and transaction number in the block.

void graphene::app::network_broadcast_api::broadcast_transaction_with_callback(
    confirmation_callback cb, 
    const precomputable_transaction &trx)
  • cb: the callback method

  • trx: the transaction

Block

broadcast_block

Broadcast a signed block to the network.

void graphene::app::network_broadcast_api::broadcast_block(
    const signed_block &block)
  • block: The signed block to broadcast.

Creating the wallet

All these experiments and examples are expected to be tried out in ipython command shell. Start the command shell with ipython

Node is the chain with which you wish to interact.

node = "wss://elizabeth.peerplays.download/api"

password = "password"

from peerplays import PeerPlays

p = PeerPlays(node)

To create a new wallet

p.newWallet(password)

Unlock the wallet

p.unlock(password)

Add private key / keys

p.wallet.addPrivateKey("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3")

Additional Methods

p.wallet.unlocked() #returns True if wallet is unlocked. Wallet needs to be unlocked to perform operations on the blockchain.

p.wallet.getAccounts() #Lists all the accounts associated with the private key.

Asset API

Asset

get_asset_holders

Get asset holders for a specific asset.

vector<account_asset_balance> graphene::app::asset_api::get_asset_holders(
    std::string asset, 
    uint32_t start, 
    uint32_t limit)const
  • asset: The specific asset id or symbol

  • start: The start index

  • limit: Maximum limit must not exceed 100

A list of asset holders for the specified asset.

get_all_asset_holders

Get all asset holders.

vector<asset_holders> graphene::app::asset_api::get_all_asset_holders()const

A list of all asset holders.

Installation

The python-peerplays library has following dependencies. Make sure that the above dependencies are installed, if not install with:

sudo apt-get install python3-dev build-essential libssl-dev\
 libffi-dev libxml2-dev libxslt1-dev zlib1g-dev

Now install python-peerplays as follows:

 pip install peerplays

Ipython is a rich interactive python command shell. It's recommended for trying out python-peerplays library. It can be installed with

pip install ipython

In case Python 2.7 is the default Python for your machine, repalce

pip with pip3

python with python3

ipython with ipython3

Ipython shell can be started with the command

ipython

To work with the latest development version of python-peerplays

git clone [email protected]:PBSA/PeerplaysIO/tools-libs/python-peerplays.git

cd python-peerplays

git checkout develop

To Do

  1. How to install system level from git for develop branch

General
Tournaments
Listeners

User Guide

The user guide helps user to understand the various functionalities of NEX application. The below section guides the user to perform desired operations,

1. Account Creation

This section helps the new user in account creation. It also explains the existing user login operation. Click the below link to learn about this in details,

2. Dashboard

The dashboard has four different operations and it is the home page of NEX application. The dashboard provide the options such as Deposit, withdraw, swap and market functions. Click the below link to learn more,

3. Market Activity

The market activity page helps the user to choose the trading pair to perform sell/buy operations. It's one of the important page which helps the user to learn about the activities such as performance, history, order history, and open orders of any selected trading pair. Click the belwo link to learn in detail,

4. Peerplays Blocks

Blockchain represents the detailed list of block, time, supply (PPY), and ID. The user can switch between witnesses, sons and committees to learn more about each in details. The fees section provide list of all activities and respective fees involved. Click the below link to learn more in detail,

5. Settings

The settings page helps the user to alter any existing feature based on preferences. It provides option to setup language, generate keys and membership. Click below to learn more about the setting operation,

6. Wallet

Wallet page show the list of assets, asset send & receive option which helps user to perform any operations at ease. Click the below link learn the wallet operation in detail,

7. Profile

The profile page has the option to check the activities of the user such as open orders, order history, activities, and notification in the account. Click the below link to learn more in detail,

8. GPOS - Voting

The voting page helps the user to verify any desired account and perform voting operation. The sections are classified as witness, sons and committee. The user also has the option to choose proxy account. Click the below link to learn in detail,

9. Logout

Click the below link to learn about the options to perform logout operation.

Connecting Elasticsearch to a blockchain node

Editing the configuration for Elasticsearch

Inside ./witness_node_data_dir/config.ini edit the following:

Uncomment plugins = and add the elasticsearch and es_object plugins.

# Space-separated list of plugins to activate 
plugins = elasticsearch es_objects

Uncomment elasticsearch-node-url = and add the Endpoint URL for your Elasticsearch instance.

Make sure to keep the trailing slash at the end of the URL.

# Elastic Search database node url(http://localhost:9200/) 
elasticsearch-node-url = <ES-ENDPOINT>

Uncomment es-objects-elasticsearch-url = and add the Endpoint URL for your Elasticsearch instance.

Make sure to keep the trailing slash at the end of the URL.

# Elasticsearch node url(http://localhost:9200/) 
es-objects-elasticsearch-url = <ES-ENDPOINT>

Start the witness node

Start the witness node to being pushing indexes to Elasticsearch. The beginning few logs should show the Elasticsearch plugins started:

572387ms th_a elasticsearch_plugin.cpp:516 plugin_startup ] elasticsearch ACCOUNT HISTORY: plugin_startup() begin
572387ms th_a application.cpp:1235 startup_plugins ] Plugin elasticsearch started
572395ms th_a es_objects.cpp:405 plugin_startup ] elasticsearch OBJECTS: plugin_startup() begin
572395ms th_a application.cpp:1235 startup_plugins ] Plugin es_objects started ...

575659ms th_a es_objects.cpp:82 genesis

Basic Checks

You can check the indexes created after the witness start with the next call:

$ curl -X GET '<ES-ENDPOINT>/_cat/indices'
yellow open ppobjects-asset   vnF2F0BMSKKNxQfu013OCQ 1 1  2 0 12.4kb 12.4kb
yellow open ppobjects-balance 3psSvHIeRC-fKHyqP2Legg 1 1  1 0  5.9kb  5.9kb
yellow open ppobjects-account zQ7uv01ESEeqCED3WHmmxg 1 1 21 0 42.4kb 42.4kb

You can also get index search data with:

curl -X GET '<ES-ENDPOINT>/peerplays-*/data/_search?pretty=true' -H 'Content-Type: application/json' 

Wallet API

The wallet (cli_wallet) requires a running full node to connect to because it does not offer P2P or blockchain capabilities directly.

If you have not set up your wallet yet, you can find more information here: CLI Wallet Setup.

Intro to Peerplays Liquidity Pools

A brief overview of the Peerplays Liquidity Pools.

1. Liquidity Pools

Liquidity pools (LPs) are designed to enable the instant swapping of various crypto assets, coins or tokens, at a price which is based on the available supply of each asset. LPs give those who are looking for an opportunity to earn rewards with the assets they own a way to do so. These asset owners supply the liquidity by staking their assets into the pool.

1.1. What is a liquidity pool?

In Peerplays, a liquidity pool is a network controlled asset address which is used to store the assets which have been staked to the pool. This pool is then used to facilitate the exchange of assets between interested traders. A small fee is charged to execute an exchange using the pool. The fees are then given to the people who staked to the pool in proportion to the amount of assets they have staked as rewards.

1.2. Get rewards by staking

When you stake assets to an LP, you receive an NFT in return. The NFT (non-fungible token) stores and tracks certain info about your stake:

  • the pool you staked to

  • the number of assets that you staked

  • the length of time you chose to lock the assets for

  • the total rewards which have been earned

  • the amount of claimed rewards so far

  • and more

The NFT represents your claim on the amount of rewards that have been generated by the staked assets.

2. Asset Staking

Staking your assets to an LP (known as an asset Power Up) helps to sustain the health of the Peerplays exchange. More assets staked to an LP means greater liquidity in the market. And greater liquidity in the market has many benefits to all participants. Staking your assets provides perks to you as well. In addition to generating rewards over time, the NFT you receive for staking can also grant you voting power.

2.1. The stake NFT perks

When you decide to stake your assets to an LP, first you'll choose which pool to support. Then you can choose how long to lock the assets into the pool. Once your assets are staked, you'll receive your stake NFT.

Rewards - Rewards will be generated over time based on the amount of assets you staked and the length of the locking period you chose for the stake. You can claim the available rewards at any time and in any asset you like. The NFT tracks the total rewards earned and the total amount you claimed. This is important information because you can buy and sell stake NFTs in the NFT marketplace. You can also power down the NFT to get your assets back (minus claimed rewards).

Voting Power - Your voting power is determined by the amount you stake as well as how long you choose to stake your assets for. Higher stakes and longer locking periods will grant more voting power. Though you won't get all the voting power all at once. To prevent people with large amounts of assets from dominating voting, voting power is generated over time.

Supporting Communities - Staking assets that are created by communities on the Peerplays network will help to support those communities. People will be able to easily exchange their assets for the community's assets and you can participate in the governance of that community.

2.2. The freedom of your stake NFT

Your stake NFT isn't bound to your account. You have the freedom to sell your NFT or to put it up for auction. You can send it to another account or you can choose to power it down.

Buying and Selling - One of the quickest ways to gain the perks of a stake NFT is to simply buy one from the NFT marketplace. The NFT will be sent to your account where it will generate rewards and voting power for you. The previous owner of the NFT may or may not have already claimed some of the rewards. Anything that remains unclaimed when you buy the NFT is then yours to claim. Similarly you will gain the voting power that the NFT has accrued over its life so far.

Because of the time dependant values explained above, you can sell aged NFTs at a premium. This is a great way to get some assets back. Selling the NFT keeps the assets in the LPs so liquidity is maintained in the market.

NFT Power Down - Another option for reclaiming your staked assets is to Power Down (burn) your stake NFT. If the NFT has matured, the locking period has elapsed, you can claim the remaining rewards that have accrued and then receive all of your staked assets from the pool.

If the locking period has not elapsed when the NFT is powered down, you will receive your staked assets from the pool minus the amount of claimed rewards. Essentially, you'll get the full amount of what you had initially staked, but no rewards. This is true for any stake NFT you own, even if you bought it from the NFT marketplace.

Flow of Voting Power - Stake NFTs will generate voting power over time until they reach their maximum voting power value. The voting power is granted to whoever owns the NFT. If you buy an NFT from the marketplace that has some voting power, that voting power is now yours and the previous owner of the NFT loses the voting power. (vice versa if you sell!)

The only way that voting power is destroyed is when a stake NFT is powered down. Not only does this remove liquidity from the market, it also removes voting power from the network. This is something to consider before powering down a stake NFT, even a mature NFT.

3. Asset Swapping

Liquidity pools were built to support instant asset swaps. This exchange of assets differs in many ways from the traditional approach of order book trading. There are pros and cons to each and both are beneficial in their own way. Peerplays offers asset swapping based on liquidity pools and fully decentralized order book trading. The best of both worlds!

3.1. Swapping vs. Order Books

The table below contrasts the trading methods of swapping and order book trading.

3.2. How can I swap assets?

Peerplays asset swapping is one of the fastest ways to exchange one asset for another. Once you visit the Peerplays DEX and sign in, you have the ability to deposit assets to your Peerplays account. Then on the swap tab, you'll be able to select the assets you'd like to exchange.

4. Liquidity Pools Flow Diagram

The diagram below shows the essence of Liquidity Pools. A more detailed liquidity pool diagram with use case examples can be .

4.1. Downloads

The Diagram in PDF form to easily view and share:

The Diagram in Draw.io's XML format. You can edit the diagram using this file in Draw.io:

Peerplays DEX

A brief overview of the Peerplays decentralized exchange.

1. Decentralized Asset Exchanges

In the cryptocurrency space, a decentralized exchange (DEX) is a place to trade crypto assets while maintaining ownership of your private keys and thereby keeping control of your assets. There is no third party or broker in the DEX. Instead, the trading is managed by an impartial (and therefore trustworthy) automatic market-making algorithm.

2. The Peerplays DEX

The user can perform the following tasks using Peerplays DEX:

  • use it as a wallet to manage your assets.

  • monitoring the market activity of any trading pair.

  • swap assets using the Peerplays PPY.

  • cast votes and participate in blockchain governance.

  • manage your Peerplays account.

  • register your Bitcoin, Hive, and Ethereum accounts to send and receive BTC, HIVE, and ETH.

3. Peerplays account

The user has to log in to Peerplays DEX to manage the Peerplays account. The user can monitor activities such as selling/buying assets, monitoring market activities, order history, profile setting, and voting in their account. Use the below document to create one,

4. Peerplays wallet

There is a built-in wallet for each account through which the user can trade the asset, receive the asset from BTC/HIVE/ETHEREUM, and maintain ownership.

Deposits and withdrawals

You can deposit Bitcoin and Hive to your Peerplays wallet to use in the Peerplays DEX. Peerplays SONs (Sidechain Operator Nodes) enable off-chain assets to be deposited and withdrawn from Peerplays accounts. More chains will be added over time to bring the most popular assets to Peerplays.

When these assets are on the Peerplays chain, they benefit from the 3-second blocks of the Peerplays network. They can be traded, swapped, or staked like any other Peerplays asset. And they can be withdrawn back to their original chains as well. When these off-chain assets are on the Peerplays chain, they are always backed by an equal amount on their original chain.

Sending assets

Assets that you own can easily be sent to any other Peerplays account. When on the Peerplays chain, Bitcoin and Hive can be sent to other Peerplays accounts or addresses on their original chains.

5. Asset staking (PowerUp)

Staking your assets using the PowerUp option in the DEX will earn you rewards and voting power over time. Your staked assets supply liquidity pools used for asset swapping. In return, you'll receive an NFT that represents and tracks your stake in the liquidity pools.

The NFT reaches maturity when its locking period (which you choose) expires. At this point, you can PowerDown the NFT to retrieve your assets from the pool. At any time along the way, you can claim the rewards that have been accruing based on the size of your stake and the length of the locking period you chose. But beware, powering down the NFT means losing the voting power that has also been accruing.

Another option you have is to sell the NFT in the NFT marketplace. Especially if you have an aged NFT, you can fetch a premium price for your NFT.

6. GPOS - Voting

Transfer the PPY to GPOS balance to participate in the voting for best witnesses, advisors, SONS, and proposals. To increase the participation rewards, the user has to transfer more PPY into the GPOS balance and share Peerplays with others. Peerplays remains the most secure provably fair blockchain globally with Decentralized Autonomous Cooperative (DAC).

Using Powerup, the user can participate in the DAC with which the user can become a big part globally, earn participant rewards, stake PPY while participating, bragging rights, and help secure Peerplays Blockchain.

7. Asset swapping

From the Peerplays account, using PPY asset swapping can be done with ease. The swapping mechanism is simple and quick compared with the traditional order book exchange. The exchange rate is calculated based on the available supply of each asset rather than set by traders seeking the best price.

8. The exchange

The Peerplays DEX provides a decentralized order book trading experience for those who prefer to set their own prices on trades. The DEX supports market, limit, and stop-limit orders. The exchange is where you can speculatively trade various markets. Since the Peerplays DEX keeps your private keys in your hands and is both a decentralized exchange and your wallet, there's no need to store your assets off the DEX. This means you can always be ready to trade in any market condition without the worry of hackers, exit scams, government takeovers, or bankruptcies (like what happens to centralized exchanges.)

9. Blockchain governance

The DEX is the place to cast your votes on important blockchain issues. You can help direct the blockchain and strengthen it by voting for the best node operators. Votes will also occur for setting fees for all the blockchain operations, how many node operators should run the network, which node operators are active, and network proposals. The voting happens on a continuous cycle so the blockchain can grow in the direction the voters wish to take it.

Wallet

The wallet option allows the user to view the asset available in that account. It also has the option to send and receive assets from other accounts.

The Wallet has three sections,

  1. Asset

  2. Send

  3. Receive

1. Asset

This section displays the list of assets available in the account. A search option is available to find any desired asset. The list of assets can be downloaded in the form of a PDF/CSV file.

The list of assets can be filtered based on symbol, name, available tokens, and orders.

Each asset has two buttons namely, send/receive to perform the transaction in a single click.

2. Send

The send section has the option to send available assets from one wallet to another account.

  1. Fill in the form with the correct input based on your transaction.

2. Click on the Send button to initiate the transfer. Next, it prompts you to enter the password for validation.

3. Click on Confirm to complete the transaction. The asset will be successfully transferred to another account.

3. Receive

To receive an asset from another account to your account, the wallet receives option can be used. Select the desired option under the Receive Assets drop-down list.

Based on the asset selection the hint to perform the transfer will be provided. Follow that to complete the transaction.

List of assets

After asset selection

Orders API

Orders

get_grouped_limit_orders

Get grouped limit orders in given market.

  • base_asset: ID or symbol of asset being sold

  • quote_asset: ID or symbol of asset being purchased

  • group: Maximum price diff within each order group, have to be one of configured values

  • start: Optional price to indicate the first order group to retrieve

  • limit: Maximum number of order groups to retrieve (must not exceed 101)

The grouped limit orders, ordered from best offered price to the worst.

Settings

The settings page helps the user to manage the activities of the accounts like language selection, lock account, notification settings, key management, and membership.

There are three sections in the settings page,

  1. General

  2. Key Management

  3. Membership

1. General

The general section consists of option to select language, enable notification and set lock wallet time.

  • Select language option has a drop-down menu to choose language among English and Russia.

  • Show notification option has Yes/No selection to enable/disable notification based on user's choice. By selecting Yes, the check boxes to enable notification for each activities will be visible. By selecting No, the check boxes will be grayed out.

  • Lock wallet option has the drop-down list with time in minutes. This helps the user to choose a desired time to lock the account.

  • The URL to copy the faucet link will be provide at the bottom of the page.

2. Key Management

This tab helps the user to generate keys for owner, active and memo account. The public account key will be listed at the bottom of the page.

a. The user has to enter the Master password in the tab provided.

b. Select the keys that has to be generated by clicking the required name such as Owner, Active and Memo

c. Click the button Let's go to generate the keys.

3. Membership

This tab provide the details about the existing information about the account. The details include Fee allocation, Fee statistics, Pending Fees, Vesting Fees.

This page allow the user to Buy Lifetime Subscription in a single click.

Market Place

Operations

Create Offer

For example

Bid

For example

Cancel Offer

For example

Calls for info

Additional Info

For examples, refer to tests/test_market_place.py

Bitcoin Transaction

An example to get the bitcoin address

Depending on the wallet that you’re using, you may have to use a tool like to find your Public Key if it’s not already displayed in your wallet.

Wasabi Wallet, for example, displays your Public key.

But wallets like and Exodus require you to use external tools like to find your Public Key.

In this example, we’ll be using Wasabi Wallet as the Deposit address and Exodus as the withdrawal address.

As you can see in the image below, the Deposit Address (Wasabi Wallet) is bc1qhlu97p4ehnvt2274na5xqra5n8a8cnumavatn3

The Deposit Public Key is 02d5a014ec94974a01b5b81550bbcf6a629715140d38e7da5f1c2c71ccdcd8b61c

The Withdraw Address (Exodus Wallet) is bc1qrk768lztvrjduama2ruuut9eweamtz5ru4vmhl

But we must find the Withdraw Private Key.. Here’s how:

Open your wallet. As seen in the image above, click on the three dotted lines and click “View Private Keys.” Then Click ”Yes, I’m sure.”

Next, type your account password.

And now you’ll see your Bitcoin deposit Address as well as your Private Key. Copy the address that starts with bc1 and it’s Private key.

The Withdraw Private Key is L5896NkkABQ9PCcWHQiM1tAyFWoPtaEf1uLRQ5eG7nTvzXeXY29g

We will now use the Private Key to find out our Public Key. Simply head over to . Then, click “Wallet Details”.

Paste your Private Key and click “View Details.”

You will find your Public Key over here. Make sure you copy and paste the compressed, 66 characters [0-9A-F] and NOT the 130 Characters key.

We now have the Deposit Public Key, the Withdraw Public Key, and the Withdraw Address.

Deposit Public Key (Wasabi Wallet – already displayed): 02d5a014ec94974a01b5b81550bbcf6a629715140d38e7da5f1c2c71ccdcd8b61c

Withdraw Public Key (Exodus Wallet – found through bitaddress.org): 038F14B6B61EF0AE7EF8317E757807CA8322257C96D54635979C1FBBB899621AF2

Withdraw Address (Exodus Wallet): bc1qrk768lztvrjduama2ruuut9eweamtz5ru4vmhl

Account Creation
Dashboard
Market Activity
Peerplays Blocks
Settings
Wallet
Profile
GPOS - Voting
Logout
Account Calls
Asset Calls
Blockchain Inspection
General Calls
Governance
Privacy Mode
Trading Calls
vector<limit_order_group> graphene::app::orders_api::get_grouped_limit_orders(
    std::string base_asset, 
    std::string quote_asset, 
    uint16_t group, 
    optional<price> start, 
    uint32_t limit)const
p.create_offer(
    item_ids,                  # list of items
    issuer_id_or_name,
    minimum_price,             # asset type
    maximum_price,             # asset type
    buying_item,               # bool
    offer_expiration_date,     # "2020-09-18T11:05:39"
    memo=None,                 # optional
    )
p.create_offer(["1.31.5"], "1.2.9", {"amount":5,"asset_id":"1.3.0"}, {"amount":15,"asset_id":"1.3.0"}, False, "2030-09-18T11:05:39", "") 
p.create_bid(
    bidder_account_id_or_name,
    bid_price,                     # asset
    offer_id,                      # offer_id type, 1.29.x
    )
p.create_bid("1.2.10", {"amount":8,"asset_id":"1.3.0"}, offer["id"]) 
p.cancel_offer(
    issuer_account_id_or_name,
    offer_id,                     # offer_id type, 1.29.x
    )
p.cancel_offer("1.2.9", offer["id"]) 
p.rpc.list_offers(lower_id, limit)   # limt is number of entries requested as integer
p.rpc.list_sell_offers(lower_id, limit)
p.rpc.list_buy_offers(lower_id, limit)
p.rpc.list_offer_history(lower_id, limit)
p.rpc.get_offers_by_issuer(lower_id, issuer_account_id, limit)
p.rpc.get_offers_by_item(lower_id, nft_id_type_item, limit)
p.rpc.get_offer_history_by_issuer(lower_id, issuer_account_id, limit)
p.rpc.get_offer_history_by_item(lower_id, item, limit)
p.rpc.get_offer_history_by_bidder(lower_id, bidder_account_id, limit)
Fig-1: Asset details
Fig-2: Sending asset to account
Fig-3: Transaction confirmation
Fig-4: List of asset to receive
Fig-5: Asset selection to receive
Fig-2: Key management settings
Fig-3: Key generation
Fig-4: Membership details
Fig-5: Lifetime membership confirmation
bitaddress.org
Trust Wallet
bitaddress.org
bitaddress.org

RNG API

Get a random number

Function uint64_t database::get_random_bits(uint64_t bound) 

bound: The upper limit for the random number.

A random number within the bound range.

TypeDefs

peerplays/libraries/chain/include/graphene/chain/protocol/types.hpp
typedef fc::ripemd160 secret_hash_type;


peerplays/libraries/fc/include/fc/crypto/hash_ctr_rng.hpp
template<class HashClass, int SeedLength>

class hash_ctr_rng
{...}

Declaration

peerplays/libraries/chain/include/graphene/chain/database.hpp 

fc::hash_ctr_rng<secret_hash_type, 20> _random_number_generator;

Examples

Initialization in constructor

peerplays/libraries/chain/db_management.cpp

_random_number_generator(fc::ripemd160().data())

Updating seed on a new block

peerplays/libraries/chain/db_update.cpp

modify( _dgp, [&]( dynamic_global_property_object& dgp ){
      secret_hash_type::encoder enc;       
      fc::raw::pack( enc, dgp.random );       
      fc::raw::pack( enc, b.previous_secret );        
      dgp.random = enc.result();
      _random_number_generator = fc::hash_ctr_rng<secret_hash_type, 20>(dgp.random.data());

Getting a new random number

peerplays/libraries/chain/db_update.cpp

uint64_t database::get_random_bits( uint64_t bound )
{
   return _random_number_generator(bound);
}

peerplays/libraries/fc/include/fc/crypto/hash_ctr_rng.hpp

      uint64_t operator()( uint64_t bound )
      {
         if( bound <= 1 )
            return 0;
         uint8_t bitcount = boost::multiprecision::detail::find_msb( bound ) + 1;
         // probability of loop exiting is >= 1/2, so probability of
         // running N times is bounded above by (1/2)^N
         while( true )
         {
            uint64_t result = get_bits( bitcount );
            if( result < bound )
               return result;
         }
      }

HRP / RBAC

Operations

Create Custom Permission

p.custom_permission_create(
    permission_name,
    owner_account=None,
    weight_threshold=[],
    account_auths=[],
    key_auths=[],
    address_auths=[],
    )

For example

    p.custom_permission_create(
        testperm1,
        owner_account="1.2.7",
        weight_threshold=1,
        account_auths=[["1.2.8", 1]])

Custom Permission Update

p.custom_permission_update(
    permission_id,
    owner_account=None,
    weight_threshold=[],
    account_auths=[],
    key_auths=[],
    address_auths=[],
    )

For example

            p.custom_permission_update(
                    permission_id,
                    weight_threshold=1,
                    account_auths=[["1.2.9", 2]],
                    owner_account="1.2.7"
            )

Custom Permission Delete

p.custom_permission_delete(
    permission_id,
    owner_account=None,
    )

For example

            p.custom_permission_delete(
                    permission_id,
                    owner_account="1.2.7"
            )

Custom Account Authority Create

p.custom_account_authority_create(
    permission_id,
    operation_type,
    valid_from,
    valid_to,
    owner_account=None,
    )

For example

p.custom_account_authority_create(
                    permission_id,
                    0,
                    "2020-07-27T00:00:00",
                    "2030-07-27T00:00:00",
                    owner_account="1.2.7") 

Custom Account Authority Update

p.custom_account_authority_update(
    auth_id,
    new_valid_from,
    new_valid_to,
    owner_account=None,
    )

For example

p.custom_account_authority_update(
            authority_id,
            "2020-07-27T00:00:00",
            "2040-07-27T00:00:00",
            owner_account="1.2.7")

Custom Account Authority Delete

p.custom_account_authority_delete(
    auth_id,
    owner_account=None,
    )

For example

    p.custom_account_authority_delete(
            authority_id,
            owner_account="1.2.7")

RPC Info calls

get_custom_permissions(account)
get_custom_permission_by_name(account, permission_name)
get_custom_account_authorities(account)
get_custom_account_authorities_by_permission_id(permission_id)
get_custom_account_authorities_by_permission_name(account, permission_name)
get_active_custom_account_authorities_by_operation(account, int operation_type)

Swapping

vs.

Order Books

The price is set by an algorithm based on the difference in supply between the two assets being exchanged.

How is the price set?

Traders using the exchange set prices at which they're willing to trade.

Whenever you make a swap, you're making an exchange with an automated market-maker on the network. "Orders" don't exist, just pools of assets.

Who is involved in the exchange?

When you place an order, your order may match another trader's order or perhaps several orders. These orders then fill for the buyer on one side of the trade and the seller on the other.

Swaps can happen between any two assets which have an existing LP. (PPY, pBTC, pHIVE)

What assets are available to exchange?

Markets exist for any network-asset in Peerplays. (PPY, pBTC, pHIVE)

Only the market price exists so swaps occur instantly.

What kind of exchanges can be made?

Market, Limit, Stop-limit, etc.

Instantly

How quickly do exchanges happen?

This depends on the type of order. Market orders are almost instant. Limit orders can be set to last until filled.

Peerplays asset swapping is decentralized.

Are these exchanges decentralized?

Peerplays order book trading is decentralized.

found here
54KB
lps-basic-diagram.pdf
pdf
Liquidity Pools Diagram (PDF)
7KB
lps-basic-diagram.xml
Liquidity Pools Diagram (Draw.io XML)

Peerplays Blocks

The Peerplays blockchain section helps the user to understand the transactions happening in the blocks. This page has the details of blockchain, assets, witnesses, committees, sons, and fees associated with that account.

To navigate to this page, click on the Blocks from the list of options available in the Menu on the right pane.

Fig-1: Block option in Menu

Blocks Page - Overview

The block page consists of details about the blocks associated with the account. The tabs under this page are Blockchain, Assets, Witnesses, Committees, Sons, and Fees.

Fig-2: Blockpage Overview

1. Blockchain

This tab contains information about the block based on the recent activity. The information consists of current block, last irreversible block, confirmation time, supply.

The most recent block activity will be featured on the top of page and it will be updated based on each block activity.

Fig-3: List of blocks

Click on a specfic Block ID to learn about the block in detail.

Fig-4: Block in detail

2. Asset

The number of assets associated with the account will be listed in numbers. The search bar provides an option to search assets along with the option to download the details in PDF/CSV file format for future reference.

The filter options available to sort the assets are ID, Max supply, and Precision in ascending/descending order. Also, the assets can be sorted based on certain categories using symbol, name, and issuer options.

Fig-5: Asset selection

3. Witnesses

The witnesses associated with the account will be listed in blocks. The number of active and current witnesses along with earnings will be listed.

The search bar helps in finding the witness at ease. There is an option to download the list in PDF/CSV format for future reference.

The filter function helps to sort the data based on rank, total votes, last block, and missed block counts.

Click on the name to learn about the witness activity in detail.

Fig-6: List of Witness
Fig-7: Asset in detail

4. Committees

The number of active committees for the account will be displayed in blocks. The search bar helps in finding the member at ease. There is an option to download the list in PDF/CSV format for future reference.

The filters will be based on rank, and total votes and can be sorted in ascending/descending order. Click on the name to learn the activity of each committee in detail.

Fig-8: List t of active Committee

The activities of any specific committee member can be monitored/viewed by clicking on the committee name.

Fig-9: Committee activity

5. SONs

The number of active Sons will be displayed in blocks along with the budget and next vote update time.

The search bar helps in finding the account at ease. There is an option to download the list in PDF/CSV format for future reference.

Based on Rank and total votes the list can be filtered. Click on the particular name to learn their activity in detail.

Fig-10: SONs detail

6. Fees

The standard fees associated with each transaction will be listed along with their operation type like transfer, update, withdraw, etc.,

Fig-11: Fees details

7. Accounts

This tab provides the list of accounts associated with the chain. Clicking on the account id/account name will direct to detailed activities of that particular account.

Fig-12 List of accounts

Fig-13: Activities of the account

Market Activity

The market activity page helps in analysing the statistics of any trading pair. The statistics include the value of current price, change (in percentage), volume for any trading pair.

The trading pair will be between the following assets,

  • BTC

  • HBD

  • HIVE

  • PPY

The market page navigation can be done in two ways,

  1. From the Dashboard

Click on the Market Tab in the Dashboard page and select any Trading pair to navigate to the Market page.

Fig-1: Dashboard selection

2. From the Menu option

On the home page, click on the three dots present in the right pane. All the options available will be listed and select Market from the available options to navigate to the Market tab.

Fig-2: Menu option-Market page

1. Market page Overview

The market page consists of the following sections,

  • Trading pair selection

  • Buy and Sell asset

  • My Open orders

  • My Open History

Fig-3: Market page

1. Trading pair selection

To select any trading pair, click on the drop-down button available on the left pane of the market page. The drop-down option opens a tab to select the desired asset for trading.

Fig-4: Trading pair selection

The select pair tab will allow the user to choose any assets like BTC, HBD, HIVE, and PPY. The pairing can be done among these assets.

In the recent pair option, the existing selection will be displayed. The user can choose the trading pair from this button too.

Finally, click on confirm to choose the trading pair or choose to cancel to go back to the market page.

Fig-5: Select pair

For any trading pair, the details about the pair will be listed like current price, change and volume. There are two options to analyse the selected trading pair namely,

  • Order Book

  • Trade history and My History

Order Book

This option provides details about the total, sell, and buy orders based on user selection from the options available.

It also has a drop-down list to choose the threshold value.

Fig-6: Asset summary

History

The history option helps the user to analyse the previous activities under the selected trading pair. It shows the details about the buy and selling details of asset with price and time.

Red color represents the sell orders while green color is for buy orders.

Fig-7: Trade history

2. Buy and Sell Asset

This section on the Market page helps to Buy/sell the asset of the selected Trading pair. The assets will change according to the pair selection. In this example, the selected trading pair is BTC/PPY.

Input the value for the Price and quantity of an asset to calculate the Total value. Based on the input, the fees, market fees, and balance will be updated. Click on the Buy/Sell button to place the order.

Fig-8: Buy Asset

The user has to click on the "sell" tab to sell the asset pair. The below diagram explains the options available to select when selling the asset.

Fig-9: Sell asset

3. My Open Orders

The open orders tab displays the current order details for the selected trading pair. The details include price, asset value (in this case, BTC and PPY), expiration, and action.

Fig-10: My open order

4. My Order History

In this section, the order history of the selected trading pair will be displayed. The values such as asset (In this example BTC and PPY), price and date of purchase are listed.

Fig-11: My open history

5. Asset

The asset option on the market page has two options "Deposit" and "Withdraw" which on the click navigates to the wallet page for receiving and sending assets respectively.

Fig-12: Assets tab to navigate to wallet page

Dashboard

The first screen on the NEX page

There are 4 tabs in the dashboard section,

  1. Deposit

  2. Withdraw

  3. Swap

  4. Market

1. Deposit

This section helps the user to deposit assets into the account. The current version supports three assets BTC, HIVE, and ETH.

BTC Deposit

To deposit Bitcoin, select BTC from the drop-down list and click on Generate Bitcoin address. This prompts you to enter the password to confirm the validation.

Please follow the steps in the below link for any Bitcoin transaction,

HIVE Deposit

To deposit HIVE/HBD, select HIVE from the drop-down menu. It instructs to send funds to son-account on hive blockchain with memo as account name.

Ethereum Deposit

To deposit Ethereum, first, the user should add the Ethereum deposit address,

2. Withdraw

To withdraw the desired asset choose withdraw tab in the dashboard. There are two assets supported in this version BTC and HIVE.

BTC Withdraw

  1. Select BTC from the list of options in the drop-down list.

  2. Enter the required amount of BTC to be withdrawn.

  3. Enter the Compressed withdraw public key & address from the keys text file.

  4. The Estimated fee, total transaction, and time will be calculated based on the withdrawal amount.

  5. Click on the Withdraw button to initiate the transaction.

HIVE Withdraw

  1. Select HIVE from the list of options available in the drop-down list

  2. Enter the amount to be withdrawn from the account

  3. Enter the HIVE account withdrawal address in the text box

  4. The Fees, total transaction, and time will be calculated based on the withdrawal amount.

  5. Click on Withdraw to initiate the transaction.

Ethereum Withdraw

  1. Select ETH from the list of options available in the drop-down list.

  2. Enter the amount to be withdrawn from the account.

  3. Enter the ETH account address withdrawal address in the text box.

  4. The Fees, total transaction, and time will be calculated based on the withdrawal amount.

  5. Click on Withdraw to initiate the transaction.

3. Swap

The swap functionality is a quick way to exchange the asset. The assets that can be exchanged with each other are Bitcoin(BTC), Hive (HBD), and Peerplays (PPY).

  1. Select the asset from which the amount has to be swapped and enter the amount to be transferred.

  2. Select the asset to which the amount has to be received. The amount will be calculated based on the transfer amount.

  3. The fees and type of transaction will be displayed.

4. Click on the Swap Coins button to initiate the swap which prompts you to enter the password for validation.

5. The swap order will be displayed. Click on Confirm button to complete the swap.

6. After successful swapping, the success message will be displayed.

7. Click Done to reflect the changes in the dashboard.

4. Market

The Market tab is the shortcut way to choose the Trading pair for any transaction. The trading pairs will be listed in blocks, hover over the blocks to click any option.

On clicking the desired block, it will direct to the Market tab to display all the activities of the Trading pair in detail.

The Market page can also be chosen from the list of options available from the menu.

What is a Peerplays Witness?

For installation instructions, refer

So What is a Peerplays Witness?

The short answer is, Witnesses run the Peerplays blockchain. The long answer is … well read on.

Chances are, even if you know very little about blockchain technology, you’ll have heard of Bitcoin and Bitcoin mining. And that’s important because as we talk about Witnesses we’ll draw a big distinction between the technology behind Bitcoin and that of the Peerplays blockchain.

The Bitcoin Way

Bitcoin based blockchains use a consensus mechanism called Proof of Work (POW).

At its simplest this means that if you want to create new blocks in the Bitcoin blockchain, colloquially become a ‘miner’, then you need to ‘work’. The harder you work the greater your chance of being paid.

The work involves solving a computational challenging puzzle. We don’t need to know what this puzzle is, but suffice to say the processing power required to profitable solve it is huge. You don’t need anybody’s permission to become a miner, and it’s quite possible to start mining on a home computer.

But realistically, the greater the computing power at your disposal the greater your chance of successfully solving the puzzle, and get paid for creating a new block. This system is anything but fair, one computer could be up against mining pools running literally thousands of computers. It’s easy to imagine the cost of such hardware, not to mention consuming enough power to run a small town!

The Peerplays Way

So enter a consensus mechanism called Delegated Proof of Stake (DPOS).

Think of Delegated Proof of Stake as technological democracy; the opportunity for any PPY token holder to vote on who creates new blocks in the Peerplays blockchain; we call these block producers Witnesses, and they keep the blockchain alive.

Witnesses also have the authority to approve, or reject, any changes to the blockchain software. Their actions have an overarching impact on all PPY token holders.

Unlike Bitcoin miners, Peerplays Witnesses have to be voted in, and once elected they need to continue to accumulate positive votes as token holders don’t just have the power to vote Witnesses in, they have the power to vote them out; remove bad actors.

To earn the right to be a Witness every prospect must accumulate votes by demonstrating why they would be a good Witness. It’s not enough for a prospective Witness to say they have a high spec computer in their basement and are tech savvy. A Witness should demonstrate qualities such as being active in the Peerplays community, blockchain competency, and past experience.

Peerplays has a unique enhancement to Delegated Proof of Stake called Gamified Proof of Stake (GPOS). In the context of Witness voting this is important as it incentivizes PPY token holders to vote. More information about GPOS can be found here:

Vote strength is determined by how many PPY tokens somebody holds. This means that people who have more tokens will influence the network more than people who have very few tokens. Vote power is determined by ‘stake’.

As the community grows, it gets harder and harder to remain a paid Witness due to increased competition.

Voting for Witnesses

With the introduction of GPOS it’s now more important than ever that PPY token holder’s vote. Without voting regularly any token holder’s rewards could be effected. Votes don’t have to be cast for Witnesses, they could be for advisors or proxies, but Witness voting is the most common; Witnesses generally have a higher profile and are more active in the community.

If we had to give only one reason for voting for Witnesses, then that’s simple … without them there would not be a working Peerplays blockchain. As mentioned earlier, the Witnesses are constantly signing blocks and ensuring transactions happen.

Choosing the right Witness to vote for doesn’t need to be difficult. Witnesses maintain their own blogs, contribute to public messaging channels and through the Peerplays Wallet it’s easy to see who are the most reliable block producers.

Witnesses and BookiePro

BookiePro is a decentralized sports betting exchange, the first of its kind in the world and has been built for the Peerplays blockchain.

For the Peerplays witnesses this represents a unique opportunity to play a very important role in ensuring that BookiePro is provably fair. Operations in the blockchain have to be approved and this approval requires consensus from 50% + 1 of the Witnesses.

What this means for BookiePro is that everything from the creation of a game to the final result, and settling the bet, has to be approved by more than one Witness.

For the BookiePro users this means a truly fair and decentralized application; no house and no single authority.

Bitcoin Miners v Peerplays Witnesses

Let’s put the Peerplays Witnesses head-to-head against the Bitcoin miners.

Would you like to be a Witness?

Your curiosity got you this far, but have you thought about taking the next step and becoming a Witness yourself?

Well if you have, there’s lots more resources available to you; we recommend starting here:

GPOS - Voting

1. GPOS

The GPOS page allows the user to perform operations like power up, power down, and voting. The Gamified Proof of Stake (GPOS) is for blockchain governance by voting for the various nodes in the network. Users need a simple and intuitive way to compare the candidates they can vote on. The page consists of 5 different tabs,

A. Power Up

Click on the Power Up button in the GPOS tab. This mainly allows the user to participate in voting. The notice to explain the user participation is listed on this page.

How to Vest?

  • The opening and available balance is shown in the text boxes.

  • Click on '+' to increase the deposit value

  • The new balance will be updated based on the deposit.

  • Click on Vest to begin the transaction and it prompts to enter the password for validation.

  • Next, Click on confirm to complete the transaction.

  • Click on Done, after successful transaction. The amount will be vested into the desired account.

B. Power Down

When the user has a need to withdraw the asset from power up, then Power down will be the option.

Click on Power down option from the GPOS tab, that switch to power down tab in the next page

The notice about the withdraw of balance and it's impact will be listed.

Next, the opening balance, available balance will be listed in text boxes.

The user has to increase the withdraw value to withdraw any desired amount.

The new balance will be updated based on withdraw value.

Click on withdraw button to initiate the transaction. It prompts to enter the password to validate the account.

Next, Click on confirm to complete the transaction.

C. Vote

Clicking on Vote will direct to the main page of GPOS. The tabs such as Witnesses, Sons, and committees has the list of name which has the option to Vote.

The Action section in the last column helps the user to vote desired account.

User has to click on the Thumps up icon symbol under the Action column of the desired account.

The icon will be grayed out to denote that voting has been done.

At the bottom of the page, Confirm button will be enabled and click on the button.

It prompts to enter the password to validate the account.

Next, click on confirm to complete the voting process.

2. Witnesses

3. Sons

The sidechains available for the account will be listed by clicking on the '+' symbol. The list of sidechains are Bitcoin, Ethereum, and Hive.

4. Committees

5. Proxy

The proxy option helps to add other account with the existing account to perform the function of that account in this existing one.

Enter a valid account name in the search box which enable Add button.

Click on ADD to add the account.

Click on Publish Changes button to apply the changes and to add the account.

Crypto API

The crypto API is available from the full node via websockets.

Blinding and Un-Blinding

blind

Get signed blocks.

Generates a Pedersen Commitment: *commit = blind * G + value * G2. The commitment is 33 bytes, the blinding factor is 32 bytes.

Tip: For more information about Pedersen Commitment see:

  • blind: Sha-256 blind factor type

  • value: Positive 64-bit integer value

A 33-byte Pedersen Commitment: commit = blind G + value * G2

blind_sum

Get SHA-256 blind factor type.

  • blinds_in: List of SHA-256 blind factor types

  • non_neg: 32-bit integer value

A blind factor type.

Range Proofs

range_get_info

Gets “range proof” information.

The cli_wallet includes functionality for sending blind transfers in which the values of the input and output amounts are “blinded.”

Note: In the case where a transaction produces two or more outputs, (e.g. an amount to the intended recipient plus “charge” back to the sender), a “range proof” must be supplied to prove that none of the outputs commit to a negative value.

proof: List of proof’s characters

A range proof info structure with exponent, mantissa, min and max values.

range_proof_sign

Proves with respect to min_value the range for Pedersen Commitment which has the provided blinding factor and value.

  • min_value: Positive 64-bit integer value

  • commit: 33-byte pedersen commitment

  • commit_blind: Sha-256 blind factor type for the correct digits

  • nonce: Sha-256 blind factor type for our non-forged signatures

  • base10_exp: Exponents base 10 in range [-1 ; 18] inclusively

  • min_bits: 8-bit positive integer, must be in range [0 ; 64] inclusively

  • actual_value: 64-bit positive integer, must be greater or equal min_value

A list of characters as proof in proof.

Verification

verify_sum

Verifies that commits + neg_commits + excess == 0.

  • commits_in: List of 33-byte Pedersen Commitments

  • neg_commits_in: List of 33-byte Pedersen Commitments

  • excess: Sum of two list of 33-byte Pedersen Commitments where sums the first set and subtracts the second

(Boolean) True in event of commits + neg_commits + excess == 0, otherwise false

verify_range

Verifies range proof for 33-byte Pedersen Commitment.

  • commit: 33-byte pedersen commitment

  • proof: List of characters

A structure with success, min and max values

verify_range_proof_rewind

Verifies range proof rewind for 33-byte Pedersen Commitment.

  • nonce: Sha-256 blind refactor type

  • commit: 33-byte pedersen commitment

  • proof: List of characters

A structure with success, min, max, value_out, blind_out and message_out values.

NFT

Non Fungible Tokens

Operations

Create NFT Meta

For example

Update NFT Meta

For example

Mint NFT

For example

Transfer NFT

For example

Approve Control over NFT

For example

Approve for all the tokens owned

For example

Info calls

p.rpc.nft_get_balance(owner)

p.rpc.nft_owner_of(token_id)

p.rpc.nft_get_approved(token_id)

p.rpc.nft_is_approved_for_all(owner, operator)

p.rpc.nft_get_name(nft_metadata_id)

p.rpc.nft_get_symbol(nft_metadata_id)

p.rpc.nft_get_token_uri(token_id)

p.rpc.nft_get_total_supply(nft_metadata_id)

p.rpc.nft_token_by_index(nft_metadata_id, token_idx)

p.rpc.nft_token_of_owner_by_index(nft_metadata_id, owner, token_idx)

p.rpc.nft_get_all_tokens()

p.rpc.nft_get_tokens_by_owner(owner)

Additional Info

For examples, refer to tests/test_nft.py

p.nft_metadata_create(
    owner_account_id_or_name,        # owner of nft meta
    name,                            # nft meta name
    symbol,                          # nft symbol
    base_uri,                        # nft uri
    is_transferable=True,
    is_sellable=True,
    )
p.nft_metadata_create("1.2.7", self.nameMetadata, self.nameMetadata, self.nameMetadata, revenue_partner="1.2.8", revenue_split=300, is_sellable=False, is_transferable=False)
p.nft_metadata_update(
    owner_account_id_or_name,
    nft_metadata_id,
    name,
    symbol,
    base_uri,
    is_transferable=True,
    is_sellable=True,
    )
p.nft_metadata_update("1.2.7", "1.30.11", self.nameMetadata + "m", self.nameMetadata + "m", self.nameMetadata + "m", "1.2.9", 400, True, True)
p.nft_mint(
    metadata_owner_account_id_or_name,
    metadata_id, 
    owner_account_id_or_name,
    approved_account_id_or_name,
    approved_operators,                     # list of operators
    token_uri,
    )
p.nft_mint("1.2.7", "1.30.11", "1.2.7", "1.2.7", "1.2.7", self.nameNft)
p.nft_safe_transfer_from(
    operator_,                # operator account name or id
    from_,
    to_,
    token_id,
    data,                     # notes as string
    )
p.nft_safe_transfer_from("1.2.7", "1.2.7", "1.2.9", "1.31.5", "whatever")
def nft_approve(
    operator_,
    approved,         # approved account id or name
    token_id,
    )
p.nft_approve("1.2.9", "1.2.8", "1.31.5")
def nft_set_approval_for_all(
    owner,
    operator_,
    approved,
    )
p.nft_set_approval_for_all("1.2.7", "1.2.10", True)
commitment_type graphene::app::crypto_api::blind(
    const fc::ecc::blind_factor_type &blind, 
    uint64_t value)
blind_factor_type graphene::app::crypto_api::blind_sum(
    const std::vector<blind_factor_type> &blinds_in, 
    uint32_t non_neg)
range_proof_info graphene::app::crypto_api::range_get_info(
    const std::vector<char> &proof)
std::vector<char> graphene::app::crypto_api::range_proof_sign(
    uint64_t min_value, 
    const commitment_type &commit, 
    const blind_factor_type &commit_blind, 
    const blind_factor_type &nonce, 
    int8_t base10_exp, 
    uint8_t min_bits, 
    uint64_t actual_value
bool graphene::app::crypto_api::verify_sum(
    const std::vector<commitment_type> &commits_in, 
    const std::vector<commitment_type> &neg_commits_in, 
    int64_t excess)
verify_range_result graphene::app::crypto_api::verify_range(
    const fc::ecc::commitment_type &commit, 
    const std::vector<char> &proof)
verify_range_proof_rewind_result graphene::app::crypto_api::verify_range_proof_rewind(
    const blind_factor_type &nonce, 
    const fc::ecc::commitment_type &commit, 
    const std::vector<char> &proof)
Commitment Scheme
Fig-1: GPOS Page
Fig-2: Power up page
Fig-3: Active Key
Fig-4: Transaction confirmation
Fig-5: Successful Confirmation
Fig-6: Power down
Fig-7: Voting
Fig-8: Voting Confirmation
Fig-9: Witnesses list
Fig-10: Sons account list
Fig-11: List of sidechains
Fig-12: List of committee members
Fig-13: Proxy account addition
Fig-14: Confirmation
Fig-15: Proxy publishing Successful

Account History API

The history API is available from the full node via websockets.

Account History

get_account_history

Get operations relevant to the specified account.

vector<operation_history_object> graphene::app::history_api::get_account_history(
    const std::string account_id_or_name, 
    operation_history_id_type stop = operation_history_id_type(), 
    unsigned limit = 100, 
    operation_history_id_type start = operation_history_id_type())const
  • account_id_or_name: The account ID or name whose history should be queried

  • stop: ID of the earliest operation to retrieve

  • limit: Maximum number of operations to retrieve (must not exceed 100)

  • start: ID of the most recent operation to retrieve

A list of operations performed by account, ordered from most recent to oldest.

get_account_history_operations

Get only asked operations relevant to the specified account.

vector<operation_history_object> graphene::app::history_api::get_account_history_operations(
    const std::string account_id_or_name, 
    int operation_type, 
    operation_history_id_type start = operation_history_id_type(), 
    operation_history_id_type stop = operation_history_id_type(), 
    unsigned limit = 100)const
  • account_id_or_name: The account ID or name whose history should be queried

  • operation_type: The type of the operation we want to get operations in the account ( 0 = transfer , 1 = limit order create, …)

  • stop: ID of the earliest operation to retrieve

  • limit: Maximum number of operations to retrieve (must not exceed 100)

  • start: ID of the most recent operation to retrieve

A list of operations performed by account, ordered from most recent to oldest.

get_relative_account_history

Get operations relevant to the specified account referenced by an event numbering specific to the account. The current number of operations for the account can be found in the account statistics (or use 0 for start).

vector<operation_history_object> graphene::app::history_api::get_relative_account_history(
    const std::string account_id_or_name, 
    uint64_t stop = 0, 
    unsigned limit = 100, 
    uint64_t start = 0)const
  • account_id_or_name: The account ID or name whose history should be queried

  • stop: Sequence number of earliest operation. 0 is default and will query ‘limit’ number of operations.

  • limit: Maximum number of operations to retrieve (must not exceed 100)

  • start: Sequence number of the most recent operation to retrieve. 0 is default, which will start querying from the most recent operation.

A list of operations performed by account, ordered from most recent to oldest.

Market History

get_fill_order_history

Get details of order executions occurred most recently in a trading pair.

vector<order_history_object> graphene::app::history_api::get_fill_order_history(
    std::string a, 
    std::string b, 
    uint32_t limit)const
  • a: Asset symbol or ID in a trading pair

  • b: The other asset symbol or ID in the trading pair

  • limit: Maximum records to return

a list of order_history objects, in most recent first order

get_market_history

Get OHLCV data of a trading pair in a time range.

vector<bucket_object> graphene::app::history_api::get_market_history(
    std::string a, 
    std::string b, 
    uint32_t bucket_seconds, 
    fc::time_point_sec start, 
    fc::time_point_sec end)const
  • a: Asset symbol or ID in a trading pair

  • b: The other asset symbol or ID in the trading pair

  • bucket_seconds: Length of each time bucket in seconds.

Note: It needs to be within result of get_market_history_buckets(), otherwise no data will be returned

  • start: The start of a time range, E.G. “2018-01-01T00:00:00”

  • end: The end of the time range

A list of OHLCV data, in least recent first order.

If there are more than 200 records in the specified time range, the first 200 records will be returned.

get_market_history_buckets

Get OHLCV time bucket lengths supported (configured) by this API server.

flat_set<uint32_t> graphene::app::history_api::get_market_history_buckets()const

A list of time bucket lengths in seconds.

For example, if the result contains a number “300” it means this API server supports OHLCV data aggregated in 5-minute buckets.

Bitcoin Miners

Peerplays Witnesses

No selection process, anybody can be a miner.

Every Witness has to be voted in by the PPY token holders.

Successful miner’s require a huge amount of computer processing power.

Witnesses require computer processing power that is readily available and affordable.

The block producing process is heavily biased towards mining pools.

Every Witness has the same opportunity to create blocks.

Block producing isn’t truly decentralized as over time the mining pools will control almost all the block production.

Truly decentralized because of the equal weight given to each witness for block production.

Miner’s create one new block approximately every 10 minutes.

Witnesses create one new block approximately every three seconds.

Miners are very well paid for each block they produce. But the probability of producing a block makes it cost prohibitive for many of them.

Witnesses receive much lower payment for each block, but all witnesses can create blocks equally, have a guaranteed income and the potential to create 1200 blocks or more an hour between them.

https://infra.peerplays.tech/witnesses/installation-guides
Gamified Proof of Stake (GPOS)
Becoming a Peerplays Witness
Fig-1 Deposit option
Fig-2: Bitcoin Deposit
Fig-3: Hive Deposit
Fig-4: Add Ethereum address
Fig-5: BTC withdraw
Fig-6: Hive Withdraw
Fig-7: ETH Withdraw
Fig-8: Asset options
Fig-9: Coin swap
Fig-10: Swap order transaction
Fig-11: Transaction confirmation
Fig-12: Market page
Fig-13: Market-page Trading pair
Fig-14: Menu selection-Market page

Becoming a Peerplays Witness

Note: You can find the installation instructions here https://infra.peerplays.tech/witnesses/installation-guides

Congratulations! You’ve taken the first step towards becoming a Peerplays Witness.

Can Anyone be a Peerplays Witness?

Yes, anybody can become a Peerplays Witness and it can be rewarding professionally, personally and financially.

In this document we'll go through the first steps to becoming a Witness: your duties, node and server requirements, getting voted in and becoming a Bookie oracle.

The Duties of a Peerplays Witness

The primary duty of Peerplays Witnesses is to bundle transactions into blocks and sign them with their signing key. Witnesses keep the blockchain alive by producing one block every three seconds. For example, if there are 20 Witnesses, each would produce one block every minute.

Other duties include:

  • Operate a full node with enough bandwidth to support current network activities.

  • Operate a test version of the blockchain that functions as a public testing environment.

  • Optionally operate an API seed node to support end user applications.

  • Integrate, or reject, any changes to the blockchain software that are published.

  • Keep a block producing node running 24/7 every day of the year!

And one unique duty of a Peerplays Witness :

BookiePro & Bookie Oracle System (BOS)

BookiePro is the world’s first decentralized sports betting exchange application.

For the application to function Peerplays Witnesses must also act as decentralized oracles, which means that the Witnesses are required to populate the Peerplays blockchain with real-world sporting data. For example, league and competition data, event data, betting market data for different sports, along with the final scores of each game. It requires consensus from a majority of Witnesses for any of this event data to be approved.

This process is automated, but sometimes incident data from different sources doesn’t match and if no consensus can be made then it’s the duty of the Witnesses to manually intervene and make proposals to fix the data. Witnesses do this using the Manual Intervention Tool (MINT).

Smart contracts then use this data to grade and settle bets placed by users on BookiePro.

For more information on the Bookie Oracle System, and how to install it, go to:

Being a Peerplays Witness is a Paid Job

Blocks are produced every three seconds by Witnesses who take turns signing and validating the blockchain in variable rounds.

As a Peerplays Witnesses you are paid for this duty by the blockchain itself which releases new PPY tokens from the reserve pool, then issues them to the signing Witness after each block is validated.

With 20 blocks being signed every minute this means 28,800 blocks a day, split evenly between the number of active Witnesses.

As Peerplays Witness pay is dependant on the value of the PPY it can vary a lot. Not only is being a Peerplays Witness rewarding, but as the commitment and reliability of Witnesses has a direct impact on the value of the PPY, as a Peerplays Witness you'll play a role in setting your own 'salary'.

How to Get Votes

As only active (block producing) Witnesses get paid it's very important to be voted in; to do this you must sell yourself to the PPY token holders. Every PPY token holder can vote for a Witness, multiple times if they want to, and only as a result of the number of votes cast will a Witness be promoted to an active, block producing, Witness. The votes are weighted according to the token holdings of each PPY token holder at the time of voting.

The Peerplays core wallet makes it easy for PPY token holders to vote for Witnesses. Anyone who holds PPY can do this by adding the name of the Witness to the voting tab. The wallet then sends the information about their votes directly to the Peerplays blockchain.

To sell yourself to the Witness voting community you'll need a web site and blog with information about how you intend to perform your duties as a Witness, and other ways in which you'll bring value to Peerplays. The best way to do this is by creating your own web page, publish the URL in as many places as possible, and make it simple to find.

A good place to start would be by checking out the web pages for existing witnesses, you can find that information here:

Be very active on social media, especially target Peerplays and Peerplays Witness channels on Telegram and Discord. Qualities that voters are going to be looking for include, experience, knowledge, commitment, responsibility and community participation.

Some useful links:

Peerplays official Rocket Chat and Telegram channels for Witnesses:

Getting started

We've already talked about the personal qualities a Witness needs to have, and the duties they're expected to perform, now we need to talk about nodes and hardware requirements.

Nodes

All nodes keep updating an internal database by applying the transactions as they arrive in incoming blocks. The difference between the node types lies in the amount of history they keep track of, and in the functionality they provide.

A Witness node, as the name implies, is a node run by a Witness. Each Witness node validates all blocks and transactions it receives. The nodes of elected Witnesses take turns in bundling new transactions into blocks and broadcasting them to the network.

API nodes (nodes with an open RPC port) provide network services to client applications. They usually have account transaction histories accessible through API calls, but can vary in the amount of available history.

Full nodes are API nodes with a complete transaction history of all accounts.

Seed nodes are nodes that accept incoming P2P connections. They are the first nodes contacted by a freshly started node; the entry point into the network. Once a node has entered the network it will receive additional node addresses from its peers, so all nodes can connect to each other. A seed node can also be an API node. Seed nodes are not mandatory, but highly recommended.

BOS nodes are required to operate the Bookie Oracle System and ensure the accuracy and decentralization of the data fed into the BookiePro application. The BOS node must be run on a separate server to the Witness node.

Every Witness is required to run nodes on both Public Mainnet and Public Testnet environments.

So the minimum node requirements are a Witness node and BOS node for both Testnet and Mainnet. If you also run a Seed Node and API Node then the number of required servers could be as many as eight.

System Requirements

Unlike mining Bitcoin, or other POW based blockchains, the processing power at your disposal has no influence on how many blocks you'll produce, and consequently how much you'll be paid as a Witness.

However, there are requirements in terms of what hardware and software you should be running.

Important: The following table shows the minimum requirements for each server.

CPU

Memory

Storage

Bandwidth

OS

8 Cores

8GB

300GB SSD

1Gbps

Ubuntu 18.04

These requirements are as of the time of writing, so consider deploying a server with specs slightly higher than the ones listed above in order to "future proof" your server in case the minimum requirements grow in the future.

Once you've procured your servers then it's time to set them up.

You're now ready to take the next step, setting up your own Witness node.

RNG Technical Summary

Introduction

The Peerplays blockchain RNG was initially added to the blockchain to provide draw features for the Easy5050 decentralized application (DApp).

The first release of the RNG was localized to the Easy5050 DApp and wasn't exposing the number generated via an API, or a similar mechanism, such that other DApps or users could consume them.

For the second release of the RNG the functionality was extended to become a general RNG, with a public API, for supporting games such as Slots, Poker, Roulette, Raffle, Bingo, Keno, etc.

How the Random Numbers are Generated

Random numbers are generated from secret hashes taken from the previous and current block, which are then combined into a single data stream and encoded using the ripemd160 algorithm, and finally fed into a random number generator as a seed.

For more information on the ripemd160 algorithm see:

https://en.wikipedia.org/wiki/RIPEMD

Block-Hash Randomness

In this approach, the hash of blocks or transactions is used as the source of randomness. As the hash is deterministic, everyone will get the same result. A block, once added to the blockchain, is likely to stay there forever, therefore everyone can verify the correctness of the generated numbers.

Consider an example of a lottery service that adopts this method. The players first buy a ticket by placing their number before a specific time, say 7PM everyday. After 8PM, the buying ticket phase is closed, the protocol proceeds to the next phase which is to determine the winning numbers for a ticket. This ticket is calculated based on the hash of the first block accessible for everyone on the blockchain after 8PM.

As we can see, at 7PM, no one can predict the hash of block at 8PM which makes the service seemingly a sound one. However, this hash is subject to manipulation by the block-signers of the blockchain. When the reward of the lottery is small, the block-signers have little motivation to tamper with the block, but as soon as this amount is larger than the block reward plus the transaction fees, there is a chance that witnesses will start influencing the block-hash to generate their desired numbers.

So on it's own a block-hash level of randomness is not enough. This is why the Peerplays RNG extends the block-hash mechanism by using the hash as a seed for randomization along with the repemd160 algorithm and Secure Hash Algorithm (SHA).

Distributed Ledger Technology (DLT)

Peerplays, and other blockchains, are one type of a distributed ledger. Distributed ledgers use independent computers (referred to as nodes) to record, share and synchronize transactions in their respective electronic ledgers (instead of keeping data centralized as in a traditional ledger).

The immutability of DLT is critical for the RNG because it ensures that once a random number is generated it is authentic and can't be changed.

Witness Randomness

Peerplays is based on the Delegated Proof of Stake (DPOS) consensus mechanism, which means that the block signers (Witnesses) are all elected by the token holders. This is important from an RNG perspective because it requires loyalty, commitment and honesty to get voted in as a Witness. Since a component of the randomness is based on the block hash, knowing that the block signers are a trusted, elected, group greatly mitigates the risk of block tampering.

Peerplays further extends the block-signing robustness and randomness because:

  1. Not all Witnesses are block-signing (active) Witnesses. There is a second level of consensus that has to happen before a Witness is promoted to an active Witness.

  2. Not all active Witnesses are signing blocks at any given time. The blockchain randomly selects which Witnesses are signing at ten minute intervals.

Because of the role of the Witnesses, Peerplays has two levels of randomness. First the Witnesses themselves are randomly selected, and secondly the randomness of the number generation itself.

Testing

For testing the RNG, the “Dieharder” random number generator testing suite was used.

Dieharder is intended to test generators, not files of possibly random numbers as the latter is based on the mistaken view of what it means to be random. Perfect random number generators produce "unlikely" sequences of random numbers -- at exactly the right average rate. Testing an RNG is therefore quite subtle.

Dieharder is a tool designed to push a weak generator to unambiguous failure.

For more information on Dieharder see:

https://webhome.phy.duke.edu/~rgb/General/dieharder.php

Install prerequisites for running RNG tests

sudo apt install dieharder

To run RNG test suite, use the following command:

$ ./tests/random_test 

Gaming Laboratories International (GLI)

GLI are an internationally recognized institute offering the the most experienced and robust RNG testing methodologies in the world. This includes software-based (pseudo-algorithmic) RNG’s, hardware RNG’s, and hybrid combinations of both.

The Peerplays RNG has been submitted to GLI for approval [TBD: or has 'been approved']

GLI generally performs the testing of applications and games, such as Keno, as opposed to an API. The game testing will automatically include the backend API as well. On successful completion of all tests each application will be certified by GLI.

For each new game, different testing will be required. An example would be the Easy5050 DApp that can be tested and with all subsequent releases, tested again.

However, as the core Peerplays RNG is a blockchain (back-end) implementation and not an application it can only be approved by GLI rather than certified.

API

The RNG has a very simple API for generating random numbers, requiring just a single API call to get_random_bits(bound) ; supplying an upper bound.

get_random_bits(uint64_t bound) 

For more information on the API see:

Labels

Scoped Labels

The scoped labels (ending with ::) are mutually exclusive. Only one of these labels can be assigned at a time to an issue.

Priority::

  • low

  • medium priority

  • high priority

  • critical priority

State::

  • pending

  • accepted

  • in progress

  • in review

  • in testing

  • completed

  • on hold

  • blocked

  • revision needed

Type::

  • bug

  • feature

  • documentation

  • question

  • maintenance

Other Labels

  • duplicate

  • discussion

  • security

Issue Lifecycle

All issues should have a state and type scoped label attached to them. The following is a proposed lifecycle an issue should have:

  1. Pending - Issues that are newly created and haven't been reviewed.

  2. Accepted - Issues that are newly created and have been accepted after review.

  3. In Progress - Issues that are currently being worked on.

  4. In Review - Issues that require a proposed solution to be reviewed.

  5. In Testing - Issues that require a proposed solution to be tested.

  6. Completed - Issues that are closed with a working solution.

This will cover a standard lifecycle of an issue. There are other state labels for issues that are not being worked on:

  • On Hold - Issues that were at least accepted, that should not be worked on at the moment.

  • Blocked - Issues that cannot be worked on due to other factors linked to it.

  • Revision Needed - Issues that need to be revised before being accepted.

Glossary

RNG API

Label

Description

priority::low

(optional) Issues that are marked as low priority.

priority::medium

(optional) Issues that are marked as medium priority.

priority::high

(optional) Issues that are marked as high priority.

priority::critical

(optional) Issues that are marked as critical priority. Should be taken care of ASAP.

state::pending

Issues that are newly created and haven't been reviewed.

state::accepted

Issues that are newly created and have been accepted after review.

state::in progress

Issues that are currently being worked on.

state::in review

Issues that require a proposed solution to be reviewed.

state::in testing

Issues whose proposed solution is being tested.

state::completed

Issues that are closed with a working solution.

state::on hold

Issues that were at least accepted, that should not be worked on at the moment.

state::blocked

Issues that cannot be worked on due to other factors linked to it.

state::revision needed

Issues that need to be revised before being accepted.

type::bug

Issues that are an unexpected, or incorrect result in the project.

type::feature

Issues that bring new functionality to the project.

type::documentation

Issues that relate to the documentation of the project.

type::question

Issues that are questions related to the project.

type::maintenance

Issues that require maintenance on the project.

duplicate

(optional) Issues that are duplicates of existing issues in the same project.

discussion

(optional) Issues that discuss specific project changes.

security

(optional) Issues that relate to the security of the project.

https://gitlab.com/groups/PBSA/-/labels

Privacy Mode

Privacy Mode

set_key_label

These methods are used for stealth transfers This method can be used to set a label for a public key

Note: No two keys can have the same label.

bool graphene::wallet::wallet_api::set_key_label(
    public_key_type key, 
    string label)
  • key: a public key

  • label: a user-defined string as label

True if the label was set, otherwise false

get_key_label

Get label of a public key.

string graphene::wallet::wallet_api::get_key_label(
    public_key_type key)const
  • key: a public key

The label if already set by set_key_label(), or an empty string if not set

get_public_key

Get the public key associated with a given label

public_key_type graphene::wallet::wallet_api::get_public_key(
    string label)const
  • label: a label

The public key associated with the given label.

get_blind_accounts

Get all blind accounts.

map<string, public_key_type> graphene::
wallet
::
wallet_api
::get_blind_accounts()const

All blind accounts

get_my_blind_accounts

Get all blind accounts for which this wallet has the private key.

map<string, public_key_type> graphene::wallet::wallet_api::get_my_blind_accounts()const

All blind accounts for which this wallet has the private key.

get_blind_balances

Return the total balances of all blinded commitments that can be claimed by the given account key or label.

vector<asset> graphene::wallet::wallet_api::get_blind_balances(
    string key_or_label)
  • key_or_label: a public key in Base58 format or a label

The total balances of all blinded commitments that can be claimed by the given account key or label

create_blind_account

Generates a new blind account for the given brain key and assigns it the given label

public_key_type graphene::
wallet
::
wallet_api
::create_blind_account(string label, string brain_key)
  • label: a label

  • brain_key: the brain key to be used to generate a new blind account

The public key of the new account

transfer_to_blind

Transfers a public balance from from_account_id_or_name to one or more blinded balances using a stealth transfer.

blind_confirmationgraphene::wallet::wallet_api::transfer_to_blind(
    string from_account_id_or_name, 
    string asset_symbol, 
    vector<pair<string, string>> to_amounts, 
    bool broadcast = false)
  • from_account_id_or_name: ID or name of an account to transfer from

  • asset_symbol: symbol or ID of the asset to be transferred

  • to_amounts: map from key or label to amount

  • broadcast: true to broadcast the transaction on the network

A blind confirmation

transfer_from_blind

Transfers funds from a set of blinded balances to a public account balance.

blind_confirmationgraphene::wallet::wallet_api::transfer_from_blind(
    string from_blind_account_key_or_label, 
    string to_account_id_or_name, 
    string amount, 
    string asset_symbol, 
    bool broadcast = false)
  • from_blind_account_key_or_label: a public key in Base58 format or a label to transfer from

  • to_account_id_or_name: ID or name of an account to transfer to

  • amount: the amount to be transferred

  • asset_symbol: symbol or ID of the asset to be transferred

  • broadcast: true to broadcast the transaction on the network

A blind confirmation.

blind_transfer

Transfer from one set of blinded balances to another.

blind_confirmationgraphene::wallet::wallet_api::blind_transfer(
    string from_key_or_label, 
    string to_key_or_label, 
    string amount, 
    string symbol, 
    bool broadcast = false)
  • from_key_or_label: a public key in Base58 format or a label to transfer from

  • to_key_or_label: a public key in Base58 format or a label to transfer to

  • amount: the amount to be transferred

  • symbol: symbol or ID of the asset to be transferred

  • broadcast: true to broadcast the transaction on the network

A blind confirmation

blind_history

Get all blind receipts to/form a particular account.

vector<blind_receipt> graphene::wallet::wallet_api::blind_history(
    string key_or_account)
  • key_or_account: a public key in Base58 format or an account

All blind receipts to/form the account.

receive_blind_transfer

Given a confirmation receipt, this method will parse it for a blinded balance and confirm that it exists in the blockchain. If it exists then it will report the amount received and who sent it.

blind_receipt graphene::
wallet
::
wallet_api
::receive_blind_transfer(string confirmation_receipt, string opt_from, string opt_memo)
  • confirmation_receipt: a base58 encoded stealth confirmation

  • opt_from: if not empty and the sender is a unknown public key, then the unknown public key will be given the label opt_from

  • opt_memo: a self-defined label for this transfer to be saved in local wallet file

A blind receipt.

Tournaments

get_tournaments_in_state

Get a list of tournament ids for upcoming tournaments

Apis.instance().db_api().exec('get_tournaments_in_state', [stateString, accountId])
  • stateString: The tournament state

  • accountId:Account Id

All tournaments for the selected state.

ChainStore.prototype.getTournamentIdsInState = function getTournamentIdsInState(accountId, stateString) {
    var _this7 = this;

    var tournamentIdsForThisAccountAndState = void 0;
    var tournamentIdsForThisAccount = this.tournament_ids_by_state.get(accountId);

    if (tournamentIdsForThisAccount === undefined) {
      tournamentIdsForThisAccountAndState = new _immutable2.default.Set();
      tournamentIdsForThisAccount = new _immutable2.default.Map().set(stateString, tournamentIdsForThisAccountAndState);
      this.tournament_ids_by_state = this.tournament_ids_by_state.set(accountId, tournamentIdsForThisAccount);
    } else {
      tournamentIdsForThisAccountAndState = tournamentIdsForThisAccount.get(stateString);

      if (tournamentIdsForThisAccountAndState !== undefined) {
        return tournamentIdsForThisAccountAndState;
      }

      tournamentIdsForThisAccountAndState = new _immutable2.default.Set();
      tournamentIdsForThisAccount = tournamentIdsForThisAccount.set(stateString, tournamentIdsForThisAccountAndState);
      this.tournament_ids_by_state = this.tournament_ids_by_state.set(accountId, tournamentIdsForThisAccount);
    }

    _ws.Apis.instance().db_api().exec('get_tournaments_in_state', [stateString, 100]).then(function (tournaments) {
      var originalTournamentIdsInState = _this7.tournament_ids_by_state.getIn([accountId, stateString]);
      // call updateObject on each tournament, which will classify it
      tournaments.forEach(function (tournament) {
        /**
         * Fix bug: we cant update tournament_ids_by_state if objects_by_id has a tournament
         */
        if (!originalTournamentIdsInState.get(tournament.id)) {
          _this7.clearObjectCache(tournament.id);
        }

        _this7._updateObject(tournament);
      });

      var tournament_id = _this7.tournament_ids_by_state.getIn([accountId, stateString]);

      if (tournament_id !== originalTournamentIdsInState) {
        _this7.notifySubscribers();
      }
    });
    return tournamentIdsForThisAccountAndState;
  };

get_registered_tournaments

Get a list of registered tournaments by account id.

Apis.instance().db_api().exec('get_registered_tournaments', [accountId, 100])
  • accountId: Account Id.

All registered tournaments for an account.

ChainStore.prototype.getRegisteredTournamentIds = function getRegisteredTournamentIds(accountId) {
    var _this8 = this;

    var tournamentIds = this.registered_tournament_ids_by_player.get(accountId);

    if (tournamentIds !== undefined) {
      return tournamentIds;
    }

    tournamentIds = new _immutable2.default.Set();
    this.registered_tournament_ids_by_player = this.registered_tournament_ids_by_player.set(accountId, tournamentIds);

    _ws.Apis.instance().db_api().exec('get_registered_tournaments', [accountId, 100]).then(function (registered_tournaments) {
      var originalTournamentIds = _this8.registered_tournament_ids_by_player.get(accountId);
      var newTournamentIds = new _immutable2.default.Set(registered_tournaments);

      if (!originalTournamentIds.equals(newTournamentIds)) {
        _this8.registered_tournament_ids_by_player = _this8.registered_tournament_ids_by_player.set(accountId, newTournamentIds);
        _this8.notifySubscribers();
      }
    });

    return tournamentIds;
  };

get_tournaments

Get all tournaments between last_tournament_id and start_tournament_id.

 _ws.Apis.instance().db_api().exec('get_tournaments', [last_tournament_id, limit, start_tournament_id])
  • last_tournament_id: The last tournament id

  • limit: The limit of tournaments to return.

  • start_tournament_id: The starting tournament id.

A list of all tournaments between last_tournament_id and start_tournament_id.

ChainStore.prototype.getTournaments = function getTournaments(last_tournament_id) {
    var _this20 = this;

    var limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5;
    var start_tournament_id = arguments[2];

    return _ws.Apis.instance().db_api().exec('get_tournaments', [last_tournament_id, limit, start_tournament_id]).then(function (tournaments) {
      var list = _immutable2.default.List();

      _this20.setLastTournamentId(null);

      if (tournaments && tournaments.length) {
        list = list.withMutations(function (l) {
          tournaments.forEach(function (tournament) {
            if (!_this20.objects_by_id.has(tournament.id)) {
              _this20._updateObject(tournament);
            }

            l.unshift(_this20.objects_by_id.get(tournament.id));
          });
        });
      }

      return list;
    });
  };

Trading Calls

Trading Calls

sell_asset

Place a limit order attempting to sell one asset for another.

Buying and selling are the same operation on Graphene; if you want to buy BTS with USD, you should sell USD for BTS.

The blockchain will attempt to sell the symbol_to_sell for as much symbol_to_receive as possible, as long as the price is at least min_to_receive / amount_to_sell.

In addition to the transaction fees, market fees will apply as specified by the issuer of both the selling asset and the receiving asset as a percentage of the amount exchanged.

If either the selling asset or the receiving asset is whitelist restricted, the order will only be created if the seller is on the whitelist of the restricted asset type.

Market orders are matched in the order they are included in the block chain.

  • seller_account: the account providing the asset being sold, and which will receive the proceeds of the sale.

  • amount_to_sell: the amount of the asset being sold to sell (in nominal units)

  • symbol_to_sell: the name or id of the asset to sell

  • min_to_receive: the minimum amount you are willing to receive in return for selling the entire amount_to_sell

  • symbol_to_receive: the name or id of the asset you wish to receive

  • timeout_sec: if the order does not fill immediately, this is the length of time the order will remain on the order books before it is cancelled and the un-spent funds are returned to the seller’s account

  • fill_or_kill: if true, the order will only be included in the blockchain if it is filled immediately; if false, an open order will be left on the books to fill any amount that cannot be filled immediately.

  • broadcast: true to broadcast the transaction on the network

The signed transaction selling the funds.

borrow_asset

Borrow an asset or update the debt/collateral ratio for the loan.

This is the first step in shorting an asset.

Call to complete the short.

  • borrower_name: the name or id of the account associated with the transaction.

  • amount_to_borrow: the amount of the asset being borrowed. Make this value negative to pay back debt.

  • asset_symbol: the symbol or id of the asset being borrowed.

  • amount_of_collateral: the amount of the backing asset to add to your collateral position. Make this negative to claim back some of your collateral. The backing asset is defined in the bitasset_options for the asset being borrowed.

  • broadcast: true to broadcast the transaction on the network

The signed transaction borrowing the asset

cancel_order

Cancel an existing order.

  • order_id: the id of order to be cancelled

  • broadcast: true to broadcast the transaction on the network

The signed transaction canceling the order

settle_asset

Schedules a market-issued asset for automatic settlement.

Holders of market-issued assets may request a forced settlement for some amount of their asset. This means that the specified sum will be locked by the chain and held for the settlement period, after which time the chain will choose a margin position holder and buy the settled asset using the margin’s collateral.

The price of this sale will be based on the feed price for the market-issued asset being settled. The exact settlement price will be the feed price at the time of settlement with an offset in favour of the margin position, where the offset is a blockchain parameter set in the global_property_object.

  • account_to_settle: the name or id of the account owning the asset

  • amount_to_settle: the amount of the named asset to schedule for settlement

  • symbol: the name or id of the asset to settle

  • broadcast: true to broadcast the transaction on the network

The signed transaction settling the named asset.

get_market_history

Get OHLCV data of a trading pair in a time range.

  • symbol: name or ID of the base asset

  • symbol2: name or ID of the quote asset

  • bucket: length of each time bucket in seconds.

  • start: the start of a time range, E.G. “2018-01-01T00:00:00”

  • end: the end of the time range

A list of OHLCV data, in “least recent first” order.

get_limit_orders

Get limit orders in a given market.

  • a: symbol or ID of asset being sold

  • b: symbol or ID of asset being purchased

  • limit: Maximum number of orders to retrieve

The limit orders, ordered from least price to greatest.

get_call_orders

Get call orders (aka margin positions) for a given asset.

  • a: symbol name or ID of the debt asset

  • limit: Maximum number of orders to retrieve

The call orders, ordered from earliest to be called to latest

get_settle_orders

Get forced settlement orders in a given asset.

  • a: Symbol or ID of asset being settled

  • limit: Maximum number of orders to retrieve

The settle orders, ordered from earliest settlement date to latest

Time Tracking

How to use GitLab quick actions for estimates, time spent and weights on issues.

Quick actions are text-based shortcuts for common actions that are usually done by selecting buttons or dropdowns in the GitLab user interface. You can enter these commands in the descriptions or comments of issues, epics, merge requests, and commits.

Be sure to enter each quick action on a separate line to allow GitLab to properly detect and execute the commands.

Selecting an Issue

  1. Navigate to the project of choice in GitLab.

  2. Click on the issues menu option

3. Select the issue of choice.

Time Tracking

Lead developers who will assign issues should make sure to provide a time estimate and weight to them. They should also ensure these issues are attached to the appropriate milestones and epics.

The purpose of this is to collect metrics and be able to provide a better timeline for project delivery.

Estimates

To estimate an issue in GitLab, quick actions can be utilized. Inside the comment section of an issue type the following command: /estimate <1w 3d 2h 14m>.

Once an estimation is provided, the issue will update to reflect the submitted comment.

Spent Time

To track the time spent on an issue in GitLab, quick actions can be utilized. Inside the comment section of an issue type the following command: /spend <time(1h30m|-1h30m)> <date(YYYY-MM-DD)> to add or subtract spent time.

Once the spent time is provided, the issue will update to reflect the submitted comment.

Weight

When you have a lot of issues, it can be hard to get an overview. By adding weight to each issue, you can get a better idea of how much time, value or complexity a given issue has or costs.

Weight points can be associated for the following task sizes:

  • Extra Small (8h or less) - 1

  • Small (9h - 16h) - 2

  • Medium (17h - 24h) - 3

  • Large (25h - 40h ) - 5

  • Extra Large (greater than 40h) - 8

To add weight to an issue in GitLab, quick actions can be utilized. Inside the comment section of an issue type the following command: /weight 0, 1, 2....

Once the weight is provided, the issue will update to reflect the submitted comment.

Milestones

Utilizing time tracking on issues and attaching them to milestones also updates the time tracking of that milestone for all issues attached.

signed_transaction graphene::wallet::wallet_api::sell_asset(
    string seller_account, 
    string amount_to_sell, 
    string symbol_to_sell, 
    string min_to_receive, 
    string symbol_to_receive, 
    uint32_t timeout_sec = 0, 
    bool fill_or_kill = false, 
    bool broadcast = false)
signed_transaction graphene::
wallet
::
wallet_api
::borrow_asset(string borrower_name, string amount_to_borrow, string asset_symbol, string amount_of_collateral, bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::cancel_order(
    object_id_type order_id, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::settle_asset(
    string account_to_settle, 
    string amount_to_settle, 
    string symbol, 
    bool broadcast = false)
vector<bucket_object> graphene::wallet::wallet_api::get_market_history(
    string symbol, 
    string symbol2, 
    uint32_t bucket, 
    fc::time_point_sec start, 
    fc::time_point_sec end)const
vector<limit_order_object> graphene::wallet::wallet_api::get_limit_orders(
    string a, 
    string b, 
    uint32_t limit)const
vector<call_order_object> graphene::wallet::wallet_api::get_call_orders(
    string a, 
    uint32_t limit)const
vector<force_settlement_object> graphene::wallet::wallet_api::get_settle_orders(
    string a, 
    uint32_t limit)const
sell_asset()

Wallet Calls

Wallet Calls

is_new

Checks whether the wallet has just been created and has not yet had a password set.

Calling set_password will transition the wallet to the locked state.

bool graphene::wallet::wallet_api::is_new()const

True if the wallet is new.

is_locked

Checks whether the wallet is locked (is unable to use its private keys).

This state can be changed by calling lock() or unlock()

bool graphene::wallet::wallet_api::is_locked()const

True if the wallet is locked

lock

Locks the wallet immediately.

void graphene::wallet::wallet_api::lock()

unlock

Unlocks the wallet.

The wallet remain unlocked until the lock is called or the program exits.

When used in command line, if typed “unlock” without a password followed, the user will be prompted to input a password without echo.

void graphene::wallet::wallet_api::unlock(
    string password)
  • password: the password previously set with set_password()

set_password

Sets a new password on the wallet.

The wallet must be either ‘new’ or ‘unlocked’ to execute this command.

When used in command line, if typed “set_password” without a password followed, the user will be prompted to input a password without echo.

void graphene::wallet::wallet_api::set_password(
    string password)
  • password: a new password

dump_private_keys

Dumps all private keys owned by the wallet.

The keys are printed in WIF format. You can import these keys into another wallet using import_key()

map<public_key_type, string> graphene::wallet::wallet_api::dump_private_keys()

A map containing the private keys, indexed by their public key

import_key

Imports the private key for an existing account.

The private key must match either an owner key or an active key for the named account.

See also dump_private_keys()

bool graphene::wallet::wallet_api::import_key(
    string account_name_or_id, 
    string wif_key)
  • account_name_or_id: the account owning the key

  • wif_key: the private key in WIF format

true if the key was imported

import_accounts

Imports accounts from a Peerplays 0.x wallet file. Current wallet file must be unlocked to perform the import.

map<string, bool> graphene::wallet::wallet_api::import_accounts(
    string filename, 
    string password)
  • filename: the Peerplays 0.x wallet file to import

  • password: the password to encrypt the Peerplays 0.x wallet file

A map containing the accounts found and whether imported.

import_account_keys

Imports from a Peerplays 0.x wallet file, find keys that were bound to a given account name on the Peerplays 0.x chain, rebind them to an account name on the 2.0 chain. Current wallet file must be unlocked to perform the import.

bool graphene::wallet::wallet_api::import_account_keys(
    string filename, 
    string password, 
    string src_account_name, 
    string dest_account_name)
  • filename: the Peerplays 0.x wallet file to import

  • password: the password to encrypt the Peerplays 0.x wallet file

  • src_account_name: name of the account on Peerplays 0.x chain

  • dest_account_name: name of the account on Peerplays 2.0 chain, can be same or different to src_account_name

Whether the import has succeeded

import_balance

This call will construct transaction(s) that will claim all balances controlled by wif_keys and deposit them into the given account.

vector<signed_transaction> graphene::wallet::wallet_api::import_balance(
    string account_name_or_id, 
    const vector<string> &wif_keys, 
    bool broadcast)
  • account_name_or_id: name or ID of an account that to claim balances to

  • wif_keys: private WIF keys of balance objects to claim balances from

  • broadcast: true to broadcast the transaction on the network

suggest_brain_key

Suggests a safe brain key to use for creating your account. create_account_with_brain_key() requires you to specify a ‘brain key’, a long passphrase that provides enough entropy to generate cryptographic keys.

This function will suggest a suitably random string that should be easy to write down (and, with effort, memorize).

brain_key_info graphene::wallet::wallet_api::suggest_brain_key()const

A suggested brain_key

get_transaction_id

This method is used to convert a JSON transaction to its transacting ID.

transaction_id_type graphene::wallet::wallet_api::get_transaction_id(
    const signed_transaction &trx)const
  • trx: a JSON transaction

The ID (hash) of the transaction.

get_private_key

Get the WIF private key corresponding to a public key. The private key must already be in the wallet.

string graphene::wallet::wallet_api::get_private_key(
    public_key_type pubkey)const
  • pubkey: a public key in Base58 format

The WIF private key

load_wallet_file

Loads a specified Graphene wallet.

The current wallet is closed before the new wallet is loaded.

Important: This does not change the filename that will be used for future wallet writes, so this may cause you to overwrite your original wallet unless you also call set_wallet_filename()

bool graphene::wallet::wallet_api::load_wallet_file(
    string wallet_filename = "")
  • wallet_filename: the filename of the wallet JSON file to load. If wallet_filename is empty, it reloads the existing wallet file.

True if the specified wallet is loaded.

normalize_brain_key

Transforms a brain key to reduce the chance of errors when re-entering the key from memory.

This takes a user-supplied brain key and normalizes it into the form used for generating private keys. In particular, this upper-cases all ASCII characters and collapses multiple spaces into one.

string graphene::wallet::wallet_api::normalize_brain_key(
    string s)const
  • s: the brain key as supplied by the user

The brain key in its normalized form.

save_wallet_file

Saves the current wallet to the given filename.

Important: This does not change the wallet filename that will be used for future writes, so think of this function as ‘Save a Copy As…’ instead of ‘Save As…’. Use set_wallet_filename() to make the filename persist.

void graphene::wallet::wallet_api::save_wallet_file(
    string wallet_filename = "")
  • wallet_filename: the filename of the new wallet JSON file to create or overwrite. If wallet_filename is empty, save to the current filename.

https://docs.gitlab.com/ee/user/project/quick_actions.html
Providing an 8 hour estimate to an issue
Issue updated based on time estimate
Providing a 2 hour time spend
Issue updated based on time spent
Providing 8 points to weight
Milestone with attached issues that have time tracking

Peerplays Technical Summary

Introducing Peerplays

Peerplays is a decentralized, global crypto platform, built on the most advanced blockchain technology available today. Peerplays brings a new paradigm of fairness, speed, transparency, and security to the global economy.

Peerplays’ decentralization is based on the Delegated Proof of Stake (DPoS) consensus model, meaning that blocks are produced by a group of "Witness" nodes which are elected by stake-weighted token holder voting.

In addition to the Witnesses and the Advisors, a group of blockchain accounts, likewise elected by token holder voting, which vote to specify configurable blockchain parameters, and vote to include or reject proposed new features and other modifications to the consensus protocol.

Peerplays is a smart contracting platform specifically targeted at humanizing crypto economies.

Peerplays is not a Turing complete smart contracting platform, meaning that Peerplays does not support arbitrary, user-defined smart contracts; rather, it provides a well-defined set of officially maintained, built-in contracts. This is in contrast to Turing complete smart contracting platforms like EOS or Ethereum, which provide few to no official contracts, but allow users to define and share contracts without any formally defined quality or correctness verification.

This document is intended to give new Peerplays developers an introduction to the Peerplays architecture and software. Readers are expected to be familiar with C++ software development in general, but not with Peerplays specifically.

This document will walk readers through the code repository structure and how to build the software; describe the individual libraries and executables and their purposes; and examine how the smart contracts work and discuss how to create or modify Peerplays smart contracts.

Graphene

Graphene is the underlying technology behind the Peerplays blockchain. It's an open-source blockchain technology, mainly written in C++. The Graphene source is available in numerous variations, as it has been forked and adapted many times.

There is no other known blockchain like Graphene that can even try to compete in the processing such a high number of transactions this blockchain already can.

Graphene-based coins can do something Bitcoin was never capable of, and will never be. And that is being a real-time value exchange system that will get mass adoption, with great apps built upon it.

A few of the advantages of Graphene are:

  • Can push over 10,000 transactions per second (TPS), versus Bitcoin, currently at around 7 transactions per second - this could mean Bitcoin payments hanging for 3-4 days!

  • Best-in-class block production and transaction finality at three seconds compared to Bitcoin at 10 minutes.

  • Supports payments with zero commission. Users can transfer coins from one account to another absolutely free of charge.

  • Uses the Delegated Proof of Stake (DPOS) algorithm instead of Proof of work (POW).

  • The possibility of working with several tokens in one system at once.

The key Graphene resources can be found here and are a very good starting point for anyone wanting to understand the Peerplays blockchain.

DPOS and GPOS

Peerplays is based on the Delegated Proof of Stake (DPOS) consensus mechanism, where the number of Witnesses are selected, via continuous voting by the PPY token holders, to produce blocks.

Note: The number of block producing (active) Witnesses has to be an odd number.

Only these Witnesses produce the blocks in their respective time slots until the next maintenance interval. After the maintenance interval, the algorithm chooses the next set of Witnesses based on the voting results. Furthermore:

  • Only token holders can participate in the voting process.

  • Token holders can vote multiple times, for multiple Witnesses.

Apart from Witnesses, the token holders also elect Advisors who have the privilege of proposing changes to the network parameters. These changes range from something as simple as transaction fees – to the number of elected Witnesses.

Under DPOS the administrative authority rests in the hands of the users, just like a democracy. But unlike Witnesses, the Advisors are not compensated for retaining their positions.

Building on the success of the DPOS consensus mechanism, Peerplays introduced a unique enhancement called Gamified Proof of Stake (GPOS).

The original intent of Peerplays was to operate as a Decentralized Autonomous Cooperative (DAC) where DPOS enabled the voting collective of core token holders to determine who would act as Advisors, Witness, and Proposals within Peerplays. However, the challenges of voter turnout continued to plague Peerplays like other DPOS based blockchains.

GPOS made a protocol change such that PPY token holders now receive a 'participation reward' based on their voting performance and how many PPY they have vested or 'staked'.

This is a significant change from the original DPOS protocol where token holders were rewarded with their share of a 'rake', taken from a percentage of the blockchain fees, and then distributed to token holders relative to their token holdings, regardless of any voting participation.

The importance of voter participation of the PPY token holders is paramount to the security of the blockchain. The introduction of GPOS ensures that token holders will take an active interest in the operation and governance of Peerplays.

Peerplays Repository

The official Peerplays repository can be found at:

This repository uses git submodules, so be sure to fetch the submodules when cloning. This can be done by passing the --recursive flag when cloning:

$ git clone https://github.com/peerplays-network/peerplays --recursive

The most significant subdirectories in the repository are libraries, programs, and tests. The Peerplays implementation is almost entirely defined within various libraries, which are located in the libraries subdirectory.

The programs subdirectory contains small wrappers around these libraries, exposing their functionality as executable binaries.

The tests subdirectory contains various tests to verify that essential blockchain features and functionality are working, and to detect regressions should they occur during development.

We'll now look at each of the three subdirectories in greater detail.

The Peerplays Libraries

Peerplays is implemented in several libraries within the libraries sub directory of the repository. A high level description of each of the libraries is as follows:

  • app contains the application class, which implements the heart of a Peerplays node

  • chain contains the bulk of the blockchain implementation, including all Peerplays specific functionality

  • db contains the database functionality, implementing the in-memory database as well as the persistence layer

  • egenesis is a small library which embeds the genesis block data into the binary

  • fc is a library implementing many utility functionalities, including serialization, RPC, concurrency, etc.

  • net contains the peer-to-peer networking layer of Peerplays

  • plugins contains several plugin libraries which can be utilized within a Peerplays node

  • utilities contains code and data necessary to Peerplays’ implementation, but not critical to the core functionality

  • wallet contains the reference command-line wallet implementation

Of these libraries, the bulk of development activity occurs within the chain library, and sometimes fc. The other libraries remain reasonably stable, seeing comparatively small updates and modifications.

The Peerplays Programs

Peerplays contains several programs, but only two of these are relevant to modern Peerplays development: witness_node and cli_wallet. In addition, the code within these folders exists just to expose library functionality in an executable, and is rarely updated.

The witness_node program is the only maintained Peerplays node executable. The name witness_node is something of a misnomer, as this executable is really just a full node, but it can provide witness (i.e., block producer) functionality by loading the witness plugin.

Tip: If you wish to sync with the Peerplays blockchain network and maintain a database of the current chain state, this is the program to do it with.

The cli_wallet program implements a command-line wallet for Peerplays. It requires a network connection to a running witness_node to provide chain state information to it. This program provides a basic UI for all Peerplays functionality.

The Peerplays Tests

Peerplays uses the Boost testing framework for its tests. Most of the Peerplays tests use the database_fixture, defined in tests/common/database_fixture.hpp, as the basis of the tests. This file also defines many macros and functions to reduce the boilerplate of test writing.

The bulk of the tests are written in the tests/tests folder, and are run by the chain_test binary. All tests of core functionality should be included in this directory and binary.

Peerplays Smart Contracts

This section provides a high-level overview of the architecture of smart contracts in Peerplays, how they work, and how they are created.

At its essence, a Peerplays smart contract is comprised of three main types of object:

  • operation

  • evaluator

  • object

The Peerplays protocol defines a set of actions a user can take within the blockchain ecosystem, called operation s. All interactions with the blockchain take place through operation s, and in a sense, they are the blockchain’s API.

Each operation has an evaluator, which implements that operation’s functionality within the Peerplays software implementation. Thus an operation is like a function prototype, whereas an evaluator is the function definition.

Finally, all data persistently stored by the blockchain is contained within database object s. Each object defines a group of fields, analogous to columns of a relational database table.

Operations

All operation s charge a fee to execute, and each must specify an account to pay the fee. This account’s ID must be returned by the fee_payer() method on the operation. Each operation must also provide a stateless consistency check which examines the operation’s fields and throws an exception if anything is invalid.

Finally, operation s must provide a calculate_fee() method which examines the operation and calculates the fee to execute it. This method may not reference blockchain state, however, each operation defines a fee_parameters_type struct containing settings for the fee calculation defined at runtime, and an instance of this struct is passed to the calculate_fee() method.

All operation s automatically require the authorization of their fee paying account, but an operation may additionally specify other accounts which must authorize their execution by defining the get_required_active_authorities() and/or get_required_owner_authorities() methods.

Note: If a transaction contains an operation which requires a given account’s authorization, signatures sufficient to satisfy that account’s authority must be provided on the transaction.

Evaluators

Each operation has an evaluator which implements that operation’s modifications to the blockchain database. Each evaluator most provide two methods: do_evaluate() and do_apply().

The evaluate step examines the operation with read-only access to the database, and verifies that the operation can be applied successfully. The apply step then modifies the database.

Each evaluator must also define a type alias, evaluator::operation_type, which aliases the specific operation implemented by that evaluator.

Objects

The Peerplays software implementation utilizes a custom, in-memory relational-style database to track the blockchain state as new blocks and transactions are applied, containing operation s which modify the database.

This database is implemented in the libraries/db folder, and it provides persistence to disk as well as undo functionality allowing the rewinding of changes, such as when a partially-applied transaction fails to execute, or blocks are popped due to a chain reorganization (i.e. when switching forks).

The Peerplays database tracks various object types, each of which defines the columns of a table. The rows of this table represent the individual object instances in the database. Along with each object type is an index type, which, in relational database terms, defines the primary and secondary keys, which can be used to look up object instances.

The primary key is always an object_id type, a unique numerical ID for each object instance known to the blockchain. All objects inherit an id field from their base class which contains this ID. This field is set by the database automatically and does not need to be modified manually.

Summary

Peerplays smart contracts are defined as a set of operation s which are analogous to API calls provided by the contract.

These operation s are implemented by evaluator s, which provide code to verify that the operation can execute successfully, and then to perform the requisite modifications to database object s.

All object s specify an index, which defines keys which can be used to look up an object instance within the database.

Peerplays API(s)

Since Peerplays is a Graphene based blockchain it supports the Graphene API at its core.

For more information on the Graphene API go to:

To make access to the API easier for developers there are two Python libraries that can be used.

python-peerplays (pypeerplays)

This is a communications library which allows interface with the Peerplays blockchain directly and without the need for a cli_wallet. It provides a wallet interface and can construct any kind of transactions and properly sign them for broadcast.

The repository can be found here:

The purpose of pypeerplays is to simplify development of products and services that use the Peerplays blockchain. It comes with:

  • It’s own (bip32-encrypted) wallet

  • RPC interface for the Blockchain backend

  • JSON-based blockchain objects (accounts, blocks, events, etc)

  • A simple to use yet powerful API

  • Transaction construction and signing

  • Push notification API

  • and more

peerplaysjs-lib

This is Javascript API for interacting with the Peerplays Blockchain. This is more commonly used for connecting dApps to the blockchain.

The repository can be found here:

Interfacing With Graphene

The APIs are separated into two categories:

  • the Blockchain API which is used to query blockchain data (account, assets, trading history, etc.)

  • the CLI Wallet API which has your private keys loaded and is required when interacting with the blockchain with new transactions.

The set of available calls depends on whether you connect to a full node (witness_node) or the wallet (cli_wallet). Both support RPC-JSON. The full node also supports the websocket protocol with notifications.

Which blockchain network you connect to depends on the configuration of the full node and the wallet.

Tip: If you run a full node, we recommend you connect your wallet to your local full node even though it could be connected to any other public full node as well.

Blockchain API

The blockchain API (as provided by the witness_node application) can be used to obtain any kind of data stored in the blockchain. Besides data stores in the blockchain itself (blocks, transactions, etc. ..), higher level objects (such as accounts, balances, etc. …) can be retrieved through the full node’s database.

It is not required to run a local full node if you want to query a particular blockchain or database, but you can also query any existing public node for information.

Important: The blockchain API doesn't know about private keys, and cannot sign transactions for you. All it does is validate and broadcast transactions to the P2P network.

CLI Wallet API

The cli-wallet api, as provided by the cli_wallet binary, allows you to create and sign transactions and broadcast them.

How to create a Peerplays Account?Peerplays Infrastructure Docs
Bitcoin TransactionPeerplays Community Docs
Welcome to bos-auto — Bookied 0.0.1 documentation
Installation GuidesPeerplays Infrastructure Docs
Peerplays WitnessesTelegram

Asset Calls

Asset Calls

list_assets

Lists all assets registered on the blockchain.

To list all assets, pass the empty string "" for the lowerbound to start at the beginning of the list, and iterate as necessary.

vector<extended_asset_object> graphene::wallet::wallet_api::list_assets(
    const string &lowerbound, 
    uint32_t limit)const
  • lowerbound: the symbol of the first asset to include in the list.

  • limit: the maximum number of assets to return (max: 100)

The list of asset objects, ordered by symbol.

create_asset

Creates a new user-issued or market-issued asset.

Many options can be changed later using update_asset()

Note: Right now this function is difficult to use because you must provide raw JSON data structures for the options objects, and those include prices and asset ids.

signed_transaction graphene::wallet::wallet_api::create_asset(
    string issuer, 
    string symbol, 
    uint8_t precision, 
    asset_options common, 
    fc::optional<bitasset_options> bitasset_opts, 
    bool broadcast = false)
  • issuer: the name or id of the account who will pay the fee and become the issuer of the new asset. This can be updated later

  • symbol: the ticker symbol of the new asset

  • precision: the number of digits of precision to the right of the decimal point, must be less than or equal to 12

  • common: asset options required for all new assets. Note that core_exchange_rate technically needs to store the asset ID of this new asset. Since this ID is not known at the time this operation is created, create this price as though the new asset has instance ID 1, and the chain will overwrite it with the new asset’s ID.

  • bitasset_opts: options specific to BitAssets. This may be null unless the market_issued flag is set in common.flags

  • broadcast: true to broadcast the transaction on the network

The signed transaction creating a new asset.

update_asset

Update the core options on an asset. There are a number of options which all assets in the network use. These options are enumerated in the asset_object::asset_options struct.

This command is used to update these options for an existing asset.

signed_transaction graphene::wallet::wallet_api::update_asset(
    string symbol, 
    optional<string> new_issuer, 
    asset_options new_options, 
    bool broadcast = false)
  • symbol: the name or id of the asset to update

  • new_issuer: if changing the asset’s issuer, the name or id of the new issuer. null if you wish to remain the issuer of the asset

  • new_options: the new asset_options object, which will entirely replace the existing options.

  • broadcast: true to broadcast the transaction on the network

The signed transaction updating the asset

update_bitasset

Update the options specific to a BitAsset.

BitAssets have some options which are not relevant to other asset types. This operation is used to update those options an an existing BitAsset.

See update_asset()

signed_transaction graphene::wallet::wallet_api::update_bitasset(
    string symbol, 
    bitasset_options new_options, 
    bool broadcast = false)
  • symbol: the name or id of the asset to update, which must be a market-issued asset

  • new_options: the new bitasset_options object, which will entirely replace the existing options.

  • broadcast: true to broadcast the transaction on the network

The signed transaction updating the Bitasset

update_asset_feed_producers

Update the set of feed-producing accounts for a BitAsset.

BitAssets have price feeds selected by taking the median values of recommendations from a set of feed producers. This command is used to specify which accounts may produce feeds for a given BitAsset.

signed_transaction graphene::wallet::wallet_api::update_asset_feed_producers(
    string symbol, 
    flat_set<string> new_feed_producers, 
    bool broadcast = false)
  • symbol: the name or id of the asset to update

  • new_feed_producers: a list of account names or ids which are authorized to produce feeds for the asset. this list will completely replace the existing list

  • broadcast: true to broadcast the transaction on the network

The signed transaction updating the BitAsset’s feed producers

publish_asset_feed

Publishes a price feed for the named asset.

Price feed providers use this command to publish their price feeds for market-issued assets. A price feed is used to tune the market for a particular market-issued asset. For each value in the feed, the median across all committee_member feeds for that asset is calculated and the market for the asset is configured with the median of that value.

The feed object in this command contains three prices:

  • A call price limit

  • A short price limit,

  • A settlement price

The call limit price is structured as (collateral asset) / (debt asset) and the short limit price is structured as (asset for sale) / (collateral asset).

Note: The asset IDs are opposite to each other, so if we’re publishing a feed for USD, the call limit price will be CORE/USD and the short limit price will be USD/CORE.

The settlement price may be flipped either direction, as long as it is a ratio between the market-issued asset and its collateral.

signed_transaction graphene::wallet::wallet_api::publish_asset_feed(
    string publishing_account, 
    string symbol, 
    price_feed feed, 
    bool broadcast = false)
  • publishing_account: the account publishing the price feed

  • symbol: the name or id of the asset whose feed we’re publishing

  • feed: the price_feed object containing the three prices making up the feed

  • broadcast: true to broadcast the transaction on the network

The signed transaction updating the price feed for the given asset.

issue_asset

Issue new shares of an asset.

signed_transaction graphene::wallet::wallet_api::issue_asset(
    string to_account, 
    string amount, 
    string symbol, 
    string memo, 
    bool broadcast = false)
  • to_account: the name or id of the account to receive the new shares

  • amount: the amount to issue, in nominal units

  • symbol: the ticker symbol of the asset to issue

  • memo: a memo to include in the transaction, readable by the recipient

  • broadcast: true to broadcast the transaction on the network

The signed transaction issuing the new shares

get_asset

Returns information about the given asset.

extended_asset_object graphene::wallet::wallet_api::get_asset(
    string asset_name_or_id)const
  • asset_name_or_id: the symbol or id of the asset in question

The information about the asset stored in the block chain.

get_bitasset_data

Returns the BitAsset-specific data for a given asset. Market-issued assets’s behaviour are determined both by their “BitAsset Data” and their basic asset data, as returned by get_asset()

asset_bitasset_data_object graphene::wallet::wallet_api::get_bitasset_data(
    string asset_name_or_id)const
  • asset_name_or_id: the symbol or id of the BitAsset in question

The BitAsset-specific data for this asset

fund_asset_fee_pool

Pay into the fee pool for the given asset.

User-issued assets can optionally have a pool of the core asset which is automatically used to pay transaction fees for any transaction using that asset (using the asset’s core exchange rate).

This command allows anyone to deposit the core asset into this fee pool.

signed_transaction graphene::wallet::wallet_api::fund_asset_fee_pool(
    string from, 
    string symbol, 
    string amount, 
    bool broadcast = false)
  • from: the name or id of the account sending the core asset

  • symbol: the name or id of the asset whose fee pool you wish to fund

  • amount: the amount of the core asset to deposit

  • broadcast: true to broadcast the transaction on the network

The signed transaction funding the fee pool.

reserve_asset

Burns an amount of given asset.

This command burns an amount of given asset to reduce the amount in circulation.

Note: You can't burn market-issued assets.

signed_transaction graphene::
wallet
::
wallet_api
::reserve_asset(string from, string amount, string symbol, bool broadcast = false)
  • from: the account containing the asset you wish to burn

  • amount: the amount to burn, in nominal units

  • symbol: the name or id of the asset to burn

  • broadcast: true to broadcast the transaction on the network

The signed transaction burning the asset

global_settle_asset

Forces a global settling of the given asset (black swan or prediction markets).

In order to use this operation, asset_to_settle must have the global_settle flag set

When this operation is executed all open margin positions are called at the settle price. A pool will be formed containing the collateral got from the margin positions. Users owning an amount of the asset may use settle_asset() to claim collateral instantly at the settle price from the pool.

If this asset is used as backing for other BitAssets, those BitAssets will not be affected.

Note: This operation is used only by the asset issuer.

signed_transaction graphene::
wallet
::
wallet_api
::global_settle_asset(string symbol, price settle_price, bool broadcast = false)
  • symbol: the name or id of the asset to globally settle

  • settle_price: the price at which to settle

  • broadcast: true to broadcast the transaction on the network

The signed transaction settling the named asset

Peerplays - Feel the HODL!Peerplays - Feel the HODL!
Peerplays DEX
Logo
Logo

GitLab Ticket Templates

Templates for the different types of tickets in GitLab.

1. Overview

The following templates help document tickets (issues) in GitLab. They are a starting point and reference for anyone unfamiliar with the ticketing process. There are two main templates given here; one for reporting bugs, and one for the implementation of a User Story (new feature).

Required fields listed below may not be required (strictly speaking) in GitLab when submitting a new ticket. The information in these fields are required for our team to handle bug fixes and new features with speed and efficiency. A few extra minutes of your time now can save the team hours or days in the long run.

2. Bug Tickets

A bug is a defect in something that already exists. When found, bugs need to be documented in tickets to be tracked like any other work item. Bugs are unique in that they can be difficult to reproduce, have obscure root causes, and may not present themselves in all contexts. This is why providing detailed tickets is key to solving these issues.

Key Elements of a Bug ticket:

  1. Title (Required): Short title that clearly states the Bug.

  2. Type (Required): Issue (for general work) or Incident (For investigating IT service disruptions or outages).

  3. Description (Required): Detailed enough so that QA does not need to ask questions in order to test the ticket. This should include the following sections:

    1. Description: Describe the bug.

    2. Preconditions: If necessary in order to run the Scenario steps properly.

    3. Affected Version(s): If known, list the build(s) where the issue has been observed.

    4. Scenario: The steps to reproduce the issue. Should be clear, direct, and have enough details to be reproducible.

    5. Current Bugged Behavior: The observed issue as it actually happens.

    6. Expected Correct Behavior: The requirements that describe a successful outcome. Simply, what should happen.

    7. Attempted Fixes: What has already been done to try to solve the issue, and the results of the attempts.

    8. Possible Fixes: If possible, link to the line of code that might be responsible for the problem. Or list other insights into the problem.

    9. Attachments: This is the visual proof (screenshots, logs, video, etc.) of the existing issue. Any other useful information should be attached as well.

    10. Quick Actions: If necessary, use quick actions to relate issues to this ticket. (/relate #issue1 #issue2) See Quick Actions for more info.

  4. Assignees: If known, adding the appropriate individual(s) here will save time.

  5. Weight: Estimate of the effort needed to solve the issue. See Time Tracking > Weight for more info.

  6. Epic: If known, select the best related epic.

  7. Due Date: Can be left blank. It's useful if the issue is blocking something with a deadline.

  8. Milestone: If known, select the best related milestone.

  9. Labels (Required): The following three label types must be provided, but others can be added if necessary. See Labels > Scoped Labels for more info.

    1. Priority: (low, medium, high, or critical) see the chart in Appendix A for help deciding the priority level.

    2. Type: bug (in the case of this template!)

    3. State: pending (for new tickets)

3. User Story / Implementation of a New Feature

A user story is a simple way to describe features that need to be implemented (and does not yet exist). The template below is built to help fully describe the task(s) that needs to be completed to satisfy the requirements of a user story. In this case, a user story may be an improvement, a previously missed requirement or functional spec, or even a brand new feature.

Key Elements of a User Story:

  1. Title (Required): Short title that clearly states the User Story.

  2. Type (Required): Issue (for general work) or Incident (For investigating IT service disruptions or outages).

  3. Description (Required): A clear explanation of the required story's content so that QA does not need to ask questions in order to test and close the story ticket. Additional notes are welcome. This should include the following sections:

    1. Description: Describe the user story.

    2. Affected Version(s): If necessary, list the build(s) where the issue applies.

    3. Acceptance Criteria: The clear definition of the final solution. What does the goal look like?

    4. Attachments: If helpful, provide screenshots, logs, video, diagrams, documents, etc. pertaining to the issue. Any other useful information should be attached as well.

    5. Quick Actions: If necessary, use quick actions to relate issues to this ticket or provide a time estimate. (/relate #issue1 #issue2) See Quick Actions for more info.

  4. Assignees: If known, adding the appropriate individual(s) here will save time.

  5. Weight: Estimate of the effort needed to solve the issue. See Time Tracking > Weight for more info.

  6. Epic: If known, select the best related epic.

  7. Due Date: Can be left blank. It's useful if the issue is blocking something with a deadline.

  8. Milestone: If known, select the best related milestone.

  9. Labels (Required): The following three label types must be provided, but others can be added if necessary. See Labels > Scoped Labels for more info.

    1. Priority: (low, medium, high, or critical) see the chart in Appendix A for help deciding the priority level.

    2. Type: feature (in the case of this template!)

    3. State: pending (for new tickets)

Appendix A - Determining Ticket Priority

The priority of a ticket depends on a mix of aspects. Applying a priority is subjective. But we can help classify the priority by thinking in terms of impact and urgency:

3KB
ticket-priority-matrix.xml
Ticket Priority Matrix (Draw.io XML)

Appendix B - Copy / Paste Description Templates

Bugs

Here is a template that you can quickly copy and paste into the Description field in the new GitLab bug ticket. This one has information to help guide you when entering information into the ticket.

## Description

(Required) Describe the bug here.

## Preconditions

(If necessary) In order to run the Scenario steps properly, list any preconditions.

- Precondition A
- Precondition B

## Affected Version(s)

(If known) List the build(s) where the issue has been observed.

- Build A
- Build B

## Scenario

(Required) The steps to reproduce the issue. Should be clear, direct, and have enough details to be reproducible.

1. Step 1...
2. Step 2...
3. Step 3...

## Current Bugged Behavior

(Required) The observed issue as it actually happens.

## Expected Correct Behavior

(Required) The requirements that describe a successful outcome. Simply, what should happen.

## Attempted Fixes

(Required, even if nothing) What has already been done to try to solve the issue, and the results of the attempts.

## Possible Fixes

(If possible) Link to the line of code that might be responsible for the problem. Or list other insights into the problem.

**Note**: Don't forget to attach any relevant files, and to use quick actions to link related issues or add time estimates. Then delete this note!

Or just the section headers if you prefer...

## Description



## Preconditions



## Affected Version(s)



## Scenario



## Current Bugged Behavior



## Expected Correct Behavior



## Attempted Fixes



## Possible Fixes


User Stories

Here is a template that you can quickly copy and paste into the Description field in the new GitLab user story ticket. This one has information to help guide you when entering information into the ticket.

## Description

(Required) Describe the user story.

## Affected Version(s)

(If necessary) List the build(s) where the issue applies.

- Build A
- Build B

## Acceptance Criteria

(Required) The clear definition of the final solution. What does the goal look like?

**Note**: Don't forget to attach any relevant files, and to use quick actions to link related issues or add time estimates. Then delete this note!

Or just the section headers if you prefer...

## Description



## Affected Version(s)



## Acceptance Criteria


Governance

Governance

create_committee_member

Creates a committee_member object owned by the given account.

An account can have at most one committee_member object.

  • owner_account: the name or id of the account which is creating the committee_member

  • url: a URL to include in the committee_member record in the blockchain. Clients may display this when showing a list of committee_members. May be blank.

  • broadcast: true to broadcast the transaction on the network

The signed transaction registering a committee_member

get_witness

Returns information about the given witness.

  • owner_account: the name or id of the witness account owner, or the id of the witness

The information about the witness stored in the block chain.

get_committee_member

Returns information about the given committee_member.

  • owner_account: the name or id of the committee_member account owner, or the id of the committee_member.

The information about the committee_member stored in the block chain

list_witnesses

Lists all Witnesses registered in the blockchain. This returns a list of all account names that own Witnesses, and the associated witness id, sorted by name. This lists Witnesses whether they are currently voted in or not.

Use the lowerbound and limit parameters to page through the list. To retrieve all Witness's, start by setting lowerbound to the empty string "", and then each iteration, pass the last witness name returned as the lowerbound for the next list_witnesss() call.

  • lowerbound: the name of the first Witness to return. If the named Witness does not exist, the list will start at the witness that comes after lowerbound

  • limit: the maximum number of Witness's to return (max: 1000)

A list of Witness's mapping witness names to witness ids

list_committee_members

Lists all committee_members registered in the blockchain. This returns a list of all account names that own committee_members, and the associated committee_member id, sorted by name. This lists committee_members whether they are currently voted in or not.

Use the lowerbound and limit parameters to page through the list. To retrieve all committee_members, start by setting lowerbound to the empty string "", and then each iteration, pass the last committee_member name returned as the lowerbound for the next list_committee_members() call.

  • lowerbound: the name of the first committee_member to return. If the named committee_member does not exist, the list will start at the committee_member that comes after lowerbound

  • limit: the maximum number of committee_members to return (max: 1000)

A list of committee_members mapping committee_member names to committee_member ids

create_witness

Creates a witness object owned by the given account.

An account can have at most one witness object.

  • owner_account: the name or id of the account which is creating the witness

  • url: a URL to include in the witness record in the blockchain. Clients may display this when showing a list of witnesses. May be blank.

  • broadcast: true to broadcast the transaction on the network

The signed transaction registering a witness

update_witness

Update a witness object owned by the given account.

  • witness_name: The name of the witness’s owner account. Also accepts the ID of the owner account or the ID of the witness.

  • url: Same as for create_witness. The empty string makes it remain the same.

  • block_signing_key: The new block signing public key. The empty string makes it remain the same.

  • broadcast: true if you wish to broadcast the transaction.

The signed transaction

create_worker

Create a worker object.

  • owner_account: The account which owns the worker and will be paid

  • work_begin_date: When the work begins

  • work_end_date: When the work ends

  • daily_pay: Amount of pay per day (NOT per maint interval)

  • name: Any text

  • url: Any text

  • worker_settings: {“type” : “burn”|”refund”|”vesting”, “pay_vesting_period_days” : x}

  • broadcast: true if you wish to broadcast the transaction.

The signed transaction

update_worker_votes

Update your votes for workers.

  • account: The account which will pay the fee and update votes.

  • delta: {“vote_for” : […], “vote_against” : […], “vote_abstain” : […]}

  • broadcast: true if you wish to broadcast the transaction.

The signed transaction

vote_for_committee_member

Vote for a given committee_member.

An account can publish a list of all committee_members they approve of. This command allows you to add or remove committee_members from this list. Each account’s vote is weighted according to the number of shares of the core asset owned by that account at the time the votes are tallied.

Note: You can't vote against a committee_member, you can only vote for the committee_member or not vote for the committee_member.

  • voting_account: the name or id of the account who is voting with their shares

  • committee_member: the name or id of the committee_member’ owner account

  • approve: true if you wish to vote in favour of that committee_member, false to remove your vote in favour of that committee_member

  • broadcast: true if you wish to broadcast the transaction

The signed transaction changing your vote for the given committee_member.

vote_for_witness

Vote for a given witness.

An account can publish a list of all witnesses they approve of. This command allows you to add or remove witnesses from this list. Each account’s vote is weighted according to the number of shares of the core asset owned by that account at the time the votes are tallied.

Note: You can't vote against a witness, you can only vote for the witness or not vote for the witness.

  • voting_account: the name or id of the account who is voting with their shares

  • witness: the name or id of the witness’ owner account

  • approve: true if you wish to vote in favour of that witness, false to remove your vote in favour of that witness

  • broadcast: true if you wish to broadcast the transaction

The signed transaction changing your vote for the given witness

set_voting_proxy

Set the voting proxy for an account.

If a user does not wish to take an active part in voting, they can choose to allow another account to vote their stake.

Setting a vote proxy does not remove your previous votes from the blockchain, they remain there but are ignored. If you later null out your vote proxy, your previous votes will take effect again.

This setting can be changed at any time.

  • account_to_modify: the name or id of the account to update

  • voting_account: the name or id of an account authorized to vote account_to_modify’s shares, or null to vote your own shares

  • broadcast: true if you wish to broadcast the transaction

The signed transaction changing your vote proxy settings

set_desired_witness_and_committee_member_count

Set your vote for the number of witnesses and committee_members in the system.

Each account can voice their opinion on how many committee_members and how many witnesses there should be in the active committee_member/active witness list. These are independent of each other. You must vote your approval of at least as many committee_members or witnesses as you claim there should be (you can’t say that there should be 20 committee_members but only vote for 10).

There are maximum values for each set in the blockchain parameters (currently defaulting to 1001).

This setting can be changed at any time. If your account has a voting proxy set, your preferences will be ignored.

  • account_to_modify: the name or id of the account to update

  • desired_number_of_witnesses: desired number of active witnesses

  • desired_number_of_committee_members: desired number of active committee members

  • broadcast: true if you wish to broadcast the transaction

The signed transaction changing your vote proxy settings

propose_parameter_change

Creates a transaction to propose a parameter change.

Multiple parameters can be specified if an atomic change is desired.

  • proposing_account: The account paying the fee to propose the tx

  • expiration_time: Timestamp specifying when the proposal will either take effect or expire.

  • changed_values: The values to change; all other chain parameters are filled in with default values

  • broadcast: true if you wish to broadcast the transaction

The signed version of the transaction

propose_fee_change

Propose a fee change.

  • proposing_account: The account paying the fee to propose the tx

  • expiration_time: Timestamp specifying when the proposal will either take effect or expire.

  • changed_values: Map of operation type to new fee. Operations may be specified by name or ID. The “scale” key changes the scale. All other operations will maintain current values.

  • broadcast: true if you wish to broadcast the transaction

The signed version of the transaction

Account Calls

Account Calls

list_my_accounts

Lists all accounts controlled by this wallet. This returns a list of the full account objects for all accounts whose private keys we possess

A list of account objects

list_accounts

Lists all accounts registered in the blockchain. This returns a list of all account names and their account ids, sorted by account name.

Use the lowerbound and limit parameters to page through the list. To retrieve all accounts, start by setting lowerbound to the empty string "", and then each iteration, pass the last account name returned as the lowerbound for the next list_accounts() call.

  • lowerbound: the name of the first account to return. If the named account does not exist, the list will start at the account that comes after lowerbound

  • limit: the maximum number of accounts to return (max: 1000)

A list of accounts mapping account names to account ids.

list_account_balances

List the balances of an account. Each account can have multiple balances, one for each type of asset owned by that account. The returned list will only contain assets for which the account has a non-zero balance.

  • id: the name or id of the account whose balances you want

A list of the given account’s balances

register_account

Registers a third party’s account on the blockchain.

This function is used to register an account for which you do not own the private keys. When acting as a registrar, an end user will generate their own private keys and send you the public keys. The registrar will use this function to register the account on behalf of the end user.

See also

  • name: the name of the account, must be unique on the blockchain. Shorter names are more expensive to register; the rules are still in flux, but in general names of more than 8 characters with at least one digit will be cheap.

  • owner: the owner key for the new account

  • active: the active key for the new account

  • registrar_account: the account which will pay the fee to register the user

  • referrer_account: the account who is acting as a referrer, and may receive a portion of the user’s transaction fees. This can be the same as the registrar_account if there is no referrer.

  • referrer_percent: the percentage (0 - 100) of the new user’s transaction fees not claimed by the blockchain that will be distributed to the referrer; the rest will be sent to the registrar. Will be multiplied by GRAPHENE_1_PERCENT when constructing the transaction.

  • broadcast: true to broadcast the transaction on the network

The signed transaction registering the account

upgrade_account

Upgrades an account to prime status. This makes the account holder a ‘lifetime member’.

  • name: the name or id of the account to upgrade

  • broadcast: true to broadcast the transaction on the network

The signed transaction upgrading the account

create_account_with_brain_key

Creates a new account and registers it on the blockchain.

See also ,

  • brain_key: the brain key used for generating the account’s private keys

  • account_name: the name of the account, must be unique on the blockchain. Shorter names are more expensive to register; the rules are still in flux, but in general names of more than 8 characters with at least one digit will be cheap.

  • registrar_account: the account which will pay the fee to register the user

  • referrer_account: the account who is acting as a referrer, and may receive a portion of the user’s transaction fees. This can be the same as the registrar_account if there is no referrer.

  • broadcast: true to broadcast the transaction on the network

The signed transaction registering the account

transfer

Transfer an amount from one account to another.

  • from: the name or id of the account sending the funds

  • to: the name or id of the account receiving the funds

  • amount: the amount to send (in nominal units to send half of a BTS, specify 0.5)

  • asset_symbol: the symbol or id of the asset to send

  • memo: a memo to attach to the transaction. The memo will be encrypted in the transaction and readable for the receiver. There is no length limit other than the limit imposed by maximum transaction size, but transaction increase with transaction size

  • broadcast: true to broadcast the transaction on the network

The signed transaction transferring funds

transfer2

This method works just like transfer, except it always broadcasts and returns the transaction ID (hash) along with the signed transaction.

  • from: the name or id of the account sending the funds

  • to: the name or id of the account receiving the funds

  • amount: the amount to send (in nominal units to send half of a BTS, specify 0.5)

  • asset_symbol: the symbol or id of the asset to send

  • memo: a memo to attach to the transaction. The memo will be encrypted in the transaction and readable for the receiver. There is no length limit other than the limit imposed by maximum transaction size, but transaction increase with transaction size

The transaction ID (hash) along with the signed transaction transferring funds

whitelist_account

Whitelist and blacklist accounts, primarily for transacting in whitelisted assets.

Accounts can freely specify opinions about other accounts, in the form of either whitelisting or blacklisting them. This information is used in chain validation only to determine whether an account is authorized to transact in an asset type which enforces a whitelist, but third parties can use this information for other uses as well, as long as it does not conflict with the use of whitelisted assets.

An asset which enforces a whitelist specifies a list of accounts to maintain its whitelist, and a list of accounts to maintain its blacklist. In order for a given account A to hold and transact in a whitelisted asset S, A must be whitelisted by at least one of S’s whitelist_authorities and blacklisted by none of S’s blacklist_authorities. If A receives a balance of S, and is later removed from the whitelist(s) which allowed it to hold S, or added to any blacklist S specifies as authoritative, A’s balance of S will be frozen until A’s authorization is reinstated.

  • authorizing_account: the account who is doing the whitelisting

  • account_to_list: the account being whitelisted

  • new_listing_status: the new whitelisting status

  • broadcast: true to broadcast the transaction on the network

The signed transaction changing the whitelisting status

get_vesting_balances

Get information about a vesting balance object or vesting balance objects owned by an account.

  • account_name: An account name, account ID, or vesting balance object ID.

A list of vesting balance objects with additional info

withdraw_vesting

Withdraw a vesting balance.

  • witness_name: The account name of the witness, also accepts account ID or vesting balance ID type.

  • amount: The amount to withdraw.

  • asset_symbol: The symbol of the asset to withdraw.

  • broadcast: true if you wish to broadcast the transaction

The signed transaction

get_account

Returns information about the given account.

  • account_name_or_id: the name or ID of the account to provide information about

The public account data stored in the blockchain

get_account_id

Lookup the id of a named account.

  • account_name_or_id: the name or ID of the account to look up

The id of the named account

get_account_history

Returns the most recent operations on the named account.

This returns a list of operation history objects, which describe activity on the account.

  • name: the name or id of the account

  • limit: the number of entries to return (starting from the most recent)

A list of operation_history_objects

approve_proposal

Approve or disapprove a proposal.

  • fee_paying_account: The account paying the fee for the op.

  • proposal_id: The proposal to modify.

  • delta: Members contain approvals to create or remove. In JSON you can leave empty members undefined.

  • broadcast: true if you wish to broadcast the transaction

The signed version of the transaction

signed_transaction graphene::wallet::wallet_api::create_committee_member(
    string owner_account, 
    string url, 
    bool broadcast = false)
witness_object graphene::wallet::wallet_api::get_witness(
    string owner_account)
committee_member_object graphene::wallet::wallet_api::get_committee_member(
    string owner_account)
map<string, witness_id_type> graphene::wallet::wallet_api::list_witnesses(
    const string &lowerbound, 
    uint32_t limit)
map<string, committee_member_id_type> graphene::wallet::wallet_api::list_committee_members(
    const string &lowerbound, 
    uint32_t limit)
signed_transaction graphene::wallet::wallet_api::create_witness(
    string owner_account, 
    string url, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::update_witness(
    string witness_name, 
    string url, 
    string block_signing_key, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::create_worker(
    string owner_account, 
    time_point_sec work_begin_date, 
    time_point_sec work_end_date, 
    share_type daily_pay, 
    string name, string url, 
    variant worker_settings, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::update_worker_votes(
    string account, 
    worker_vote_delta delta,
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::vote_for_committee_member(
    string voting_account, 
    string committee_member, 
    bool approve, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::vote_for_witness(
    string voting_account, 
    string witness, 
    bool approve, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::set_voting_proxy(
    string account_to_modify, 
    optional<string> voting_account, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::set_desired_witness_and_committee_member_count(
    string account_to_modify, 
    uint16_t desired_number_of_witnesses, 
    uint16_t desired_number_of_committee_members, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::propose_parameter_change(
    const string &proposing_account, 
    fc::time_point_sec expiration_time, 
    const variant_object &changed_values, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::propose_fee_change(
    const string &proposing_account, 
    fc::time_point_sec expiration_time, 
    const variant_object &changed_values, 
    bool broadcast = false)
vector<account_object> graphene::wallet::wallet_api::list_my_accounts()
map<string, account_id_type> graphene::wallet::wallet_api::list_accounts(
    const string &lowerbound, 
    uint32_t limit)
vector<asset> graphene::wallet::wallet_api::list_account_balances(
    const string &id)
signed_transaction graphene::wallet::wallet_api::register_account(
    string name, 
    public_key_type owner, 
    public_key_type active, 
    string registrar_account, 
    string referrer_account, 
    uint32_t referrer_percent, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::upgrade_account(
    string name, 
    bool broadcast)
signed_transaction graphene::wallet::wallet_api::create_account_with_brain_key(
    string brain_key, 
    string account_name, 
    string registrar_account, 
    string referrer_account, 
    bool broadcast = false)
signed_transaction graphene::wallet::wallet_api::transfer(
    string from, 
    string to, 
    string amount, 
    string asset_symbol, 
    string memo, 
    bool broadcast = false)
pair<transaction_id_type, signed_transaction> graphene::wallet::wallet_api::transfer2(
    string from, 
    string to, 
    string amount, 
    string asset_symbol, 
    string memo)
signed_transaction graphene::wallet::wallet_api::whitelist_account(
    string authorizing_account, 
    string account_to_list, 
    account_whitelist_operation::account_listing new_listing_status, 
    bool broadcast = false)
vector<vesting_balance_object_with_info> graphene::wallet::wallet_api::get_vesting_balances(
    string account_name)
signed_transaction graphene::wallet::wallet_api::withdraw_vesting(
    string witness_name, 
    string amount, 
    string asset_symbol, 
    bool broadcast = false)
account_object graphene::wallet::wallet_api::get_account(
    string account_name_or_id)const
account_id_type graphene::wallet::wallet_api::get_account_id(
    string account_name_or_id)const
vector<operation_detail> graphene::wallet::wallet_api::get_account_history(
    string name, 
    int limit)const
signed_transaction graphene::wallet::wallet_api::approve_proposal(
    const string &fee_paying_account, 
    const string &proposal_id, 
    const approval_delta &delta, 
    bool broadcast)
create_account_with_brain_key()
suggest_brain_key()
register_account()
Logo

Transaction Builder

Transaction Builder

begin_builder_transaction

Create a new transaction builder.

transaction_handle_typegraphene::wallet::wallet_api::begin_builder_transaction()

Handle of the new transaction builder.

add_operation_to_builder_transaction

Append a new operation to a transaction builder.

void graphene::wallet::wallet_api::add_operation_to_builder_transaction(
    transaction_handle_typetransaction_handle, 
    const operation &op)
  • transaction_handle: handle of the transaction builder

  • op: the operation in JSON format

replace_operation_in_builder_transaction

Replace an operation in a transaction builder with a new operation.

void graphene::wallet::wallet_api::replace_operation_in_builder_transaction(
    transaction_handle_typehandle, 
    unsigned operation_index, 
    const operation &new_op)
  • handle: handle of the transaction builder

  • operation_index: the index of the old operation in the builder to be replaced

  • new_op: the new operation in JSON format

set_fees_on_builder_transaction

Calculate and update fees for the operations in a transaction builder.

asset graphene::wallet::wallet_api::set_fees_on_builder_transaction(
    transaction_handle_typehandle, 
    string fee_asset = GRAPHENE_SYMBOL)
  • handle: handle of the transaction builder

  • fee_asset: name or ID of an asset that to be used to pay fees

Total fees.

preview_builder_transaction

Show content of a transaction builder.

transaction graphene::wallet::wallet_api::preview_builder_transaction(
    transaction_handle_typehandle)
  • handle: handle of the transaction builder

A transaction.

sign_builder_transaction

Sign the transaction in a transaction builder and optionally broadcast to the network.

signed_transaction graphene::wallet::wallet_api::sign_builder_transaction(
    transaction_handle_typetransaction_handle, 
    bool broadcast = true)
  • transaction_handle: handle of the transaction builder

  • broadcast: whether to broadcast the signed transaction to the network

A signed transaction.

propose_builder_transaction

Create a proposal containing the operations in a transaction builder (create a new proposal_create operation, then replace the transaction builder with the new operation), then sign the transaction and optionally broadcast to the network.

Note: this command is not effective because you're unable to specify a proposer. It will be deprecated in a future release. Use propose_builder_transaction2() instead.

signed_transaction graphene::wallet::wallet_api::propose_builder_transaction(
    transaction_handle_typehandle, 
    time_point_sec expiration = time_point::now() + fc::minutes(1), 
    uint32_t review_period_seconds = 0, 
    bool broadcast = true)
  • handle: handle of the transaction builder

  • expiration: when the proposal will expire

  • review_period_seconds: review period of the proposal in seconds

  • broadcast: whether to broadcast the signed transaction to the network

A signed transaction.

propose_builder_transaction2

Create a proposal containing the operations in a transaction builder (create a new proposal_create operation, then replace the transaction builder with the new operation), then sign the transaction and optionally broadcast to the network.

signed_transaction graphene::wallet::wallet_api::propose_builder_transaction2(
    transaction_handle_typehandle, 
    string account_name_or_id, 
    time_point_sec expiration = time_point::now() + fc::minutes(1), 
    uint32_t review_period_seconds = 0, 
    bool broadcast = true)
  • handle: handle of the transaction builder

  • account_name_or_id: name or ID of the account who would pay fees for creating the proposal

  • expiration: when the proposal will expire

  • review_period_seconds: review period of the proposal in seconds

  • broadcast: whether to broadcast the signed transaction to the network

A signed transaction.

remove_builder_transaction

Destroy a transaction builder.

void graphene::wallet::wallet_api::remove_builder_transaction(
    transaction_handle_typehandle)
  • handle: handle of the transaction builder

serialize_transaction

Converts a signed_transaction in JSON form to its binary representation.

string graphene::wallet::wallet_api::serialize_transaction(
    signed_transaction tx)const
  • tx: the transaction to serialize

The binary form of the transaction. It will not be hex encoded, this returns a raw string that may have null characters embedded in it

sign_transaction

Signs a transaction.

Given a fully-formed transaction that is only lacking signatures, this signs the transaction with the necessary keys and optionally broadcasts the transaction.

signed_transaction graphene::wallet::wallet_api::sign_transaction(
    signed_transaction tx, 
    bool broadcast = false)
  • tx: the unsigned transaction

  • broadcast: true if you wish to broadcast the transaction

The signed version of the transaction

get_prototype_operation

Returns an uninitialized object representing a given blockchain operation.

This returns a default-initialized object of the given type; it can be used during early development of the wallet when we don’t yet have custom commands for creating all of the operations the blockchain supports.

Any operation the blockchain supports can be created using the transaction builder’s add_operation_to_builder_transaction() , but to do that from the CLI you need to know what the JSON form of the operation looks like. This will give you a template you can fill in. It’s better than nothing.

operation graphene::wallet::wallet_api::get_prototype_operation(
    string operation_type)
  • operation_type: the type of operation to return, must be one of the operations defined in graphene/protocol/operations.hpp (e.g., “global_parameters_update_operation”)

A default-constructed operation of the given type.

Logo
Logo

General

This page documents the BookiePro data abstraction layer with the Peerplays blockchain.

BookiePro communicates with the blockchain using web-socket API calls.

list_sports

Get a list of available sports.

A list of all the available sports.

list_event_groups

Get a list of all event groups for a sport, for example, all soccer leagues in soccer.

sportId: The id of the sport that the event groups are to be listed for.

A list of all event groups for the selected sport.

list_betting_market_groups

Get a list of all betting market groups for an event, for example, Moneyline and OVER/UNDER for soccer)

eventId: The id of the event that the betting market groups are to be listed for.

A list of all the betting market groups for the event.

list_betting_markets

Get a list of all betting markets for a betting market group (BMG).

bettingMarketGroupId: The id of the betting market group that the betting markets are to be listed for.

A list of all the betting markets for the betting market group.

get_global_betting_statistics

Get global betting statistics

A list of all the global betting statistics.

get_binned_order_book

Get the binned order book for a betting market.

  • betting_market_id: The id of the betting market for the order book.

  • precision: Precision

A list of binned orders for the betting market.

get_total_matched_bet_amount_for_betting_market_group

Get the total matched bets for a betting market group (BMG).

  • group_id: The betting market group id.

Total of all the matched bet amounts for the selected betting market group.

get_events_containing_sub_string

Used to search for events.

  • sub_string: The (sub) string of text to search for

  • language: Language id.

List of events that contain the sub-string

get_unmatched_bets_for_bettor

Get unmatched bets for a bettor.

  • bettor_id: The id of the bettor.

List of all matched bets for a bettor.

list_events_in_group

Get a list of events in any event group.

  • event_group_id: The id of the event group.

A list of all the events in the event group.

get_all_unmatched_bets_for_bettor

Get all unmatched bets of a bettor according to account type.

  • account_type_id: The id of the bettor account type/

All unmatched bets by bettor account type.

get_matched_bets_for_bettor

Get the matched bets for a bettor.

  • bettor_id: The id of the bettor.

All matched bets for the bettor.

get_all_matched_bets_for_bettor

Get all matched bets for a bettor within a range.

  • bettor_id: The id of the bettor

  • start: The start date

  • limit: Number of bets to be returned

All matched bets for the better within the range start to limit.

Apis.instance().db_api().exec( "list_sports", [] )
Apis.instance().db_api().exec( "list_event_groups", [sportId] )
Apis.instance().db_api().exec( "list_betting_market_groups", [eventId] )
Apis.instance().db_api().exec( "list_betting_markets", [bettingMarketGroupId] )
ChainStore.prototype.getBettingMarketsList = function getBettingMarketsList(bettingMarketGroupId) {
    var _this19 = this;

    var bettingMarketsList = this.betting_markets_list_by_sport_id.get(bettingMarketGroupId);

    if (bettingMarketsList === undefined) {
      this.betting_markets_list_by_sport_id = this.betting_markets_list_by_sport_id.set(bettingMarketGroupId, _immutable2.default.Set());

      _ws.Apis.instance().db_api().exec('list_betting_markets', [bettingMarketGroupId]).then(function (bettingMarkets) {
        var set = new Set();

        for (var i = 0, len = bettingMarkets.length; i < len; ++i) {
          set.add(bettingMarkets[i]);
        }

        _this19.betting_markets_list_by_sport_id = _this19.betting_markets_list_by_sport_id.set(bettingMarketGroupId, _immutable2.default.Set(set));
        _this19.notifySubscribers();
      }, function () {
        _this19.betting_markets_list_by_sport_id = _this19.betting_markets_list_by_sport_id.delete(bettingMarketGroupId);
      });
    }

    return this.betting_markets_list_by_sport_id.get(bettingMarketGroupId);
  };
Apis.instance().db_api().exec( "get_global_betting_statistics", [] )
ChainStore.getGlobalBettingStatistics = function getGlobalBettingStatistics() {
    return new Promise(function (resolve, reject) {
      _ws.Apis.instance().db_api().exec('get_global_betting_statistics', []).then(function (getGlobalBettingStatistics) {
        if (getGlobalBettingStatistics) {
          resolve(getGlobalBettingStatistics);
        } else {
          resolve(null);
        }
      }, reject);
    });
  };
Apis.instance().bookie_api().exec( "get_binned_order_book", [ betting_market_id, precision ] )
ChainStore.getBinnedOrderBook = function getBinnedOrderBook(betting_market_id, precision) {
    return new Promise(function (resolve, reject) {
      _ws.Apis.instance().bookie_api().exec('get_binned_order_book', [betting_market_id, precision]).then(function (order_book_object) {
        if (order_book_object) {
          resolve(order_book_object);
        } else {
          resolve(null);
        }
      }, reject);
    });
  };
Apis.instance().bookie_api().exec( "get_total_matched_bet_amount_for_betting_market_group", [ group_id ] )
ChainStore.getTotalMatchedBetAmountForBettingMarketGroup = function getTotalMatchedBetAmountForBettingMarketGroup(group_id) {
    return new Promise(function (resolve, reject) {
      _ws.Apis.instance().bookie_api().exec('get_total_matched_bet_amount_for_betting_market_group', [group_id]).then(function (total_matched_bet_amount) {
        if (total_matched_bet_amount) {
          resolve(total_matched_bet_amount);
        } else {
          resolve(null);
        }
      }, reject);
    });
  };
Apis.instance().bookie_api().exec( "get_events_containing_sub_string", [ sub_string, language ])
function getEventsContainingSubString(sub_string, language) {
    return new Promise(function (resolve, reject) {
      _ws.Apis.instance().bookie_api().exec('get_events_containing_sub_string', [sub_string, language]).then(
        function (events_containing_sub_string) {
        if (events_containing_sub_string) {
          resolve(events_containing_sub_string);
        } else {
          resolve(null);
        }
      }, reject);
    });
  };
Apis.instance().bookie_api().exec( "get_matched_bets_for_bettor", [ bettor_id ] )
ChainStore.getUnmatchedBetsForBettor = function getUnmatchedBetsForBettor(betting_market_id_type, account_id_type) {
    return new Promise(function (resolve, reject) {
      _ws.Apis.instance().db_api().exec('get_unmatched_bets_for_bettor', [betting_market_id_type, account_id_type]).then(function (unmatched_bets_for_bettor) {
        if (unmatched_bets_for_bettor) {
          resolve(unmatched_bets_for_bettor);
        } else {
          resolve(null);
        }
      }, reject);
    });
  };
Apis.instance().db_api().exec( "list_events_in_group", [ event_group_id ] )
 ChainStore.listEventsInGroup = function listEventsInGroup(event_group_id) {
    return new Promise(function (resolve, reject) {
      _ws.Apis.instance().db_api().exec('list_events_in_group', [event_group_id]).then(function (events_in_group) {
        if (events_in_group) {
          resolve(events_in_group);
        } else {
          resolve(null);
        }
      }, reject);
    });
  };
Apis.instance().db_api().exec( "get_all_unmatched_bets_for_bettor", [ account_id_type ] )
ChainStore.getAllUnmatchedBetsForBettor = function getAllUnmatchedBetsForBettor(account_id_type) {
    return new Promise(function (resolve, reject) {
      _ws.Apis.instance().db_api().exec('get_all_unmatched_bets_for_bettor', [account_id_type]).then(function (all_unmatched_bets_for_bettor) {
        if (all_unmatched_bets_for_bettor) {
          resolve(all_unmatched_bets_for_bettor);
        } else {
          resolve(null);
        }
      }, reject);
    });
  };
Apis.instance().bookie_api().exec( "get_matched_bets_for_bettor", [ bettor_id ] )
ChainStore.getMatchedBetsForBettor = function getMatchedBetsForBettor(bettor_id) {
    return new Promise(function (resolve, reject) {
      _ws.Apis.instance().bookie_api().exec('get_matched_bets_for_bettor', [bettor_id]).then(function (matched_bets_for_bettor) {
        if (matched_bets_for_bettor) {
          resolve(matched_bets_for_bettor);
        } else {
          resolve(null);
        }
      }, reject);
    });
  };
Apis.instance().bookie_api().exec( "get_all_matched_bets_for_bettor", [ bettor_id, start, limit ] )
ChainStore.getAllMatchedBetsForBettor = function getAllMatchedBetsForBettor(bettor_id, start) {
    var limit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000;

    return new Promise(function (resolve, reject) {
      _ws.Apis.instance().bookie_api().exec('get_all_matched_bets_for_bettor', [bettor_id, start, limit]).then(function (all_matched_bets_for_bettor) {
        if (all_matched_bets_for_bettor) {
          resolve(all_matched_bets_for_bettor);
        } else {
          resolve(null);
        }
      }, reject);
    });
  };
ChainStore.getSportsList = function getSportsList() {
    return new Promise(function (resolve, reject) {
      _ws.Apis.instance().db_api().exec('list_sports', []).then(function (sportsList) {
        if (sportsList) {
          resolve(sportsList);
        } else {
          resolve(null);
        }
      }, reject);
    });
  };
ChainStore.prototype.getEventGroupsList = function getEventGroupsList(sportId) {
    var _this17 = this;

    var eventGroupsList = this.event_groups_list_by_sport_id.get(sportId);

    if (eventGroupsList === undefined) {
      this.event_groups_list_by_sport_id = this.event_groups_list_by_sport_id.set(sportId, _immutable2.default.Set());

      _ws.Apis.instance().db_api().exec('list_event_groups', [sportId]).then(function (eventGroups) {
        var set = new Set();

        for (var i = 0, len = eventGroups.length; i < len; ++i) {
          set.add(eventGroups[i]);
        }

        _this17.event_groups_list_by_sport_id = _this17.event_groups_list_by_sport_id.set(sportId, _immutable2.default.Set(set));
        _this17.notifySubscribers();
      }, function () {
        _this17.event_groups_list_by_sport_id = _this17.event_groups_list_by_sport_id.delete(sportId);
      });
    }

    return this.event_groups_list_by_sport_id.get(sportId);
  };
ChainStore.prototype.getBettingMarketGroupsList = function getBettingMarketGroupsList(eventId) {
    var _this18 = this;

    var bettingMarketGroupsList = this.betting_market_groups_list_by_sport_id.get(eventId);

    if (bettingMarketGroupsList === undefined) {
      this.betting_market_groups_list_by_sport_id = this.betting_market_groups_list_by_sport_id.set(eventId, _immutable2.default.Set());

      _ws.Apis.instance().db_api().exec('list_betting_market_groups', [eventId]).then(function (bettingMarketGroups) {
        var set = new Set();

        for (var i = 0, len = bettingMarketGroups.length; i < len; ++i) {
          set.add(bettingMarketGroups[i]);
        }

        _this18.betting_market_groups_list_by_sport_id = _this18.betting_market_groups_list_by_sport_id.set( // eslint-disable-line
        eventId, _immutable2.default.Set(set));
        _this18.notifySubscribers();
      }, function () {
        _this18.betting_market_groups_list_by_sport_id = _this18.betting_market_groups_list_by_sport_id.delete( // eslint-disable-line
        eventId);
      });
    }

    return this.betting_market_groups_list_by_sport_id.get(eventId);
  };

Popular API Calls

Overview

Some of the most interesting API calls for exchanges and gateways are listed in this document.

We will now take a look at some sample outputs for some of the API calls.

API Calls

list_account_balances

List the balances of an account. Each account can have multiple balances, one for each type of asset owned by that account. The returned list will only contain assets for which the account has a nonzero balance.

vector<asset> graphene::wallet::wallet_api::list_account_balances(
    const string &id)
  • id: the name or id of the account whose balances you want

A list of the given account’s balances.

import json
from grapheneapi import GrapheneAPI
client = GrapheneAPI("localhost", 8092, "", "")
res = client.list_account_balances("dan")
print(json.dumps(res,indent=4))
[
    {
        "asset_id": "1.3.0",
        "amount": "331104701530"
    },
    {
        "asset_id": "1.3.511",
        "amount": 3844848635
    },
    {
        "asset_id": "1.3.427",
        "amount": 8638
    },
    {
        "asset_id": "1.3.536",
        "amount": 31957981
    }
]

transfer

Transfer an amount from one account to another.

signed_transaction graphene::wallet::wallet_api::transfer(
    string from, 
    string to, 
    string amount, 
    string asset_symbol, 
    string memo, 
    bool broadcast = false)
  • from: the name or id of the account sending the funds

  • to: the name or id of the account receiving the funds

  • amount: the amount to send (in nominal units to send half of a BTS, specify 0.5)

  • asset_symbol: the symbol or id of the asset to send

  • memo: a memo to attach to the transaction. The memo will be encrypted in the transaction and readable for the receiver. There is no length limit other than the limit imposed by maximum transaction size, but transaction increase with transaction size

  • broadcast: true to broadcast the transaction on the network

The final parameter True states that the signed transaction will be broadcast. If this parameter is False the transaction will be signed but not broadcast, hence not executed.

The signed transaction transferring funds.

import json
from grapheneapi import GrapheneAPI
client = GrapheneAPI("localhost", 8092, "", "")
res = client.transfer("fromaccount","toaccount","10", "USD", "$10 gift", True);
print(json.dumps(res,indent=4))
{
  "ref_block_num": 18,
  "ref_block_prefix": 2320098938,
  "expiration": "2015-10-13T13:56:15",
  "operations": [[
      0,{
        "fee": {
          "amount": 2089843,
          "asset_id": "1.3.0"
        },
        "from": "1.2.17",
        "to": "1.2.7",
        "amount": {
          "amount": 10000000,
          "asset_id": "1.3.0"
        },
        "memo": {
          "from": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
          "to": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
          "nonce": "16430576185191232340",
          "message": "74d0e455e2e5587b7dc85380102c3291"
        },
        "extensions": []
      }
    ]
  ],
  "extensions": [],
  "signatures": [
    "1f147aed197a2925038e4821da54bd7818472ebe25257ac9a7ea66429494e7242d0dc13c55c6840614e6da6a5bf65ae609a436d13a3174fd12f073550f51c8e565"
  ]
}

transfer2

This method works just like transfer, except it always broadcasts and returns the transaction ID (hash) along with the signed transaction.

pair<transaction_id_type, signed_transaction> graphene::wallet::wallet_api::transfer2(
    string from, 
    string to, 
    string amount, 
    string asset_symbol, 
    string memo)
  • from: the name or id of the account sending the funds

  • to: the name or id of the account receiving the funds

  • amount: the amount to send

  • asset_symbol: the symbol or id of the asset to send

  • memo: a memo to attach to the transaction. The memo will be encrypted in the transaction and readable for the receiver. There is no length limit other than the limit imposed by maximum transaction size, but transaction increase with transaction size

The transaction ID (hash) along with the signed transaction transferring funds

import json
from grapheneapi import GrapheneAPI
client = GrapheneAPI("localhost", 8092, "", "")
res = client.transfer2("fromaccount","toaccount","10", "USD", "$10 gift");
print(json.dumps(res,indent=4))
 [b546a75a891b5c51de6d1aafd40d10e91a717bb3,{
   "ref_block_num": 18,
   "ref_block_prefix": 2320098938,
   "expiration": "2015-10-13T13:56:15",
   "operations": [[
       0,{
         "fee": {
           "amount": 2089843,
           "asset_id": "1.3.0"
         },
         "from": "1.2.17",
         "to": "1.2.7",
         "amount": {
           "amount": 10000000,
           "asset_id": "1.3.0"
         },
         "memo": {
           "from": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
           "to": "GPH6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
           "nonce": "16430576185191232340",
           "message": "74d0e455e2e5587b7dc85380102c3291"
         },
         "extensions": []
       }
     ]
   ],
   "extensions": [],
   "signatures": [
     "1f147aed197a2925038e4821da54bd7818472ebe25257ac9a7ea66429494e7242d0dc13c55c6840614e6da6a5bf65ae609a436d13a3174fd12f073550f51c8e565"
   ]
 }
]

get_account_history

Returns the most recent operations on the named account.

This returns a list of operation history objects, which describe activity on the account.

vector<operation_detail> graphene::wallet::wallet_api::get_account_history(
    string name, 
    int limit)const
  • name: the name or id of the account

  • limit: the number of entries to return (starting from the most recent)

A list of operation_history_objects.

import json
from grapheneapi import GrapheneAPI
client = GrapheneAPI("localhost", 8092, "", "")
res = client.get_account_history("dan", 1)
print(json.dumps(res,indent=4))
[
     {
         "description": "fill_order_operation dan fee: 0 CORE",
         "op": {
             "block_num": 28672,
             "op": [
                 4,
                 {
                     "pays": {
                         "asset_id": "1.3.536",
                         "amount": 20000
                     },
                     "fee": {
                         "asset_id": "1.3.0",
                         "amount": 0
                     },
                     "order_id": "1.7.1459",
                     "account_id": "1.2.21532",
                     "receives": {
                         "asset_id": "1.3.0",
                         "amount": 50000000
                     }
                 }
             ],
             "id": "1.11.213277",
             "trx_in_block": 0,
             "virtual_op": 47888,
             "op_in_trx": 0,
             "result": [
                 0,
                 {}
             ]
         },
         "memo": ""
     }
 ]

get_object

Returns the blockchain object corresponding to the given id.

This generic function can be used to retrieve any object from the blockchain that is assigned an ID. Certain types of objects have specialized convenience functions to return their objects e.g., assets have get_asset(), accounts have get_account(), but this function will work for any object.

variant graphene::wallet::wallet_api::get_object(
    object_id_type id)const
  • id: the id of the object to return

The requested object.

import json
from grapheneapi import GrapheneAPI
client = GrapheneAPI("localhost", 8092, "", "")
res = client.get_object("1.11.213277")
print(json.dumps(res,indent=4))
{
    "trx_in_block": 0,
    "id": "1.11.213277",
    "block_num": 28672,
    "op": [
        4,
        {
            "fee": {
                "asset_id": "1.3.0",
                "amount": 0
            },
            "receives": {
                "asset_id": "1.3.0",
                "amount": 50000000
            },
            "pays": {
                "asset_id": "1.3.536",
                "amount": 20000
            },
            "account_id": "1.2.21532",
            "order_id": "1.7.1459"
        }
    ],
    "result": [
        0,
        {}
    ],
    "op_in_trx": 0,
    "virtual_op": 47888
}

get_asset

Returns information about the given asset.

extended_asset_object graphene::wallet::wallet_api::get_asset(
    string asset_name_or_id)const
  • asset_name_or_id: the symbol or id of the asset in question

The information about the asset stored in the block chain.

import json
from grapheneapi import GrapheneAPI
client = GrapheneAPI("localhost", 8092, "", "")
res = client.get_asset("USD")
print(json.dumps(res,indent=4))
{
    "symbol": "USD",
    "issuer": "1.2.1",
    "options": {
        "description": "1 United States dollar",
        "whitelist_authorities": [],
        "flags": 0,
        "extensions": [],
        "core_exchange_rate": {
            "quote": {
                "asset_id": "1.3.536",
                "amount": 11
            },
            "base": {
                "asset_id": "1.3.0",
                "amount": 22428
            }
        },
        "whitelist_markets": [],
        "max_supply": "1000000000000000",
        "blacklist_markets": [],
        "issuer_permissions": 79,
        "market_fee_percent": 0,
        "max_market_fee": "1000000000000000",
        "blacklist_authorities": []
    },
    "dynamic_asset_data_id": "2.3.536",
    "bitasset_data_id": "2.4.32",
    "id": "1.3.536",
    "precision": 4
}
Logo
Logo
https://docslocalcoinis.readthedocs.io/en/latest/api/index.htmldocslocalcoinis.readthedocs.io
GitHub - peerplays-network/peerplays: The Peerplays BlockchainGitHub
GitHub - cryptonomex/grapheneGitHub
GitHub - peerplays-network/python-peerplays: This is a communications library which allows interface with the Peerplays blockchain directly and without the need for a cli_wallet. It provides a wallet interface and can construct any kind of transactions and properly sign them for broadcast.GitHub

Gamified Proof of Stake (GPOS)

Introduction

Building on the success of the DPOS consensus mechanism, Peerplays introduced a unique enhancement called Gamified Proof of Stake (GPOS). This idea was first proposed as in January 2019.

The original intent of Peerplays was to operate as a Decentralized Autonomous Cooperative (DAC) where DPOS enables the voting collective of core token holders to determine who would act as Advisors, Witness, and Proposals within Peerplays. However, like other DPOS based blockchains, the challenges of voter turnout continue to plague Peerplays.

What Makes GPOS Different?

GPOS made a protocol change such that PPY token holders now receive a participation reward based on their voting performance and how many PPY they have vested or staked.

This is a significant change from the original protocol where token holders were rewarded with their share of a rake, taken from a percentage of the blockchain fees, and then distributed to token holders relative to their token holdings, regardless of any voting participation.

Put simply, this means that each PPY token holder needs to vest some, or close to all, of their PPY balance towards GPOS and then once a month vote for either Witnesses, Advisors or Proxies.

Why is GPOS Important?

Being a DPOS consensus blockchain, the importance of voter participation from the PPY token holders is paramount to the security of the blockchain. The introduction of GPOS ensures that token holders will take an active interest in the operation and governance of Peerplays.

Each vote cast impacts the people behind the successful operation of Peerplays, in particular the Witnesses. A Witness receiving high votes is much more likely to be elected as a block producing (active) Witness.

Under DPOS the Witness position is more secure because a lot less token holders are voting and subsequently it might just take one or two major PPY token holders to influence the election of a Witness. Under GPOS all token holders should participate making it a much more democratic process, and also receive rewards for voting.

Participation Rewards

Participation rewards combined with voting performance are what makes the Peerplays consensus mechanism gamified.

The rewards are calculated as follows:

Qualified Reward %

This is the percentage of a user's maximum possible reward received based on their voting performance. This reward decays at a rate of 16.67% per month. For example, if a token holder doesn't vote for a month the qualified reward percentage drops to 83.33% and if the token holder doesn't vote for six consecutive months the reward will be 0%.

Note: Complete decay was set at six consecutive months to coincide with the dividend distribution periods.

Below are the some of the key GPOS parameters that are currently set on mainnet.

GPOS period = 6 months(180 days)

GPOS sub-period = 30 days

GPOS lock-in period = 30 days

Vesting fee = 1PPY

Withdrawal fee = 0.01PPY

Estimated Rake Reward %

This is the potential percentage reward a user could receive based on the , the amount of PPY they have vested and their share of the total GPOS balance.

So the estimated rake reward is calculated as:

GPOS balance = b Total GPOS balance on blockchain = TB Qualified reward % = q

Estimated Rake Reward% = (b / TB) * q

For example:

A user has a GPOS balance of 1,000PPY and is entitled to 100% of their reward based on voting performance. The total GPOS balance on the blockchain is 4,000,000PPY.

The user would receive the following percentage of the rake:

(1,000 / 4,000,000) * 100% = 0.025%

So if the total (month) rake was 100,000PPY then the user would receive 25PPY.

GPOS related cli_wallet commands

create_vesting_balance account amount asset_symbol vesting_type broadcast

Creates vesting balance of GPOS type, enables user to participate in GPOS

Example:

vote_for_witness account witness approve broadcast

Cast or withdraw vote for a witness by given account. To keep user vesting performance, it is best for user to vote in each GPOS subperiod

Example:

withdraw_GPOS_vesting_balance account amount asset_symbol broadcast

Once the vesting period expires, user is able to collect his reward with withdraw_GPOS_vesting_balance command. User is not allowed to withdraw his balance before vesting period expires. Default GPOS vesting period is 30 days.

Example:

How to retrieve GPOS info

Some GPOS info is stored in global properties object. Retrieve GPO and inspect the following values - gpos_period, gpos_subperiod, gpos_period_start and gpos_vesting_lockin_period.

Example:

How to check account's last voting time

Account's last voting time is stored in account's statistic object. To retrieve the account statistic object, user needs account statistic object id, which is stored in account object.

Example:

create_vesting_balance account_name 50 PPY gpos true
# Cast a vote for a witness
vote_for_witness account_name witness_name true true

# Withdraw a vote for a witness
vote_for_witness account_name witness_name false true
withdraw_GPOS_vesting_balance account_name 10 PPY true
# Output is shortened, check out "extensions" section
get_global_properties 
{
  "id": "2.0.0",
  "parameters": {
...
    "maximum_tournament_start_delay": 604800,
    "maximum_tournament_number_of_wins": 100,
    "extensions": {
      "sweeps_distribution_percentage": 200,
      "sweeps_distribution_asset": "1.3.0",
      "sweeps_vesting_accumulator_account": "1.2.0",
      "gpos_period": 15552000,                   <----- Length of GPOS period (180 days)
      "gpos_subperiod": 2592000,                 <----- Length of GPOS subperiod (30 days)
      "gpos_period_start": 1609376400,           <----- Epoch time of last GPOS subperiod start (2020-12-31 1:00:00)
      "gpos_vesting_lockin_period": 2592000,     <----- GPOS Vesting period (30 days)
      "rbac_max_permissions_per_account": 5,
      "rbac_max_account_authority_lifetime": 15552000,
      "rbac_max_authorities_per_permission": 15,
      "account_roles_max_per_account": 20,
      "account_roles_max_lifetime": 31536000,
...
    }
  },
...
}
# Get the account object first, and retrieve statistic object id
get_account account_name
{
  "id": "1.2.20",
  "membership_expiration_date": "1970-01-01T00:00:00",
  "registrar": "1.2.18",
  "referrer": "1.2.18",
  "lifetime_referrer": "1.2.18",
  "network_fee_percentage": 2000,
  "lifetime_referrer_fee_percentage": 3000,
  "referrer_rewards_percentage": 0,
  "name": "account_name",
  ...
  "statistics": "2.6.20",          <--- HERE IT IS!!!
  "whitelisting_accounts": [],
  "blacklisting_accounts": [],
  "whitelisted_accounts": [],
  "blacklisted_accounts": [],
  "owner_special_authority": [
    0,{}
  ],
  "active_special_authority": [
    0,{}
  ],
  "top_n_control_flags": 0
}

# Retrieve the account's statistic object
get_object 2.6.20
[{
    "id": "2.6.20",
    "owner": "1.2.20",
    "name": "account_name",
    "most_recent_op": "2.9.0",
    "total_ops": 0,
    "removed_ops": 0,
    "total_core_in_orders": 0,
    "core_in_balance": "5000000000000",
    "has_cashback_vb": false,
    "is_voting": false,
    "lifetime_fees_paid": 0,
    "pending_fees": 0,
    "pending_vested_fees": 0,
    "last_vote_time": "1970-01-01T00:00:00"     <--- HERE IT IS
  }
]
Peerplays Improvement Proposal (PIP) #2
qualified reward percentage
GitHub - peerplays-network/peerplaysjs-lib: Javascript API for interacting with the Peerplays BlockchainGitHub
GitHub - peerplays-network/peerplaysjs-lib: Javascript API for interacting with the Peerplays BlockchainGitHub
Logo
Logo
Logo

NFT, Marketplace, HRP, and RBAC related Commands/Use Cases

Here we learn some commands and use cases related to NFT, Marketplace, HRP, and RBAC.

1. NFT Metadata Creation

nft_metadata_create(string owner_account_id_or_name, string name, string symbol, string base_uri, optional<string> revenue_partner, optional<uint16_t> revenue_split, bool is_transferable, bool is_sellable, optional<account_role_id_type> role_id, bool broadcast)

Example NFT metadata create command without permissions,

nft_metadata_create account01 "AVALON NAME" "AVALON SYMBOL" "AVALON BASE URI" account02 100 false true null true
  • account01 is the owner account of the metadata

  • “AVALON NAME” is the name of the NFT types created from the NFT metadata being created

  • “AVALON SYMBOL” is the symbol of the NFT types created from the NFT metadata being created. The symbol is reserved for future use.

  • “AVALON BASE URI” is the URI of the NFT types. Eg: avalonmeta.com

  • account02 is the revenue partner, this can be owner as well. Whenever the minted NFT is sold in the marketplace a split of the selling price goes to the revenue partner. The split can be specified in revenue_split parameter.

  • 100 is the revenue_split on the scale of 10000 being 100 percent. i.e. 100 is 1%

  • is_transferable specifies if the minted NFTs can be transferred by the owner of the NFT to other accounts

  • is_sellable specifies if the minted NFTs can be sold in the marketplace.

  • role_id is the resource permissions specifying the whitelisting accounts among which the NFTs can either be transferred or sold on marketplace.

  • broadcast either true or false, keeping it true will include the transaction in the upcoming block on the chain.

Example NFT metadata create command with permissions

First create a permission:

create_account_role(string owner_account_id_or_name, string name, string metadata, flat_set<int> allowed_operations, flat_set<account_id_type> whitelisted_accounts, time_point_sec valid_to, bool broadcast)

Example Permission:

create_account_role account01 "Avalon Permissions1" "Permission Metadata" [88,89,90,95] [1.2.40, 1.2.41] "2020-11-04T13:43:39" true
  • account01 is the owner of the permission being created which can be attached to NFT metadata.

  • “Avalon Permissions1” is the name of the resource permission being created.

  • “Permission Metadata” is the metadata, can be a JSON as well.

  • [88,89,90,95] is the list of operations this permission whitelists for accounts. 88 - List Offer operation in marketplace 89 - Bid operation in marketplace 90 - Cancel Offer operation in marketplace 95 - Safe transfer from owner to another NFT

  • [1.2.40, 1.2.41] List of accounts whitelisted for the above operations. Offer, bid and transfer operations can only be among the whitelisted accounts.

  • "2020-11-04T13:43:39" Expiry date of the permission

  • true broadcast, keep it true to include the transaction in upcoming block.

Example NFT metadata create command with permissions:

nft_metadata_create account01 "AVALON NAME" "AVALON SYMBOL" "AVALON BASE URI" account02 100 false true 1.32.0 true
  • 1.32.0 This is specified in the metadata create operation to attach permissions to all the NFTs created from this metadata.

NFT creation

NFT is always minted by the owner of the metadata object this NFT is based on. The fees associated with minting this NFT is just the transaction fee + storage fee which are both collected in core PPY token. After the NFT has been minted this can be sold on marketplace in any token of NFT owner’s choice.

Syntax:

nft_create(string metadata_owner_account_id_or_name, nft_metadata_id_type metadata_id, string owner_account_id_or_name, string approved_account_id_or_name, string token_uri, bool broadcast)

Example NFT creation based on the metadata created above:

nft_create account01 1.30.0 account02 account02 "AVALON NFT URI" true
  • account01 is the owner of the metadata this NFT is based on

  • 1.30.0 is the metadata ID of the metadata object this NFT is based on ( Currently this works on best guess method by doing get_object 1.30.0, 1.30.1, 1.30.2 …. so on, in future a new cli command will be introduced that can list all the metadata objects by owner account ).

  • account02 is the owner of the NFT, can be one of the user of the Avalon App.

  • account02 is the approved account of the NFT, can be the owner as well.

  • "AVALON NFT URI"is the URI that has additional information about this NFT.

NFT Safe Transfer from owner to other account

nft_safe_transfer_from(string operator_account_id_or_name, string from_account_id_or_name, string to_account_id_or_name, nft_id_type token_id, string data, bool broadcast)

Example command:

Note that NFTs can be transferred only when is_transferableflag is set to true, also if permissions are enabled both from and to accounts have to be whitelisted.

nft_safe_transfer_from account02 account02 account03 1.31.0 "Enjoy my NFT" true
  • account02 operator or owner account

  • account02 from account

  • account03 to account

  • 1.31.0 Id of the NFT

  • "Enjoy my NFT"is the metadata of the transfer

  • true is broadcast option mentioned above.

Create Market Listing Offer

create_offer(set<nft_id_type> item_ids, string issuer_accound_id_or_name, asset minimum_price, asset maximum_price, bool buying_item, time_point_sec offer_expiration_date, optional<memo_data> memo, bool broadcast)

Example command:

Note that is_sellable of NFT metadata should be true to make listing of the NFTs created from the metadata.

Only owner of the NFT can create a listing in auction.

create_offer ["1.31.0","1.31.1"] account02 {"amount":100,"asset_id":"1.3.0"} {"amount":10000,"asset_id":"1.3.0"} false "2020-08-18T11:05:39" null true 
  • ["1.31.0","1.31.1"] - List of NFTs to sell or buy

  • account02 is the owner of the NFTs

  • {"amount":100,"asset_id":"1.3.0"} minimum bid price expected

  • {"amount":10000,"asset_id":"1.3.0"} maximum bid price expected

  • false buying_item denotes if this is an auction or reverse auction

  • "2020-08-18T11:05:39" Listing expiry date

  • null Optional metadata, if not null assign a string value

  • true broadcast value mentioned above

Create Bid Offer

create_bid(string bidder_account_id_or_name, asset bid_price, offer_id_type offer_id, bool broadcast)

Example bid command:

create_bid account04 {"amount":10000,"asset_id":"1.3.0"} 1.29.0 true
  • account04 is the bidder

  • {"amount":10000,"asset_id":"1.3.0"} bid price

  • 1.29.0 Offer listing objected created from create_offer command

  • true broadcast value mentioned above

Cancel Offer

cancel_offer(string issuer_account_id_or_name, offer_id_type offer_id, bool broadcast)

Example cancel offer command:

cancel_offer account02 1.29.0 true
  • account02 is the creator of the listing

  • 1.29.0 is the offer object

  • true broadcast value mentioned above

List Offers

Returns all the sell and buy listings offer objects in the marketplace.

list_offers(uint32_t limit, optional<offer_id_type> lower_id)

Example command:

list_offers 100 1.29.0
  • 100 Number of items per fetch (pagination)

  • 1.29.0 Index to start the search for. (pagination)

Example command without pagination:

list_offers 100 null

List Sell Offers

Returns all the sell listing offer objects in the marketplace.

list_sell_offers(uint32_t limit, optional<offer_id_type> lower_id)

Example command:

list_sell_offers 10 1.29.6
  • 10 Number of items per fetch (pagination)

  • 1.29.6 Index to start the search for. (pagination)

Example command without pagination:

list_sell_offers 10 null

List Buy Offers

Returns all the buy listing offer objects in the marketplace. (Reverse Auction offer objects).

list_buy_offers(uint32_t limit, optional<offer_id_type> lower_id)

Example command:

list_buy_offers 10 1.29.6
  • 10 Number of items per fetch (pagination)

  • 1.29.6 Index to start the search for. (pagination)

Example command without pagination:

list_buy_offers 10 null

List Offer History

Returns all the closed auction and reverse auction listings. (offers)

list_offer_history(uint32_t limit, optional<offer_history_id_type> lower_id)

Example command:

list_offer_history 10 2.24.2
  • 10Number of items per fetch (pagination)

  • 2.24.2Index to start the search for. (pagination)

Example command without pagination:

list_offer_history 10 null

Get Offers by Issuer

Returns all the offers listed by an account.

get_offers_by_issuer(string issuer_account_id_or_name, uint32_t limit, optional<offer_id_type> lower_id)

Example command:

get_offers_by_issuer account02 10 1.29.0
  • account02 issuer

  • 10 Number of items per fetch (Pagination)

  • 1.29.0 Index to start the search for. (pagination)

Example command without pagination:

get_offers_by_issuer account02 10 null

Get Offers by NFT Item

get_offers_by_item(const nft_id_type item, uint32_t limit, optional<offer_id_type> lower_id)

Example command:

get_offers_by_item 1.31.0 10 1.29.1
  • 1.31.0 NFT Id

  • 10 Number of items per fetch (Pagination)

  • 1.29.1 Index to start the search for. (pagination)

Example command without pagination:

get_offers_by_item 1.31.0 10 null

Get Offer History by Issuer

get_offer_history_by_issuer(string issuer_account_id_or_name, uint32_t limit, optional<offer_history_id_type> lower_id)

Example command:

get_offer_history_by_issuer account06 10 2.24.1
  • account06 Issuer

  • 10 Number of items per fetch (Pagination)

  • 2.24.1 Index to start the search for. (pagination)

Example command without pagination:

get_offer_history_by_issuer account06 10 null

Get Offer History by NFT Item

get_offer_history_by_item(const nft_id_type item, uint32_t limit, optional<offer_history_id_type> lower_id)

Example Command:

get_offer_history_by_item 1.31.0 10 2.24.1
  • 1.31.0 NFT Id

  • 10 Number of items per fetch (Pagination)

  • 2.24.1 Index to start the search for. (pagination)

Example command without pagination:

get_offer_history_by_item 1.31.0 10 null

Get Offer History by Bidder

get_offer_history_by_bidder(string bidder_account_id_or_name, uint32_t limit, optional<offer_history_id_type> lower_id)

Example Command:

get_offer_history_by_bidder account07 10 2.24.1
  • account07 Bidder

  • 10 Number of items per fetch (Pagination)

  • 2.24.1 Index to start the search for. (pagination)

Example command without pagination:

get_offer_history_by_bidder account07 10 null

HRP User Authorities

Hierarchical role based permissions is a feature of Peerplays blockchain which helps in increasing the security of user accounts.

Users don’t have to use their active and owner keys for everything they do on the chain.

They can create role based custom permissions and map them to different keys other than active and owner keys.

They can then use these custom keys to sign transactions.

Create Custom Permissions

 create_custom_permission(string owner, string permission_name, authority auth, bool broadcast)
  • owner Owner of the account who is creating the custom permission

  • permission_name Permission name, eg. nftcreatepermission

  • auth authority is account authority, more info at permissions, public/private keys, multi authority

Example Command:

create_custom_permission account01 perm1 { "weight_threshold": 1,  "account_auths": [["1.2.52",1]], "key_auths": [["TEST71ADtL4fzjGKErk9nQJrABmCPUR8QCjkCUNfdmgY5yDzQGhwto",1]], "address_auths": [] } true

{ "weight_threshold": 1, "account_auths": [["1.2.52",1]], "key_auths": [["TEST71ADtL4fzjGKErk9nQJrABmCPUR8QCjkCUNfdmgY5yDzQGhwto",1]], "address_auths": [] }

This represents an authority structure, account_auths represent the amount of weight each accounts have on our account, in this example 1.2.52 has weight 1

key_auths represent the amount of weight each public key has on this account, in this example TEST71ADtL4fzjGKErk9nQJrABmCPUR8QCjkCUNfdmgY5yDzQGhwto has weight 1

Weight_threshold represent the required weight for a transaction to be signed successfully.

In this example either 1.2.52 can sign with his active key or TEST71ADtL4fzjGKErk9nQJrABmCPUR8QCjkCUNfdmgY5yDzQGhwto can be used to sign a transaction successfully.

Get Custom Permissions

get_custom_permissions(string owner)

Example Command,

get_custom_permissions account01

Update Custom Permissions

update_custom_permission(string owner, custom_permission_id_type permission_id, fc::optional<authority> new_auth, bool broadcast)

Example Command:

update_custom_permission account01 1.27.0 { "weight_threshold": 1,  "account_auths": [["1.2.53",1]], "key_auths": [], "address_auths": [] } true

Here we removed the key_auths and added 1.2.53 with weight 1, which is equal to weight_threshold , so 1.2.53 can alone sign the transaction successfully.

Create Custom Account Authority

Creating custom authority maps the created custom permissions with the actual operations present on the blockchain.

It also has expiry time by when this custom permission is no more valid on any given account and operation combination.

create_custom_account_authority(string owner, custom_permission_id_type permission_id, int operation_type, fc::time_point_sec valid_from, fc::time_point_sec valid_to, bool broadcast)

Example Command:

create_custom_account_authority account01 1.27.0 0 "2020-11-02T17:53:25" "2020-12-03T17:53:25" true

account01 is the owner of the account and the one who created a permission 1.27.0

1.27.0 is the custom permission created

0 is the operation number, refer to operations at operations, here 0 is transfer_operation

"2020-11-02T17:53:25" valid from timestamp

"2020-12-03T17:53:25" valid to timestamp

true broadcast

Basically this represents a full HRP where transfer operation on account01 can be done by authorities present in 1.27.0 instead of account owner account01

Update Custom Account Authority

Can be used to update existing valid_from and valid_to times,

update_custom_account_authority(string owner, custom_account_authority_id_type auth_id, fc::optional<fc::time_point_sec> new_valid_from, fc::optional<fc::time_point_sec> new_valid_to, bool broadcast)

Example command:

update_custom_account_authority account01 1.28.0 "2020-06-02T17:52:25" "2020-06-03T17:52:25" true

Delete Custom Permission

Used to delete the existing custom permission, this will delete all the custom account authorities linked to this permission as well.( cascading delete )

delete_custom_permission(string owner, custom_permission_id_type permission_id, bool broadcast)

Example command:

delete_custom_permission account01 1.27.0 true

Delete Custom Account Authority

Used to delete an account authority attached to a permission.

delete_custom_account_authority(string owner, custom_account_authority_id_type auth_id, bool broadcast)

Example command:

delete_custom_account_authority account01 1.28.0 true

Resource Permissions ( Account Roles )

As opposed to HRP mentioned above, resource permissions are controlled by an owner of a resource (eg. NFT metadata is a resource).

These are similar to IAM permissions in AWS Cloud environment.

Create Account Role

Used to create an account role.

create_account_role(string owner_account_id_or_name, string name, string metadata, flat_set<int> allowed_operations, flat_set<account_id_type> whitelisted_accounts, time_point_sec valid_to, bool broadcast)

owner_account_id_or_name resource owner Eg. account creating an NFT Metadata resource

name name of the account role Eg. Movie Interstellar Permissions

metadata metadata for additional info Eg. Some JSON struct or an external URL with info

allowed_operations allowed operations that whitelisted_accounts can perform on this resource.

whitelisted_accounts All the accounts that can perform any allowed_operations on a resource

valid_to exports time of the account role, valid from is the time of creation of the account role

broadcast broadcast mentioned above

Currently valid allowed_operations are

offer_operation(88), Checks if the user who is listing an NFT for sale is in whitelisted_accounts , if not the user can’t list the NFTs in marketplace.

bid_operation(89), Checks if the user who is bidding for an NFT on sale is in whitelisted_accounts , if not the user can’t bid / buy the NFT from marketplace.

nft_safe_transfer_from_operation (95), Checks if the user who transferring i.e. owner is in whitelisted_accounts, if yes it checks the to-account is also in the whitelisted_accounts. If any of the two checks fail, the transfer fails.

More operations like NFT Lottery, RNG are to be attached to account roles.

Example Command:

create_account_role account01 ar1 ar1 [89,95] [1.2.40, 1.2.41, 1.2.43] "2020-09-04T13:43:39" true

This command effectively limits any NFT to be sold or transferred between only three accounts, 1.2.40, 1.2.41, 1.2.43

For attaching NFT metadata to an account role, please refer to the above NFT sections.

Get Account Roles

get_account_roles_by_owner(string owner_account_id_or_name)

Example command:

get_account_roles_by_owner account01

Update Account Role

As a resource owner, one can update the operations and whitelisted accounts present in an account role.

This helps in blacklisting any users from selling or transferring NFTs or any resources.

update_account_role(string owner_account_id_or_name, account_role_id_type role_id, optional<string> name, optional<string> metadata, flat_set<int> operations_to_add, flat_set<int> operations_to_remove, flat_set<account_id_type> accounts_to_add, flat_set<account_id_type> accounts_to_remove, optional<time_point_sec> valid_to, bool broadcast)

operations_to_add new operations to add to the account role

operations_to_remove existing operations to remove from the account role

accounts_to_add new accounts to add to the whitelist

accounts_to_remove existing accounts to remove from the whitelist

Example command:

update_account_role account01 1.32.0 null null [88] [95] [1.2.42] [1.2.40] "2020-09-04T13:52:38" true

88 offer_operation(88) is added

95 nft_safe_transfer_from_operation is removed

1.2.42 account to the whitelist

1.2.40 account removed from the whitelist

Delete Account Role

Once account role is deleted, restrictions on resource access no longer work.

delete_account_role(string owner_account_id_or_name, account_role_id_type role_id, bool broadcast)

Example command:

delete_account_role account01 1.32.0 true

Fee Considerations

PPY is the core token of peerplays blockchain. Blockchain users can issue their own tokens with a conversion rate to core token.

In the Peerplays blockchain, every operation executed has a fee associated with it. The majority of these fees go as payments to witnesses that run the blockchain. These fees are called transaction fees and are collected in core (PPY) tokens only.

There is also a fee for storing any data on the blockchain like metadata or names.

Currently for the operations related to NFT, Marketplace, HRP, and Account Roles:

 ID     Operation Name                              Fees (in PPY)
 82	custom_permission_create_operation__________0.005 + 0.01 per Kb data
 83	custom_permission_update_operation__________0.005
 84	custom_permission_delete_operation__________0.005
 85	custom_account_authority_create_operation___0.005 + 0.01 per Kb data
 86	custom_account_authority_update_operation___0.005
 87	custom_account_authority_delete_operation___0.005
 88	offer_operation_____________________________0.001 + 0.01 per Kb data
 89	bid_operation_______________________________0.001
 90	cancel_offer_operation______________________0.001
 91	finalize_offer_operation____________________0.0 (Free!)
 92	nft_metadata_create_operation_______________0.1  + 0.01 per Kb data
 93	nft_metadata_update_operation_______________0.1
 94	nft_mint_operation__________________________0.01 + 0.01 per Kb data
 95	nft_safe_transfer_from_operation____________0.01 + 0.01 per Kb data
 96	nft_approve_operation_______________________0.005
 97	nft_set_approval_for_all_operation__________0.005
 98	account_role_create_operation_______________1.0  + 1.00 per Kb data
 99	account_role_update_operation_______________1.0  + 1.00 per Kb data
 100	account_role_delete_operation_______________1.0

These values are subject to change by committee members.

NFT Notes

  • In order to create an NFT, a metadata has to be created first.

  • Only the owner of the metadata can mint NFTs

  • These NFTs can be assigned to any user of metadata owner’s choice.

  • NFT Metadata owner is the owner of the metadata that mints the NFTs, NFT owner is the one who is assigned an NFT by metadata owner after minting.

  • User who is not the metadata owner cannot mint NFTs to himself

  • is_transferable and is_sellable flags configured on metadata control the transfer and selling properties of all the NFTs minted from the metadata.

  • If is_transferable is false and is_sellable is true, then the NFT owner can only list it in marketplace and sell it. He can’t transfer to another user.

  • If is_transferable is true and is_sellable is false, then the NFT owner cannot list it in marketplace and he can freely transfer it to other users.

  • If is_transferable is false and is_sellable is false, then the NFT owner can neither be transfer nor sell the NFT. It remains with him forever.

Marketplace Notes

  • Peerplays blockchain operates the marketplace through offer_operation, bid_operation, cancel_offer_operation, finalize_offer_operation operations/smart contracts.

  • Offers operate as an auction where max bid before the expiry time owns the NFT

  • If max_price is equal to min_price in offer_operation it acts as normal listing. Whoever bids the max_price gets the NFT instantly.

  • For a successful bid, revenue_partner gets the revenue_split percent of the bid. This is configured during NFT metadata creation. So for all the NFT sales that are based on the metadata, revenue_partner gets the cut.

  • Currently peerplays stakeholders don’t get the cut, this will be implemented in the future.

  • Currently there is only one marketplace i.e. Peerplays blockchain is providing a marketplace where any owner can sell his NFT based on the configuration of the parent metadata.

  • Metadata owner can customize this marketplace in the UI to show only the NFTs minted from his own metadata to his DAPP users.

  • So there are no multiple marketplaces on peerplays blockchain at the moment, only UI customization are possible.

  • Price can be set in terms of custom assets (tokens) in market place. In this case both offers and bids should be in the same asset (token). Eg. Offer price is in XCOIN token, then bid price should also be in XCOIN token.

Use Cases

Movie Tickets (For Blockchain Savvy Users)

  • I’m the owner of a movie theater where there is a premiere show for a movie Interstellar.

  • I create NFT metadata for Interstellar movie that has basic info about the genre, running time, movie posters etc

  • To maximize my profit and take a cut from the black market ticket sales, I created the metadata of the movie is_transferable to false and is_sellable to true

  • I accept payment on the blockchain in multiple currencies namely PPY, XCOIN and BTC (or some off chain mechanism in FIAT currencies like USD)

  • I mint the tickets as NFTs to the users who sent me the amount in the above currencies. Users can gain entry to the movie only with these NFT tickets.

  • Users cannot transfer the tickets among themselves, they can only list them on marketplace.

  • As the demand for tickets increase, listing price increase, so I get more cut for every ticket sold.

NFT Lottery with Geolocation restrictions (Account Roles/ Resource Permission use case)

  • I’m the issuer of the lottery which has geo restrictions saying the lottery can only be sold to residents of the state New South Wales(NSW) in Australia.

  • I do the KYC check off chain and list down all the users on the blockchain that are residents of the state.

  • While creating NFT metadata I attach the account roles with the whitelist of users along with is_transferable to true and is_sellable to false.

  • I create a smart contract for minting NFTs from the metadata created.

  • This smart contract accesses the account role associated with the metadata.

  • If any user is not whitelisted he can’t purchase the NFT lottery ticket from the smart contract.

  • If the user is whitelisted and minted a lottery ticket, he can’t transfer it to non-whitelisting users who are not residents of NSW.

  • I create a draw and declare the owner of NFT as winner.

University Degrees

  • I’m the university issuing degrees to students that complete masters degree in two streams science and arts.

  • I create two NFT metadata one each for both Science and Arts.

  • I make both is_transferable to false and is_sellable to false.

  • I mint NFT accordingly based on the stream to each student.

  • Each NFT (degree) has the info about the student grades, courses etc.

  • These NFTs (degrees) stays with the students (users) forever, they can’t be transferred or sold.

Minting NFTs (For not so Blockchain Savvy Users)

  • I’m the owner of an NFT Metadata and my DAPP users are not blockchain savvy.

  • I mint the NFTs to my account itself.

  • I modify the URI of NFTs accordingly off chain to denote the ownership.

Example NFT creation

Core coin : PPY for fee

Purchase/Sell/Transaction token for NFTs : ava-token

PPY:ava-token = 1:10000

Logo
Logo

Database API

The database API is available from the full node via web-sockets.

Objects

get_objects

Get the objects corresponding to the provided IDs.

If any of the provided IDs does not map to an object, a null variant is returned in its position.

fc::variants graphene::app::database_api::get_objects(
    const vector<object_id_type> &ids, 
    optional<bool> subscribe = optional<bool>())const
  • ids: IDs of the objects to retrieve

  • subscribe: true to subscribe to the queried objects; false to not subscribe; null to subscribe or not subscribe according to current auto-subscription setting (see set_auto_subscription)

The objects retrieved, in the order they are mentioned in ids.

Subscriptions

set_subscribe_callback

Register a callback handle which then can be used to subscribe to object database changes.

Note: auto-subscription is enabled by default and can be disabled with set_auto_subscription

void graphene::app::database_api::set_subscribe_callback(
    std::function<void(const variant&)> cb, 
    bool notify_remove_create, )
  • cb: The callback handle to register

  • notify_remove_create: Whether subscribe to universal object creation and removal events. If this is set to true, the API server will notify all newly created objects and ID of all newly removed objects to the client, no matter whether client subscribed to the objects. By default, API servers don’t allow subscribing to universal events, which can be changed on server startup.

set_pending_transaction_callback

Register a callback handle which will get notified when a transaction is pushed to database.

Note: A transaction can be pushed to the database and be popped from the database several times while processing, before and after,, included in a block. Every time a push is done, the client will be notified.

void graphene::app::database_api::set_pending_transaction_callback(
    std::function<void(const variant &signed_transaction_object)> cb)
  • cb: The callback handle to register

set_block_applied_callback

Register a callback handle which will get notified when a block is pushed to database.

void graphene::app::database_api::set_block_applied_callback(
    std::function<void(const variant &block_id)> cb)
  • cb: The callback handle to register

cancel_all_subscriptions

Stop receiving any notifications.

This unsubscribes from all subscribed markets and objects.

void graphene::app::database_api::cancel_all_subscriptions()

Blocks and transactions

get_block_header

Retrieve a block header.

optional<block_header> graphene::app::database_api::get_block_header(
    uint32_t block_num)const
  • block_num: Height of the block whose header should be returned

  • The header of the referenced block, or null if no matching block was foun

get_block

Retrieve a full, signed block.

optional<signed_block> graphene::app::database_api::get_block(
    uint32_t block_num)const
  • block_num: Height of the block to be returned

The referenced block, or null if no matching block was found.

get_transaction

Fetch an individual transaction.

processed_transaction graphene::app::database_api::get_transaction(
    uint32_t block_num, uint32_t trx_in_block)const
  • block_num: height of the block to fetch

  • trx_in_block: the index (sequence number) of the transaction in the block, starts from 0

The transaction at the given position.

get_recent_transaction_by_id

optional<signed_transaction> graphene::app::database_api::get_recent_transaction_by_id(
    const transaction_id_type &txid)const
  • txid: hash of the transaction

The corresponding transaction if found, or null if not found.

If the transaction has not expired, this method will return the transaction for the given ID or it will return NULL if it is not known. Just because it is not known does not mean it wasn’t included in the blockchain.

Globals

get_chain_properties

Retrieve the graphene::chain::chain_property_object associated with the chain.

chain_property_object graphene::app::database_api::get_chain_properties()const

get_global_properties

Retrieve the current graphene::chain::global_property_object.

global_property_object graphene::app::database_api::get_global_properties()const

get_config

Retrieve compile-time constants.

fc::variant_object graphene::app::database_api::get_config()const

get_chain_id

Get the chain ID.

chain_id_type graphene::app::database_api::get_chain_id()cons

get_dynamic_global_properties

Retrieve the current graphene::chain::dynamic_global_property_object.

dynamic_global_property_object graphene::app::database_api::get_dynamic_global_properties()const

Keys

get_key_references

Get all accounts that refer to the specified public keys in their owner authority, active authorities or memo key.

vector<flat_set<account_id_type>> graphene::app::database_api::get_key_references(
    vector<public_key_type> keys)const
  • keys: a list of public keys to query

ID of all accounts that refer to the specified keys.

Accounts

get_accounts

Get a list of accounts by names or IDs.

This function has semantics identical toget_objects

vector<optional<account_object>> graphene::app::database_api::get_accounts(
    const vector<std::string> &account_names_or_ids, 
    optional<bool> subscribe = optional<bool>())const
  • account_names_or_ids: names or IDs of the accounts to retrieve

  • subscribe: true to subscribe to the queried account objects; false to not subscribe; null to subscribe or not subscribe according to current auto-subscription setting (see set_auto_subscription)

The accounts corresponding to the provided names or IDs.

get_full_accounts

Fetch all objects relevant to the specified accounts and optionally subscribe to updates.

This function fetches all relevant objects for the given accounts, and subscribes to updates to the given accounts. If any of the strings innames_or_ids cannot be tied to an account, that input will be ignored. All other accounts will be retrieved and subscribed.

std::map<string, full_account> graphene::app::database_api::get_full_accounts(
    const vector<string> &names_or_ids, 
    optional<bool> subscribe = optional<bool>())
  • names_or_ids: Each item must be the name or ID of an account to retrieve

  • subscribe: true to subscribe to the queried full account objects; false to not subscribe; null to subscribe or not subscribe according to current auto-subscription setting (see set_auto_subscription)

Map of string from names_or_ids to the corresponding account.

get_account_by_name

Get info of an account by name.

optional<account_object> graphene::app::database_api::get_account_by_name(
    string name)const
  • name: Name of the account to retrieve

The account holding the provided name.

get_account_references

Get all accounts that refer to the specified account in their owner or active authorities.

vector<account_id_type> graphene::app::database_api::get_account_references(
    const std::string account_name_or_id)const
  • account_name_or_id: Account name or ID to query

All accounts that refer to the specified account in their owner or active authorities

lookup_account_names

Get a list of accounts by name.

This function has semantics identical to get_objects, but doesn’t subscribe

vector<optional<account_object>> graphene::app::database_api::lookup_account_names(
    const vector<string> &account_names)const
  • account_names: Names of the accounts to retrieve

The accounts holding the provided names.

lookup_accounts

Get names and IDs for registered accounts.

Note: In addition to the common auto-subscription rules, this API will subscribe to the returned account only if limit is 1.

map<string, account_id_type> graphene::app::database_api::lookup_accounts(
    const string &lower_bound_name, 
    uint32_t limit, 
    optional<bool> subscribe = optional<bool>())const
  • lower_bound_name: Lower bound of the first name to return

  • limit: Maximum number of results to return must not exceed 1000

  • subscribe: true to subscribe to the queried account objects; false to not subscribe; null to subscribe or not subscribe according to current auto-subscription setting (see set_auto_subscription).

Map of account names to corresponding IDs.

get_account_count

Get the total number of accounts registered with the blockchain.

uint64_t graphene::app::database_api::get_account_count()const

Balances

get_account_balances

Get an account’s balances in various assets.

vector<asset> graphene::app::database_api::get_account_balances(
    const std::string &account_name_or_id, 
    const flat_set<asset_id_type> &assets)const
  • account_name_or_id: name or ID of the account to get balances for.

  • assets: IDs of the assets to get balances of; if empty, get all assets account has a balance in.

Balances of the account.

get_named_account_balances

Semantically equivalent to get_account_balances.

vector<asset> graphene::app::database_api::get_named_account_balances(
    const std::string &name, 
    const flat_set<asset_id_type> &assets)const
  • account_name_or_id: name or ID of the account to get balances for.

  • assets: IDs of the assets to get balances of; if empty, get all assets account has a balance in.

Balances of the account.

get_balance_objects

vector<balance_object> graphene::app::database_api::get_balance_objects(
    const vector<address> &addrs)const
  • addrs: a list of addresses

All unclaimed balance objects for the addresses.

get_vested_balances

Calculate how much assets in the given balance objects are able to be claimed at current head block time.

vector<asset> graphene::app::database_api::get_vested_balances(
    const vector<balance_id_type> &objs)const
  • objs: a list of balance object IDs

A list indicating how much asset in each balance object is available to be claimed.

get_vesting_balances

Return all vesting balance objects owned by an account.

vector<vesting_balance_object> graphene::app::database_api::get_vesting_balances(
    const std::string account_name_or_id)const
  • account_name_or_id: name or ID of an account

All vesting balance objects owned by the account.

Assets

get_assets

Get a list of assets by symbol names or IDs.

Semantically equivalent to get_objects.

vector<optional<extended_asset_object>> graphene::app::database_api::get_assets(
    const vector<std::string> &asset_symbols_or_ids, 
    optional<bool> subscribe = optional<bool>())const
  • asset_symbols_or_ids: symbol names or IDs of the assets to retrieve

  • subscribe: true to subscribe to the queried asset objects; false to not subscribe; null to subscribe or not subscribe according to current auto-subscription setting (see set_auto_subscription)

The assets corresponding to the provided symbol names or IDs.

list_assets

Get assets alphabetically by symbol name.

vector<extended_asset_object> graphene::app::database_api::list_assets(
    const string &lower_bound_symbol, 
    uint32_t limit)const
  • lower_bound_symbol: Lower bound of symbol names to retrieve

  • limit: Maximum number of assets to fetch (must not exceed 101)

The assets found.

lookup_asset_symbols

Get a list of assets by symbol names or IDs.

Semantically equivalent to get_objects, but doesn’t subscribe.

vector<optional<extended_asset_object>> graphene::app::database_api::lookup_asset_symbols(
    const vector<string> &symbols_or_ids)const
  • symbols_or_ids: symbol names or IDs of the assets to retrieve

The assets corresponding to the provided symbols or IDs

Markets / Feeds

get_order_book

Returns the order book for the market base

order_book graphene::app::database_api::get_order_book(
    const string &base, 
    const string &quote, 
    unsigned limit = 50)const
  • base: symbol name or ID of the base asset

  • quote: symbol name or ID of the quote asset

  • limit: depth of the order book to retrieve, for bids and asks each, capped at 50

Order book of the market.

get_limit_orders

Get limit orders in a given market.

vector<limit_order_object> graphene::app::database_api::get_limit_orders(
    std::string a, 
    std::string b, 
    uint32_t limit)const
  • a: symbol or ID of asset being sold

  • b: symbol or ID of asset being purchased

  • limit: Maximum number of orders to retrieve

The limit orders, ordered from least price to greatest.

get_call_orders

Get call orders (aka margin positions) for a given asset.

vector<call_order_object> graphene::app::database_api::get_call_orders(
    const std::string &a, 
    uint32_t limit)const
  • a: symbol name or ID of the debt asset

  • limit: Maximum number of orders to retrieve

The call orders, ordered from earliest to be called to latest

get_settle_orders

Get forced settlement orders in a given asset.

vector<force_settlement_object> graphene::app::database_api::get_settle_orders(
    const std::string &a, 
    uint32_t limit)const
  • a: Symbol or ID of asset being settled

  • limit: Maximum number of orders to retrieve

The settle orders, ordered from earliest settlement date to latest.

get_margin_positions

Get all open margin positions of a given account.

Similar to get_call_orders_by_account, but without pagination.

vector<call_order_object> graphene::app::database_api::get_margin_positions(
    const std::string account_name_or_id)const
  • account_name_or_id: name or ID of an account

All open margin positions of the account.

subscribe_to_market

Request notification when the active orders in the market between two assets changes.

Callback will be passed a variant containing a vector<pair<operation, operation_result>>.

The vector will contain, in order, the operations which changed the market, and their results

void graphene::app::database_api::subscribe_to_market(std::function<void(
    const variant&)> callback, 
    const std::string &a, 
    const std::string &b, )
  • callback: Callback method which is called when the market changes

  • a: symbol name or ID of the first asset

  • b: symbol name or ID of the second asset

unsubscribe_from_market

Unsubscribe from updates to a given market.

void graphene::app::database_api::unsubscribe_from_market(
    const std::string &a, 
    const std::string &b)
  • a: symbol name or ID of the first asset

  • b: symbol name or ID of the second asset

get_ticker

Returns the ticker for the market assetA:assetB.

market_ticker graphene::app::database_api::get_ticker(
    const string &base, 
    const string &quote)const
  • base: symbol name or ID of the base asset

  • quote: symbol name or ID of the quote asset

The market ticker for the past 24 hours.

get_24_volume

Returns the 24 hour volume for the market assetA:assetB.

market_volume graphene::app::database_api::get_24_volume(
    const string &base, 
    const string &quote)const
  • base: symbol name or ID of the base asset

  • quote: symbol name or ID of the quote asset

The market volume over the past 24 hours.

get_trade_history

Returns recent trades for the market base:quote, ordered by time, most recent first.

Note: Currently, timezone offsets are not supported. The time must be UTC.

The range is [stop, start). In case there are more than 100 trades occurring in the same second, this API only returns the first 100 records; use get_trade_history_by_sequence to query for the rest.

vector<market_trade> graphene::app::database_api::get_trade_history(
    const string &base, 
    const string &quote, 
    fc::time_point_sec start, 
    fc::time_point_sec stop, 
    unsigned limit = 100)const
  • base: symbol or ID of the base asset

  • quote: symbol or ID of the quote asset

  • start: Start time as a UNIX timestamp, the latest trade to retrieve

  • stop: Stop time as a UNIX timestamp, the earliest trade to retrieve

  • limit: Number of transactions to retrieve, capped at 100.

Recent transactions in the market

Witnesses

get_witnesses

Get a list of witnesses by ID.

Semantically equivalent to get_objects, but doesn’t subscribe.

vector<optional<witness_object>> graphene::app::database_api::get_witnesses(
    const vector<witness_id_type> &witness_ids)const
  • witness_ids: IDs of the witnesses to retrieve

The witnesses corresponding to the provided IDs.

get_witness_by_account

Get the witness owned by a given account.

fc::optional<witness_object> graphene::app::database_api::get_witness_by_account(
    const std::string account_name_or_id)const
  • account_name_or_id: The name or ID of the account whose witness should be retrieved

The witness object, or null if the account does not have a witness.

lookup_witness_accounts

Get names and IDs for registered witnesses.

map<string, witness_id_type> graphene::app::database_api::lookup_witness_accounts(
    const string &lower_bound_name, uint32_t limit)const
  • lower_bound_name: Lower bound of the first name to return

  • limit: Maximum number of results to return must not exceed 1000

Map of witness names to corresponding IDs.

get_witness_count

Get the total number of witnesses registered with the blockchain.

uint64_t graphene::app::database_api::get_witness_count()const

Committee members

get_committee_members

Get a list of committee_members by ID.

Semantically equivalent to get_objects, but doesn’t subscribe.

vector<optional<committee_member_object>> graphene::app::database_api::get_committee_members(
    const vector<committee_member_id_type> &committee_member_ids)const
  • committee_member_ids: IDs of the committee_members to retrieve

The committee_members corresponding to the provided IDs.

get_committee_member_by_account

Get the committee_member owned by a given account.

fc::optional<committee_member_object> graphene::app::database_api::get_committee_member_by_account(
    const string account_name_or_id)const
  • account_name_or_id: The name or ID of the account whose committee_member should be retrieved

The committee_member object, or null if the account does not have a committee_member.

lookup_committee_member_accounts

Get names and IDs for registered committee_members.

map<string, committee_member_id_type> graphene::app::database_api::lookup_committee_member_accounts(
    const string &lower_bound_name, 
    uint32_t limit)const
  • lower_bound_name: Lower bound of the first name to return

  • limit: Maximum number of results to return must not exceed 1000

Map of committee_member names to corresponding IDs

Workers

get_workers_by_account

Get the workers owned by a given account.

vector<optional<worker_object>> graphene::app::database_api::get_workers_by_account(
    const std::string account_name_or_id)const
  • account_name_or_id: The name or ID of the account whose worker should be retrieved

A list of worker objects owned by the account.

Votes

lookup_vote_ids

Given a set of votes, returns the objects they are voting for.

This will be a mixture of committee_member_objects, witness_objects, and worker_objects

vector<variant> graphene::app::database_api::lookup_vote_ids(
    const vector<vote_id_type> &votes)const
  • votes: a list of vote IDs

The referenced objects

The results will be in the same order as the votes. Null will be returned for any vote IDs that are not found.

Authority / Validation

get_transaction_hex

Get a hexdump of the serialized binary form of a transaction.

std::string graphene::app::database_api::get_transaction_hex(
    const signed_transaction &trx)const
  • trx: a transaction to get hexdump from

The hexdump of the transaction.

get_required_signatures

This API will take a partially signed transaction and a set of public keys that the owner has the ability to sign for and return the minimal subset of public keys that should add signatures to the transaction.

set<public_key_type> graphene::app::database_api::get_required_signatures(
    const signed_transaction &trx, 
    const flat_set<public_key_type> &available_keys)const
  • trx: the transaction to be signed

  • available_keys: a set of public keys

A subset of available_keys that could sign for the given transaction.

get_potential_signatures

This method will return the set of all public keys that could possibly sign for a given transaction. This call can be used by wallets to filter their set of public keys to just the relevant subset prior to calling get_required_signatures to get the minimum subset.

set<public_key_type> graphene::app::database_api::get_potential_signatures(
    const signed_transaction &trx)const
  • trx: the transaction to be signed

A set of public keys that could possibly sign for the given transaction.

get_potential_address_signatures

This method will return the set of all addresses that could possibly sign for a given transaction.

set<address> graphene::app::database_api::get_potential_address_signatures(
    const signed_transaction &trx)const
  • trx: the transaction to be signed

A set of addresses that could possibly sign for the given transaction.

verify_authority

Check whether a transaction has all of the required signatures

bool graphene::app::database_api::verify_authority(
    const signed_transaction &trx)const
  • trx: a transaction to be verified

true if the trx has all of the required signatures, otherwise throws an exception.

verify_account_authority

Verify that the public keys have enough authority to approve an operation for this account.

bool graphene::app::database_api::verify_account_authority(
    const string &account_name_or_id, 
    const flat_set<public_key_type> &signers)const
  • account_name_or_id: name or ID of an account to check

  • signers: the public keys

true if the passed in keys have enough authority to approve an operation for this account.

validate_transaction

Validates a transaction against the current state without broadcasting it on the network.

processed_transaction graphene::app::database_api::validate_transaction(
const signed_transaction &trx)const
  • trx: a transaction to be validated

A processed_transaction object if the transaction passes the validation, otherwise an exception will be thrown.

get_required_fees

For each operation calculate the required fee in the specified asset type.

vector<fc::variant> graphene::app::database_api::get_required_fees(
    const vector<operation> &ops, 
    const std::string &asset_symbol_or_id)const
  • ops: a list of operations to be query for required fees

  • asset_symbol_or_id: symbol name or ID of an asset that to be used to pay the fees

A list of objects which indicates required fees of each operation

Proposed Transactions

get_proposed_transactions

Gets a set of proposed transactions (proposals) that the specified account can add approval to or remove approval from.

vector<proposal_object> graphene::app::database_api::get_proposed_transactions(
    const std::string account_name_or_id)const
  • account_name_or_id: The name or ID of an account

A set of proposed transactions that the specified account can act on.

Blinded balances

get_blinded_balances

Gets the set of blinded balance objects by commitment ID.

vector<blinded_balance_object> graphene::app::database_api::get_blinded_balances(
    const flat_set<commitment_type> &commitments)const
  • commitments: a set of commitments to query for

The set of blinded balance objects by commitment ID.