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

Feature manifest and permission system #766

Merged
merged 66 commits into from
May 24, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
9e101ab
Classes
shargon May 20, 2019
0ab7368
Check Valid group signature
shargon May 20, 2019
f548702
Is Allowed
shargon May 20, 2019
143297b
Reuse some classes
shargon May 20, 2019
dfed28b
Fix IsAllowed
shargon May 20, 2019
5ce76cc
Trusts and SafeMethods
shargon May 20, 2019
6b26077
Process trust and Group
shargon May 20, 2019
8781770
Clean code
shargon May 20, 2019
a1c6f72
Add comments
shargon May 20, 2019
5b1aaec
Add more comments
shargon May 20, 2019
34aa3ba
WillCardContainer
shargon May 21, 2019
ed75324
Group as Array
shargon May 21, 2019
f7f36e8
Willcard in ContractPermission
shargon May 21, 2019
2058fd0
Fix trusts
shargon May 21, 2019
deb3707
Clean code
shargon May 21, 2019
6d1d627
Merge branch 'master' into feature-manifest
shargon May 21, 2019
44f5ce0
Merge branch 'master' into feature-manifest
shargon May 21, 2019
1f8b316
Typo fix
shargon May 21, 2019
0137897
Integrate ContractManifest
shargon May 21, 2019
7736247
Integrate in Contract.Call
shargon May 21, 2019
3a5b0ba
Clone Manifest
shargon May 21, 2019
453675c
full manifest in json
shargon May 21, 2019
55fd385
Default value in constructor
shargon May 21, 2019
cd306e8
Serialize ContractManifest
shargon May 21, 2019
2b40a8d
Default Abi for Native Contract
shargon May 21, 2019
6b36687
Fix return for PolicyContract
shargon May 21, 2019
c402d0b
Nep5Token Abi
shargon May 21, 2019
f33b0e8
Clean code
shargon May 21, 2019
ce0aa85
Abi for GastToken
shargon May 21, 2019
89051bf
Abi for NeoToken
shargon May 21, 2019
93d6ae8
Default entry point in the static method
shargon May 21, 2019
768df1f
MaxLength for ContractManifest
shargon May 21, 2019
0729674
Migrate too
shargon May 21, 2019
7842694
Merge branch 'master' into feature-manifest
shargon May 22, 2019
524a745
Parsing json
shargon May 22, 2019
548acf0
Merge remote-tracking branch 'shargon/feature-manifest' into feature-…
shargon May 22, 2019
16d1ff5
Unit test for json
shargon May 22, 2019
c09a795
Validate ContractManifest
shargon May 22, 2019
47b3efc
Neo.Contract.UpdateManifest
shargon May 22, 2019
1cb3650
Deserialize
shargon May 22, 2019
2b9c5dc
Check hash of the manifest in update
shargon May 22, 2019
c18cd5b
Rename classes
shargon May 22, 2019
31feebc
Erik recommendations
shargon May 23, 2019
3f0772b
Move default entry point
shargon May 23, 2019
ecb338f
Revert Helper.cs
erikzhang May 23, 2019
f94021b
fix tests
erikzhang May 23, 2019
1d4e281
Change the type of `ContractManifestGroup.PubKey` to `ECPoint`
erikzhang May 23, 2019
6bc60f1
Move classes to namespace `Neo.SmartContract.Manifest`, and rename
erikzhang May 23, 2019
8d38246
Remove `Equals()`
erikzhang May 23, 2019
93cd013
Fix `DefaultEntryPoint`
erikzhang May 23, 2019
4dacb2c
Fix `ToJson()` and `ContractManifest.CreateDefault()`
erikzhang May 23, 2019
5400351
Add `ContractManifest.DeserializeFromJson()`
erikzhang May 23, 2019
cc4a340
optimize
erikzhang May 23, 2019
dab02a5
Groups never be null
shargon May 23, 2019
38fc8d7
Not allowed to be set to null
erikzhang May 23, 2019
26ff492
Combine `Neo.Contract.Migrate` and `Neo.Contract.UpdateManifest`
erikzhang May 23, 2019
d00903e
Ensure `contract.Manifest.Hash == contract.ScriptHash` in `Contract_C…
erikzhang May 23, 2019
12a1576
rename
erikzhang May 23, 2019
162758e
Fix `Contract_Call`
erikzhang May 23, 2019
2cdb847
Implement `ContractPermission` correctly
erikzhang May 23, 2019
84c38f9
Simplify `IsValid()`
erikzhang May 23, 2019
fcdab61
Update ContractGroup.cs
shargon May 23, 2019
7c7a82d
Change max length of ContractManifest
shargon May 23, 2019
efac87f
Add `events` for ABI of `Nep5Token`
erikzhang May 23, 2019
a3a1b0d
format
erikzhang May 23, 2019
b44ec29
Update WildCardContainer.cs
erikzhang May 23, 2019
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
21 changes: 11 additions & 10 deletions neo/Ledger/ContractState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ namespace Neo.Ledger
public class ContractState : ICloneable<ContractState>, ISerializable
{
public byte[] Script;
public ContractPropertyState ContractProperties;

public bool HasStorage => ContractProperties.HasFlag(ContractPropertyState.HasStorage);
public bool Payable => ContractProperties.HasFlag(ContractPropertyState.Payable);
public ContractManifest Manifest;

private UInt160 _scriptHash;
public UInt160 ScriptHash
Expand All @@ -26,33 +24,36 @@ public UInt160 ScriptHash
}
}

int ISerializable.Size => Script.GetVarSize() + sizeof(ContractParameterType);
public bool HasStorage => Manifest.Features.HasFlag(ContractPropertyState.HasStorage);
public bool Payable => Manifest.Features.HasFlag(ContractPropertyState.Payable);

int ISerializable.Size => Script.GetVarSize() + Manifest.ToJson().GetVarSize();

ContractState ICloneable<ContractState>.Clone()
{
return new ContractState
{
Script = Script,
ContractProperties = ContractProperties
Manifest = Manifest
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
};
}

void ISerializable.Deserialize(BinaryReader reader)
{
Script = reader.ReadVarBytes();
ContractProperties = (ContractPropertyState)reader.ReadByte();
Manifest = ContractManifest.Parse(reader.ReadVarString(ushort.MaxValue));
}

void ICloneable<ContractState>.FromReplica(ContractState replica)
{
Script = replica.Script;
ContractProperties = replica.ContractProperties;
Manifest = replica.Manifest.Clone();
}

void ISerializable.Serialize(BinaryWriter writer)
{
writer.WriteVarBytes(Script);
writer.Write((byte)ContractProperties);
writer.WriteVarString(Manifest.ToJson());
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
}

public JObject ToJson()
Expand All @@ -61,8 +62,8 @@ public JObject ToJson()
json["hash"] = ScriptHash.ToString();
json["script"] = Script.ToHexString();
json["properties"] = new JObject();
json["properties"]["storage"] = HasStorage;
json["properties"]["payable"] = Payable;
json["properties"]["storage"] = Manifest.Features.HasFlag(ContractPropertyState.HasStorage);
json["properties"]["payable"] = Manifest.Features.HasFlag(ContractPropertyState.Payable);
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
return json;
}
}
Expand Down
35 changes: 35 additions & 0 deletions neo/SmartContract/ContractManifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,40 @@ public bool CanCall(ContractManifest manifest, string method)

return Permissions == null || Permissions.IsWildcard || Permissions.Any(u => u.IsAllowed(manifest.Hash, method));
}

/// <summary>
/// Parse ContractManifest from json
/// </summary>
/// <param name="json">Json</param>
/// <returns>Return Contract manifest</returns>
public static ContractManifest Parse(string json)
{
// TODO: Parse json

throw new NotImplementedException();
}

/// <summary>
/// To json
/// </summary>
/// <returns>Return json string</returns>
public string ToJson()
{
// TODO: Generate json

throw new NotImplementedException();
}

/// <summary>
/// Clone
/// </summary>
/// <returns>Return a copy of this object</returns>
public ContractManifest Clone() => Parse(ToJson());

/// <summary>
/// String representation
/// </summary>
/// <returns>Return json string</returns>
public override string ToString() => ToJson();
}
}
14 changes: 9 additions & 5 deletions neo/SmartContract/InteropService.NEO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using VMArray = Neo.VM.Types.Array;

namespace Neo.SmartContract
Expand Down Expand Up @@ -51,12 +52,13 @@ private static bool Native_Deploy(ApplicationEngine engine)
{
if (engine.Trigger != TriggerType.Application) return false;
if (engine.Snapshot.PersistingBlock.Index != 0) return false;

foreach (NativeContract contract in NativeContract.Contracts)
{
engine.Snapshot.Contracts.Add(contract.Hash, new ContractState
{
Script = contract.Script,
ContractProperties = contract.Properties
Manifest = contract.Manifest
});
contract.Initialize(engine);
}
Expand Down Expand Up @@ -226,15 +228,16 @@ private static bool Contract_Create(ApplicationEngine engine)
if (engine.Trigger != TriggerType.Application) return false;
byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
if (script.Length > 1024 * 1024) return false;
ContractPropertyState contract_properties = (ContractPropertyState)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

var manifest = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());
UInt160 hash = script.ToScriptHash();
ContractState contract = engine.Snapshot.Contracts.TryGet(hash);
if (contract == null)
{
contract = new ContractState
{
Script = script,
ContractProperties = contract_properties
Manifest = ContractManifest.Parse(manifest)
};
engine.Snapshot.Contracts.Add(hash, contract);
}
Expand All @@ -247,15 +250,16 @@ private static bool Contract_Migrate(ApplicationEngine engine)
if (engine.Trigger != TriggerType.Application) return false;
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
if (script.Length > 1024 * 1024) return false;
ContractPropertyState contract_properties = (ContractPropertyState)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

var manifest = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());
UInt160 hash = script.ToScriptHash();
ContractState contract = engine.Snapshot.Contracts.TryGet(hash);
if (contract == null)
{
contract = new ContractState
{
Script = script,
ContractProperties = contract_properties
Manifest = ContractManifest.Parse(manifest)
};
engine.Snapshot.Contracts.Add(hash, contract);
if (contract.HasStorage)
Expand Down
11 changes: 10 additions & 1 deletion neo/SmartContract/Native/NativeContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,16 @@ public abstract class NativeContract
public uint ServiceHash { get; }
public byte[] Script { get; }
public UInt160 Hash { get; }
public virtual ContractPropertyState Properties => ContractPropertyState.NoProperty;
public virtual ContractManifest Manifest => new ContractManifest()
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
{
Hash = Hash,
Features = ContractPropertyState.NoProperty,
Abi = null,
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
Groups = null,
Permissions = null,
SafeMethods = null,
Trusts = null
};
public virtual string[] SupportedStandards { get; } = { "NEP-10" };

protected NativeContract()
Expand Down
11 changes: 10 additions & 1 deletion neo/SmartContract/Native/PolicyContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@ namespace Neo.SmartContract.Native
public sealed class PolicyContract : NativeContract
{
public override string ServiceName => "Neo.Native.Policy";
public override ContractPropertyState Properties => ContractPropertyState.HasStorage;
public override ContractManifest Manifest
{
get
{
var manifest = base.Manifest;
manifest.Features = ContractPropertyState.HasStorage;

return manifest;
}
}

private const byte Prefix_MaxTransactionsPerBlock = 23;
private const byte Prefix_MaxLowPriorityTransactionsPerBlock = 34;
Expand Down
11 changes: 10 additions & 1 deletion neo/SmartContract/Native/Tokens/Nep5Token.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ namespace Neo.SmartContract.Native.Tokens
public abstract class Nep5Token<TState> : NativeContract
where TState : Nep5AccountState, new()
{
public override ContractPropertyState Properties => ContractPropertyState.HasStorage;
public override ContractManifest Manifest
{
get
{
var manifest = base.Manifest;
manifest.Features = ContractPropertyState.HasStorage;

return manifest;
}
}
public override string[] SupportedStandards { get; } = { "NEP-5", "NEP-10" };
public abstract string Name { get; }
public abstract string Symbol { get; }
Expand Down