npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

aeternity-fungible-token

v2.0.0

Published

This is the default package.json generated for your project

Downloads

77

Readme

Aeternity Fungible Token

Build Status

This is an example reference implementation of the proposed aeternity fungible token standard (AEX-9).

A Fungible token is a technical standard used for smart contracts on the blockchain for implementing tokens/digital assets. Fungible token defines a common list of rules for tokens to follow within the larger ecosystem, allowing developers to accurately predict interaction between tokens. These rules include how the tokens are transferred between addresses and how data within each token is accessed. Fungible tokens are interchangeable, divisible, and identical tokens that are useful as in various use-cases.

How it works? Upon deployment, the token sets its owner - the Call.caller (deployer).

In the case you are using mintable extension the owner has special privilege - the ability to create (mint) new tokens. When token is created it is associated with a user - the account parameter.

Each token owner can act upon their tokens in various ways. They can transfer it, allow for it to be transferred on their behalf or completely destroy it (using burn).

AEX 9

AEX: 9
Title: Fungible Token Standard
Author: @mradkov, @thepiwo
License: ISC
Discussions-To: https://forum.aeternity.com/t/aex-9-fungible-token/3565
Status: Review
Type: Standards Track
Created: 2019-05-11

Simple Summary

This document aims to outline a standard and define how fungible tokens should be created and used on aeternity blockchain.

Abstract

The following standard allows for the implementation of a standard API for tokens within smart contracts. This standard provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party.

Motivation

This standard will allow decentralized applications and wallets to handle tokens across multiple interfaces.

The most important here are transfer, balance and the Transfer event.

A standard interface allows any tokens to be re-used by other applications: from wallets to decentralized exchanges.

  • The following specification is following the ERC20 standard introduced in Ethereum for fungible tokens.
  • This standard is proven to be working and we think we can leverage of using it. It will also help us with interoperability and easier developers onboarding as the main differences will be Sophia syntax related.

Specification

Basic Token

Interface

@compiler >= 4

contract FungibleTokenInterface =
  record meta_info =
    { name : string
    , symbol : string
    , decimals : int }

  datatype event =
    Transfer(address, address, int)

  entrypoint aex9_extensions : ()             => list(string)
  entrypoint meta_info       : ()             => meta_info
  entrypoint total_supply    : ()             => int
  entrypoint owner           : ()             => address
  entrypoint balances        : ()             => map(address, int)
  entrypoint balance         : (address)      => option(int)
  entrypoint transfer        : (address, int) => unit

Methods

aex9_extensions()

This function returns a hardcoded list of all implemented extensions on the deployed contract.

entrypoint aex9_extensions() : list(string)

meta_info()

This function returns meta information associated with the token contract.

entrypoint meta_info() : meta_info

| return | type | | :--- | :--- | | meta_info | meta_info |

record meta_info =
  { name     : string
  , symbol   : string
  , decimals : int }

total_supply()

This function returns the total token supply.

entrypoint total_supply() : int

| return | type | | :--- | :--- | | total_supply | int |

balances()

This function returns the full balance state for static calls, e.g. by a blockchain explorer.

entrypoint balances() : map(address, int)

| return | type | | :--- | :--- | | balances | map(address, int) |

balance()

This function returns the account balance of another account with address owner, if the account exists. If the owner address is unknown to the contract None will be returned. Using option type as a return value allows us to determine if the account has balance of 0, more than 0, or the account has never had balance and is still unknown to the contract.

entrypoint balance(owner: address) : option(int)

| parameter | type | | :--- | :--- | | owner | address |

| return | type | | :--- | :--- | | balance | option(int) |

transfer()

This function allows transfer of value amount of tokens to to_account address and MUST fire the Transfer event. The function SHOULD abort if the Call.caller's account balance does not have enough tokens to spend.

Note: Transfers of 0 values MUST be treated as normal transfers and fire the Transfer event.

stateful entrypoint transfer(to_account: address, value: int) : unit

| parameter | type | | :--- | :--- | | to_account | address | | value | int |

Events

Transfer

This event MUST be triggered and emitted when tokens are transferred, including zero value transfers.

The transfer event arguments should be as follows: (from_account, to_account, value)

Transfer(address, address, int)

| parameter | type | | :--- | :--- | | from_account | address | | to_account | address | | value | int |

Extensions

This section covers the extendability of the basic token - e.g. mintable, burnable and allowances.

When a token contract implements an extension its name should be included in the aex9_extensions array, in order for third party software or contracts to know the interface. Any extensions should be implementable without permission. Developers of extensions MUST choose a name for aex9_extensions that is not yet used. Developers CAN make a pull request to the reference implementation for general purpose extensions and maintainers choose to eventually include them.

Extension Mintable ("mintable")

mint()

This function mints value new tokens to account. The function SHOULD abort if Call.caller is not the owner of the contract state.owner.

