MIGRATE TO N3

Take a look at the latest version of the Neo platform
Take A Tour
The Complete Blockchain Development Platform
All in One - All in Neo
All in One - All in Neo
Interoperability
Native Oracles
Self-Sovereign ID
Decentralized Storage
Neo Name Service
One Block Finality
Best-In-Class Tooling
Smart Contracts
Multi-Language
Neo is
new again
After four years of stable MainNet operation, Neo is undergoing its biggest evolution as it migrates to N3 - The most powerful and feature rich version of the Neo blockchain to date.
Learn More
Building Blocks for the Next Generation Internet
Neo provides a full stack of features out of the box, but doesn't keep you boxed in.

Native functionality provides all the infrastructure you need to build complete decentralized applications, while advanced interoperability allows you to harness the power of the global blockchain ecosystem.
Learn More
One Block Finality
dBFT consensus mechanism guarantees fast and efficient finality in a single block.
Oracle
A built-in oracle enabling secured access to any off-chain data.
NeoFS
A distributed data storage solution made for scalability and privacy.
Smart Contracts
Write your smart contracts in C#, Go, Python, Java, or TypeScript.
Neo Name Service
A decentralized .neo domain name service for next-gen internet web applications.
Interoperability
Poly.Network enabled cross-chain interoperability with Ethereum, Binance Chain, and more.
NeoID
A set of self-sovereign decentralized identity solution standards.
Blockchain
You know
Write smart contracts in a language you already love
Learn More
Python
C#
Go
Typescript
Java
Python
Python

from boa3.builtin.contract import Nep17TransferEvent, abort

@metadata
def manifest_metadata() -> NeoMetadata:
    meta = NeoMetadata()
    meta.author = "coz"
    return meta

