Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c937be2
If exists
shargon Oct 26, 2020
a374286
Call onPayment if to it's a smart contract
shargon Oct 27, 2020
427a595
Increase cost in transfer
shargon Oct 27, 2020
1da0df6
Merge branch 'master' into allow-call-if-exists
shargon Oct 27, 2020
153c250
Remove Mint check
shargon Oct 27, 2020
8179ae3
Merge remote-tracking branch 'origin/allow-call-if-exists' into allow…
shargon Oct 27, 2020
2d909a0
Merge branch 'master' into allow-call-if-exists
shargon Oct 28, 2020
bbffc39
return
shargon Oct 28, 2020
772b566
Remove extra args
shargon Oct 28, 2020
ec0264a
Drop result
shargon Oct 29, 2020
7b59c50
Merge branch 'master' into allow-call-if-exists
shargon Oct 29, 2020
a87d7f3
Clean code
shargon Oct 29, 2020
ec77bc9
Merge remote-tracking branch 'origin/allow-call-if-exists' into allow…
shargon Oct 29, 2020
5074b27
Merge branch 'master' into allow-call-if-exists
shargon Nov 4, 2020
fde07e8
Method.Exists
shargon Nov 4, 2020
849ce9a
Merge remote-tracking branch 'origin/allow-call-if-exists' into allow…
shargon Nov 4, 2020
2f4ae86
Rename
erikzhang Nov 5, 2020
9bb5e85
protected
erikzhang Nov 5, 2020
fb0128e
Update ApplicationEngine.Contract.cs
erikzhang Nov 5, 2020
a4e9e5b
Merge branch 'master' into allow-call-if-exists
shargon Nov 10, 2020
259be1e
Fix merge
shargon Nov 10, 2020
7aef12a
Merge branch 'master' into allow-call-if-exists
shargon Nov 12, 2020
41a0871
Add Name in Extra
shargon Nov 12, 2020
93c4cfd
Name in manifest
shargon Nov 12, 2020
2d6d40a
Merge remote-tracking branch 'neo-project/master' into allow-call-if-…
shargon Nov 12, 2020
af57798
Fix UT
shargon Nov 12, 2020
6a03132
dotnet format
shargon Nov 12, 2020
dfb2f06
Remove Method.Exists
shargon Nov 13, 2020
202c005
Clean code
shargon Nov 13, 2020
de0fabb
Move filed `Name`
erikzhang Nov 15, 2020
d43e7ee
Rename
erikzhang Nov 15, 2020
ce9876b
Update null checks
erikzhang Nov 15, 2020
5f7630d
Fix CallFromNativeContract parameters
erikzhang Nov 15, 2020
b774259
Update AssetDescriptor.cs
erikzhang Nov 15, 2020
a75d5f0
Fix UT
erikzhang Nov 15, 2020
6734e60
format
erikzhang Nov 15, 2020
06517a5
Shargon's suggestion
erikzhang Nov 17, 2020
d33ff2f
Update src/neo/SmartContract/Native/Tokens/Nep17Token.cs
erikzhang Nov 18, 2020
93f6f5c
Merge branch 'master' into allow-call-if-exists
erikzhang Nov 18, 2020
134e024
Fix
erikzhang Nov 18, 2020
fff5001
Merge branch 'master' into allow-call-if-exists
erikzhang Nov 18, 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
15 changes: 13 additions & 2 deletions src/neo/SmartContract/ApplicationEngine.Contract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ partial class ApplicationEngine
public static readonly InteropDescriptor System_Contract_Create = Register("System.Contract.Create", nameof(CreateContract), 0, CallFlags.AllowModifyStates, false);
public static readonly InteropDescriptor System_Contract_Update = Register("System.Contract.Update", nameof(UpdateContract), 0, CallFlags.AllowModifyStates, false);
public static readonly InteropDescriptor System_Contract_Destroy = Register("System.Contract.Destroy", nameof(DestroyContract), 0_01000000, CallFlags.AllowModifyStates, false);
public static readonly InteropDescriptor System_Contract_Exists = Register("System.Contract.Exists", nameof(ContractExists), 0_01000000, CallFlags.AllowCall, false);
public static readonly InteropDescriptor System_Contract_Call = Register("System.Contract.Call", nameof(CallContract), 0_01000000, CallFlags.AllowCall, false);
public static readonly InteropDescriptor System_Contract_CallEx = Register("System.Contract.CallEx", nameof(CallContractEx), 0_01000000, CallFlags.AllowCall, false);
public static readonly InteropDescriptor System_Contract_IsStandard = Register("System.Contract.IsStandard", nameof(IsStandardContract), 0_00030000, CallFlags.AllowStates, true);
Expand Down Expand Up @@ -118,6 +119,16 @@ protected internal void DestroyContract()
Snapshot.Storages.Delete(key);
}

internal bool ContractExists(UInt160 contractHash, string method)
{
if (contractHash is null) return false;

ContractState contract = Snapshot.Contracts.TryGet(contractHash);
if (contract is null) return false;

return method == null || contract.Manifest.Abi.GetMethod(method) != null;
}

