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
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
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
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
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
Learn More