Skip to content

Commit

Permalink
Allow deployed contract as verification script
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang committed Jun 25, 2019
1 parent a9b3ee7 commit f253fae
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 8 deletions.
2 changes: 1 addition & 1 deletion neo.UnitTests/TestUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public static Transaction CreateRandomHashTransaction()
new Witness
{
InvocationScript = new byte[0],
VerificationScript = new byte[1]
VerificationScript = new byte[0]
}
}
};
Expand Down
4 changes: 1 addition & 3 deletions neo/Network/P2P/Payloads/Witness.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Neo.IO;
using Neo.IO.Json;
using Neo.SmartContract;
using System;
using Neo.VM;
using System.IO;

namespace Neo.Network.P2P.Payloads
Expand Down Expand Up @@ -30,8 +30,6 @@ void ISerializable.Deserialize(BinaryReader reader)
{
InvocationScript = reader.ReadVarBytes(65536);
VerificationScript = reader.ReadVarBytes(65536);
if (VerificationScript.Length == 0)
throw new FormatException();
}

void ISerializable.Serialize(BinaryWriter writer)
Expand Down
13 changes: 11 additions & 2 deletions neo/SmartContract/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,19 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, Snapshot snaps
if (hashes.Length != verifiable.Witnesses.Length) return false;
for (int i = 0; i < hashes.Length; i++)
{
if (hashes[i] != verifiable.Witnesses[i].ScriptHash) return false;
byte[] verification = verifiable.Witnesses[i].VerificationScript;
if (verification.Length == 0)
{
verification = snapshot.Contracts.TryGet(hashes[i])?.Script;
if (verification is null) return false;
}
else
{
if (hashes[i] != verifiable.Witnesses[i].ScriptHash) return false;
}
using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, verifiable, snapshot, gas))
{
engine.LoadScript(verifiable.Witnesses[i].VerificationScript);
engine.LoadScript(verification);
engine.LoadScript(verifiable.Witnesses[i].InvocationScript);
if (engine.Execute().HasFlag(VMState.FAULT)) return false;
if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) return false;
Expand Down
4 changes: 2 additions & 2 deletions neo/SmartContract/InteropService.NEO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ private static bool Transaction_GetWitnesses(ApplicationEngine engine)
if (tx == null) return false;
if (tx.Witnesses.Length > engine.MaxArraySize)
return false;
engine.CurrentContext.EvaluationStack.Push(tx.Witnesses.Select(p => StackItem.FromInterface(p)).ToArray());
engine.CurrentContext.EvaluationStack.Push(WitnessWrapper.Create(tx, engine.Snapshot).Select(p => StackItem.FromInterface(p)).ToArray());
return true;
}
return false;
Expand All @@ -224,7 +224,7 @@ private static bool Witness_GetVerificationScript(ApplicationEngine engine)
{
if (engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface)
{
Witness witness = _interface.GetInterface<Witness>();
WitnessWrapper witness = _interface.GetInterface<WitnessWrapper>();
if (witness == null) return false;
engine.CurrentContext.EvaluationStack.Push(witness.VerificationScript);
return true;
Expand Down
27 changes: 27 additions & 0 deletions neo/SmartContract/WitnessWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using System.Linq;

namespace Neo.SmartContract
{
internal class WitnessWrapper
{
public byte[] VerificationScript;

public static WitnessWrapper[] Create(IVerifiable verifiable, Snapshot snapshot)
{
WitnessWrapper[] wrappers = verifiable.Witnesses.Select(p => new WitnessWrapper
{
VerificationScript = p.VerificationScript
}).ToArray();
if (wrappers.Any(p => p.VerificationScript.Length == 0))
{
UInt160[] hashes = verifiable.GetScriptHashesForVerifying(snapshot);
for (int i = 0; i < wrappers.Length; i++)
if (wrappers[i].VerificationScript.Length == 0)
wrappers[i].VerificationScript = snapshot.Contracts[hashes[i]].Script;
}
return wrappers;
}
}
}

0 comments on commit f253fae

Please sign in to comment.