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

Adding contact information to manifest #1246

Merged
merged 23 commits into from
Dec 13, 2019
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
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
25 changes: 17 additions & 8 deletions src/neo/SmartContract/Manifest/ContractManifest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Neo.IO;
using Neo.IO.Json;
using System.Collections.Generic;
using System.IO;
using System.Linq;

Expand Down Expand Up @@ -50,13 +51,18 @@ public class ContractManifest : ISerializable
/// The trusts field is an array containing a set of contract hashes or group public keys. It can also be assigned with a wildcard *. If it is a wildcard *, then it means that it trusts any contract.
/// If a contract is trusted, the user interface will not give any warnings when called by the contract.
/// </summary>
public WildCardContainer<UInt160> Trusts { get; set; }
public WildcardContainer<UInt160> Trusts { get; set; }

/// <summary>
/// The safemethods field is an array containing a set of method names. It can also be assigned with a wildcard *. If it is a wildcard *, then it means that all methods of the contract are safe.
/// If a method is marked as safe, the user interface will not give any warnings when it is called by any other contract.
/// </summary>
public WildCardContainer<string> SafeMethods { get; set; }
public WildcardContainer<string> SafeMethods { get; set; }

/// <summary>
/// Custom user data
/// </summary>
public JObject Extra { get; set; }

/// <summary>
/// Create Default Contract manifest
Expand All @@ -77,8 +83,9 @@ public static ContractManifest CreateDefault(UInt160 hash)
},
Features = ContractFeatures.NoProperty,
Groups = new ContractGroup[0],
SafeMethods = WildCardContainer<string>.Create(),
Trusts = WildCardContainer<UInt160>.Create()
SafeMethods = WildcardContainer<string>.Create(),
Trusts = WildcardContainer<UInt160>.Create(),
Extra = null,
};
}

Expand Down Expand Up @@ -128,6 +135,7 @@ public JObject ToJson()
json["permissions"] = Permissions.Select(p => p.ToJson()).ToArray();
json["trusts"] = Trusts.ToJson();
json["safeMethods"] = SafeMethods.ToJson();
json["extra"] = Extra;

return json;
}
Expand All @@ -145,7 +153,8 @@ public ContractManifest Clone()
Abi = Abi.Clone(),
Permissions = Permissions.Select(p => p.Clone()).ToArray(),
Trusts = Trusts,
SafeMethods = SafeMethods
SafeMethods = SafeMethods,
Extra = Extra
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
};
}

Expand All @@ -171,9 +180,9 @@ private void DeserializeFromJson(JObject json)
Groups = ((JArray)json["groups"]).Select(u => ContractGroup.FromJson(u)).ToArray();
Features = ContractFeatures.NoProperty;
Permissions = ((JArray)json["permissions"]).Select(u => ContractPermission.FromJson(u)).ToArray();
Trusts = WildCardContainer<UInt160>.FromJson(json["trusts"], u => UInt160.Parse(u.AsString()));
SafeMethods = WildCardContainer<string>.FromJson(json["safeMethods"], u => u.AsString());

Trusts = WildcardContainer<UInt160>.FromJson(json["trusts"], u => UInt160.Parse(u.AsString()));
SafeMethods = WildcardContainer<string>.FromJson(json["safeMethods"], u => u.AsString());
Extra = json["extra"];
if (json["features"]["storage"].AsBoolean()) Features |= ContractFeatures.HasStorage;
if (json["features"]["payable"].AsBoolean()) Features |= ContractFeatures.Payable;
}
Expand Down
6 changes: 3 additions & 3 deletions src/neo/SmartContract/Manifest/ContractPermission.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ public class ContractPermission
/// The methods field is an array containing a set of methods to be called. It can also be assigned with a wildcard *. If it is a wildcard *, then it means that any method can be called.
/// If a contract invokes a contract or method that is not declared in the manifest at runtime, the invocation will fail.
/// </summary>
public WildCardContainer<string> Methods { get; set; }
public WildcardContainer<string> Methods { get; set; }

public static readonly ContractPermission DefaultPermission = new ContractPermission
{
Contract = ContractPermissionDescriptor.CreateWildcard(),
Methods = WildCardContainer<string>.CreateWildcard()
Methods = WildcardContainer<string>.CreateWildcard()
};

public ContractPermission Clone()
Expand All @@ -46,7 +46,7 @@ public static ContractPermission FromJson(JObject json)
return new ContractPermission
{
Contract = ContractPermissionDescriptor.FromJson(json["contract"]),
Methods = WildCardContainer<string>.FromJson(json["methods"], u => u.AsString()),
Methods = WildcardContainer<string>.FromJson(json["methods"], u => u.AsString()),
};
}

