-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
571 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// 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 stake transaction body | ||
StakeBody body = StakeBody( | ||
inputs: [ | ||
Input(outputPointer: outputPointer), | ||
], | ||
output: StakeOutput( | ||
value: MINIMUM_STAKEABLE_AMOUNT_WITS, | ||
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()); | ||
} | ||
|
||
/// 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())), | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>(2, '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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
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<KeyedSignature>(2, '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, | ||
KeyedSignature? authorization, | ||
}) { | ||
final _result = create(); | ||
if (value != null) { | ||
_result.value = Int64(value); | ||
} | ||
if (authorization != null) { | ||
_result.authorization = authorization; | ||
} | ||
return _result; | ||
} | ||
|
||
factory StakeOutput.fromRawJson(String str) => | ||
StakeOutput.fromJson(json.decode(str)); | ||
|
||
@override | ||
factory StakeOutput.fromJson(Map<String, dynamic> json) => StakeOutput( | ||
value: json["value"], | ||
authorization: KeyedSignature.fromJson(json["authorization"]), | ||
); | ||
|
||
Map<String, dynamic> jsonMap({bool asHex = false}) => { | ||
"value": value.toInt(), | ||
"authorization": authorization.jsonMap(asHex: asHex), | ||
}; | ||
|
||
@override | ||
BuilderInfo get info_ => _i; | ||
|
||
Uint8List get pbBytes => writeToBuffer(); | ||
|
||
@TagNumber(1) | ||
Int64 get value => $_getI64(1); | ||
@TagNumber(1) | ||
set value(Int64 v) { | ||
$_setInt64(0, v); | ||
} | ||
|
||
@TagNumber(1) | ||
bool hasValue() => $_has(0); | ||
@TagNumber(1) | ||
void clearValue() => clearField(1); | ||
|
||
@TagNumber(2) | ||
KeyedSignature get authorization => $_getN(2); | ||
@TagNumber(2) | ||
set authorization(KeyedSignature v) { | ||
setField(2, v); | ||
} | ||
|
||
@TagNumber(2) | ||
bool hasAuthorization() => $_has(1); | ||
@TagNumber(2) | ||
void clearAuthorization() => clearField(2); | ||
@TagNumber(2) | ||
PublicKeyHash ensureAuthorization() => $_ensure(1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
Oops, something went wrong.