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

Fix stake/unstake #62

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all 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
84 changes: 84 additions & 0 deletions example/stake_transaction_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// import 'package:witnet/node.dart';
import 'package:witnet/schema.dart';
import 'package:witnet/src/constants.dart';
import 'package:witnet/src/utils/transformations/transformations.dart';
import 'package:witnet/witnet.dart';

var outputPointer = OutputPointer.fromString(
'0000000000000000000000000000000000000000000000000000000000000000:0');

void main() async {
/// connect to local node rpc
// NodeClient nodeClient = NodeClient(address: "127.0.0.1", port: 21338);

// String mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
/// load node xprv for the default mnemonic
Xprv masterNode = Xprv.fromXprv(
"xprv1qpujxsyd4hfu0dtwa524vac84e09mjsgnh5h9crl8wrqg58z5wmsuqqcxlqmar3fjhkprndzkpnp2xlze76g4hu7g7c4r4r2m2e6y8xlvu566tn6");

Xprv withdrawer = masterNode /
KEYPATH_PURPOSE /
KEYPATH_COIN_TYPE /
KEYPATH_ACCOUNT /
EXTERNAL_KEYCHAIN /
0;

/// The 20 byte Public Key Hash of the withdrawer
String pkh = bytesToHex(withdrawer.privateKey.publicKey.publicKeyHash);

/// The authorization by the node
KeyedSignature authorization = signHash(pkh, masterNode.privateKey);

/// Build the Stake Key
StakeKey stakeKey = StakeKey(
validator: authorization.publicKey.pkh,
withdrawer: PublicKeyHash.fromAddress(withdrawer.address.address),
);

/// build stake transaction body
StakeBody body = StakeBody(
inputs: [
Input(outputPointer: outputPointer),
],
output: StakeOutput(
value: MINIMUM_STAKEABLE_AMOUNT_WITS,
key: stakeKey,
authorization: authorization,
),
);

/// build and sign stake transaction
StakeTransaction stake = StakeTransaction(
body: body,
signatures: [signHash(body.transactionId, masterNode.privateKey)]);

/// The Stake Transaction ID
print(stake.transactionID);

/// send stake transaction
/// var response = await nodeClient.inventory(stake.jsonMap());
///
UnstakeBody unstakeBody = UnstakeBody(
operator: PublicKeyHash.fromAddress(withdrawer.address.address),
withdrawal: ValueTransferOutput.fromJson({
"pkh": withdrawer.address.address,
"time_lock": 0,
"value": 1,
}));

KeyedSignature unstakeSignature =
signHash(bytesToHex(unstakeBody.hash), masterNode.privateKey);
UnstakeTransaction unstake =
UnstakeTransaction(body: unstakeBody, signature: unstakeSignature);

print(unstake.transactionID);
}

/// Sign Hash
KeyedSignature signHash(String hash, WitPrivateKey privateKey) {
final sig = privateKey.signature(hash);
return KeyedSignature(
publicKey: PublicKey(bytes: privateKey.publicKey.encode()),
signature: Signature(secp256k1: Secp256k1Signature(der: sig.encode())),
);
}
5 changes: 4 additions & 1 deletion lib/constants.dart
Original file line number Diff line number Diff line change
@@ -12,4 +12,7 @@ export 'src/constants.dart'
KEYPATH_PURPOSE,
KEYPATH_COIN_TYPE,
EXTERNAL_KEYCHAIN,
INTERNAL_KEYCHAIN;
INTERNAL_KEYCHAIN,
STAKE_OUTPUT_WEIGHT,
UNSTAKE_OUTPUT_WEIGHT,
MINIMUM_STAKEABLE_AMOUNT_WITS;
3 changes: 3 additions & 0 deletions lib/src/constants.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const INPUT_SIZE = 133;
const OUTPUT_SIZE = 36;
const STAKE_OUTPUT_WEIGHT = 105;
const UNSTAKE_OUTPUT_WEIGHT = 153;
const MINIMUM_STAKEABLE_AMOUNT_WITS = 10000;
const COMMIT_WEIGHT = 400;
const REVEAL_WEIGHT = 200;
const TALLY_WEIGHT = 100;
1 change: 1 addition & 0 deletions lib/src/crypto/hd_wallet/extended_private_key.dart
Original file line number Diff line number Diff line change
@@ -146,6 +146,7 @@ class Xprv extends ExtendedKey {
}