OWNER = UInt160(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
TOKEN_TOTAL_SUPPLY = 100_000_000 * 100_000_000  # 10m total supply * 10^8 (decimals)

# Events
on_transfer = Nep17TransferEvent

@public
def transfer(from_address: UInt160, to_address: UInt160, amount: int, data: Any) -> bool:
    assert len(from_address) == 20 and len(to_address) == 20
    assert amount >= 0

    # The function MUST return false if the from account balance does not have enough tokens to spend.
    from_balance = get(from_address).to_int()
    if from_balance < amount:
        return False

    # The function should check whether the from address equals the caller contract hash.
    if from_address != calling_script_hash:
        if not check_witness(from_address):
            return False

    # skip balance changes if transferring to yourself or transferring 0 cryptocurrency
    if from_address != to_address and amount != 0:
        if from_balance == amount:
            delete(from_address)
        else:
            put(from_address, from_balance - amount)

        to_balance = get(to_address).to_int()
        put(to_address, to_balance + amount)

    on_transfer(from_address, to_address, amount)
    # if the to_address is a smart contract, it must call the contract's onPayment method
    post_transfer(from_address, to_address, amount, data)
    return True

C#
C#

using Neo.SmartContract.Framework;

[DisplayName("Nep17 example")]
[ManifestExtra("Author", "Neo Core Dev")]
public class Nep17Contract : SmartContract
{
    #region Token Settings
    static readonly ulong TotalSupply = 10_000_000_000_000_000;
    static readonly UInt160 Owner = "NdHjSPVnw99RDMCoJdCnAcjkE23gvqUeg2".ToScriptHash();
    #endregion

    #region Notifications
    [DisplayName("Transfer")]
    public static event Action OnTransfer;
    #endregion

    public static bool Transfer(UInt160 from, UInt160 to, BigInteger amount, object data)
    {
        if (!ValidateAddress(from) || !ValidateAddress(to)) throw new Exception("The parameters from and to SHOULD be 20-byte non-zero addresses.");
        if (amount <= 0) throw new Exception("The parameter amount MUST be greater than 0.");
        if (!Runtime.CheckWitness(from) && !from.Equals(ExecutionEngine.CallingScriptHash)) throw new Exception("No authorization.");
        if (AssetStorage.Get(from) < amount) throw new Exception("Insufficient balance.");
        if (from == to) return true;

        AssetStorage.Reduce(from, amount);
        AssetStorage.Increase(to, amount);

        OnTransfer(from, to, amount);

        // Validate payable
        if (IsDeployed(to)) Contract.Call(to, "onPayment", new object[] { from, amount, data });
        return true;
    }
}

Go
Go

package nep17Contract

var (
    token nep17.Token
    ctx   storage.Context
)
// initializes the Token Interface and storage context
func init() {
    token = nep17.Token{
        ...
        Name:           "Nep17 example",
        Owner:          util.FromAddress("NdHjSPVnw99RDMCoJdCnAcjkE23gvqUeg2"),
        TotalSupply:    10000000000000000
    }
    ctx = storage.GetContext()
}
// Transfer token from one user to another
func (t Token) Transfer(ctx storage.Context, from, to interop.Hash160, amount int, data interface{}) bool {
    amountFrom := t.CanTransfer(ctx, from, to, amount)
    if amountFrom == -1 {
        return false
    }

    if amountFrom == 0 {
        storage.Delete(ctx, from)
    }

    if amountFrom > 0 {
        diff := amountFrom - amount
        storage.Put(ctx, from, diff)
    }

    amountTo := getIntFromDB(ctx, to)
    totalAmountTo := amountTo + amount
    storage.Put(ctx, to, totalAmountTo)
    runtime.Notify("Transfer", from, to, amount)
    if to != nil && management.GetContract(to) != nil {
        contract.Call(to, "onNEP17Payment", contract.All, from, amount, data)
    }
    return true
}

Typescript
Typescript

import {  SmartContract} from '@neo-one/smart-contract';

export class NEP17Contract extends SmartContract {
  public readonly properties = {
    name: 'NEO•ONE NEP17 Example',
    groups: [],
    trusts: '*',
    permissions: [],
  };
  public readonly name = 'NEO•ONE NEP17 Example';
  public readonly decimals = 8;

  private readonly notifyTransfer = createEventNotifier<Address | undefined, Address | undefined, Fixed<8>>(
    'Transfer', 'from', 'to', 'amount',
  );

  public transfer(from: Address, to: Address, amount: Fixed<8>, data?: any): boolean {
    if (amount < 0) {throw new Error(`Amount must be greater than 0: ${amount}`);}

    const fromBalance = this.balanceOf(from);
    if (fromBalance < amount) { return false; }

    const contract = Contract.for(to);
    if (contract !== undefined && !Address.isCaller(to)) {
      const smartContract = SmartContract.for<TokenPayableContract>(to);
      if (!smartContract.approveReceiveTransfer(from, amount, this.address)) {
        return false;
      }
    }

    const toBalance = this.balanceOf(to);
    this.balances.set(from, fromBalance - amount);
    this.balances.set(to, toBalance + amount);
    this.notifyTransfer(from, to, amount);

    if (contract !== undefined) {
      const smartContract = SmartContract.for<TokenPayableContract>(to);
      smartContract.onNEP17Payable(from, amount, data);
    }
    return true;
  }
}

Java
Java

import io.neow3j.devpack.contracts.ContractManagement;

@ManifestExtra(key = "Name", value = "Nep17 example")
@ManifestExtra(key = "Author", value = "neow3j")
public class Nep17Contract {

    static final Hash160 contractOwner = addressToScriptHash("NdHjSPVnw99RDMCoJdCnAcjkE23gvqUeg2");
    static final int initialSupply = 10_000_000_000_000_000;

    static final StorageContext ctx = Storage.getStorageContext();
    static final StorageMap tokenOwnerMap = ctx.createMap("tokenOwner");

    @DisplayName("Transfer")
    static Event3Args
    onTransfer;

    // Transfers a token.
    public static boolean transfer(Hash160 from, Hash160 to, int amount, Object[] data) throws Exception {
        if (!from.isValid() || !to.isValid()) {
            throw new Exception("From or To address is not a valid address.");
        }
        if (amount < 0) {throw new Exception("The transfer amount was negative.");}

        if (!Runtime.checkWitness(from) && from != ExecutionEngine.getCallingScriptHash()) {
            throw new Exception("Invalid sender signature. The sender of the tokens needs to be the signing account.");
        }
        if (assetGet(from) < amount) {return false;}

        if (from != to && amount != 0) {
            deductFromBalance(from, amount);
            addToBalance(to, amount);
        }
        if (ContractManagement.getContract(to) != null) {
            Contract.call(to, "onNEP17Payment", CallFlags.ALL, data);
        }
        onTransfer.notify(from, to, amount);
        return true;
    }
}
    
Learn More
Dual
Tokens
Neo has a unique dual token model that separates governance from utility.
NEO token
GAS token
NEO token holders are the owners of the network and are able to participate in governance. NEO holders also receive passive distribution of the network utility token, GAS - No staking required. GAS rewards are increased for voting participation.

GAS is used to pay for network fees, smart contract deployments, and in dApp purchases.
NEO & GAS Calculator
A user with
500
would receive up to
0.44
Gas Per Month*

For holding NEO
17.52
Gas Per Month*

For Governance Participation
0.44
Gas Per Month*

For holding NEO
17.52
Gas Per Month*

For Governance Participation
*estimate based on average 20% circulating NEO voting participation
On-chain
Governance
A dynamic on-chain council voted in by the NEO token holders.
N3 introduces the ability for NEO holders to vote in council members and consensus nodes that maintain the liveliness of the Neo network and adjust critical blockchain parameters.

GAS rewards are distributed to both voters and committee members.
On-chain
Governance
A dynamic on-chain council voted in by the NEO token holders.
N3 introduces the ability for NEO holders to vote in council members and consensus nodes that maintain the liveliness of the Neo network and adjust critical blockchain parameters.

GAS rewards are distributed to both voters and committee members.
On-chain
Governance
A dynamic on-chain council voted in by the NEO token holders.
N3 introduces the ability for NEO holders to vote in council members and consensus nodes that maintain the liveliness of the Neo network and adjust critical blockchain parameters.

GAS rewards are distributed to both voters and committee members.
Global
Contributors
Neo is a joint effort by community groups from all over the world.
3.2Kstars
3.2Kstars
927forks
927forks
386subscribers
386subscribers
NDG Enterprise GitHub NDG Enterprise Website NDG Tracker GitHub NDG Tracker Website COZ GitHub COZ Website NEO Research GitHub NEO Research Website Red4Sec GitHub Red4Sec Website AxLabs GitHub AxLabs Website NEO S.Petersburg Center GitHub NEO S.Petersburg Center Website NGD Shanghai GitHub NGD Shanghai Website NewEconoLab GitHub NewEconoLab Website NEXT GitHub NEXT Website
Join the Community
Explore the Ecosystem
Industry Partners