protected internal void CallContract(UInt160 contractHash, string method, Array args)
{
CallContractInternal(contractHash, method, args, CallFlags.All);
Expand All @@ -130,7 +141,7 @@ protected internal void CallContractEx(UInt160 contractHash, string method, Arra
CallContractInternal(contractHash, method, args, callFlags);
}

private void CallContractInternal(UInt160 contractHash, string method, Array args, CallFlags flags)
protected internal void CallContractInternal(UInt160 contractHash, string method, Array args, CallFlags flags, CheckReturnType returnType = CheckReturnType.EnsureNotEmpty)
{
if (method.StartsWith('_')) throw new ArgumentException($"Invalid Method Name: {method}");

Expand All @@ -143,7 +154,7 @@ private void CallContractInternal(UInt160 contractHash, string method, Array arg
if (currentManifest != null && !currentManifest.CanCall(contract.Manifest, method))
throw new InvalidOperationException($"Cannot Call Method {method} Of Contract {contractHash} From Contract {CurrentScriptHash}");

CallContractInternal(contract, md, args, flags, CheckReturnType.EnsureNotEmpty);
CallContractInternal(contract, md, args, flags, returnType);
}

private void CallContractInternal(ContractState contract, ContractMethodDescriptor method, Array args, CallFlags flags, CheckReturnType checkReturnValue)
Expand Down
12 changes: 10 additions & 2 deletions src/neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ namespace Neo.SmartContract
{
public partial class ApplicationEngine : ExecutionEngine
{
private enum CheckReturnType : byte
protected internal enum CheckReturnType : byte
{
None = 0,
EnsureIsEmpty = 1,
EnsureNotEmpty = 2
EnsureNotEmpty = 2,
DropResult = 3
}

private class InvocationState
Expand Down Expand Up @@ -120,6 +121,13 @@ protected override void ContextUnloaded(ExecutionContext context)
throw new InvalidOperationException();
break;
}
case CheckReturnType.DropResult:
{
if (context.EvaluationStack.Count == 1)
context.EvaluationStack.Pop();
else throw new InvalidOperationException();
break;
}
}
switch (state.Callback)
{
Expand Down
22 changes: 18 additions & 4 deletions src/neo/SmartContract/Native/Tokens/Nep5Token.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,21 @@ internal protected virtual void Mint(ApplicationEngine engine, UInt160 account,
state.Balance += amount;
storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_TotalSupply), () => new StorageItem(BigInteger.Zero));
storage.Add(amount);
engine.SendNotification(Hash, "Transfer", new Array { StackItem.Null, account.ToArray(), amount });
onPostTransfer(engine, null, account, amount);
}

private void onPostTransfer(ApplicationEngine engine, UInt160 from, UInt160 to, BigInteger amount)
{
// Send notification

engine.SendNotification(Hash, "Transfer",
new Array { from == null ? StackItem.Null : from.ToArray(), to == null ? StackItem.Null : to.ToArray(), amount });

if (!engine.ContractExists(to, "onPayment")) return;
Copy link
Contributor

Choose a reason for hiding this comment

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

Hi Shargon, I noticed that now neo is doing some method checks using hardcoded strings for method names ('verify', for example). I believe this may cause some issues in the future. First 'verify', now 'onPayment'. Maybe the manifest file should have a section to map these methods into ABI methods. This way, instead of checking only if the method exists, you would get the name of it first, and if it exists, execute it.

Copy link
Member Author

Choose a reason for hiding this comment

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

instead of checking only if the method exists, you would get the name of it first, and if it exists, execute it.

Could you give me an example, i don't see the difference right now. 😕

Copy link
Contributor

Choose a reason for hiding this comment

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


// Call onPayment method if exists

engine.CallContractInternal(to, "onPayment", new Array(engine.ReferenceCounter) { amount }, CallFlags.All, ApplicationEngine.CheckReturnType.DropResult);
}

internal protected virtual void Burn(ApplicationEngine engine, UInt160 account, BigInteger amount)
Expand All @@ -86,7 +100,7 @@ internal protected virtual void Burn(ApplicationEngine engine, UInt160 account,
state.Balance -= amount;
storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_TotalSupply));
storage.Add(-amount);
engine.SendNotification(Hash, "Transfer", new Array { account.ToArray(), StackItem.Null, amount });
onPostTransfer(engine, account, null, amount);
}

[ContractMethod(0_01000000, CallFlags.AllowStates)]
Expand All @@ -105,7 +119,7 @@ public virtual BigInteger BalanceOf(StoreView snapshot, UInt160 account)
return storage.GetInteroperable<TState>().Balance;
}

[ContractMethod(0_08000000, CallFlags.AllowModifyStates)]
[ContractMethod(0_09000000, CallFlags.AllowModifyStates)]
protected virtual bool Transfer(ApplicationEngine engine, UInt160 from, UInt160 to, BigInteger amount)
{
if (amount.Sign < 0) throw new ArgumentOutOfRangeException(nameof(amount));
Expand Down Expand Up @@ -146,7 +160,7 @@ protected virtual bool Transfer(ApplicationEngine engine, UInt160 from, UInt160
state_to.Balance += amount;
}
}
engine.SendNotification(Hash, "Transfer", new Array { from.ToArray(), to.ToArray(), amount });
onPostTransfer(engine, from, to, amount);
return true;
}

Expand Down