Skip to content

Commit

Permalink
Merge pull request #16 from shargon/other-version
Browse files Browse the repository at this point in the history
Without appcall
  • Loading branch information
shargon authored Jul 30, 2020
2 parents e8d59a9 + 6b7ce69 commit ea03ae6
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 29 deletions.
10 changes: 8 additions & 2 deletions src/neo/SmartContract/ApplicationEngine.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ partial class ApplicationEngine
public static readonly InteropDescriptor System_Runtime_GetExecutingScriptHash = Register("System.Runtime.GetExecutingScriptHash", nameof(CurrentScriptHash), 0_00000400, CallFlags.None, true);
public static readonly InteropDescriptor System_Runtime_GetCallingScriptHash = Register("System.Runtime.GetCallingScriptHash", nameof(CallingScriptHash), 0_00000400, CallFlags.None, true);
public static readonly InteropDescriptor System_Runtime_GetEntryScriptHash = Register("System.Runtime.GetEntryScriptHash", nameof(EntryScriptHash), 0_00000400, CallFlags.None, true);
public static readonly InteropDescriptor System_Runtime_CheckWitness = Register("System.Runtime.CheckWitness", nameof(CheckWitness), 0_00030000, CallFlags.AllowStates, true);
public static readonly InteropDescriptor System_Runtime_CheckWitness = Register("System.Runtime.CheckWitness", nameof(CheckWitness), 0_00030000, CallFlags.None, true);
public static readonly InteropDescriptor System_Runtime_GetInvocationCounter = Register("System.Runtime.GetInvocationCounter", nameof(GetInvocationCounter), 0_00000400, CallFlags.None, true);
public static readonly InteropDescriptor System_Runtime_Log = Register("System.Runtime.Log", nameof(RuntimeLog), 0_01000000, CallFlags.AllowNotify, false);
public static readonly InteropDescriptor System_Runtime_Notify = Register("System.Runtime.Notify", nameof(RuntimeNotify), 0_01000000, CallFlags.AllowNotify, false);
Expand Down Expand Up @@ -109,7 +109,7 @@ internal bool CheckWitnessInternal(UInt160 hash)
if (signer.Scopes == WitnessScope.Global) return true;
if (signer.Scopes.HasFlag(WitnessScope.CalledByEntry))
{
if (CallingScriptHash == EntryScriptHash)
if (CallingScriptHash == null || CallingScriptHash == EntryScriptHash)
return true;
}
if (signer.Scopes.HasFlag(WitnessScope.CustomContracts))
Expand All @@ -127,6 +127,12 @@ internal bool CheckWitnessInternal(UInt160 hash)
return false;
}

// Check allow state callflag

ExecutionContextState state = CurrentContext.GetState<ExecutionContextState>();
if (!state.CallFlags.HasFlag(CallFlags.AllowStates))
throw new InvalidOperationException($"Cannot call this SYSCALL with the flag {state.CallFlags}.");

// only for non-Transaction types (Block, etc)

var hashes_for_verifying = ScriptContainer.GetScriptHashesForVerifying(Snapshot);
Expand Down
6 changes: 2 additions & 4 deletions src/neo/SmartContract/DeployedContract.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
using Neo.Ledger;
using Neo.SmartContract.Manifest;
using System;
using System.Linq;

