Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync neo changes #391

Merged
merged 55 commits into from
Dec 10, 2020
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
4c2e79d
Initial commit
shargon Nov 12, 2020
f5f161b
Remove hash from ABI
shargon Nov 12, 2020
38e0590
Clean lines
shargon Nov 12, 2020
9c8e7db
Fixes
shargon Nov 13, 2020
5379d41
Merge remote-tracking branch 'neo-project/master' into sync-nep17
shargon Nov 13, 2020
7ad9b72
Fix some UT
shargon Nov 13, 2020
4448877
Change name to manifest
shargon Nov 16, 2020
cc4cced
Merge branch 'master' into sync-nep17
shargon Nov 19, 2020
88fa514
Update nuget
shargon Nov 19, 2020
6947047
Update NEP17.cs
shargon Nov 20, 2020
c0db531
Merge branch 'master' into sync-nep17
shargon Nov 20, 2020
f4df31a
Fix more UT
shargon Nov 20, 2020
2ec0748
Some fixes
shargon Nov 20, 2020
9894e83
Fix Contract
shargon Nov 20, 2020
821f834
Update NEP17.Owner.cs
shargon Nov 21, 2020
057d5ba
Update NEP17.Methods.cs
shargon Nov 26, 2020
9e79f27
Merge branch 'master' into sync-nep17
shargon Nov 26, 2020
af62c81
Add data to Transfer
shargon Nov 26, 2020
32905b6
add data to onPayment
shargon Nov 26, 2020
1650325
Remove name
shargon Nov 27, 2020
afad1b1
Merge branch 'master' into sync-nep17
shargon Dec 1, 2020
425718f
Update src/Neo.Compiler.MSIL/Neo.Compiler.MSIL.csproj
shargon Dec 1, 2020
ecdb308
Fix NEF Version
shargon Dec 1, 2020
0fafec4
Fix UT
shargon Dec 1, 2020
0633281
Fix test
shargon Dec 1, 2020
3de92ed
Add OnPayment() for Mint()
superboyiii Dec 4, 2020
9110b42
Fix
superboyiii Dec 4, 2020
ba8a716
Fix
superboyiii Dec 4, 2020
c496fe8
Format
superboyiii Dec 4, 2020
da701ad
Format
superboyiii Dec 4, 2020
2e4fc2c
Format
superboyiii Dec 4, 2020
1cfec66
Update NEP17.Owner.cs
shargon Dec 4, 2020
e1eff81
Update templates/Template.NEP17.CSharp/NEP17.cs
shargon Dec 4, 2020
560e161
Update templates/Template.NEP17.CSharp/NEP17.Methods.cs
shargon Dec 4, 2020
0ef68d9
Update AssetStorage.cs
shargon Dec 4, 2020
b7d657a
Update AssetStorage.cs
shargon Dec 4, 2020
c75bb6b
Update AssetStorage.cs
shargon Dec 4, 2020
a33b14b
Merge pull request #9 from superboyiii/sync-nep17
shargon Dec 4, 2020
d1d2300
Update templates/Template.NEP17.CSharp/NEP17.cs
shargon Dec 4, 2020
0b9fd67
Update templates/Template.NEP17.CSharp/NEP17.Methods.cs
shargon Dec 4, 2020
0c27e44
Rename to ContractNameAttribute & fix invocation counter
shargon Dec 7, 2020
e3d02dc
Change mint
shargon Dec 8, 2020
5db20de
Rename to IsDeployed
shargon Dec 8, 2020
ad2d89e
Use DisplayName
shargon Dec 8, 2020
c903184
Fix mint
shargon Dec 8, 2020
882a721
Fix
shargon Dec 8, 2020
bd4c246
Optimize Mint
erikzhang Dec 9, 2020
8d0d298
Remove GetTransactionAmount
erikzhang Dec 9, 2020
493b278
Fix claim gas
erikzhang Dec 9, 2020
15f9de1
Add IsValid
shargon Dec 9, 2020
8d1e266
Update NEP17.Crowdsale.cs
erikzhang Dec 10, 2020
0823a31
Update src/Neo.SmartContract.Framework/UInt160.cs
shargon Dec 10, 2020
7992c3a
Remove Size from UInt160 and UInt256
erikzhang Dec 10, 2020
befe380
Update UInt256.cs
erikzhang Dec 10, 2020
a572293
Fix UT
erikzhang Dec 10, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ jobs:
run: dotnet test tests/Neo.Compiler.MSIL.UnitTests /p:CollectCoverage=true /p:CoverletOutput=${GITHUB_WORKSPACE}/coverage/ /p:Exclude=\"[Neo.SmartContract.*]*,[Neo.Compiler.MSIL.UnitTests]*,[Neo.Compiler.MSIL.UnitTests.*]*\"
- name: Test Neo.SmartContract.Framework.UnitTests
run: dotnet test tests/Neo.SmartContract.Framework.UnitTests /p:CollectCoverage=true /p:CoverletOutput=${GITHUB_WORKSPACE}/coverage/lcov /p:MergeWith=${GITHUB_WORKSPACE}/coverage/coverage.json /p:Exclude=\"[Neo.SmartContract.*]*,[Neo.Compiler.MSIL.UnitTests]*,[Neo.Compiler.MSIL.UnitTests.*]*\" /p:CoverletOutputFormat=lcov
- name: Test Template.NEP5.UnitTests
run: dotnet test tests/Template.NEP5.UnitTests /p:CollectCoverage=true /p:CoverletOutput=${GITHUB_WORKSPACE}/coverage/lcov /p:MergeWith=${GITHUB_WORKSPACE}/coverage/coverage.json /p:Exclude=\"[Neo.SmartContract.*]*,[Neo.Compiler.MSIL.UnitTests]*,[Neo.Compiler.MSIL.UnitTests.*]*\" /p:CoverletOutputFormat=lcov
- name: Test Template.NEP17.UnitTests
run: dotnet test tests/Template.NEP17.UnitTests /p:CollectCoverage=true /p:CoverletOutput=${GITHUB_WORKSPACE}/coverage/lcov /p:MergeWith=${GITHUB_WORKSPACE}/coverage/coverage.json /p:Exclude=\"[Neo.SmartContract.*]*,[Neo.Compiler.MSIL.UnitTests]*,[Neo.Compiler.MSIL.UnitTests.*]*\" /p:CoverletOutputFormat=lcov
- name: Coveralls
uses: coverallsapp/github-action@master
with:
Expand Down
4 changes: 2 additions & 2 deletions neo-devpack-dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D5266066-0AFD-44D5-A83E-2F73668A63C8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Template.NEP5.CSharp", "templates\Template.NEP5.CSharp\Template.NEP5.CSharp.csproj", "{ADD05222-DC45-4FDC-A41A-30A97BACC95F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Template.NEP17.CSharp", "templates\Template.NEP17.CSharp\Template.NEP17.CSharp.csproj", "{ADD05222-DC45-4FDC-A41A-30A97BACC95F}"
ProjectSection(ProjectDependencies) = postProject
{42C0FF0F-0A7C-4166-A773-1F944642C209} = {42C0FF0F-0A7C-4166-A773-1F944642C209}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Template.NEP5.UnitTests", "tests\Template.NEP5.UnitTests\Template.NEP5.UnitTests.csproj", "{780141EE-D6E9-4591-8470-8F91B12027CA}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Template.NEP17.UnitTests", "tests\Template.NEP17.UnitTests\Template.NEP17.UnitTests.csproj", "{780141EE-D6E9-4591-8470-8F91B12027CA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
3 changes: 1 addition & 2 deletions src/Neo.Compiler.MSIL/DebugExport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,12 @@ private static JArray GetDocuments(IReadOnlyDictionary<string, int> docMap)
return outjson;
}

public static JObject Export(NeoModule module, byte[] script, IReadOnlyDictionary<int, int> addrConvTable)
public static JObject Export(NeoModule module, IReadOnlyDictionary<int, int> addrConvTable)
{
var docMap = GetDocumentMap(module);
addrConvTable ??= ImmutableDictionary<int, int>.Empty;

var outjson = new JObject();
outjson["hash"] = FuncExport.ComputeHash(script);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@devhawk do you need the name in debugExport?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need whatever unique identifier is used to identify the contract.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a design document describing how contract deploy and invoke is supposed to work now? I am all for having a stable contract identifier other than the script hash, though it's not clear what the new design is?

One question - Have we considered the impact on dynamic contract invocations scenarios. Using script hash to invoke a contract means that any calling contracts break when a dependent contract is updated. That is, I was calling a specific contract by script hash it will be obvious something has changed if that script hash is no longer valid. With a stable identifier, will it still be obvious if a dependent contract has made a backwards incompatible change?

Copy link
Member

@vncoelho vncoelho Nov 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @devhawk, thinking in this perspective you mentioned, it may be important to create a flag that says that the contract trust any update on the dynamic invoked contract.
For instance, most of the DeFi projects are relying on external dynamic invoked contracts. In this sense, consider the need of mutual update is something plausible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect that dynamic invoke scenarios always require "mutual update" as you called it @vncoelho. I'm not sure it's a good idea to make the change less obvious. Right now, if you update your contract it breaks anyone who calls it since the hash changes. If we keep the hash, will that allow a developer to publish a malicious contract update w/o their users noticing?

// outjson["entrypoint"]= module.mainMethod;
outjson["documents"] = GetDocuments(docMap);
outjson["methods"] = GetMethods(module, docMap, addrConvTable);
Expand Down
29 changes: 8 additions & 21 deletions src/Neo.Compiler.MSIL/FuncExport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,29 +64,10 @@ internal static string ConvType(TypeReference t)
return "Unknown:" + type;
}

public static string ComputeHash(byte[] script)
{
var sha256 = System.Security.Cryptography.SHA256.Create();
byte[] hash256 = sha256.ComputeHash(script);
var ripemd160 = new Neo.Cryptography.RIPEMD160Managed();
var hash = ripemd160.ComputeHash(hash256);

StringBuilder sb = new StringBuilder();
sb.Append("0x");
for (int i = hash.Length - 1; i >= 0; i--)
{
sb.Append(hash[i].ToString("x02"));
}
return sb.ToString();
}

public static JObject Export(NeoModule module, byte[] script, Dictionary<int, int> addrConvTable)
public static JObject GenerateAbi(NeoModule module, Dictionary<int, int> addrConvTable)
{
var outjson = new JObject();

//hash
outjson["hash"] = ComputeHash(script);

shargon marked this conversation as resolved.
Show resolved Hide resolved
//functions
var methods = new JArray();
outjson["methods"] = methods;
Expand Down Expand Up @@ -217,10 +198,16 @@ public static string GenerateManifest(JObject abi, NeoModule module)
var extra = BuildExtraAttributes(extraAttributes);
var supportedStandards = BuildSupportedStandards(supportedStandardsAttribute);

var name = module.attributes
.Where(u => u.AttributeType.FullName == "System.ComponentModel.DisplayNameAttribute")
.Select(u => ScapeJson((string)u.ConstructorArguments.FirstOrDefault().Value))
.FirstOrDefault() ?? "";

return
@"{""groups"":[],""abi"":" +
sbABI +
@",""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""supportedstandards"":" + supportedStandards + @",""extra"":" + extra + "}";
@",""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""name"":""" + name +
@""",""supportedstandards"":" + supportedStandards + @",""extra"":" + extra + "}";
}
}
}
2 changes: 1 addition & 1 deletion src/Neo.Compiler.MSIL/Neo.Compiler.MSIL.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="3.4.0" />
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
<PackageReference Include="Neo" Version="3.0.0-CI01068" />
<PackageReference Include="Neo" Version="3.0.0-CI01089" />
</ItemGroup>

<ItemGroup>
Expand Down
9 changes: 4 additions & 5 deletions src/Neo.Compiler.MSIL/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public static int Compile(Options options, ILogger log = null)

try
{
abi = FuncExport.Export(module, bytes, addrConvTable);
abi = FuncExport.GenerateAbi(module, addrConvTable);
log.Log("gen abi succ");
}
catch (Exception err)
Expand All @@ -191,7 +191,7 @@ public static int Compile(Options options, ILogger log = null)

try
{
var outjson = DebugExport.Export(module, bytes, addrConvTable);
var outjson = DebugExport.Export(module, addrConvTable);
debugstr = outjson.ToString(false);
log.Log("gen debug succ");
}
Expand All @@ -215,9 +215,8 @@ public static int Compile(Options options, ILogger log = null)
{
Compiler = "neon",
Version = Version.Parse(((AssemblyFileVersionAttribute)Assembly.GetAssembly(typeof(Program))
.GetCustomAttribute(typeof(AssemblyFileVersionAttribute))).Version),
Script = bytes,
ScriptHash = bytes.ToScriptHash()
.GetCustomAttribute(typeof(AssemblyFileVersionAttribute))).Version).ToString(),
Script = bytes
};
nef.CheckSum = NefFile.ComputeChecksum(nef);

Expand Down
21 changes: 13 additions & 8 deletions src/Neo.SmartContract.Framework/Services/Neo/Contract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,29 @@ namespace Neo.SmartContract.Framework.Services.Neo
public class Contract
{
/// <summary>
/// Script
/// Id
/// </summary>
public readonly byte[] Script;
public readonly int Id;

/// <summary>
/// Manifest
/// UpdateCounter
/// </summary>
public readonly string Manifest;
public readonly ushort UpdateCounter;

/// <summary>
/// Has storage
/// Hash
/// </summary>
public readonly bool HasStorage;
public readonly UInt160 Hash;

/// <summary>
/// Is payable
/// Script
/// </summary>
public readonly bool IsPayable;
public readonly byte[] Script;

/// <summary>
/// Manifest
/// </summary>
public readonly string Manifest;

[Syscall("System.Contract.Call")]
public static extern object Call(UInt160 scriptHash, string method, object[] arguments);
Expand Down
3 changes: 1 addition & 2 deletions src/Neo.SmartContract.Framework/Services/Neo/Designation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

namespace Neo.SmartContract.Framework.Services.Neo
{
[Contract("0x763afecf3ebba0a67568a2c8be06e8f068c62666")]
[Contract("0x7062149f9377e3a110a343f811b9e406f8ef7824")]
public class Designation
{
public static extern UInt160 Hash { [ContractHash] get; }
public static extern string Name { get; }
public static extern Cryptography.ECC.ECPoint[] GetDesignatedByRole(DesignationRole role, uint index);
}
}
5 changes: 2 additions & 3 deletions src/Neo.SmartContract.Framework/Services/Neo/GAS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@

namespace Neo.SmartContract.Framework.Services.Neo
{
[Contract("0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc")]
[Contract("0x36a019d836d964c438c573f78badf79b9e7eebdd")]
public class GAS
{
public static extern UInt160 Hash { [ContractHash] get; }
public static extern string Name { get; }
public static extern string Symbol { get; }
public static extern byte Decimals { get; }
public static extern BigInteger TotalSupply();
public static extern BigInteger BalanceOf(UInt160 account);
public static extern bool Transfer(UInt160 from, UInt160 to, BigInteger amount);
public static extern bool Transfer(UInt160 from, UInt160 to, BigInteger amount, object data);
}
}
5 changes: 2 additions & 3 deletions src/Neo.SmartContract.Framework/Services/Neo/NEO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@

namespace Neo.SmartContract.Framework.Services.Neo
{
[Contract("0xde5f57d430d3dece511cf975a8d37848cb9e0525")]
[Contract("0xe22f9134cef8b03e53f71b3f960a20a65cddc972")]
public class NEO
{
public static extern UInt160 Hash { [ContractHash] get; }
public static extern string Name { get; }
public static extern string Symbol { get; }
public static extern byte Decimals { get; }
public static extern BigInteger TotalSupply();
public static extern BigInteger BalanceOf(UInt160 account);
public static extern bool Transfer(UInt160 from, UInt160 to, BigInteger amount);
public static extern bool Transfer(UInt160 from, UInt160 to, BigInteger amount, object data);

public static extern bool SetGasPerBlock(BigInteger gasPerBlock);
public static extern BigInteger GetGasPerBlock();
Expand Down
3 changes: 1 addition & 2 deletions src/Neo.SmartContract.Framework/Services/Neo/Oracle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

namespace Neo.SmartContract.Framework.Services.Neo
{
[Contract("0x3c05b488bf4cf699d0631bf80190896ebbf38c3b")]
[Contract("0x35e4fc2e69a4d04d1db4d755c4150c50aff2e9a9")]
public class Oracle
{
public static extern UInt160 Hash { [ContractHash] get; }
public const uint MinimumResponseFee = 0_10000000;
public static extern string Name { get; }
public static extern void Request(string url, string filter, string callback, object userData, long gasForResponse);
}
}
4 changes: 1 addition & 3 deletions src/Neo.SmartContract.Framework/Services/Neo/Policy.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
#pragma warning disable CS0626

using System;
using System.Numerics;

namespace Neo.SmartContract.Framework.Services.Neo
{
[Contract("0xce06595079cd69583126dbfd1d2e25cca74cffe9")]
[Contract("0x1ca594b36b6b6b3f05efce8b106c824053d18713")]
public class Policy
{
public static extern UInt160 Hash { [ContractHash] get; }
public static extern string Name();
public static extern uint GetMaxTransactionsPerBlock();
public static extern uint GetMaxBlockSize();
public static extern long GetMaxBlockSystemFee();
Expand Down
20 changes: 20 additions & 0 deletions src/Neo.SmartContract.Framework/UInt160.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@ public extern bool IsZero
get;
}

public extern int Size
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
{
[OpCode(OpCode.SIZE)]
get;
}

public extern bool IsValid
{
[OpCode(OpCode.DUP)]
[OpCode(OpCode.ISNULL)]
[OpCode(OpCode.JMPIF, "0x08")]
[OpCode(OpCode.SIZE)]
[OpCode(OpCode.PUSHINT8, "14")] // 0x14 == 20 bytes expected array size
[OpCode(OpCode.NUMEQUAL)]
[OpCode(OpCode.JMP, "0x04")]
[OpCode(OpCode.DROP)]
[OpCode(OpCode.PUSH0)]
shargon marked this conversation as resolved.
Show resolved Hide resolved
get;
}

[OpCode(OpCode.CONVERT, StackItemType.ByteString)]
[OpCode(OpCode.DUP)]
[OpCode(OpCode.SIZE)]
Expand Down
20 changes: 20 additions & 0 deletions src/Neo.SmartContract.Framework/UInt256.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@ public extern bool IsZero
get;
}

public extern int Size
{
[OpCode(OpCode.SIZE)]
get;
}

public extern bool IsValid
{
[OpCode(OpCode.DUP)]
[OpCode(OpCode.ISNULL)]
[OpCode(OpCode.JMPIF, "0x08")]
[OpCode(OpCode.SIZE)]
[OpCode(OpCode.PUSHINT8, "20")] // 0x20 == 32 bytes expected array size
[OpCode(OpCode.NUMEQUAL)]
[OpCode(OpCode.JMP, "0x04")]
[OpCode(OpCode.DROP)]
[OpCode(OpCode.PUSH0)]
get;
}

[OpCode(OpCode.CONVERT, StackItemType.ByteString)]
[OpCode(OpCode.DUP)]
[OpCode(OpCode.SIZE)]
Expand Down
47 changes: 47 additions & 0 deletions templates/Template.NEP17.CSharp/NEP17.Crowdsale.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Neo;
using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Services.Neo;
using Neo.SmartContract.Framework.Services.System;
using System;
using System.Numerics;

namespace Template.NEP17.CSharp
{
public partial class NEP17 : SmartContract
{
public static void OnPayment(UInt160 from, BigInteger amount, object data)
{
if (AssetStorage.GetPaymentStatus())
{
if (ExecutionEngine.CallingScriptHash == NEO.Hash)
Mint(amount * TokensPerNEO);
else if (ExecutionEngine.CallingScriptHash == GAS.Hash && from != null)
Mint(amount * TokensPerGAS);
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
else
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
throw new Exception("Wrong calling script hash");
}
else
{
throw new Exception("Payment is disable on this contract!");
}
}

private static bool Mint(BigInteger amount)
{
var totalSupply = TotalSupplyStorage.Get();
if (totalSupply <= 0) throw new Exception("Contract not deployed.");

var avaliable_supply = MaxSupply - totalSupply;

if (amount <= 0) throw new Exception("Amount cannot be zero.");
if (amount > avaliable_supply) throw new Exception("Insufficient supply for mint tokens.");

Transaction tx = (Transaction)ExecutionEngine.ScriptContainer;
AssetStorage.Increase(tx.Sender, amount);
TotalSupplyStorage.Increase(amount);

OnTransfer(null, tx.Sender, amount);
return true;
}
}
}
12 changes: 12 additions & 0 deletions templates/Template.NEP17.CSharp/NEP17.Helpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Neo;
using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Services.Neo;

namespace Template.NEP17.CSharp
{
public partial class NEP17 : SmartContract
{
private static bool ValidateAddress(UInt160 address) => address.IsValid && !address.IsZero;
private static bool IsDeployed(UInt160 address) => Blockchain.GetContract(address) != null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
using System;
using System.Numerics;

namespace Template.NEP5.CSharp
namespace Template.NEP17.CSharp
{
public partial class NEP5 : SmartContract
public partial class NEP17 : SmartContract
{
public static BigInteger TotalSupply() => TotalSupplyStorage.Get();

Expand All @@ -17,11 +17,10 @@ public static BigInteger BalanceOf(UInt160 account)
return AssetStorage.Get(account);
}

public static bool Transfer(UInt160 from, UInt160 to, BigInteger amount)
public static bool Transfer(UInt160 from, UInt160 to, BigInteger amount, object data)
{
if (!ValidateAddress(from) || !ValidateAddress(to)) throw new Exception("The parameters from and to SHOULD be 20-byte non-zero addresses.");
if (amount <= 0) throw new Exception("The parameter amount MUST be greater than 0.");
if (!IsPayable(to)) throw new Exception("Receiver cannot receive.");
if (!Runtime.CheckWitness(from) && !from.Equals(ExecutionEngine.CallingScriptHash)) throw new Exception("No authorization.");
if (AssetStorage.Get(from) < amount) throw new Exception("Insufficient balance.");
if (from == to) return true;
Expand All @@ -30,6 +29,9 @@ public static bool Transfer(UInt160 from, UInt160 to, BigInteger amount)
AssetStorage.Increase(to, amount);

OnTransfer(from, to, amount);

// Validate payable
if (IsDeployed(to)) Contract.Call(to, "onPayment", new object[] { from, amount, data });
return true;
}
}
Expand Down
Loading