factory Xprv.fromEncryptedXprv(String xprv, String password) {
// throw 'Error from encrypted xprv';
try {
Bech32 bech = bech32.decode(xprv);
List<int> checksum = createChecksum(bech.hrp, bech.data);
8 changes: 7 additions & 1 deletion lib/src/data_structures/utxo_pool.dart
Original file line number Diff line number Diff line change
@@ -41,6 +41,8 @@ class UtxoPool {
}

List<Utxo> sortUtxos(UtxoSelectionStrategy utxoSelectionStrategy) {
print(utxoSelectionStrategy);
print('...sortUtxos.. 0. ${map.values.toList().length}');
List<Utxo> sortedUtxos;
switch (utxoSelectionStrategy) {
case UtxoSelectionStrategy.Random:
@@ -68,13 +70,16 @@ class UtxoPool {
});
}
}
print('...sortUtxos.. 1. ${sortedUtxos.length}');
return sortedUtxos;
}

List<Utxo> cover({
required int amountNanoWit,
required UtxoSelectionStrategy utxoStrategy,
}) {
print('-------cover UTXOS-------');
print('amount nanowit: $amountNanoWit');
List<Utxo> utxos = sortUtxos(utxoStrategy);
if (utxos.isEmpty) {
throw 'No UTXOS to select';
@@ -86,7 +91,8 @@ class UtxoPool {
});

List<Utxo> selectedUtxos = [];

print('utxos value: $utxoValue');
print('Insufficient funds?? ${amountNanoWit > utxoValue}');
if (amountNanoWit > utxoValue) {
throw 'Insufficient funds';
}
4 changes: 4 additions & 0 deletions lib/src/schema/public_key.dart
Original file line number Diff line number Diff line change
@@ -64,6 +64,10 @@ class PublicKey extends GeneratedMessage {

Uint8List get pbBytes => writeToBuffer();

PublicKeyHash get pkh => PublicKeyHash(
hash: sha256(data: Uint8List.fromList(publicKey)).sublist(0, 20),
);

@TagNumber(1)
List<int> get publicKey => $_getN(0);
@TagNumber(1)
10 changes: 9 additions & 1 deletion lib/src/schema/schema.dart
Original file line number Diff line number Diff line change
@@ -16,7 +16,9 @@ import 'package:witnet/constants.dart'
REVEAL_WEIGHT,
TALLY_WEIGHT,
INPUT_SIZE,
OUTPUT_SIZE;
OUTPUT_SIZE,
STAKE_OUTPUT_WEIGHT,
UNSTAKE_OUTPUT_WEIGHT;

import '../../radon.dart' show radToCbor, cborToRad;

@@ -54,6 +56,12 @@ part 'reveal_body.dart';
part 'reveal_transaction.dart';
part 'secp256k1_signature.dart';
part 'signature.dart';
part 'stake_body.dart';
part 'stake_key.dart';
part 'stake_output.dart';
part 'stake_transaction.dart';
part 'unstake_body.dart';
part 'unstake_transaction.dart';
part 'string_pair.dart';
part 'super_block.dart';
part 'super_block_vote.dart';
113 changes: 113 additions & 0 deletions lib/src/schema/stake_body.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
part of 'schema.dart';

class StakeBody extends GeneratedMessage {
static final BuilderInfo _i = BuilderInfo('StakeBody',
package: const PackageName('witnet'), createEmptyInstance: create)
..pc<Input>(1, 'inputs', PbFieldType.PM, subBuilder: Input.create)
..aOM<StakeOutput>(2, 'output', subBuilder: StakeOutput.create)
..aOM<ValueTransferOutput>(3, 'change',
subBuilder: ValueTransferOutput.create)
..hasRequiredFields = false;

static StakeBody create() => StakeBody._();
static PbList<StakeBody> createRepeated() => PbList<StakeBody>();
static StakeBody getDefault() =>
_defaultInstance ??= GeneratedMessage.$_defaultFor<StakeBody>(create);
static StakeBody? _defaultInstance;

StakeBody._() : super();

@override
StakeBody clone() => StakeBody()..mergeFromMessage(this);

@override
StakeBody createEmptyInstance() => create();

factory StakeBody({
Iterable<Input>? inputs,
StakeOutput? output,
ValueTransferOutput? change,
}) {
final _result = create();
if (inputs != null) {
_result.inputs.addAll(inputs);
}
if (output != null) {
_result.output = output;
}
if (change != null) {
_result.change = change;
}
return _result;
}

factory StakeBody.fromRawJson(String str) =>
StakeBody.fromJson(json.decode(str));

@override
factory StakeBody.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(i, r);

@override
factory StakeBody.fromJson(Map<String, dynamic> json) => StakeBody(
inputs: List<Input>.from(json["inputs"].map((x) => Input.fromJson(x))),
output: StakeOutput.fromJson(json["output"]),
change: ValueTransferOutput.fromJson(json["change"]),
);

factory StakeBody.fromPbBytes(Uint8List buffer) =>
create()..mergeFromBuffer(buffer, ExtensionRegistry.EMPTY);

String toRawJson({bool asHex = false}) => json.encode(jsonMap(asHex: asHex));

Map<String, dynamic> jsonMap({bool asHex = false}) => {
"inputs":
List<dynamic>.from(inputs.map((x) => x.jsonMap(asHex: asHex))),
"output": output.jsonMap(asHex: asHex),
"change": change.jsonMap(asHex: asHex),
};

Uint8List get pbBytes => writeToBuffer();

Uint8List get hash => sha256(data: pbBytes);

String get transactionId => bytesToHex(hash);
// VT_weight = N * INPUT_SIZE + M * OUTPUT_SIZE + STAKE_OUTPUT_WEIGHT
int get weight =>
(inputs.length * INPUT_SIZE) + OUTPUT_SIZE + STAKE_OUTPUT_WEIGHT;

@override
BuilderInfo get info_ => _i;

@TagNumber(1)
List<Input> get inputs => $_getList(0);

@TagNumber(2)
StakeOutput get output => $_getN(1);
@TagNumber(2)
set output(StakeOutput v) {
setField(2, v);
}

@TagNumber(2)
bool hasOutput() => $_has(1);
@TagNumber(2)
void clearOutput() => clearField(2);
@TagNumber(2)
StakeOutput ensureOutput() => $_ensure(1);

@TagNumber(3)
ValueTransferOutput get change => $_getN(2);
@TagNumber(3)
set change(ValueTransferOutput v) {
setField(3, v);
}

@TagNumber(3)
bool hasChange() => $_has(2);
@TagNumber(3)
void clearChange() => clearField(3);
@TagNumber(3)
VTTransactionBody ensureChange() => $_ensure(2);
}
83 changes: 83 additions & 0 deletions lib/src/schema/stake_key.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
part of 'schema.dart';

class StakeKey extends GeneratedMessage {
static final BuilderInfo _i = BuilderInfo('StakeOutput',
package: const PackageName('witnet'), createEmptyInstance: create)
..aOM<PublicKeyHash>(1, 'validator', subBuilder: PublicKeyHash.create)
..aOM<PublicKeyHash>(2, 'withdrawer', subBuilder: PublicKeyHash.create)
..hasRequiredFields = false;

static StakeKey create() => StakeKey._();
static PbList<StakeKey> createRepeated() => PbList<StakeKey>();
static StakeKey getDefault() =>
_defaultInstance ??= GeneratedMessage.$_defaultFor<StakeKey>(create);
static StakeKey? _defaultInstance;
StakeKey._() : super();

@override
GeneratedMessage clone() => StakeKey()..mergeFromMessage(this);

@override
GeneratedMessage createEmptyInstance() => create();

factory StakeKey({
PublicKeyHash? validator,
PublicKeyHash? withdrawer,
}) {
final _result = create();
if (validator != null) {
_result.validator = validator;
}
if (withdrawer != null) {
_result.withdrawer = withdrawer;
}
return _result;
}

factory StakeKey.fromRawJson(String str) =>
StakeKey.fromJson(json.decode(str));

@override
factory StakeKey.fromJson(Map<String, dynamic> json) => StakeKey(
validator: PublicKeyHash.fromAddress(json["validator"]),
withdrawer: PublicKeyHash.fromAddress(json["withdrawer"]),
);

Map<String, dynamic> jsonMap({bool asHex = false}) => {
"validator": validator.address,
"withdrawer": withdrawer.address,
};

@override
BuilderInfo get info_ => _i;

Uint8List get pbBytes => writeToBuffer();

@TagNumber(1)
PublicKeyHash get validator => $_getN(0);
@TagNumber(1)
set validator(PublicKeyHash v) {
setField(1, v);
}

@TagNumber(1)
bool hasValidator() => $_has(0);
@TagNumber(1)
void clearValidator() => clearField(1);
@TagNumber(1)
PublicKeyHash ensureValidator() => $_ensure(0);

@TagNumber(2)
PublicKeyHash get withdrawer => $_getN(1);
@TagNumber(2)
set withdrawer(PublicKeyHash v) {
setField(1, v);
}

@TagNumber(2)
bool hasWithdrawer() => $_has(1);
@TagNumber(2)
void clearWithdrawer() => clearField(2);
@TagNumber(2)
PublicKeyHash ensureWithdrawer() => $_ensure(1);
}
113 changes: 113 additions & 0 deletions lib/src/schema/stake_output.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
part of 'schema.dart';

class StakeOutput extends GeneratedMessage {
static final BuilderInfo _i = BuilderInfo('StakeOutput',
package: const PackageName('witnet'), createEmptyInstance: create)
..a<Int64>(1, 'value', PbFieldType.OU6, defaultOrMaker: Int64.ZERO)
..aOM<StakeKey>(2, 'key', subBuilder: StakeKey.create)
..aOM<KeyedSignature>(3, 'authorization', subBuilder: KeyedSignature.create)
..hasRequiredFields = false;

static StakeOutput create() => StakeOutput._();
static PbList<StakeOutput> createRepeated() => PbList<StakeOutput>();
static StakeOutput getDefault() =>
_defaultInstance ??= GeneratedMessage.$_defaultFor<StakeOutput>(create);
static StakeOutput? _defaultInstance;
StakeOutput._() : super();

@override
GeneratedMessage clone() => StakeOutput()..mergeFromMessage(this);

@override
GeneratedMessage createEmptyInstance() => create();

factory StakeOutput({
int? value,
StakeKey? key,
KeyedSignature? authorization,
}) {
final _result = create();
print('result >>>>***** $value');
print('result >>>>***** $key');
print('result >>>>***** $authorization');
if (value != null) {
_result.value = Int64(value);
}

if (key != null) {
_result.key = key;
}

if (authorization != null) {
_result.authorization = authorization;
}
print('result >>>>***** $_result');
return _result;
}

factory StakeOutput.fromRawJson(String str) =>
StakeOutput.fromJson(json.decode(str));

@override
factory StakeOutput.fromJson(Map<String, dynamic> json) => StakeOutput(
value: json["value"],
key: StakeKey.fromJson(json["key"]),
authorization: json["authorization"] != null
? KeyedSignature.fromJson(json["authorization"])
: null,
);

Map<String, dynamic> jsonMap({bool asHex = false}) => {
"value": value.toInt(),
"key": key.jsonMap(asHex: asHex),
"authorization":
authorization != null ? authorization!.jsonMap(asHex: asHex) : null,
};

@override
BuilderInfo get info_ => _i;

Uint8List get pbBytes => writeToBuffer();

@TagNumber(1)
Int64 get value => $_getI64(0);
@TagNumber(1)
set value(Int64 v) {
setField(1, v);
}

@TagNumber(1)
bool hasValue() => $_has(0);
@TagNumber(1)
void clearValue() => clearField(1);

@TagNumber(2)
StakeKey get key => $_getN(1);
@TagNumber(2)
set key(StakeKey v) {
setField(2, v);
}

@TagNumber(2)
bool hasKey() => $_has(1);
@TagNumber(2)
void clearKey() => clearField(2);
@TagNumber(2)
StakeKey ensureKey() => $_ensure(1);

@TagNumber(3)
KeyedSignature? get authorization => $_getN(2);
@TagNumber(3)
set authorization(KeyedSignature? v) {
if (v != null) {
setField(3, v);
}
}

@TagNumber(3)
bool hasAuthorization() => $_has(2);
@TagNumber(3)
void clearAuthorization() => clearField(3);
@TagNumber(3)
KeyedSignature? ensureAuthorization() => $_ensure(2);
}
89 changes: 89 additions & 0 deletions lib/src/schema/stake_transaction.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
part of 'schema.dart';

class StakeTransaction extends GeneratedMessage {
static final BuilderInfo _i = BuilderInfo('StakeTransaction',
package: const PackageName('witnet'), createEmptyInstance: create)
..aOM<StakeBody>(1, 'body', subBuilder: StakeBody.create)
..pc<KeyedSignature>(2, 'signatures', PbFieldType.PM,
subBuilder: KeyedSignature.create)
..hasRequiredFields = false;

static StakeTransaction create() => StakeTransaction._();
static PbList<StakeTransaction> createRepeated() =>
PbList<StakeTransaction>();
static StakeTransaction getDefault() => _defaultInstance ??=
GeneratedMessage.$_defaultFor<StakeTransaction>(create);
static StakeTransaction? _defaultInstance;

StakeTransaction._() : super();

@override
StakeTransaction clone() => StakeTransaction()..mergeFromMessage(this);

@override
StakeTransaction createEmptyInstance() => create();

factory StakeTransaction({
StakeBody? body,
Iterable<KeyedSignature>? signatures,
}) {
final _result = create();
if (body != null) {
_result.body = body;
}
if (signatures != null) {
_result.signatures.addAll(signatures);
}
return _result;
}

factory StakeTransaction.fromRawJson(String str) =>
StakeTransaction.fromJson(json.decode(str));

@override
factory StakeTransaction.fromJson(Map<String, dynamic> json) =>
StakeTransaction(
body: StakeBody.fromJson(json["body"]),
signatures: List<KeyedSignature>.from(
json["signatures"].map((x) => KeyedSignature.fromJson(x))),
);

@override
factory StakeTransaction.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(i, r);

String rawJson({bool asHex = false}) => json.encode(jsonMap(asHex: asHex));

Map<String, dynamic> jsonMap({bool asHex = false}) => {
"body": body.jsonMap(asHex: asHex),
"signatures":
List<dynamic>.from(signatures.map((x) => x.jsonMap(asHex: asHex))),
};

String get transactionID => bytesToHex(body.hash);

int get weight => body.weight;

@override
BuilderInfo get info_ => _i;

Uint8List get pbBytes => writeToBuffer();

@TagNumber(1)
StakeBody get body => $_getN(0);
@TagNumber(1)
set body(StakeBody v) {
setField(1, v);
}

@TagNumber(1)
bool hasBody() => $_has(0);
@TagNumber(1)
void clearBody() => clearField(1);
@TagNumber(1)
StakeBody ensureBody() => $_ensure(0);

@TagNumber(2)
List<KeyedSignature> get signatures => $_getList(1);
}
111 changes: 100 additions & 11 deletions lib/src/schema/transaction.dart
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@ enum TransactionKind {
reveal,
tally,
mint,
stake,
unstake,
notSet
}

@@ -17,13 +19,15 @@ const Map<int, TransactionKind> _Transaction_KindByTag = {
4: TransactionKind.reveal,
5: TransactionKind.tally,
6: TransactionKind.mint,
7: TransactionKind.stake,
8: TransactionKind.unstake,
0: TransactionKind.notSet
};

class Transaction extends GeneratedMessage {
static final BuilderInfo _i = BuilderInfo('Transaction',
package: const PackageName('witnet'), createEmptyInstance: create)
..oo(0, [1, 2, 3, 4, 5, 6])
..oo(0, [1, 2, 3, 4, 5, 6, 7, 8])
..aOM<VTTransaction>(1, 'ValueTransfer',
protoName: 'ValueTransfer', subBuilder: VTTransaction.create)
..aOM<DRTransaction>(2, 'DataRequest',
@@ -36,6 +40,10 @@ class Transaction extends GeneratedMessage {
protoName: 'Tally', subBuilder: TallyTransaction.create)
..aOM<MintTransaction>(6, 'Mint',
protoName: 'Mint', subBuilder: MintTransaction.create)
..aOM<StakeTransaction>(7, 'Stake',
protoName: 'Stake', subBuilder: StakeTransaction.create)
..aOM<UnstakeTransaction>(8, 'Unstake',
protoName: 'Unstake', subBuilder: UnstakeTransaction.create)
..hasRequiredFields = false;

static Transaction create() => Transaction._();
@@ -59,6 +67,8 @@ class Transaction extends GeneratedMessage {
RevealTransaction? reveal,
TallyTransaction? tally,
MintTransaction? mint,
StakeTransaction? stake,
UnstakeTransaction? unstake,
}) {
final _result = create();
if (valueTransfer != null) {
@@ -79,6 +89,12 @@ class Transaction extends GeneratedMessage {
if (mint != null) {
_result.mint = mint;
}
if (stake != null) {
_result.stake = stake;
}
if (unstake != null) {
_result.unstake = unstake;
}
return _result;
}

@@ -110,9 +126,13 @@ class Transaction extends GeneratedMessage {
case 'Reveal':
return Transaction(
reveal: RevealTransaction.fromJson(_txn['Reveal']));

case 'Tally':
return Transaction(tally: TallyTransaction.fromJson(_txn['Tally']));
case 'Stake':
return Transaction(stake: StakeTransaction.fromJson(_txn['Stake']));
case 'Unstake':
return Transaction(
unstake: UnstakeTransaction.fromJson(_txn['Unstake']));
}
} else {
throw ArgumentError('Invalid json');
@@ -123,16 +143,55 @@ class Transaction extends GeneratedMessage {
String toRawJson({bool asHex = false}) => json.encode(jsonMap(asHex: asHex));

Map<String, dynamic> jsonMap({bool asHex = false}) {
final txType = hasDataRequest() ? 'DataRequest' : 'ValueTransfer';
return {
"transaction": {
txType: {
"body": transaction.body.jsonMap(asHex: asHex),
"signatures": List<dynamic>.from(
transaction.signatures.map((x) => x.jsonMap(asHex: asHex))),
if (hasValueTransfer())
return {
"transaction": {
'ValueTransfer': {
"body": transaction.body.jsonMap(asHex: asHex),
"signatures": List<dynamic>.from(
transaction.signatures.map((x) => x.jsonMap(asHex: asHex))),
}
}
}
};
};
if (hasDataRequest())
return {
"transaction": {
'DataRequest': {
"body": transaction.body.jsonMap(asHex: asHex),
"signatures": List<dynamic>.from(
transaction.signatures.map((x) => x.jsonMap(asHex: asHex))),
}
}
};
if (hasStake())
return {
"transaction": {
'Stake': {
"body": transaction.body.jsonMap(asHex: asHex),
"signatures": List<dynamic>.from(
transaction.signatures.map((x) => x.jsonMap(asHex: asHex))),
},
}
};
if (hasUnstake())
return {
"transaction": {
'Unstake': {
"body": transaction.body.jsonMap(asHex: asHex),
"signature": transaction.signature.jsonMap(asHex: asHex),
}
}
};
else
return {
"transaction": {
'ValueTransfer': {
"body": transaction.body.jsonMap(asHex: asHex),
"signatures": List<dynamic>.from(
transaction.signatures.map((x) => x.jsonMap(asHex: asHex))),
}
}
};
}

@override
@@ -161,6 +220,8 @@ class Transaction extends GeneratedMessage {
if (hasReveal()) return reveal;
if (hasTally()) return tally;
if (hasMint()) return mint;
if (hasStake()) return stake;
if (hasUnstake()) return unstake;
}

TransactionKind whichKind() => _Transaction_KindByTag[$_whichOneof(0)]!;
@@ -250,4 +311,32 @@ class Transaction extends GeneratedMessage {
void clearMint() => clearField(6);
@TagNumber(6)
MintTransaction ensureMint() => $_ensure(5);

@TagNumber(7)
StakeTransaction get stake => $_getN(6);
@TagNumber(7)
set stake(StakeTransaction v) {
setField(7, v);
}

@TagNumber(7)
bool hasStake() => $_has(6);
@TagNumber(7)
void clearStake() => clearField(7);
@TagNumber(7)
StakeTransaction ensureStake() => $_ensure(6);

@TagNumber(8)
UnstakeTransaction get unstake => $_getN(7);
@TagNumber(8)
set unstake(UnstakeTransaction v) {
setField(8, v);
}

@TagNumber(8)
bool hasUnstake() => $_has(7);
@TagNumber(8)
void clearUnstake() => clearField(8);
@TagNumber(8)
UnstakeTransaction ensureUnstake() => $_ensure(7);
}
101 changes: 101 additions & 0 deletions lib/src/schema/unstake_body.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
part of 'schema.dart';

class UnstakeBody extends GeneratedMessage {
static final BuilderInfo _i = BuilderInfo('UnstakeBody',
package: const PackageName('witnet'), createEmptyInstance: create)
..aOM<PublicKeyHash>(1, 'operator', subBuilder: PublicKeyHash.create)
..aOM<ValueTransferOutput>(2, 'withdrawal',
subBuilder: ValueTransferOutput.create)
..hasRequiredFields = false;

static UnstakeBody create() => UnstakeBody._();
static PbList<UnstakeBody> createRepeated() => PbList<UnstakeBody>();
static UnstakeBody getDefault() =>
_defaultInstance ??= GeneratedMessage.$_defaultFor<UnstakeBody>(create);
static UnstakeBody? _defaultInstance;

UnstakeBody._() : super();

@override
UnstakeBody clone() => UnstakeBody()..mergeFromMessage(this);

@override
UnstakeBody createEmptyInstance() => create();

factory UnstakeBody({
PublicKeyHash? operator,
ValueTransferOutput? withdrawal,
}) {
final _result = create();
if (operator != null) {
_result.operator = operator;
}
if (withdrawal != null) {
_result.withdrawal = withdrawal;
}

return _result;
}

factory UnstakeBody.fromRawJson(String str) =>
UnstakeBody.fromJson(json.decode(str));

@override
factory UnstakeBody.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(i, r);

@override
factory UnstakeBody.fromJson(Map<String, dynamic> json) => UnstakeBody(
operator: PublicKeyHash.fromAddress(json["operator"]),
withdrawal: ValueTransferOutput.fromJson(json["withdrawal"]),
);

factory UnstakeBody.fromPbBytes(Uint8List buffer) =>
create()..mergeFromBuffer(buffer, ExtensionRegistry.EMPTY);

String toRawJson({bool asHex = false}) => json.encode(jsonMap(asHex: asHex));

Map<String, dynamic> jsonMap({bool asHex = false}) => {
"operator": operator.address,
"withdrawal": withdrawal.jsonMap(asHex: asHex),
};

Uint8List get pbBytes => writeToBuffer();

Uint8List get hash => sha256(data: pbBytes);

// VT_weight = 153
int get weight => UNSTAKE_OUTPUT_WEIGHT;

@override
BuilderInfo get info_ => _i;

@TagNumber(1)
PublicKeyHash get operator => $_getN(0);
@TagNumber(1)
set operator(PublicKeyHash v) {
setField(1, v);
}

@TagNumber(1)
bool hasOperator() => $_has(0);
@TagNumber(1)
void clearOperator() => clearField(1);
@TagNumber(1)
PublicKeyHash ensureOperator() => $_ensure(0);

@TagNumber(2)
ValueTransferOutput get withdrawal => $_getN(1);
@TagNumber(2)
set withdrawal(ValueTransferOutput v) {
setField(2, v);
}

@TagNumber(2)
bool hasWithdrawal() => $_has(1);
@TagNumber(2)
void clearWithdrawal() => clearField(2);
@TagNumber(2)
ValueTransferOutput ensureWithdrawal() => $_ensure(1);
}
97 changes: 97 additions & 0 deletions lib/src/schema/unstake_transaction.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
part of 'schema.dart';

class UnstakeTransaction extends GeneratedMessage {
static final BuilderInfo _i = BuilderInfo('UnstakeTransaction',
package: const PackageName('witnet'), createEmptyInstance: create)
..aOM<UnstakeBody>(1, 'body', subBuilder: UnstakeBody.create)
..aOM<KeyedSignature>(2, 'signature', subBuilder: KeyedSignature.create)
..hasRequiredFields = false;

static UnstakeTransaction create() => UnstakeTransaction._();
static PbList<UnstakeTransaction> createRepeated() =>
PbList<UnstakeTransaction>();
static UnstakeTransaction getDefault() => _defaultInstance ??=
GeneratedMessage.$_defaultFor<UnstakeTransaction>(create);
static UnstakeTransaction? _defaultInstance;

UnstakeTransaction._() : super();

@override
UnstakeTransaction clone() => UnstakeTransaction()..mergeFromMessage(this);

@override
UnstakeTransaction createEmptyInstance() => create();

factory UnstakeTransaction({
UnstakeBody? body,
KeyedSignature? signature,
}) {
final _result = create();
if (body != null) {
_result.body = body;
}
if (signature != null) {
_result.signature = signature;
}
return _result;
}

factory UnstakeTransaction.fromRawJson(String str) =>
UnstakeTransaction.fromJson(json.decode(str));

@override
factory UnstakeTransaction.fromJson(Map<String, dynamic> json) =>
UnstakeTransaction(
body: UnstakeBody.fromJson(json["body"]),
signature: KeyedSignature.fromJson(json["signature"]),
);

@override
factory UnstakeTransaction.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(i, r);

String rawJson({bool asHex = false}) => json.encode(jsonMap(asHex: asHex));

Map<String, dynamic> jsonMap({bool asHex = false}) => {
"body": body.jsonMap(asHex: asHex),
"signature": signature.jsonMap(asHex: asHex)
};

String get transactionID => bytesToHex(body.hash);

int get weight => body.weight;

@override
BuilderInfo get info_ => _i;

Uint8List get pbBytes => writeToBuffer();

@TagNumber(1)
UnstakeBody get body => $_getN(0);
@TagNumber(1)
set body(UnstakeBody v) {
setField(1, v);
}

@TagNumber(1)
bool hasBody() => $_has(0);
@TagNumber(1)
void clearBody() => clearField(1);
@TagNumber(1)
UnstakeBody ensureBody() => $_ensure(0);

@TagNumber(2)
KeyedSignature get signature => $_getN(1);

@TagNumber(2)
bool hasSignature() => $_has(1);
@TagNumber(2)
void clearSignature() => clearField(2);
@TagNumber(2)
UnstakeBody ensureSignature() => $_ensure(1);
@TagNumber(2)
set signature(KeyedSignature v) {
setField(2, v);
}
}