LoginSignup
0
0

More than 5 years have passed since last update.

NEOトークン(NEP5)C#で実装

Last updated at Posted at 2019-02-19

C#でNEP5トークンを実装してみました。
NEPはNEOの技術仕様を取りまとめたもので、Ethereumで言うERCの様なものです。

nep5.cs
using Neo.SmartContract.Framework;

using Neo.SmartContract.Framework.Services.Neo;

using System;

using System.Numerics;

using System.ComponentModel;

namespace nepCoin {

   public class NepCoin : SmartContract
   {
       public static readonly byte[] Owner = "AGgg3odmiU287C4KKReSy6ntgRxXoU34LQ".ToScriptHash();
       public static event Action<byte[], byte[], BigInteger> tranfer;
       public static object Main(string operation, object[] args)
       {
           if (operation == "name")
           {
               return "Token";
           }
           if (operation == "symbol")
           {
               return "TKN";
           }
           if (operation == "decimals")
           {
               return 2;
           }
           if (operation == "totalSupply")
           {
               return 1000_00;
           }
           if (operation == "balanceOf")
           {
               return BalanceOf((byte[])args[0]);
           }
           if (operation == "transfer")
           {
               var from = (byte[])args[0];
               if (!Runtime.CheckWitness(from))
               {
                   Runtime.Notify("Not Authorized");
                   return false;
               }
               return PerfromTransfer((byte[])args[0], (byte[])args[1], (BigInteger)args[2]);
           }
           if(operation == "approve")
           {
               return Approve((byte[])args[0], (byte[])args[1], new BigInteger((byte[]) args[2]));
           }
           if(operation == "allowance")
           {
               return Allowance((byte[])args[0], (byte[])args[1]);
           }
           if(operation == "transferFrom")
           {
               return TransferFrom((byte[])args[0], (byte[])args[1], (byte[])args[2], new BigInteger((byte[])args[3]));
           }
           if (operation == "deploy")
           {
               return Deploy();
           }
           Runtime.Notify("Could not find action",operation);
           return false;
       }
       public static bool PerfromTransfer(byte[] from, byte[] to, BigInteger amount)
       {
           if(from.Length != 20)
           {
               Runtime.Notify("Invalid from");
           }
           if(to.Length != 20)
           {
               Runtime.Notify("Invalid to");
           }
           if (Runtime.CheckWitness(from))
           {
               Runtime.Notify("Not Authorized");
               return false;
           }
           if (from == to)
           {
               Runtime.Notify("Can not seed to self");
               return false;
           }
           if(amount <= 0)
           {
               Runtime.Notify("Invalid Amount");
               return false;
           }
           var fromBalance = BalanceOf(from);
           if (fromBalance - amount < 0)
           {
               Runtime.Notify("Insufficient Fund!");
               return false;
           }
           var toBalance = BalanceOf(to);
           fromBalance = fromBalance - amount;
           toBalance = toBalance + amount;
           Storage.Put(Storage.CurrentContext, from, fromBalance);
           Storage.Put(Storage.CurrentContext, to, toBalance);
           tranfer(from, to, amount);
           return true;
       }
       public static BigInteger BalanceOf(byte[] account)
       {
           var balanceFromStorage = Storage.Get(Storage.CurrentContext, account);
           Runtime.Notify("Retrieved Balance", account, balanceFromStorage);
           return new BigInteger(balanceFromStorage);
       }
       public static bool Deploy()
       {
           if (!Runtime.CheckWitness(Owner))
           {
               Runtime.Log("You are not authorized!");
               return false;
           }
           var deployComplete = Storage.Get(Storage.CurrentContext, "DeploymentComplete");
           if (deployComplete != null)
           {
               Runtime.Log("Can not deploy. Deployment already ran");
               return false;
           }
           Storage.Put(Storage.CurrentContext, "DeploymentComplete", 1);
           Storage.Put(Storage.CurrentContext, Owner, 100_00);
           Runtime.Log("Deployment Complete");
           return true;
       }
       public static bool Approve(byte[] approver, byte[] trustee,BigInteger amount)
       {
           if(approver.Length != 20)
           {
               Runtime.Notify("Invalid Approver");
               return false;
           }
           if(trustee.Length != 20)
           {
               Runtime.Notify("Invalid Trustee");
               return false;
           }
           if(amount < 0)
           {
               Runtime.Notify("Approver failure");
               return false;
           }
           if (!Runtime.CheckWitness(approver))
           {
               Runtime.Notify("Approver failure");
               return false;
           }
           Storage.Put(Storage.CurrentContext, approver.Concat(trustee), amount);
           return true;
       }
       public static BigInteger Allowance(byte[] approver,byte[] trustee)
       {
           return new BigInteger(Storage.Get(Storage.CurrentContext, approver.Concat(trustee)));
       }
       public static bool TransferFrom(byte[] trustee,byte[] approver,byte[] to,BigInteger amount)
       {
           if(trustee.Length != 20)
           {
               Runtime.Notify("Invalid trustee");
               return false;
           }
           if (approver.Length != 20)
           {
               Runtime.Notify("Invalid approver");
               return false;
           }
           if(to.Length != 20)
           {
               Runtime.Notify("Invalid to");
               return false;
           }
           if (amount <= 0)
           {
               Runtime.Notify("Invalid amount");
               return false;
           }
           if (!Runtime.CheckWitness(trustee)) {
               Runtime.Notify("Trustee Failure");
               return false;
           }
           var approvedAmount = Allowance(approver, trustee);
           if(amount > approvedAmount)
           {
               Runtime.Notify("Allowance Failure");
               return false;
           }
           var transferSuccess = PerfromTransfer(approver, to, amount);
           if (transferSuccess)
           {
               Storage.Put(Storage.CurrentContext, approver.Concat(trustee), approvedAmount - amount);
               return true;
           }
           return false;
       }
   }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0