MIGRATE TO N3

# Introducing:
Neo X

Neo’s EVM-based sidechain is here.
Find out what opportunities await.
LEARN MORE
Latest News:
Neo X Grind Hackathon kicks off for EVM innovators with over $22 million in prizes and grants 
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
Take A Tour
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
Take A Tour
Find a Wallet
Neo & Gas Tokens
Neo's Features
Documentation
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

Python Resources
Documentation Templates Tools
C#
C#


    using Neo;
    using Neo.SmartContract;
    using Neo.SmartContract.Framework;
    using Neo.SmartContract.Framework.Attributes;
    using Neo.SmartContract.Framework.Native;
    using Neo.SmartContract.Framework.Services;
    using System;
    using System.Numerics;

    namespace Desktop
    {
        [ManifestExtra("Author", "Neo")]
        [ManifestExtra("Email", "dev@neo.org")]
        [ManifestExtra("Description", "This is a contract example")]
        [ContractSourceCode("https://github.com/neo-project/neo-devpack-dotnet/tree/master/src/Neo.SmartContract.Template")]
        public class Contract1 : SmartContract
        {
            //TODO: Replace it with your own address.
            [InitialValue("NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB", ContractParameterType.Hash160)]
            static readonly UInt160 Owner = default;

            private static bool IsOwner() => Runtime.CheckWitness(Owner);

            // When this contract address is included in the transaction signature,
            // this method will be triggered as a VerificationTrigger to verify that the signature is correct.
            // For example, this method needs to be called when withdrawing token from the contract.
            public static bool Verify() => IsOwner();

            // TODO: Replace it with your methods.
            public static string MyMethod()
            {
                return Storage.Get(Storage.CurrentContext, "Hello");
            }

            public static void _deploy(object data, bool update)
            {
                if (update) return;

                // It will be executed during deploy
                Storage.Put(Storage.CurrentContext, "Hello", "World");
            }

            public static void Update(ByteString nefFile, string manifest)
            {
                if (!IsOwner()) throw new Exception("No authorization.");
                ContractManagement.Update(nefFile, manifest, null);
            }

            public static void Destroy()
            {
                if (!IsOwner()) throw new Exception("No authorization.");
                ContractManagement.Destroy();
            }
        }
    }

CSharp Resources
Documentation Templates Tools
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

    }

Go Resources
Documentation Templates Tools
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;

      }

    }

