SEP206: Manipulate Native Token as a SEP20 Token

1. Summary

This SEP proposes a method to manipulate the native token, i.e., BCH, through a pseudo smart contract with SEP20 interface.

2. Abstract

On Ethereum, the developers of DApp have always a pain: ETH is not an ERC20 token. And the methods to manipulate ETH and ERC20 tokens are totally different. There are two ways to alleviate this problem:

  1. Wrap ETH to make it an ERC20 token: WETH.

  2. Write two sets of logic in smart contracts to support ETH and ERC20 seperately.

These methods are neither perfect.

On smartBCH, a psuedo smart contract can help you manipulate BCH directly. This smart contract is psuedo because it is not implemented by EVM bytecode. Instead, it is supported natively in the full client, smartbchd. So it can do a thing that no other smart contracts can do: moving BCH. It has a predefined address: 10001, like the precompiled contracts.

This pseudo contract has a SEP20 interface, it can be called as if it is SEP20 smart contract.

3. Motivation

This proposal specifies the behavior of functions in this psuedo smart contract, such that developers can use it correctly.

4. Status

This SEP is under draft.

5. Specification

5.1 Token


  • The following specifications use syntax from Solidity 0.5.16 (or above)

  • The following methods must be invoked through call or staticall, delegatecall and callcode are not allowed.

  • The allowance granted by owner to spender is stored at the slot whose location is calculated as uint(sha256(abi.encodePacked(uint(owner), uint(spender)). The size of this slot is not required to be 32-byte long and you can NOT read its value with eth_getStorageAt.

5.1.1 Methods name

function name() external view returns (string)
  • Returns "BCH". symbol

function symbol() external view returns (string)
  • Returns "BCH". decimals

function decimals() external view returns (uint8)
  • Returns 18. totalSupply

function totalSupply() external view returns (uint256)
  • Returns 2.1E25.

  • NOTE - Most of the BCH tokens of smartBCH will be locked in a smart contract, which is be controlled by the gateway keepers. balanceOf

function balanceOf(address _owner) external view returns (uint256 balance)
  • Returns the BCH balance of another account with address _owner.

  • Returns the same value as the eth_getBalance function in Web3 API. transfer

function transfer(address _to, uint256 _value) external returns (bool success)
  • Transfers _value amount of BCH to address _to, and fire the Transfer event. The function throws if the message caller’s account balance does not have enough tokens to spend. transferFrom

function transferFrom(address _from, address _to, uint256 _value) external returns (bool success)
  • Transfers _value amount of BCH from address _from to address _to, and fires the Transfer event.

  • The function throws unless the _from account has deliberately authorized the sender of the message via allowance control. approve

function approve(address _spender, uint256 _value) external returns (bool success)
  • Allows _spender to withdraw from your account multiple times, up to the _value amount of BCH. If this function is called again it overwrites the current allowance with _value. allowance

function allowance(address _owner, address _spender) external view returns (uint256 remaining)
  • Returns the amount which _spender is still allowed to withdraw from _owner. increaseAllowance

function increaseAllowance(address _spender, uint256 _delta) external returns (bool success)
  • Increases the amount which _spender is still allowed to withdraw from you. decreaseAllowance

function decreaseAllowance(address _spender, uint256 _delta) external returns (bool success)
  • Decreases the amount which _spender is still allowed to withdraw from you.

5.1.2 Events Transfer

event Transfer(address indexed _from, address indexed _to, uint256 _value)
  • It's triggerred when tokens are transferred, including zero value transfers. Approval

event Approval(address indexed _owner, address indexed _spender, uint256 _value)
  • It's triggerred on any successful call to approve(address _spender, uint256 _value), increaseAllowance(address _spender, uint256 _delta) or decreaseAllowance(address _spender, uint256 _delta).

5.1.3 Gas Cost

Calling these functions costs fixed gas, as is shown below:

  • name: 3000

  • symbol: 3000

  • decimals: 1000

  • totalSupply: 1000

  • balanceOf: 20000

  • transfer: 32000

  • transferFrom: 40000

  • approve: 25000

  • allowance: 20000

  • increaseAllowance: 31000

  • decreaseAllowance: 31000

6. License

The content is licensed under CC0.