Open Immmmmmortal1 opened 1 month ago
hi, in this section u sure about the address type ? We have different types of p2sh(p2pkh, p2pk, p2wpkh and ...). make sure select the correct address type
BaseWalletNoti.selectUtxos.asMap().forEach((index, element) {
unspentValue += BigInt.parse(element.value);
unspent.add(UtxoWithAddress(
utxo: BitcoinUtxo(
txHash: element.txid,
value: BigInt.parse(element.value),
vout: 1, //index, // 使用当前索引作为 vout
scriptType: senderPublicKey.toP2pkInP2sh().type, // here
),
ownerDetails: UtxoAddressDetails(
publicKey: senderPublicKey.toHex(),
address: senderPublicKey.toP2pkInP2sh(), // here
),
));
});
Dogecoin P2PK, P2PKH, P2SH this is my address
// DDbxjkznhsn5Ap1RUKFJ7SfUxoFcVdzrHL
//D6FoqUcqevrCgKUsejxDJNudVaebQ6pGk6
i want send dogecoins to this type address , which address Type i can use? Is P2PKH
Dogecoin P2PK, P2PKH, P2SH this is my address
// DDbxjkznhsn5Ap1RUKFJ7SfUxoFcVdzrHL //D6FoqUcqevrCgKUsejxDJNudVaebQ6pGk6
i want send dogecoins to this type address , which address Type i can use? Is P2PKH
It doesn't matter for the output which p2sh address you use.
In this code block
BaseWalletNoti.selectUtxos.asMap().forEach((index, element) {
unspentValue += BigInt.parse(element.value);
unspent.add(UtxoWithAddress(
utxo: BitcoinUtxo(
txHash: element.txid,
value: BigInt.parse(element.value),
vout: 1, //index, // 使用当前索引作为 vout
scriptType: senderPublicKey.toP2pkInP2sh().type, // here
),
ownerDetails: UtxoAddressDetails(
publicKey: senderPublicKey.toHex(),
address: senderPublicKey.toP2pkInP2sh(), // here
),
));
});
You must select Utxo address not receiver.
You must choose the correct type of account by using senderPublicKey.****p2sh().type
. This account type is related to UTXO, not the output.
It is essential to know which type of address was created. Without this knowledge, it is impossible to determine the correct P2SH address programmatically.
you can check the transaction details on the blockchain explorer. Alternatively, you can use the public key and test all possible P2SH address types to find the correct one.
Dogecoin P2PK, P2PKH, P2SH this is my address
// DDbxjkznhsn5Ap1RUKFJ7SfUxoFcVdzrHL //D6FoqUcqevrCgKUsejxDJNudVaebQ6pGk6
i want send dogecoins to this type address , which address Type i can use? Is P2PKH
these two address its P2pkh not p2sh
final addr = DogeAddress("D6FoqUcqevrCgKUsejxDJNudVaebQ6pGk6",
network: DogecoinNetwork.mainnet);
print(addr.type);
Thank you. I'll try it right away.
//:out1
final out1 = P2pkhAddress.fromAddress(address: recipientAddress, network: network);
// P2pkAddress.fromAddress(address: recipientAddress, network: network);
//:change
final out2 = P2pkhAddress.fromAddress(
address: BaseWalletNoti.baseWalletNotifier.value!.address,
network: network);
final addr = DogeAddress(recipientAddress,
network: DogecoinNetwork.mainnet);
BitcoinAddressType type = addr.type;
//:utxos
List<UtxoWithAddress> unspent = [];
BigInt unspentValue = BigInt.zero;
BaseWalletNoti.selectUtxos.asMap().forEach((index, element) {
unspentValue += BigInt.parse(element.value);
unspent.add(UtxoWithAddress(
utxo: BitcoinUtxo(
txHash: element.txid,
value: BigInt.parse(element.value),
vout: index, // 使用当前索引作为 vout
scriptType: type,
),
ownerDetails: UtxoAddressDetails(
publicKey: senderPublicKey.toHex(),
address: senderPublicKey.toP2pkhInP2sh(),
),
));
});
now ,i get utxo type from blow, and Assign to "scriptType "
final addr = DogeAddress(recipientAddress,
network: DogecoinNetwork.mainnet);
BitcoinAddressType type = addr.type;
but i got same error,like this
flutter: 当前交易结果{code: -26, message: 16: mandatory-script-verify-flag-failed (Script failed an OP_EQUALVERIFY operation)}
//:out1 final out1 = P2pkhAddress.fromAddress(address: recipientAddress, network: network); // P2pkAddress.fromAddress(address: recipientAddress, network: network); //:change final out2 = P2pkhAddress.fromAddress( address: BaseWalletNoti.baseWalletNotifier.value!.address, network: network); final addr = DogeAddress(recipientAddress, network: DogecoinNetwork.mainnet); BitcoinAddressType type = addr.type; //:utxos List<UtxoWithAddress> unspent = []; BigInt unspentValue = BigInt.zero; BaseWalletNoti.selectUtxos.asMap().forEach((index, element) { unspentValue += BigInt.parse(element.value); unspent.add(UtxoWithAddress( utxo: BitcoinUtxo( txHash: element.txid, value: BigInt.parse(element.value), vout: index, // 使用当前索引作为 vout scriptType: type, ), ownerDetails: UtxoAddressDetails( publicKey: senderPublicKey.toHex(), address: senderPublicKey.toP2pkhInP2sh(), ), )); });
now ,i get utxo type from blow, and Assign to "scriptType "
final addr = DogeAddress(recipientAddress, network: DogecoinNetwork.mainnet); BitcoinAddressType type = addr.type;
but i got same error,like this
flutter: 当前交易结果{code: -26, message: 16: mandatory-script-verify-flag-failed (Script failed an OP_EQUALVERIFY operation)}
what is recipientAddress? please send code fully i check them and dont use another class just create simple transaction in one method i can check all of them
//:sendrawtransaction
static Future<void> managerSendTransaction(String digets) async {
final params = {
"jsonrpc": "2.0",
"API_key": apiKey,
"id": 'send_${DateTime.now().millisecondsSinceEpoch}',
"method": "sendrawtransaction",
"params": [digets]
};
final cl = http.Client();
final res = await cl.post(Uri.parse("https://doge.nownodes.io"),
body: jsonEncode(params), headers: {"Content-Type": "application/json"});
final json = jsonDecode(res.body);
print("当前交易结果${json["error"]} ");
}
//:change
static BigInt _changeValue(BigInt sum, List<BigInt> all) {
final sumAll = all.fold<BigInt>(
BigInt.zero, (previousValue, element) => previousValue + element);
final remind = sum - sumAll;
if (remind < BigInt.zero) {
throw ArgumentError("invalid values");
}
return remind;
}
static Future<void> sendDoge(String recipientAddress, double amount) async {
/// Define the network
const network = DogecoinNetwork.mainnet;
String mne = "brain virus repair blame slogan cheap beauty plug slim math gate entire";
final seed = bip39.mnemonicToSeed(mne);
final bip32Node = Bip32Slip10Secp256k1.fromSeed(seed);
final childNode = bip32Node.childKey(Bip32KeyIndex(3));
//发送方的公钥和私钥
final senderPrivateKey = ECPrivate.fromBytes(childNode.privateKey.raw);
final senderPublicKey = senderPrivateKey.getPublic();
//:输出地址
final out1 = P2pkhAddress.fromAddress(address: "DDbxjkznhsn5Ap1RUKFJ7SfUxoFcVdzrHL", network: network);
//:找零地址
final out2 = P2pkhAddress.fromAddress(
address: "D6FoqUcqevrCgKUsejxDJNudVaebQ6pGk6",
network: network);
//:
final addr = DogeAddress(recipientAddress,
network: DogecoinNetwork.mainnet);
// print(addr.type);
BitcoinAddressType type = addr.type;
//:获取未花费的交易输出
<!-- {
"txid": "87c1a70bc9e8636737ceaf212c2042b24f41cf82316611897a9d81b365e1f1d5",
"vout": 0,
"value": "200000000",
"height": 5219509,
"confirmations": 11928
},-->
List<UtxoWithAddress> unspent = [
UtxoWithAddress(
utxo: BitcoinUtxo(
txHash: "87c1a70bc9e8636737ceaf212c2042b24f41cf82316611897a9d81b365e1f1d5",
value: BigInt.parse("200000000"),
vout: 0,
scriptType: type,
),
ownerDetails: UtxoAddressDetails(
publicKey: senderPublicKey.toHex(),
address: senderPublicKey.toP2pkAddress(),
),
)
];
BigInt unspentValue = BigInt.zero;
final fee = BtcUtils.toSatoshi(BaseWalletNoti.feeNotifier.value!);
final change = _changeValue(
unspentValue,
[
BtcUtils.toSatoshi("1"),
fee,
]);
/// Define the UTXO (Unspent Transaction Output)
final b = BitcoinTransactionBuilder(
outPuts: [
//:输出
BitcoinOutput(address: out1, value: BtcUtils.toSatoshi("1")),
//:找零
BitcoinOutput(address: out2, value: change),
],
fee: fee,
network: network,
// memo: "MRTNETWORK.com",
utxos: unspent,
);
final tr = b.buildTransaction((trDigest, utxo, publicKey, sighash) {
if (publicKey == senderPublicKey.toHex()) {
return senderPrivateKey.signInput(trDigest, sigHash: sighash);
}
throw UnimplementedError();
});
final txId = tr.txId();
final size = tr.getSize();
managerSendTransaction(tr.serialize());
}
//:gas fee
static Future<void> managerestimateFee() async {
final params = {
"jsonrpc": "2.0",
"API_key": apiKey,
"method": "estimatesmartfee",
"id" : "fee_${DateTime.now()}",
"params": [2]
};
final cl = http.Client();
final res = await cl.post(Uri.parse("https://doge.nownodes.io"),
body: jsonEncode(params), headers: {"Content-Type": "application/json"});
final json = jsonDecode(res.body);
if (json["error"] == null) {
BaseWalletNoti.feeNotifier.value = json["result"]["feerate"].toString();
// print("当前交易${json["result"]} ");
}
}
hi! these are all the codes,and the blow api can get utxos
https://dogebook.nownodes.io/api/v2/utxo/D6FoqUcqevrCgKUsejxDJNudVaebQ6pGk6?API_key=6ed8dfb4-704c-4bc1-83e5-6710cb7903da
//:sendrawtransaction static Future<void> managerSendTransaction(String digets) async { final params = { "jsonrpc": "2.0", "API_key": apiKey, "id": 'send_${DateTime.now().millisecondsSinceEpoch}', "method": "sendrawtransaction", "params": [digets] }; final cl = http.Client(); final res = await cl.post(Uri.parse("https://doge.nownodes.io"), body: jsonEncode(params), headers: {"Content-Type": "application/json"}); final json = jsonDecode(res.body); print("当前交易结果${json["error"]} "); } //:change static BigInt _changeValue(BigInt sum, List<BigInt> all) { final sumAll = all.fold<BigInt>( BigInt.zero, (previousValue, element) => previousValue + element); final remind = sum - sumAll; if (remind < BigInt.zero) { throw ArgumentError("invalid values"); } return remind; } static Future<void> sendDoge(String recipientAddress, double amount) async { /// Define the network const network = DogecoinNetwork.mainnet; String mne = "brain virus repair blame slogan cheap beauty plug slim math gate entire"; final seed = bip39.mnemonicToSeed(mne); final bip32Node = Bip32Slip10Secp256k1.fromSeed(seed); final childNode = bip32Node.childKey(Bip32KeyIndex(3)); //发送方的公钥和私钥 final senderPrivateKey = ECPrivate.fromBytes(childNode.privateKey.raw); final senderPublicKey = senderPrivateKey.getPublic(); //:输出地址 final out1 = P2pkhAddress.fromAddress(address: "DDbxjkznhsn5Ap1RUKFJ7SfUxoFcVdzrHL", network: network); //:找零地址 final out2 = P2pkhAddress.fromAddress( address: "D6FoqUcqevrCgKUsejxDJNudVaebQ6pGk6", network: network); //: final addr = DogeAddress(recipientAddress, network: DogecoinNetwork.mainnet); // print(addr.type); BitcoinAddressType type = addr.type; //:获取未花费的交易输出 <!-- { "txid": "87c1a70bc9e8636737ceaf212c2042b24f41cf82316611897a9d81b365e1f1d5", "vout": 0, "value": "200000000", "height": 5219509, "confirmations": 11928 },--> List<UtxoWithAddress> unspent = [ UtxoWithAddress( utxo: BitcoinUtxo( txHash: "87c1a70bc9e8636737ceaf212c2042b24f41cf82316611897a9d81b365e1f1d5", value: BigInt.parse("200000000"), vout: 0, scriptType: type, ), ownerDetails: UtxoAddressDetails( publicKey: senderPublicKey.toHex(), address: senderPublicKey.toP2pkAddress(), ), ) ]; BigInt unspentValue = BigInt.zero; final fee = BtcUtils.toSatoshi(BaseWalletNoti.feeNotifier.value!); final change = _changeValue( unspentValue, [ BtcUtils.toSatoshi("1"), fee, ]); /// Define the UTXO (Unspent Transaction Output) final b = BitcoinTransactionBuilder( outPuts: [ //:输出 BitcoinOutput(address: out1, value: BtcUtils.toSatoshi("1")), //:找零 BitcoinOutput(address: out2, value: change), ], fee: fee, network: network, // memo: "MRTNETWORK.com", utxos: unspent, ); final tr = b.buildTransaction((trDigest, utxo, publicKey, sighash) { if (publicKey == senderPublicKey.toHex()) { return senderPrivateKey.signInput(trDigest, sigHash: sighash); } throw UnimplementedError(); }); final txId = tr.txId(); final size = tr.getSize(); managerSendTransaction(tr.serialize()); } //:gas fee static Future<void> managerestimateFee() async { final params = { "jsonrpc": "2.0", "API_key": apiKey, "method": "estimatesmartfee", "id" : "fee_${DateTime.now()}", "params": [2] }; final cl = http.Client(); final res = await cl.post(Uri.parse("https://doge.nownodes.io"), body: jsonEncode(params), headers: {"Content-Type": "application/json"}); final json = jsonDecode(res.body); if (json["error"] == null) { BaseWalletNoti.feeNotifier.value = json["result"]["feerate"].toString(); // print("当前交易${json["result"]} "); } }
hi! these are all the codes,and the blow api can get utxos
https://dogebook.nownodes.io/api/v2/utxo/D6FoqUcqevrCgKUsejxDJNudVaebQ6pGk6?API_key=6ed8dfb4-704c-4bc1-83e5-6710cb7903da
what is receipment address? you must use spender address for utxos not receipment
please check comments
UtxoWithAddress(
utxo: BitcoinUtxo(
txHash:
"87c1a70bc9e8636737ceaf212c2042b24f41cf82316611897a9d81b365e1f1d5",
value: BigInt.parse("200000000"),
vout: 0,
/// Exactly type address related to this utxo
/// but if address is p2sh you must know about the address type
/// for example when you create address from public key
/// final address = senderPublicKey.toP2pkAddress()
/// you can use address in script type
/// scriptType: address.type
/// address: address
/// but if you want to define p2sh address without public key
/// you should use correct type
/// final address = P2shAddress.fromAddress(
/// address: "",
/// network: network,
/// type: P2shAddressType.p2pkInP2sh);
/// and then you can use scriptType: address.type
///
///
///
/// and its is `senderPublicKey.toP2pkAddress()` address is not P2PKH address its P2PK
/// for P2PKH address use `senderPublicKey.toAddress()`
scriptType: senderPublicKey.toP2pkAddress().type,
),
ownerDetails: UtxoAddressDetails(
publicKey: senderPublicKey.toHex(),
/// exactly address related to this utxo
address: senderPublicKey.toP2pkAddress(),
),
)
];
static String dogeDomain() {
// return 'https://dogebook-testnet.nownodes.io';
return "https://dogebook.nownodes.io";
}
static String apiKey = "6ed8dfb4-704c-4bc1-83e5-6710cb7903da";
//:sendrawtransaction
static Future<void> managerSendTransaction(String digets) async {
final params = {
"jsonrpc": "2.0",
"API_key": apiKey,
"id": 'send_${DateTime.now().millisecondsSinceEpoch}',
"method": "sendrawtransaction",
"params": [digets]
};
try {
final cl = http.Client();
final res = await cl.post(Uri.parse("https://doge.nownodes.io"),
body: jsonEncode(params),
headers: {"Content-Type": "application/json"});
final json = jsonDecode(res.body);
} catch (e) {}
}
static BigInt _changeValue(BigInt sum, List<BigInt> all) {
final sumAll = all.fold<BigInt>(
BigInt.zero, (previousValue, element) => previousValue + element);
final remind = sum - sumAll;
if (remind < BigInt.zero) {
throw ArgumentError("invalid values");
}
return remind;
}
static Future<void> sendDoge() async {
/// Define the network
const network = DogecoinNetwork.mainnet;
String mne = "brain virus repair blame slogan cheap beauty plug slim math gate entire";
final seed = bip39.mnemonicToSeed(mne);
final bip32Node = Bip32Slip10Secp256k1.fromSeed(seed);
final childNode = bip32Node.childKey(Bip32KeyIndex(3));
//发送方的公钥和私钥
final senderPrivateKey = ECPrivate.fromBytes(childNode.privateKey.raw);
final senderPublicKey = senderPrivateKey.getPublic();
final receiveA = "DDbxjkznhsn5Ap1RUKFJ7SfUxoFcVdzrHL";
final outPutA = "D6FoqUcqevrCgKUsejxDJNudVaebQ6pGk6";
//:输出地址
final out1 = P2pkhAddress.fromAddress(address: receiveA, network: network);
//:找零地址
final out2 = P2pkhAddress.fromAddress(
address: outPutA,
network: network);
//:获取未花费的交易输出
List<UtxoWithAddress> unspent = [BitcoinUtxo(
txHash: "87c1a70bc9e8636737ceaf212c2042b24f41cf82316611897a9d81b365e1f1d5",
value: BtcUtils.toSatoshi("2"),
vout: 0, // 使用当前索引作为 vout
scriptType: senderPublicKey.toAddress().type,
),
ownerDetails: UtxoAddressDetails(
publicKey: senderPublicKey.toHex(),
address: senderPublicKey.toAddress(),
),
)];
BigInt unspentValue = BigInt.zero;
final fee = await managerestimateFee();
final change = _changeValue(unspentValue, [
BtcUtils.toSatoshi("1"),
fee,
]);
/// Define the UTXO (Unspent Transaction Output)
final b = BitcoinTransactionBuilder(
outPuts: [
//:输出
BitcoinOutput(address: out1, value: BtcUtils.toSatoshi("1")),
//:找零
BitcoinOutput(address: out2, value: change),
],
fee: fee,
network: network,
// memo: "MRTNETWORK.com",
utxos: unspent,
);
final tr = b.buildTransaction((trDigest, utxo, publicKey, sighash) {
if (publicKey == senderPublicKey.toHex()) {
return senderPrivateKey.signInput(trDigest, sigHash: sighash);
}
throw UnimplementedError();
});
final txId = tr.txId();
final size = tr.getSize();
BaseWalletManger.managerSendTransaction(tr.serialize());
}
//:gas fee
static Future<String> managerestimateFee() async {
final params = {
"jsonrpc": "2.0",
"API_key": apiKey,
"method": "estimatesmartfee",
"id": "fee_${DateTime.now()}",
"params": [2]
};
try {
final cl = http.Client();
final res = await cl.post(Uri.parse("https://doge.nownodes.io"),
body: jsonEncode(params),
headers: {"Content-Type": "application/json"});
final json = jsonDecode(res.body);
if (json["error"] == null) {
return json["result"]["feerate"].toString();
}
} catch (e) {
return "";
}
}
this is my Complete code, and used the spent address Type , but i still get error like before. i see other lib has sign header in network, like this
const network = {
messagePrefix: '\x19Dogecoin Signed Message:\n',
bech32: 'dc',
bip44: 3,
bip32: {
public: 0x02facafd,
private: 0x02fac398,
},
pubKeyHash: 0x1e,
scriptHash: 0x16,
wif: 0x80,
};
Does my mistake have anything to do with this?
D6FoqUcqevrCgKUsejxDJNudVaebQ6pGk6
this address is also unspent address
According to {dog_example.dart} to sendrawTransaction ,Always get this mistake.