Expand Down
10 changes: 5 additions & 5 deletions src/neo/SmartContract/Manifest/WildCardContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Neo.SmartContract.Manifest
{
public class WildCardContainer<T> : IReadOnlyList<T>
public class WildcardContainer<T> : IReadOnlyList<T>
{
private readonly T[] _data;

Expand All @@ -26,7 +26,7 @@ public class WildCardContainer<T> : IReadOnlyList<T>
/// Constructor
/// </summary>
/// <param name="data">Data</param>
private WildCardContainer(T[] data)
private WildcardContainer(T[] data)
{
_data = data;
}
Expand All @@ -36,15 +36,15 @@ private WildCardContainer(T[] data)
/// </summary>
/// <param name="data">Data</param>
/// <returns>WildCardContainer</returns>
public static WildCardContainer<T> Create(params T[] data) => new WildCardContainer<T>(data);
public static WildcardContainer<T> Create(params T[] data) => new WildcardContainer<T>(data);

/// <summary>
/// Create a wildcard
/// </summary>
/// <returns>WildCardContainer</returns>
public static WildCardContainer<T> CreateWildcard() => new WildCardContainer<T>(null);
public static WildcardContainer<T> CreateWildcard() => new WildcardContainer<T>(null);

public static WildCardContainer<T> FromJson(JObject json, Func<JObject, T> elementSelector)
public static WildcardContainer<T> FromJson(JObject json, Func<JObject, T> elementSelector)
{
switch (json)
{
Expand Down
2 changes: 1 addition & 1 deletion src/neo/SmartContract/Native/NativeContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ protected NativeContract()
});
}
this.Manifest.Abi.Methods = descriptors.ToArray();
this.Manifest.SafeMethods = WildCardContainer<string>.Create(safeMethods.ToArray());
this.Manifest.SafeMethods = WildcardContainer<string>.Create(safeMethods.ToArray());
contracts.Add(this);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/neo.UnitTests/Ledger/UT_ContractState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public void TestDeserialize()
public void TestGetSize()
{
ISerializable newContract = contract;
newContract.Size.Should().Be(355);
newContract.Size.Should().Be(368);
}

[TestMethod]
Expand Down
36 changes: 23 additions & 13 deletions tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Cryptography.ECC;
using Neo.IO.Json;
using Neo.SmartContract.Manifest;
using System.IO;

Expand All @@ -11,7 +12,7 @@ public class UT_ContractManifest
[TestMethod]
public void ParseFromJson_Default()
{
var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[]}";
var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":null}";
var manifest = ContractManifest.Parse(json);

Assert.AreEqual(manifest.ToString(), json);
Expand All @@ -22,7 +23,7 @@ public void ParseFromJson_Default()
[TestMethod]
public void ParseFromJson_Features()
{
var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[]}";
var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToJson().ToString(), json);

Expand All @@ -34,7 +35,7 @@ public void ParseFromJson_Features()
[TestMethod]
public void ParseFromJson_Permissions()
{
var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[]}";
var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToString(), json);

Expand All @@ -44,7 +45,7 @@ public void ParseFromJson_Permissions()
new ContractPermission()
{
Contract = ContractPermissionDescriptor.Create(UInt160.Zero),
Methods = WildCardContainer<string>.Create("method1", "method2")
Methods = WildcardContainer<string>.Create("method1", "method2")
}
};
Assert.AreEqual(manifest.ToString(), check.ToString());
Expand All @@ -53,31 +54,31 @@ public void ParseFromJson_Permissions()
[TestMethod]
public void ParseFromJson_SafeMethods()
{
var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""]}";
var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToString(), json);

var check = ContractManifest.CreateDefault(UInt160.Zero);
check.SafeMethods = WildCardContainer<string>.Create("balanceOf");
check.SafeMethods = WildcardContainer<string>.Create("balanceOf");
Assert.AreEqual(manifest.ToString(), check.ToString());
}

[TestMethod]
public void ParseFromJson_Trust()
{
var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safeMethods"":[]}";
var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safeMethods"":[],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToString(), json);

var check = ContractManifest.CreateDefault(UInt160.Zero);
check.Trusts = WildCardContainer<UInt160>.Create(UInt160.Parse("0x0000000000000000000000000000000000000001"));
check.Trusts = WildcardContainer<UInt160>.Create(UInt160.Parse("0x0000000000000000000000000000000000000001"));
Assert.AreEqual(manifest.ToString(), check.ToString());
}

[TestMethod]
public void ParseFromJson_Groups()
{
var json = @"{""groups"":[{""pubKey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[]}";
var json = @"{""groups"":[{""pubKey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToString(), json);

Expand All @@ -86,14 +87,23 @@ public void ParseFromJson_Groups()
Assert.AreEqual(manifest.ToString(), check.ToString());
}

[TestMethod]
public void ParseFromJson_Extra()
{
var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":{""key"":""value""}}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(json, json);
Assert.AreEqual("value", manifest.Extra["key"].AsString(), false);
}

[TestMethod]
public void TestDeserializeAndSerialize()
{
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
BinaryReader reader = new BinaryReader(stream);
var expected = ContractManifest.CreateDefault(UInt160.Zero);
expected.SafeMethods = WildCardContainer<string>.Create(new string[] { "AAA" });
expected.SafeMethods = WildcardContainer<string>.Create(new string[] { "AAA" });
expected.Serialize(writer);
stream.Seek(0, SeekOrigin.Begin);
var actual = ContractManifest.CreateDefault(UInt160.Zero);
Expand All @@ -113,7 +123,7 @@ public void TestGetHash()
public void TestGetSize()
{
var temp = ContractManifest.CreateDefault(UInt160.Zero);
Assert.AreEqual(353, temp.Size);
Assert.AreEqual(366, temp.Size);
}

[TestMethod]
Expand All @@ -127,15 +137,15 @@ public void TestGenerator()
public void TestCanCall()
{
var temp = ContractManifest.CreateDefault(UInt160.Zero);
temp.SafeMethods = WildCardContainer<string>.Create(new string[] { "AAA" });
temp.SafeMethods = WildcardContainer<string>.Create(new string[] { "AAA" });
Assert.AreEqual(true, temp.CanCall(ContractManifest.CreateDefault(UInt160.Zero), "AAA"));
}

[TestMethod]
public void TestClone()
{
var expected = ContractManifest.CreateDefault(UInt160.Zero);
expected.SafeMethods = WildCardContainer<string>.Create(new string[] { "AAA" });
expected.SafeMethods = WildcardContainer<string>.Create(new string[] { "AAA" });
var actual = expected.Clone();
Assert.AreEqual(actual.ToString(), expected.ToString());
}
Expand Down
Loading