PRC20

PRC20: The Standard for PowBlocks Tokens.

PRC20: The Standard for PowBlocks Tokens

As the blockchain space evolved, standards became vital for interoperability, consistency, and ease of integration. Ethereum gave us the ERC20 standard, which quickly became the benchmark for token implementations. PowBlocks, in its pursuit of excellence and compatibility, introduced its own version: the PRC20.

1. What is PRC20?

PRC20 is a token standard on the PowBlocks blockchain. It defines a set of rules that a token contract must implement to ensure consistent interaction across various platforms, DApps, and interfaces. This standard ensures that different tokenized assets on PowBlocks can be handled similarly, eliminating the complexities of dealing with diverse custom token functionalities.

2. Key Features of PRC20 Tokens:

  • Uniformity: All PRC20 tokens follow the same set of rules. This means they have the same methods and properties, ensuring uniformity across all token contracts on the PowBlocks blockchain.

  • Interoperability: Due to their standardized nature, PRC20 tokens can be easily integrated with existing applications, wallets, exchanges, and other services with minimal adjustments.

  • Simplicity: Developers familiar with Ethereum's ERC20 will find it straightforward to work with PRC20. The standards share many similarities, making the transition or parallel development on PowBlocks more accessible.

3. Essential Functions of PRC20:

The PRC20 standard encompasses several functions, including but not limited to:

  • totalSupply(): Returns the total token supply.

  • balanceOf(address _owner): Returns the token balance of a specific address.

  • transfer(address _to, uint256 _value): Transfers a specific token amount to a given address.

  • transferFrom(address _from, address _to, uint256 _value): Allows for token transfers on behalf of a user, given that they've provided approval.

  • approve(address _spender, uint256 _value): Approves a third-party, like a DApp, to transfer tokens up to a specified amount.

  • allowance(address _owner, address _spender): Returns the amount of tokens a spender is allowed to transfer on behalf of an owner.

4. Events in PRC20:

For frontend applications and DApps to interact and react to changes, PRC20 tokens emit events, such as:

  • Transfer(address indexed _from, address indexed _to, uint256 _value): Emitted when tokens are transferred.

  • Approval(address indexed _owner, address indexed _spender, uint256 _value): Emitted when approval is granted to spend tokens on behalf of an owner.

5. Compatibility with EVM:

Given that PowBlocks supports the Ethereum Virtual Machine (EVM), the PRC20 standard is designed to be familiar to developers from the Ethereum ecosystem. This ensures that porting applications between the two blockchains remains streamlined.

In essence, the PRC20 standard is a testament to PowBlocks' commitment to a seamless and developer-friendly environment. Whether you're looking to mint a new token, integrate with an existing one, or develop sophisticated DApps, the PRC20 offers a reliable foundation for your endeavors on the PowBlocks blockchain.

PRC20 Contract Example:

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.6;

interface PRC20 {
    function totalSupply() external view returns (uint);
    function balanceOf(address who) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);
    function transfer(address to, uint value) external returns (bool);
    function approve(address spender, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);
    event Transfer(address indexed from, address indexed to, uint value);
    event Approval(address indexed owner, address indexed spender, uint value);
}

interface ApproveAndCallFallBack {
    function receiveApproval(address from, uint tokens, address token, bytes calldata data) external;
}

contract PRC20Token is PRC20 {
  using SafeMath for uint256;
  mapping (address => uint256) private balances;
  mapping (address => mapping (address => uint256)) private allowed;
  string public constant name  = "Fun Token"; // Token name
  string public constant symbol = "FUN"; // Token ticker
  uint8 public constant decimals = 18;
  address deployer;
  uint256 _totalSupply = 100000 * 10**18; // Total supply

  constructor()  {
    deployer = msg.sender;
    balances[deployer] = _totalSupply;
    emit Transfer(address(0), deployer, _totalSupply);
  }

  function totalSupply() public view override returns (uint256) {
    return _totalSupply;
  }

  function balanceOf(address addr) public view override returns (uint256) {
    return balances[addr];
  }

  function allowance(address addr, address spender) public view override returns (uint256) {
    return allowed[addr][spender];
  }

  function transfer(address to, uint256 value) public override returns (bool) {
    require(value <= balances[msg.sender]);
    require(to != address(0));

    balances[msg.sender] = balances[msg.sender].sub(value);
    balances[to] = balances[to].add(value);

    emit Transfer(msg.sender, to, value);
    return true;
  }

  function multiTransfer(address[] memory receivers, uint256[] memory amounts) public {
    for (uint256 i = 0; i < receivers.length; i++) {
      transfer(receivers[i], amounts[i]);
    }
  }

  function approve(address spender, uint256 value) public override returns (bool) {
    require(spender != address(0));
    allowed[msg.sender][spender] = value;
    emit Approval(msg.sender, spender, value);
    return true;
  }

  function transferFrom(address from, address to, uint256 value) public override returns (bool) {
    require(value <= balances[from]);
    require(value <= allowed[from][msg.sender]);
    require(to != address(0));

    balances[from] = balances[from].sub(value);
    balances[to] = balances[to].add(value);

    allowed[from][msg.sender] = allowed[from][msg.sender].sub(value);

    emit Transfer(from, to, value);
    return true;
  }

  function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
    require(spender != address(0));
    allowed[msg.sender][spender] = allowed[msg.sender][spender].add(addedValue);
    emit Approval(msg.sender, spender, allowed[msg.sender][spender]);
    return true;
  }

  function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
    require(spender != address(0));
    allowed[msg.sender][spender] = allowed[msg.sender][spender].sub(subtractedValue);
    emit Approval(msg.sender, spender, allowed[msg.sender][spender]);
    return true;
  }

}

library SafeMath {
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
      return 0;
    }
    uint256 c = a * b;
    require(c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a / b;
    return c;
  }

  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a);
    return c;
  }

  function ceil(uint256 a, uint256 m) internal pure returns (uint256) {
    uint256 c = add(a,m);
    uint256 d = sub(c,1);
    return mul(div(d,m),m);
  }
}

Last updated