commit b80fee7cc3a059eda7ae14d041d25e7b7b093733
parent 81f01ae261ec1c457f7b7b8b9a1f59383bb34a32
Author: Antoine A <>
Date: Tue, 16 Nov 2021 16:00:30 +0100
Draft refund steps
Diffstat:
| M | research.md | | | 12 | ++++++++++++ |
| M | src/lib.rs | | | 128 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
2 files changed, 80 insertions(+), 60 deletions(-)
diff --git a/research.md b/research.md
@@ -124,6 +124,18 @@ Bitcoin Metadata. Journal of Grid Computing. 10.1007/s10723-019-09473-3.
OP_RETURN test
+## Refund
+
+- get raw transaction details
+- remove refund fee from sent amount
+- filter out fake addresses and self address (the onde in 'details')
+- send an equal part to each remaining addresses making them pay transactions
+ fees
+- ignore insufficient_funds
+
+RPC error code :
+https://github.com/bitcoin/bitcoin/blob/master/src/rpc/protocol.h
+
## Ethereum
- A transaction is from one address to another
diff --git a/src/lib.rs b/src/lib.rs
@@ -63,6 +63,67 @@ pub fn encode_segwit_key(hrp: &str, msg: &[u8; 32]) -> [String; 2] {
]
}
+#[derive(Debug, Clone)]
+pub enum DecodeError {
+ TooManyAddress,
+ MissingSeqWitAddress,
+ MagicIdCollision,
+}
+
+/// Decode a 32B key into from adresses
+pub fn decode_segwit_msg(segwit_addrs: &[impl AsRef<str>]) -> Result<[u8; 32], DecodeError> {
+ if segwit_addrs.len() < 2 {
+ return Err(DecodeError::MissingSeqWitAddress);
+ }
+
+ if segwit_addrs.len() > 4 {
+ return Err(DecodeError::TooManyAddress);
+ }
+
+ // Extract parts from every addresses
+ let decoded: Vec<(bool, [u8; 4], [u8; 16])> = segwit_addrs
+ .into_iter()
+ .filter_map(|addr| {
+ bech32::decode(addr.as_ref()).ok().and_then(|(_, wp, _)| {
+ // Skip version
+ let pg: Vec<u8> = Vec::from_base32(&wp[1..]).unwrap();
+ if pg.len() == 20 {
+ let mut magic_id: [u8; 4] = pg[..4].try_into().unwrap();
+ let key_half: [u8; 16] = pg[4..].try_into().unwrap();
+ let is_first = !pg[0] & 0b1000_0000 == 0;
+ // Clear first bit
+ magic_id[0] &= 0b0111_1111;
+ Some((is_first, magic_id, key_half))
+ } else {
+ None
+ }
+ })
+ })
+ .collect();
+
+ if decoded.len() < 2 {
+ return Err(DecodeError::MissingSeqWitAddress);
+ }
+ // Keep only the addresses with duplicated magic id
+ let matches: Vec<&(bool, [u8; 4], [u8; 16])> = decoded
+ .iter()
+ .filter(|(_, magic, _)| {
+ decoded
+ .iter()
+ .filter(|(_, other, _)| other == magic)
+ .count()
+ > 1
+ })
+ .collect();
+ assert_eq!(matches.len(), 2, "Magic ID collision");
+
+ let mut key = [0; 32];
+ for (is_first, _, half) in matches {
+ key[*is_first as usize * 16..][..16].copy_from_slice(half);
+ }
+ Ok(key)
+}
+
/// Send transaction to multiple recipients
fn send_many(client: &Client, recipients: Vec<(String, Amount)>) -> bitcoincore_rpc::Result<Txid> {
let amounts = Value::Object(
@@ -88,6 +149,13 @@ fn send_many(client: &Client, recipients: Vec<(String, Amount)>) -> bitcoincore_
)
}
+pub fn refund(rpc: &Client, id: &Txid) -> bitcoincore_rpc::Result<Txid> {
+ let tx = rpc.get_transaction(id, None)?;
+ //tx.details.
+ //assert!(tx)
+ Ok(*id)
+}
+
/// An extended bitcoincore JSON-RPC api client who can send and retrieve metadata with their transaction
pub trait ClientExtended {
// TODO error handling for get functions
@@ -213,66 +281,6 @@ impl ClientExtended for Client {
}
}
-#[derive(Debug, Clone)]
-pub enum DecodeError {
- TooManyAddress,
- MissingSeqWitAddress,
- MagicIdCollision,
-}
-
-pub fn decode_segwit_msg(segwit_addrs: &[impl AsRef<str>]) -> Result<[u8; 32], DecodeError> {
- if segwit_addrs.len() < 2 {
- return Err(DecodeError::MissingSeqWitAddress);
- }
-
- if segwit_addrs.len() > 4 {
- return Err(DecodeError::TooManyAddress);
- }
-
- // Extract parts from every addresses
- let decoded: Vec<(bool, [u8; 4], [u8; 16])> = segwit_addrs
- .into_iter()
- .filter_map(|addr| {
- bech32::decode(addr.as_ref()).ok().and_then(|(_, wp, _)| {
- // Skip version
- let pg: Vec<u8> = Vec::from_base32(&wp[1..]).unwrap();
- if pg.len() == 20 {
- let mut magic_id: [u8; 4] = pg[..4].try_into().unwrap();
- let key_half: [u8; 16] = pg[4..].try_into().unwrap();
- let is_first = !pg[0] & 0b1000_0000 == 0;
- // Clear first bit
- magic_id[0] &= 0b0111_1111;
- Some((is_first, magic_id, key_half))
- } else {
- None
- }
- })
- })
- .collect();
-
- if decoded.len() < 2 {
- return Err(DecodeError::MissingSeqWitAddress);
- }
- // Keep only the addresses with duplicated magic id
- let matches: Vec<&(bool, [u8; 4], [u8; 16])> = decoded
- .iter()
- .filter(|(_, magic, _)| {
- decoded
- .iter()
- .filter(|(_, other, _)| other == magic)
- .count()
- > 1
- })
- .collect();
- assert_eq!(matches.len(), 2, "Magic ID collision");
-
- let mut key = [0; 32];
- for (is_first, _, half) in matches {
- key[*is_first as usize * 16..][..16].copy_from_slice(half);
- }
- Ok(key)
-}
-
pub mod utils {
use crate::{encode_segwit_addr, encode_segwit_key};