Skip to content

Commit

Permalink
Support Dogecoin (#16)
Browse files Browse the repository at this point in the history
* ckb-auth-cli support dogecoin

* Add dogecoin doc
  • Loading branch information
joii2020 authored Nov 23, 2023
1 parent df6e9ef commit f3d7b5d
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The following blockchains are supported:
* [Ethereum](./docs/ethereum.md)
* [EOS](./docs/eos.md)
* [Tron](./docs/tron.md)
* Dogecoin
* [Dogecoin](./docs/dogecoin.md)
* CKB
* [Litecoin](./docs/litecoin.md)
* [Cardano](./docs/cardano.md)
Expand Down
67 changes: 67 additions & 0 deletions docs/dogecoin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# [Dogecoin](../README.md)

To work with Dogecoin, utilize the official command-line tool: [DogecoinCore](https://github.com/dogecoin/dogecoin/tree/v1.14.6).

Dogecoin shares many similarities with [Bitcoin](./bitcoin.md), including its signature algorithm and command-line tools. Here, we will focus on the distinctive aspects that set Dogecoin apart.

## Installation and Configuration
[Download](https://github.com/dogecoin/dogecoin/releases/tag/v1.14.6)
- It's essential to note that, much like `BitcoinCore` on Mac, Dogecoin provides GUI tools exclusively.
- For configuration, you can use the official default settings. If you prefer not to synchronize with online nodes, you can add `proxy=127.0.0.1:12345` to the configuration, using a non-existent proxy.

Start Dogecoin with the following command:
```
./dogecoind -daemonwait
```

## Generate a Key

When using dogecoin-cli for the first time, the `getaddressesbyaccount` command will automatically generate a new key group. Account information is stored in `wallet.dat`.

```bash
./dogecoin-cli getaddressesbyaccount ""
```

```
[
"DNF59P3dX2S2i188aPfBfL4aecs9gWtBt8"
]
```

A Dogecoin address always begins with the letter `D`, followed by content encoded in Base58, which includes the `public key hash` and a `checksum`. [You can find the code to parse and check addresses here](../tools/ckb-auth-cli/src/chain_command/dogecoin.rs#L52).

## Sign

Dogecoin Core supports signing and verifying messages.

```bash
./dogecoin-cli signmessage DNF59P3dX2S2i188aPfBfL4aecs9gWtBt8 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff
```

Output:
```
IIu/kxASl/W/5o3bjTD4KKBCQKcsDPUdp0+1Xu4vy0FhcpSfsIPu5Mi90VV0FGsN2gdlUvQFswTI886CeKNp7So=
```

The output signature data is Base58 encoded and can be used directly in ckb-auth.

To verify with `Dogecoin Core`:

```bash
./dogecoin-cli verifymessage DNF59P3dX2S2i188aPfBfL4aecs9gWtBt8 IIu/kxASl/W/5o3bjTD4KKBCQKcsDPUdp0+1Xu4vy0FhcpSfsIPu5Mi90VV0FGsN2gdlUvQFswTI886CeKNp7So= 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff
```

Output:
```
true
```

## Verify

To verify in ckb-auth-cli:

```bash
ckb-auth-cli dogecoin verify -a DNF59P3dX2S2i188aPfBfL4aecs9gWtBt8 -s IIu/kxASl/W/5o3bjTD4KKBCQKcsDPUdp0+1Xu4vy0FhcpSfsIPu5Mi90VV0FGsN2gdlUvQFswTI886CeKNp7So= -m 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff
```

Verification in Dogecoin is quite similar to Bitcoin, with the exception of address handling. For the most part, Bitcoin code can be used.
64 changes: 62 additions & 2 deletions tools/ckb-auth-cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tools/ckb-auth-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ monero = { version = "0.18.2", features = ["serde"] }
base58-monero = "1.0.0"
mbedtls = "0.8.1"
sha2 = "0.10.6"
bitcoin = "0.30.0"
5 changes: 3 additions & 2 deletions tools/ckb-auth-cli/src/bin/ckb-auth-cli.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use anyhow::{anyhow, Error};
use ckb_auth_cli::{
chain_command::{
BitcoinLockArgs, CardanoLockArgs, EosLockArgs, EthereumLockArgs, LitecoinLockArgs,
MoneroLockArgs, RippleLockArgs, SolanaLockArgs, TronLockArgs,
BitcoinLockArgs, CardanoLockArgs, DogecoinLockArgs, EosLockArgs, EthereumLockArgs,
LitecoinLockArgs, MoneroLockArgs, RippleLockArgs, SolanaLockArgs, TronLockArgs,
},
BlockChainArgs,
};
Expand Down Expand Up @@ -62,6 +62,7 @@ fn main() -> Result<(), Error> {
Box::new(EthereumLockArgs {}) as Box<dyn BlockChainArgs>,
Box::new(EosLockArgs {}) as Box<dyn BlockChainArgs>,
Box::new(TronLockArgs {}) as Box<dyn BlockChainArgs>,
Box::new(DogecoinLockArgs {}) as Box<dyn BlockChainArgs>,
];

let matches = cli(block_chain_args.as_slice()).get_matches();
Expand Down
98 changes: 98 additions & 0 deletions tools/ckb-auth-cli/src/chain_command/dogecoin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use crate::{
auth_script::run_auth_exec,
utils::{calculate_sha256, decode_string},
};
use crate::{BlockChain, BlockChainArgs};
use anyhow::{anyhow, Error};
use ckb_auth_rs::AuthAlgorithmIdType;
use clap::{arg, ArgMatches, Command};

pub struct DogecoinLockArgs {}

impl BlockChainArgs for DogecoinLockArgs {
fn block_chain_name(&self) -> &'static str {
"dogecoin"
}

fn reg_parse_args(&self, cmd: Command) -> Command {
cmd
}
fn reg_generate_args(&self, cmd: Command) -> Command {
cmd
}
fn reg_verify_args(&self, cmd: Command) -> Command {
cmd.arg(arg!(-a --address <PUBKEYHASH> "The dogecoin address"))
.arg(arg!(-s --signature <SIGNATURE> "The signature to verify"))
.arg(arg!(-m --message <MESSAGE> "The signature message"))
}

fn get_block_chain(&self) -> Box<dyn BlockChain> {
Box::new(DogecoinLock {})
}
}

pub struct DogecoinLock {}

impl BlockChain for DogecoinLock {
fn parse(&self, _operate_mathches: &ArgMatches) -> Result<(), Error> {
Err(anyhow!("dogecoin does not parse"))
}

fn generate(&self, _operate_mathches: &ArgMatches) -> Result<(), Error> {
Err(anyhow!("dogecoin does not generate"))
}

fn verify(&self, operate_mathches: &ArgMatches) -> Result<(), Error> {
let address = operate_mathches
.get_one::<String>("address")
.expect("Get address from args");
let address = bs58::decode(&address).into_vec().expect("get base58");

// https://github.com/dogecoin/dogecoin/blob/v1.14.6/src/chainparams.cpp#L167
if address[0] != 30 {
return Err(anyhow!("The first byte of address is not 30"));
}

let checksum = calculate_sha256(&calculate_sha256(&address[..21]));
if checksum[..4] != address[21..] {
return Err(anyhow!("Address Checksum failed,"));
}

let signature = decode_string(
operate_mathches
.get_one::<String>("signature")
.expect("Get signature from args"),
"base64",
)
.expect("decode signature from base64 string");

let message = hex::decode(
operate_mathches
.get_one::<String>("message")
.expect("Get message from args"),
)
.expect("decode message");

if address.len() < 21 {
return Err(anyhow!("dogecoin address invalidate"));
}
if signature.len() != 65 {
return Err(anyhow!("dogecoin signature size is not 65"));
}
if message.len() != 32 {
return Err(anyhow!("dogecoin message size is not 32"));
}

let pubkey_hash = &address[1..21];

run_auth_exec(
AuthAlgorithmIdType::Dogecoin,
pubkey_hash,
&message,
&signature,
)?;

println!("Success");
Ok(())
}
}
2 changes: 2 additions & 0 deletions tools/ckb-auth-cli/src/chain_command/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod bitcoin;
mod cardano;
mod dogecoin;
mod eos;
mod ethereum;
mod litecoin;
Expand All @@ -11,6 +12,7 @@ mod tron;
pub use self::monero::{MoneroLock, MoneroLockArgs};
pub use bitcoin::{BitcoinLock, BitcoinLockArgs};
pub use cardano::{CardanoLock, CardanoLockArgs};
pub use dogecoin::{DogecoinLock, DogecoinLockArgs};
pub use eos::{EosLock, EosLockArgs};
pub use ethereum::{EthereumLock, EthereumLockArgs};
pub use litecoin::{LitecoinLock, LitecoinLockArgs};
Expand Down

0 comments on commit f3d7b5d

Please sign in to comment.