迁移到 N3

GRANTSHARES

现已启动

为 Neo 生态系统提供去中心化和透明的激励计划
最新资讯:
All in One - All in Neo
All in One - All in Neo
多链互操作性
原生预言机
自主权身份
去中心化存储
Neo 域名服务
单区块终局性
最优开发工具
先进智能合约
多种语言支持
Neo
再次飞跃
2016 年,Neo主网开始稳定运行。2021年,Neo 正向有史以来最强大且全能的版本 N3 进行迁移。
Learn More
下一代
互联网的
基石
为开发者提供开箱即用的全栈式开发体验,更助力开发者开拓更广阔的视野。

Neo 不但原生提供开发去中心化应用所需的全套基础设施,更支持先进的互操作性,帮助开发者轻松触达整个区块链生态系统。
Learn More
单区块终局性
dBFT 共识机制可以确保快速且安全的单区块终局性。
预言机
内置预言机,让应用以去中心化的方式安全地访问任何链下数据。
NeoFS
为增强扩容与隐私性打造的分布式数据存储解决方案。
智能合约
用 C#、Python、Go、Java 或 TypeScript 编写你的智能合约。
Neo 域名服务
为下一代互联网应用设计的去中心化.neo 域名服务。
多链互操作性
通过 Poly Network,实现与以太坊、币安智能链、火币生态链等多个网络的双向跨链互操作。
NeoID
全局自主权去中心化身份解决方案。
你已经熟知的
区块链
熟悉的语言 + 熟悉的工具
= 轻松编写智能合约
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;
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();
        }
    }
}

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

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 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());
    }

}
    
Learn More
双通证
机制
Neo 特有的双通证机制
有效区分治理权与使用权
NEO 通证
GAS 激励
NEO 通证的持有者共享 Neo 区块链的所有权与治理权。NEO 持有者无需进行质押即可被动获得 GAS。

GAS 的使用场景包括支付 Neo 区块链上的网络费用、智能合约部署费用,以及 dAPP 交互等等。
GAS 计算器
用户持有
500
最多获得
0.44
GAS/ 月*
持有 NEO
17.52
GAS/ 月*
参与治理
*根据 20% 投票参与率预估
链上
治理
NEO 持有者投票产生
链上动态治理委员会
NEO 持有者投票产生的委员会成员与共识节点,将承担保持 Neo 网络活跃度与提案调整关键链上参数的职责。

投票者与委员会成员都将获得 GAS 奖励。
链上
治理
NEO 持有者投票产生
链上动态治理委员会
NEO 持有者投票产生的委员会成员与共识节点,将承担保持 Neo 网络活跃度与提案调整关键链上参数的职责。

投票者与委员会成员都将获得 GAS 奖励。
链上
治理
NEO 持有者投票产生
链上动态治理委员会
NEO 持有者投票产生的委员会成员与共识节点,将承担保持 Neo 网络活跃度与提案调整关键链上参数的职责。

投票者与委员会成员都将获得 GAS 奖励。
全球
贡献者
遍布全球的社区成员
是 Neo 不断前进的原动力
3.4Kstars
3.4Kstars
988forks
988forks
388subscribers
388subscribers
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
加入 社区
了解 生态
助力 产业