Typescript Resources
Documentation Templates Tools
Java
Java


    package io.neow3j.examples.contractdevelopment.contracts;

    import static io.neow3j.devpack.StringLiteralHelper.addressToScriptHash;

    import io.neow3j.devpack.*

    @ManifestExtra(key = "name", value = "FungibleToken")
    @ManifestExtra(key = "author", value = "AxLabs")
    @SupportedStandards("NEP-17")
    @Permission(contract = "fffdc93764dbaddd97c48f252a53ea4643faa3fd") // ContractManagement
    public class FungibleToken {

        static final Hash160 owner = addressToScriptHash("NM7Aky765FG8NhhwtxjXRx7jEL1cnw7PBP");

        @DisplayName("Transfer")
        static Event3Args<Hash160, Hash160, Integer> onTransfer;

        static final int initialSupply = 200_000_000;
        static final int decimals = 8;
        static final String assetPrefix = "asset";
        static final String totalSupplyKey = "totalSupply";
        static final StorageContext sc = Storage.getStorageContext();
        static final StorageMap assetMap = sc.createMap(assetPrefix);

        public static String symbol() {
            return "FGT";
        }

        public static int decimals() {
            return decimals;
        }

        public static int totalSupply() {
            return getTotalSupply();
        }

        static int getTotalSupply() {
            return Storage.getInteger(sc, totalSupplyKey);
        }

        public static boolean transfer(Hash160 from, Hash160 to, int amount, Object[] data)
                throws Exception {

            if (!Hash160.isValid(from) || !Hash160.isValid(to)) {
                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 != Runtime.getCallingScriptHash()) {
                throw new Exception("Invalid sender signature. The sender of the tokens needs to be "
                        + "the signing account.");
            }
            if (getBalance(from) < amount) {
                return false;
            }
            if (from != to && amount != 0) {
                deductFromBalance(from, amount);
                addToBalance(to, amount);
            }

            onTransfer.fire(from, to, amount);
            if (ContractManagement.getContract(to) != null) {
                Contract.call(to, "onNEP17Payment", CallFlags.All, data);
            }

            return true;
        }

        public static int balanceOf(Hash160 account) throws Exception {
            if (!Hash160.isValid(account)) {
                throw new Exception("Argument is not a valid address.");
            }
            return getBalance(account);
        }

        @OnDeployment
        public static void deploy(Object data, boolean update) throws Exception {
            throwIfSignerIsNotOwner();
            if (!update) {
                if (Storage.get(sc, totalSupplyKey) != null) {
                    throw new Exception("Contract was already deployed.");
                }
                // Initialize supply
                Storage.put(sc, totalSupplyKey, initialSupply);
                // And allocate all tokens to the contract owner.
                assetMap.put(owner.toByteArray(), initialSupply);
            }
        }

        public static void update(ByteString script, String manifest) throws Exception {
            throwIfSignerIsNotOwner();
            if (script.length() == 0 && manifest.length() == 0) {
                throw new Exception("The new contract script and manifest must not be empty.");
            }
            ContractManagement.update(script, manifest);
        }

        public static void destroy() throws Exception {
            throwIfSignerIsNotOwner();
            ContractManagement.destroy();
        }

        @OnVerification
        public static boolean verify() throws Exception {
            throwIfSignerIsNotOwner();
            return true;
        }

        /**
         * Gets the address of the contract owner.
         *
         * @return the address of the contract owner.
         */
        public static Hash160 contractOwner() {
            return owner;
        }

        private static void throwIfSignerIsNotOwner() throws Exception {
            if (!Runtime.checkWitness(owner)) {
                throw new Exception("The calling entity is not the owner of this contract.");
            }
        }

        private static void addToBalance(Hash160 key, int value) {
            assetMap.put(key.toByteArray(), getBalance(key) + value);
        }

        private static void deductFromBalance(Hash160 key, int value) {
            int oldValue = getBalance(key);
            if (oldValue == value) {
                assetMap.delete(key.toByteArray());
            } else {
                assetMap.put(key.toByteArray(), oldValue - value);
            }
        }

        private static int getBalance(Hash160 key) {
            return assetMap.getInteger(key.toByteArray());
        }

    }

Java Resources
Documentation Templates Tools
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.
Learn More Find a Wallet
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
*estimate based on average 20% circulating NEO voting participation
Learn More
How to vote
General guide to governance
Register as a committee candidate
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.
Learn More
How to vote
General guide to governance
Register as a committee candidate
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.
Learn More
How to vote
General guide to governance
Register as a committee candidate
Global
Contributors
Neo is a joint effort by community groups from all over the world.
3.4Kstars
3.4Kstars
988forks
988forks
388subscribers
388subscribers
 
Join the Community
        
Explore the Ecosystem

Industry Partners
    
Latest News
October 30, 2024 Blog

### Neo X Grind Hackathon kicks off for EVM innovators with over $22 million in prizes and grants

#### Co-hosted with IOSG Kickstarter, Web3Labs, Foresight Ventures, and Bit…

#hackathon
October 25, 2024 Blog

### Neo Global Development General Monthly Report: July - September 2024

#### 🚀 Neo X: The start of a new chapter During the reporting period, we …

#Monthly Report
August 2, 2024 Blog

### Neo launches NeoPod ambassador program

#### Following the launch of the Neo X MainNet, we are excited to announce …

#Neo X
View All