stateful entrypoint mint(account: address, value: int) : unit

| parameter | type | | :--- | :--- | | account | address | | value | int |

Events

Mint - MUST trigger when tokens are minted using the mint function.

The mint event arguments should be as follows: (account, value)

Mint(address, int)

| parameter | type | | :--- | :--- | | account| address | | value | int |

Extension Burnable ("burnable")

burn()

This function burns value of tokens from Call.caller.

stateful entrypoint burn(value: int) : unit

| parameter | type | | :--- | :--- | | value | int |

Events

Burn - MUST trigger when tokens are burned using the burn function.

The burn event arguments should be as follows: (account, value)

Burn(address, int)

| parameter | type | | :--- | :--- | | account| address | | value | int |

Extension Allowance ("allowances")

create_allowance()

Allows for_account to withdraw from your account multiple times, up to the value amount. If this function is called again it overwrites the current allowance with value.

Note: To prevent attack vectors (like the ones possible in ERC20) clients SHOULD make sure to create user interfaces in such a way that they set the allowance first to 0 before setting it to another value for the same spender. THOUGH the contract itself shouldn't enforce it, to allow backwards compatibility with contracts deployed before.

stateful entrypoint create_allowance(for_account: address, value: int) : unit

| parameter | type | | :--- | :--- | | for_account| address | | value | int |

transfer_allowance()

Transfers value amount of tokens from address from_account to address to_account, and MUST fire the Transfer event.

The transfer_allowance method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD abort unless the from_account account has deliberately authorized the sender of the message via some mechanism.

Note: Transfers of 0 values MUST be treated as normal transfers and fire the Transfer event.

stateful entrypoint transfer_allowance(from_account: address, to_account: address, value: int)

| parameter | type | | :--- | :--- | | from_account| address | | to_account| address | | value | int |

allowance()

This function returns the amount which for_account is still allowed to withdraw from from_account, where record allowance_accounts = { from_account: address, for_account: address }. If no allowance for this combination of accounts exists, None is returned.

entrypoint allowance(allowance_accounts : allowance_accounts) : option(int)

| parameter | type | | :--- | :--- | | allowance_accounts| allowance_accounts |

record allowance_accounts =
  { from_account: address
  , for_account: address }

allowances()

This function returns all of the allowances stored in state.allowances record.

entrypoint allowances() : allowances

| return | type | | :--- | :--- | | allowances | map(allowance_accounts, int) |

allowance_for_caller()

This function will look up the allowances and return the allowed spendable amount from from_account for the transaction sender Call.caller. If there is no such allowance present result is None, otherwise Some(int) is returned with the allowance amount.

entrypoint allowance_for_caller(from_account: address) : option(int)

| parameter | type | | :--- | :--- | | from_account| address |

| return | type | | :--- | :--- | | | option(int) |

change_allowance()

This function allows the Call.caller to change the allowed spendable value for for_account with value_change. This adds the value_change to the current allowance value. If used for increasing allowance amount a positive value should be passed, if the desired outcome is to lower the value of the allowed spendable value a negative value_change should be passed.

stateful entrypoint change_allowance(for_account: address, value_change: int)

| parameter | type | | :--- | :--- | | for_account | address | | value_change | int |

| return | type | | :--- | :--- | | | unit |

reset_allowance()

Resets the allowance given for_account to zero.

stateful entrypoint reset_allowance(for_account: address)

| parameter | type | | :--- | :--- | | for_account| address |

| return | type | | :--- | :--- | | | unit |

Events

Allowance - MUST trigger on any successful call to create_allowance(for_account: address, value: int).

The approval event arguments should be as follows: (from_account, for_account, value)

Allowance(address, address, int)

| parameter | type | | :--- | :--- | | from_account| address | | for_account| address | | value| int |

Extension Swappable ("swappable")

swap()

This function burns the whole balance of the Call.caller and stores the same amount in the swapped map.

stateful entrypoint swap() : unit

| parameter | type | | :--- | :--- | | value | int |

| return | type | | :--- | :--- | | () | unit |

check_swap()

This function returns the amount of tokens that were burned trough swap for the provided account.

stateful entrypoint check_swap(account: address) : int

| parameter | type | | :--- | :--- | | account | address |

| return | type | | :--- | :--- | | int | int |

swapped()

This function returns all of the swapped tokens that are stored in contract state.

stateful entrypoint swapped() : map(address, int)

| return | type | | :--- | :--- | | swapped | map(address, int) |

Events

Swap - MUST trigger when tokens are swapped using the swap function.

The swap event arguments should be as follows: (account, value)

Swap(address, int)

| parameter | type | | :--- | :--- | | account| address | | value | int |

Implementation

There are several implementations available at the moment, but they lack a thing or two (that is why this standard is being proposed).

Example implementations:

References

ERC-20 ERC-20 attack vectors