diff --git a/NEP5/NEP5.cs b/NEP5/NEP5.cs new file mode 100644 index 0000000..eba1694 --- /dev/null +++ b/NEP5/NEP5.cs @@ -0,0 +1,113 @@ +using Neo.SmartContract.Framework; +using Neo.SmartContract.Framework.Services.Neo; +using Neo.SmartContract.Framework.Services.System; +using System; +using System.ComponentModel; +using System.Numerics; + +namespace NEP5 +{ + public class NEP5 : SmartContract + { + [DisplayName("transfer")] + public static event Action Transferred; + + private static readonly byte[] Owner = "Ae2d6qj91YL3LVUMkza7WQsaTYjzjHm4z1".ToScriptHash(); //Owner Address + + public static object Main(string method, object[] args) + { + if (Runtime.Trigger == TriggerType.Verification) + { + return Runtime.CheckWitness(Owner); + } + else if (Runtime.Trigger == TriggerType.Application) + { + var callscript = ExecutionEngine.CallingScriptHash; + + if (method == "balanceOf") return BalanceOf((byte[])args[0]); + + if (method == "decimals") return Decimals(); + + if (method == "name") return Name(); + + if (method == "symbol") return Symbol(); + + if (method == "supportedStandards") return SupportedStandards(); + + if (method == "totalSupply") return TotalSupply(); + + if (method == "transfer") return Transfer((byte[])args[0], (byte[])args[1], (BigInteger)args[2], callscript); + } + return false; + } + + [DisplayName("balanceOf")] + public static BigInteger BalanceOf(byte[] account) + { + if (account.Length != 20) + throw new InvalidOperationException("The parameter account SHOULD be 20-byte addresses."); + StorageMap asset = Storage.CurrentContext.CreateMap(nameof(asset)); + return asset.Get(account).AsBigInteger(); + } + [DisplayName("decimals")] + public static byte Decimals() => 8; + + private static bool IsPayable(byte[] to) + { + var c = Blockchain.GetContract(to); + return c == null || c.IsPayable; + } + + [DisplayName("name")] + public static string Name() => "MyToken"; //name of the token + + [DisplayName("symbol")] + public static string Symbol() => "MYT"; //symbol of the token + + [DisplayName("supportedStandards")] + public static string[] SupportedStandards() => new string[] { "NEP-5", "NEP-7", "NEP-10" }; + + [DisplayName("totalSupply")] + public static BigInteger TotalSupply() + { + StorageMap contract = Storage.CurrentContext.CreateMap(nameof(contract)); + return contract.Get("totalSupply").AsBigInteger(); + } +#if DEBUG + [DisplayName("transfer")] //Only for ABI file + public static bool Transfer(byte[] from, byte[] to, BigInteger amount) => true; +#endif + //Methods of actual execution + private static bool Transfer(byte[] from, byte[] to, BigInteger amount, byte[] callscript) + { + //Check parameters + if (from.Length != 20 || to.Length != 20) + throw new InvalidOperationException("The parameters from and to SHOULD be 20-byte addresses."); + if (amount <= 0) + throw new InvalidOperationException("The parameter amount MUST be greater than 0."); + if (!IsPayable(to)) + return false; + if (!Runtime.CheckWitness(from) && from.AsBigInteger() != callscript.AsBigInteger()) + return false; + StorageMap asset = Storage.CurrentContext.CreateMap(nameof(asset)); + var fromAmount = asset.Get(from).AsBigInteger(); + if (fromAmount < amount) + return false; + if (from == to) + return true; + + //Reduce payer balances + if (fromAmount == amount) + asset.Delete(from); + else + asset.Put(from, fromAmount - amount); + + //Increase the payee balance + var toAmount = asset.Get(to).AsBigInteger(); + asset.Put(to, toAmount + amount); + + Transferred(from, to, amount); + return true; + } + } +} diff --git a/NEP5/NEP5.csproj b/NEP5/NEP5.csproj new file mode 100644 index 0000000..e2e7f65 --- /dev/null +++ b/NEP5/NEP5.csproj @@ -0,0 +1,67 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {2712642F-46ED-47B6-95D9-FB2567BFA2F5} + Library + Properties + NEP5 + NEP5 + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + none + true + bin\Release\ + + + prompt + 4 + + + + False + .\Neo.SmartContract.Framework.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NEP5/Neo.ConvertTask.dll b/NEP5/Neo.ConvertTask.dll new file mode 100644 index 0000000..2de7c65 Binary files /dev/null and b/NEP5/Neo.ConvertTask.dll differ diff --git a/NEP5/Neo.SmartContract.Framework.dll b/NEP5/Neo.SmartContract.Framework.dll new file mode 100644 index 0000000..66491b7 Binary files /dev/null and b/NEP5/Neo.SmartContract.Framework.dll differ diff --git a/NEP5/Properties/AssemblyInfo.cs b/NEP5/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..71eab29 --- /dev/null +++ b/NEP5/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NEP5")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("NEP5")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2712642f-46ed-47b6-95d9-fb2567bfa2f5")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/NEP5/build.tasks b/NEP5/build.tasks new file mode 100644 index 0000000..87cd344 --- /dev/null +++ b/NEP5/build.tasks @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/NEP5/packages.config b/NEP5/packages.config new file mode 100644 index 0000000..813669f --- /dev/null +++ b/NEP5/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/examples.sln b/examples.sln index cad4162..a85f8e2 100644 --- a/examples.sln +++ b/examples.sln @@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapExample", "MapExample\Ma EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventExample", "EventExample\EventExample.csproj", "{63CECEA1-2506-4FDE-BFE2-EA89F75FBF7A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NEP5", "NEP5\NEP5.csproj", "{2712642F-46ED-47B6-95D9-FB2567BFA2F5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -57,6 +59,10 @@ Global {63CECEA1-2506-4FDE-BFE2-EA89F75FBF7A}.Debug|Any CPU.Build.0 = Debug|Any CPU {63CECEA1-2506-4FDE-BFE2-EA89F75FBF7A}.Release|Any CPU.ActiveCfg = Release|Any CPU {63CECEA1-2506-4FDE-BFE2-EA89F75FBF7A}.Release|Any CPU.Build.0 = Release|Any CPU + {2712642F-46ED-47B6-95D9-FB2567BFA2F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2712642F-46ED-47B6-95D9-FB2567BFA2F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2712642F-46ED-47B6-95D9-FB2567BFA2F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2712642F-46ED-47B6-95D9-FB2567BFA2F5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE