From 4ba6d4f795b19e8e61c6bdab2eca7df2c693f5da Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Wed, 10 Nov 2021 15:15:14 +0800 Subject: [PATCH 01/15] NeoBurgerTestnetVote.cs which records proposals, delegates and votes on testnet --- NeoBurgerTestnetVote.cs | 155 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 NeoBurgerTestnetVote.cs diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs new file mode 100644 index 0000000..0ceb19e --- /dev/null +++ b/NeoBurgerTestnetVote.cs @@ -0,0 +1,155 @@ +using System; +using System.Numerics; +using Neo; +using Neo.SmartContract.Framework; +using Neo.SmartContract.Framework.Native; +using Neo.SmartContract.Framework.Services; +using Neo.SmartContract.Framework.Attributes; +using Neo.SmartContract; + +namespace NeoBurger +{ + [ManifestExtra("Author", "NEOBURGER")] + [ManifestExtra("Email", "developer@neo.org")] + [ManifestExtra("Description", "NeoBurger Governance Token")] + [SupportedStandards("NEP-17")] + [ContractPermission("*", "*")] + public class NeoBurgerVote:SmartContract + { + [InitialValue("[TODO]: ARGS", ContractParameterType.Hash160)] + private static readonly UInt160 OWNER = default; + private const ulong VOTING_PERIOD = 86400000 * 7; + private const byte PREFIX_PROPOSAL_LATEST_ID = 0x02; + private const byte PREFIX_PROPOSAL = 0x03; + private const byte PREFIX_PROPOSAL_PAUSED = 0x04; + private const byte PREFIX_PROPOSAL_EXECUTED_TIME = 0x05; + private const byte PREFIX_DELEGATE = 0x81; + private const byte PREFIX_VOTE = 0xc1; + + public static BigInteger GetVotingPeriod() => VOTING_PERIOD; + public static BigInteger GetLatestProposalID() => (BigInteger)Storage.Get(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_LATEST_ID }); + + public static object[] ProposalAttributes(BigInteger id) + { + StorageMap proposal_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL }); + ProposalAttributesStruct proposal_attributes = (ProposalAttributesStruct)proposal_map.GetObject((ByteString)id); + StorageMap proposal_executed_time_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_EXECUTED_TIME }); + BigInteger executed_time = (BigInteger)proposal_executed_time_map.Get((ByteString)id); + StorageMap proposal_paused_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_PAUSED }); + BigInteger paused = (BigInteger)proposal_paused_map.Get((ByteString)id); + return new object[] { proposal_attributes.provider, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.created_time, proposal_attributes.voting_deadline, paused, executed_time }; + } + + public static UInt160 GetDelegate(UInt160 from) => (UInt160)new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Get(from); + public static BigInteger GetVote(UInt160 from, BigInteger proposal_index) => (BigInteger)new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_index).Get(from); + public static Iterator GetVotersOfProposal(BigInteger proposal_id) => new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_id).Find((FindOptions)((byte)FindOptions.KeysOnly + (byte)FindOptions.RemovePrefix)); + + struct ProposalAttributesStruct + { + public BigInteger id; + public UInt160 provider; + public UInt160 scripthash; + public string method; + public ByteString[] args; + public BigInteger created_time; + public BigInteger voting_deadline; + } + + public static void _deploy(object data, bool update) + { + StorageMap proposal_id_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL }); + ProposalAttributesStruct proposal_attributes = new(); + proposal_attributes.id = 0; + proposal_id_map.PutObject((ByteString)(BigInteger)0, proposal_attributes); + } + + public static void SetEmergencyPause(BigInteger proposal_id, bool pause) + { + StorageMap proposal_paused_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_PAUSED }); + if (pause) + { + StorageMap proposal_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL }); + ProposalAttributesStruct proposal_attributes = (ProposalAttributesStruct)proposal_map.GetObject((ByteString)proposal_id); + ExecutionEngine.Assert(Runtime.CheckWitness(OWNER) || Runtime.CheckWitness(proposal_attributes.provider)); + proposal_paused_map.Put((ByteString)proposal_id, 1); + } + else + { + ExecutionEngine.Assert(Runtime.CheckWitness(OWNER)); + proposal_paused_map.Put((ByteString)proposal_id, 0); + } + } + + public static BigInteger NewProposal(UInt160 provider, BigInteger proposal_id, UInt160 scripthash, string method, ByteString[] args) + { + ExecutionEngine.Assert(Runtime.CheckWitness(provider)); + StorageMap proposal_id_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL }); + if ((BigInteger)proposal_id_map.Get((ByteString)proposal_id) != 0 || ((ProposalAttributesStruct)proposal_id_map.GetObject((ByteString)(proposal_id - 1))).id != proposal_id - 1) + throw new Exception("Invalid proposal id"); + + Storage.Put(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_LATEST_ID }, (ByteString)proposal_id); + + ProposalAttributesStruct proposal_attributes = new(); + proposal_attributes.id = proposal_id; + proposal_attributes.provider = provider; + proposal_attributes.scripthash = scripthash; + proposal_attributes.method = method; + proposal_attributes.args = args; + BigInteger current_time = Runtime.Time; + proposal_attributes.created_time = current_time; + proposal_attributes.voting_deadline = current_time + VOTING_PERIOD; + proposal_id_map.PutObject((ByteString)proposal_id, proposal_attributes); + + StorageMap proposal_paused_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_PAUSED }); + proposal_paused_map.Put((ByteString)proposal_id, 0); + + return proposal_id; + } + + public static void Delegate(UInt160 from, UInt160 to) + { + ExecutionEngine.Assert(Runtime.CheckWitness(from)); + StorageMap delegate_map = new(Storage.CurrentContext, PREFIX_DELEGATE); + if (to == UInt160.Zero || to == from) + delegate_map.Delete(from); + else + delegate_map.Put(from, to); + } + + public static void Vote(UInt160 from, BigInteger proposal_index, bool for_or_against) + { + ExecutionEngine.Assert(Runtime.CheckWitness(from)); + StorageMap proposal_id_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL }); + ProposalAttributesStruct proposal_attributes = (ProposalAttributesStruct)proposal_id_map.GetObject((ByteString)proposal_index); + BigInteger voting_deadline = proposal_attributes.voting_deadline; + if (Runtime.Time > voting_deadline) + throw new Exception("Cannot vote after the deadline"); + StorageMap proposal_executed_time_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_EXECUTED_TIME }); + BigInteger executed_time = (BigInteger)proposal_executed_time_map.Get((ByteString)proposal_index); + if (executed_time > 0) + throw new Exception("Cannot vote for executed proposal"); + StorageMap proposal_paused_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_PAUSED }); + BigInteger paused = (BigInteger)proposal_paused_map.Get((ByteString)proposal_index); + if (paused > 0) + throw new Exception("Cannot vote for paused proposal"); + StorageMap vote_map = new(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_index); + if (for_or_against) + vote_map.Put(from, 1); + else + vote_map.Delete(from); + } + + public static void MarkProposalExecuted(BigInteger id, BigInteger time) + { + ByteString proposal_executed_time_bytearray = (ByteString)new byte[] { PREFIX_PROPOSAL_EXECUTED_TIME }; + StorageMap proposal_executed_time_map = new(Storage.CurrentContext, proposal_executed_time_bytearray); + proposal_executed_time_map.Put((ByteString)id, (ByteString)time); + } + + public static void Update(ByteString nefFile, string manifest) + { + ExecutionEngine.Assert(Runtime.CheckWitness(OWNER)); + ContractManagement.Update(nefFile, manifest, null); + } + } +} From 49cebed5494015cdbb048c374986e11475cf6cc6 Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Fri, 12 Nov 2021 09:36:54 +0800 Subject: [PATCH 02/15] provide proposal digest in method `ProposalAttributes` --- NeoBurgerTestnetVote.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index 0ceb19e..37b1887 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -37,7 +37,8 @@ public static object[] ProposalAttributes(BigInteger id) BigInteger executed_time = (BigInteger)proposal_executed_time_map.Get((ByteString)id); StorageMap proposal_paused_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_PAUSED }); BigInteger paused = (BigInteger)proposal_paused_map.Get((ByteString)id); - return new object[] { proposal_attributes.provider, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.created_time, proposal_attributes.voting_deadline, paused, executed_time }; + UInt256 digest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(id) + StdLib.Serialize(proposal_attributes.scripthash) + StdLib.Serialize(proposal_attributes.method) + StdLib.Serialize(proposal_attributes.args)); + return new object[] { proposal_attributes.provider, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.created_time, proposal_attributes.voting_deadline, paused, executed_time, digest }; } public static UInt160 GetDelegate(UInt160 from) => (UInt160)new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Get(from); From 3cdfd4227f0823b4310ac590feb9789b4740d79a Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Fri, 12 Nov 2021 10:00:48 +0800 Subject: [PATCH 03/15] hash an array of proposal attributes --- NeoBurgerTestnetVote.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index 37b1887..b65e1f4 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -37,7 +37,7 @@ public static object[] ProposalAttributes(BigInteger id) BigInteger executed_time = (BigInteger)proposal_executed_time_map.Get((ByteString)id); StorageMap proposal_paused_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_PAUSED }); BigInteger paused = (BigInteger)proposal_paused_map.Get((ByteString)id); - UInt256 digest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(id) + StdLib.Serialize(proposal_attributes.scripthash) + StdLib.Serialize(proposal_attributes.method) + StdLib.Serialize(proposal_attributes.args)); + UInt256 digest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { id, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args })); return new object[] { proposal_attributes.provider, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.created_time, proposal_attributes.voting_deadline, paused, executed_time, digest }; } From 8ebd02445ae497ca314f267336f7b0e9b1234e69 Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Mon, 15 Nov 2021 10:19:03 +0800 Subject: [PATCH 04/15] CheckWitness(OWNER) for method `MarkProposalExecuted` --- NeoBurgerTestnetVote.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index b65e1f4..1e34c0b 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -142,6 +142,7 @@ public static void Vote(UInt160 from, BigInteger proposal_index, bool for_or_aga public static void MarkProposalExecuted(BigInteger id, BigInteger time) { + ExecutionEngine.Assert(Runtime.CheckWitness(OWNER)); ByteString proposal_executed_time_bytearray = (ByteString)new byte[] { PREFIX_PROPOSAL_EXECUTED_TIME }; StorageMap proposal_executed_time_map = new(Storage.CurrentContext, proposal_executed_time_bytearray); proposal_executed_time_map.Put((ByteString)id, (ByteString)time); From 00dfc164a12cc51f19e9c3abc6c79aef79af53d1 Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Mon, 15 Nov 2021 11:30:43 +0800 Subject: [PATCH 05/15] cancel pausing on testnet --- NeoBurgerTestnetVote.cs | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index 1e34c0b..391a2e8 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -21,7 +21,6 @@ public class NeoBurgerVote:SmartContract private const ulong VOTING_PERIOD = 86400000 * 7; private const byte PREFIX_PROPOSAL_LATEST_ID = 0x02; private const byte PREFIX_PROPOSAL = 0x03; - private const byte PREFIX_PROPOSAL_PAUSED = 0x04; private const byte PREFIX_PROPOSAL_EXECUTED_TIME = 0x05; private const byte PREFIX_DELEGATE = 0x81; private const byte PREFIX_VOTE = 0xc1; @@ -35,10 +34,8 @@ public static object[] ProposalAttributes(BigInteger id) ProposalAttributesStruct proposal_attributes = (ProposalAttributesStruct)proposal_map.GetObject((ByteString)id); StorageMap proposal_executed_time_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_EXECUTED_TIME }); BigInteger executed_time = (BigInteger)proposal_executed_time_map.Get((ByteString)id); - StorageMap proposal_paused_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_PAUSED }); - BigInteger paused = (BigInteger)proposal_paused_map.Get((ByteString)id); UInt256 digest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { id, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args })); - return new object[] { proposal_attributes.provider, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.created_time, proposal_attributes.voting_deadline, paused, executed_time, digest }; + return new object[] { proposal_attributes.provider, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.created_time, proposal_attributes.voting_deadline, executed_time, digest }; } public static UInt160 GetDelegate(UInt160 from) => (UInt160)new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Get(from); @@ -64,23 +61,6 @@ public static void _deploy(object data, bool update) proposal_id_map.PutObject((ByteString)(BigInteger)0, proposal_attributes); } - public static void SetEmergencyPause(BigInteger proposal_id, bool pause) - { - StorageMap proposal_paused_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_PAUSED }); - if (pause) - { - StorageMap proposal_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL }); - ProposalAttributesStruct proposal_attributes = (ProposalAttributesStruct)proposal_map.GetObject((ByteString)proposal_id); - ExecutionEngine.Assert(Runtime.CheckWitness(OWNER) || Runtime.CheckWitness(proposal_attributes.provider)); - proposal_paused_map.Put((ByteString)proposal_id, 1); - } - else - { - ExecutionEngine.Assert(Runtime.CheckWitness(OWNER)); - proposal_paused_map.Put((ByteString)proposal_id, 0); - } - } - public static BigInteger NewProposal(UInt160 provider, BigInteger proposal_id, UInt160 scripthash, string method, ByteString[] args) { ExecutionEngine.Assert(Runtime.CheckWitness(provider)); @@ -101,9 +81,6 @@ public static BigInteger NewProposal(UInt160 provider, BigInteger proposal_id, U proposal_attributes.voting_deadline = current_time + VOTING_PERIOD; proposal_id_map.PutObject((ByteString)proposal_id, proposal_attributes); - StorageMap proposal_paused_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_PAUSED }); - proposal_paused_map.Put((ByteString)proposal_id, 0); - return proposal_id; } @@ -129,10 +106,6 @@ public static void Vote(UInt160 from, BigInteger proposal_index, bool for_or_aga BigInteger executed_time = (BigInteger)proposal_executed_time_map.Get((ByteString)proposal_index); if (executed_time > 0) throw new Exception("Cannot vote for executed proposal"); - StorageMap proposal_paused_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_PAUSED }); - BigInteger paused = (BigInteger)proposal_paused_map.Get((ByteString)proposal_index); - if (paused > 0) - throw new Exception("Cannot vote for paused proposal"); StorageMap vote_map = new(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_index); if (for_or_against) vote_map.Put(from, 1); From 89c4a199182ad7a410882b1060e5b370e1402aba Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Mon, 22 Nov 2021 13:28:19 +0800 Subject: [PATCH 06/15] GetAllDelgates --- NeoBurgerTestnetVote.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index 391a2e8..98e1de2 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -39,6 +39,7 @@ public static object[] ProposalAttributes(BigInteger id) } public static UInt160 GetDelegate(UInt160 from) => (UInt160)new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Get(from); + public static Iterator GetAllDelgates() => new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Find((FindOptions)((byte)FindOptions.KeysOnly + (byte)FindOptions.RemovePrefix)); public static BigInteger GetVote(UInt160 from, BigInteger proposal_index) => (BigInteger)new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_index).Get(from); public static Iterator GetVotersOfProposal(BigInteger proposal_id) => new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_id).Find((FindOptions)((byte)FindOptions.KeysOnly + (byte)FindOptions.RemovePrefix)); From d1aa526f0261bcbee9f16c06e56611c82792d54a Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Mon, 29 Nov 2021 12:45:52 +0800 Subject: [PATCH 07/15] use nonce for each new proposal --- NeoBurgerTestnetVote.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index 98e1de2..ca5fd66 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -34,7 +34,7 @@ public static object[] ProposalAttributes(BigInteger id) ProposalAttributesStruct proposal_attributes = (ProposalAttributesStruct)proposal_map.GetObject((ByteString)id); StorageMap proposal_executed_time_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_EXECUTED_TIME }); BigInteger executed_time = (BigInteger)proposal_executed_time_map.Get((ByteString)id); - UInt256 digest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { id, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args })); + UInt256 digest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.nonce })); return new object[] { proposal_attributes.provider, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.created_time, proposal_attributes.voting_deadline, executed_time, digest }; } @@ -50,6 +50,7 @@ struct ProposalAttributesStruct public UInt160 scripthash; public string method; public ByteString[] args; + public BigInteger nonce; public BigInteger created_time; public BigInteger voting_deadline; } @@ -77,6 +78,7 @@ public static BigInteger NewProposal(UInt160 provider, BigInteger proposal_id, U proposal_attributes.scripthash = scripthash; proposal_attributes.method = method; proposal_attributes.args = args; + proposal_attributes.nonce = Runtime.GetRandom(); BigInteger current_time = Runtime.Time; proposal_attributes.created_time = current_time; proposal_attributes.voting_deadline = current_time + VOTING_PERIOD; From 13414e510e422e7ae76204f8d1cf8b8a951ad98a Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Tue, 30 Nov 2021 16:21:40 +0800 Subject: [PATCH 08/15] standalone method `ProposalDigest` --- NeoBurgerTestnetVote.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index ca5fd66..e74170b 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -42,6 +42,7 @@ public static object[] ProposalAttributes(BigInteger id) public static Iterator GetAllDelgates() => new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Find((FindOptions)((byte)FindOptions.KeysOnly + (byte)FindOptions.RemovePrefix)); public static BigInteger GetVote(UInt160 from, BigInteger proposal_index) => (BigInteger)new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_index).Get(from); public static Iterator GetVotersOfProposal(BigInteger proposal_id) => new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_id).Find((FindOptions)((byte)FindOptions.KeysOnly + (byte)FindOptions.RemovePrefix)); + public static UInt256 ProposalDigest(UInt160 scripthash, string method, object[] args, BigInteger nonce) => (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { scripthash, method, args, nonce })); struct ProposalAttributesStruct { From b23da4f5c620eaff7ee5218f1f612368eb0ff079 Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Tue, 21 Dec 2021 14:33:17 +0800 Subject: [PATCH 09/15] proposal title and description --- NeoBurgerTestnetVote.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index e74170b..09ccca0 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -35,7 +35,7 @@ public static object[] ProposalAttributes(BigInteger id) StorageMap proposal_executed_time_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_EXECUTED_TIME }); BigInteger executed_time = (BigInteger)proposal_executed_time_map.Get((ByteString)id); UInt256 digest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.nonce })); - return new object[] { proposal_attributes.provider, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.created_time, proposal_attributes.voting_deadline, executed_time, digest }; + return new object[] { proposal_attributes.provider, proposal_attributes.title, proposal_attributes.description, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.created_time, proposal_attributes.voting_deadline, executed_time, digest }; } public static UInt160 GetDelegate(UInt160 from) => (UInt160)new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Get(from); @@ -48,6 +48,8 @@ struct ProposalAttributesStruct { public BigInteger id; public UInt160 provider; + public string title; + public string description; public UInt160 scripthash; public string method; public ByteString[] args; @@ -64,7 +66,7 @@ public static void _deploy(object data, bool update) proposal_id_map.PutObject((ByteString)(BigInteger)0, proposal_attributes); } - public static BigInteger NewProposal(UInt160 provider, BigInteger proposal_id, UInt160 scripthash, string method, ByteString[] args) + public static BigInteger NewProposal(UInt160 provider, string title, string description, BigInteger proposal_id, UInt160 scripthash, string method, ByteString[] args) { ExecutionEngine.Assert(Runtime.CheckWitness(provider)); StorageMap proposal_id_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL }); @@ -76,6 +78,8 @@ public static BigInteger NewProposal(UInt160 provider, BigInteger proposal_id, U ProposalAttributesStruct proposal_attributes = new(); proposal_attributes.id = proposal_id; proposal_attributes.provider = provider; + proposal_attributes.title = title; + proposal_attributes.description = description; proposal_attributes.scripthash = scripthash; proposal_attributes.method = method; proposal_attributes.args = args; From 470b73918f8ce7a0dcf1a80636d1454225a69a1e Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Wed, 22 Dec 2021 16:04:53 +0800 Subject: [PATCH 10/15] return nonce in proposalAttributes --- NeoBurgerTestnetVote.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index 09ccca0..604c79e 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -35,7 +35,7 @@ public static object[] ProposalAttributes(BigInteger id) StorageMap proposal_executed_time_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL_EXECUTED_TIME }); BigInteger executed_time = (BigInteger)proposal_executed_time_map.Get((ByteString)id); UInt256 digest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.nonce })); - return new object[] { proposal_attributes.provider, proposal_attributes.title, proposal_attributes.description, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.created_time, proposal_attributes.voting_deadline, executed_time, digest }; + return new object[] { proposal_attributes.provider, proposal_attributes.title, proposal_attributes.description, proposal_attributes.scripthash, proposal_attributes.method, proposal_attributes.args, proposal_attributes.nonce, proposal_attributes.created_time, proposal_attributes.voting_deadline, executed_time, digest }; } public static UInt160 GetDelegate(UInt160 from) => (UInt160)new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Get(from); From ba8bfd08e2c396b3854ba342de7d8b613fa39bf9 Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Wed, 22 Dec 2021 16:26:36 +0800 Subject: [PATCH 11/15] remove FindOptions.KeysOnly --- NeoBurgerTestnetVote.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index 604c79e..f8e9976 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -39,7 +39,7 @@ public static object[] ProposalAttributes(BigInteger id) } public static UInt160 GetDelegate(UInt160 from) => (UInt160)new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Get(from); - public static Iterator GetAllDelgates() => new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Find((FindOptions)((byte)FindOptions.KeysOnly + (byte)FindOptions.RemovePrefix)); + public static Iterator GetAllDelgates() => new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Find(FindOptions.RemovePrefix); public static BigInteger GetVote(UInt160 from, BigInteger proposal_index) => (BigInteger)new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_index).Get(from); public static Iterator GetVotersOfProposal(BigInteger proposal_id) => new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_id).Find((FindOptions)((byte)FindOptions.KeysOnly + (byte)FindOptions.RemovePrefix)); public static UInt256 ProposalDigest(UInt160 scripthash, string method, object[] args, BigInteger nonce) => (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { scripthash, method, args, nonce })); From 3a7ed60149da5b9e4dc65388bb5b12b72aacc65b Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Wed, 22 Dec 2021 16:29:58 +0800 Subject: [PATCH 12/15] if (update) return; --- NeoBurgerTestnetVote.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index f8e9976..c1f1549 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -60,6 +60,7 @@ struct ProposalAttributesStruct public static void _deploy(object data, bool update) { + if (update) return; StorageMap proposal_id_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL }); ProposalAttributesStruct proposal_attributes = new(); proposal_attributes.id = 0; From 7aa0132c872ac185866dfa92934414de120f0444 Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Wed, 22 Dec 2021 16:59:13 +0800 Subject: [PATCH 13/15] support voting against proposal --- NeoBurgerTestnetVote.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index c1f1549..98d7761 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -103,7 +103,7 @@ public static void Delegate(UInt160 from, UInt160 to) delegate_map.Put(from, to); } - public static void Vote(UInt160 from, BigInteger proposal_index, bool for_or_against) + public static void Vote(UInt160 from, BigInteger proposal_index, bool for_or_against, bool unvote=false) { ExecutionEngine.Assert(Runtime.CheckWitness(from)); StorageMap proposal_id_map = new(Storage.CurrentContext, new byte[] { PREFIX_PROPOSAL }); @@ -116,10 +116,15 @@ public static void Vote(UInt160 from, BigInteger proposal_index, bool for_or_aga if (executed_time > 0) throw new Exception("Cannot vote for executed proposal"); StorageMap vote_map = new(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_index); + if (unvote) + { + vote_map.Delete(from); + return; + } if (for_or_against) vote_map.Put(from, 1); else - vote_map.Delete(from); + vote_map.Put(from, -1); } public static void MarkProposalExecuted(BigInteger id, BigInteger time) From 18a0060371437bbac107fb465c87f1ab92d200d6 Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Wed, 22 Dec 2021 17:06:28 +0800 Subject: [PATCH 14/15] remove FindOptions.KeysOnly in GetVotersOfProposal --- NeoBurgerTestnetVote.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index 98d7761..1ec043f 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -41,7 +41,7 @@ public static object[] ProposalAttributes(BigInteger id) public static UInt160 GetDelegate(UInt160 from) => (UInt160)new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Get(from); public static Iterator GetAllDelgates() => new StorageMap(Storage.CurrentContext, PREFIX_DELEGATE).Find(FindOptions.RemovePrefix); public static BigInteger GetVote(UInt160 from, BigInteger proposal_index) => (BigInteger)new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_index).Get(from); - public static Iterator GetVotersOfProposal(BigInteger proposal_id) => new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_id).Find((FindOptions)((byte)FindOptions.KeysOnly + (byte)FindOptions.RemovePrefix)); + public static Iterator GetVotersOfProposal(BigInteger proposal_id) => new StorageMap(Storage.CurrentContext, (ByteString)new byte[] { PREFIX_VOTE } + (ByteString)proposal_id).Find(FindOptions.RemovePrefix); public static UInt256 ProposalDigest(UInt160 scripthash, string method, object[] args, BigInteger nonce) => (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { scripthash, method, args, nonce })); struct ProposalAttributesStruct From dae7df985cbef3a14934f37b0614ca6dc4473ec1 Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Tue, 15 Feb 2022 14:10:15 +0800 Subject: [PATCH 15/15] remove email --- NeoBurgerTestnetVote.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/NeoBurgerTestnetVote.cs b/NeoBurgerTestnetVote.cs index 1ec043f..8fc9770 100644 --- a/NeoBurgerTestnetVote.cs +++ b/NeoBurgerTestnetVote.cs @@ -10,7 +10,6 @@ namespace NeoBurger { [ManifestExtra("Author", "NEOBURGER")] - [ManifestExtra("Email", "developer@neo.org")] [ManifestExtra("Description", "NeoBurger Governance Token")] [SupportedStandards("NEP-17")] [ContractPermission("*", "*")]