Skip to content

Commit 9a9ebaf

Browse files
shargonerikzhangajara87Wi1l-B0t
authored
[N3] Init Treasury (#4271)
* Init Treasury * Remove comments * Update src/Neo/SmartContract/Native/Treasury.cs Co-authored-by: Erik Zhang <[email protected]> * Update src/Neo/SmartContract/Native/Treasury.cs * Update src/Neo/SmartContract/Native/Treasury.cs * Update src/Neo/SmartContract/Native/Treasury.cs * Fix comments * Add SupportedStandards * format * Fix ut * Delete docs/native-contracts-api.md * Fix Name (#4313) * Change price to 1 << 5 * Change call flags to None * fix safe manifest --------- Co-authored-by: Erik Zhang <[email protected]> Co-authored-by: Alvaro <[email protected]> Co-authored-by: Will <[email protected]>
1 parent e47ef7a commit 9a9ebaf

File tree

4 files changed

+79
-6
lines changed

4 files changed

+79
-6
lines changed

src/Neo/SmartContract/Native/NativeContract.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ public CacheEntry GetAllowedMethods(NativeContract native, ApplicationEngine eng
105105
/// </summary>
106106
public static Notary Notary { get; } = new();
107107

108+
/// <summary>
109+
/// Gets the instance of the <see cref="Treasury"/> class.
110+
/// </summary>
111+
public static Treasury Treasury { get; } = new();
112+
108113
#endregion
109114

110115
/// <summary>

src/Neo/SmartContract/Native/NeoToken.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,17 +164,17 @@ private BigInteger CalculateBonus(DataCache snapshot, NeoAccountState state, uin
164164
// Compute Neo holder reward
165165

166166
// In the unit of datoshi, 1 GAS = 10^8 datoshi
167-
BigInteger sumNeoHold = 0;
167+
BigInteger sumGasPerBlock = 0;
168168
foreach (var (index, gasPerBlock) in GetSortedGasRecords(snapshot, end - 1))
169169
{
170170
if (index > start)
171171
{
172-
sumNeoHold += gasPerBlock * (end - index);
172+
sumGasPerBlock += gasPerBlock * (end - index);
173173
end = index;
174174
}
175175
else
176176
{
177-
sumNeoHold += gasPerBlock * (end - start);
177+
sumGasPerBlock += gasPerBlock * (end - start);
178178
break;
179179
}
180180
}
@@ -190,7 +190,7 @@ private BigInteger CalculateBonus(DataCache snapshot, NeoAccountState state, uin
190190
voteReward = state.Balance * (latestGasPerVote - state.LastGasPerVote) / VoteFactor;
191191
}
192192

193-
return (state.Balance * sumNeoHold * NeoHolderRewardRatio / 100 / TotalAmount, voteReward);
193+
return (state.Balance * sumGasPerBlock * NeoHolderRewardRatio / 100 / TotalAmount, voteReward);
194194
}
195195

196196
private void CheckCandidate(DataCache snapshot, ECPoint pubkey, CandidateState candidate)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (C) 2015-2025 The Neo Project.
2+
//
3+
// Treasury.cs file belongs to the neo project and is free
4+
// software distributed under the MIT software license, see the
5+
// accompanying file LICENSE in the main directory of the
6+
// repository or http://www.opensource.org/licenses/mit-license.php
7+
// for more details.
8+
//
9+
// Redistribution and use in source and binary forms with or without
10+
// modifications are permitted.
11+
12+
#nullable enable
13+
#pragma warning disable IDE0051
14+
15+
using Neo.SmartContract.Manifest;
16+
using Neo.VM.Types;
17+
using System.Numerics;
18+
19+
namespace Neo.SmartContract.Native
20+
{
21+
/// <summary>
22+
/// The Treasury native contract used for manage the treasury funds.
23+
/// </summary>
24+
public sealed class Treasury : NativeContract
25+
{
26+
internal Treasury() : base() { }
27+
28+
public override Hardfork? ActiveIn => Hardfork.HF_Faun;
29+
30+
protected override void OnManifestCompose(IsHardforkEnabledDelegate hfChecker, uint blockHeight, ContractManifest manifest)
31+
{
32+
manifest.SupportedStandards = ["NEP-26", "NEP-27"];
33+
}
34+
35+
/// <summary>
36+
/// Verify checks whether the transaction is signed by the committee.
37+
/// </summary>
38+
/// <param name="engine">ApplicationEngine</param>
39+
/// <returns>Whether transaction is valid.</returns>
40+
[ContractMethod(CpuFee = 1 << 5, RequiredCallFlags = CallFlags.ReadStates)]
41+
private bool Verify(ApplicationEngine engine) => CheckCommittee(engine);
42+
43+
/// <summary>
44+
/// OnNEP17Payment callback.
45+
/// </summary>
46+
/// <param name="engine">ApplicationEngine</param>
47+
/// <param name="from">GAS sender</param>
48+
/// <param name="amount">The amount of GAS sent</param>
49+
/// <param name="data">Optional data</param>
50+
[ContractMethod(CpuFee = 1 << 5, RequiredCallFlags = CallFlags.None)]
51+
private void OnNEP17Payment(ApplicationEngine engine, UInt160 from, BigInteger amount, StackItem data) { }
52+
53+
/// <summary>
54+
/// OnNEP11Payment callback.
55+
/// </summary>
56+
/// <param name="engine">ApplicationEngine</param>
57+
/// <param name="from">GAS sender</param>
58+
/// <param name="amount">The amount of GAS sent</param>
59+
/// <param name="tokenId">Nep11 token Id</param>
60+
/// <param name="data">Optional data</param>
61+
[ContractMethod(CpuFee = 1 << 5, RequiredCallFlags = CallFlags.None)]
62+
private void OnNEP11Payment(ApplicationEngine engine, UInt160 from, BigInteger amount, byte[] tokenId, StackItem data) { }
63+
}
64+
}
65+
66+
#nullable disable

tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ public void TestSetup()
5151
{"PolicyContract", """{"id":-7,"updatecounter":0,"hash":"0xcc5e4edd9f5f8dba8bb65734541df7a1c081c67b","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQA==","checksum":65467259},"manifest":{"name":"PolicyContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"blockAccount","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean","offset":0,"safe":false},{"name":"getAttributeFee","parameters":[{"name":"attributeType","type":"Integer"}],"returntype":"Integer","offset":7,"safe":true},{"name":"getBlockedAccounts","parameters":[],"returntype":"InteropInterface","offset":14,"safe":true},{"name":"getExecFeeFactor","parameters":[],"returntype":"Integer","offset":21,"safe":true},{"name":"getExecPicoFeeFactor","parameters":[],"returntype":"Integer","offset":28,"safe":true},{"name":"getFeePerByte","parameters":[],"returntype":"Integer","offset":35,"safe":true},{"name":"getMaxTraceableBlocks","parameters":[],"returntype":"Integer","offset":42,"safe":true},{"name":"getMaxValidUntilBlockIncrement","parameters":[],"returntype":"Integer","offset":49,"safe":true},{"name":"getMillisecondsPerBlock","parameters":[],"returntype":"Integer","offset":56,"safe":true},{"name":"getStoragePrice","parameters":[],"returntype":"Integer","offset":63,"safe":true},{"name":"isBlocked","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean","offset":70,"safe":true},{"name":"setAttributeFee","parameters":[{"name":"attributeType","type":"Integer"},{"name":"value","type":"Integer"}],"returntype":"Void","offset":77,"safe":false},{"name":"setExecFeeFactor","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":84,"safe":false},{"name":"setFeePerByte","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":91,"safe":false},{"name":"setMaxTraceableBlocks","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":98,"safe":false},{"name":"setMaxValidUntilBlockIncrement","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":105,"safe":false},{"name":"setMillisecondsPerBlock","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":112,"safe":false},{"name":"setStoragePrice","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":119,"safe":false},{"name":"unblockAccount","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Boolean","offset":126,"safe":false}],"events":[{"name":"MillisecondsPerBlockChanged","parameters":[{"name":"old","type":"Integer"},{"name":"new","type":"Integer"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""},
5252
{"RoleManagement", """{"id":-8,"updatecounter":0,"hash":"0x49cf4e5378ffcd4dec034fd98a174c5491e395e2","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0A=","checksum":983638438},"manifest":{"name":"RoleManagement","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"designateAsRole","parameters":[{"name":"role","type":"Integer"},{"name":"nodes","type":"Array"}],"returntype":"Void","offset":0,"safe":false},{"name":"getDesignatedByRole","parameters":[{"name":"role","type":"Integer"},{"name":"index","type":"Integer"}],"returntype":"Array","offset":7,"safe":true}],"events":[{"name":"Designation","parameters":[{"name":"Role","type":"Integer"},{"name":"BlockIndex","type":"Integer"},{"name":"Old","type":"Array"},{"name":"New","type":"Array"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""},
5353
{"OracleContract", """{"id":-9,"updatecounter":0,"hash":"0xfe924b7cfe89ddd271abaf7210a80a7e11178758","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":2663858513},"manifest":{"name":"OracleContract","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"finish","parameters":[],"returntype":"Void","offset":0,"safe":false},{"name":"getPrice","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"request","parameters":[{"name":"url","type":"String"},{"name":"filter","type":"String"},{"name":"callback","type":"String"},{"name":"userData","type":"Any"},{"name":"gasForResponse","type":"Integer"}],"returntype":"Void","offset":14,"safe":false},{"name":"setPrice","parameters":[{"name":"price","type":"Integer"}],"returntype":"Void","offset":21,"safe":false},{"name":"verify","parameters":[],"returntype":"Boolean","offset":28,"safe":true}],"events":[{"name":"OracleRequest","parameters":[{"name":"Id","type":"Integer"},{"name":"RequestContract","type":"Hash160"},{"name":"Url","type":"String"},{"name":"Filter","type":"String"}]},{"name":"OracleResponse","parameters":[{"name":"Id","type":"Integer"},{"name":"OriginalTx","type":"Hash256"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""},
54-
{"Notary", """{"id":-10,"updatecounter":0,"hash":"0xc1e14f19c3e60d0b9244d06dd7ba9b113135ec3b","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1110259869},"manifest":{"name":"Notary","groups":[],"features":{},"supportedstandards":["NEP-27"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"expirationOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":7,"safe":true},{"name":"getMaxNotValidBeforeDelta","parameters":[],"returntype":"Integer","offset":14,"safe":true},{"name":"lockDepositUntil","parameters":[{"name":"account","type":"Hash160"},{"name":"till","type":"Integer"}],"returntype":"Boolean","offset":21,"safe":false},{"name":"onNEP17Payment","parameters":[{"name":"from","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Void","offset":28,"safe":false},{"name":"setMaxNotValidBeforeDelta","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":35,"safe":false},{"name":"verify","parameters":[{"name":"signature","type":"ByteArray"}],"returntype":"Boolean","offset":42,"safe":true},{"name":"withdraw","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"}],"returntype":"Boolean","offset":49,"safe":false}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}
54+
{"Notary", """{"id":-10,"updatecounter":0,"hash":"0xc1e14f19c3e60d0b9244d06dd7ba9b113135ec3b","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=","checksum":1110259869},"manifest":{"name":"Notary","groups":[],"features":{},"supportedstandards":["NEP-27"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"expirationOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":7,"safe":true},{"name":"getMaxNotValidBeforeDelta","parameters":[],"returntype":"Integer","offset":14,"safe":true},{"name":"lockDepositUntil","parameters":[{"name":"account","type":"Hash160"},{"name":"till","type":"Integer"}],"returntype":"Boolean","offset":21,"safe":false},{"name":"onNEP17Payment","parameters":[{"name":"from","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Void","offset":28,"safe":false},{"name":"setMaxNotValidBeforeDelta","parameters":[{"name":"value","type":"Integer"}],"returntype":"Void","offset":35,"safe":false},{"name":"verify","parameters":[{"name":"signature","type":"ByteArray"}],"returntype":"Boolean","offset":42,"safe":true},{"name":"withdraw","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"}],"returntype":"Boolean","offset":49,"safe":false}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""},
55+
{"Treasury", """{"id":-11,"updatecounter":0,"hash":"0x156326f25b1b5d839a4d326aeaa75383c9563ac1","nef":{"magic":860243278,"compiler":"neo-core-v3.0","source":"","tokens":[],"script":"EEEa93tnQBBBGvd7Z0AQQRr3e2dA","checksum":1592866325},"manifest":{"name":"Treasury","groups":[],"features":{},"supportedstandards":["NEP-26","NEP-27"],"abi":{"methods":[{"name":"onNEP11Payment","parameters":[{"name":"from","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"tokenId","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","offset":0,"safe":true},{"name":"onNEP17Payment","parameters":[{"name":"from","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Void","offset":7,"safe":true},{"name":"verify","parameters":[],"returntype":"Boolean","offset":14,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}}"""}
5556
};
5657
}
5758

@@ -163,9 +164,10 @@ public void TestNativeContractId()
163164
Assert.AreEqual(-7, NativeContract.Policy.Id);
164165
Assert.AreEqual(-8, NativeContract.RoleManagement.Id);
165166
Assert.AreEqual(-9, NativeContract.Oracle.Id);
167+
Assert.AreEqual(-10, NativeContract.Notary.Id);
168+
Assert.AreEqual(-11, NativeContract.Treasury.Id);
166169
}
167170

168-
169171
class TestSpecialParameter
170172
{
171173
[ContractMethod]

0 commit comments

Comments
 (0)