Skip to content

Commit 73cea01

Browse files
cschuchardt88JimmyshargonNGDAdmin
authored
[Add] Transaction Builder (#3477)
* Added Builders with tests * Added SignerBuilder and started WitnessRuleBuilder * Added `WitnessConditionBuilder` with tests * Added more logic * Fixed `SignerBuilder` class * Code touch ups * Added more tests * Update src/Neo/Builders/TransactionBuilder.cs * Fixed `And` `Or` and `Not` conditions * Fixed Memory leak * Added error message for Witness scripts --------- Co-authored-by: Jimmy <[email protected]> Co-authored-by: Shargon <[email protected]> Co-authored-by: NGD Admin <[email protected]>
1 parent d6ed5a5 commit 73cea01

14 files changed

+1471
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright (C) 2015-2024 The Neo Project.
2+
//
3+
// AndConditionBuilder.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+
using Neo.Cryptography.ECC;
13+
using Neo.Network.P2P.Payloads.Conditions;
14+
using System;
15+
16+
namespace Neo.Builders
17+
{
18+
public sealed class AndConditionBuilder
19+
{
20+
private readonly AndCondition _condition = new() { Expressions = [] };
21+
22+
private AndConditionBuilder() { }
23+
24+
public static AndConditionBuilder CreateEmpty()
25+
{
26+
return new AndConditionBuilder();
27+
}
28+
29+
public AndConditionBuilder And(Action<AndConditionBuilder> config)
30+
{
31+
var acb = new AndConditionBuilder();
32+
config(acb);
33+
34+
_condition.Expressions = [.. _condition.Expressions, acb.Build()];
35+
36+
return this;
37+
}
38+
39+
public AndConditionBuilder Or(Action<OrConditionBuilder> config)
40+
{
41+
var ocb = OrConditionBuilder.CreateEmpty();
42+
config(ocb);
43+
44+
_condition.Expressions = [.. _condition.Expressions, ocb.Build()];
45+
46+
return this;
47+
}
48+
49+
public AndConditionBuilder Boolean(bool expression)
50+
{
51+
_condition.Expressions = [.. _condition.Expressions, new BooleanCondition { Expression = expression }];
52+
return this;
53+
}
54+
55+
public AndConditionBuilder CalledByContract(UInt160 hash)
56+
{
57+
_condition.Expressions = [.. _condition.Expressions, new CalledByContractCondition { Hash = hash }];
58+
return this;
59+
}
60+
61+
public AndConditionBuilder CalledByEntry()
62+
{
63+
_condition.Expressions = [.. _condition.Expressions, new CalledByEntryCondition()];
64+
return this;
65+
}
66+
67+
public AndConditionBuilder CalledByGroup(ECPoint publicKey)
68+
{
69+
_condition.Expressions = [.. _condition.Expressions, new CalledByGroupCondition { Group = publicKey }];
70+
return this;
71+
}
72+
73+
public AndConditionBuilder Group(ECPoint publicKey)
74+
{
75+
_condition.Expressions = [.. _condition.Expressions, new GroupCondition() { Group = publicKey }];
76+
return this;
77+
}
78+
79+
public AndConditionBuilder ScriptHash(UInt160 scriptHash)
80+
{
81+
_condition.Expressions = [.. _condition.Expressions, new ScriptHashCondition() { Hash = scriptHash }];
82+
return this;
83+
}
84+
85+
public AndCondition Build()
86+
{
87+
return _condition;
88+
}
89+
}
90+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright (C) 2015-2024 The Neo Project.
2+
//
3+
// OrConditionBuilder.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+
using Neo.Cryptography.ECC;
13+
using Neo.Network.P2P.Payloads.Conditions;
14+
using System;
15+
16+
namespace Neo.Builders
17+
{
18+
public sealed class OrConditionBuilder
19+
{
20+
private readonly OrCondition _condition = new() { Expressions = [] };
21+
22+
private OrConditionBuilder() { }
23+
24+
public static OrConditionBuilder CreateEmpty()
25+
{
26+
return new OrConditionBuilder();
27+
}
28+
29+
public OrConditionBuilder And(Action<AndConditionBuilder> config)
30+
{
31+
var acb = AndConditionBuilder.CreateEmpty();
32+
config(acb);
33+
34+
_condition.Expressions = [.. _condition.Expressions, acb.Build()];
35+
36+
return this;
37+
}
38+
39+
public OrConditionBuilder Or(Action<OrConditionBuilder> config)
40+
{
41+
var acb = new OrConditionBuilder();
42+
config(acb);
43+
44+
_condition.Expressions = [.. _condition.Expressions, acb.Build()];
45+
46+
return this;
47+
}
48+
49+
public OrConditionBuilder Boolean(bool expression)
50+
{
51+
_condition.Expressions = [.. _condition.Expressions, new BooleanCondition { Expression = expression }];
52+
return this;
53+
}
54+
55+
public OrConditionBuilder CalledByContract(UInt160 hash)
56+
{
57+
_condition.Expressions = [.. _condition.Expressions, new CalledByContractCondition { Hash = hash }];
58+
return this;
59+
}
60+
61+
public OrConditionBuilder CalledByEntry()
62+
{
63+
_condition.Expressions = [.. _condition.Expressions, new CalledByEntryCondition()];
64+
return this;
65+
}
66+
67+
public OrConditionBuilder CalledByGroup(ECPoint publicKey)
68+
{
69+
_condition.Expressions = [.. _condition.Expressions, new CalledByGroupCondition { Group = publicKey }];
70+
return this;
71+
}
72+
73+
public OrConditionBuilder Group(ECPoint publicKey)
74+
{
75+
_condition.Expressions = [.. _condition.Expressions, new GroupCondition() { Group = publicKey }];
76+
return this;
77+
}
78+
79+
public OrConditionBuilder ScriptHash(UInt160 scriptHash)
80+
{
81+
_condition.Expressions = [.. _condition.Expressions, new ScriptHashCondition() { Hash = scriptHash }];
82+
return this;
83+
}
84+
85+
public OrCondition Build()
86+
{
87+
return _condition;
88+
}
89+
}
90+
}

src/Neo/Builders/SignerBuilder.cs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright (C) 2015-2024 The Neo Project.
2+
//
3+
// SignerBuilder.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+
using Neo.Cryptography.ECC;
13+
using Neo.Network.P2P.Payloads;
14+
using System;
15+
16+
namespace Neo.Builders
17+
{
18+
public sealed class SignerBuilder
19+
{
20+
private readonly Signer _signer = new Signer()
21+
{
22+
Account = UInt160.Zero,
23+
AllowedContracts = [],
24+
AllowedGroups = [],
25+
Rules = [],
26+
Scopes = WitnessScope.None,
27+
};
28+
29+
private SignerBuilder() { }
30+
31+
public static SignerBuilder CreateEmpty()
32+
{
33+
return new SignerBuilder();
34+
}
35+
36+
public SignerBuilder Account(UInt160 scriptHash)
37+
{
38+
_signer.Account = scriptHash;
39+
return this;
40+
}
41+
42+
public SignerBuilder AllowContract(UInt160 contractHash)
43+
{
44+
_signer.AllowedContracts = [.. _signer.AllowedContracts, contractHash];
45+
return this;
46+
}
47+
48+
public SignerBuilder AllowGroup(ECPoint publicKey)
49+
{
50+
_signer.AllowedGroups = [.. _signer.AllowedGroups, publicKey];
51+
return this;
52+
}
53+
54+
public SignerBuilder AddWitnessScope(WitnessScope scope)
55+
{
56+
_signer.Scopes |= scope;
57+
return this;
58+
}
59+
60+
public SignerBuilder AddWitnessRule(WitnessRuleAction action, Action<WitnessRuleBuilder> config)
61+
{
62+
var rb = WitnessRuleBuilder.Create(action);
63+
config(rb);
64+
_signer.Rules = [.. _signer.Rules, rb.Build()];
65+
return this;
66+
}
67+
68+
public Signer Build()
69+
{
70+
return _signer;
71+
}
72+
}
73+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright (C) 2015-2024 The Neo Project.
2+
//
3+
// TransactionAttributesBuilder.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+
using Neo.Network.P2P.Payloads;
13+
using System;
14+
using System.Linq;
15+
16+
namespace Neo.Builders
17+
{
18+
public sealed class TransactionAttributesBuilder
19+
{
20+
private TransactionAttribute[] _attributes = [];
21+
22+
private TransactionAttributesBuilder() { }
23+
24+
public static TransactionAttributesBuilder CreateEmpty()
25+
{
26+
return new TransactionAttributesBuilder();
27+
}
28+
29+
public TransactionAttributesBuilder AddConflict(Action<Conflicts> config)
30+
{
31+
var conflicts = new Conflicts();
32+
config(conflicts);
33+
_attributes = [.. _attributes, conflicts];
34+
return this;
35+
}
36+
37+
public TransactionAttributesBuilder AddOracleResponse(Action<OracleResponse> config)
38+
{
39+
var oracleResponse = new OracleResponse();
40+
config(oracleResponse);
41+
_attributes = [.. _attributes, oracleResponse];
42+
return this;
43+
}
44+
45+
public TransactionAttributesBuilder AddHighPriority()
46+
{
47+
if (_attributes.Any(a => a is HighPriorityAttribute))
48+
throw new InvalidOperationException("HighPriority already exists in the attributes.");
49+
50+
var highPriority = new HighPriorityAttribute();
51+
_attributes = [.. _attributes, highPriority];
52+
return this;
53+
}
54+
55+
public TransactionAttributesBuilder AddNotValidBefore(uint block)
56+
{
57+
if (_attributes.Any(a => a is NotValidBefore b && b.Height == block))
58+
throw new InvalidOperationException($"Block {block} already exists in the attributes.");
59+
60+
var validUntilBlock = new NotValidBefore()
61+
{
62+
Height = block
63+
};
64+
65+
_attributes = [.. _attributes, validUntilBlock];
66+
return this;
67+
}
68+
69+
public TransactionAttribute[] Build()
70+
{
71+
return _attributes;
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)