namespace Neo.SmartContract
{
public class DeployedContract : Contract
{
public override UInt160 ScriptHash { get; }

public ContractParameterDefinition[] VerifyArguments { get; }

public DeployedContract(ContractState contract)
{
if (contract == null) throw new ArgumentNullException(nameof(contract));
Expand All @@ -19,8 +18,7 @@ public DeployedContract(ContractState contract)
ContractMethodDescriptor descriptor = contract.Manifest.Abi.GetMethod("verify");
if (descriptor == null) throw new ArgumentNullException("The smart contract haven't got verify method.");

VerifyArguments = descriptor.Parameters;
ParameterList = new ContractParameterType[] { ContractParameterType.Array };
ParameterList = descriptor.Parameters.Select(u => u.Type).ToArray();
}
}
}
15 changes: 8 additions & 7 deletions src/neo/SmartContract/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,27 +146,28 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap
if (hashes.Length != verifiable.Witnesses.Length) return false;
for (int i = 0; i < hashes.Length; i++)
{
int offset;
ContractMethodDescriptor init = null;
byte[] verification = verifiable.Witnesses[i].VerificationScript;
if (verification.Length == 0)
{
ContractState cs = snapshot.Contracts.TryGet(hashes[i]);
if (cs is null) return false;
ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod("verify");
if (md is null) return false;

using var sb = new ScriptBuilder();
sb.EmitPush("verify");
sb.EmitPush(cs.ScriptHash);
sb.EmitSysCall(ApplicationEngine.System_Contract_Call);
verification = sb.ToArray();
verification = cs.Script;
offset = md.Offset;
init = cs.Manifest.Abi.GetMethod("_initialize");
}
else
{
if (hashes[i] != verifiable.Witnesses[i].ScriptHash) return false;
offset = 0;
}
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot.Clone(), gas))
{
engine.LoadScript(verification, CallFlags.ReadOnly);
engine.LoadScript(verification, CallFlags.None).InstructionPointer = offset;
if (init != null) engine.LoadClonedContext(init.Offset);
engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None);
if (engine.Execute() == VMState.FAULT) return false;
if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) return false;
Expand Down
24 changes: 8 additions & 16 deletions src/neo/Wallets/Wallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -381,26 +381,18 @@ private Transaction MakeTransaction(StoreView snapshot, byte[] script, Signer[]

public static long CalculateNetworkFee(StoreView snapshot, Transaction tx, ContractState contract, ref int size)
{
// Empty verification scripts and PACK 0 as invocation
size += Array.Empty<byte>().GetVarSize() + (IO.Helper.GetVarSize(2) + 2);
// Empty invocation and verification scripts
size += Array.Empty<byte>().GetVarSize() * 2;

// Check verify cost
ContractMethodDescriptor verify = contract.Manifest.Abi.GetMethod("verify");
if (verify is null) throw new ArgumentException($"The smart contract {contract.ScriptHash} haven't got verify method");

using var invocation = new ScriptBuilder();
invocation.EmitPush(0);
invocation.Emit(OpCode.PACK);

using var verification = new ScriptBuilder();
verification.EmitPush("verify");
verification.EmitPush(contract.ScriptHash);
verification.EmitSysCall(ApplicationEngine.System_Contract_Call);

ContractMethodDescriptor init = contract.Manifest.Abi.GetMethod("_initialize");
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.Clone(), 0, testMode: true))
{
engine.LoadScript(verification.ToArray(), CallFlags.ReadOnly);
engine.LoadScript(invocation.ToArray(), CallFlags.None);
engine.LoadScript(contract.Script, CallFlags.None).InstructionPointer = verify.Offset;
if (init != null) engine.LoadClonedContext(init.Offset);
engine.LoadScript(Array.Empty<byte>(), CallFlags.None);
if (engine.Execute() == VMState.FAULT) throw new ArgumentException($"Smart contract {contract.ScriptHash} verification fault.");
if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) throw new ArgumentException($"Smart contract {contract.ScriptHash} returns false.");

Expand Down Expand Up @@ -486,9 +478,9 @@ public bool Sign(ContractParametersContext context)

// Only works with verify without parameters

if (deployed.VerifyArguments.Length == 0)
if (deployed.ParameterList.Length == 0)
{
fSuccess |= context.Add(new DeployedContract(contract), new object[] { new ContractParameter[0] { } });
fSuccess |= context.Add(new DeployedContract(contract), new object[0]);
}
}
}
Expand Down

0 comments on commit ea03ae6

Please sign in to comment.